@scp-dev/cli 0.1.2 → 0.1.3
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 +10 -6
- package/dist/{chunk-DA3EB2YF.js → chunk-3PGDKPRN.js} +4 -59
- package/dist/{chunk-6UFMKYPH.js → chunk-5UWLTO2Y.js} +4 -4
- package/dist/{chunk-V5I7KEU7.js → chunk-ABP5AKFH.js} +8 -6
- package/dist/{chunk-XWLF7ON2.js → chunk-ABR5UABL.js} +1 -1
- package/dist/{chunk-4QYUPPGV.js → chunk-BUC5G5PY.js} +3 -3
- package/dist/{chunk-N3ZROLFA.js → chunk-IH2RJRIW.js} +6 -5
- package/dist/chunk-M2DCR2J4.js +63 -0
- package/dist/{chunk-4DNQFATX.js → chunk-QQZF5TQD.js} +4 -4
- package/dist/{chunk-7KP6TAJW.js → chunk-URSBFDR6.js} +9 -5
- package/dist/claude-5WTICOYS.js +88 -0
- package/dist/cli.js +1 -1
- package/dist/daemon-SUTLTY5U.js +52 -0
- package/dist/{hooks-O3UZXDYG.js → hooks-4YVIPZKE.js} +3 -2
- package/dist/install-4KQQWGGB.js +15 -0
- package/dist/{login-JTRUWG6Q.js → login-5Y3HPSVC.js} +5 -4
- package/dist/{main-5CAHHN55.js → main-PZQAJGHQ.js} +91 -24
- package/dist/{mcp-P2AZYP5G.js → mcp-GI5OMTUT.js} +15 -6
- package/dist/{peek-YCOWBEPD.js → peek-X4SEGEUB.js} +3 -2
- package/dist/{relay-VVJPYVXE.js → relay-W2NFUE2U.js} +4 -3
- package/dist/{remote-3BWFISXJ.js → remote-GC4XN44U.js} +5 -4
- package/dist/{setup-RDPVGE4H.js → setup-UF4AA6RO.js} +8 -5
- package/dist/{spawn-TQ3HOZTQ.js → spawn-KT5235WX.js} +7 -6
- package/dist/{up-KXOYO7QV.js → up-VA54QWA6.js} +8 -7
- package/package.json +3 -3
- package/dist/install-HFBSKSTG.js +0 -14
package/README.md
CHANGED
|
@@ -3,21 +3,25 @@
|
|
|
3
3
|
The `swarm` command line tool, the reference binding of SCP for shells, hooks and MCP.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
npm
|
|
6
|
+
npm i -g @scp-dev/cli
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
swarm login
|
|
13
|
-
swarm
|
|
14
|
-
|
|
12
|
+
swarm up # browser login, links this machine to the org hub, installs hooks and MCP
|
|
13
|
+
swarm claude --name lead # start a named orchestrator that wakes on peer messages
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
From the orchestrator's shell:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
swarm spawn --name parser -- claude -p "Fix the parser tests"
|
|
15
20
|
swarm send parser "Also cover the empty-input case."
|
|
16
21
|
swarm list --tree
|
|
17
|
-
swarm inbox --wait 30
|
|
18
22
|
```
|
|
19
23
|
|
|
20
|
-
Headless (CI, cron, cloud runners): `swarm
|
|
24
|
+
Headless (CI, cron, cloud runners): `swarm up --token scp_t_... [--machine NAME]`. The default relay is https://app.scp.dev; `swarm relay use <url>` picks another. Runs on Node 22.13 or later.
|
|
21
25
|
|
|
22
26
|
## Provides
|
|
23
27
|
|
|
@@ -1,56 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var FAILED = 125;
|
|
5
|
-
var SELF = [process.execPath, ...process.versions.bun ? ["--no-env-file", "--config=/dev/null"] : [], process.argv[1]];
|
|
6
|
-
function capture(argv, env) {
|
|
7
|
-
const result = spawnSync(argv[0], argv.slice(1), { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], ...env ? { env } : {} });
|
|
8
|
-
return result.status === 0 ? result.stdout : void 0;
|
|
9
|
-
}
|
|
10
|
-
function note(message) {
|
|
11
|
-
process.stderr.write(`${message.startsWith(`${CLI_NAME} `) ? "" : `${CLI_NAME}: `}${message}
|
|
12
|
-
`);
|
|
13
|
-
}
|
|
14
|
-
async function exitFlushed(code, waitMs = 1e4) {
|
|
15
|
-
const ended = (stream) => new Promise((resolve2) => {
|
|
16
|
-
try {
|
|
17
|
-
stream.end(() => resolve2());
|
|
18
|
-
} catch {
|
|
19
|
-
resolve2();
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
let timer;
|
|
23
|
-
await Promise.race([Promise.all([ended(process.stdout), ended(process.stderr)]), new Promise((resolve2) => timer = setTimeout(resolve2, waitMs))]);
|
|
24
|
-
clearTimeout(timer);
|
|
25
|
-
process.exit(code);
|
|
26
|
-
}
|
|
27
|
-
function printTable(rows) {
|
|
28
|
-
const widths = rows[0].map((_, column) => Math.max(...rows.map((row) => row[column].length)));
|
|
29
|
-
for (const row of rows)
|
|
30
|
-
console.log(
|
|
31
|
-
row.map((cell, column) => cell.padEnd(widths[column])).join(" ").trimEnd()
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
var DURATION_PART = /(\d+(?:\.\d+)?)(ms|s|m|h|d)/g;
|
|
35
|
-
var DURATION_UNITS = { ms: 1e-3, s: 1, m: 60, h: 3600, d: 86400 };
|
|
36
|
-
function parseSeconds(text, flag) {
|
|
37
|
-
const trimmed = text.trim();
|
|
38
|
-
let seconds;
|
|
39
|
-
if (/^\d+(?:\.\d+)?$/.test(trimmed)) seconds = Number(trimmed);
|
|
40
|
-
else {
|
|
41
|
-
seconds = 0;
|
|
42
|
-
let consumed = "";
|
|
43
|
-
for (const match of trimmed.matchAll(DURATION_PART)) {
|
|
44
|
-
seconds += Number(match[1]) * DURATION_UNITS[match[2]];
|
|
45
|
-
consumed += match[0];
|
|
46
|
-
}
|
|
47
|
-
if (consumed !== trimmed || consumed === "") {
|
|
48
|
-
throw new Error(`${flag} ${JSON.stringify(text)} is not a duration like 90s, 30m or 1h30m`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (!(seconds > 0)) throw new Error(`${flag} must be more than zero`);
|
|
52
|
-
return Math.max(1, Math.ceil(seconds));
|
|
53
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
capture
|
|
3
|
+
} from "./chunk-M2DCR2J4.js";
|
|
54
4
|
|
|
55
5
|
// src/identity.ts
|
|
56
6
|
import { existsSync, realpathSync } from "fs";
|
|
@@ -337,12 +287,6 @@ function relayIdentity(input) {
|
|
|
337
287
|
}
|
|
338
288
|
|
|
339
289
|
export {
|
|
340
|
-
FAILED,
|
|
341
|
-
SELF,
|
|
342
|
-
note,
|
|
343
|
-
exitFlushed,
|
|
344
|
-
printTable,
|
|
345
|
-
parseSeconds,
|
|
346
290
|
shortHostname,
|
|
347
291
|
detectHarness,
|
|
348
292
|
hookHarness,
|
|
@@ -353,6 +297,7 @@ export {
|
|
|
353
297
|
hiddenHarness,
|
|
354
298
|
lineage,
|
|
355
299
|
spawnerKey,
|
|
300
|
+
psParent,
|
|
356
301
|
harnessPid,
|
|
357
302
|
hookHarnessPid,
|
|
358
303
|
relayIdentity
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
configDir,
|
|
5
5
|
relayCredential,
|
|
6
6
|
writePrivateJson
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BUC5G5PY.js";
|
|
8
8
|
import {
|
|
9
9
|
RelayUsage
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-URSBFDR6.js";
|
|
11
11
|
import {
|
|
12
12
|
note,
|
|
13
13
|
printTable
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-M2DCR2J4.js";
|
|
15
15
|
|
|
16
16
|
// src/remote.ts
|
|
17
17
|
import { existsSync, readFileSync, rmSync } from "fs";
|
|
@@ -202,7 +202,7 @@ async function cloudMain(positionals, values, brokerStatus) {
|
|
|
202
202
|
writePrivateJson(path, file);
|
|
203
203
|
if (values.json) json({ file: path, ...file, token: problem ? "missing" : "found" });
|
|
204
204
|
else {
|
|
205
|
-
out(`the relay broker links to ${url} as machine ${machine}
|
|
205
|
+
out(`the relay broker links to ${url} as machine ${machine} (${path})`);
|
|
206
206
|
if (problem) note(problem);
|
|
207
207
|
}
|
|
208
208
|
return 0;
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
agySettingsFile,
|
|
4
4
|
mcpFile,
|
|
5
5
|
mountedEntry
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IH2RJRIW.js";
|
|
7
7
|
import {
|
|
8
8
|
OPTIONS,
|
|
9
9
|
RelayUsage,
|
|
@@ -13,16 +13,18 @@ import {
|
|
|
13
13
|
open,
|
|
14
14
|
selectorList,
|
|
15
15
|
walkNow
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-URSBFDR6.js";
|
|
17
17
|
import {
|
|
18
18
|
steerPrompt
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-ABR5UABL.js";
|
|
20
20
|
import {
|
|
21
|
-
SELF,
|
|
22
21
|
detectHarness,
|
|
23
|
-
note,
|
|
24
22
|
spawnerKey
|
|
25
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-3PGDKPRN.js";
|
|
24
|
+
import {
|
|
25
|
+
SELF,
|
|
26
|
+
note
|
|
27
|
+
} from "./chunk-M2DCR2J4.js";
|
|
26
28
|
|
|
27
29
|
// src/spawn.ts
|
|
28
30
|
import { spawn, spawnSync } from "child_process";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RelayUsage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-URSBFDR6.js";
|
|
4
4
|
import {
|
|
5
5
|
note
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-M2DCR2J4.js";
|
|
7
7
|
|
|
8
8
|
// src/relay.ts
|
|
9
9
|
import { chmodSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
@@ -119,7 +119,7 @@ function relayVerb(positionals, asJson, env = process.env) {
|
|
|
119
119
|
}
|
|
120
120
|
async function loginMain(positionals, values) {
|
|
121
121
|
if (positionals.length) throw new RelayUsage(`${CLI_NAME} login takes only flags`);
|
|
122
|
-
return (await import("./login-
|
|
122
|
+
return (await import("./login-5Y3HPSVC.js")).login(values);
|
|
123
123
|
}
|
|
124
124
|
function logoutMain(positionals, asJson, env = process.env) {
|
|
125
125
|
if (positionals.length) throw new RelayUsage(`${CLI_NAME} logout takes no arguments`);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hooksTarget
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QQZF5TQD.js";
|
|
4
4
|
import {
|
|
5
5
|
RelayUsage
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-URSBFDR6.js";
|
|
7
7
|
import {
|
|
8
8
|
AGY_HOOK_SET,
|
|
9
9
|
BLOCK_STOP,
|
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
mergeHooks,
|
|
16
16
|
musePlugin,
|
|
17
17
|
opencodePlugin
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ABR5UABL.js";
|
|
19
19
|
import {
|
|
20
20
|
gitToplevel
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-3PGDKPRN.js";
|
|
22
22
|
|
|
23
23
|
// src/setup.ts
|
|
24
24
|
import { spawnSync } from "child_process";
|
|
@@ -179,7 +179,7 @@ function entryRight(harness, entry, argv) {
|
|
|
179
179
|
}
|
|
180
180
|
var withoutRemote = (entry) => Object.fromEntries(Object.entries(entry).filter(([key]) => !REMOTE_KEYS.includes(key)));
|
|
181
181
|
function mountArgv(harness, bin) {
|
|
182
|
-
return [bin, "mcp", "--harness", harness];
|
|
182
|
+
return [bin, "mcp", "--harness", harness, ...harness === "claude" ? ["--channels"] : []];
|
|
183
183
|
}
|
|
184
184
|
function agyRules() {
|
|
185
185
|
return TOOLS.map((tool) => `mcp(${SERVER}/${tool.name})`);
|
|
@@ -1172,6 +1172,7 @@ export {
|
|
|
1172
1172
|
agySettingsFile,
|
|
1173
1173
|
manifestFile,
|
|
1174
1174
|
mountedEntry,
|
|
1175
|
+
entryArgv,
|
|
1175
1176
|
mountArgv,
|
|
1176
1177
|
agyRules,
|
|
1177
1178
|
verifyMount,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/term.ts
|
|
2
|
+
import { spawnSync } from "child_process";
|
|
3
|
+
import { CLI_NAME } from "@scp-dev/core";
|
|
4
|
+
var FAILED = 125;
|
|
5
|
+
var SELF = [process.execPath, ...process.versions.bun ? ["--no-env-file", "--config=/dev/null"] : [], process.argv[1]];
|
|
6
|
+
function capture(argv, env) {
|
|
7
|
+
const result = spawnSync(argv[0], argv.slice(1), { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], ...env ? { env } : {} });
|
|
8
|
+
return result.status === 0 ? result.stdout : void 0;
|
|
9
|
+
}
|
|
10
|
+
function note(message) {
|
|
11
|
+
process.stderr.write(`${message.startsWith(`${CLI_NAME} `) ? "" : `${CLI_NAME}: `}${message}
|
|
12
|
+
`);
|
|
13
|
+
}
|
|
14
|
+
async function exitFlushed(code, waitMs = 1e4) {
|
|
15
|
+
const ended = (stream) => new Promise((resolve) => {
|
|
16
|
+
try {
|
|
17
|
+
stream.end(() => resolve());
|
|
18
|
+
} catch {
|
|
19
|
+
resolve();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
let timer;
|
|
23
|
+
await Promise.race([Promise.all([ended(process.stdout), ended(process.stderr)]), new Promise((resolve) => timer = setTimeout(resolve, waitMs))]);
|
|
24
|
+
clearTimeout(timer);
|
|
25
|
+
process.exit(code);
|
|
26
|
+
}
|
|
27
|
+
function printTable(rows) {
|
|
28
|
+
const widths = rows[0].map((_, column) => Math.max(...rows.map((row) => row[column].length)));
|
|
29
|
+
for (const row of rows)
|
|
30
|
+
console.log(
|
|
31
|
+
row.map((cell, column) => cell.padEnd(widths[column])).join(" ").trimEnd()
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
var DURATION_PART = /(\d+(?:\.\d+)?)(ms|s|m|h|d)/g;
|
|
35
|
+
var DURATION_UNITS = { ms: 1e-3, s: 1, m: 60, h: 3600, d: 86400 };
|
|
36
|
+
function parseSeconds(text, flag) {
|
|
37
|
+
const trimmed = text.trim();
|
|
38
|
+
let seconds;
|
|
39
|
+
if (/^\d+(?:\.\d+)?$/.test(trimmed)) seconds = Number(trimmed);
|
|
40
|
+
else {
|
|
41
|
+
seconds = 0;
|
|
42
|
+
let consumed = "";
|
|
43
|
+
for (const match of trimmed.matchAll(DURATION_PART)) {
|
|
44
|
+
seconds += Number(match[1]) * DURATION_UNITS[match[2]];
|
|
45
|
+
consumed += match[0];
|
|
46
|
+
}
|
|
47
|
+
if (consumed !== trimmed || consumed === "") {
|
|
48
|
+
throw new Error(`${flag} ${JSON.stringify(text)} is not a duration like 90s, 30m or 1h30m`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!(seconds > 0)) throw new Error(`${flag} must be more than zero`);
|
|
52
|
+
return Math.max(1, Math.ceil(seconds));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
FAILED,
|
|
57
|
+
SELF,
|
|
58
|
+
capture,
|
|
59
|
+
note,
|
|
60
|
+
exitFlushed,
|
|
61
|
+
printTable,
|
|
62
|
+
parseSeconds
|
|
63
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RelayUsage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-URSBFDR6.js";
|
|
4
4
|
import {
|
|
5
5
|
AGY_HOOK_SET,
|
|
6
6
|
AGY_UNVERIFIED,
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
mergeHooks,
|
|
14
14
|
musePlugin,
|
|
15
15
|
opencodePlugin
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ABR5UABL.js";
|
|
17
17
|
import {
|
|
18
18
|
gitToplevel
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-3PGDKPRN.js";
|
|
20
20
|
|
|
21
21
|
// src/install.ts
|
|
22
22
|
import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
@@ -185,7 +185,7 @@ function mcpInstall(harness, as, out) {
|
|
|
185
185
|
const line = (cli, extra = []) => out([...cli, CLI_NAME, ...args(extra)].map(shellWord).join(" "));
|
|
186
186
|
switch (harness) {
|
|
187
187
|
case "claude":
|
|
188
|
-
line(["claude", "mcp", "add", "scp", "--"]);
|
|
188
|
+
line(["claude", "mcp", "add", "scp", "--"], ["--harness", "claude", "--channels"]);
|
|
189
189
|
return 0;
|
|
190
190
|
case "codex":
|
|
191
191
|
line(["codex", "mcp", "add", "scp", "--"], ["--harness", "codex"]);
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
SELF,
|
|
3
2
|
harnessLineage,
|
|
4
3
|
hiddenHarness,
|
|
5
4
|
labelsFor,
|
|
6
5
|
lineage,
|
|
7
|
-
parseSeconds,
|
|
8
6
|
readPsTable
|
|
9
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3PGDKPRN.js";
|
|
8
|
+
import {
|
|
9
|
+
SELF,
|
|
10
|
+
parseSeconds
|
|
11
|
+
} from "./chunk-M2DCR2J4.js";
|
|
10
12
|
|
|
11
13
|
// src/common.ts
|
|
12
14
|
import { spawn } from "child_process";
|
|
@@ -184,7 +186,7 @@ async function open(verb, values, cwd, bodyFromStdin, walk) {
|
|
|
184
186
|
`${CLI_NAME} ${verb} needs an identity: --as HANDLE (or $SCP_NAME) for an agent, or --human for your own inbox me/ (no terminal is attached, so me/ is not assumed)`
|
|
185
187
|
);
|
|
186
188
|
}
|
|
187
|
-
const { machineName, openCloud } = await import("./remote-
|
|
189
|
+
const { machineName, openCloud } = await import("./remote-GC4XN44U.js");
|
|
188
190
|
const handle2 = named ? localHandle(named) : void 0;
|
|
189
191
|
const claim = handle2 ? {
|
|
190
192
|
handle: handle2,
|
|
@@ -317,6 +319,7 @@ function stamp(iso) {
|
|
|
317
319
|
const at = new Date(iso);
|
|
318
320
|
return Number.isNaN(at.getTime()) ? iso : `${at.getFullYear()}-${pad(at.getMonth() + 1)}-${pad(at.getDate())} ${time(iso)}`;
|
|
319
321
|
}
|
|
322
|
+
var CHANNELS_ENV = "SCP_CHANNELS";
|
|
320
323
|
|
|
321
324
|
export {
|
|
322
325
|
RelayUsage,
|
|
@@ -332,5 +335,6 @@ export {
|
|
|
332
335
|
peekGrant,
|
|
333
336
|
grantParams,
|
|
334
337
|
time,
|
|
335
|
-
stamp
|
|
338
|
+
stamp,
|
|
339
|
+
CHANNELS_ENV
|
|
336
340
|
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {
|
|
2
|
+
entryArgv,
|
|
3
|
+
mcpFile,
|
|
4
|
+
mountedEntry,
|
|
5
|
+
whichOnPath
|
|
6
|
+
} from "./chunk-IH2RJRIW.js";
|
|
7
|
+
import "./chunk-QQZF5TQD.js";
|
|
8
|
+
import {
|
|
9
|
+
CHANNELS_ENV,
|
|
10
|
+
RelayUsage
|
|
11
|
+
} from "./chunk-URSBFDR6.js";
|
|
12
|
+
import "./chunk-ABR5UABL.js";
|
|
13
|
+
import "./chunk-YYSLYVNZ.js";
|
|
14
|
+
import "./chunk-3PGDKPRN.js";
|
|
15
|
+
import "./chunk-M2DCR2J4.js";
|
|
16
|
+
|
|
17
|
+
// src/claude.ts
|
|
18
|
+
import { spawn } from "child_process";
|
|
19
|
+
import { CLI_NAME, validHandle } from "@scp-dev/core";
|
|
20
|
+
var CHANNEL_FLAGS = ["--dangerously-load-development-channels", "server:scp"];
|
|
21
|
+
function claudeArgv(argv) {
|
|
22
|
+
let name;
|
|
23
|
+
let i = 0;
|
|
24
|
+
if (argv[0] === "--name") {
|
|
25
|
+
if (argv[1] === void 0) throw new RelayUsage(`${CLI_NAME} claude --name takes a handle`);
|
|
26
|
+
name = argv[1];
|
|
27
|
+
i = 2;
|
|
28
|
+
} else if (argv[0]?.startsWith("--name=")) {
|
|
29
|
+
name = argv[0].slice("--name=".length);
|
|
30
|
+
i = 1;
|
|
31
|
+
}
|
|
32
|
+
if (argv[i] === "--") i++;
|
|
33
|
+
if (name !== void 0 && !validHandle(name)) throw new RelayUsage(`--name ${JSON.stringify(name)} is not a valid agent handle`);
|
|
34
|
+
return { ...name !== void 0 ? { name } : {}, args: argv.slice(i) };
|
|
35
|
+
}
|
|
36
|
+
function mountHint(env) {
|
|
37
|
+
const file = mcpFile("claude", env);
|
|
38
|
+
let entry;
|
|
39
|
+
try {
|
|
40
|
+
entry = mountedEntry("claude", file);
|
|
41
|
+
} catch {
|
|
42
|
+
return `${CLI_NAME} claude: ${file} is unreadable, so the scp mount is unchecked`;
|
|
43
|
+
}
|
|
44
|
+
if (!entry) return `${CLI_NAME} claude: Claude Code has no scp MCP mount; run ${CLI_NAME} setup --write`;
|
|
45
|
+
if (!entryArgv("claude", entry).includes("--channels"))
|
|
46
|
+
return `${CLI_NAME} claude: the scp mount lacks --channels, so messages will not wake this session; re-run ${CLI_NAME} setup --write`;
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
async function claudeCommand(argv, env = process.env, err = (line) => void process.stderr.write(`${line}
|
|
50
|
+
`)) {
|
|
51
|
+
if (argv[0] === "--help" || argv[0] === "-h") {
|
|
52
|
+
process.stdout.write(`${CLI_NAME} claude [--name N] [--] [claude args...] start Claude Code with the scp channel loaded, so peer messages wake it
|
|
53
|
+
`);
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
const { name, args } = claudeArgv(argv);
|
|
57
|
+
const bin = whichOnPath("claude", env);
|
|
58
|
+
if (!bin) throw new RelayUsage("claude is not on PATH");
|
|
59
|
+
const hint = mountHint(env);
|
|
60
|
+
if (hint) err(hint);
|
|
61
|
+
const child = spawn(bin, [...CHANNEL_FLAGS, ...args], {
|
|
62
|
+
stdio: "inherit",
|
|
63
|
+
env: { ...env, ...name !== void 0 ? { SCP_NAME: name } : {}, [CHANNELS_ENV]: String(process.pid) }
|
|
64
|
+
});
|
|
65
|
+
const forward = (signal) => () => void child.kill(signal);
|
|
66
|
+
const handlers = ["SIGTERM", "SIGHUP"].map((signal) => [signal, forward(signal)]);
|
|
67
|
+
const ignore = () => {
|
|
68
|
+
};
|
|
69
|
+
process.on("SIGINT", ignore);
|
|
70
|
+
for (const [signal, handler] of handlers) process.on(signal, handler);
|
|
71
|
+
try {
|
|
72
|
+
return await new Promise((resolve, reject) => {
|
|
73
|
+
child.once("error", reject);
|
|
74
|
+
child.once("exit", (code, signal) => resolve(code ?? (signal ? 128 + (signalNumber(signal) ?? 1) : 1)));
|
|
75
|
+
});
|
|
76
|
+
} finally {
|
|
77
|
+
process.off("SIGINT", ignore);
|
|
78
|
+
for (const [signal, handler] of handlers) process.off(signal, handler);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
var SIGNALS = { SIGHUP: 1, SIGINT: 2, SIGKILL: 9, SIGTERM: 15 };
|
|
82
|
+
var signalNumber = (signal) => SIGNALS[signal];
|
|
83
|
+
export {
|
|
84
|
+
CHANNEL_FLAGS,
|
|
85
|
+
claudeArgv,
|
|
86
|
+
claudeCommand,
|
|
87
|
+
mountHint
|
|
88
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -17,6 +17,6 @@ function quietSqliteWarning() {
|
|
|
17
17
|
// src/cli.ts
|
|
18
18
|
if (!await subagentFastPath(process.argv.slice(2))) {
|
|
19
19
|
quietSqliteWarning();
|
|
20
|
-
const { run } = await import("./main-
|
|
20
|
+
const { run } = await import("./main-PZQAJGHQ.js");
|
|
21
21
|
await run(process.argv.slice(2));
|
|
22
22
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
capture
|
|
3
|
+
} from "./chunk-M2DCR2J4.js";
|
|
4
|
+
|
|
5
|
+
// src/daemon.ts
|
|
6
|
+
import { readFileSync } from "fs";
|
|
7
|
+
import { join } from "path";
|
|
8
|
+
import { setTimeout as sleep } from "timers/promises";
|
|
9
|
+
function brokerPid(dir) {
|
|
10
|
+
let pid;
|
|
11
|
+
try {
|
|
12
|
+
pid = Number(readFileSync(join(dir, "broker.lock"), "utf8").split(":")[0]);
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
17
|
+
const command = capture(["ps", "-p", String(pid), "-o", "command="])?.trim() ?? "";
|
|
18
|
+
return /(^|\s)daemon(\s|$)/.test(command) && (/scp|swarm/.test(command) || command.includes(process.argv[1] ?? "\0")) ? pid : null;
|
|
19
|
+
}
|
|
20
|
+
function alive(pid) {
|
|
21
|
+
try {
|
|
22
|
+
process.kill(pid, 0);
|
|
23
|
+
return true;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
return error.code === "EPERM";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function exited(pid, ms = 5e3) {
|
|
29
|
+
const deadline = Date.now() + ms;
|
|
30
|
+
while (alive(pid)) {
|
|
31
|
+
if (Date.now() >= deadline) return false;
|
|
32
|
+
await sleep(50);
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
async function stopBroker(dir) {
|
|
37
|
+
const pid = brokerPid(dir);
|
|
38
|
+
if (pid === null) return null;
|
|
39
|
+
try {
|
|
40
|
+
process.kill(pid, "SIGTERM");
|
|
41
|
+
} catch (error) {
|
|
42
|
+
if (error.code === "ESRCH") return null;
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
if (!await exited(pid)) throw new Error(`the relay broker (pid ${pid}) did not stop within 5 s`);
|
|
46
|
+
return pid;
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
brokerPid,
|
|
50
|
+
exited,
|
|
51
|
+
stopBroker
|
|
52
|
+
};
|
|
@@ -30,11 +30,12 @@ import {
|
|
|
30
30
|
subagentIntro,
|
|
31
31
|
summarize,
|
|
32
32
|
unreadPointer
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-ABR5UABL.js";
|
|
34
34
|
import {
|
|
35
35
|
SUBAGENT
|
|
36
36
|
} from "./chunk-YYSLYVNZ.js";
|
|
37
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-3PGDKPRN.js";
|
|
38
|
+
import "./chunk-M2DCR2J4.js";
|
|
38
39
|
export {
|
|
39
40
|
AGY_HOOK_SET,
|
|
40
41
|
AGY_UNVERIFIED,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hooksTarget,
|
|
3
|
+
installHooks,
|
|
4
|
+
mcpInstall
|
|
5
|
+
} from "./chunk-QQZF5TQD.js";
|
|
6
|
+
import "./chunk-URSBFDR6.js";
|
|
7
|
+
import "./chunk-ABR5UABL.js";
|
|
8
|
+
import "./chunk-YYSLYVNZ.js";
|
|
9
|
+
import "./chunk-3PGDKPRN.js";
|
|
10
|
+
import "./chunk-M2DCR2J4.js";
|
|
11
|
+
export {
|
|
12
|
+
hooksTarget,
|
|
13
|
+
installHooks,
|
|
14
|
+
mcpInstall
|
|
15
|
+
};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
machineName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5UWLTO2Y.js";
|
|
4
4
|
import {
|
|
5
5
|
activeRelay,
|
|
6
6
|
saveCredential
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BUC5G5PY.js";
|
|
8
8
|
import {
|
|
9
9
|
RelayUsage
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-URSBFDR6.js";
|
|
11
|
+
import "./chunk-3PGDKPRN.js";
|
|
11
12
|
import {
|
|
12
13
|
note
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-M2DCR2J4.js";
|
|
14
15
|
|
|
15
16
|
// src/login.ts
|
|
16
17
|
import { spawn } from "child_process";
|
|
@@ -14,15 +14,17 @@ import {
|
|
|
14
14
|
stamp,
|
|
15
15
|
startDaemon,
|
|
16
16
|
time
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-URSBFDR6.js";
|
|
18
|
+
import {
|
|
19
|
+
shortHostname
|
|
20
|
+
} from "./chunk-3PGDKPRN.js";
|
|
18
21
|
import {
|
|
19
22
|
FAILED,
|
|
20
23
|
exitFlushed,
|
|
21
24
|
note,
|
|
22
25
|
parseSeconds,
|
|
23
|
-
printTable
|
|
24
|
-
|
|
25
|
-
} from "./chunk-DA3EB2YF.js";
|
|
26
|
+
printTable
|
|
27
|
+
} from "./chunk-M2DCR2J4.js";
|
|
26
28
|
|
|
27
29
|
// src/main.ts
|
|
28
30
|
import { text as readAll } from "stream/consumers";
|
|
@@ -33,7 +35,7 @@ import { parseArgs } from "util";
|
|
|
33
35
|
// package.json
|
|
34
36
|
var package_default = {
|
|
35
37
|
name: "@scp-dev/cli",
|
|
36
|
-
version: "0.1.
|
|
38
|
+
version: "0.1.3",
|
|
37
39
|
description: "The swarm command line tool.",
|
|
38
40
|
license: "Apache-2.0",
|
|
39
41
|
homepage: "https://scp.dev",
|
|
@@ -230,6 +232,7 @@ scopes (selectors are comma-separated, e.g. tree:parent,tree:children,group:team
|
|
|
230
232
|
other process under an agent they may only narrow. An ancestor always reaches its descendants, and a recipient
|
|
231
233
|
may always reply in the thread to a message it got; a reply to another message of the thread is checked as a send.
|
|
232
234
|
${CLI_NAME} daemon [--idle DURATION] [--policy FILE] run the broker in the foreground (it otherwise starts on demand)
|
|
235
|
+
${CLI_NAME} daemon stop|restart stop the running broker, or replace it with a fresh one
|
|
233
236
|
|
|
234
237
|
agent sessions:
|
|
235
238
|
${CLI_NAME} mcp [--as NAME] [--harness H] [--channels] the MCP shim a harness mounts: relay tools for one agent, never me/
|
|
@@ -254,7 +257,9 @@ agent sessions:
|
|
|
254
257
|
A Claude Code subagent's hooks give it a child endpoint, <session handle>-<type>-<first 6 of its id>, whose messages
|
|
255
258
|
reach it after its tools; its shell is the session's, so it acts as that child with --as.
|
|
256
259
|
Grok runs the Claude Code hooks, labelled grok; Muse takes them as a plugin; Codex runs new hooks after /hooks review.
|
|
257
|
-
--
|
|
260
|
+
${CLI_NAME} claude [--name N] [--] [claude args...] start Claude Code with the scp channel loaded, so peer messages wake
|
|
261
|
+
it while idle (claude --dangerously-load-development-channels server:scp; SCP_NAME=N)
|
|
262
|
+
--channels pushes messages into a Claude Code that ${CLI_NAME} claude started; setup mounts claude's shim with it.
|
|
258
263
|
|
|
259
264
|
relay:
|
|
260
265
|
${CLI_NAME} relay use <url> | show select a relay, or show its source and credential status
|
|
@@ -491,10 +496,11 @@ async function relayMain(argv, cwd = process.cwd()) {
|
|
|
491
496
|
out(package_default.version);
|
|
492
497
|
return 0;
|
|
493
498
|
}
|
|
494
|
-
if (verb === "hook") return (await import("./hooks-
|
|
495
|
-
if (verb === "setup") return (await import("./setup-
|
|
499
|
+
if (verb === "hook") return (await import("./hooks-4YVIPZKE.js")).relayHookCommand(rest, startDaemon);
|
|
500
|
+
if (verb === "setup") return (await import("./setup-UF4AA6RO.js")).relaySetupCommand(rest, cwd, out);
|
|
501
|
+
if (verb === "claude") return (await import("./claude-5WTICOYS.js")).claudeCommand(rest);
|
|
496
502
|
if (verb === "spawn") {
|
|
497
|
-
const { splitSpawn, spawnCommand } = await import("./spawn-
|
|
503
|
+
const { splitSpawn, spawnCommand } = await import("./spawn-KT5235WX.js");
|
|
498
504
|
const { flags } = splitSpawn(rest);
|
|
499
505
|
if (flags.includes("--help") || flags.includes("-h")) {
|
|
500
506
|
out(flags.includes("--all") ? RELAY_HELP : SPAWN_HELP);
|
|
@@ -516,13 +522,16 @@ async function relayMain(argv, cwd = process.cwd()) {
|
|
|
516
522
|
return 0;
|
|
517
523
|
}
|
|
518
524
|
for (const key of Object.keys(values)) if (!allowed.includes(key)) throw new RelayUsage(`${CLI_NAME} ${verb} does not take --${key}`);
|
|
519
|
-
if (verb === "daemon")
|
|
525
|
+
if (verb === "daemon") {
|
|
526
|
+
if (positionals.length) return daemonControl(positionals, values);
|
|
527
|
+
return daemon(values.idle, values.policy);
|
|
528
|
+
}
|
|
520
529
|
if (verb === "mcp")
|
|
521
|
-
return (await import("./mcp-
|
|
530
|
+
return (await import("./mcp-GI5OMTUT.js")).relayMcpCommand(values, positionals);
|
|
522
531
|
if (verb === "hooks") {
|
|
523
532
|
if (positionals[0] !== "install" || positionals.length > 1) throw new RelayUsage(`${CLI_NAME} hooks takes install --harness claude|codex|opencode|agy|muse`);
|
|
524
533
|
if (values.write && values.print) throw new RelayUsage("--print and --write: pick one");
|
|
525
|
-
return (await import("./install-
|
|
534
|
+
return (await import("./install-4KQQWGGB.js")).installHooks({
|
|
526
535
|
harness: values.harness,
|
|
527
536
|
scope: values.scope,
|
|
528
537
|
write: values.write === true,
|
|
@@ -533,18 +542,25 @@ async function relayMain(argv, cwd = process.cwd()) {
|
|
|
533
542
|
out
|
|
534
543
|
});
|
|
535
544
|
}
|
|
536
|
-
if (verb === "relay") return (await import("./relay-
|
|
537
|
-
if (verb === "up") return (await import("./up-
|
|
538
|
-
if (verb === "login")
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
545
|
+
if (verb === "relay") return (await import("./relay-W2NFUE2U.js")).relayVerb(positionals, values.json === true);
|
|
546
|
+
if (verb === "up") return (await import("./up-VA54QWA6.js")).up(positionals, values, cwd, relinkBroker);
|
|
547
|
+
if (verb === "login") {
|
|
548
|
+
const code = await (await import("./relay-W2NFUE2U.js")).loginMain(positionals, values);
|
|
549
|
+
if (code === 0) await relinkRunning();
|
|
550
|
+
return code;
|
|
551
|
+
}
|
|
552
|
+
if (verb === "logout") return (await import("./relay-W2NFUE2U.js")).logoutMain(positionals, values.json === true);
|
|
553
|
+
if (verb === "cloud") {
|
|
554
|
+
const code = await (await import("./remote-GC4XN44U.js")).cloudMain(positionals, values, cloudStatus);
|
|
555
|
+
if (code === 0 && positionals[0] === "enable") await relinkRunning();
|
|
556
|
+
return code;
|
|
557
|
+
}
|
|
542
558
|
if (verb === "holds") holdsArgs(values, positionals);
|
|
543
559
|
const bodyFromStdin = (verb === "send" || verb === "ask" || verb === "reply") && (positionals[1] === void 0 || positionals[1] === "-");
|
|
544
560
|
const opened = await open(verb, values, cwd, bodyFromStdin);
|
|
545
561
|
const { client } = opened;
|
|
546
562
|
try {
|
|
547
|
-
if (verb === "machines") return await (await import("./remote-
|
|
563
|
+
if (verb === "machines") return await (await import("./remote-GC4XN44U.js")).machinesVerb(client, positionals, values.json === true);
|
|
548
564
|
return await runVerb(opened, verb, values, positionals, cwd);
|
|
549
565
|
} finally {
|
|
550
566
|
client.close();
|
|
@@ -560,6 +576,55 @@ async function cloudStatus() {
|
|
|
560
576
|
client.close();
|
|
561
577
|
}
|
|
562
578
|
}
|
|
579
|
+
async function relinkBroker() {
|
|
580
|
+
const dir = relayDir();
|
|
581
|
+
const client = await connectBroker(dir, () => startDaemon(dir));
|
|
582
|
+
let result;
|
|
583
|
+
let pid;
|
|
584
|
+
try {
|
|
585
|
+
pid = (await client.hello({ observe: true })).broker.pid;
|
|
586
|
+
result = await client.request("bridge_relink");
|
|
587
|
+
} catch (error) {
|
|
588
|
+
if (error instanceof RelayError && error.code === "method_not_found") return cloudStatus();
|
|
589
|
+
throw error;
|
|
590
|
+
} finally {
|
|
591
|
+
client.close();
|
|
592
|
+
}
|
|
593
|
+
if (!result.restarting) return result;
|
|
594
|
+
await (await import("./daemon-SUTLTY5U.js")).exited(pid);
|
|
595
|
+
return cloudStatus();
|
|
596
|
+
}
|
|
597
|
+
async function relinkRunning() {
|
|
598
|
+
try {
|
|
599
|
+
await connectBroker(relayDir()).then((client) => client.close());
|
|
600
|
+
} catch {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
try {
|
|
604
|
+
await relinkBroker();
|
|
605
|
+
} catch (error) {
|
|
606
|
+
note(`the running broker did not link again (${error instanceof Error ? error.message : String(error)}); run \`${CLI_NAME} daemon restart\``);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async function daemonControl(positionals, values) {
|
|
610
|
+
const [action] = positionals;
|
|
611
|
+
if (positionals.length !== 1 || action !== "stop" && action !== "restart" || values.idle !== void 0 || values.policy !== void 0)
|
|
612
|
+
throw new RelayUsage(`${CLI_NAME} daemon takes stop or restart, or --idle and --policy to run in the foreground`);
|
|
613
|
+
const dir = relayDir();
|
|
614
|
+
const pid = await (await import("./daemon-SUTLTY5U.js")).stopBroker(dir);
|
|
615
|
+
if (action === "stop") {
|
|
616
|
+
out(pid === null ? "no relay broker runs" : `stopped the relay broker (pid ${pid}); the next command starts a fresh one`);
|
|
617
|
+
return 0;
|
|
618
|
+
}
|
|
619
|
+
const client = await connectBroker(dir, () => startDaemon(dir));
|
|
620
|
+
try {
|
|
621
|
+
const { broker } = await client.hello({ observe: true });
|
|
622
|
+
out(`${pid === null ? "started" : `replaced the relay broker (pid ${pid}) with`} a fresh one (pid ${broker.pid})`);
|
|
623
|
+
} finally {
|
|
624
|
+
client.close();
|
|
625
|
+
}
|
|
626
|
+
return 0;
|
|
627
|
+
}
|
|
563
628
|
async function runVerb({ client, me, broker, where, bound, harnessPid }, verb, values, positionals, cwd) {
|
|
564
629
|
const asJson = values.json === true;
|
|
565
630
|
const attachments = (values.attach ?? []).map((path) => ({ kind: "path", path: path.startsWith("/") ? path : `${cwd}/${path}` }));
|
|
@@ -672,9 +737,9 @@ async function runVerb({ client, me, broker, where, bound, harnessPid }, verb, v
|
|
|
672
737
|
return 0;
|
|
673
738
|
}
|
|
674
739
|
case "peek":
|
|
675
|
-
return (await import("./peek-
|
|
740
|
+
return (await import("./peek-X4SEGEUB.js")).peekCommand(localClient(client, broker, verb), values, positionals);
|
|
676
741
|
case "set-peek":
|
|
677
|
-
return (await import("./peek-
|
|
742
|
+
return (await import("./peek-X4SEGEUB.js")).setPeekCommand(localClient(client, broker, verb), values, positionals);
|
|
678
743
|
case "why": {
|
|
679
744
|
const [from, to] = positionals;
|
|
680
745
|
if (!from || !to || positionals.length > 2) throw new RelayUsage(`${CLI_NAME} why takes <from> <to>`);
|
|
@@ -747,9 +812,10 @@ async function runVerb({ client, me, broker, where, bound, harnessPid }, verb, v
|
|
|
747
812
|
}
|
|
748
813
|
case "inbox": {
|
|
749
814
|
if (values.ack && values.keep) throw new RelayUsage("--ack and --keep: pick one");
|
|
750
|
-
const
|
|
815
|
+
const waited = waitArg(values.wait, 0);
|
|
816
|
+
const { messages } = await client.request("inbox", { wait_s: waited });
|
|
751
817
|
if (asJson) json({ preamble: PREAMBLE, messages });
|
|
752
|
-
else if (!messages.length) note(
|
|
818
|
+
else if (!messages.length) note(`no unread messages${waited > LIMITS.waitMaxS ? `; waited ${LIMITS.waitMaxS} s (cap)` : ""}`);
|
|
753
819
|
else {
|
|
754
820
|
out(PREAMBLE);
|
|
755
821
|
out();
|
|
@@ -1226,11 +1292,12 @@ async function daemon(idle, policyFile) {
|
|
|
1226
1292
|
});
|
|
1227
1293
|
let broker;
|
|
1228
1294
|
try {
|
|
1229
|
-
const { daemonBridge } = await import("./remote-
|
|
1295
|
+
const { daemonBridge } = await import("./remote-GC4XN44U.js");
|
|
1230
1296
|
const bridge = await daemonBridge();
|
|
1231
1297
|
broker = await startBroker({
|
|
1232
1298
|
dir: relayDir(),
|
|
1233
1299
|
...bridge ? { bridge } : {},
|
|
1300
|
+
bridgeConfig: () => daemonBridge(),
|
|
1234
1301
|
...idleMs !== void 0 ? { idleMs } : {},
|
|
1235
1302
|
...policyFile ? { policyPath: resolve(policyFile) } : {}
|
|
1236
1303
|
});
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
spawnDetached
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ABP5AKFH.js";
|
|
4
4
|
import "./chunk-KN7WEIE4.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-IH2RJRIW.js";
|
|
6
6
|
import {
|
|
7
7
|
mcpInstall
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QQZF5TQD.js";
|
|
9
9
|
import {
|
|
10
|
+
CHANNELS_ENV,
|
|
10
11
|
RelayUsage,
|
|
11
12
|
startDaemon
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-URSBFDR6.js";
|
|
14
|
+
import "./chunk-ABR5UABL.js";
|
|
14
15
|
import "./chunk-YYSLYVNZ.js";
|
|
15
16
|
import {
|
|
16
17
|
harnessPid,
|
|
18
|
+
psParent,
|
|
17
19
|
relayIdentity
|
|
18
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-3PGDKPRN.js";
|
|
21
|
+
import "./chunk-M2DCR2J4.js";
|
|
19
22
|
|
|
20
23
|
// src/mcp.ts
|
|
21
24
|
import { CLI_NAME, validHandle } from "@scp-dev/core";
|
|
@@ -46,6 +49,7 @@ async function relayMcpCommand(values, positionals) {
|
|
|
46
49
|
output: (line) => void process.stdout.write(line),
|
|
47
50
|
env: process.env,
|
|
48
51
|
channels: values.channels === true,
|
|
52
|
+
launchedWithChannels: values.channels === true && launchedWithChannels(process.env),
|
|
49
53
|
spawn: (request) => spawnDetached(spawnWords(request), request.cwd ?? claim.cwd),
|
|
50
54
|
log: (line) => void process.stderr.write(`${line}
|
|
51
55
|
`)
|
|
@@ -66,7 +70,12 @@ function spawnWords(request) {
|
|
|
66
70
|
...request.command
|
|
67
71
|
];
|
|
68
72
|
}
|
|
73
|
+
function launchedWithChannels(env, harness = harnessPid, parentOf = psParent) {
|
|
74
|
+
const launcher = Number(env[CHANNELS_ENV]);
|
|
75
|
+
return Number.isInteger(launcher) && launcher > 1 && parentOf(harness())?.ppid === launcher;
|
|
76
|
+
}
|
|
69
77
|
export {
|
|
78
|
+
launchedWithChannels,
|
|
70
79
|
relayMcpCommand,
|
|
71
80
|
spawnWords
|
|
72
81
|
};
|
|
@@ -2,10 +2,11 @@ import {
|
|
|
2
2
|
RelayUsage,
|
|
3
3
|
peekGrant,
|
|
4
4
|
stamp
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-URSBFDR6.js";
|
|
6
|
+
import "./chunk-3PGDKPRN.js";
|
|
6
7
|
import {
|
|
7
8
|
note
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-M2DCR2J4.js";
|
|
9
10
|
|
|
10
11
|
// src/peek.ts
|
|
11
12
|
import { PREAMBLE, wrapPeek, CLI_NAME } from "@scp-dev/core";
|
|
@@ -11,9 +11,10 @@ import {
|
|
|
11
11
|
removeCredential,
|
|
12
12
|
saveCredential,
|
|
13
13
|
writePrivateJson
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-BUC5G5PY.js";
|
|
15
|
+
import "./chunk-URSBFDR6.js";
|
|
16
|
+
import "./chunk-3PGDKPRN.js";
|
|
17
|
+
import "./chunk-M2DCR2J4.js";
|
|
17
18
|
export {
|
|
18
19
|
DEFAULT_RELAY,
|
|
19
20
|
activeRelay,
|
|
@@ -9,10 +9,11 @@ import {
|
|
|
9
9
|
machinesVerb,
|
|
10
10
|
openCloud,
|
|
11
11
|
readCloudFile
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-5UWLTO2Y.js";
|
|
13
|
+
import "./chunk-BUC5G5PY.js";
|
|
14
|
+
import "./chunk-URSBFDR6.js";
|
|
15
|
+
import "./chunk-3PGDKPRN.js";
|
|
16
|
+
import "./chunk-M2DCR2J4.js";
|
|
16
17
|
export {
|
|
17
18
|
CloudRelayClient,
|
|
18
19
|
CloudUsage,
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
agyRules,
|
|
5
5
|
agySettingsFile,
|
|
6
6
|
detectHarnesses,
|
|
7
|
+
entryArgv,
|
|
7
8
|
manifestFile,
|
|
8
9
|
mcpFile,
|
|
9
10
|
mountArgv,
|
|
@@ -14,18 +15,20 @@ import {
|
|
|
14
15
|
verifyMount,
|
|
15
16
|
verifyMusePlugin,
|
|
16
17
|
whichOnPath
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-IH2RJRIW.js";
|
|
19
|
+
import "./chunk-QQZF5TQD.js";
|
|
20
|
+
import "./chunk-URSBFDR6.js";
|
|
21
|
+
import "./chunk-ABR5UABL.js";
|
|
21
22
|
import "./chunk-YYSLYVNZ.js";
|
|
22
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-3PGDKPRN.js";
|
|
24
|
+
import "./chunk-M2DCR2J4.js";
|
|
23
25
|
export {
|
|
24
26
|
SETUP_HARNESSES,
|
|
25
27
|
SETUP_HELP,
|
|
26
28
|
agyRules,
|
|
27
29
|
agySettingsFile,
|
|
28
30
|
detectHarnesses,
|
|
31
|
+
entryArgv,
|
|
29
32
|
manifestFile,
|
|
30
33
|
mcpFile,
|
|
31
34
|
mountArgv,
|
|
@@ -29,16 +29,17 @@ import {
|
|
|
29
29
|
steerArgv,
|
|
30
30
|
transcriptReplies,
|
|
31
31
|
workerName
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-ABP5AKFH.js";
|
|
33
33
|
import {
|
|
34
34
|
SPAWN_HELP
|
|
35
35
|
} from "./chunk-KN7WEIE4.js";
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
38
|
-
import "./chunk-
|
|
39
|
-
import "./chunk-
|
|
36
|
+
import "./chunk-IH2RJRIW.js";
|
|
37
|
+
import "./chunk-QQZF5TQD.js";
|
|
38
|
+
import "./chunk-URSBFDR6.js";
|
|
39
|
+
import "./chunk-ABR5UABL.js";
|
|
40
40
|
import "./chunk-YYSLYVNZ.js";
|
|
41
|
-
import "./chunk-
|
|
41
|
+
import "./chunk-3PGDKPRN.js";
|
|
42
|
+
import "./chunk-M2DCR2J4.js";
|
|
42
43
|
export {
|
|
43
44
|
MESSAGING,
|
|
44
45
|
SPAWN_HELP,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
activeRelay,
|
|
3
3
|
relayCredential
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BUC5G5PY.js";
|
|
5
5
|
import {
|
|
6
6
|
RelayUsage
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-URSBFDR6.js";
|
|
8
|
+
import "./chunk-3PGDKPRN.js";
|
|
9
|
+
import "./chunk-M2DCR2J4.js";
|
|
9
10
|
|
|
10
11
|
// src/up.ts
|
|
11
12
|
import { CLI_NAME } from "@scp-dev/core";
|
|
@@ -16,19 +17,19 @@ async function up(positionals, values, cwd, brokerStatus) {
|
|
|
16
17
|
const { url } = activeRelay(process.env);
|
|
17
18
|
const headless = values.token !== void 0 || Boolean(process.env.SCP_TOKEN?.trim());
|
|
18
19
|
if (headless || !relayCredential(process.env, url).token) {
|
|
19
|
-
const code = await (await import("./login-
|
|
20
|
+
const code = await (await import("./login-5Y3HPSVC.js")).login({
|
|
20
21
|
...values.token !== void 0 ? { token: values.token } : {},
|
|
21
22
|
...values.label !== void 0 ? { label: values.label } : {},
|
|
22
23
|
...values["no-browser"] ? { "no-browser": true } : {}
|
|
23
24
|
});
|
|
24
25
|
if (code !== 0) return code;
|
|
25
26
|
} else out(`already logged in to ${url}`);
|
|
26
|
-
const enabled = await (await import("./remote-
|
|
27
|
+
const enabled = await (await import("./remote-GC4XN44U.js")).cloudMain(["enable"], values.machine !== void 0 ? { machine: values.machine } : {}, brokerStatus);
|
|
27
28
|
if (enabled !== 0) return enabled;
|
|
28
|
-
const setup = (await import("./setup-
|
|
29
|
+
const setup = (await import("./setup-UF4AA6RO.js")).relaySetupCommand(["--write"], cwd, out);
|
|
29
30
|
if (setup !== 0) return setup;
|
|
30
31
|
const broker = await brokerStatus();
|
|
31
|
-
if (!broker.enabled) out(`the broker
|
|
32
|
+
if (!broker.enabled) out(`the broker is still local-only; run \`${CLI_NAME} daemon restart\` to link it to ${url}`);
|
|
32
33
|
else out(`broker linked to ${broker.url ?? url}${broker.connected ? "" : " (connecting)"}`);
|
|
33
34
|
return 0;
|
|
34
35
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scp-dev/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "The swarm command line tool.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://scp.dev",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@scp-dev/core": "0.1.1",
|
|
28
|
-
"@scp-dev/broker": "0.1.
|
|
28
|
+
"@scp-dev/broker": "0.1.2",
|
|
29
29
|
"@scp-dev/hub": "0.1.1",
|
|
30
|
-
"@scp-dev/mcp": "0.1.
|
|
30
|
+
"@scp-dev/mcp": "0.1.2",
|
|
31
31
|
"smol-toml": "^1.9.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
package/dist/install-HFBSKSTG.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
hooksTarget,
|
|
3
|
-
installHooks,
|
|
4
|
-
mcpInstall
|
|
5
|
-
} from "./chunk-4DNQFATX.js";
|
|
6
|
-
import "./chunk-7KP6TAJW.js";
|
|
7
|
-
import "./chunk-XWLF7ON2.js";
|
|
8
|
-
import "./chunk-YYSLYVNZ.js";
|
|
9
|
-
import "./chunk-DA3EB2YF.js";
|
|
10
|
-
export {
|
|
11
|
-
hooksTarget,
|
|
12
|
-
installHooks,
|
|
13
|
-
mcpInstall
|
|
14
|
-
};
|