@velum-labs/routekit-tool-claude 0.16.8 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/install.d.ts +1 -1
- package/dist/install.js +51 -19
- package/dist/test/install.test.js +79 -11
- package/dist/test/launch.test.js +19 -18
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -5,6 +5,7 @@ Product-neutral Claude Code launcher and canonical harness driver.
|
|
|
5
5
|
## Architecture
|
|
6
6
|
|
|
7
7
|
This package owns the one Claude Code profile serializer, launcher, and driver.
|
|
8
|
+
The native Claude client owns its transcript store and session lifecycle.
|
|
8
9
|
|
|
9
10
|
## Usage
|
|
10
11
|
|
|
@@ -18,3 +19,9 @@ import { claudeTool } from "@velum-labs/routekit-tool-claude";
|
|
|
18
19
|
|
|
19
20
|
- CLI reference: [../../docs/cli.md](../../docs/cli.md)
|
|
20
21
|
- Maintainer reference: [../../docs/typescript-reference.md](../../docs/typescript-reference.md)
|
|
22
|
+
|
|
23
|
+
## Native client ownership
|
|
24
|
+
|
|
25
|
+
RouteKit does not observe, store, resume, or delete Claude sessions. Use Claude's
|
|
26
|
+
native history and resume/delete commands directly; launcher arguments after `--`
|
|
27
|
+
are forwarded to Claude unchanged.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ToolIntegration } from "@velum-labs/routekit-tools";
|
|
2
2
|
export declare const claudeTool: ToolIntegration;
|
|
3
|
-
export { claudeDriverConfigSchema, createClaudeDriver } from "./driver.js";
|
|
4
3
|
export type { ClaudeDriverConfig, ClaudeDriverOptions, ClaudeQueryFn } from "./driver.js";
|
|
5
|
-
export {
|
|
4
|
+
export { claudeDriverConfigSchema, createClaudeDriver } from "./driver.js";
|
|
6
5
|
export type { ClaudeInstallInput, ClaudeInstallOwner, ClaudeInstallResult } from "./install.js";
|
|
6
|
+
export { claudeIntegrationConfigPath, installClaudeIntegration, uninstallClaudeIntegration } from "./install.js";
|
|
7
7
|
export { claudeAgentsJson, claudeEnv, claudeLaunchArgs, launchClaude } from "./launch.js";
|
package/dist/index.js
CHANGED
|
@@ -30,5 +30,5 @@ export const claudeTool = {
|
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
export { claudeDriverConfigSchema, createClaudeDriver } from "./driver.js";
|
|
33
|
-
export { installClaudeIntegration, uninstallClaudeIntegration } from "./install.js";
|
|
33
|
+
export { claudeIntegrationConfigPath, installClaudeIntegration, uninstallClaudeIntegration } from "./install.js";
|
|
34
34
|
export { claudeAgentsJson, claudeEnv, claudeLaunchArgs, launchClaude } from "./launch.js";
|
package/dist/install.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ export type ClaudeInstallOwner = {
|
|
|
7
7
|
};
|
|
8
8
|
export type ClaudeInstallInput = {
|
|
9
9
|
gatewayUrl: string;
|
|
10
|
-
authToken?: string;
|
|
11
10
|
owner: ClaudeInstallOwner;
|
|
12
11
|
claudeConfigDir?: string;
|
|
13
12
|
};
|
|
@@ -16,6 +15,7 @@ export type ClaudeInstallResult = {
|
|
|
16
15
|
action: "installed" | "updated";
|
|
17
16
|
managedKeys: string[];
|
|
18
17
|
};
|
|
18
|
+
export declare function claudeIntegrationConfigPath(claudeConfigDir?: string): string;
|
|
19
19
|
export declare function installClaudeIntegration(input: ClaudeInstallInput): Promise<ClaudeInstallResult>;
|
|
20
20
|
export declare function uninstallClaudeIntegration(input: {
|
|
21
21
|
ownerId: string;
|
package/dist/install.js
CHANGED
|
@@ -6,9 +6,9 @@ import { SUBSCRIPTIONS } from "@velum-labs/routekit-registry";
|
|
|
6
6
|
import { acquireLifecycleLock, trimTrailingSlashes, writeFileAtomic } from "@velum-labs/routekit-runtime";
|
|
7
7
|
const MANAGED_ENV_KEYS = [
|
|
8
8
|
"ANTHROPIC_BASE_URL",
|
|
9
|
-
"ANTHROPIC_AUTH_TOKEN",
|
|
10
9
|
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"
|
|
11
10
|
];
|
|
11
|
+
const RETIRED_MANAGED_ENV_KEYS = ["ANTHROPIC_AUTH_TOKEN"];
|
|
12
12
|
function reached(boundary) {
|
|
13
13
|
// Deliberately not part of the package API: tests install a same-process
|
|
14
14
|
// throw hook to model termination immediately after an atomic boundary.
|
|
@@ -31,14 +31,16 @@ function defaultClaudeConfigDir() {
|
|
|
31
31
|
: registryPath;
|
|
32
32
|
return dirname(configPath);
|
|
33
33
|
}
|
|
34
|
+
export function claudeIntegrationConfigPath(claudeConfigDir) {
|
|
35
|
+
return join(claudeConfigDir ?? process.env.CLAUDE_CONFIG_DIR ?? defaultClaudeConfigDir(), "settings.json");
|
|
36
|
+
}
|
|
34
37
|
function paths(input) {
|
|
35
38
|
assertSafeOwnerId(input.ownerId);
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
defaultClaudeConfigDir();
|
|
39
|
+
const configPath = claudeIntegrationConfigPath(input.claudeConfigDir);
|
|
40
|
+
const configDirectory = dirname(configPath);
|
|
39
41
|
return {
|
|
40
42
|
configDirectory,
|
|
41
|
-
configPath
|
|
43
|
+
configPath,
|
|
42
44
|
manifestPath: join(configDirectory, `.${input.ownerId}-integration.json`),
|
|
43
45
|
lockPath: join(configDirectory, ".routekit-claude-integration.lock")
|
|
44
46
|
};
|
|
@@ -157,7 +159,6 @@ function serialize(value) {
|
|
|
157
159
|
function managedEnv(input) {
|
|
158
160
|
return {
|
|
159
161
|
ANTHROPIC_BASE_URL: trimTrailingSlashes(input.gatewayUrl),
|
|
160
|
-
ANTHROPIC_AUTH_TOKEN: input.authToken ?? "routekit",
|
|
161
162
|
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY: "1"
|
|
162
163
|
};
|
|
163
164
|
}
|
|
@@ -283,14 +284,20 @@ function recoverPending(manifest, configPath, manifestPath) {
|
|
|
283
284
|
assertRegularFileIfExists(manifestPath, "Claude ownership metadata");
|
|
284
285
|
rmSync(manifestPath, { force: true });
|
|
285
286
|
}
|
|
286
|
-
function
|
|
287
|
+
function removableManagedKeys(env, managedEnvValues, configPath) {
|
|
288
|
+
const removable = [];
|
|
287
289
|
for (const [key, expected] of Object.entries(managedEnvValues)) {
|
|
288
290
|
const accepted = Array.isArray(expected) ? expected : [expected];
|
|
289
|
-
if (
|
|
290
|
-
|
|
291
|
-
|
|
291
|
+
if (accepted.includes(String(env[key]))) {
|
|
292
|
+
removable.push(key);
|
|
293
|
+
continue;
|
|
292
294
|
}
|
|
295
|
+
if (RETIRED_MANAGED_ENV_KEYS.includes(key))
|
|
296
|
+
continue;
|
|
297
|
+
throw new Error(`your Claude settings changed RouteKit-managed env.${key} in ${configPath}; ` +
|
|
298
|
+
`remove or restore that value before rerunning the install command`);
|
|
293
299
|
}
|
|
300
|
+
return removable;
|
|
294
301
|
}
|
|
295
302
|
const CLAUDE_LOCK_TIMEOUT_MS = 5_000;
|
|
296
303
|
async function withConfigLock(resolved, operation) {
|
|
@@ -320,8 +327,31 @@ function migrateLegacyManifest(manifest, current, configPath, manifestPath) {
|
|
|
320
327
|
rmSync(manifestPath, { force: true });
|
|
321
328
|
return undefined;
|
|
322
329
|
}
|
|
323
|
-
|
|
324
|
-
|
|
330
|
+
const currentHash = current.hash;
|
|
331
|
+
if (currentHash === null) {
|
|
332
|
+
throw new Error(`RouteKit's legacy Claude ownership metadata (${manifestPath}) cannot ` +
|
|
333
|
+
"match missing settings; refusing to overwrite them");
|
|
334
|
+
}
|
|
335
|
+
let recognizedContent = manifest.installedContentHashes.includes(currentHash);
|
|
336
|
+
if (!recognizedContent) {
|
|
337
|
+
for (const key of RETIRED_MANAGED_ENV_KEYS) {
|
|
338
|
+
const accepted = manifest.managedEnvValues[key];
|
|
339
|
+
const value = env[key];
|
|
340
|
+
if (accepted === undefined || accepted.includes(String(value)))
|
|
341
|
+
continue;
|
|
342
|
+
for (const candidate of accepted) {
|
|
343
|
+
const candidateSettings = {
|
|
344
|
+
...settings,
|
|
345
|
+
env: { ...env, [key]: candidate }
|
|
346
|
+
};
|
|
347
|
+
if (manifest.installedContentHashes.includes(hash(serialize(candidateSettings)))) {
|
|
348
|
+
recognizedContent = true;
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (!recognizedContent) {
|
|
325
355
|
throw new Error(`RouteKit's legacy Claude ownership metadata (${manifestPath}) does not ` +
|
|
326
356
|
"match the current settings; refusing to overwrite them");
|
|
327
357
|
}
|
|
@@ -329,6 +359,8 @@ function migrateLegacyManifest(manifest, current, configPath, manifestPath) {
|
|
|
329
359
|
for (const [key, accepted] of Object.entries(manifest.managedEnvValues)) {
|
|
330
360
|
const value = env[key];
|
|
331
361
|
if (value === undefined || !accepted.includes(String(value))) {
|
|
362
|
+
if (RETIRED_MANAGED_ENV_KEYS.includes(key))
|
|
363
|
+
continue;
|
|
332
364
|
throw new Error(`RouteKit's legacy Claude ownership metadata (${manifestPath}) cannot ` +
|
|
333
365
|
`safely identify the current env.${key} value; refusing to overwrite settings`);
|
|
334
366
|
}
|
|
@@ -339,8 +371,9 @@ function migrateLegacyManifest(manifest, current, configPath, manifestPath) {
|
|
|
339
371
|
state: "installed",
|
|
340
372
|
ownerId: manifest.ownerId,
|
|
341
373
|
original: snapshot(manifest.originalContent, null),
|
|
342
|
-
exactRestoreEligible: manifest.exactRestoreEligible
|
|
343
|
-
|
|
374
|
+
exactRestoreEligible: manifest.exactRestoreEligible &&
|
|
375
|
+
manifest.installedContentHashes.includes(currentHash),
|
|
376
|
+
installedContentHash: currentHash,
|
|
344
377
|
managedEnvValues: selectedValues
|
|
345
378
|
};
|
|
346
379
|
writeManifest(manifestPath, migrated);
|
|
@@ -387,12 +420,11 @@ export async function installClaudeIntegration(input) {
|
|
|
387
420
|
}
|
|
388
421
|
}
|
|
389
422
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
for (const key of
|
|
423
|
+
const removableKeys = previousManifest === undefined
|
|
424
|
+
? []
|
|
425
|
+
: removableManagedKeys(env, previousManifest.managedEnvValues, configPath);
|
|
426
|
+
for (const key of removableKeys)
|
|
394
427
|
delete env[key];
|
|
395
|
-
}
|
|
396
428
|
Object.assign(env, nextManaged);
|
|
397
429
|
const nextSettings = { ...settings, env };
|
|
398
430
|
const nextContent = serialize(nextSettings);
|
|
@@ -15,10 +15,9 @@ const OWNER = {
|
|
|
15
15
|
uninstallCommand: "example uninstall claude",
|
|
16
16
|
startCommand: "example serve"
|
|
17
17
|
};
|
|
18
|
-
function install(configDirectory, gatewayUrl = "http://127.0.0.1:9999/",
|
|
18
|
+
function install(configDirectory, gatewayUrl = "http://127.0.0.1:9999/", _authToken) {
|
|
19
19
|
return installClaudeIntegration({
|
|
20
20
|
gatewayUrl,
|
|
21
|
-
...(authToken !== undefined ? { authToken } : {}),
|
|
22
21
|
owner: OWNER,
|
|
23
22
|
claudeConfigDir: configDirectory
|
|
24
23
|
});
|
|
@@ -32,21 +31,23 @@ test("Claude managed install updates and restores the exact original settings",
|
|
|
32
31
|
const installed = await install(configDirectory, "http://127.0.0.1:9999/", "gateway-secret");
|
|
33
32
|
assert.equal(installed.action, "installed");
|
|
34
33
|
assert.deepEqual(installed.managedKeys.sort(), [
|
|
35
|
-
"ANTHROPIC_AUTH_TOKEN",
|
|
36
34
|
"ANTHROPIC_BASE_URL",
|
|
37
35
|
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY"
|
|
38
36
|
]);
|
|
39
37
|
const settings = JSON.parse(readFileSync(configPath, "utf8"));
|
|
40
38
|
assert.deepEqual(settings.permissions, { allow: ["Bash(git status)"] });
|
|
41
39
|
assert.equal(settings.env.ANTHROPIC_BASE_URL, "http://127.0.0.1:9999");
|
|
42
|
-
assert.equal(settings.env
|
|
40
|
+
assert.equal("ANTHROPIC_AUTH_TOKEN" in settings.env, false);
|
|
43
41
|
assert.equal(statSync(configPath).mode & 0o777, 0o600);
|
|
44
42
|
const manifestPath = join(configDirectory, `.${OWNER.id}-integration.json`);
|
|
43
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
45
44
|
assert.deepEqual({
|
|
46
|
-
version:
|
|
47
|
-
state:
|
|
45
|
+
version: manifest.version,
|
|
46
|
+
state: manifest.state,
|
|
48
47
|
mode: statSync(manifestPath).mode & 0o777
|
|
49
48
|
}, { version: 2, state: "installed", mode: 0o600 });
|
|
49
|
+
assert.equal("ANTHROPIC_AUTH_TOKEN" in manifest.managedEnvValues, false);
|
|
50
|
+
assert.equal(readFileSync(manifestPath, "utf8").includes("gateway-secret"), false);
|
|
50
51
|
assert.equal((await install(configDirectory, "http://127.0.0.1:8888", "updated-secret")).action, "updated");
|
|
51
52
|
assert.equal(JSON.parse(readFileSync(configPath, "utf8")).env.ANTHROPIC_BASE_URL, "http://127.0.0.1:8888");
|
|
52
53
|
assert.equal((await uninstallClaudeIntegration({
|
|
@@ -324,6 +325,71 @@ test("install never persists or takes ownership of ANTHROPIC_MODEL", async () =>
|
|
|
324
325
|
rmSync(configDirectory, { recursive: true, force: true });
|
|
325
326
|
}
|
|
326
327
|
});
|
|
328
|
+
test("updating a v2 install removes an owned token without persisting its replacement", async () => {
|
|
329
|
+
const configDirectory = mkdtempSync(join(tmpdir(), "routekit-claude-v2-token-"));
|
|
330
|
+
const configPath = join(configDirectory, "settings.json");
|
|
331
|
+
const manifestPath = join(configDirectory, `.${OWNER.id}-integration.json`);
|
|
332
|
+
const original = '{"theme":"light"}\n';
|
|
333
|
+
const installed = `${JSON.stringify({
|
|
334
|
+
theme: "light",
|
|
335
|
+
env: {
|
|
336
|
+
ANTHROPIC_BASE_URL: "http://127.0.0.1:7000",
|
|
337
|
+
ANTHROPIC_AUTH_TOKEN: "old-secret",
|
|
338
|
+
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY: "1"
|
|
339
|
+
}
|
|
340
|
+
}, null, 2)}\n`;
|
|
341
|
+
writeFileSync(configPath, installed);
|
|
342
|
+
writeFileSync(manifestPath, `${JSON.stringify({
|
|
343
|
+
version: 2,
|
|
344
|
+
state: "installed",
|
|
345
|
+
ownerId: OWNER.id,
|
|
346
|
+
original: {
|
|
347
|
+
content: original,
|
|
348
|
+
mode: 0o644,
|
|
349
|
+
hash: createHash("sha256").update(original).digest("hex")
|
|
350
|
+
},
|
|
351
|
+
exactRestoreEligible: true,
|
|
352
|
+
installedContentHash: createHash("sha256").update(installed).digest("hex"),
|
|
353
|
+
managedEnvValues: {
|
|
354
|
+
ANTHROPIC_BASE_URL: "http://127.0.0.1:7000",
|
|
355
|
+
ANTHROPIC_AUTH_TOKEN: "old-secret",
|
|
356
|
+
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY: "1"
|
|
357
|
+
}
|
|
358
|
+
}, null, 2)}\n`);
|
|
359
|
+
try {
|
|
360
|
+
await install(configDirectory, "http://127.0.0.1:7001", "new-secret");
|
|
361
|
+
const settings = JSON.parse(readFileSync(configPath, "utf8"));
|
|
362
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
363
|
+
assert.equal("ANTHROPIC_AUTH_TOKEN" in settings.env, false);
|
|
364
|
+
assert.equal("ANTHROPIC_AUTH_TOKEN" in manifest.managedEnvValues, false);
|
|
365
|
+
assert.equal(readFileSync(manifestPath, "utf8").includes("old-secret"), false);
|
|
366
|
+
assert.equal(readFileSync(manifestPath, "utf8").includes("new-secret"), false);
|
|
367
|
+
}
|
|
368
|
+
finally {
|
|
369
|
+
rmSync(configDirectory, { recursive: true, force: true });
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
test("updating a v2 install preserves a user-edited token", async () => {
|
|
373
|
+
const configDirectory = mkdtempSync(join(tmpdir(), "routekit-claude-v2-user-token-"));
|
|
374
|
+
const configPath = join(configDirectory, "settings.json");
|
|
375
|
+
try {
|
|
376
|
+
await install(configDirectory, "http://127.0.0.1:7000");
|
|
377
|
+
const manifestPath = join(configDirectory, `.${OWNER.id}-integration.json`);
|
|
378
|
+
const settings = JSON.parse(readFileSync(configPath, "utf8"));
|
|
379
|
+
settings.env.ANTHROPIC_AUTH_TOKEN = "user-secret";
|
|
380
|
+
writeFileSync(configPath, `${JSON.stringify(settings, null, 2)}\n`);
|
|
381
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
382
|
+
manifest.managedEnvValues.ANTHROPIC_AUTH_TOKEN = "old-secret";
|
|
383
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
384
|
+
await install(configDirectory, "http://127.0.0.1:7001", "new-secret");
|
|
385
|
+
assert.equal(JSON.parse(readFileSync(configPath, "utf8")).env.ANTHROPIC_AUTH_TOKEN, "user-secret");
|
|
386
|
+
assert.equal("ANTHROPIC_AUTH_TOKEN" in
|
|
387
|
+
JSON.parse(readFileSync(manifestPath, "utf8")).managedEnvValues, false);
|
|
388
|
+
}
|
|
389
|
+
finally {
|
|
390
|
+
rmSync(configDirectory, { recursive: true, force: true });
|
|
391
|
+
}
|
|
392
|
+
});
|
|
327
393
|
test("updating a legacy install removes its formerly managed ANTHROPIC_MODEL", async () => {
|
|
328
394
|
const configDirectory = mkdtempSync(join(tmpdir(), "routekit-claude-legacy-model-"));
|
|
329
395
|
const configPath = join(configDirectory, "settings.json");
|
|
@@ -414,12 +480,14 @@ test("install migrates interrupted v1 updates before and after settings", async
|
|
|
414
480
|
assert.equal(result.action, "updated");
|
|
415
481
|
const settings = JSON.parse(readFileSync(configPath, "utf8"));
|
|
416
482
|
assert.equal(settings.env.ANTHROPIC_BASE_URL, "http://127.0.0.1:7002");
|
|
417
|
-
assert.equal(settings.env
|
|
483
|
+
assert.equal("ANTHROPIC_AUTH_TOKEN" in settings.env, false);
|
|
418
484
|
assert.equal("ANTHROPIC_MODEL" in settings.env, false);
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
485
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
486
|
+
assert.deepEqual({ version: manifest.version, state: manifest.state }, { version: 2, state: "installed" });
|
|
487
|
+
assert.equal("ANTHROPIC_AUTH_TOKEN" in manifest.managedEnvValues, false);
|
|
488
|
+
assert.equal(readFileSync(manifestPath, "utf8").includes("final-token"), false);
|
|
489
|
+
assert.equal(readFileSync(manifestPath, "utf8").includes("before-token"), false);
|
|
490
|
+
assert.equal(readFileSync(manifestPath, "utf8").includes("after-token"), false);
|
|
423
491
|
await uninstallClaudeIntegration({
|
|
424
492
|
ownerId: OWNER.id,
|
|
425
493
|
claudeConfigDir: configDirectory
|
package/dist/test/launch.test.js
CHANGED
|
@@ -35,7 +35,10 @@ test("claudeAgentsJson serializes generic profiles", () => {
|
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
test("Claude launcher projects claude-code models to native picker ids", () => {
|
|
38
|
-
assert.deepEqual(claudeLaunchArgs(context([], [], "claude-code/claude-sonnet-4-6")), [
|
|
38
|
+
assert.deepEqual(claudeLaunchArgs(context([], [], "claude-code/claude-sonnet-4-6")), [
|
|
39
|
+
"--model",
|
|
40
|
+
"claude-sonnet-4-6"
|
|
41
|
+
]);
|
|
39
42
|
assert.deepEqual(JSON.parse(claudeAgentsJson([
|
|
40
43
|
{
|
|
41
44
|
id: "native",
|
|
@@ -77,22 +80,17 @@ test("Claude launcher forwards an explicit isolated config directory", () => {
|
|
|
77
80
|
});
|
|
78
81
|
test("claudeLaunchArgs adds profiles unless the user supplied agents", () => {
|
|
79
82
|
const args = claudeLaunchArgs(context(["--verbose"]));
|
|
80
|
-
assert.deepEqual(args.slice(0, 4), [
|
|
81
|
-
"--model",
|
|
82
|
-
"claude-opaque-model",
|
|
83
|
-
"--verbose",
|
|
84
|
-
"--agents"
|
|
85
|
-
]);
|
|
83
|
+
assert.deepEqual(args.slice(0, 4), ["--model", "claude-opaque-model", "--verbose", "--agents"]);
|
|
86
84
|
assert.deepEqual(claudeLaunchArgs(context(["--agents={}"])), [
|
|
87
85
|
"--model",
|
|
88
86
|
"claude-opaque-model",
|
|
89
87
|
"--agents={}"
|
|
90
88
|
]);
|
|
91
|
-
assert.deepEqual(claudeLaunchArgs(context([], [])), [
|
|
89
|
+
assert.deepEqual(claudeLaunchArgs(context([], [])), ["--model", "claude-opaque-model"]);
|
|
90
|
+
assert.deepEqual(claudeLaunchArgs(context(["--model", "claude-user-selected"], [])), [
|
|
92
91
|
"--model",
|
|
93
|
-
"claude-
|
|
92
|
+
"claude-user-selected"
|
|
94
93
|
]);
|
|
95
|
-
assert.deepEqual(claudeLaunchArgs(context(["--model", "claude-user-selected"], [])), ["--model", "claude-user-selected"]);
|
|
96
94
|
});
|
|
97
95
|
test("Claude launcher projects validated effort onto the picker model id", () => {
|
|
98
96
|
const withEffort = {
|
|
@@ -102,10 +100,7 @@ test("Claude launcher projects validated effort onto the picker model id", () =>
|
|
|
102
100
|
reasoning: { mode: "effort", effort: "high" }
|
|
103
101
|
}
|
|
104
102
|
};
|
|
105
|
-
assert.deepEqual(claudeLaunchArgs(withEffort), [
|
|
106
|
-
"--model",
|
|
107
|
-
"claude-sonnet-4-6:high"
|
|
108
|
-
]);
|
|
103
|
+
assert.deepEqual(claudeLaunchArgs(withEffort), ["--model", "claude-sonnet-4-6:high"]);
|
|
109
104
|
const crossProvider = {
|
|
110
105
|
...context([], [], "codex/gpt-5.5"),
|
|
111
106
|
spec: {
|
|
@@ -113,10 +108,7 @@ test("Claude launcher projects validated effort onto the picker model id", () =>
|
|
|
113
108
|
reasoning: { mode: "effort", effort: "deep" }
|
|
114
109
|
}
|
|
115
110
|
};
|
|
116
|
-
assert.deepEqual(claudeLaunchArgs(crossProvider), [
|
|
117
|
-
"--model",
|
|
118
|
-
"claude-codex/gpt-5.5:deep"
|
|
119
|
-
]);
|
|
111
|
+
assert.deepEqual(claudeLaunchArgs(crossProvider), ["--model", "claude-codex/gpt-5.5:deep"]);
|
|
120
112
|
assert.deepEqual(claudeLaunchArgs({
|
|
121
113
|
...withEffort,
|
|
122
114
|
spec: {
|
|
@@ -125,3 +117,12 @@ test("Claude launcher projects validated effort onto the picker model id", () =>
|
|
|
125
117
|
}
|
|
126
118
|
}), ["--model", "claude-user-selected"]);
|
|
127
119
|
});
|
|
120
|
+
test("Claude launches keep native session flags under native-client control", () => {
|
|
121
|
+
assert.deepEqual(claudeLaunchArgs(context(["--continue", "--resume", "native-id"], [])), [
|
|
122
|
+
"--model",
|
|
123
|
+
"claude-opaque-model",
|
|
124
|
+
"--continue",
|
|
125
|
+
"--resume",
|
|
126
|
+
"native-id"
|
|
127
|
+
]);
|
|
128
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velum-labs/routekit-tool-claude",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.17.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/velum-labs/routekit.git",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@anthropic-ai/claude-agent-sdk": "0.3.198",
|
|
30
30
|
"zod": "4.4.3",
|
|
31
|
-
"@velum-labs/routekit-contracts": "0.
|
|
32
|
-
"@velum-labs/routekit-harness-core": "0.
|
|
33
|
-
"@velum-labs/routekit-registry": "0.
|
|
34
|
-
"@velum-labs/routekit-runtime": "0.
|
|
35
|
-
"@velum-labs/routekit-tools": "0.
|
|
31
|
+
"@velum-labs/routekit-contracts": "0.17.0",
|
|
32
|
+
"@velum-labs/routekit-harness-core": "0.17.0",
|
|
33
|
+
"@velum-labs/routekit-registry": "0.17.0",
|
|
34
|
+
"@velum-labs/routekit-runtime": "0.17.0",
|
|
35
|
+
"@velum-labs/routekit-tools": "0.17.0"
|
|
36
36
|
},
|
|
37
37
|
"keywords": [
|
|
38
38
|
"llm",
|