@cabane/companion 0.6.50 → 0.6.51
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 +75 -38
- package/dist/runtime.js +75 -38
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Command, Option } from "commander";
|
|
|
5
5
|
|
|
6
6
|
// src/control-socket.ts
|
|
7
7
|
import { createHash } from "crypto";
|
|
8
|
-
import { existsSync as existsSync2, rmSync as rmSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
8
|
+
import { chmodSync as chmodSync2, existsSync as existsSync2, rmSync as rmSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
9
9
|
import { createServer, connect } from "net";
|
|
10
10
|
import { join as join2 } from "path";
|
|
11
11
|
|
|
@@ -495,13 +495,18 @@ function deleteConfig() {
|
|
|
495
495
|
|
|
496
496
|
// src/control-socket.ts
|
|
497
497
|
var CONTROL_TIMEOUT_MS = 1e3;
|
|
498
|
+
var MAX_UNIX_SOCKET_PATH_BYTES = 103;
|
|
498
499
|
function controlSocketPath() {
|
|
499
500
|
const dir2 = cabaneDir();
|
|
501
|
+
const key = createHash("sha256").update(dir2).digest("hex").slice(0, 16);
|
|
500
502
|
if (process.platform === "win32") {
|
|
501
|
-
const key = createHash("sha256").update(dir2).digest("hex").slice(0, 16);
|
|
502
503
|
return `\\\\.\\pipe\\cabane-companion-${key}`;
|
|
503
504
|
}
|
|
504
|
-
|
|
505
|
+
const besideRuntime = join2(dir2, "companion.sock");
|
|
506
|
+
if (Buffer.byteLength(besideRuntime) <= MAX_UNIX_SOCKET_PATH_BYTES) return besideRuntime;
|
|
507
|
+
const filename = `cabane-companion-${key}.sock`;
|
|
508
|
+
const xdgPath = process.env.XDG_RUNTIME_DIR && existsSync2(process.env.XDG_RUNTIME_DIR) ? join2(process.env.XDG_RUNTIME_DIR, filename) : null;
|
|
509
|
+
return xdgPath && Buffer.byteLength(xdgPath) <= MAX_UNIX_SOCKET_PATH_BYTES ? xdgPath : join2("/tmp", filename);
|
|
505
510
|
}
|
|
506
511
|
async function startControlServer(handlers) {
|
|
507
512
|
const path = controlSocketPath();
|
|
@@ -522,6 +527,18 @@ async function startControlServer(handlers) {
|
|
|
522
527
|
resolve();
|
|
523
528
|
});
|
|
524
529
|
});
|
|
530
|
+
if (process.platform !== "win32") {
|
|
531
|
+
try {
|
|
532
|
+
chmodSync2(path, 384);
|
|
533
|
+
} catch (err) {
|
|
534
|
+
await new Promise((resolve) => server.close(() => resolve()));
|
|
535
|
+
try {
|
|
536
|
+
rmSync2(path, { force: true });
|
|
537
|
+
} catch {
|
|
538
|
+
}
|
|
539
|
+
throw err;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
525
542
|
server.on("error", () => {
|
|
526
543
|
});
|
|
527
544
|
return {
|
|
@@ -1348,7 +1365,7 @@ import { confirm as confirm2 } from "@inquirer/prompts";
|
|
|
1348
1365
|
|
|
1349
1366
|
// src/credentials.ts
|
|
1350
1367
|
import {
|
|
1351
|
-
chmodSync as
|
|
1368
|
+
chmodSync as chmodSync3,
|
|
1352
1369
|
existsSync as existsSync4,
|
|
1353
1370
|
mkdirSync as mkdirSync4,
|
|
1354
1371
|
readFileSync as readFileSync3,
|
|
@@ -1383,14 +1400,14 @@ function save(map) {
|
|
|
1383
1400
|
const path = credentialsPath();
|
|
1384
1401
|
mkdirSync4(dirname2(path), { recursive: true });
|
|
1385
1402
|
try {
|
|
1386
|
-
|
|
1403
|
+
chmodSync3(cabaneDir(), 448);
|
|
1387
1404
|
} catch {
|
|
1388
1405
|
}
|
|
1389
1406
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
1390
1407
|
try {
|
|
1391
1408
|
writeFileSync3(tmp, JSON.stringify(map, null, 2) + "\n", { mode: 384 });
|
|
1392
1409
|
try {
|
|
1393
|
-
|
|
1410
|
+
chmodSync3(tmp, 384);
|
|
1394
1411
|
} catch {
|
|
1395
1412
|
}
|
|
1396
1413
|
renameSync2(tmp, path);
|
|
@@ -7188,7 +7205,7 @@ function resolveMcpSecrets(mcpServers, store) {
|
|
|
7188
7205
|
}
|
|
7189
7206
|
|
|
7190
7207
|
// src/transcript-writer.ts
|
|
7191
|
-
import { appendFileSync, chmodSync as
|
|
7208
|
+
import { appendFileSync, chmodSync as chmodSync4, copyFileSync, mkdirSync as mkdirSync9, readdirSync, rmSync as rmSync6 } from "fs";
|
|
7192
7209
|
import { basename, dirname as dirname5, join as join13 } from "path";
|
|
7193
7210
|
function transcriptsDir() {
|
|
7194
7211
|
return join13(cabaneDir(), "transcripts");
|
|
@@ -7205,7 +7222,7 @@ var TranscriptWriter = class {
|
|
|
7205
7222
|
try {
|
|
7206
7223
|
mkdirSync9(dir2, { recursive: true });
|
|
7207
7224
|
try {
|
|
7208
|
-
|
|
7225
|
+
chmodSync4(dir2, 448);
|
|
7209
7226
|
} catch {
|
|
7210
7227
|
}
|
|
7211
7228
|
pruneOld(dir2, RETAIN);
|
|
@@ -7232,10 +7249,10 @@ var TranscriptWriter = class {
|
|
|
7232
7249
|
try {
|
|
7233
7250
|
const dir2 = join13(dirname5(this.path), "anomalies");
|
|
7234
7251
|
mkdirSync9(dir2, { recursive: true, mode: 448 });
|
|
7235
|
-
|
|
7252
|
+
chmodSync4(dir2, 448);
|
|
7236
7253
|
const target = join13(dir2, basename(this.path));
|
|
7237
7254
|
copyFileSync(this.path, target);
|
|
7238
|
-
|
|
7255
|
+
chmodSync4(target, 384);
|
|
7239
7256
|
pruneOld(dir2, ANOMALY_RETAIN);
|
|
7240
7257
|
} catch (err) {
|
|
7241
7258
|
this.fail(err);
|
|
@@ -10120,7 +10137,8 @@ async function createCompanionRuntime(opts = {}) {
|
|
|
10120
10137
|
if (!claim.acquired) {
|
|
10121
10138
|
return { ok: false, reason: "already-running", existing: claim.existing ?? null };
|
|
10122
10139
|
}
|
|
10123
|
-
|
|
10140
|
+
const clearRuntimeOnExit = () => clearRuntimeStateIfOurs(instanceId);
|
|
10141
|
+
process.on("exit", clearRuntimeOnExit);
|
|
10124
10142
|
const hub = new CompanionStateHub({
|
|
10125
10143
|
// CT29: one device, one base URL — the cabane instance this device is paired
|
|
10126
10144
|
// with. The dashboard's connection line shows it.
|
|
@@ -10155,41 +10173,60 @@ async function createCompanionRuntime(opts = {}) {
|
|
|
10155
10173
|
if (!result.ok) return { ok: false, error: result.error };
|
|
10156
10174
|
return { ok: true, message: connectedLine(runtime, verdict) };
|
|
10157
10175
|
};
|
|
10158
|
-
|
|
10159
|
-
status: () => hub.statusJson(),
|
|
10160
|
-
connect: async (runtime, serverUrl) => {
|
|
10161
|
-
const result = await connectHarness(runtime, serverUrl);
|
|
10162
|
-
return result.ok ? { ok: true, message: result.message } : { ok: false, message: result.error };
|
|
10163
|
-
},
|
|
10164
|
-
stop: () => void supervisor.requestStop()
|
|
10165
|
-
});
|
|
10176
|
+
let control = null;
|
|
10166
10177
|
let dashboard = null;
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10170
|
-
|
|
10171
|
-
|
|
10172
|
-
|
|
10178
|
+
try {
|
|
10179
|
+
control = await startControlServer({
|
|
10180
|
+
status: () => hub.statusJson(),
|
|
10181
|
+
connect: async (runtime, serverUrl) => {
|
|
10182
|
+
const result = await connectHarness(runtime, serverUrl);
|
|
10183
|
+
return result.ok ? { ok: true, message: result.message } : { ok: false, message: result.error };
|
|
10184
|
+
},
|
|
10185
|
+
stop: () => void supervisor.requestStop()
|
|
10186
|
+
});
|
|
10187
|
+
if (opts.dashboard) {
|
|
10188
|
+
const preferredPort = opts.port ?? cfg.dashboardPort;
|
|
10189
|
+
dashboard = await startDashboard({
|
|
10190
|
+
supervisor,
|
|
10191
|
+
hub,
|
|
10192
|
+
...preferredPort !== void 0 ? { port: preferredPort } : {}
|
|
10193
|
+
});
|
|
10194
|
+
hub.setDashboardUrl(dashboard.url);
|
|
10195
|
+
}
|
|
10196
|
+
writeRuntimeState({
|
|
10197
|
+
pid: process.pid,
|
|
10198
|
+
socket: control.path,
|
|
10199
|
+
...dashboard ? { url: dashboard.url, port: dashboard.port } : {},
|
|
10200
|
+
startedAt,
|
|
10201
|
+
// SJ495: the daemon launcher sets this env on the detached child, so the
|
|
10202
|
+
// marker records whether this companion is backgrounded (foreground start
|
|
10203
|
+
// leaves it unset → false).
|
|
10204
|
+
daemon: process.env.CABANE_COMPANION_DAEMON === "1",
|
|
10205
|
+
instanceId
|
|
10173
10206
|
});
|
|
10174
|
-
|
|
10207
|
+
clearCrash();
|
|
10208
|
+
} catch (err) {
|
|
10209
|
+
clearRuntimeStateIfOurs(instanceId);
|
|
10210
|
+
process.removeListener("exit", clearRuntimeOnExit);
|
|
10211
|
+
await Promise.allSettled([
|
|
10212
|
+
supervisor.shutdown(),
|
|
10213
|
+
...control ? [control.close()] : [],
|
|
10214
|
+
...dashboard ? [dashboard.close()] : []
|
|
10215
|
+
]);
|
|
10216
|
+
recordCrash({
|
|
10217
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
10218
|
+
...errorCode(err) ? { code: errorCode(err) } : {},
|
|
10219
|
+
origin: "startup",
|
|
10220
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
10221
|
+
});
|
|
10222
|
+
throw err;
|
|
10175
10223
|
}
|
|
10176
|
-
writeRuntimeState({
|
|
10177
|
-
pid: process.pid,
|
|
10178
|
-
socket: control.path,
|
|
10179
|
-
...dashboard ? { url: dashboard.url, port: dashboard.port } : {},
|
|
10180
|
-
startedAt,
|
|
10181
|
-
// SJ495: the daemon launcher sets this env on the detached child, so the
|
|
10182
|
-
// marker records whether this companion is backgrounded (foreground start
|
|
10183
|
-
// leaves it unset → false).
|
|
10184
|
-
daemon: process.env.CABANE_COMPANION_DAEMON === "1",
|
|
10185
|
-
instanceId
|
|
10186
|
-
});
|
|
10187
|
-
clearCrash();
|
|
10188
10224
|
let stopped = false;
|
|
10189
10225
|
const stop2 = async () => {
|
|
10190
10226
|
if (stopped) return;
|
|
10191
10227
|
stopped = true;
|
|
10192
10228
|
clearRuntimeStateIfOurs(instanceId);
|
|
10229
|
+
process.removeListener("exit", clearRuntimeOnExit);
|
|
10193
10230
|
try {
|
|
10194
10231
|
await supervisor.shutdown();
|
|
10195
10232
|
await closeSurfaces(control, dashboard);
|
package/dist/runtime.js
CHANGED
|
@@ -1387,17 +1387,22 @@ function resolveStaticDir() {
|
|
|
1387
1387
|
|
|
1388
1388
|
// src/control-socket.ts
|
|
1389
1389
|
import { createHash } from "crypto";
|
|
1390
|
-
import { existsSync as existsSync3, rmSync as rmSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
1390
|
+
import { chmodSync as chmodSync2, existsSync as existsSync3, rmSync as rmSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
1391
1391
|
import { createServer, connect } from "net";
|
|
1392
1392
|
import { join as join5 } from "path";
|
|
1393
1393
|
var CONTROL_TIMEOUT_MS = 1e3;
|
|
1394
|
+
var MAX_UNIX_SOCKET_PATH_BYTES = 103;
|
|
1394
1395
|
function controlSocketPath() {
|
|
1395
1396
|
const dir2 = cabaneDir();
|
|
1397
|
+
const key = createHash("sha256").update(dir2).digest("hex").slice(0, 16);
|
|
1396
1398
|
if (process.platform === "win32") {
|
|
1397
|
-
const key = createHash("sha256").update(dir2).digest("hex").slice(0, 16);
|
|
1398
1399
|
return `\\\\.\\pipe\\cabane-companion-${key}`;
|
|
1399
1400
|
}
|
|
1400
|
-
|
|
1401
|
+
const besideRuntime = join5(dir2, "companion.sock");
|
|
1402
|
+
if (Buffer.byteLength(besideRuntime) <= MAX_UNIX_SOCKET_PATH_BYTES) return besideRuntime;
|
|
1403
|
+
const filename = `cabane-companion-${key}.sock`;
|
|
1404
|
+
const xdgPath = process.env.XDG_RUNTIME_DIR && existsSync3(process.env.XDG_RUNTIME_DIR) ? join5(process.env.XDG_RUNTIME_DIR, filename) : null;
|
|
1405
|
+
return xdgPath && Buffer.byteLength(xdgPath) <= MAX_UNIX_SOCKET_PATH_BYTES ? xdgPath : join5("/tmp", filename);
|
|
1401
1406
|
}
|
|
1402
1407
|
async function startControlServer(handlers) {
|
|
1403
1408
|
const path = controlSocketPath();
|
|
@@ -1418,6 +1423,18 @@ async function startControlServer(handlers) {
|
|
|
1418
1423
|
resolve();
|
|
1419
1424
|
});
|
|
1420
1425
|
});
|
|
1426
|
+
if (process.platform !== "win32") {
|
|
1427
|
+
try {
|
|
1428
|
+
chmodSync2(path, 384);
|
|
1429
|
+
} catch (err) {
|
|
1430
|
+
await new Promise((resolve) => server.close(() => resolve()));
|
|
1431
|
+
try {
|
|
1432
|
+
rmSync2(path, { force: true });
|
|
1433
|
+
} catch {
|
|
1434
|
+
}
|
|
1435
|
+
throw err;
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1421
1438
|
server.on("error", () => {
|
|
1422
1439
|
});
|
|
1423
1440
|
return {
|
|
@@ -2162,7 +2179,7 @@ function errorMessage2(status, body) {
|
|
|
2162
2179
|
|
|
2163
2180
|
// src/credentials.ts
|
|
2164
2181
|
import {
|
|
2165
|
-
chmodSync as
|
|
2182
|
+
chmodSync as chmodSync3,
|
|
2166
2183
|
existsSync as existsSync5,
|
|
2167
2184
|
mkdirSync as mkdirSync5,
|
|
2168
2185
|
readFileSync as readFileSync3,
|
|
@@ -2197,14 +2214,14 @@ function save(map) {
|
|
|
2197
2214
|
const path = credentialsPath();
|
|
2198
2215
|
mkdirSync5(dirname4(path), { recursive: true });
|
|
2199
2216
|
try {
|
|
2200
|
-
|
|
2217
|
+
chmodSync3(cabaneDir(), 448);
|
|
2201
2218
|
} catch {
|
|
2202
2219
|
}
|
|
2203
2220
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
2204
2221
|
try {
|
|
2205
2222
|
writeFileSync3(tmp, JSON.stringify(map, null, 2) + "\n", { mode: 384 });
|
|
2206
2223
|
try {
|
|
2207
|
-
|
|
2224
|
+
chmodSync3(tmp, 384);
|
|
2208
2225
|
} catch {
|
|
2209
2226
|
}
|
|
2210
2227
|
renameSync2(tmp, path);
|
|
@@ -6687,7 +6704,7 @@ function resolveMcpSecrets(mcpServers, store) {
|
|
|
6687
6704
|
}
|
|
6688
6705
|
|
|
6689
6706
|
// src/transcript-writer.ts
|
|
6690
|
-
import { appendFileSync, chmodSync as
|
|
6707
|
+
import { appendFileSync, chmodSync as chmodSync4, copyFileSync, mkdirSync as mkdirSync9, readdirSync, rmSync as rmSync6 } from "fs";
|
|
6691
6708
|
import { basename, dirname as dirname5, join as join13 } from "path";
|
|
6692
6709
|
function transcriptsDir() {
|
|
6693
6710
|
return join13(cabaneDir(), "transcripts");
|
|
@@ -6704,7 +6721,7 @@ var TranscriptWriter = class {
|
|
|
6704
6721
|
try {
|
|
6705
6722
|
mkdirSync9(dir2, { recursive: true });
|
|
6706
6723
|
try {
|
|
6707
|
-
|
|
6724
|
+
chmodSync4(dir2, 448);
|
|
6708
6725
|
} catch {
|
|
6709
6726
|
}
|
|
6710
6727
|
pruneOld(dir2, RETAIN);
|
|
@@ -6731,10 +6748,10 @@ var TranscriptWriter = class {
|
|
|
6731
6748
|
try {
|
|
6732
6749
|
const dir2 = join13(dirname5(this.path), "anomalies");
|
|
6733
6750
|
mkdirSync9(dir2, { recursive: true, mode: 448 });
|
|
6734
|
-
|
|
6751
|
+
chmodSync4(dir2, 448);
|
|
6735
6752
|
const target = join13(dir2, basename(this.path));
|
|
6736
6753
|
copyFileSync(this.path, target);
|
|
6737
|
-
|
|
6754
|
+
chmodSync4(target, 384);
|
|
6738
6755
|
pruneOld(dir2, ANOMALY_RETAIN);
|
|
6739
6756
|
} catch (err) {
|
|
6740
6757
|
this.fail(err);
|
|
@@ -9619,7 +9636,8 @@ async function createCompanionRuntime(opts = {}) {
|
|
|
9619
9636
|
if (!claim.acquired) {
|
|
9620
9637
|
return { ok: false, reason: "already-running", existing: claim.existing ?? null };
|
|
9621
9638
|
}
|
|
9622
|
-
|
|
9639
|
+
const clearRuntimeOnExit = () => clearRuntimeStateIfOurs(instanceId);
|
|
9640
|
+
process.on("exit", clearRuntimeOnExit);
|
|
9623
9641
|
const hub = new CompanionStateHub({
|
|
9624
9642
|
// CT29: one device, one base URL — the cabane instance this device is paired
|
|
9625
9643
|
// with. The dashboard's connection line shows it.
|
|
@@ -9654,41 +9672,60 @@ async function createCompanionRuntime(opts = {}) {
|
|
|
9654
9672
|
if (!result.ok) return { ok: false, error: result.error };
|
|
9655
9673
|
return { ok: true, message: connectedLine(runtime, verdict) };
|
|
9656
9674
|
};
|
|
9657
|
-
|
|
9658
|
-
status: () => hub.statusJson(),
|
|
9659
|
-
connect: async (runtime, serverUrl) => {
|
|
9660
|
-
const result = await connectHarness(runtime, serverUrl);
|
|
9661
|
-
return result.ok ? { ok: true, message: result.message } : { ok: false, message: result.error };
|
|
9662
|
-
},
|
|
9663
|
-
stop: () => void supervisor.requestStop()
|
|
9664
|
-
});
|
|
9675
|
+
let control = null;
|
|
9665
9676
|
let dashboard = null;
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9677
|
+
try {
|
|
9678
|
+
control = await startControlServer({
|
|
9679
|
+
status: () => hub.statusJson(),
|
|
9680
|
+
connect: async (runtime, serverUrl) => {
|
|
9681
|
+
const result = await connectHarness(runtime, serverUrl);
|
|
9682
|
+
return result.ok ? { ok: true, message: result.message } : { ok: false, message: result.error };
|
|
9683
|
+
},
|
|
9684
|
+
stop: () => void supervisor.requestStop()
|
|
9685
|
+
});
|
|
9686
|
+
if (opts.dashboard) {
|
|
9687
|
+
const preferredPort = opts.port ?? cfg.dashboardPort;
|
|
9688
|
+
dashboard = await startDashboard({
|
|
9689
|
+
supervisor,
|
|
9690
|
+
hub,
|
|
9691
|
+
...preferredPort !== void 0 ? { port: preferredPort } : {}
|
|
9692
|
+
});
|
|
9693
|
+
hub.setDashboardUrl(dashboard.url);
|
|
9694
|
+
}
|
|
9695
|
+
writeRuntimeState({
|
|
9696
|
+
pid: process.pid,
|
|
9697
|
+
socket: control.path,
|
|
9698
|
+
...dashboard ? { url: dashboard.url, port: dashboard.port } : {},
|
|
9699
|
+
startedAt,
|
|
9700
|
+
// SJ495: the daemon launcher sets this env on the detached child, so the
|
|
9701
|
+
// marker records whether this companion is backgrounded (foreground start
|
|
9702
|
+
// leaves it unset → false).
|
|
9703
|
+
daemon: process.env.CABANE_COMPANION_DAEMON === "1",
|
|
9704
|
+
instanceId
|
|
9672
9705
|
});
|
|
9673
|
-
|
|
9706
|
+
clearCrash();
|
|
9707
|
+
} catch (err) {
|
|
9708
|
+
clearRuntimeStateIfOurs(instanceId);
|
|
9709
|
+
process.removeListener("exit", clearRuntimeOnExit);
|
|
9710
|
+
await Promise.allSettled([
|
|
9711
|
+
supervisor.shutdown(),
|
|
9712
|
+
...control ? [control.close()] : [],
|
|
9713
|
+
...dashboard ? [dashboard.close()] : []
|
|
9714
|
+
]);
|
|
9715
|
+
recordCrash({
|
|
9716
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
9717
|
+
...errorCode(err) ? { code: errorCode(err) } : {},
|
|
9718
|
+
origin: "startup",
|
|
9719
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
9720
|
+
});
|
|
9721
|
+
throw err;
|
|
9674
9722
|
}
|
|
9675
|
-
writeRuntimeState({
|
|
9676
|
-
pid: process.pid,
|
|
9677
|
-
socket: control.path,
|
|
9678
|
-
...dashboard ? { url: dashboard.url, port: dashboard.port } : {},
|
|
9679
|
-
startedAt,
|
|
9680
|
-
// SJ495: the daemon launcher sets this env on the detached child, so the
|
|
9681
|
-
// marker records whether this companion is backgrounded (foreground start
|
|
9682
|
-
// leaves it unset → false).
|
|
9683
|
-
daemon: process.env.CABANE_COMPANION_DAEMON === "1",
|
|
9684
|
-
instanceId
|
|
9685
|
-
});
|
|
9686
|
-
clearCrash();
|
|
9687
9723
|
let stopped = false;
|
|
9688
9724
|
const stop = async () => {
|
|
9689
9725
|
if (stopped) return;
|
|
9690
9726
|
stopped = true;
|
|
9691
9727
|
clearRuntimeStateIfOurs(instanceId);
|
|
9728
|
+
process.removeListener("exit", clearRuntimeOnExit);
|
|
9692
9729
|
try {
|
|
9693
9730
|
await supervisor.shutdown();
|
|
9694
9731
|
await closeSurfaces(control, dashboard);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cabane/companion",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.51",
|
|
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",
|