@cabane/companion 0.6.9 → 0.6.11
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 +1 -1
- package/dist/cli.js +10 -6
- package/dist/runtime.js +10 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,7 +76,7 @@ cabane-companion start
|
|
|
76
76
|
|
|
77
77
|
A headless machine needs no browser of its own: run `cabane-companion pair` on it, then open **Settings → Connectors** in any browser you're signed in to and enter the short code it printed. The device token is delivered straight to the waiting CLI over the pairing channel — nothing is ever copied or pasted.
|
|
78
78
|
|
|
79
|
-
A freshly paired device runs nothing yet — it has no agents. In **Workspace settings → Agents**, set an agent's **executor** to this device. The running Companion picks the assignment up within a minute (no restart), and the next time you
|
|
79
|
+
A freshly paired device runs nothing yet — it has no agents. In **Workspace settings → Agents**, set an agent's **executor** to this device. The running Companion picks the assignment up within a minute (no restart), and the next time you address that agent — put it on a message's **To** line — the reply comes from your own machine. Assign agents in as many of your workspaces as you like — one running Companion serves them all.
|
|
80
80
|
|
|
81
81
|
## Commands
|
|
82
82
|
|
package/dist/cli.js
CHANGED
|
@@ -6314,9 +6314,11 @@ function createSummonMcpServer(summonState, skipState, askState, subAgentCreate,
|
|
|
6314
6314
|
tools: [
|
|
6315
6315
|
tool(
|
|
6316
6316
|
SUMMON_AGENT_TOOL,
|
|
6317
|
-
"Summon another agent into THIS conversation \u2014 dispatch a peer to reply here on your turn. Use it to hand part of the work to a teammate, or pull in an expert, without leaving the conversation. Pass the peer's `agentId`
|
|
6317
|
+
"Summon another agent into THIS conversation \u2014 dispatch a peer to reply here on your turn. Use it to hand part of the work to a teammate, or pull in an expert, without leaving the conversation. Pass the peer's `agentId` \u2014 every agent's handle and id is on the roster in your turn context. The peer is dispatched on your turn's final reply, so write the context/ask into that reply first \u2014 it receives your message + this conversation to work from. Writing `@handle` in your prose does NOT summon anyone (agent prose never dispatches); this tool is the only in-thread lever. Single target \u2014 the last call wins. Summoning yourself is a no-op. Reach for it when the human wants the peer's answer right HERE, in front of them \u2014 the reply lands in this thread, so there's no return to wire (a return is for work YOU consume, never a courtesy notification). A handoff to a DIFFERENT conversation is `cabane.conversations.create` / `cabane.conversations.post` with their `dispatch` field instead.",
|
|
6318
6318
|
{
|
|
6319
|
-
agentId: z12.string().uuid().describe(
|
|
6319
|
+
agentId: z12.string().uuid().describe(
|
|
6320
|
+
"The peer agent to summon \u2014 a workspace agent id, from your turn context's roster."
|
|
6321
|
+
)
|
|
6320
6322
|
},
|
|
6321
6323
|
async (args) => {
|
|
6322
6324
|
summonState.agentId = args.agentId;
|
|
@@ -6346,9 +6348,11 @@ function createSummonMcpServer(summonState, skipState, askState, subAgentCreate,
|
|
|
6346
6348
|
...askState ? [
|
|
6347
6349
|
tool(
|
|
6348
6350
|
ASK_TOOL,
|
|
6349
|
-
"Ask a HUMAN a structured question (or a short LIST of them) you need answered to continue, then END your turn \u2014 don't wait for the reply. Use it when you genuinely can't proceed without a person's input (a decision only they can make, a missing fact). Pass `targetUserId` (a workspace member's user id \u2014
|
|
6351
|
+
"Ask a HUMAN a structured question (or a short LIST of them) you need answered to continue, then END your turn \u2014 don't wait for the reply. Use it when you genuinely can't proceed without a person's input (a decision only they can make, a missing fact). Pass `targetUserId` (a workspace member's user id \u2014 every person's id is on the roster in your turn context). Two forms: a SINGLE question \u2014 a `headline` (the actual question as one clear, capitalized sentence ending in `?`, \"Do we go to prod?\") plus a short `question` body for the framing the headline can't hold \u2014 OR, when a plan ends with SEVERAL bounded decisions at once, a `questions` array of 1\u20135 items, each `{ headline, body?, options? }`. **Prefer the list over cramming the extra decisions into prose or dropping them** \u2014 end the turn with one ask carrying every question, never pick one and bury the rest. Each question keeps the same form rules: a one-sentence `headline`, a short `body` frame (NOT a report \u2014 your status, links, and detail go in your REPLY, and the body renders inline markdown only: links/emphasis/inline code, no bulleted lists or headings), and 2\u20134 `options` when the answer is a bounded choice \u2014 for a yes/no go-ahead always pass them, so it's one click, not a typed reply. An option can be a short button label or a whole sentence. Provide EITHER `question` (single) or `questions` (array), never both. The ask is a first-class attention item aimed at that person; your final reply carries the surrounding CONTEXT (what you found, why you're stuck), the ask carries the QUESTION(S). An open ask marks you as blocked until EVERY question is answered, so raise one only when you truly can't proceed \u2014 never ceremonially. One ask per turn (last call wins). After asking, stop \u2014 when the person replies addressed to you, the ask resolves and you resume; other people's or agents' messages may wake you but leave it open. Targets a human only; to hand work to another AGENT use summon/dispatch instead.",
|
|
6350
6352
|
{
|
|
6351
|
-
targetUserId: z12.string().uuid().describe(
|
|
6353
|
+
targetUserId: z12.string().uuid().describe(
|
|
6354
|
+
"The workspace member (human) to ask \u2014 a user id, from your turn context's roster."
|
|
6355
|
+
),
|
|
6352
6356
|
question: z12.string().min(1).max(400).optional().describe(
|
|
6353
6357
|
"SINGLE-question form: a short body \u2014 one or two sentences of framing the headline can't hold. NOT a report (capped, inline markdown only). Provide EITHER this or `questions`, not both. Put the crisp one-sentence question in `headline`."
|
|
6354
6358
|
),
|
|
@@ -6423,7 +6427,7 @@ function createSummonMcpServer(summonState, skipState, askState, subAgentCreate,
|
|
|
6423
6427
|
"The sub-agent's opening instruction \u2014 self-contained (it starts with a fresh context window; only this prompt + the thread it lands in)."
|
|
6424
6428
|
),
|
|
6425
6429
|
agentId: z12.string().uuid().optional().describe(
|
|
6426
|
-
"Optional peer to run the sub-agent as (a workspace agent id from
|
|
6430
|
+
"Optional peer to run the sub-agent as (a workspace agent id, from your turn context's roster); omit to spawn yourself with a fresh context window."
|
|
6427
6431
|
),
|
|
6428
6432
|
title: z12.string().max(200).optional().describe("Optional title for the child thread (result chips link it).")
|
|
6429
6433
|
},
|
|
@@ -7087,7 +7091,7 @@ function describeSubAgentError(status2, body) {
|
|
|
7087
7091
|
case "callout_depth_exceeded":
|
|
7088
7092
|
return "sub_agent: this would nest sub-agents too deep (max 3 levels). Have the current worker report back rather than spawning another layer.";
|
|
7089
7093
|
case "dispatch_agent_not_found":
|
|
7090
|
-
return "sub_agent: no live agent in this workspace matches that `agentId`. Check
|
|
7094
|
+
return "sub_agent: no live agent in this workspace matches that `agentId`. Check the roster in your turn context, or omit `agentId` to spawn yourself.";
|
|
7091
7095
|
case "dispatch_return_requires_turn":
|
|
7092
7096
|
case "dispatch_return_requires_agent":
|
|
7093
7097
|
case "dispatch_return_requires_dispatch":
|
package/dist/runtime.js
CHANGED
|
@@ -5967,9 +5967,11 @@ function createSummonMcpServer(summonState, skipState, askState, subAgentCreate,
|
|
|
5967
5967
|
tools: [
|
|
5968
5968
|
tool(
|
|
5969
5969
|
SUMMON_AGENT_TOOL,
|
|
5970
|
-
"Summon another agent into THIS conversation \u2014 dispatch a peer to reply here on your turn. Use it to hand part of the work to a teammate, or pull in an expert, without leaving the conversation. Pass the peer's `agentId`
|
|
5970
|
+
"Summon another agent into THIS conversation \u2014 dispatch a peer to reply here on your turn. Use it to hand part of the work to a teammate, or pull in an expert, without leaving the conversation. Pass the peer's `agentId` \u2014 every agent's handle and id is on the roster in your turn context. The peer is dispatched on your turn's final reply, so write the context/ask into that reply first \u2014 it receives your message + this conversation to work from. Writing `@handle` in your prose does NOT summon anyone (agent prose never dispatches); this tool is the only in-thread lever. Single target \u2014 the last call wins. Summoning yourself is a no-op. Reach for it when the human wants the peer's answer right HERE, in front of them \u2014 the reply lands in this thread, so there's no return to wire (a return is for work YOU consume, never a courtesy notification). A handoff to a DIFFERENT conversation is `cabane.conversations.create` / `cabane.conversations.post` with their `dispatch` field instead.",
|
|
5971
5971
|
{
|
|
5972
|
-
agentId: z12.string().uuid().describe(
|
|
5972
|
+
agentId: z12.string().uuid().describe(
|
|
5973
|
+
"The peer agent to summon \u2014 a workspace agent id, from your turn context's roster."
|
|
5974
|
+
)
|
|
5973
5975
|
},
|
|
5974
5976
|
async (args) => {
|
|
5975
5977
|
summonState.agentId = args.agentId;
|
|
@@ -5999,9 +6001,11 @@ function createSummonMcpServer(summonState, skipState, askState, subAgentCreate,
|
|
|
5999
6001
|
...askState ? [
|
|
6000
6002
|
tool(
|
|
6001
6003
|
ASK_TOOL,
|
|
6002
|
-
"Ask a HUMAN a structured question (or a short LIST of them) you need answered to continue, then END your turn \u2014 don't wait for the reply. Use it when you genuinely can't proceed without a person's input (a decision only they can make, a missing fact). Pass `targetUserId` (a workspace member's user id \u2014
|
|
6004
|
+
"Ask a HUMAN a structured question (or a short LIST of them) you need answered to continue, then END your turn \u2014 don't wait for the reply. Use it when you genuinely can't proceed without a person's input (a decision only they can make, a missing fact). Pass `targetUserId` (a workspace member's user id \u2014 every person's id is on the roster in your turn context). Two forms: a SINGLE question \u2014 a `headline` (the actual question as one clear, capitalized sentence ending in `?`, \"Do we go to prod?\") plus a short `question` body for the framing the headline can't hold \u2014 OR, when a plan ends with SEVERAL bounded decisions at once, a `questions` array of 1\u20135 items, each `{ headline, body?, options? }`. **Prefer the list over cramming the extra decisions into prose or dropping them** \u2014 end the turn with one ask carrying every question, never pick one and bury the rest. Each question keeps the same form rules: a one-sentence `headline`, a short `body` frame (NOT a report \u2014 your status, links, and detail go in your REPLY, and the body renders inline markdown only: links/emphasis/inline code, no bulleted lists or headings), and 2\u20134 `options` when the answer is a bounded choice \u2014 for a yes/no go-ahead always pass them, so it's one click, not a typed reply. An option can be a short button label or a whole sentence. Provide EITHER `question` (single) or `questions` (array), never both. The ask is a first-class attention item aimed at that person; your final reply carries the surrounding CONTEXT (what you found, why you're stuck), the ask carries the QUESTION(S). An open ask marks you as blocked until EVERY question is answered, so raise one only when you truly can't proceed \u2014 never ceremonially. One ask per turn (last call wins). After asking, stop \u2014 when the person replies addressed to you, the ask resolves and you resume; other people's or agents' messages may wake you but leave it open. Targets a human only; to hand work to another AGENT use summon/dispatch instead.",
|
|
6003
6005
|
{
|
|
6004
|
-
targetUserId: z12.string().uuid().describe(
|
|
6006
|
+
targetUserId: z12.string().uuid().describe(
|
|
6007
|
+
"The workspace member (human) to ask \u2014 a user id, from your turn context's roster."
|
|
6008
|
+
),
|
|
6005
6009
|
question: z12.string().min(1).max(400).optional().describe(
|
|
6006
6010
|
"SINGLE-question form: a short body \u2014 one or two sentences of framing the headline can't hold. NOT a report (capped, inline markdown only). Provide EITHER this or `questions`, not both. Put the crisp one-sentence question in `headline`."
|
|
6007
6011
|
),
|
|
@@ -6076,7 +6080,7 @@ function createSummonMcpServer(summonState, skipState, askState, subAgentCreate,
|
|
|
6076
6080
|
"The sub-agent's opening instruction \u2014 self-contained (it starts with a fresh context window; only this prompt + the thread it lands in)."
|
|
6077
6081
|
),
|
|
6078
6082
|
agentId: z12.string().uuid().optional().describe(
|
|
6079
|
-
"Optional peer to run the sub-agent as (a workspace agent id from
|
|
6083
|
+
"Optional peer to run the sub-agent as (a workspace agent id, from your turn context's roster); omit to spawn yourself with a fresh context window."
|
|
6080
6084
|
),
|
|
6081
6085
|
title: z12.string().max(200).optional().describe("Optional title for the child thread (result chips link it).")
|
|
6082
6086
|
},
|
|
@@ -6740,7 +6744,7 @@ function describeSubAgentError(status, body) {
|
|
|
6740
6744
|
case "callout_depth_exceeded":
|
|
6741
6745
|
return "sub_agent: this would nest sub-agents too deep (max 3 levels). Have the current worker report back rather than spawning another layer.";
|
|
6742
6746
|
case "dispatch_agent_not_found":
|
|
6743
|
-
return "sub_agent: no live agent in this workspace matches that `agentId`. Check
|
|
6747
|
+
return "sub_agent: no live agent in this workspace matches that `agentId`. Check the roster in your turn context, or omit `agentId` to spawn yourself.";
|
|
6744
6748
|
case "dispatch_return_requires_turn":
|
|
6745
6749
|
case "dispatch_return_requires_agent":
|
|
6746
6750
|
case "dispatch_return_requires_dispatch":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cabane/companion",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.11",
|
|
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",
|