@cabane/companion 0.6.4 → 0.6.6
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 +40 -33
- package/dist/runtime.js +40 -33
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2827,7 +2827,17 @@ import {
|
|
|
2827
2827
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
2828
2828
|
|
|
2829
2829
|
// packages/agent-runtime/src/claude-code/addendum.ts
|
|
2830
|
-
var CLAUDE_CODE_ADDENDUM =
|
|
2830
|
+
var CLAUDE_CODE_ADDENDUM = [
|
|
2831
|
+
"On this harness the Cabane tools register under MCP prefixes. The workspace tool is",
|
|
2832
|
+
"`mcp__cabane__sdk`; the ancillary tools are `mcp__cabane__list_workspaces`,",
|
|
2833
|
+
"`mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`,",
|
|
2834
|
+
"`mcp__cabane__finalize_upload`, and `mcp__cabane__mint_render_token`; the turn tools are",
|
|
2835
|
+
"`mcp__cabane_companion__ask`, `mcp__cabane_companion__wake_me`,",
|
|
2836
|
+
"`mcp__cabane_companion__summon_agent`, `mcp__cabane_companion__sub_agent`, and",
|
|
2837
|
+
"`mcp__cabane_companion__skip_turn`. Where this prompt names a tool by its bare verb, call",
|
|
2838
|
+
"the prefixed form from your tool list. Your harness's own tools (shell, local file",
|
|
2839
|
+
"read/edit) keep their ordinary names and act on the local machine only."
|
|
2840
|
+
].join(" ");
|
|
2831
2841
|
|
|
2832
2842
|
// packages/agent-runtime/src/claude-code/policy.ts
|
|
2833
2843
|
import { z as z9 } from "zod";
|
|
@@ -3612,19 +3622,15 @@ function selectAdapter(registry, runtime) {
|
|
|
3612
3622
|
|
|
3613
3623
|
// packages/agent-runtime/src/opencode/addendum.ts
|
|
3614
3624
|
var OPENCODE_ADDENDUM = [
|
|
3615
|
-
"
|
|
3616
|
-
"
|
|
3617
|
-
"
|
|
3618
|
-
"
|
|
3619
|
-
"
|
|
3620
|
-
"`
|
|
3621
|
-
"`
|
|
3622
|
-
"
|
|
3623
|
-
"
|
|
3624
|
-
"prefix is not part of its name \u2014 call the tool by its plain verb. Write your",
|
|
3625
|
-
"closing reply as the last thing you say in the turn: you can interleave",
|
|
3626
|
-
"narration with tool calls, but only your final message is recorded as the",
|
|
3627
|
-
"turn\u2019s reply."
|
|
3625
|
+
"Every tool here goes by its plain name: the workspace tool is `sdk`; the turn tools are",
|
|
3626
|
+
"`ask`, `wake_me`, `summon_agent`, `sub_agent`, `skip_turn`; the ancillary tools are",
|
|
3627
|
+
"`list_workspaces`, `read_binary`, `upload`, `begin_upload`, `finalize_upload`,",
|
|
3628
|
+
"`mint_render_token`; and the host tools are plain verbs too (`bash`, `read`, `edit`). Mind",
|
|
3629
|
+
"the collision: a bare `read` or `edit` is the HOST tool, acting on the local machine \u2014 a",
|
|
3630
|
+
"workspace read is `cabane.files.read` inside an `sdk` program. If a tool ever appears with",
|
|
3631
|
+
"an `mcp__\u2026__` prefix, that prefix is not part of its name here. One more harness fact: you",
|
|
3632
|
+
"can interleave narration with tool calls, but only your final message is recorded as the",
|
|
3633
|
+
"turn's reply \u2014 write your closing answer last."
|
|
3628
3634
|
].join(" ");
|
|
3629
3635
|
|
|
3630
3636
|
// packages/agent-runtime/src/opencode/events.ts
|
|
@@ -4577,22 +4583,17 @@ var OPENCODE_CONFORMANCE_FIXTURES = [
|
|
|
4577
4583
|
|
|
4578
4584
|
// packages/agent-runtime/src/codex/addendum.ts
|
|
4579
4585
|
var CODEX_ADDENDUM = [
|
|
4580
|
-
"
|
|
4581
|
-
"`mcp__cabane__sdk
|
|
4582
|
-
"
|
|
4583
|
-
"
|
|
4584
|
-
"
|
|
4585
|
-
"
|
|
4586
|
-
"
|
|
4587
|
-
"
|
|
4588
|
-
"
|
|
4589
|
-
"the
|
|
4590
|
-
"
|
|
4591
|
-
"There is no Cabane `read`/`write`/`search`/`edit` tool here \u2014 those are `cabane`",
|
|
4592
|
-
"SDK calls inside your program, not tools. If a tool appears in this prompt with",
|
|
4593
|
-
"an `mcp__\u2026__` prefix, preserve that qualified name. Write your closing reply as",
|
|
4594
|
-
"the last thing you say in the turn: you can interleave narration with tool",
|
|
4595
|
-
"calls, but only your final message is recorded as the turn\u2019s reply."
|
|
4586
|
+
"Codex surfaces MCP tools under qualified names, and on some versions defers them. The",
|
|
4587
|
+
"workspace tool is `mcp__cabane__sdk` \u2014 if it isn't in your visible tool list, locate it in",
|
|
4588
|
+
"the deferred-tool inventory and invoke that exact qualified name; never conclude the SDK is",
|
|
4589
|
+
"absent without attempting discovery and invocation, and if a call fails, report the recorded",
|
|
4590
|
+
"error. The turn tools are `mcp__cabane_companion__ask` / `wake_me` / `summon_agent` /",
|
|
4591
|
+
"`sub_agent` / `skip_turn`, and the ancillary tools `mcp__cabane__list_workspaces` /",
|
|
4592
|
+
"`read_binary` / `upload` / `begin_upload` / `finalize_upload` / `mint_render_token` \u2014 all",
|
|
4593
|
+
"possibly deferred too. There is no Cabane `read`/`write`/`search` tool \u2014 those are",
|
|
4594
|
+
"`cabane.*` calls inside your program. One more harness fact: you can interleave narration",
|
|
4595
|
+
"with tool calls, but only your final message is recorded as the turn's reply \u2014 write your",
|
|
4596
|
+
"closing answer last."
|
|
4596
4597
|
].join(" ");
|
|
4597
4598
|
|
|
4598
4599
|
// packages/agent-runtime/src/codex/events.ts
|
|
@@ -4980,6 +4981,7 @@ function buildConfig(req) {
|
|
|
4980
4981
|
}
|
|
4981
4982
|
const policy = codexToolPolicy(req.policy);
|
|
4982
4983
|
const tmpDir = req.local.env?.TMPDIR;
|
|
4984
|
+
const gateLockDir = req.local.env?.CABANE_GATE_LOCK_DIR;
|
|
4983
4985
|
return {
|
|
4984
4986
|
mcp_servers,
|
|
4985
4987
|
experimental_use_rmcp_client: true,
|
|
@@ -4997,7 +4999,9 @@ function buildConfig(req) {
|
|
|
4997
4999
|
[policy.permissionProfile]: {
|
|
4998
5000
|
filesystem: {
|
|
4999
5001
|
":root": "read",
|
|
5000
|
-
":workspace_roots": { ".": "write", ".git": "write" }
|
|
5002
|
+
":workspace_roots": { ".": "write", ".git": "write" },
|
|
5003
|
+
// The one absolute-path grant — see the CT612-fallout note above.
|
|
5004
|
+
...gateLockDir ? { [gateLockDir]: "write" } : {}
|
|
5001
5005
|
},
|
|
5002
5006
|
network: { enabled: policy.networkAccessEnabled, mode: "full" }
|
|
5003
5007
|
}
|
|
@@ -7254,6 +7258,9 @@ ${reason}`,
|
|
|
7254
7258
|
);
|
|
7255
7259
|
}
|
|
7256
7260
|
}
|
|
7261
|
+
if (turnContext.runtime === "codex" && process.env.CABANE_GATE_LOCK_DIR) {
|
|
7262
|
+
turnEnv = { ...turnEnv, CABANE_GATE_LOCK_DIR: process.env.CABANE_GATE_LOCK_DIR };
|
|
7263
|
+
}
|
|
7257
7264
|
const key = runKey(payload.conversationId, payload.agentId);
|
|
7258
7265
|
const abortController = new AbortController();
|
|
7259
7266
|
this.aborts.set(key, abortController);
|
|
@@ -7280,13 +7287,13 @@ ${reason}`,
|
|
|
7280
7287
|
const wakeState = createWakeState();
|
|
7281
7288
|
const subAgentCreate = async (args) => {
|
|
7282
7289
|
const dispatchTarget = args.agentId ?? payload.agentId;
|
|
7283
|
-
const
|
|
7290
|
+
const projectId = turnContext.conversation.projectId;
|
|
7284
7291
|
const { status: status2, body } = await this.opts.api.createSubAgentConversation(
|
|
7285
7292
|
workspaceId,
|
|
7286
7293
|
payload.conversationId,
|
|
7287
7294
|
turnContext.turnToken ?? this.opts.credential,
|
|
7288
7295
|
{
|
|
7289
|
-
...
|
|
7296
|
+
...projectId ? { projectId } : {},
|
|
7290
7297
|
...args.title ? { title: args.title } : {},
|
|
7291
7298
|
body: args.prompt,
|
|
7292
7299
|
dispatch: dispatchTarget,
|
package/dist/runtime.js
CHANGED
|
@@ -2480,7 +2480,17 @@ import {
|
|
|
2480
2480
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
2481
2481
|
|
|
2482
2482
|
// packages/agent-runtime/src/claude-code/addendum.ts
|
|
2483
|
-
var CLAUDE_CODE_ADDENDUM =
|
|
2483
|
+
var CLAUDE_CODE_ADDENDUM = [
|
|
2484
|
+
"On this harness the Cabane tools register under MCP prefixes. The workspace tool is",
|
|
2485
|
+
"`mcp__cabane__sdk`; the ancillary tools are `mcp__cabane__list_workspaces`,",
|
|
2486
|
+
"`mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`,",
|
|
2487
|
+
"`mcp__cabane__finalize_upload`, and `mcp__cabane__mint_render_token`; the turn tools are",
|
|
2488
|
+
"`mcp__cabane_companion__ask`, `mcp__cabane_companion__wake_me`,",
|
|
2489
|
+
"`mcp__cabane_companion__summon_agent`, `mcp__cabane_companion__sub_agent`, and",
|
|
2490
|
+
"`mcp__cabane_companion__skip_turn`. Where this prompt names a tool by its bare verb, call",
|
|
2491
|
+
"the prefixed form from your tool list. Your harness's own tools (shell, local file",
|
|
2492
|
+
"read/edit) keep their ordinary names and act on the local machine only."
|
|
2493
|
+
].join(" ");
|
|
2484
2494
|
|
|
2485
2495
|
// packages/agent-runtime/src/claude-code/policy.ts
|
|
2486
2496
|
import { z as z9 } from "zod";
|
|
@@ -3265,19 +3275,15 @@ function selectAdapter(registry, runtime) {
|
|
|
3265
3275
|
|
|
3266
3276
|
// packages/agent-runtime/src/opencode/addendum.ts
|
|
3267
3277
|
var OPENCODE_ADDENDUM = [
|
|
3268
|
-
"
|
|
3269
|
-
"
|
|
3270
|
-
"
|
|
3271
|
-
"
|
|
3272
|
-
"
|
|
3273
|
-
"`
|
|
3274
|
-
"`
|
|
3275
|
-
"
|
|
3276
|
-
"
|
|
3277
|
-
"prefix is not part of its name \u2014 call the tool by its plain verb. Write your",
|
|
3278
|
-
"closing reply as the last thing you say in the turn: you can interleave",
|
|
3279
|
-
"narration with tool calls, but only your final message is recorded as the",
|
|
3280
|
-
"turn\u2019s reply."
|
|
3278
|
+
"Every tool here goes by its plain name: the workspace tool is `sdk`; the turn tools are",
|
|
3279
|
+
"`ask`, `wake_me`, `summon_agent`, `sub_agent`, `skip_turn`; the ancillary tools are",
|
|
3280
|
+
"`list_workspaces`, `read_binary`, `upload`, `begin_upload`, `finalize_upload`,",
|
|
3281
|
+
"`mint_render_token`; and the host tools are plain verbs too (`bash`, `read`, `edit`). Mind",
|
|
3282
|
+
"the collision: a bare `read` or `edit` is the HOST tool, acting on the local machine \u2014 a",
|
|
3283
|
+
"workspace read is `cabane.files.read` inside an `sdk` program. If a tool ever appears with",
|
|
3284
|
+
"an `mcp__\u2026__` prefix, that prefix is not part of its name here. One more harness fact: you",
|
|
3285
|
+
"can interleave narration with tool calls, but only your final message is recorded as the",
|
|
3286
|
+
"turn's reply \u2014 write your closing answer last."
|
|
3281
3287
|
].join(" ");
|
|
3282
3288
|
|
|
3283
3289
|
// packages/agent-runtime/src/opencode/events.ts
|
|
@@ -4230,22 +4236,17 @@ var OPENCODE_CONFORMANCE_FIXTURES = [
|
|
|
4230
4236
|
|
|
4231
4237
|
// packages/agent-runtime/src/codex/addendum.ts
|
|
4232
4238
|
var CODEX_ADDENDUM = [
|
|
4233
|
-
"
|
|
4234
|
-
"`mcp__cabane__sdk
|
|
4235
|
-
"
|
|
4236
|
-
"
|
|
4237
|
-
"
|
|
4238
|
-
"
|
|
4239
|
-
"
|
|
4240
|
-
"
|
|
4241
|
-
"
|
|
4242
|
-
"the
|
|
4243
|
-
"
|
|
4244
|
-
"There is no Cabane `read`/`write`/`search`/`edit` tool here \u2014 those are `cabane`",
|
|
4245
|
-
"SDK calls inside your program, not tools. If a tool appears in this prompt with",
|
|
4246
|
-
"an `mcp__\u2026__` prefix, preserve that qualified name. Write your closing reply as",
|
|
4247
|
-
"the last thing you say in the turn: you can interleave narration with tool",
|
|
4248
|
-
"calls, but only your final message is recorded as the turn\u2019s reply."
|
|
4239
|
+
"Codex surfaces MCP tools under qualified names, and on some versions defers them. The",
|
|
4240
|
+
"workspace tool is `mcp__cabane__sdk` \u2014 if it isn't in your visible tool list, locate it in",
|
|
4241
|
+
"the deferred-tool inventory and invoke that exact qualified name; never conclude the SDK is",
|
|
4242
|
+
"absent without attempting discovery and invocation, and if a call fails, report the recorded",
|
|
4243
|
+
"error. The turn tools are `mcp__cabane_companion__ask` / `wake_me` / `summon_agent` /",
|
|
4244
|
+
"`sub_agent` / `skip_turn`, and the ancillary tools `mcp__cabane__list_workspaces` /",
|
|
4245
|
+
"`read_binary` / `upload` / `begin_upload` / `finalize_upload` / `mint_render_token` \u2014 all",
|
|
4246
|
+
"possibly deferred too. There is no Cabane `read`/`write`/`search` tool \u2014 those are",
|
|
4247
|
+
"`cabane.*` calls inside your program. One more harness fact: you can interleave narration",
|
|
4248
|
+
"with tool calls, but only your final message is recorded as the turn's reply \u2014 write your",
|
|
4249
|
+
"closing answer last."
|
|
4249
4250
|
].join(" ");
|
|
4250
4251
|
|
|
4251
4252
|
// packages/agent-runtime/src/codex/events.ts
|
|
@@ -4633,6 +4634,7 @@ function buildConfig(req) {
|
|
|
4633
4634
|
}
|
|
4634
4635
|
const policy = codexToolPolicy(req.policy);
|
|
4635
4636
|
const tmpDir = req.local.env?.TMPDIR;
|
|
4637
|
+
const gateLockDir = req.local.env?.CABANE_GATE_LOCK_DIR;
|
|
4636
4638
|
return {
|
|
4637
4639
|
mcp_servers,
|
|
4638
4640
|
experimental_use_rmcp_client: true,
|
|
@@ -4650,7 +4652,9 @@ function buildConfig(req) {
|
|
|
4650
4652
|
[policy.permissionProfile]: {
|
|
4651
4653
|
filesystem: {
|
|
4652
4654
|
":root": "read",
|
|
4653
|
-
":workspace_roots": { ".": "write", ".git": "write" }
|
|
4655
|
+
":workspace_roots": { ".": "write", ".git": "write" },
|
|
4656
|
+
// The one absolute-path grant — see the CT612-fallout note above.
|
|
4657
|
+
...gateLockDir ? { [gateLockDir]: "write" } : {}
|
|
4654
4658
|
},
|
|
4655
4659
|
network: { enabled: policy.networkAccessEnabled, mode: "full" }
|
|
4656
4660
|
}
|
|
@@ -6907,6 +6911,9 @@ ${reason}`,
|
|
|
6907
6911
|
);
|
|
6908
6912
|
}
|
|
6909
6913
|
}
|
|
6914
|
+
if (turnContext.runtime === "codex" && process.env.CABANE_GATE_LOCK_DIR) {
|
|
6915
|
+
turnEnv = { ...turnEnv, CABANE_GATE_LOCK_DIR: process.env.CABANE_GATE_LOCK_DIR };
|
|
6916
|
+
}
|
|
6910
6917
|
const key = runKey(payload.conversationId, payload.agentId);
|
|
6911
6918
|
const abortController = new AbortController();
|
|
6912
6919
|
this.aborts.set(key, abortController);
|
|
@@ -6933,13 +6940,13 @@ ${reason}`,
|
|
|
6933
6940
|
const wakeState = createWakeState();
|
|
6934
6941
|
const subAgentCreate = async (args) => {
|
|
6935
6942
|
const dispatchTarget = args.agentId ?? payload.agentId;
|
|
6936
|
-
const
|
|
6943
|
+
const projectId = turnContext.conversation.projectId;
|
|
6937
6944
|
const { status, body } = await this.opts.api.createSubAgentConversation(
|
|
6938
6945
|
workspaceId,
|
|
6939
6946
|
payload.conversationId,
|
|
6940
6947
|
turnContext.turnToken ?? this.opts.credential,
|
|
6941
6948
|
{
|
|
6942
|
-
...
|
|
6949
|
+
...projectId ? { projectId } : {},
|
|
6943
6950
|
...args.title ? { title: args.title } : {},
|
|
6944
6951
|
body: args.prompt,
|
|
6945
6952
|
dispatch: dispatchTarget,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cabane/companion",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.6",
|
|
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",
|