@cabane/companion 0.6.226 → 0.6.228

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 CHANGED
@@ -2572,7 +2572,7 @@ var init_transcript_sink = __esm({
2572
2572
  });
2573
2573
 
2574
2574
  // packages/agent-runtime/src/turn-control/descriptions.ts
2575
- var MAX_ASK_QUESTION_BYTES, MAX_ASK_HEADLINE_BYTES, MAX_ASK_ITEMS, EXCHANGE_KINDS, APPROVAL_OPTIONS, REQUEST_OPTIONS, EXCHANGE_EXPECTS, MAX_EXCHANGE_FILES, MAX_REQUEST_BODY_BYTES, MAX_ASK_OPTION_BYTES, ASK_OPTION_NOT_A_STRING, MIN_ASK_OPTIONS, MAX_ASK_OPTIONS, ASK_TARGET_PATTERN, ASK_TARGET_INVALID, MAX_WAKE_NOTE_BYTES, MAX_WITHDRAW_REASON_BYTES, MAX_SKIP_REASON_BYTES, TURN_CONTROL_MCP_SERVER, TURN_CONTROL_TOOLS, TURN_CONTROL_TOOL_DESCRIPTIONS, TURN_CONTROL_FIELD_DESCRIPTIONS;
2575
+ var MAX_ASK_QUESTION_BYTES, MAX_ASK_HEADLINE_BYTES, MAX_ASK_ITEMS, EXCHANGE_KINDS, APPROVAL_OPTIONS, MAX_EXCHANGE_ACTION_BYTES, REQUEST_OPTIONS, EXCHANGE_EXPECTS, MAX_EXCHANGE_FILES, MAX_REQUEST_BODY_BYTES, MAX_ASK_OPTION_BYTES, ASK_OPTION_NOT_A_STRING, MIN_ASK_OPTIONS, MAX_ASK_OPTIONS, ASK_TARGET_PATTERN, ASK_TARGET_INVALID, MAX_WAKE_NOTE_BYTES, MAX_WITHDRAW_REASON_BYTES, MAX_SKIP_REASON_BYTES, TURN_CONTROL_MCP_SERVER, TURN_CONTROL_TOOLS, TURN_CONTROL_TOOL_DESCRIPTIONS, TURN_CONTROL_FIELD_DESCRIPTIONS;
2576
2576
  var init_descriptions = __esm({
2577
2577
  "packages/agent-runtime/src/turn-control/descriptions.ts"() {
2578
2578
  "use strict";
@@ -2581,6 +2581,7 @@ var init_descriptions = __esm({
2581
2581
  MAX_ASK_ITEMS = 20;
2582
2582
  EXCHANGE_KINDS = ["question", "approval", "request"];
2583
2583
  APPROVAL_OPTIONS = ["Yes", "No"];
2584
+ MAX_EXCHANGE_ACTION_BYTES = 32;
2584
2585
  REQUEST_OPTIONS = ["Done"];
2585
2586
  EXCHANGE_EXPECTS = ["confirmation", "result"];
2586
2587
  MAX_EXCHANGE_FILES = 5;
@@ -2605,8 +2606,8 @@ var init_descriptions = __esm({
2605
2606
  ];
2606
2607
  TURN_CONTROL_TOOL_DESCRIPTIONS = {
2607
2608
  answer: `Call this just before you write your answer: the text you write next is what the conversation keeps as your message. Call it once.`,
2608
- open_exchange: `Put something in front of one person that comes back with a recorded outcome, then end your turn; don't wait for it. Not for delivering finished work, and never for acknowledgement or feedback on it; the reply delivers. Open one only when the work can't continue without the answer. \`targetUserId\` is a person on your roster, by their \`@handle\`; to bring in an agent, name them with \`@handle\` in your reply.
2609
- - A question is one item (\`headline\`, optional \`question\` body, \`options\`) or \`questions\`, 1\u2013${MAX_ASK_ITEMS} items; never both. An approval or request is \`headline\` and an optional \`question\` body only. An approval is answered ${APPROVAL_OPTIONS.join(" / ")}; a request ${REQUEST_OPTIONS.join("")}, or the typed result when \`expects\` is \`result\`, or a note saying the person couldn't. A request's body carries the steps and may hold a list and code blocks; every other body is a sentence or two of framing, inline Markdown only.
2609
+ open_exchange: `Put something in front of one person that comes back with a recorded outcome, then end your turn; don't wait for it. Not for delivering finished work, and never for acknowledgement or feedback on it; the reply delivers. Open one only when the work can't continue without the answer. \`targetUserId\` is a person; to bring in an agent, name them with \`@handle\` in your reply.
2610
+ - A question is one item (\`headline\`, optional \`question\` body, \`options\`) or \`questions\`, 1\u2013${MAX_ASK_ITEMS} items; never both. An approval or request is \`headline\` and an optional \`question\` body only. An approval is answered by its \`go\` or \`hold\` word, ${APPROVAL_OPTIONS.join(" / ")} without them; a request ${REQUEST_OPTIONS.join("")}, or the typed result when \`expects\` is \`result\`, or a note saying the person couldn't. A request's body carries the steps and may hold a list and code blocks; every other body is a sentence or two of framing, inline Markdown only.
2610
2611
  - Decisions that arise together go in ONE call, in the order you want them answered. A second call is a separate exchange, never an edit.
2611
2612
  - Voice, in headline, body and options: "I" for yourself, never your own name; name everyone else who decides or acts, as on your roster. Never "you", "your", "we", "us", "our" or their contractions, nor "he", "she" or "they" for a named actor. A quotation stays accurate: say who said it.
2612
2613
  - It must stand alone, since it can arrive first: the reply carries the findings, the exchange the question; don't repeat the reply in it.
@@ -2622,7 +2623,9 @@ var init_descriptions = __esm({
2622
2623
  answer: {},
2623
2624
  open_exchange: {
2624
2625
  targetUserId: "The person: their `@handle` from your turn context's roster (preferred), or their user id.",
2625
- kind: `What the exchange is for; default \`question\`. \`question\`: the person picks among courses of action or types an answer. \`approval\`: a yes/no on one proposed action \u2014 the person answers ${APPROVAL_OPTIONS.join(" or ")}. \`request\`: something only the person can do \u2014 they answer ${REQUEST_OPTIONS.join("")}, or type the result when \`expects\` is \`result\`, or send a note saying they couldn't.`,
2626
+ kind: `What the exchange is for; default \`question\`. \`question\`: the person picks among courses of action or types an answer. \`approval\`: a yes/no on one proposed action \u2014 the person answers with its \`go\` or \`hold\` word, ${APPROVAL_OPTIONS.join(" or ")} when none is given. \`request\`: something only the person can do \u2014 they answer ${REQUEST_OPTIONS.join("")}, or type the result when \`expects\` is \`result\`, or send a note saying they couldn't.`,
2627
+ go: `An approval only: the go answer as the action itself, a short verb phrase ("Merge", "Send them", "Archive it"; not "Yes, merge it"), about 24 characters and at most ${MAX_EXCHANGE_ACTION_BYTES}. Given with \`hold\`, or neither: without them the person answers ${APPROVAL_OPTIONS.join(" or ")}.`,
2628
+ hold: `An approval only: the hold answer in the same voice ("Hold off", "Not yet", "Keep it"), at most ${MAX_EXCHANGE_ACTION_BYTES} characters and different from \`go\`. Given with \`go\`.`,
2626
2629
  expects: "A request only: `confirmation` (default) when you only need to hear it's done, `result` when you need something back. Either way the person may send only a note saying they couldn't. Refused on a question or approval.",
2627
2630
  question: `The body beneath the headline \u2014 for a question or approval one or two sentences of framing, NOT a report (up to ${MAX_ASK_QUESTION_BYTES} characters, inline markdown only); for a request the steps, with lists and code blocks allowed (up to ${MAX_REQUEST_BODY_BYTES} characters). With \`questions\`, leave it out.`,
2628
2631
  headline: `ONE clear, capitalized sentence, up to ${MAX_ASK_HEADLINE_BYTES} characters: for a question or approval, the question ending in \`?\` ("Should Ledger deploy once Mia approves?"); for a request, what to do ("Run these and send me the output"). What the person reads first in For you. Required for an approval or request.`,
@@ -2819,8 +2822,10 @@ var init_pump = __esm({
2819
2822
 
2820
2823
  // packages/agent-runtime/src/turn-control/prompt-guidance.ts
2821
2824
  function turnControlPromptGuidance(prefix) {
2822
- const controls = TURN_CONTROL_TOOLS.map((name) => `\`${prefix}${name}\` (${MEANINGS[name]})`);
2823
- return `The turn tools are: ${controls.join("; ")}. Read a tool's description before calling it. A peer response is ordinary conversation speech; your reply is the answer.`;
2825
+ return [
2826
+ "Turn tools (read each description before calling):",
2827
+ ...TURN_CONTROL_TOOLS.map((name) => `- \`${prefix}${name}\` \u2014 ${MEANINGS[name]}.`)
2828
+ ].join("\n");
2824
2829
  }
2825
2830
  var MEANINGS;
2826
2831
  var init_prompt_guidance = __esm({
@@ -2829,8 +2834,8 @@ var init_prompt_guidance = __esm({
2829
2834
  init_descriptions();
2830
2835
  MEANINGS = {
2831
2836
  answer: "declare the text you write next as your answer",
2832
- open_exchange: "put a question, go-ahead or request to a person",
2833
- cancel_wake: "cancel your own armed wake in this conversation",
2837
+ open_exchange: "ask a person for a decision, approval or action",
2838
+ cancel_wake: "cancel your scheduled return to this conversation",
2834
2839
  skip_turn: "end without posting a reply",
2835
2840
  wake_me: "schedule your own return; when it fires, say what you came back to check",
2836
2841
  withdraw_exchange: "withdraw an open exchange in this conversation with a reason"
@@ -2845,15 +2850,14 @@ var init_addendum = __esm({
2845
2850
  "use strict";
2846
2851
  init_prompt_guidance();
2847
2852
  CLAUDE_CODE_ADDENDUM = [
2848
- "On this harness the Cabane tools register under MCP prefixes. The workspace tools are",
2849
- "`mcp__cabane__query`, `mcp__cabane__mutate` and `mcp__cabane__describe`; the ancillary",
2850
- "tools are `mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`,",
2851
- "`mcp__cabane__finalize_upload`, and `mcp__cabane__mint_render_token`.",
2852
- turnControlPromptGuidance("mcp__cabane_companion__"),
2853
- "Where this prompt names a tool by its bare verb, call",
2854
- "the prefixed form from your tool list. Your harness's own tools (shell, local file",
2855
- "read/edit) keep their ordinary names and act on the local machine only."
2856
- ].join(" ");
2853
+ "- Workspace tools: `mcp__cabane__query`, `mcp__cabane__mutate`, `mcp__cabane__describe`.",
2854
+ "- File tools: `mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`, `mcp__cabane__finalize_upload`.",
2855
+ "- Page verification: `mcp__cabane__mint_render_token`.",
2856
+ "- Where these instructions use a bare tool name, call its prefixed form from the tool list.",
2857
+ "- Host tools such as the shell and local file editor keep their ordinary names and act on the local device.",
2858
+ "",
2859
+ turnControlPromptGuidance("mcp__cabane_companion__")
2860
+ ].join("\n");
2857
2861
  }
2858
2862
  });
2859
2863
 
@@ -3701,17 +3705,14 @@ var init_addendum2 = __esm({
3701
3705
  "use strict";
3702
3706
  init_prompt_guidance();
3703
3707
  OPENCODE_ADDENDUM = [
3704
- "Every tool here goes by its plain name: the workspace tools are `query`, `mutate` and",
3705
- "`describe`.",
3706
- turnControlPromptGuidance(""),
3707
- "The ancillary tools are `read_binary`, `upload`, `begin_upload`,",
3708
- "`finalize_upload`, `mint_render_token`; and the host tools are plain verbs too (`bash`,",
3709
- "`read`, `edit`). Mind the collision: a bare `read` or `edit` is the HOST tool, acting on the",
3710
- "local machine \u2014 a workspace read is `query` with the operation name `files.read`. The",
3711
- "collision runs the other way too: `read` is a host tool here AND `files.read` is an",
3712
- "operation name, so keep the bare verb and the dotted name apart. If a tool ever appears with",
3713
- "an `mcp__\u2026__` prefix, that prefix is not part of its name here."
3714
- ].join(" ");
3708
+ "- Workspace tools: `query`, `mutate`, `describe`.",
3709
+ "- File tools: `read_binary`, `upload`, `begin_upload`, `finalize_upload`.",
3710
+ "- Page verification: `mint_render_token`.",
3711
+ "- Call tools by their plain names here, without an `mcp__\u2026__` prefix.",
3712
+ "- Host tools such as `bash`, `read` and `edit` act on the local device. To read a workspace file, call `query` with the operation `files.read`.",
3713
+ "",
3714
+ turnControlPromptGuidance("")
3715
+ ].join("\n");
3715
3716
  }
3716
3717
  });
3717
3718
 
@@ -4444,23 +4445,14 @@ var init_addendum3 = __esm({
4444
4445
  "use strict";
4445
4446
  init_prompt_guidance();
4446
4447
  CODEX_ADDENDUM = [
4447
- "Codex surfaces MCP tools under qualified names, and on some versions defers them. The",
4448
- "workspace tools are `mcp__cabane__query`, `mcp__cabane__mutate` and",
4449
- "`mcp__cabane__describe` \u2014 if they aren't in your visible tool list, locate them in",
4450
- "the deferred-tool inventory and invoke those exact qualified names; never conclude the",
4451
- "workspace is",
4452
- "absent without attempting discovery and invocation, and if a call fails, report the recorded",
4453
- "error.",
4454
- turnControlPromptGuidance("mcp__cabane_companion__"),
4455
- // Every ancillary tool is written as Codex's own tool list shows it — qualified — so the sentence
4456
- // instructing exact qualified names doesn't contradict itself. The bare `query` / `mutate` below
4457
- // stay: that sentence is about operation names, after the qualified forms are given.
4458
- "The ancillary tools are `mcp__cabane__read_binary`, `mcp__cabane__upload`,",
4459
- "`mcp__cabane__begin_upload`, `mcp__cabane__finalize_upload` and",
4460
- "`mcp__cabane__mint_render_token` \u2014 all possibly deferred too.",
4461
- "There is no Cabane `read`/`write`/`search` tool \u2014 those are",
4462
- "operation NAMES you pass to `query` / `mutate`."
4463
- ].join(" ");
4448
+ "- Workspace tools: `mcp__cabane__query`, `mcp__cabane__mutate`, `mcp__cabane__describe`.",
4449
+ "- File tools: `mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`, `mcp__cabane__finalize_upload`.",
4450
+ "- Page verification: `mcp__cabane__mint_render_token`.",
4451
+ "- Codex may defer MCP tools. If a listed tool is missing, search the deferred-tool inventory and call the matching tool by its exact name. Report discovery or call failures with the recorded error.",
4452
+ "- Names such as `files.read` are operations passed to `query` or `mutate`, not separate tools.",
4453
+ "",
4454
+ turnControlPromptGuidance("mcp__cabane_companion__")
4455
+ ].join("\n");
4464
4456
  }
4465
4457
  });
4466
4458
 
@@ -6252,6 +6244,8 @@ function createTurnControlMcpServer(acts, skipState) {
6252
6244
  ).min(MIN_ASK_OPTIONS).max(MAX_ASK_OPTIONS).optional().describe(TURN_CONTROL_FIELD_DESCRIPTIONS.open_exchange["questions.options"])
6253
6245
  })
6254
6246
  ).min(1).max(MAX_ASK_ITEMS).optional().describe(TURN_CONTROL_FIELD_DESCRIPTIONS.open_exchange.questions),
6247
+ go: z15.string().min(1).max(MAX_EXCHANGE_ACTION_BYTES).optional().describe(TURN_CONTROL_FIELD_DESCRIPTIONS.open_exchange.go),
6248
+ hold: z15.string().min(1).max(MAX_EXCHANGE_ACTION_BYTES).optional().describe(TURN_CONTROL_FIELD_DESCRIPTIONS.open_exchange.hold),
6255
6249
  files: z15.array(z15.string().min(1).max(1024)).optional().describe(TURN_CONTROL_FIELD_DESCRIPTIONS.open_exchange.files),
6256
6250
  replaces: z15.object({
6257
6251
  askId: z15.string().uuid().describe(TURN_CONTROL_FIELD_DESCRIPTIONS.open_exchange["replaces.askId"]),
@@ -6275,6 +6269,11 @@ function createTurnControlMcpServer(acts, skipState) {
6275
6269
  ...args.question ? { question: args.question } : {},
6276
6270
  ...args.options ? { options: args.options } : {},
6277
6271
  ...args.questions ? { questions: args.questions } : {},
6272
+ // Forwarded whole, so the server's rule (both or neither, an
6273
+ // approval's only) refuses them by name rather than one half
6274
+ // being dropped here unseen.
6275
+ ...args.go !== void 0 ? { go: args.go } : {},
6276
+ ...args.hold !== void 0 ? { hold: args.hold } : {},
6278
6277
  ...args.files ? { files: args.files } : {}
6279
6278
  }
6280
6279
  });
package/dist/runtime.js CHANGED
@@ -2939,6 +2939,7 @@ var MAX_ASK_QUESTION_BYTES = 400;
2939
2939
  var MAX_ASK_HEADLINE_BYTES = 120;
2940
2940
  var MAX_ASK_ITEMS = 20;
2941
2941
  var APPROVAL_OPTIONS = ["Yes", "No"];
2942
+ var MAX_EXCHANGE_ACTION_BYTES = 32;
2942
2943
  var REQUEST_OPTIONS = ["Done"];
2943
2944
  var MAX_EXCHANGE_FILES = 5;
2944
2945
  var MAX_REQUEST_BODY_BYTES = 2e3;
@@ -2959,8 +2960,8 @@ var TURN_CONTROL_TOOLS = [
2959
2960
  ];
2960
2961
  var TURN_CONTROL_TOOL_DESCRIPTIONS = {
2961
2962
  answer: `Call this just before you write your answer: the text you write next is what the conversation keeps as your message. Call it once.`,
2962
- open_exchange: `Put something in front of one person that comes back with a recorded outcome, then end your turn; don't wait for it. Not for delivering finished work, and never for acknowledgement or feedback on it; the reply delivers. Open one only when the work can't continue without the answer. \`targetUserId\` is a person on your roster, by their \`@handle\`; to bring in an agent, name them with \`@handle\` in your reply.
2963
- - A question is one item (\`headline\`, optional \`question\` body, \`options\`) or \`questions\`, 1\u2013${MAX_ASK_ITEMS} items; never both. An approval or request is \`headline\` and an optional \`question\` body only. An approval is answered ${APPROVAL_OPTIONS.join(" / ")}; a request ${REQUEST_OPTIONS.join("")}, or the typed result when \`expects\` is \`result\`, or a note saying the person couldn't. A request's body carries the steps and may hold a list and code blocks; every other body is a sentence or two of framing, inline Markdown only.
2963
+ open_exchange: `Put something in front of one person that comes back with a recorded outcome, then end your turn; don't wait for it. Not for delivering finished work, and never for acknowledgement or feedback on it; the reply delivers. Open one only when the work can't continue without the answer. \`targetUserId\` is a person; to bring in an agent, name them with \`@handle\` in your reply.
2964
+ - A question is one item (\`headline\`, optional \`question\` body, \`options\`) or \`questions\`, 1\u2013${MAX_ASK_ITEMS} items; never both. An approval or request is \`headline\` and an optional \`question\` body only. An approval is answered by its \`go\` or \`hold\` word, ${APPROVAL_OPTIONS.join(" / ")} without them; a request ${REQUEST_OPTIONS.join("")}, or the typed result when \`expects\` is \`result\`, or a note saying the person couldn't. A request's body carries the steps and may hold a list and code blocks; every other body is a sentence or two of framing, inline Markdown only.
2964
2965
  - Decisions that arise together go in ONE call, in the order you want them answered. A second call is a separate exchange, never an edit.
2965
2966
  - Voice, in headline, body and options: "I" for yourself, never your own name; name everyone else who decides or acts, as on your roster. Never "you", "your", "we", "us", "our" or their contractions, nor "he", "she" or "they" for a named actor. A quotation stays accurate: say who said it.
2966
2967
  - It must stand alone, since it can arrive first: the reply carries the findings, the exchange the question; don't repeat the reply in it.
@@ -2976,7 +2977,9 @@ var TURN_CONTROL_FIELD_DESCRIPTIONS = {
2976
2977
  answer: {},
2977
2978
  open_exchange: {
2978
2979
  targetUserId: "The person: their `@handle` from your turn context's roster (preferred), or their user id.",
2979
- kind: `What the exchange is for; default \`question\`. \`question\`: the person picks among courses of action or types an answer. \`approval\`: a yes/no on one proposed action \u2014 the person answers ${APPROVAL_OPTIONS.join(" or ")}. \`request\`: something only the person can do \u2014 they answer ${REQUEST_OPTIONS.join("")}, or type the result when \`expects\` is \`result\`, or send a note saying they couldn't.`,
2980
+ kind: `What the exchange is for; default \`question\`. \`question\`: the person picks among courses of action or types an answer. \`approval\`: a yes/no on one proposed action \u2014 the person answers with its \`go\` or \`hold\` word, ${APPROVAL_OPTIONS.join(" or ")} when none is given. \`request\`: something only the person can do \u2014 they answer ${REQUEST_OPTIONS.join("")}, or type the result when \`expects\` is \`result\`, or send a note saying they couldn't.`,
2981
+ go: `An approval only: the go answer as the action itself, a short verb phrase ("Merge", "Send them", "Archive it"; not "Yes, merge it"), about 24 characters and at most ${MAX_EXCHANGE_ACTION_BYTES}. Given with \`hold\`, or neither: without them the person answers ${APPROVAL_OPTIONS.join(" or ")}.`,
2982
+ hold: `An approval only: the hold answer in the same voice ("Hold off", "Not yet", "Keep it"), at most ${MAX_EXCHANGE_ACTION_BYTES} characters and different from \`go\`. Given with \`go\`.`,
2980
2983
  expects: "A request only: `confirmation` (default) when you only need to hear it's done, `result` when you need something back. Either way the person may send only a note saying they couldn't. Refused on a question or approval.",
2981
2984
  question: `The body beneath the headline \u2014 for a question or approval one or two sentences of framing, NOT a report (up to ${MAX_ASK_QUESTION_BYTES} characters, inline markdown only); for a request the steps, with lists and code blocks allowed (up to ${MAX_REQUEST_BODY_BYTES} characters). With \`questions\`, leave it out.`,
2982
2985
  headline: `ONE clear, capitalized sentence, up to ${MAX_ASK_HEADLINE_BYTES} characters: for a question or approval, the question ending in \`?\` ("Should Ledger deploy once Mia approves?"); for a request, what to do ("Run these and send me the output"). What the person reads first in For you. Required for an approval or request.`,
@@ -3013,28 +3016,29 @@ import {
3013
3016
  // packages/agent-runtime/src/turn-control/prompt-guidance.ts
3014
3017
  var MEANINGS = {
3015
3018
  answer: "declare the text you write next as your answer",
3016
- open_exchange: "put a question, go-ahead or request to a person",
3017
- cancel_wake: "cancel your own armed wake in this conversation",
3019
+ open_exchange: "ask a person for a decision, approval or action",
3020
+ cancel_wake: "cancel your scheduled return to this conversation",
3018
3021
  skip_turn: "end without posting a reply",
3019
3022
  wake_me: "schedule your own return; when it fires, say what you came back to check",
3020
3023
  withdraw_exchange: "withdraw an open exchange in this conversation with a reason"
3021
3024
  };
3022
3025
  function turnControlPromptGuidance(prefix) {
3023
- const controls = TURN_CONTROL_TOOLS.map((name) => `\`${prefix}${name}\` (${MEANINGS[name]})`);
3024
- return `The turn tools are: ${controls.join("; ")}. Read a tool's description before calling it. A peer response is ordinary conversation speech; your reply is the answer.`;
3026
+ return [
3027
+ "Turn tools (read each description before calling):",
3028
+ ...TURN_CONTROL_TOOLS.map((name) => `- \`${prefix}${name}\` \u2014 ${MEANINGS[name]}.`)
3029
+ ].join("\n");
3025
3030
  }
3026
3031
 
3027
3032
  // packages/agent-runtime/src/claude-code/addendum.ts
3028
3033
  var CLAUDE_CODE_ADDENDUM = [
3029
- "On this harness the Cabane tools register under MCP prefixes. The workspace tools are",
3030
- "`mcp__cabane__query`, `mcp__cabane__mutate` and `mcp__cabane__describe`; the ancillary",
3031
- "tools are `mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`,",
3032
- "`mcp__cabane__finalize_upload`, and `mcp__cabane__mint_render_token`.",
3033
- turnControlPromptGuidance("mcp__cabane_companion__"),
3034
- "Where this prompt names a tool by its bare verb, call",
3035
- "the prefixed form from your tool list. Your harness's own tools (shell, local file",
3036
- "read/edit) keep their ordinary names and act on the local machine only."
3037
- ].join(" ");
3034
+ "- Workspace tools: `mcp__cabane__query`, `mcp__cabane__mutate`, `mcp__cabane__describe`.",
3035
+ "- File tools: `mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`, `mcp__cabane__finalize_upload`.",
3036
+ "- Page verification: `mcp__cabane__mint_render_token`.",
3037
+ "- Where these instructions use a bare tool name, call its prefixed form from the tool list.",
3038
+ "- Host tools such as the shell and local file editor keep their ordinary names and act on the local device.",
3039
+ "",
3040
+ turnControlPromptGuidance("mcp__cabane_companion__")
3041
+ ].join("\n");
3038
3042
 
3039
3043
  // packages/agent-runtime/src/mcp-secret-env.ts
3040
3044
  function headersAsEnvReferences(server) {
@@ -3760,17 +3764,14 @@ var claudeCodeAdapter = createClaudeCodeAdapter();
3760
3764
 
3761
3765
  // packages/agent-runtime/src/opencode/addendum.ts
3762
3766
  var OPENCODE_ADDENDUM = [
3763
- "Every tool here goes by its plain name: the workspace tools are `query`, `mutate` and",
3764
- "`describe`.",
3765
- turnControlPromptGuidance(""),
3766
- "The ancillary tools are `read_binary`, `upload`, `begin_upload`,",
3767
- "`finalize_upload`, `mint_render_token`; and the host tools are plain verbs too (`bash`,",
3768
- "`read`, `edit`). Mind the collision: a bare `read` or `edit` is the HOST tool, acting on the",
3769
- "local machine \u2014 a workspace read is `query` with the operation name `files.read`. The",
3770
- "collision runs the other way too: `read` is a host tool here AND `files.read` is an",
3771
- "operation name, so keep the bare verb and the dotted name apart. If a tool ever appears with",
3772
- "an `mcp__\u2026__` prefix, that prefix is not part of its name here."
3773
- ].join(" ");
3767
+ "- Workspace tools: `query`, `mutate`, `describe`.",
3768
+ "- File tools: `read_binary`, `upload`, `begin_upload`, `finalize_upload`.",
3769
+ "- Page verification: `mint_render_token`.",
3770
+ "- Call tools by their plain names here, without an `mcp__\u2026__` prefix.",
3771
+ "- Host tools such as `bash`, `read` and `edit` act on the local device. To read a workspace file, call `query` with the operation `files.read`.",
3772
+ "",
3773
+ turnControlPromptGuidance("")
3774
+ ].join("\n");
3774
3775
 
3775
3776
  // packages/agent-runtime/src/opencode/events.ts
3776
3777
  function asRecord(v) {
@@ -4430,23 +4431,14 @@ var opencodeAdapter = createOpencodeAdapter();
4430
4431
 
4431
4432
  // packages/agent-runtime/src/codex/addendum.ts
4432
4433
  var CODEX_ADDENDUM = [
4433
- "Codex surfaces MCP tools under qualified names, and on some versions defers them. The",
4434
- "workspace tools are `mcp__cabane__query`, `mcp__cabane__mutate` and",
4435
- "`mcp__cabane__describe` \u2014 if they aren't in your visible tool list, locate them in",
4436
- "the deferred-tool inventory and invoke those exact qualified names; never conclude the",
4437
- "workspace is",
4438
- "absent without attempting discovery and invocation, and if a call fails, report the recorded",
4439
- "error.",
4440
- turnControlPromptGuidance("mcp__cabane_companion__"),
4441
- // Every ancillary tool is written as Codex's own tool list shows it — qualified — so the sentence
4442
- // instructing exact qualified names doesn't contradict itself. The bare `query` / `mutate` below
4443
- // stay: that sentence is about operation names, after the qualified forms are given.
4444
- "The ancillary tools are `mcp__cabane__read_binary`, `mcp__cabane__upload`,",
4445
- "`mcp__cabane__begin_upload`, `mcp__cabane__finalize_upload` and",
4446
- "`mcp__cabane__mint_render_token` \u2014 all possibly deferred too.",
4447
- "There is no Cabane `read`/`write`/`search` tool \u2014 those are",
4448
- "operation NAMES you pass to `query` / `mutate`."
4449
- ].join(" ");
4434
+ "- Workspace tools: `mcp__cabane__query`, `mcp__cabane__mutate`, `mcp__cabane__describe`.",
4435
+ "- File tools: `mcp__cabane__read_binary`, `mcp__cabane__upload`, `mcp__cabane__begin_upload`, `mcp__cabane__finalize_upload`.",
4436
+ "- Page verification: `mcp__cabane__mint_render_token`.",
4437
+ "- Codex may defer MCP tools. If a listed tool is missing, search the deferred-tool inventory and call the matching tool by its exact name. Report discovery or call failures with the recorded error.",
4438
+ "- Names such as `files.read` are operations passed to `query` or `mutate`, not separate tools.",
4439
+ "",
4440
+ turnControlPromptGuidance("mcp__cabane_companion__")
4441
+ ].join("\n");
4450
4442
 
4451
4443
  // packages/agent-runtime/src/codex/events.ts
4452
4444
  function asRecord3(v) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cabane/companion",
3
- "version": "0.6.226",
3
+ "version": "0.6.228",
4
4
  "type": "module",
5
5
  "description": "The Cabane Companion (headless): connect an 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",