Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bin-launcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { cpSync, mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } fr
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const projectRoot = fileURLToPath(new URL("..", import.meta.url));
const tsxRoot = join(projectRoot, "node_modules", "tsx");
Expand Down
2 changes: 1 addition & 1 deletion src/cli-show-changes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import test from "node:test";
import { fileURLToPath } from "node:url";
import { promisify } from "node:util";
import { createReviewCheckpointManager } from "./review-checkpoints.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const execFileAsync = promisify(execFile);
const require = createRequire(import.meta.url);
Expand Down
2 changes: 1 addition & 1 deletion src/cli-worktrees.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { fileURLToPath } from "node:url";
import test from "node:test";
import { promisify } from "node:util";
import { openDatabase } from "./db/client.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";
import { SqliteWorkspaceStore } from "./workspace-store.js";

const execFileAsync = promisify(execFile);
Expand Down
2 changes: 1 addition & 1 deletion src/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from "./local-agent-daemon-lifecycle.js";
import { encodeLocalAgentDaemonResponse } from "./local-agent-daemon-protocol.js";
import { LocalAgentStore } from "./local-agent-store.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const execFileAsync = promisify(execFile);
const require = createRequire(import.meta.url);
Expand Down
60 changes: 0 additions & 60 deletions src/local-agent-catalog.test.ts

This file was deleted.

50 changes: 11 additions & 39 deletions src/local-agent-presentation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,34 @@ import type { LocalAgentCatalog } from "./local-agent-catalog.js";
import {
presentAgentObservation,
presentAgentReceipt,
presentAgentSummary,
presentAgentTargetCatalog,
} from "./local-agent-presentation.js";
Comment thread
Waishnav marked this conversation as resolved.
import type { LocalAgentRecord } from "./local-agent-store.js";

const record: LocalAgentRecord = {
const starting: LocalAgentRecord = {
id: "agt_test",
workspaceId: "ws_private",
workspaceRoot: "/private/project",
profileName: "reviewer",
provider: "codex",
model: "gpt-5.4",
effort: "high",
providerSessionId: "provider_private",
status: "running",
latestResponse: "previous response",
status: "starting",
createdAt: "2026-08-21T10:00:00.000Z",
updatedAt: "2026-08-21T10:01:00.000Z",
};

assert.deepEqual(presentAgentReceipt({ ...record, status: "starting" }), {
assert.deepEqual(presentAgentReceipt(starting), {
id: "agt_test",
status: "running",
});
assert.deepEqual(presentAgentSummary({ ...record, status: "idle" }), {
id: "agt_test",
status: "completed",
target: "reviewer",
});

const completed = presentAgentObservation({
...record,
status: "idle",
latestResponse: "Found one issue.",
});
assert.deepEqual(completed, {
id: "agt_test",
status: "completed",
response: "Found one issue.",
});

const failed = presentAgentObservation({
...record,
const failed: LocalAgentRecord = {
...starting,
status: "error",
latestResponse: undefined,
error: "Provider disconnected.",
errorCode: "PROVIDER_EXECUTION_ERROR",
errorRetryable: true,
});
assert.deepEqual(failed, {
};

assert.deepEqual(presentAgentObservation(failed), {
id: "agt_test",
status: "failed",
error: {
Expand All @@ -66,13 +44,7 @@ const catalog: LocalAgentCatalog = {
enabled: true,
providers: [
{ id: "codex", enabled: true, available: true, usable: true, model: "gpt-5.4", effort: "high" },
{
id: "claude",
enabled: true,
available: false,
usable: false,
reason: "credentials missing",
},
{ id: "claude", enabled: true, available: false, usable: false },
],
profiles: [{
name: "reviewer",
Expand All @@ -82,8 +54,8 @@ const catalog: LocalAgentCatalog = {
effort: "high",
}],
};
const targetCatalog = presentAgentTargetCatalog(catalog);
assert.deepEqual(targetCatalog, {

assert.deepEqual(presentAgentTargetCatalog(catalog), {
targets: [
{ name: "codex", kind: "provider", model: "gpt-5.4", effort: "high" },
{
Expand Down
2 changes: 1 addition & 1 deletion src/local-agent-profiles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { loadConfig } from "./config.js";
import { loadLocalAgentProfiles } from "./local-agent-profiles.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const root = await mkdtemp(join(tmpdir(), "devspace-agent-profiles-test-"));

Expand Down
24 changes: 0 additions & 24 deletions src/request-meta.test.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/server-oauth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import test from "node:test";
import { loadConfig } from "./config.js";
import { SqliteOAuthStore } from "./oauth-store.js";
import { createServer } from "./server.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

test("HTTP MCP enforces canonical and exact alias bearer resources", async (t) => {
const root = await mkdtemp(join(tmpdir(), "devspace-http-oauth-"));
Expand Down
76 changes: 66 additions & 10 deletions src/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ProcessSessionManager } from "./process-sessions.js";
import { createMcpServer, createServer } from "./server.js";
import { SqliteWorkspaceStore } from "./workspace-store.js";
import { WorkspaceRegistry } from "./workspaces.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const execFileAsync = promisify(execFile);

Expand Down Expand Up @@ -386,23 +386,68 @@ test("open_workspace keeps lifecycle flags out of model output and preserves com
test("open_workspace refreshes provider availability for each catalog", async (t) => {
let available = false;
const context = await fixture(t, {
localAgentProviders: () => [{ name: "codex", available }],
localAgentProviders: () => [
{ name: "codex", available },
{ name: "claude", available: false },
],
subagents: {
enabled: true,
instructions: "on-demand",
providers: [
{ id: "codex", enabled: true, model: "gpt-default", effort: "medium" },
{ id: "claude", enabled: true },
],
},
});
await writeFile(join(context.project, ".devspace", "agents", "custom.md"), [
"---",
"name: custom",
"description: Uses a custom model.",
"provider: codex",
"model: gpt-custom",
"---",
"Inspect.",
].join("\n"));
await writeFile(join(context.project, ".devspace", "agents", "claude-reviewer.md"), [
"---",
"name: claude-reviewer",
"description: Uses an unavailable provider.",
"provider: claude",
"---",
"Review with Claude.",
].join("\n"));

const unavailable = structuredContent(await callOpen(context.client, context.project, "chat-1"));
assert.deepEqual(unavailable.agent_providers, []);
assert.deepEqual(unavailable.agents, []);

available = true;
const usable = structuredContent(await callOpen(context.client, context.project, "chat-2"));
assert.equal(
(usable.agent_providers as Array<Record<string, unknown>>)[0]?.id,
"codex",
assert.deepEqual(
(usable.agent_providers as Array<Record<string, unknown>>).map((provider) => provider.id),
["codex"],
);
assert.equal(
(usable.agents as Array<Record<string, unknown>>)[0]?.name,
"reviewer",
const provider = (usable.agent_providers as Array<Record<string, unknown>>)[0];
assert.deepEqual(
{ id: provider?.id, model: provider?.model, effort: provider?.effort },
{ id: "codex", model: "gpt-default", effort: "medium" },
);
const agents = usable.agents as Array<Record<string, unknown>>;
assert.deepEqual(agents.find((agent) => agent.name === "reviewer"), {
name: "reviewer",
description: "Reviews project changes.",
provider: "codex",
model: "gpt-default",
effort: "medium",
});
assert.deepEqual(agents.find((agent) => agent.name === "custom"), {
name: "custom",
description: "Uses a custom model.",
provider: "codex",
model: "gpt-custom",
effort: "medium",
});
assert.deepEqual(agents.map((agent) => agent.name).sort(), ["custom", "reviewer"]);
});

test("open_workspace omits providers disabled by configuration", async (t) => {
Expand Down Expand Up @@ -468,6 +513,17 @@ test("open_workspace scopes checkout reuse to OpenAI session metadata", async (t
assert.notEqual(structuredContent(unscoped).workspace_id, structuredContent(first).workspace_id);
assert.ok(Array.isArray(structuredContent(otherSession).agents_files));
assert.ok(Array.isArray(structuredContent(unscoped).agents_files));

for (const malformedSession of ["", 42, {}]) {
const firstMalformed = await callOpen(context.client, context.project, malformedSession);
const repeatedMalformed = await callOpen(context.client, context.project, malformedSession);
assert.notEqual(
structuredContent(repeatedMalformed).workspace_id,
structuredContent(firstMalformed).workspace_id,
);
assert.ok(Array.isArray(structuredContent(firstMalformed).agents_files));
assert.ok(Array.isArray(structuredContent(repeatedMalformed).agents_files));
}
});

test("HTTP endpoint serves modern MCP and stateless legacy clients", async (t) => {
Expand Down Expand Up @@ -953,12 +1009,12 @@ function recordValue(value: unknown): Record<string, unknown> {
async function callOpen(
client: Client,
path: string,
conversationScopeId?: string,
conversationScopeId?: unknown,
): Promise<Awaited<ReturnType<Client["callTool"]>>> {
const params = {
name: "open_workspace",
arguments: { path },
...(conversationScopeId
...(conversationScopeId !== undefined
? { _meta: { "openai/session": conversationScopeId } }
: {}),
} as Parameters<Client["callTool"]>[0];
Expand Down
2 changes: 1 addition & 1 deletion src/skills.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
loadWorkspaceSkills,
resolveSkillReadPath,
} from "./skills.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const root = await mkdtemp(join(tmpdir(), "devspace-skills-test-"));
const originalHome = process.env.HOME;
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/workspace-conversation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { loadConfig, type ServerConfig } from "./config.js";
import { openDatabase } from "./db/client.js";
import { SqliteWorkspaceStore } from "./workspace-store.js";
import { WorkspaceRegistry } from "./workspaces.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const execFileAsync = promisify(execFile);

Expand Down
2 changes: 1 addition & 1 deletion src/workspaces.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
type WorkspaceStoreError,
} from "./workspace-store.js";
import { WorkspaceRegistry } from "./workspaces.js";
import { writeTestDevspaceConfig } from "./test-support/config.test.js";
import { writeTestDevspaceConfig } from "./test-support/config.js";

const execFileAsync = promisify(execFile);

Expand Down
2 changes: 1 addition & 1 deletion test/package-install-smoke.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { mkdirSync, mkdtempSync, readdirSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { writeTestDevspaceConfig } from "../src/test-support/config.test.js";
import { writeTestDevspaceConfig } from "../src/test-support/config.js";

const projectRoot = fileURLToPath(new URL("..", import.meta.url));

Expand Down
2 changes: 1 addition & 1 deletion tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["src/ui/**/*", "src/**/*.test.ts"]
"exclude": ["src/ui/**/*", "src/test-support/**/*", "src/**/*.test.ts"]
}
Loading