@cabane/companion 0.6.151 → 0.6.153
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/dist/cli.js +51 -8
- package/dist/runtime.js +51 -8
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1892,7 +1892,8 @@ var init_turn_request = __esm({
|
|
|
1892
1892
|
type: z8.literal("stdio").optional(),
|
|
1893
1893
|
command: z8.string(),
|
|
1894
1894
|
args: z8.array(z8.string()).optional(),
|
|
1895
|
-
env: z8.record(z8.string(), z8.string()).optional()
|
|
1895
|
+
env: z8.record(z8.string(), z8.string()).optional(),
|
|
1896
|
+
envFromEnv: z8.record(z8.string(), z8.string()).optional()
|
|
1896
1897
|
}),
|
|
1897
1898
|
z8.object({
|
|
1898
1899
|
type: z8.literal("http"),
|
|
@@ -2439,6 +2440,22 @@ function headersResolvedFrom(server, secretEnv) {
|
|
|
2439
2440
|
if (!server.headers && Object.keys(resolved).length === 0) return void 0;
|
|
2440
2441
|
return { ...server.headers, ...resolved };
|
|
2441
2442
|
}
|
|
2443
|
+
function envAsEnvReferences(server) {
|
|
2444
|
+
const refs = Object.entries(server.envFromEnv ?? {}).map(
|
|
2445
|
+
([variable, envName]) => [variable, `\${${envName}}`]
|
|
2446
|
+
);
|
|
2447
|
+
if (!server.env && refs.length === 0) return void 0;
|
|
2448
|
+
return { ...server.env, ...Object.fromEntries(refs) };
|
|
2449
|
+
}
|
|
2450
|
+
function envResolvedFrom(server, secretEnv) {
|
|
2451
|
+
const resolved = {};
|
|
2452
|
+
for (const [variable, envName] of Object.entries(server.envFromEnv ?? {})) {
|
|
2453
|
+
const value = secretEnv?.[envName];
|
|
2454
|
+
if (value !== void 0) resolved[variable] = value;
|
|
2455
|
+
}
|
|
2456
|
+
if (!server.env && Object.keys(resolved).length === 0) return void 0;
|
|
2457
|
+
return { ...server.env, ...resolved };
|
|
2458
|
+
}
|
|
2442
2459
|
var init_mcp_secret_env = __esm({
|
|
2443
2460
|
"packages/agent-runtime/src/mcp-secret-env.ts"() {
|
|
2444
2461
|
"use strict";
|
|
@@ -2600,7 +2617,9 @@ function buildClaudeCodeOptions(req, augment) {
|
|
|
2600
2617
|
const headers = headersAsEnvReferences(server);
|
|
2601
2618
|
userServers[name] = { ...rest, ...headers ? { headers } : {} };
|
|
2602
2619
|
} else {
|
|
2603
|
-
|
|
2620
|
+
const { envFromEnv: _refs, env: _env, ...rest } = server;
|
|
2621
|
+
const env = envAsEnvReferences(server);
|
|
2622
|
+
userServers[name] = { ...rest, ...env ? { env } : {} };
|
|
2604
2623
|
}
|
|
2605
2624
|
}
|
|
2606
2625
|
const mcpServers = {
|
|
@@ -2690,7 +2709,12 @@ function buildClaudeCodeOptions(req, augment) {
|
|
|
2690
2709
|
if (useCodingPreset) {
|
|
2691
2710
|
options = {
|
|
2692
2711
|
...base,
|
|
2693
|
-
systemPrompt: {
|
|
2712
|
+
systemPrompt: {
|
|
2713
|
+
type: "preset",
|
|
2714
|
+
preset: "claude_code",
|
|
2715
|
+
append: req.systemPrompt,
|
|
2716
|
+
snapshot: false
|
|
2717
|
+
},
|
|
2694
2718
|
settingSources: ["project"],
|
|
2695
2719
|
allowedTools,
|
|
2696
2720
|
disallowedTools,
|
|
@@ -2699,7 +2723,7 @@ function buildClaudeCodeOptions(req, augment) {
|
|
|
2699
2723
|
} else {
|
|
2700
2724
|
options = {
|
|
2701
2725
|
...base,
|
|
2702
|
-
systemPrompt: req.systemPrompt,
|
|
2726
|
+
systemPrompt: { type: "custom", prompt: req.systemPrompt, snapshot: false },
|
|
2703
2727
|
allowedTools,
|
|
2704
2728
|
disallowedTools,
|
|
2705
2729
|
permissionMode: "bypassPermissions",
|
|
@@ -4101,8 +4125,10 @@ function buildRunSpec(req, resumeSessionId) {
|
|
|
4101
4125
|
sendClientMessageId: resumeSessionId == null,
|
|
4102
4126
|
...dialect.agent ? { agent: dialect.agent } : {},
|
|
4103
4127
|
mcp: buildMcp(req),
|
|
4128
|
+
// Every server this turn installs with a credential resolved into it: a remote one's
|
|
4129
|
+
// `headersFromEnv`, a stdio one's `envFromEnv`. None may take an operator-configured name.
|
|
4104
4130
|
credentialServers: Object.entries(req.local.mcpServers ?? {}).filter(
|
|
4105
|
-
([, server]) => "url" in server
|
|
4131
|
+
([, server]) => "url" in server ? Object.keys(server.headersFromEnv ?? {}).length > 0 : Object.keys(server.envFromEnv ?? {}).length > 0
|
|
4106
4132
|
).map(([name]) => name)
|
|
4107
4133
|
};
|
|
4108
4134
|
}
|
|
@@ -4131,10 +4157,11 @@ function buildMcp(req) {
|
|
|
4131
4157
|
};
|
|
4132
4158
|
} else if ("command" in server) {
|
|
4133
4159
|
const command = [server.command, ...server.args ?? []];
|
|
4160
|
+
const environment = envResolvedFrom(server, req.local.secretEnv);
|
|
4134
4161
|
mcp[name] = {
|
|
4135
4162
|
type: "local",
|
|
4136
4163
|
command,
|
|
4137
|
-
...
|
|
4164
|
+
...environment ? { environment } : {},
|
|
4138
4165
|
enabled: true
|
|
4139
4166
|
};
|
|
4140
4167
|
}
|
|
@@ -5421,9 +5448,20 @@ function buildRunSpec2(req, resumeThreadId, instructionsFile = null, threadPromp
|
|
|
5421
5448
|
promptRidesInput,
|
|
5422
5449
|
promptFingerprint,
|
|
5423
5450
|
config: buildConfig(req, baseInstructionsFile),
|
|
5424
|
-
secretEnv:
|
|
5451
|
+
secretEnv: codexSecretEnv(req)
|
|
5425
5452
|
};
|
|
5426
5453
|
}
|
|
5454
|
+
function codexSecretEnv(req) {
|
|
5455
|
+
const env = { ...req.local.secretEnv };
|
|
5456
|
+
for (const server of Object.values(req.local.mcpServers ?? {})) {
|
|
5457
|
+
if ("url" in server) continue;
|
|
5458
|
+
for (const [variable, envName] of Object.entries(server.envFromEnv ?? {})) {
|
|
5459
|
+
const value = req.local.secretEnv?.[envName];
|
|
5460
|
+
if (value !== void 0) env[variable] = value;
|
|
5461
|
+
}
|
|
5462
|
+
}
|
|
5463
|
+
return Object.keys(env).length > 0 ? env : null;
|
|
5464
|
+
}
|
|
5427
5465
|
function buildInput(req, promptRidesInput) {
|
|
5428
5466
|
const userText = req.content.filter((b) => b.type === "text").map((b) => b.text).join("\n\n");
|
|
5429
5467
|
const body = userText.trim().length > 0 ? userText : req.prompt;
|
|
@@ -5452,10 +5490,12 @@ function buildConfig(req, baseInstructionsFile) {
|
|
|
5452
5490
|
default_tools_approval_mode: "approve"
|
|
5453
5491
|
};
|
|
5454
5492
|
} else if ("command" in server) {
|
|
5493
|
+
const forwarded = Object.keys(server.envFromEnv ?? {}).sort();
|
|
5455
5494
|
mcp_servers[name] = {
|
|
5456
5495
|
command: server.command,
|
|
5457
5496
|
...server.args ? { args: server.args } : {},
|
|
5458
5497
|
...server.env ? { env: server.env } : {},
|
|
5498
|
+
...forwarded.length > 0 ? { env_vars: forwarded } : {},
|
|
5459
5499
|
default_tools_approval_mode: "approve"
|
|
5460
5500
|
};
|
|
5461
5501
|
}
|
|
@@ -7412,7 +7452,10 @@ var init_run_config = __esm({
|
|
|
7412
7452
|
type: z15.literal("stdio").optional(),
|
|
7413
7453
|
command: z15.string().min(1),
|
|
7414
7454
|
args: z15.array(z15.string()).optional(),
|
|
7415
|
-
env: z15.record(z15.string(), z15.string()).optional()
|
|
7455
|
+
env: z15.record(z15.string(), z15.string()).optional(),
|
|
7456
|
+
// Variable → the name of a `secretEnv` entry holding its value. Set by the server on a
|
|
7457
|
+
// room's shared browser, whose connect URL is a credential.
|
|
7458
|
+
envFromEnv: z15.record(z15.string(), z15.string()).optional()
|
|
7416
7459
|
});
|
|
7417
7460
|
mcpHttpServerSchema = z15.object({
|
|
7418
7461
|
type: z15.literal("http"),
|
package/dist/runtime.js
CHANGED
|
@@ -3355,7 +3355,8 @@ var resolvedMcpServerSchema = z8.union([
|
|
|
3355
3355
|
type: z8.literal("stdio").optional(),
|
|
3356
3356
|
command: z8.string(),
|
|
3357
3357
|
args: z8.array(z8.string()).optional(),
|
|
3358
|
-
env: z8.record(z8.string(), z8.string()).optional()
|
|
3358
|
+
env: z8.record(z8.string(), z8.string()).optional(),
|
|
3359
|
+
envFromEnv: z8.record(z8.string(), z8.string()).optional()
|
|
3359
3360
|
}),
|
|
3360
3361
|
z8.object({
|
|
3361
3362
|
type: z8.literal("http"),
|
|
@@ -3857,6 +3858,22 @@ function headersResolvedFrom(server, secretEnv) {
|
|
|
3857
3858
|
if (!server.headers && Object.keys(resolved).length === 0) return void 0;
|
|
3858
3859
|
return { ...server.headers, ...resolved };
|
|
3859
3860
|
}
|
|
3861
|
+
function envAsEnvReferences(server) {
|
|
3862
|
+
const refs = Object.entries(server.envFromEnv ?? {}).map(
|
|
3863
|
+
([variable, envName]) => [variable, `\${${envName}}`]
|
|
3864
|
+
);
|
|
3865
|
+
if (!server.env && refs.length === 0) return void 0;
|
|
3866
|
+
return { ...server.env, ...Object.fromEntries(refs) };
|
|
3867
|
+
}
|
|
3868
|
+
function envResolvedFrom(server, secretEnv) {
|
|
3869
|
+
const resolved = {};
|
|
3870
|
+
for (const [variable, envName] of Object.entries(server.envFromEnv ?? {})) {
|
|
3871
|
+
const value = secretEnv?.[envName];
|
|
3872
|
+
if (value !== void 0) resolved[variable] = value;
|
|
3873
|
+
}
|
|
3874
|
+
if (!server.env && Object.keys(resolved).length === 0) return void 0;
|
|
3875
|
+
return { ...server.env, ...resolved };
|
|
3876
|
+
}
|
|
3860
3877
|
|
|
3861
3878
|
// packages/agent-runtime/src/claude-code/policy.ts
|
|
3862
3879
|
import { z as z10 } from "zod";
|
|
@@ -3998,7 +4015,9 @@ function buildClaudeCodeOptions(req, augment) {
|
|
|
3998
4015
|
const headers = headersAsEnvReferences(server);
|
|
3999
4016
|
userServers[name] = { ...rest, ...headers ? { headers } : {} };
|
|
4000
4017
|
} else {
|
|
4001
|
-
|
|
4018
|
+
const { envFromEnv: _refs, env: _env, ...rest } = server;
|
|
4019
|
+
const env = envAsEnvReferences(server);
|
|
4020
|
+
userServers[name] = { ...rest, ...env ? { env } : {} };
|
|
4002
4021
|
}
|
|
4003
4022
|
}
|
|
4004
4023
|
const mcpServers = {
|
|
@@ -4088,7 +4107,12 @@ function buildClaudeCodeOptions(req, augment) {
|
|
|
4088
4107
|
if (useCodingPreset) {
|
|
4089
4108
|
options = {
|
|
4090
4109
|
...base,
|
|
4091
|
-
systemPrompt: {
|
|
4110
|
+
systemPrompt: {
|
|
4111
|
+
type: "preset",
|
|
4112
|
+
preset: "claude_code",
|
|
4113
|
+
append: req.systemPrompt,
|
|
4114
|
+
snapshot: false
|
|
4115
|
+
},
|
|
4092
4116
|
settingSources: ["project"],
|
|
4093
4117
|
allowedTools,
|
|
4094
4118
|
disallowedTools,
|
|
@@ -4097,7 +4121,7 @@ function buildClaudeCodeOptions(req, augment) {
|
|
|
4097
4121
|
} else {
|
|
4098
4122
|
options = {
|
|
4099
4123
|
...base,
|
|
4100
|
-
systemPrompt: req.systemPrompt,
|
|
4124
|
+
systemPrompt: { type: "custom", prompt: req.systemPrompt, snapshot: false },
|
|
4101
4125
|
allowedTools,
|
|
4102
4126
|
disallowedTools,
|
|
4103
4127
|
permissionMode: "bypassPermissions",
|
|
@@ -5409,8 +5433,10 @@ function buildRunSpec(req, resumeSessionId) {
|
|
|
5409
5433
|
sendClientMessageId: resumeSessionId == null,
|
|
5410
5434
|
...dialect.agent ? { agent: dialect.agent } : {},
|
|
5411
5435
|
mcp: buildMcp(req),
|
|
5436
|
+
// Every server this turn installs with a credential resolved into it: a remote one's
|
|
5437
|
+
// `headersFromEnv`, a stdio one's `envFromEnv`. None may take an operator-configured name.
|
|
5412
5438
|
credentialServers: Object.entries(req.local.mcpServers ?? {}).filter(
|
|
5413
|
-
([, server]) => "url" in server
|
|
5439
|
+
([, server]) => "url" in server ? Object.keys(server.headersFromEnv ?? {}).length > 0 : Object.keys(server.envFromEnv ?? {}).length > 0
|
|
5414
5440
|
).map(([name]) => name)
|
|
5415
5441
|
};
|
|
5416
5442
|
}
|
|
@@ -5439,10 +5465,11 @@ function buildMcp(req) {
|
|
|
5439
5465
|
};
|
|
5440
5466
|
} else if ("command" in server) {
|
|
5441
5467
|
const command = [server.command, ...server.args ?? []];
|
|
5468
|
+
const environment = envResolvedFrom(server, req.local.secretEnv);
|
|
5442
5469
|
mcp[name] = {
|
|
5443
5470
|
type: "local",
|
|
5444
5471
|
command,
|
|
5445
|
-
...
|
|
5472
|
+
...environment ? { environment } : {},
|
|
5446
5473
|
enabled: true
|
|
5447
5474
|
};
|
|
5448
5475
|
}
|
|
@@ -6651,9 +6678,20 @@ function buildRunSpec2(req, resumeThreadId, instructionsFile = null, threadPromp
|
|
|
6651
6678
|
promptRidesInput,
|
|
6652
6679
|
promptFingerprint,
|
|
6653
6680
|
config: buildConfig(req, baseInstructionsFile),
|
|
6654
|
-
secretEnv:
|
|
6681
|
+
secretEnv: codexSecretEnv(req)
|
|
6655
6682
|
};
|
|
6656
6683
|
}
|
|
6684
|
+
function codexSecretEnv(req) {
|
|
6685
|
+
const env = { ...req.local.secretEnv };
|
|
6686
|
+
for (const server of Object.values(req.local.mcpServers ?? {})) {
|
|
6687
|
+
if ("url" in server) continue;
|
|
6688
|
+
for (const [variable, envName] of Object.entries(server.envFromEnv ?? {})) {
|
|
6689
|
+
const value = req.local.secretEnv?.[envName];
|
|
6690
|
+
if (value !== void 0) env[variable] = value;
|
|
6691
|
+
}
|
|
6692
|
+
}
|
|
6693
|
+
return Object.keys(env).length > 0 ? env : null;
|
|
6694
|
+
}
|
|
6657
6695
|
function buildInput(req, promptRidesInput) {
|
|
6658
6696
|
const userText = req.content.filter((b) => b.type === "text").map((b) => b.text).join("\n\n");
|
|
6659
6697
|
const body = userText.trim().length > 0 ? userText : req.prompt;
|
|
@@ -6682,10 +6720,12 @@ function buildConfig(req, baseInstructionsFile) {
|
|
|
6682
6720
|
default_tools_approval_mode: "approve"
|
|
6683
6721
|
};
|
|
6684
6722
|
} else if ("command" in server) {
|
|
6723
|
+
const forwarded = Object.keys(server.envFromEnv ?? {}).sort();
|
|
6685
6724
|
mcp_servers[name] = {
|
|
6686
6725
|
command: server.command,
|
|
6687
6726
|
...server.args ? { args: server.args } : {},
|
|
6688
6727
|
...server.env ? { env: server.env } : {},
|
|
6728
|
+
...forwarded.length > 0 ? { env_vars: forwarded } : {},
|
|
6689
6729
|
default_tools_approval_mode: "approve"
|
|
6690
6730
|
};
|
|
6691
6731
|
}
|
|
@@ -8519,7 +8559,10 @@ var mcpStdioServerSchema = z15.object({
|
|
|
8519
8559
|
type: z15.literal("stdio").optional(),
|
|
8520
8560
|
command: z15.string().min(1),
|
|
8521
8561
|
args: z15.array(z15.string()).optional(),
|
|
8522
|
-
env: z15.record(z15.string(), z15.string()).optional()
|
|
8562
|
+
env: z15.record(z15.string(), z15.string()).optional(),
|
|
8563
|
+
// Variable → the name of a `secretEnv` entry holding its value. Set by the server on a
|
|
8564
|
+
// room's shared browser, whose connect URL is a credential.
|
|
8565
|
+
envFromEnv: z15.record(z15.string(), z15.string()).optional()
|
|
8523
8566
|
});
|
|
8524
8567
|
var mcpHttpServerSchema = z15.object({
|
|
8525
8568
|
type: z15.literal("http"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cabane/companion",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.153",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Cabane Companion (headless): connect a coding agent on your machine to your Cabane workspace as a responder — drive work against your own codebase, files, and MCP servers without putting any of it in Cabane.",
|
|
6
6
|
"license": "UNLICENSED",
|