@cabane/companion 0.6.43 → 0.6.45
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 +26 -11
- package/dist/runtime.js +26 -11
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6678,7 +6678,6 @@ var SUMMON_AGENT_TOOL = "summon_agent";
|
|
|
6678
6678
|
var SUMMON_AGENT_TOOL_NAME = `mcp__${COMPANION_LOCAL_MCP_SERVER}__${SUMMON_AGENT_TOOL}`;
|
|
6679
6679
|
var COMPANION_LOCAL_TOOL_GLOB = `mcp__${COMPANION_LOCAL_MCP_SERVER}__*`;
|
|
6680
6680
|
var SKIP_TURN_TOOL = "skip_turn";
|
|
6681
|
-
var SKIP_TURN_TOOL_NAME = `mcp__${COMPANION_LOCAL_MCP_SERVER}__${SKIP_TURN_TOOL}`;
|
|
6682
6681
|
var ASK_TOOL = "ask";
|
|
6683
6682
|
var ASK_TOOL_NAME = `mcp__${COMPANION_LOCAL_MCP_SERVER}__${ASK_TOOL}`;
|
|
6684
6683
|
var SUB_AGENT_TOOL = "sub_agent";
|
|
@@ -8828,11 +8827,7 @@ var mcpSseServerSchema = z15.object({
|
|
|
8828
8827
|
url: z15.string().url(),
|
|
8829
8828
|
headers: z15.record(z15.string(), z15.string()).optional()
|
|
8830
8829
|
});
|
|
8831
|
-
var mcpServerDefSchema = z15.union([
|
|
8832
|
-
mcpHttpServerSchema,
|
|
8833
|
-
mcpSseServerSchema,
|
|
8834
|
-
mcpStdioServerSchema
|
|
8835
|
-
]);
|
|
8830
|
+
var mcpServerDefSchema = z15.union([mcpHttpServerSchema, mcpSseServerSchema, mcpStdioServerSchema]);
|
|
8836
8831
|
var thinkingConfigSchema = z15.discriminatedUnion("type", [
|
|
8837
8832
|
z15.object({ type: z15.literal("adaptive") }),
|
|
8838
8833
|
z15.object({ type: z15.literal("enabled"), budgetTokens: z15.number().int().positive().optional() }),
|
|
@@ -8974,6 +8969,7 @@ var COMPANION_VERSION = pkg.version;
|
|
|
8974
8969
|
|
|
8975
8970
|
// src/supervisor.ts
|
|
8976
8971
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
8972
|
+
var SHUTDOWN_HEARTBEAT_WAIT_MS = 1e3;
|
|
8977
8973
|
function positiveIntEnv(name) {
|
|
8978
8974
|
const raw = process.env[name];
|
|
8979
8975
|
if (!raw) return void 0;
|
|
@@ -9054,7 +9050,8 @@ var CompanionSupervisor = class {
|
|
|
9054
9050
|
{ protocolVersion: TURN_PROTOCOL_VERSION, version: COMPANION_VERSION },
|
|
9055
9051
|
"companion: starting"
|
|
9056
9052
|
);
|
|
9057
|
-
|
|
9053
|
+
const startupHarnessRefresh = this.refreshHarnessStatuses();
|
|
9054
|
+
this.trackHeartbeat(startupHarnessRefresh);
|
|
9058
9055
|
if (!this.config.deviceToken) {
|
|
9059
9056
|
this.log.warn("companion: not paired (no device token) \u2014 run `cabane-companion pair`");
|
|
9060
9057
|
process.stdout.write(
|
|
@@ -9085,7 +9082,11 @@ var CompanionSupervisor = class {
|
|
|
9085
9082
|
});
|
|
9086
9083
|
this.deviceSub.start();
|
|
9087
9084
|
await this.refreshAssignments();
|
|
9088
|
-
|
|
9085
|
+
const firstHeartbeat = startupHarnessRefresh.then(async () => {
|
|
9086
|
+
if (this.stopped) return;
|
|
9087
|
+
await this.sendHeartbeat();
|
|
9088
|
+
});
|
|
9089
|
+
this.trackHeartbeat(firstHeartbeat);
|
|
9089
9090
|
this.heartbeatTimer = setInterval(() => this.kickHeartbeat(), HEARTBEAT_INTERVAL_MS);
|
|
9090
9091
|
this.heartbeatTimer.unref?.();
|
|
9091
9092
|
this.pollTimer = setInterval(() => void this.refreshAssignments(), ASSIGNMENTS_POLL_MS);
|
|
@@ -9103,8 +9104,10 @@ var CompanionSupervisor = class {
|
|
|
9103
9104
|
}
|
|
9104
9105
|
// ---- device-level loops ----
|
|
9105
9106
|
kickHeartbeat() {
|
|
9106
|
-
if (this.inFlightHeartbeat) return;
|
|
9107
|
-
|
|
9107
|
+
if (this.stopped || this.inFlightHeartbeat) return;
|
|
9108
|
+
this.trackHeartbeat(this.sendHeartbeat());
|
|
9109
|
+
}
|
|
9110
|
+
trackHeartbeat(pending) {
|
|
9108
9111
|
this.inFlightHeartbeat = pending;
|
|
9109
9112
|
void pending.finally(() => {
|
|
9110
9113
|
if (this.inFlightHeartbeat === pending) this.inFlightHeartbeat = null;
|
|
@@ -9858,7 +9861,7 @@ var CompanionSupervisor = class {
|
|
|
9858
9861
|
if (wr.sub) wr.sub.stop();
|
|
9859
9862
|
}
|
|
9860
9863
|
await Promise.all([
|
|
9861
|
-
...heartbeat ? [heartbeat] : [],
|
|
9864
|
+
...heartbeat ? [waitForBoundedHeartbeat(heartbeat)] : [],
|
|
9862
9865
|
...this.deviceSub ? [this.deviceSub.finished] : [],
|
|
9863
9866
|
...[...this.workspaces.values()].flatMap((wr) => wr.sub ? [wr.sub.finished] : [])
|
|
9864
9867
|
]);
|
|
@@ -9871,6 +9874,18 @@ var CompanionSupervisor = class {
|
|
|
9871
9874
|
this.reexecFn();
|
|
9872
9875
|
}
|
|
9873
9876
|
};
|
|
9877
|
+
async function waitForBoundedHeartbeat(heartbeat) {
|
|
9878
|
+
let timer = null;
|
|
9879
|
+
const timeout = new Promise((resolve) => {
|
|
9880
|
+
timer = setTimeout(resolve, SHUTDOWN_HEARTBEAT_WAIT_MS);
|
|
9881
|
+
timer.unref?.();
|
|
9882
|
+
});
|
|
9883
|
+
try {
|
|
9884
|
+
await Promise.race([heartbeat, timeout]);
|
|
9885
|
+
} finally {
|
|
9886
|
+
if (timer) clearTimeout(timer);
|
|
9887
|
+
}
|
|
9888
|
+
}
|
|
9874
9889
|
function defaultReexec() {
|
|
9875
9890
|
clearRuntimeState();
|
|
9876
9891
|
void import("child_process").then(({ spawn: spawn6 }) => {
|
package/dist/runtime.js
CHANGED
|
@@ -6187,7 +6187,6 @@ var SUMMON_AGENT_TOOL = "summon_agent";
|
|
|
6187
6187
|
var SUMMON_AGENT_TOOL_NAME = `mcp__${COMPANION_LOCAL_MCP_SERVER}__${SUMMON_AGENT_TOOL}`;
|
|
6188
6188
|
var COMPANION_LOCAL_TOOL_GLOB = `mcp__${COMPANION_LOCAL_MCP_SERVER}__*`;
|
|
6189
6189
|
var SKIP_TURN_TOOL = "skip_turn";
|
|
6190
|
-
var SKIP_TURN_TOOL_NAME = `mcp__${COMPANION_LOCAL_MCP_SERVER}__${SKIP_TURN_TOOL}`;
|
|
6191
6190
|
var ASK_TOOL = "ask";
|
|
6192
6191
|
var ASK_TOOL_NAME = `mcp__${COMPANION_LOCAL_MCP_SERVER}__${ASK_TOOL}`;
|
|
6193
6192
|
var SUB_AGENT_TOOL = "sub_agent";
|
|
@@ -8337,11 +8336,7 @@ var mcpSseServerSchema = z15.object({
|
|
|
8337
8336
|
url: z15.string().url(),
|
|
8338
8337
|
headers: z15.record(z15.string(), z15.string()).optional()
|
|
8339
8338
|
});
|
|
8340
|
-
var mcpServerDefSchema = z15.union([
|
|
8341
|
-
mcpHttpServerSchema,
|
|
8342
|
-
mcpSseServerSchema,
|
|
8343
|
-
mcpStdioServerSchema
|
|
8344
|
-
]);
|
|
8339
|
+
var mcpServerDefSchema = z15.union([mcpHttpServerSchema, mcpSseServerSchema, mcpStdioServerSchema]);
|
|
8345
8340
|
var thinkingConfigSchema = z15.discriminatedUnion("type", [
|
|
8346
8341
|
z15.object({ type: z15.literal("adaptive") }),
|
|
8347
8342
|
z15.object({ type: z15.literal("enabled"), budgetTokens: z15.number().int().positive().optional() }),
|
|
@@ -8483,6 +8478,7 @@ var COMPANION_VERSION = pkg.version;
|
|
|
8483
8478
|
|
|
8484
8479
|
// src/supervisor.ts
|
|
8485
8480
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
8481
|
+
var SHUTDOWN_HEARTBEAT_WAIT_MS = 1e3;
|
|
8486
8482
|
function positiveIntEnv(name) {
|
|
8487
8483
|
const raw = process.env[name];
|
|
8488
8484
|
if (!raw) return void 0;
|
|
@@ -8563,7 +8559,8 @@ var CompanionSupervisor = class {
|
|
|
8563
8559
|
{ protocolVersion: TURN_PROTOCOL_VERSION, version: COMPANION_VERSION },
|
|
8564
8560
|
"companion: starting"
|
|
8565
8561
|
);
|
|
8566
|
-
|
|
8562
|
+
const startupHarnessRefresh = this.refreshHarnessStatuses();
|
|
8563
|
+
this.trackHeartbeat(startupHarnessRefresh);
|
|
8567
8564
|
if (!this.config.deviceToken) {
|
|
8568
8565
|
this.log.warn("companion: not paired (no device token) \u2014 run `cabane-companion pair`");
|
|
8569
8566
|
process.stdout.write(
|
|
@@ -8594,7 +8591,11 @@ var CompanionSupervisor = class {
|
|
|
8594
8591
|
});
|
|
8595
8592
|
this.deviceSub.start();
|
|
8596
8593
|
await this.refreshAssignments();
|
|
8597
|
-
|
|
8594
|
+
const firstHeartbeat = startupHarnessRefresh.then(async () => {
|
|
8595
|
+
if (this.stopped) return;
|
|
8596
|
+
await this.sendHeartbeat();
|
|
8597
|
+
});
|
|
8598
|
+
this.trackHeartbeat(firstHeartbeat);
|
|
8598
8599
|
this.heartbeatTimer = setInterval(() => this.kickHeartbeat(), HEARTBEAT_INTERVAL_MS);
|
|
8599
8600
|
this.heartbeatTimer.unref?.();
|
|
8600
8601
|
this.pollTimer = setInterval(() => void this.refreshAssignments(), ASSIGNMENTS_POLL_MS);
|
|
@@ -8612,8 +8613,10 @@ var CompanionSupervisor = class {
|
|
|
8612
8613
|
}
|
|
8613
8614
|
// ---- device-level loops ----
|
|
8614
8615
|
kickHeartbeat() {
|
|
8615
|
-
if (this.inFlightHeartbeat) return;
|
|
8616
|
-
|
|
8616
|
+
if (this.stopped || this.inFlightHeartbeat) return;
|
|
8617
|
+
this.trackHeartbeat(this.sendHeartbeat());
|
|
8618
|
+
}
|
|
8619
|
+
trackHeartbeat(pending) {
|
|
8617
8620
|
this.inFlightHeartbeat = pending;
|
|
8618
8621
|
void pending.finally(() => {
|
|
8619
8622
|
if (this.inFlightHeartbeat === pending) this.inFlightHeartbeat = null;
|
|
@@ -9367,7 +9370,7 @@ var CompanionSupervisor = class {
|
|
|
9367
9370
|
if (wr.sub) wr.sub.stop();
|
|
9368
9371
|
}
|
|
9369
9372
|
await Promise.all([
|
|
9370
|
-
...heartbeat ? [heartbeat] : [],
|
|
9373
|
+
...heartbeat ? [waitForBoundedHeartbeat(heartbeat)] : [],
|
|
9371
9374
|
...this.deviceSub ? [this.deviceSub.finished] : [],
|
|
9372
9375
|
...[...this.workspaces.values()].flatMap((wr) => wr.sub ? [wr.sub.finished] : [])
|
|
9373
9376
|
]);
|
|
@@ -9380,6 +9383,18 @@ var CompanionSupervisor = class {
|
|
|
9380
9383
|
this.reexecFn();
|
|
9381
9384
|
}
|
|
9382
9385
|
};
|
|
9386
|
+
async function waitForBoundedHeartbeat(heartbeat) {
|
|
9387
|
+
let timer = null;
|
|
9388
|
+
const timeout = new Promise((resolve) => {
|
|
9389
|
+
timer = setTimeout(resolve, SHUTDOWN_HEARTBEAT_WAIT_MS);
|
|
9390
|
+
timer.unref?.();
|
|
9391
|
+
});
|
|
9392
|
+
try {
|
|
9393
|
+
await Promise.race([heartbeat, timeout]);
|
|
9394
|
+
} finally {
|
|
9395
|
+
if (timer) clearTimeout(timer);
|
|
9396
|
+
}
|
|
9397
|
+
}
|
|
9383
9398
|
function defaultReexec() {
|
|
9384
9399
|
clearRuntimeState();
|
|
9385
9400
|
void import("child_process").then(({ spawn: spawn5 }) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cabane/companion",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.45",
|
|
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",
|