@cabane/companion 0.6.2 → 0.6.4
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 +19 -5
- package/dist/pairing-config.js +2 -2
- package/dist/runtime.js +16 -2
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -900,7 +900,7 @@ async function postJson(baseUrl, path3, body) {
|
|
|
900
900
|
if (res.status >= 400) {
|
|
901
901
|
if (res.status === 404 && path3.endsWith("/code")) {
|
|
902
902
|
throw new CompanionError(
|
|
903
|
-
`
|
|
903
|
+
`no device-flow pairing endpoint at ${baseUrl}. Either that server predates \`cabane-companion pair\`, or it isn't a Cabane API origin \u2014 the hosted app is https://app.cabane.ai (pass \`--server <url>\` for your own instance).`
|
|
904
904
|
);
|
|
905
905
|
}
|
|
906
906
|
const msg = parsed && typeof parsed === "object" && "error" in parsed ? String(parsed.error) : `${res.status}`;
|
|
@@ -959,7 +959,7 @@ async function runDeviceFlow(baseUrl, print, opts = {}) {
|
|
|
959
959
|
}
|
|
960
960
|
|
|
961
961
|
// src/pairing-config.ts
|
|
962
|
-
var DEFAULT_BASE_URL = "https://cabane.ai";
|
|
962
|
+
var DEFAULT_BASE_URL = "https://app.cabane.ai";
|
|
963
963
|
function resolvePairBaseUrl(server) {
|
|
964
964
|
const raw = (server ?? process.env.CABANE_BASE_URL ?? DEFAULT_BASE_URL).trim();
|
|
965
965
|
if (!isAllowedBaseUrl(raw)) {
|
|
@@ -7331,7 +7331,10 @@ ${reason}`,
|
|
|
7331
7331
|
...this.opts.local.claudeCode ? { claudeCode: this.opts.local.claudeCode } : {}
|
|
7332
7332
|
});
|
|
7333
7333
|
const onWarn = (msg, meta) => turnLog.warn(meta ?? {}, msg);
|
|
7334
|
-
const adapters = [
|
|
7334
|
+
const adapters = [];
|
|
7335
|
+
if (this.opts.claudeCodeAvailable?.() ?? true) {
|
|
7336
|
+
adapters.push(createClaudeCodeAdapter({ queryFn: this.opts.queryFn, onWarn }));
|
|
7337
|
+
}
|
|
7335
7338
|
if (this.opts.opencodeServerUrl) {
|
|
7336
7339
|
adapters.push(createOpencodeAdapter({ serverUrl: this.opts.opencodeServerUrl, onWarn }));
|
|
7337
7340
|
}
|
|
@@ -8384,7 +8387,7 @@ var CompanionSupervisor = class {
|
|
|
8384
8387
|
// until the first re-probe lands. Same exit-0 `claude --version` signal
|
|
8385
8388
|
// either way, so the manifest's claude-code advertising is unchanged in
|
|
8386
8389
|
// meaning — just refreshed on the beat instead of frozen at boot.
|
|
8387
|
-
claudeCode: this.
|
|
8390
|
+
claudeCode: this.claudeCodePresent(),
|
|
8388
8391
|
opencode: !!this.config.opencode?.serverUrl,
|
|
8389
8392
|
// CT481: advertise codex when the operator enabled it (config-gated,
|
|
8390
8393
|
// like opencode — the CLI's presence is the operator's responsibility;
|
|
@@ -8607,6 +8610,13 @@ var CompanionSupervisor = class {
|
|
|
8607
8610
|
"companion: stopped agent (unassigned)"
|
|
8608
8611
|
);
|
|
8609
8612
|
}
|
|
8613
|
+
// CT833: is Claude Code on this machine right now? The ONE signal both the
|
|
8614
|
+
// heartbeat manifest and the dispatcher's adapter registry read, so what the
|
|
8615
|
+
// device advertises and what it can actually select can't disagree. Live (the
|
|
8616
|
+
// per-beat re-probe), falling back to the boot probe until the first one lands.
|
|
8617
|
+
claudeCodePresent() {
|
|
8618
|
+
return this.harnessSignals?.claudeOnPath ?? this.claudeCode;
|
|
8619
|
+
}
|
|
8610
8620
|
buildDispatcher(ctx) {
|
|
8611
8621
|
if (this.dispatcherFactory) return this.dispatcherFactory(ctx);
|
|
8612
8622
|
return new Dispatcher({
|
|
@@ -8624,6 +8634,10 @@ var CompanionSupervisor = class {
|
|
|
8624
8634
|
}),
|
|
8625
8635
|
runConfig: ctx.runConfig,
|
|
8626
8636
|
log: this.log,
|
|
8637
|
+
// CT833: register the claude-code adapter only when `claude` is actually on
|
|
8638
|
+
// this machine — read per turn (not captured here), so a harness installed
|
|
8639
|
+
// after boot works on the next turn exactly as it appears on the next beat.
|
|
8640
|
+
claudeCodeAvailable: () => this.claudeCodePresent(),
|
|
8627
8641
|
// CT270: the opencode server URL (operator-configured), when this device
|
|
8628
8642
|
// offers the opencode runtime. Threaded so an opencode turn selects the
|
|
8629
8643
|
// opencode adapter; unset leaves the device claude-code-only.
|
|
@@ -9801,7 +9815,7 @@ program.name("cabane-companion").description(
|
|
|
9801
9815
|
).version(COMPANION_VERSION);
|
|
9802
9816
|
program.command("pair").description(
|
|
9803
9817
|
"pair this device with cabane \u2014 shows a short code you confirm in Settings \u2192 Devices."
|
|
9804
|
-
).allowExcessArguments(false).option("--server <url>", "the cabane instance to pair with (default https://cabane.ai)").action(async (opts) => {
|
|
9818
|
+
).allowExcessArguments(false).option("--server <url>", "the cabane instance to pair with (default https://app.cabane.ai)").action(async (opts) => {
|
|
9805
9819
|
await pair({
|
|
9806
9820
|
...opts.server !== void 0 ? { server: opts.server } : {}
|
|
9807
9821
|
});
|
package/dist/pairing-config.js
CHANGED
|
@@ -292,7 +292,7 @@ async function postJson(baseUrl, path, body) {
|
|
|
292
292
|
if (res.status >= 400) {
|
|
293
293
|
if (res.status === 404 && path.endsWith("/code")) {
|
|
294
294
|
throw new CompanionError(
|
|
295
|
-
`
|
|
295
|
+
`no device-flow pairing endpoint at ${baseUrl}. Either that server predates \`cabane-companion pair\`, or it isn't a Cabane API origin \u2014 the hosted app is https://app.cabane.ai (pass \`--server <url>\` for your own instance).`
|
|
296
296
|
);
|
|
297
297
|
}
|
|
298
298
|
const msg = parsed && typeof parsed === "object" && "error" in parsed ? String(parsed.error) : `${res.status}`;
|
|
@@ -351,7 +351,7 @@ async function runDeviceFlow(baseUrl, print, opts = {}) {
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
// src/pairing-config.ts
|
|
354
|
-
var DEFAULT_BASE_URL = "https://cabane.ai";
|
|
354
|
+
var DEFAULT_BASE_URL = "https://app.cabane.ai";
|
|
355
355
|
function resolvePairBaseUrl(server) {
|
|
356
356
|
const raw = (server ?? process.env.CABANE_BASE_URL ?? DEFAULT_BASE_URL).trim();
|
|
357
357
|
if (!isAllowedBaseUrl(raw)) {
|
package/dist/runtime.js
CHANGED
|
@@ -6984,7 +6984,10 @@ ${reason}`,
|
|
|
6984
6984
|
...this.opts.local.claudeCode ? { claudeCode: this.opts.local.claudeCode } : {}
|
|
6985
6985
|
});
|
|
6986
6986
|
const onWarn = (msg, meta) => turnLog.warn(meta ?? {}, msg);
|
|
6987
|
-
const adapters = [
|
|
6987
|
+
const adapters = [];
|
|
6988
|
+
if (this.opts.claudeCodeAvailable?.() ?? true) {
|
|
6989
|
+
adapters.push(createClaudeCodeAdapter({ queryFn: this.opts.queryFn, onWarn }));
|
|
6990
|
+
}
|
|
6988
6991
|
if (this.opts.opencodeServerUrl) {
|
|
6989
6992
|
adapters.push(createOpencodeAdapter({ serverUrl: this.opts.opencodeServerUrl, onWarn }));
|
|
6990
6993
|
}
|
|
@@ -8037,7 +8040,7 @@ var CompanionSupervisor = class {
|
|
|
8037
8040
|
// until the first re-probe lands. Same exit-0 `claude --version` signal
|
|
8038
8041
|
// either way, so the manifest's claude-code advertising is unchanged in
|
|
8039
8042
|
// meaning — just refreshed on the beat instead of frozen at boot.
|
|
8040
|
-
claudeCode: this.
|
|
8043
|
+
claudeCode: this.claudeCodePresent(),
|
|
8041
8044
|
opencode: !!this.config.opencode?.serverUrl,
|
|
8042
8045
|
// CT481: advertise codex when the operator enabled it (config-gated,
|
|
8043
8046
|
// like opencode — the CLI's presence is the operator's responsibility;
|
|
@@ -8260,6 +8263,13 @@ var CompanionSupervisor = class {
|
|
|
8260
8263
|
"companion: stopped agent (unassigned)"
|
|
8261
8264
|
);
|
|
8262
8265
|
}
|
|
8266
|
+
// CT833: is Claude Code on this machine right now? The ONE signal both the
|
|
8267
|
+
// heartbeat manifest and the dispatcher's adapter registry read, so what the
|
|
8268
|
+
// device advertises and what it can actually select can't disagree. Live (the
|
|
8269
|
+
// per-beat re-probe), falling back to the boot probe until the first one lands.
|
|
8270
|
+
claudeCodePresent() {
|
|
8271
|
+
return this.harnessSignals?.claudeOnPath ?? this.claudeCode;
|
|
8272
|
+
}
|
|
8263
8273
|
buildDispatcher(ctx) {
|
|
8264
8274
|
if (this.dispatcherFactory) return this.dispatcherFactory(ctx);
|
|
8265
8275
|
return new Dispatcher({
|
|
@@ -8277,6 +8287,10 @@ var CompanionSupervisor = class {
|
|
|
8277
8287
|
}),
|
|
8278
8288
|
runConfig: ctx.runConfig,
|
|
8279
8289
|
log: this.log,
|
|
8290
|
+
// CT833: register the claude-code adapter only when `claude` is actually on
|
|
8291
|
+
// this machine — read per turn (not captured here), so a harness installed
|
|
8292
|
+
// after boot works on the next turn exactly as it appears on the next beat.
|
|
8293
|
+
claudeCodeAvailable: () => this.claudeCodePresent(),
|
|
8280
8294
|
// CT270: the opencode server URL (operator-configured), when this device
|
|
8281
8295
|
// offers the opencode runtime. Threaded so an opencode turn selects the
|
|
8282
8296
|
// opencode adapter; unset leaves the device claude-code-only.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cabane/companion",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
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",
|