test: remove obsolete specification guards

This commit is contained in:
murashit 2026-07-21 06:46:39 +09:00
parent 193b680f06
commit 96b88c1715
17 changed files with 0 additions and 325 deletions

View file

@ -116,9 +116,6 @@ describe("thread title", () => {
expect(prompt).toContain("3-7 words for languages that use spaces");
expect(prompt).toContain("12-28 characters for languages that usually do not");
expect(prompt).toContain(`Never exceed ${String(THREAD_TITLE_MAX_CHARS)} characters`);
expect(prompt).not.toContain("日本語の短い名詞句");
expect(prompt).not.toContain("Japanese characters");
expect(prompt).not.toContain("English words");
});
it("uses explicit title runtime overrides", async () => {

View file

@ -5,7 +5,6 @@ import {
EphemeralThreadCleanupRequiredError,
forkEphemeralThread,
listThreads,
startEphemeralThread,
startThread,
threadFromAppServerRecord,
unsubscribeThread,
@ -200,28 +199,6 @@ describe("app-server thread response adapters", () => {
});
});
it("starts ephemeral helper threads without deprecated multi-agent mode params", async () => {
const client = {
request: vi.fn().mockResolvedValue({ thread: { id: "thread-new" } }),
} as unknown as AppServerRequestClient;
await startEphemeralThread(client, {
cwd: "/vault",
serviceName: "codex-panel-selection-rewrite",
developerInstructions: "Return structured output.",
});
expect(client.request).toHaveBeenCalledWith("thread/start", {
cwd: "/vault",
serviceName: "codex-panel-selection-rewrite",
developerInstructions: "Return structured output.",
ephemeral: true,
sandbox: "read-only",
approvalPolicy: "never",
environments: [],
});
});
it("maps listed threads to domain threads with archive state", async () => {
const clientListThreads = vi.fn().mockResolvedValue({
data: [{ id: "thread-1", preview: "Preview", name: null, createdAt: 10, updatedAt: 20 }],

View file

@ -1526,111 +1526,6 @@ describe("ChatInboundHandler", () => {
expect(chatStateThreadStreamItems(handler.currentState())).toEqual([]);
});
it("reconciles optimistic user echoes by client id before falling back to same-turn text only when client ids are absent", () => {
let state = activeRunningState();
state = withChatStateThreadStreamItems(state, [
{ id: "local-user-1", kind: "dialogue", dialogueKind: "user", role: "user", text: "same text", turnId: "turn-active" },
{ id: "local-steer-2", kind: "dialogue", dialogueKind: "user", role: "user", text: "same text", turnId: "turn-active" },
{ id: "local-user-2", kind: "dialogue", dialogueKind: "user", role: "user", text: "same text", turnId: "turn-other" },
]);
const handler = handlerForState(state);
handler.handleNotification({
method: "turn/completed",
params: {
threadId: "thread-active",
turn: {
id: "turn-active",
status: "completed",
error: null,
startedAt: null,
completedAt: null,
durationMs: null,
itemsView: "full",
items: [
{
type: "userMessage",
id: "u1",
clientId: "local-user-1",
content: [{ type: "text", text: "same text", text_elements: [] }],
},
{ type: "agentMessage", id: "a1", text: "done", phase: "final_answer", memoryCitation: null },
],
},
},
} satisfies Extract<ServerNotification, { method: "turn/completed" }>);
expect(chatStateThreadStreamItems(handler.currentState())).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: "u1", clientId: "local-user-1", text: "same text" }),
expect.objectContaining({ id: "local-steer-2", text: "same text" }),
expect.objectContaining({ id: "local-user-2", text: "same text" }),
]),
);
expect(chatStateThreadStreamItems(handler.currentState()).some((item) => item.id === "local-user-1")).toBe(false);
let fallbackStateWithoutClientId = chatStateFixture();
fallbackStateWithoutClientId = chatStateWith(fallbackStateWithoutClientId, { activeThread: { id: "thread-active" } });
fallbackStateWithoutClientId = chatStateWith(fallbackStateWithoutClientId, {
turn: { lifecycle: { kind: "running", turnId: "turn-active" } },
});
fallbackStateWithoutClientId = withChatStateThreadStreamItems(fallbackStateWithoutClientId, [
{
id: "local-user-without-client-id",
kind: "dialogue",
dialogueKind: "user",
role: "user",
text: "fallback text",
turnId: "turn-active",
},
{
id: "local-user-other-turn",
kind: "dialogue",
dialogueKind: "user",
role: "user",
text: "fallback text",
turnId: "turn-other",
},
]);
const fallbackHandlerWithoutClientId = handlerForState(fallbackStateWithoutClientId);
fallbackHandlerWithoutClientId.handleNotification({
method: "turn/completed",
params: {
threadId: "thread-active",
turn: {
id: "turn-active",
status: "completed",
error: null,
startedAt: null,
completedAt: null,
durationMs: null,
itemsView: "full",
items: [
{
type: "userMessage",
id: "server-u1",
clientId: null,
content: [{ type: "text", text: "fallback text", text_elements: [] }],
},
],
},
},
} satisfies Extract<ServerNotification, { method: "turn/completed" }>);
expect(chatStateThreadStreamItems(fallbackHandlerWithoutClientId.currentState())).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: "server-u1", text: "fallback text" }),
expect.objectContaining({ id: "local-user-other-turn", text: "fallback text" }),
]),
);
expect(
chatStateThreadStreamItems(fallbackHandlerWithoutClientId.currentState()).some(
(item) => item.id === "local-user-without-client-id",
),
).toBe(false);
});
it("keeps the observed steer message order when completed turns reconcile by client id", () => {
let state = activeRunningState();
state = withChatStateThreadStreamItems(state, [

View file

@ -22,7 +22,6 @@ describe("slash command catalog", () => {
expect(keys("Thread settings")).toEqual(
expect.arrayContaining(["/plan [message]", "/goal", "/goal set <objective>", "/goal edit", "/permissions [profile|default]"]),
);
expect(keys("Thread settings")).not.toContain("/goal [set <objective>|edit|pause|resume|clear]");
expect(keys("Diagnostics")).toEqual(expect.arrayContaining(["/status", "/doctor", "/tools", "/help"]));
expect(keys("Composition")).toEqual(["/refer <thread> <message>", "/web <url> [message]"]);
});

View file

@ -596,16 +596,6 @@ describe("slash commands", () => {
expect(ctx.addSystemMessage).toHaveBeenCalledWith("Permission profile reset to default for subsequent turns.");
});
it.each(["reset", "clear", "off"])("treats permission profile alias-like value %s as a profile id", async (profile) => {
const ctx = context();
await executeSlashCommand("permissions", profile, ctx);
expect(ctx.runtimeSettings.requestPermissionProfile).toHaveBeenCalledWith(profile);
expect(ctx.runtimeSettings.resetPermissionProfileToConfig).not.toHaveBeenCalled();
expect(ctx.addSystemMessage).toHaveBeenCalledWith(`Permission profile set to ${profile} for subsequent turns.`);
});
it("does not announce permission profile changes when applying them fails", async () => {
const ctx = context();
ctx.runtimeSettings.requestPermissionProfile = vi.fn().mockResolvedValue(false);
@ -663,18 +653,6 @@ describe("slash commands", () => {
expect(ctx.addSystemMessage).toHaveBeenCalledWith("Reasoning effort reset to default for subsequent turns.");
});
it.each(["reset", "clear", "off"])("routes runtime reset alias %s through reset commands", async (alias) => {
const ctx = context();
await executeSlashCommand("model", alias, ctx);
await executeSlashCommand("reasoning", alias, ctx);
expect(ctx.runtimeSettings.resetModelToConfig).toHaveBeenCalledOnce();
expect(ctx.runtimeSettings.resetReasoningEffortToConfig).toHaveBeenCalledOnce();
expect(ctx.runtimeSettings.requestModel).not.toHaveBeenCalled();
expect(ctx.runtimeSettings.requestReasoningEffort).not.toHaveBeenCalled();
});
it("shows model and reasoning status for empty runtime commands", async () => {
const modelDetails = [{ auditFacts: [{ key: "Model", value: "gpt-5.5" }] }];
const effortDetails = [{ auditFacts: [{ key: "Effort", value: "high" }] }];

View file

@ -102,35 +102,6 @@ describe("reconcileCompletedTurnItems", () => {
]);
});
it("keeps local context attachment metadata when reconciling by text without client ids", () => {
const optimistic = {
...userDialogue("local-user-1", "https://example.com/ summarize this", "turn"),
contextAttachments: [{ label: "Web page", detail: "https://example.com/" }],
} satisfies ThreadStreamItem;
const server = userDialogue("u1", "https://example.com/ summarize this", "turn");
const next = reconcileCompletedTurnItems({ currentItems: [optimistic], completedTurnId: "turn", turnItems: [server] });
expect(next).toEqual([
expect.objectContaining({
id: "u1",
contextAttachments: [{ label: "Web page", detail: "https://example.com/" }],
}),
]);
});
it("falls back to local user text only when server user dialogues have no client ids", () => {
const currentItems: ThreadStreamItem[] = [
userDialogue("local-user-without-client-id", "fallback text", "turn"),
userDialogue("local-user-other-turn", "fallback text", "other"),
];
const turnItems: ThreadStreamItem[] = [userDialogue("u1", "fallback text", "turn")];
const next = reconcileCompletedTurnItems({ currentItems, completedTurnId: "turn", turnItems });
expect(next.map((item) => item.id)).toEqual(["local-user-other-turn", "u1"]);
});
it("model-checks client-id reconciliation across current and server ordering", () => {
for (const currentItems of permutations([
userDialogue("local-user-1", "same text", "turn", "local-user-1"),
@ -151,26 +122,6 @@ describe("reconcileCompletedTurnItems", () => {
}
}
});
it("model-checks text fallback reconciliation only for the completed turn", () => {
for (const currentItems of permutations([
userDialogue("local-user-completed", "fallback text", "turn"),
userDialogue("local-user-other-turn", "fallback text", "other"),
userDialogue("local-user-different-text", "different text", "turn"),
])) {
const next = reconcileCompletedTurnItems({
currentItems,
completedTurnId: "turn",
turnItems: [userDialogue("server-user", "fallback text", "turn")],
});
const nextIds = next.map((item) => item.id);
expect(nextIds, currentIds(currentItems)).toContain("server-user");
expect(nextIds, currentIds(currentItems)).not.toContain("local-user-completed");
expect(nextIds, currentIds(currentItems)).toContain("local-user-other-turn");
expect(nextIds, currentIds(currentItems)).toContain("local-user-different-text");
}
});
});
function permutations<T>(items: readonly T[]): T[][] {

View file

@ -53,25 +53,6 @@ describe("ChatPanelSessionRuntime actions", () => {
await Promise.all([firstRestoration, secondRestoration]);
});
it("refreshes the shared query without projecting the returned value directly", async () => {
const thread = threadFixture({ id: "thread-1", preview: "From catalog" });
const refresh = vi.fn().mockResolvedValue([thread]);
const { runtime, stateStore } = sessionRuntimeFixture({
environment: {
plugin: {
threadCatalog: {
refreshActive: refresh,
},
},
},
});
await runtime.actions.refreshSharedThreads();
expect(refresh).toHaveBeenCalledOnce();
expect(stateStore.getState().threadList.listedThreads).toEqual([]);
});
it("treats stale shared thread refreshes as runtime-local no-ops", async () => {
const refresh = vi.fn().mockRejectedValue(new StaleExecutionRuntimeError());
const { runtime, stateStore } = sessionRuntimeFixture({

View file

@ -41,7 +41,6 @@ describe("CodexChatView workspace restoration", () => {
expect(view.surface.openPanelSnapshot()).toMatchObject({ threadId: "thread-1" });
expect(connectionMockState().connectCalls).toBe(0);
expect(requestMethods(client)).not.toContain("thread/resume");
expect(view.containerEl.textContent).not.toContain("Thread restored. Send a message to resume it.");
await vi.advanceTimersByTimeAsync(0);

View file

@ -12,10 +12,4 @@ describe("parseChatPanelViewState", () => {
expect(parseChatPanelViewState({ threadId: "" })).toEqual({ kind: "empty" });
expect(parseChatPanelViewState(null)).toEqual({ kind: "empty" });
});
it("treats persisted ephemeral side chats as discarded", () => {
expect(parseChatPanelViewState({ version: 2, ephemeralSource: { threadId: "source", title: "Source" } })).toEqual({
kind: "empty",
});
});
});

View file

@ -131,16 +131,6 @@ describe("CodexChatView thread state", () => {
expect(requestSaveLayout).toHaveBeenCalledTimes(2);
});
it("restores an unavailable side-chat tab as a normal empty chat", async () => {
const view = await chatView();
await view.setState({ version: 2, ephemeralSource: { threadId: "source", title: "Source" } }, {} as never);
expect(view.getState()).toEqual({ version: 1 });
expect(view.getDisplayText()).not.toBe("Side chat");
expect(view.surface.openPanelSnapshot()).toMatchObject({ threadId: null, turnBusy: false, hasComposerDraft: false });
expect(view.containerEl.textContent).not.toContain("This side conversation is no longer available.");
});
it("focuses the composer after panel thread actions", async () => {
const client = connectedClient();
connectionMockState().client = client;
@ -244,7 +234,6 @@ describe("CodexChatView thread state", () => {
});
expect(view.getState()).toEqual({ version: 1, threadId: "thread-1", threadTitle: "Restored thread" });
expect(view.containerEl.textContent).not.toContain("Loading thread...");
history.resolve({ data: [], nextCursor: null });
await opening;

View file

@ -173,37 +173,6 @@ describe("createChatPanelRuntimeProjection", () => {
{ key: "Extra writable roots", value: "(not reported)" },
]);
});
it("does not report legacy sandbox details for configured permission profiles in an empty panel", () => {
const state = chatStateWith(chatStateFixture(), {
connection: {
runtimeConfig: runtimeConfigFixture({
default_permissions: "DevProfile",
sandbox_mode: "workspace-write",
sandbox_workspace_write: {
writable_roots: ["/vault"],
network_access: false,
exclude_tmpdir_env_var: false,
exclude_slash_tmp: false,
},
}),
},
});
const projection = createChatPanelRuntimeProjection({
state: () => state,
connected: () => true,
configuredCommand: () => "codex",
vaultPath: () => "/vault",
nowMs: () => 0,
});
expect(projection.permissionDetails()[0]?.auditFacts).toEqual([
{ key: "Profile", value: "DevProfile" },
{ key: "Sandbox", value: "(not reported)" },
{ key: "Codex network", value: "(not reported)" },
{ key: "Extra writable roots", value: "(not reported)" },
]);
});
});
function runtimeConfigFixture(config: Record<string, unknown>): RuntimeConfigSnapshot {

View file

@ -357,9 +357,6 @@ describe("chat panel surface projections", () => {
expect(parent.textContent).toContain("Permissions & Approvals");
expect(parent.textContent).toContain("Permissions");
expect(parent.textContent).toContain("Approvals");
expect([...parent.querySelectorAll(".codex-panel__status-diagnostics-section")].map((section) => section.textContent)).not.toContain(
"New thread",
);
expect(parent.textContent).toContain(":workspace");
expect(parent.textContent).toContain("on-request");
expect(parent.textContent).toContain("off");

View file

@ -136,7 +136,6 @@ describe("ComposerShell decisions", () => {
expect(modeIcons.map((icon) => icon.classList.contains("is-active"))).toEqual([true, false, true]);
expect(modeIcons.map((icon) => icon.getAttribute("aria-hidden"))).toEqual(["true", "true", "true"]);
expect(parent.querySelector(".codex-panel__composer-action.codex-panel__send")).not.toBeNull();
expect(parent.querySelector(".codex-panel__new-chat")).toBeNull();
});
it("toggles composer runtime controls and opens separate lightweight pickers", async () => {

View file

@ -29,16 +29,11 @@ describe("Toolbar decisions", () => {
mountToolbar(parent, baseModel, toolbarActions({ startNewThread, toggleChatActions, toggleHistory }));
const navButtons = parent.querySelector(".codex-panel__toolbar-buttons");
expect(parent.querySelector(".codex-panel__runtime-area")).toBeNull();
expect(parent.querySelector(".codex-panel__runtime-strip")).toBeNull();
expect([...expectPresent(navButtons).children].map((button) => button.getAttribute("aria-label"))).toEqual([
"Show thread list",
"Show chat actions",
"Show status",
]);
expect(parent.querySelector(".codex-panel__plan-toggle")).toBeNull();
expect(parent.querySelector(".codex-panel__auto-review-toggle")).toBeNull();
expect(parent.querySelector(".codex-panel__runtime-model")).toBeNull();
const newChatButton = parent.querySelector<HTMLElement>(".codex-panel__new-chat");
expect(newChatButton?.getAttribute("aria-label")).toBe("Show chat actions");
newChatButton?.click();
@ -138,8 +133,6 @@ describe("Toolbar decisions", () => {
toolbarActions(),
);
expect(parent.querySelector(".codex-panel__context-compact")).toBeNull();
expect(parent.querySelector(".codex-panel__limit-compact")).toBeNull();
expect(parent.querySelector(".codex-panel__limit-panel")?.textContent).toContain("5h");
expect(parent.querySelector(".codex-panel__limit-panel")?.textContent).toContain("42%");
expect(parent.querySelector(".codex-panel__limit-panel")?.textContent).toContain("reset in 2h");
@ -220,9 +213,6 @@ describe("Toolbar decisions", () => {
expect(parent.textContent).toContain("Permissions & Approvals");
expect(parent.textContent).toContain("Permissions");
expect(parent.textContent).toContain("Approvals");
expect([...parent.querySelectorAll(".codex-panel__status-diagnostics-section")].map((section) => section.textContent)).not.toContain(
"Current thread",
);
expect(parent.textContent).toContain(":workspace");
expect(parent.textContent).toContain("workspace-write");
expect(parent.textContent).toContain("on");
@ -245,12 +235,9 @@ describe("Toolbar decisions", () => {
toolbarActions({ copyDebugDetails }),
);
expect(parent.querySelector(".codex-panel__region--config")).toBeNull();
expect(parent.querySelector(".codex-panel__debug-details")).toBeNull();
expect(parent.textContent).not.toContain('"model": "gpt-5.5"');
parent.querySelectorAll<HTMLButtonElement>(".codex-panel__status-panel-item")[2]?.click();
expect(copyDebugDetails).toHaveBeenCalledWith(debugDetails);
expect(parent.querySelector(".codex-panel__toolbar-panel .codex-panel__config")).toBeNull();
});
it("renders thread list rename actions and an inline rename editor", () => {

View file

@ -148,11 +148,6 @@ describe("turn diff view decisions", () => {
value: { threadId: "thread", turnId: "turn", files: ["src/main.ts"] },
valid: true,
},
{
name: "a legacy state with a working directory",
value: { threadId: "thread", turnId: "turn", cwd: "/vault/project", files: [] },
valid: true,
},
{ name: "null", value: null, valid: false },
{
name: "a missing turn id",
@ -198,7 +193,6 @@ describe("turn diff view decisions", () => {
{
threadId: "restored-thread",
turnId: "restored-turn",
cwd: "/legacy/vault",
files: ["src/restored.ts"],
},
{} as never,

View file

@ -464,22 +464,4 @@ describe("CodexPanelPlugin runtime integration", () => {
expect(refreshChat).toHaveBeenCalledOnce();
expect(refreshThreads).toHaveBeenCalledOnce();
});
it("does not redundantly refresh workspace views after runtime replacement", async () => {
const { CodexChatView } = await import("../src/features/chat/host/view.obsidian");
const { CodexThreadsView } = await import("../src/features/threads-view/view.obsidian");
const chatLeaf = leaf();
chatLeaf.view = chatView(CodexChatView, chatLeaf);
const refreshChat = vi.spyOn((chatLeaf.view as CodexChatView).surface, "refreshSettings");
const threadsView = Object.create(CodexThreadsView.prototype) as InstanceType<typeof CodexThreadsView>;
const refreshThreads = vi.spyOn(threadsView, "refreshSettings");
const threadsLeaf = leaf();
threadsLeaf.view = threadsView;
const plugin = await pluginWithLeaves([chatLeaf], { threadsLeaves: [threadsLeaf] });
await publishCodexPath(plugin, "codex-next");
expect(refreshChat).not.toHaveBeenCalled();
expect(refreshThreads).not.toHaveBeenCalled();
});
});

View file

@ -240,7 +240,6 @@ describe("settings tab", () => {
expect(withShortLivedAppServerClientMock).toHaveBeenCalledTimes(1);
expect(fetchModels).toHaveBeenCalledTimes(1);
expect(requestMethods(client)).not.toContain("model/list");
expectRequestTimes(client, "hooks/list", 1);
tab.display();
@ -248,10 +247,6 @@ describe("settings tab", () => {
expect(withShortLivedAppServerClientMock).toHaveBeenCalledTimes(1);
expect(buttonLabels(tab)).toContain("Refresh Codex details");
expect(buttonTexts(tab)).not.toContain("Refresh Codex details");
expect(buttonTexts(tab)).not.toContain("Load models");
expect(buttonTexts(tab)).not.toContain("Load hooks");
expect(buttonTexts(tab)).not.toContain("Load archive list");
expect(settingNames(tab)).toEqual([
"Codex executable",
"Show chat toolbar",
@ -731,9 +726,7 @@ describe("settings tab", () => {
tab.display();
await flushPromises();
expect(tab.containerEl.textContent).not.toContain("Loaded 1 model.");
expect(tab.containerEl.textContent).toContain("Could not load hooks: hooks unavailable");
expect(tab.containerEl.querySelector(".codex-panel-settings__refresh-status")).toBeNull();
expect(tab.containerEl.textContent).toContain("Archived thread");
expect(notices).toEqual(["Could not refresh all Codex details."]);
});
@ -748,10 +741,6 @@ describe("settings tab", () => {
tab.display();
await flushPromises();
expect(tab.containerEl.textContent).not.toContain("Restore or permanently delete archived Codex threads.");
expect(tab.containerEl.textContent).not.toContain("Trust, enable, or disable discovered Codex hooks.");
expect(tab.containerEl.textContent).not.toContain("Loaded 1 hook from Codex app server.");
expect(tab.containerEl.textContent).not.toContain("Loaded 1 archived thread from Codex app server.");
expect(tab.containerEl.querySelector(".codex-panel-settings__hook-section .setting-item-heading")?.textContent).toContain(
"Codex hooks",
);
@ -767,8 +756,6 @@ describe("settings tab", () => {
expect(tab.containerEl.querySelector(".codex-panel-settings__hook-list")?.textContent).toContain("untrusted · inactive");
expect(tab.containerEl.querySelector(".codex-panel-settings__archived-list")?.textContent).toContain("Archived thread");
expect(buttonTexts(tab)).toContain("Trust");
expect(buttonTexts(tab)).not.toContain("Enable");
expect(buttonTexts(tab)).not.toContain("Disable");
expect(buttonLabels(tab)).toContain("Restore thread");
expect(buttonLabels(tab)).toContain("Delete thread");
});