@cabane/companion 0.6.152 → 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 +44 -6
- package/dist/runtime.js +44 -6
- 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 = {
|
|
@@ -4106,8 +4125,10 @@ function buildRunSpec(req, resumeSessionId) {
|
|
|
4106
4125
|
sendClientMessageId: resumeSessionId == null,
|
|
4107
4126
|
...dialect.agent ? { agent: dialect.agent } : {},
|
|
4108
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.
|
|
4109
4130
|
credentialServers: Object.entries(req.local.mcpServers ?? {}).filter(
|
|
4110
|
-
([, server]) => "url" in server
|
|
4131
|
+
([, server]) => "url" in server ? Object.keys(server.headersFromEnv ?? {}).length > 0 : Object.keys(server.envFromEnv ?? {}).length > 0
|
|
4111
4132
|
).map(([name]) => name)
|
|
4112
4133
|
};
|
|
4113
4134
|
}
|
|
@@ -4136,10 +4157,11 @@ function buildMcp(req) {
|
|
|
4136
4157
|
};
|
|
4137
4158
|
} else if ("command" in server) {
|
|
4138
4159
|
const command = [server.command, ...server.args ?? []];
|
|
4160
|
+
const environment = envResolvedFrom(server, req.local.secretEnv);
|
|
4139
4161
|
mcp[name] = {
|
|
4140
4162
|
type: "local",
|
|
4141
4163
|
command,
|
|
4142
|
-
...
|
|
4164
|
+
...environment ? { environment } : {},
|
|
4143
4165
|
enabled: true
|
|
4144
4166
|
};
|
|
4145
4167
|
}
|
|
@@ -5426,9 +5448,20 @@ function buildRunSpec2(req, resumeThreadId, instructionsFile = null, threadPromp
|
|
|
5426
5448
|
promptRidesInput,
|
|
5427
5449
|
promptFingerprint,
|
|
5428
5450
|
config: buildConfig(req, baseInstructionsFile),
|
|
5429
|
-
secretEnv:
|
|
5451
|
+
secretEnv: codexSecretEnv(req)
|
|
5430
5452
|
};
|
|
5431
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
|
+
}
|
|
5432
5465
|
function buildInput(req, promptRidesInput) {
|
|
5433
5466
|
const userText = req.content.filter((b) => b.type === "text").map((b) => b.text).join("\n\n");
|
|
5434
5467
|
const body = userText.trim().length > 0 ? userText : req.prompt;
|
|
@@ -5457,10 +5490,12 @@ function buildConfig(req, baseInstructionsFile) {
|
|
|
5457
5490
|
default_tools_approval_mode: "approve"
|
|
5458
5491
|
};
|
|
5459
5492
|
} else if ("command" in server) {
|
|
5493
|
+
const forwarded = Object.keys(server.envFromEnv ?? {}).sort();
|
|
5460
5494
|
mcp_servers[name] = {
|
|
5461
5495
|
command: server.command,
|
|
5462
5496
|
...server.args ? { args: server.args } : {},
|
|
5463
5497
|
...server.env ? { env: server.env } : {},
|
|
5498
|
+
...forwarded.length > 0 ? { env_vars: forwarded } : {},
|
|
5464
5499
|
default_tools_approval_mode: "approve"
|
|
5465
5500
|
};
|
|
5466
5501
|
}
|
|
@@ -7417,7 +7452,10 @@ var init_run_config = __esm({
|
|
|
7417
7452
|
type: z15.literal("stdio").optional(),
|
|
7418
7453
|
command: z15.string().min(1),
|
|
7419
7454
|
args: z15.array(z15.string()).optional(),
|
|
7420
|
-
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()
|
|
7421
7459
|
});
|
|
7422
7460
|
mcpHttpServerSchema = z15.object({
|
|
7423
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 = {
|
|
@@ -5414,8 +5433,10 @@ function buildRunSpec(req, resumeSessionId) {
|
|
|
5414
5433
|
sendClientMessageId: resumeSessionId == null,
|
|
5415
5434
|
...dialect.agent ? { agent: dialect.agent } : {},
|
|
5416
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.
|
|
5417
5438
|
credentialServers: Object.entries(req.local.mcpServers ?? {}).filter(
|
|
5418
|
-
([, server]) => "url" in server
|
|
5439
|
+
([, server]) => "url" in server ? Object.keys(server.headersFromEnv ?? {}).length > 0 : Object.keys(server.envFromEnv ?? {}).length > 0
|
|
5419
5440
|
).map(([name]) => name)
|
|
5420
5441
|
};
|
|
5421
5442
|
}
|
|
@@ -5444,10 +5465,11 @@ function buildMcp(req) {
|
|
|
5444
5465
|
};
|
|
5445
5466
|
} else if ("command" in server) {
|
|
5446
5467
|
const command = [server.command, ...server.args ?? []];
|
|
5468
|
+
const environment = envResolvedFrom(server, req.local.secretEnv);
|
|
5447
5469
|
mcp[name] = {
|
|
5448
5470
|
type: "local",
|
|
5449
5471
|
command,
|
|
5450
|
-
...
|
|
5472
|
+
...environment ? { environment } : {},
|
|
5451
5473
|
enabled: true
|
|
5452
5474
|
};
|
|
5453
5475
|
}
|
|
@@ -6656,9 +6678,20 @@ function buildRunSpec2(req, resumeThreadId, instructionsFile = null, threadPromp
|
|
|
6656
6678
|
promptRidesInput,
|
|
6657
6679
|
promptFingerprint,
|
|
6658
6680
|
config: buildConfig(req, baseInstructionsFile),
|
|
6659
|
-
secretEnv:
|
|
6681
|
+
secretEnv: codexSecretEnv(req)
|
|
6660
6682
|
};
|
|
6661
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
|
+
}
|
|
6662
6695
|
function buildInput(req, promptRidesInput) {
|
|
6663
6696
|
const userText = req.content.filter((b) => b.type === "text").map((b) => b.text).join("\n\n");
|
|
6664
6697
|
const body = userText.trim().length > 0 ? userText : req.prompt;
|
|
@@ -6687,10 +6720,12 @@ function buildConfig(req, baseInstructionsFile) {
|
|
|
6687
6720
|
default_tools_approval_mode: "approve"
|
|
6688
6721
|
};
|
|
6689
6722
|
} else if ("command" in server) {
|
|
6723
|
+
const forwarded = Object.keys(server.envFromEnv ?? {}).sort();
|
|
6690
6724
|
mcp_servers[name] = {
|
|
6691
6725
|
command: server.command,
|
|
6692
6726
|
...server.args ? { args: server.args } : {},
|
|
6693
6727
|
...server.env ? { env: server.env } : {},
|
|
6728
|
+
...forwarded.length > 0 ? { env_vars: forwarded } : {},
|
|
6694
6729
|
default_tools_approval_mode: "approve"
|
|
6695
6730
|
};
|
|
6696
6731
|
}
|
|
@@ -8524,7 +8559,10 @@ var mcpStdioServerSchema = z15.object({
|
|
|
8524
8559
|
type: z15.literal("stdio").optional(),
|
|
8525
8560
|
command: z15.string().min(1),
|
|
8526
8561
|
args: z15.array(z15.string()).optional(),
|
|
8527
|
-
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()
|
|
8528
8566
|
});
|
|
8529
8567
|
var mcpHttpServerSchema = z15.object({
|
|
8530
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",
|