import { ClaudeSettings } from "@t3tools/contracts"; import * as NodeServices from "@effect/platform-node/NodeServices"; import { assert, it } from "@effect/vitest"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Path from "effect/Path"; import * as Schema from "effect/Schema"; import { buildClaudeCapabilitiesProbeQueryOptions, CLAUDE_CAPABILITIES_PROBE_SETTING_SOURCES, isLegacyClaudeModel, probeClaudeCapabilities, } from "./ClaudeProvider.ts"; const decodeClaudeSettings = Schema.decodeSync(ClaudeSettings); it("keeps only the Claude 5 family out of legacy models", () => { assert.deepStrictEqual( ["claude-fable-5", "claude-opus-5", "claude-sonnet-5", "claude-opus-4-8"].map((model) => [ model, isLegacyClaudeModel(model), ]), [ ["claude-fable-5", false], ["claude-opus-5", false], ["claude-sonnet-5", false], ["claude-opus-4-8", true], ], ); }); it("isolates Claude capability probes without dropping workspace setting sources", () => { const abortController = new AbortController(); const options = buildClaudeCapabilitiesProbeQueryOptions({ executablePath: "/usr/bin/claude", abortController, environment: { HOME: "/home/user", ENABLE_CLAUDEAI_MCP_SERVERS: "true", }, cwd: "/workspace/project", }); assert.deepEqual(options.mcpServers, {}); assert.equal(options.strictMcpConfig, true); assert.equal(options.cwd, "/workspace/project"); assert.deepEqual(options.settingSources, [...CLAUDE_CAPABILITIES_PROBE_SETTING_SOURCES]); assert.deepEqual(options.allowedTools, []); assert.equal(options.persistSession, false); assert.equal(options.pathToClaudeCodeExecutable, "/usr/bin/claude"); assert.equal(options.abortController, abortController); assert.equal(options.env?.HOME, "/home/user"); assert.equal(options.env?.ENABLE_CLAUDEAI_MCP_SERVERS, "false"); }); it.layer(NodeServices.layer)("Claude capability probe SDK boundary", (it) => { it.effect("serializes strict no-MCP options and still resolves account capabilities", () => Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; const path = yield* Path.Path; const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-claude-probe-sdk-" }); const executablePath = path.join(tempDir, "fake-claude.mjs"); const invocationPath = path.join(tempDir, "invocation.json"); const workspaceCwd = path.join(tempDir, "workspace"); yield* fs.makeDirectory(workspaceCwd, { recursive: true }); yield* fs.writeFileString( executablePath, [ "#!/usr/bin/env node", 'import { existsSync, readFileSync, writeFileSync } from "node:fs";', 'import { createInterface } from "node:readline";', "const args = process.argv.slice(2);", 'const mcpConfigIndex = args.indexOf("--mcp-config");', "const rawMcpConfig = mcpConfigIndex >= 0 ? args[mcpConfigIndex + 1] : undefined;", "let mcpConfig;", "if (rawMcpConfig) {", ' const contents = existsSync(rawMcpConfig) ? readFileSync(rawMcpConfig, "utf8") : rawMcpConfig;', " try { mcpConfig = JSON.parse(contents); } catch { mcpConfig = contents; }", "}", "writeFileSync(process.env.T3_PROBE_INVOCATION_PATH, JSON.stringify({", " args,", " cwd: process.cwd(),", " connectorEnv: process.env.ENABLE_CLAUDEAI_MCP_SERVERS,", " mcpConfig,", "}));", "const lines = createInterface({ input: process.stdin });", 'lines.on("line", (line) => {', " const message = JSON.parse(line);", ' if (message.type !== "control_request" || message.request?.subtype !== "initialize") return;', " process.stdout.write(JSON.stringify({", ' type: "control_response",', " response: {", ' subtype: "success",', " request_id: message.request_id,", " response: {", ' commands: [{ name: "review", description: "Review changes", argumentHint: "[path]" }],', " agents: [],", ' output_style: "default",', ' available_output_styles: ["default"],', " models: [],", ' account: { email: "dev@example.com", subscriptionType: "pro", tokenSource: "oauth" },', " },", " },", ' }) + "\\n");', "});", "setInterval(() => {}, 1_000);", "", ].join("\n"), ); yield* fs.chmod(executablePath, 0o755); const capabilities = yield* probeClaudeCapabilities( decodeClaudeSettings({ binaryPath: executablePath }), { ...process.env, T3_PROBE_INVOCATION_PATH: invocationPath, ENABLE_CLAUDEAI_MCP_SERVERS: "true", }, workspaceCwd, ); assert.deepEqual(capabilities, { email: "dev@example.com", subscriptionType: "pro", tokenSource: "oauth", apiProvider: undefined, slashCommands: [ { name: "review", description: "Review changes", input: { hint: "[path]" }, }, ], }); // @effect-diagnostics-next-line preferSchemaOverJson:off const invocation = JSON.parse(yield* fs.readFileString(invocationPath)) as { readonly args: ReadonlyArray; readonly cwd: string; readonly connectorEnv: string; readonly mcpConfig: unknown; }; assert.equal(invocation.cwd, yield* fs.realPath(workspaceCwd)); assert.equal(invocation.connectorEnv, "false"); assert.equal(invocation.args.includes("--strict-mcp-config"), true); assert.equal(invocation.args.includes("--mcp-config"), false); assert.equal(invocation.mcpConfig, undefined); assert.equal(invocation.args.includes("--setting-sources=user,project,local"), true); }).pipe(Effect.scoped), ); });