@scp-dev/cli 0.2.0 → 0.2.2
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 -0
- package/dist/chunk-E7JG5PJB.js +806 -0
- package/dist/{chunk-5DYFYLAQ.js → chunk-F5QVHJIT.js} +3 -5
- package/dist/{chunk-GH7AXFUL.js → chunk-G2SQPY6E.js} +8 -10
- package/dist/{chunk-M2DCR2J4.js → chunk-MNTIEWKF.js} +13 -3
- package/dist/{chunk-WV5FINTW.js → chunk-NOYMSD4F.js} +20 -10
- package/dist/{chunk-RXKBND3T.js → chunk-OTO6DBU6.js} +229 -13
- package/dist/{chunk-U2RSSTNW.js → chunk-ZDU53ZRF.js} +3 -5
- package/dist/{claude-YJLGFQ2P.js → claude-CVWECMRQ.js} +21 -11
- package/dist/cli.js +1 -1
- package/dist/codex-Y7SGLZ64.js +565 -0
- package/dist/{daemon-SUTLTY5U.js → daemon-OMJY7T2F.js} +1 -1
- package/dist/{hooks-EI7M3YKY.js → hooks-EKGY5O5N.js} +19 -3
- package/dist/install-4VBSX6RI.js +14 -0
- package/dist/join-RGFHOSLE.js +48 -0
- package/dist/{login-V2WT7QX5.js → login-IPS75GLQ.js} +4 -7
- package/dist/{main-HPBTO3JK.js → main-YN3J6MGW.js} +116 -32
- package/dist/{mcp-DGAQNFKO.js → mcp-BVC4PLZ7.js} +11 -11
- package/dist/mesh-VNZV3POO.js +28 -0
- package/dist/{peek-WLG3ZROU.js → peek-4D4VGKOW.js} +2 -3
- package/dist/{pi-HMESQA64.js → pi-R23XR4AC.js} +2 -3
- package/dist/{relay-5Z7IEXKD.js → relay-U634RHIJ.js} +6 -4
- package/dist/{remote-FYN5ZXE4.js → remote-NTHRHVEP.js} +3 -5
- package/dist/{setup-LXG346FJ.js → setup-H7GGUID2.js} +5 -6
- package/dist/{spawn-DLPMAS5M.js → spawn-AJAYD6CW.js} +6 -7
- package/dist/{up-GPM4LWY3.js → up-HZKGURPI.js} +6 -9
- package/package.json +8 -5
- package/dist/chunk-3RRPUYTE.js +0 -147
- package/dist/chunk-3V3DRXB2.js +0 -340
- package/dist/chunk-E53YHYEP.js +0 -305
- package/dist/install-MYHVFKT4.js +0 -15
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RelayUsage,
|
|
3
|
+
localHandle,
|
|
4
|
+
relayIdentity,
|
|
5
|
+
sessionKey,
|
|
6
|
+
startDaemon,
|
|
7
|
+
walkNow
|
|
8
|
+
} from "./chunk-E7JG5PJB.js";
|
|
9
|
+
import "./chunk-MNTIEWKF.js";
|
|
10
|
+
|
|
11
|
+
// src/join.ts
|
|
12
|
+
import { CLI_NAME } from "@scp-dev/core";
|
|
13
|
+
import { connectBroker, readSessionMarker, relayDir } from "@scp-dev/broker";
|
|
14
|
+
async function joinCommand(values, positionals, cwd, out) {
|
|
15
|
+
if (positionals.length > 1) throw new RelayUsage(`${CLI_NAME} join takes one handle, or none to keep the session's name`);
|
|
16
|
+
const handle = positionals[0] === void 0 ? void 0 : localHandle(positionals[0]);
|
|
17
|
+
const { keys, self } = walkNow();
|
|
18
|
+
const key = self.at(-1);
|
|
19
|
+
const match = key === void 0 ? null : /^pid:(\d+):(.+)$/.exec(key);
|
|
20
|
+
if (!match) throw new RelayUsage(`${CLI_NAME} join runs in an agent session's shell: no harness process runs this shell`);
|
|
21
|
+
const dir = relayDir();
|
|
22
|
+
const known = readSessionMarker(dir, sessionKey(process.env, key))?.handle;
|
|
23
|
+
const claim = relayIdentity({
|
|
24
|
+
...known ? { as: known } : {},
|
|
25
|
+
...typeof values.harness === "string" ? { harness: values.harness } : {},
|
|
26
|
+
fallbackHarness: "cli",
|
|
27
|
+
cwd,
|
|
28
|
+
env: process.env,
|
|
29
|
+
harnessPid: () => Number(match[1]),
|
|
30
|
+
startOf: () => match[2],
|
|
31
|
+
lineageOf: () => keys.slice(Math.max(0, keys.indexOf(key)))
|
|
32
|
+
});
|
|
33
|
+
const client = await connectBroker(dir, () => startDaemon(dir));
|
|
34
|
+
try {
|
|
35
|
+
const under = typeof values.under === "string" ? values.under : void 0;
|
|
36
|
+
const hello = await client.hello({ transient: true, claim, join: { ...handle ? { handle } : {}, ...under ? { under } : {} } });
|
|
37
|
+
const view = hello.endpoint;
|
|
38
|
+
if (values.json === true) out(JSON.stringify(view, null, 2));
|
|
39
|
+
else
|
|
40
|
+
out(`joined as ${view.address}${view.parent ? ` under ${view.parent}` : ""}: peers can message it, and its hooks hand it new messages at turn boundaries`);
|
|
41
|
+
} finally {
|
|
42
|
+
client.close();
|
|
43
|
+
}
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
joinCommand
|
|
48
|
+
};
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
machineName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZDU53ZRF.js";
|
|
4
4
|
import {
|
|
5
|
+
RelayUsage,
|
|
5
6
|
activeRelay,
|
|
6
7
|
saveCredential
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
RelayUsage
|
|
10
|
-
} from "./chunk-3V3DRXB2.js";
|
|
11
|
-
import "./chunk-E53YHYEP.js";
|
|
8
|
+
} from "./chunk-E7JG5PJB.js";
|
|
12
9
|
import {
|
|
13
10
|
note
|
|
14
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MNTIEWKF.js";
|
|
15
12
|
|
|
16
13
|
// src/login.ts
|
|
17
14
|
import { spawn } from "child_process";
|
|
@@ -11,20 +11,18 @@ import {
|
|
|
11
11
|
open,
|
|
12
12
|
preset,
|
|
13
13
|
selectorList,
|
|
14
|
+
shortHostname,
|
|
14
15
|
stamp,
|
|
15
16
|
startDaemon,
|
|
16
17
|
time
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import {
|
|
19
|
-
shortHostname
|
|
20
|
-
} from "./chunk-E53YHYEP.js";
|
|
18
|
+
} from "./chunk-E7JG5PJB.js";
|
|
21
19
|
import {
|
|
22
20
|
FAILED,
|
|
23
21
|
exitFlushed,
|
|
24
22
|
note,
|
|
25
23
|
parseSeconds,
|
|
26
24
|
printTable
|
|
27
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-MNTIEWKF.js";
|
|
28
26
|
|
|
29
27
|
// src/main.ts
|
|
30
28
|
import { text as readAll } from "stream/consumers";
|
|
@@ -35,7 +33,7 @@ import { parseArgs } from "util";
|
|
|
35
33
|
// package.json
|
|
36
34
|
var package_default = {
|
|
37
35
|
name: "@scp-dev/cli",
|
|
38
|
-
version: "0.2.
|
|
36
|
+
version: "0.2.2",
|
|
39
37
|
description: "The swarm command line tool.",
|
|
40
38
|
license: "Apache-2.0",
|
|
41
39
|
homepage: "https://scp.dev",
|
|
@@ -66,6 +64,9 @@ var package_default = {
|
|
|
66
64
|
"smol-toml": "^1.9.1"
|
|
67
65
|
},
|
|
68
66
|
devDependencies: {
|
|
67
|
+
"@openai/codex": "0.159.0",
|
|
68
|
+
"@scp-dev/mesh": "workspace:*",
|
|
69
|
+
"opencode-ai": "1.18.34",
|
|
69
70
|
tsup: "^8.5.1"
|
|
70
71
|
},
|
|
71
72
|
publishConfig: {
|
|
@@ -98,7 +99,9 @@ results back, as with native subagents.
|
|
|
98
99
|
${CLI_NAME} reply <id> [text|-] answer a message in its thread: ${CLI_NAME} reply 5af1f2 "done"
|
|
99
100
|
${CLI_NAME} ask <to> [text|-] [--wait S] send a request and wait for its reply: ${CLI_NAME} ask lead "which branch?"
|
|
100
101
|
${CLI_NAME} inbox [--wait S] your unread messages, then marked read: ${CLI_NAME} inbox
|
|
101
|
-
${CLI_NAME} list [--all] agents on the relay: address, title, presence, status
|
|
102
|
+
${CLI_NAME} list [--all] agents on the relay: address, title, presence, status; --all adds offline ones
|
|
103
|
+
${CLI_NAME} join [name] put this session on the relay, named once: ${CLI_NAME} join lead (${CLI_NAME} name renames it)
|
|
104
|
+
${CLI_NAME} join --under <parent> link this session under an orchestrator, as a spawned worker sits: ${CLI_NAME} join --under lead
|
|
102
105
|
${CLI_NAME} status [id] the fleet in short; with the id of a message you sent: who read it when
|
|
103
106
|
${CLI_NAME} peek <ep> a short, redacted view of a peekable agent's last turns: ${CLI_NAME} peek rev
|
|
104
107
|
${CLI_NAME} set-status <state> [note] working, waiting, blocked or done: ${CLI_NAME} set-status done "PR open"
|
|
@@ -123,8 +126,10 @@ usage:
|
|
|
123
126
|
sessions nobody spawned that spawned nobody fold into one line, --roots (or --all) lists
|
|
124
127
|
them; --tree nests them by parent; (you) marks your own
|
|
125
128
|
${CLI_NAME} list --contacts the endpoints of other accounts your contacts let you reach: address, harness, presence
|
|
126
|
-
${CLI_NAME} send <to> [text|-] send a message (- or no text reads stdin); a line per recipient says when it sees it
|
|
127
|
-
[--reply-to ID] [--thread ID] [--private] [--attach PATH]...
|
|
129
|
+
${CLI_NAME} send <to> [text|-] send a message (- or no text reads stdin); a line per recipient says when it sees it,
|
|
130
|
+
[--reply-to ID] [--thread ID] [--private] [--attach PATH]... [--live] and "queued: no live session holds <addr>" for one
|
|
131
|
+
that is offline; --live refuses those (not_live) and queues nothing;
|
|
132
|
+
--thread takes a thread id or the <id> of a message in it
|
|
128
133
|
${CLI_NAME} reply <id> [text|-] reply to message <id>: to its sender, in its thread, marking it read; <id> may
|
|
129
134
|
also be another's message in a thread you sent or got a message in
|
|
130
135
|
${CLI_NAME} inbox [--wait S] [--keep] your unread messages, then marked read (--keep leaves them unread); --wait waits up
|
|
@@ -227,6 +232,8 @@ scopes (selectors are comma-separated, e.g. tree:parent,tree:children,group:team
|
|
|
227
232
|
-c sandbox_workspace_write.network_access=true (the relay socket counts as network)
|
|
228
233
|
${CLI_NAME} pi [--name N] [--] [pi args...] runs pi with the @scp-dev/pi extension: the relay tools, and each new
|
|
229
234
|
message as a turn (steering a running one, waking an idle session)
|
|
235
|
+
${CLI_NAME} codex [--name N] [--headless] [--] [codex args...]
|
|
236
|
+
runs codex with relay messages waking an idle thread or steering a running turn
|
|
230
237
|
${CLI_NAME} peers [--all] [--roots] who you may message: title, status and the rule that admits each; offline ones and
|
|
231
238
|
sessions nobody spawned that spawned nobody only with --all (--roots: those sessions)
|
|
232
239
|
${CLI_NAME} why <from> <to> whether from may message to, and why
|
|
@@ -262,6 +269,30 @@ agent sessions:
|
|
|
262
269
|
${CLI_NAME} claude [--name N] [--] [claude args...] start Claude Code with the scp channel loaded, so peer messages wake
|
|
263
270
|
it while idle (claude --dangerously-load-development-channels server:scp; SCP_NAME=N)
|
|
264
271
|
--channels pushes messages into a Claude Code that ${CLI_NAME} claude started; setup mounts claude's shim with it.
|
|
272
|
+
Without --name, ${CLI_NAME} claude asks the session to pick its own name with ${CLI_NAME} name <name>.
|
|
273
|
+
${CLI_NAME} join [<handle>] put the session that runs this shell on the relay (it then shows in list,
|
|
274
|
+
peers can message it, and its hooks hand it new messages), named <handle>
|
|
275
|
+
when given; on a joined session it renames it in place. Works for a session
|
|
276
|
+
started before the hooks were installed too. Tell any session: ${CLI_NAME} join <name>
|
|
277
|
+
${CLI_NAME} name [<handle>] [--endpoint EP] print this session's address, or rename it in place: id, mail, threads, status
|
|
278
|
+
and title stay; a handle another endpoint holds, live or offline, is refused;
|
|
279
|
+
a spawned worker is named by its spawner (policy defaults.rename: self lets it);
|
|
280
|
+
--endpoint renames another agent, for the human at a terminal
|
|
281
|
+
${CLI_NAME} join [<handle>] --under <parent> link the session under the agent <parent> (local, one it may message), as if
|
|
282
|
+
<parent> had spawned it: it shows under <parent> in list --tree, the dashboard
|
|
283
|
+
and the graph, and takes on a worker's scope (the policy's child_default: by
|
|
284
|
+
default it reaches only what <parent> reaches). Narrowing, so always allowed
|
|
285
|
+
${CLI_NAME} adopt <child> [--parent <p>] link a local root agent and its subtree under <p>, for the human at a terminal;
|
|
286
|
+
from an agent's shell with a terminal attached <p> defaults to that agent.
|
|
287
|
+
An agent without a terminal is refused: the session joins with --under itself
|
|
288
|
+
${CLI_NAME} unlink [<child>] put a linked agent back at the root, its subtree along and the child scope off;
|
|
289
|
+
widening, so the human at a terminal only (policy defaults.unlink: self lets
|
|
290
|
+
an agent unlink itself). A link that would put a parent under its own child
|
|
291
|
+
(a cycle) is refused; both are audited, as adopt and unlink
|
|
292
|
+
${CLI_NAME} leave [--endpoint EP] take this session off the relay: offline, no messages pushed, mail kept until
|
|
293
|
+
${CLI_NAME} join; a spawned worker stays joined while it runs
|
|
294
|
+
With setup --join manual a session stays off the relay until it runs ${CLI_NAME} join; the default, auto, joins every
|
|
295
|
+
hooked session when it starts.
|
|
265
296
|
|
|
266
297
|
relay:
|
|
267
298
|
${CLI_NAME} relay use <url> | show select a relay, or show its source and credential status
|
|
@@ -277,7 +308,8 @@ identity:
|
|
|
277
308
|
--as HANDLE (or --as=HANDLE, anywhere on the line, or $SCP_NAME, a local handle; a leading me/ is dropped) acts as that agent, with --harness H
|
|
278
309
|
($SCP_HARNESS, default cli), $SCP_LABELS (role=impl,lane=relay) and $SCP_PARENT. An offline
|
|
279
310
|
agent of the same handle and harness is taken back with its inbox; a handle a live session holds is refused, never
|
|
280
|
-
|
|
311
|
+
suffixed. Run from that agent's own process, it acts as the agent, narrowing only. A session renamed with join or
|
|
312
|
+
name keeps its new handle: its hooks, its shim and commands with $SCP_NAME from its shell claim that one.
|
|
281
313
|
Without --as, at a terminal or with --human you are your own human inbox (me/); messages sent with --human and no
|
|
282
314
|
terminal are marked tty="false" and get no scope exemption. From an agent's process, --human acts as that agent.
|
|
283
315
|
Without either and without a terminal, a command acts as the agent whose harness process runs this shell (the
|
|
@@ -327,7 +359,12 @@ var VERB_OPTIONS = {
|
|
|
327
359
|
var IDENTITY = ["as", "harness", "human", "json", "cloud", "machine"];
|
|
328
360
|
var VERBS = {
|
|
329
361
|
list: [...IDENTITY, "all", "tree", "roots", "contacts"],
|
|
330
|
-
send: [...IDENTITY, "reply-to", "thread", "private", "attach"],
|
|
362
|
+
send: [...IDENTITY, "reply-to", "thread", "private", "attach", "live"],
|
|
363
|
+
join: ["harness", "json", "under"],
|
|
364
|
+
adopt: [...IDENTITY, "parent"],
|
|
365
|
+
unlink: IDENTITY,
|
|
366
|
+
leave: [...IDENTITY, "endpoint"],
|
|
367
|
+
name: [...IDENTITY, "endpoint"],
|
|
331
368
|
inbox: [...IDENTITY, "wait", "ack", "keep"],
|
|
332
369
|
reply: IDENTITY,
|
|
333
370
|
ack: [...IDENTITY, "all"],
|
|
@@ -498,12 +535,13 @@ async function relayMain(argv, cwd = process.cwd()) {
|
|
|
498
535
|
out(package_default.version);
|
|
499
536
|
return 0;
|
|
500
537
|
}
|
|
501
|
-
if (verb === "hook") return (await import("./hooks-
|
|
502
|
-
if (verb === "setup") return (await import("./setup-
|
|
503
|
-
if (verb === "claude") return (await import("./claude-
|
|
504
|
-
if (verb === "pi") return (await import("./pi-
|
|
538
|
+
if (verb === "hook") return (await import("./hooks-EKGY5O5N.js")).relayHookCommand(rest, startDaemon);
|
|
539
|
+
if (verb === "setup") return (await import("./setup-H7GGUID2.js")).relaySetupCommand(rest, cwd, out);
|
|
540
|
+
if (verb === "claude") return (await import("./claude-CVWECMRQ.js")).claudeCommand(rest);
|
|
541
|
+
if (verb === "pi") return (await import("./pi-R23XR4AC.js")).piCommand(rest);
|
|
542
|
+
if (verb === "codex") return (await import("./codex-Y7SGLZ64.js")).codexCommand(rest);
|
|
505
543
|
if (verb === "spawn") {
|
|
506
|
-
const { splitSpawn, spawnCommand } = await import("./spawn-
|
|
544
|
+
const { splitSpawn, spawnCommand } = await import("./spawn-AJAYD6CW.js");
|
|
507
545
|
const { flags } = splitSpawn(rest);
|
|
508
546
|
if (flags.includes("--help") || flags.includes("-h")) {
|
|
509
547
|
out(flags.includes("--all") ? RELAY_HELP : SPAWN_HELP);
|
|
@@ -511,6 +549,7 @@ async function relayMain(argv, cwd = process.cwd()) {
|
|
|
511
549
|
}
|
|
512
550
|
return spawnCommand(rest, cwd);
|
|
513
551
|
}
|
|
552
|
+
if (verb === "mesh") return (await import("./mesh-VNZV3POO.js")).meshCommand(rest);
|
|
514
553
|
const allowed = VERBS[verb];
|
|
515
554
|
if (!allowed) throw new RelayUsage(`unknown command "${verb}"`);
|
|
516
555
|
let parsed;
|
|
@@ -530,11 +569,11 @@ async function relayMain(argv, cwd = process.cwd()) {
|
|
|
530
569
|
return daemon(values.idle, values.policy);
|
|
531
570
|
}
|
|
532
571
|
if (verb === "mcp")
|
|
533
|
-
return (await import("./mcp-
|
|
572
|
+
return (await import("./mcp-BVC4PLZ7.js")).relayMcpCommand(values, positionals);
|
|
534
573
|
if (verb === "hooks") {
|
|
535
574
|
if (positionals[0] !== "install" || positionals.length > 1) throw new RelayUsage(`${CLI_NAME} hooks takes install --harness claude|codex|opencode|agy|muse`);
|
|
536
575
|
if (values.write && values.print) throw new RelayUsage("--print and --write: pick one");
|
|
537
|
-
return (await import("./install-
|
|
576
|
+
return (await import("./install-4VBSX6RI.js")).installHooks({
|
|
538
577
|
harness: values.harness,
|
|
539
578
|
scope: values.scope,
|
|
540
579
|
write: values.write === true,
|
|
@@ -545,25 +584,26 @@ async function relayMain(argv, cwd = process.cwd()) {
|
|
|
545
584
|
out
|
|
546
585
|
});
|
|
547
586
|
}
|
|
548
|
-
if (verb === "relay") return (await import("./relay-
|
|
549
|
-
if (verb === "up") return (await import("./up-
|
|
587
|
+
if (verb === "relay") return (await import("./relay-U634RHIJ.js")).relayVerb(positionals, values.json === true);
|
|
588
|
+
if (verb === "up") return (await import("./up-HZKGURPI.js")).up(positionals, values, cwd, relinkBroker);
|
|
550
589
|
if (verb === "login") {
|
|
551
|
-
const code = await (await import("./relay-
|
|
590
|
+
const code = await (await import("./relay-U634RHIJ.js")).loginMain(positionals, values);
|
|
552
591
|
if (code === 0) await relinkRunning();
|
|
553
592
|
return code;
|
|
554
593
|
}
|
|
555
|
-
if (verb === "logout") return (await import("./relay-
|
|
594
|
+
if (verb === "logout") return (await import("./relay-U634RHIJ.js")).logoutMain(positionals, values.json === true);
|
|
556
595
|
if (verb === "cloud") {
|
|
557
|
-
const code = await (await import("./remote-
|
|
596
|
+
const code = await (await import("./remote-NTHRHVEP.js")).cloudMain(positionals, values, cloudStatus);
|
|
558
597
|
if (code === 0 && positionals[0] === "enable") await relinkRunning();
|
|
559
598
|
return code;
|
|
560
599
|
}
|
|
600
|
+
if (verb === "join") return (await import("./join-RGFHOSLE.js")).joinCommand(values, positionals, cwd, out);
|
|
561
601
|
if (verb === "holds") holdsArgs(values, positionals);
|
|
562
602
|
const bodyFromStdin = (verb === "send" || verb === "ask" || verb === "reply") && (positionals[1] === void 0 || positionals[1] === "-");
|
|
563
603
|
const opened = await open(verb, values, cwd, bodyFromStdin);
|
|
564
604
|
const { client } = opened;
|
|
565
605
|
try {
|
|
566
|
-
if (verb === "machines") return await (await import("./remote-
|
|
606
|
+
if (verb === "machines") return await (await import("./remote-NTHRHVEP.js")).machinesVerb(client, positionals, values.json === true);
|
|
567
607
|
return await runVerb(opened, verb, values, positionals, cwd);
|
|
568
608
|
} finally {
|
|
569
609
|
client.close();
|
|
@@ -594,7 +634,7 @@ async function relinkBroker() {
|
|
|
594
634
|
client.close();
|
|
595
635
|
}
|
|
596
636
|
if (!result.restarting) return result;
|
|
597
|
-
await (await import("./daemon-
|
|
637
|
+
await (await import("./daemon-OMJY7T2F.js")).exited(pid);
|
|
598
638
|
return cloudStatus();
|
|
599
639
|
}
|
|
600
640
|
async function relinkRunning() {
|
|
@@ -614,7 +654,7 @@ async function daemonControl(positionals, values) {
|
|
|
614
654
|
if (positionals.length !== 1 || action !== "stop" && action !== "restart" || values.idle !== void 0 || values.policy !== void 0)
|
|
615
655
|
throw new RelayUsage(`${CLI_NAME} daemon takes stop or restart, or --idle and --policy to run in the foreground`);
|
|
616
656
|
const dir = relayDir();
|
|
617
|
-
const pid = await (await import("./daemon-
|
|
657
|
+
const pid = await (await import("./daemon-OMJY7T2F.js")).stopBroker(dir);
|
|
618
658
|
if (action === "stop") {
|
|
619
659
|
out(pid === null ? "no relay broker runs" : `stopped the relay broker (pid ${pid}); the next command starts a fresh one`);
|
|
620
660
|
return 0;
|
|
@@ -740,9 +780,9 @@ async function runVerb({ client, me, broker, where, bound, harnessPid }, verb, v
|
|
|
740
780
|
return 0;
|
|
741
781
|
}
|
|
742
782
|
case "peek":
|
|
743
|
-
return (await import("./peek-
|
|
783
|
+
return (await import("./peek-4D4VGKOW.js")).peekCommand(localClient(client, broker, verb), values, positionals);
|
|
744
784
|
case "set-peek":
|
|
745
|
-
return (await import("./peek-
|
|
785
|
+
return (await import("./peek-4D4VGKOW.js")).setPeekCommand(localClient(client, broker, verb), values, positionals);
|
|
746
786
|
case "why": {
|
|
747
787
|
const [from, to] = positionals;
|
|
748
788
|
if (!from || !to || positionals.length > 2) throw new RelayUsage(`${CLI_NAME} why takes <from> <to>`);
|
|
@@ -768,13 +808,13 @@ async function runVerb({ client, me, broker, where, bound, harnessPid }, verb, v
|
|
|
768
808
|
...attachments.length ? { attachments } : {}
|
|
769
809
|
};
|
|
770
810
|
if (verb === "send") {
|
|
771
|
-
const result2 = await client.request("send", params);
|
|
811
|
+
const result2 = await client.request("send", { ...params, ...values.live ? { live: true } : {} });
|
|
772
812
|
if (asJson) json(result2);
|
|
773
813
|
else if (result2.held) out(heldText(result2.held));
|
|
774
814
|
else {
|
|
775
815
|
const lines = reachLines(result2.deliveries);
|
|
776
816
|
out(`sent ${result2.id} to ${result2.deliveries.map((d) => lines.length ? d.address : deliveryText(d)).join(", ")}${redactedText(result2.redacted)}`);
|
|
777
|
-
for (const line of lines) out(` ${line}`);
|
|
817
|
+
for (const line of [...lines, ...result2.warnings ?? []]) out(` ${line}`);
|
|
778
818
|
if (result2.deliveries.some((d) => d.state === "running" || d.state === "starting"))
|
|
779
819
|
out(` ${CLI_NAME} status ${shortId(result2.id)} shows when it is read`);
|
|
780
820
|
}
|
|
@@ -943,6 +983,50 @@ async function runVerb({ client, me, broker, where, bound, harnessPid }, verb, v
|
|
|
943
983
|
else out(`${view.address}: ${view.status ? statusText(view.status) : "-"}`);
|
|
944
984
|
return 0;
|
|
945
985
|
}
|
|
986
|
+
case "name": {
|
|
987
|
+
if (positionals.length > 1) throw new RelayUsage(`${CLI_NAME} name takes one handle, or none to print your address`);
|
|
988
|
+
const endpoint = values.endpoint;
|
|
989
|
+
if (!positionals.length) {
|
|
990
|
+
if (endpoint !== void 0) throw new RelayUsage(`${CLI_NAME} name --endpoint EP takes the new handle`);
|
|
991
|
+
if (me?.kind !== "agent") throw new RelayUsage(`${CLI_NAME} name: this shell is no joined session; ${CLI_NAME} join <name> joins it`);
|
|
992
|
+
if (asJson) json({ address: me.address });
|
|
993
|
+
else out(me.address);
|
|
994
|
+
return 0;
|
|
995
|
+
}
|
|
996
|
+
const before = endpoint ?? me?.address;
|
|
997
|
+
const view = await client.request("rename", { handle: positionals[0], ...endpoint !== void 0 ? { endpoint } : {} });
|
|
998
|
+
if (asJson) json(view);
|
|
999
|
+
else out(before && before !== view.address ? `${before} is now ${view.address}` : `${view.address}`);
|
|
1000
|
+
return 0;
|
|
1001
|
+
}
|
|
1002
|
+
case "adopt": {
|
|
1003
|
+
if (positionals.length !== 1) throw new RelayUsage(`${CLI_NAME} adopt takes the child to link: ${CLI_NAME} adopt <child> [--parent <p>]`);
|
|
1004
|
+
const parent = values.parent;
|
|
1005
|
+
if (parent === void 0 && me?.kind !== "agent")
|
|
1006
|
+
throw new RelayUsage(`${CLI_NAME} adopt: name the parent with --parent <p> (run from an agent's shell, it defaults to that agent)`);
|
|
1007
|
+
const result = await client.request("adopt", {
|
|
1008
|
+
endpoint: positionals[0],
|
|
1009
|
+
...parent !== void 0 ? { parent } : {}
|
|
1010
|
+
});
|
|
1011
|
+
if (asJson) json(result);
|
|
1012
|
+
else out(`${result.endpoint.address} now sits under ${result.parent}`);
|
|
1013
|
+
return 0;
|
|
1014
|
+
}
|
|
1015
|
+
case "unlink": {
|
|
1016
|
+
if (positionals.length > 1) throw new RelayUsage(`${CLI_NAME} unlink takes one child, or none for this session`);
|
|
1017
|
+
const result = await client.request("unlink", positionals.length ? { endpoint: positionals[0] } : {});
|
|
1018
|
+
if (asJson) json(result);
|
|
1019
|
+
else out(`${result.endpoint.address} is a root again (was under ${result.parent})`);
|
|
1020
|
+
return 0;
|
|
1021
|
+
}
|
|
1022
|
+
case "leave": {
|
|
1023
|
+
if (positionals.length) throw new RelayUsage(`${CLI_NAME} leave takes no arguments (--endpoint EP for the human at a terminal)`);
|
|
1024
|
+
const endpoint = values.endpoint;
|
|
1025
|
+
const view = await client.request("leave", endpoint !== void 0 ? { endpoint } : {});
|
|
1026
|
+
if (asJson) json(view);
|
|
1027
|
+
else out(`${view.address} left the relay: offline, no messages pushed; its mail is kept until ${CLI_NAME} join`);
|
|
1028
|
+
return 0;
|
|
1029
|
+
}
|
|
946
1030
|
case "set-title": {
|
|
947
1031
|
if (!positionals.length) throw new RelayUsage(`${CLI_NAME} set-title takes the title text ("" clears it)`);
|
|
948
1032
|
const view = await client.request("title", { text: positionals.join(" ") });
|
|
@@ -1295,11 +1379,11 @@ async function daemon(idle, policyFile) {
|
|
|
1295
1379
|
});
|
|
1296
1380
|
let broker;
|
|
1297
1381
|
try {
|
|
1298
|
-
const { daemonBridge } = await import("./remote-
|
|
1382
|
+
const { daemonBridge } = await import("./remote-NTHRHVEP.js");
|
|
1299
1383
|
const bridge = await daemonBridge();
|
|
1300
1384
|
broker = await startBroker({
|
|
1301
1385
|
dir: relayDir(),
|
|
1302
|
-
...bridge ? { bridge } :
|
|
1386
|
+
...bridge ? { bridge } : await (await import("./mesh-VNZV3POO.js")).meshBrokerOptions(),
|
|
1303
1387
|
bridgeConfig: () => daemonBridge(),
|
|
1304
1388
|
...idleMs !== void 0 ? { idleMs } : {},
|
|
1305
1389
|
...policyFile ? { policyPath: resolve(policyFile) } : {}
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
spawnDetached
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-G2SQPY6E.js";
|
|
4
4
|
import "./chunk-KN7WEIE4.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-NOYMSD4F.js";
|
|
6
6
|
import {
|
|
7
7
|
mcpInstall
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-F5QVHJIT.js";
|
|
9
|
+
import "./chunk-OTO6DBU6.js";
|
|
10
|
+
import "./chunk-YYSLYVNZ.js";
|
|
9
11
|
import {
|
|
10
12
|
CHANNELS_ENV,
|
|
11
13
|
RelayUsage,
|
|
12
|
-
startDaemon
|
|
13
|
-
} from "./chunk-3V3DRXB2.js";
|
|
14
|
-
import "./chunk-RXKBND3T.js";
|
|
15
|
-
import "./chunk-YYSLYVNZ.js";
|
|
16
|
-
import {
|
|
17
14
|
harnessPid,
|
|
15
|
+
membership,
|
|
18
16
|
psParent,
|
|
19
|
-
relayIdentity
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
relayIdentity,
|
|
18
|
+
startDaemon
|
|
19
|
+
} from "./chunk-E7JG5PJB.js";
|
|
20
|
+
import "./chunk-MNTIEWKF.js";
|
|
22
21
|
|
|
23
22
|
// src/mcp.ts
|
|
24
23
|
import { CLI_NAME, validHandle } from "@scp-dev/core";
|
|
@@ -45,6 +44,7 @@ async function relayMcpCommand(values, positionals) {
|
|
|
45
44
|
await runRelayMcp({
|
|
46
45
|
connect: () => connectBroker(dir, () => startDaemon(dir)),
|
|
47
46
|
claim,
|
|
47
|
+
membership: () => membership(process.env, claim.session),
|
|
48
48
|
input: process.stdin,
|
|
49
49
|
output: (line) => void process.stdout.write(line),
|
|
50
50
|
env: process.env,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RelayUsage
|
|
3
|
+
} from "./chunk-E7JG5PJB.js";
|
|
4
|
+
import "./chunk-MNTIEWKF.js";
|
|
5
|
+
|
|
6
|
+
// src/mesh.ts
|
|
7
|
+
import { existsSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
import { relayDir } from "@scp-dev/broker";
|
|
10
|
+
var MESH_MODULE = "@scp-dev/mesh";
|
|
11
|
+
async function load() {
|
|
12
|
+
try {
|
|
13
|
+
return await import(MESH_MODULE);
|
|
14
|
+
} catch {
|
|
15
|
+
throw new RelayUsage("swarm mesh is experimental and runs only from a source checkout of the swarm CLI");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function meshCommand(argv) {
|
|
19
|
+
return (await load()).meshCommand(argv);
|
|
20
|
+
}
|
|
21
|
+
async function meshBrokerOptions() {
|
|
22
|
+
if (!existsSync(join(relayDir(), "mesh", "mesh.json"))) return {};
|
|
23
|
+
return (await load()).meshBrokerOptions();
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
meshBrokerOptions,
|
|
27
|
+
meshCommand
|
|
28
|
+
};
|
|
@@ -2,11 +2,10 @@ import {
|
|
|
2
2
|
RelayUsage,
|
|
3
3
|
peekGrant,
|
|
4
4
|
stamp
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-E53YHYEP.js";
|
|
5
|
+
} from "./chunk-E7JG5PJB.js";
|
|
7
6
|
import {
|
|
8
7
|
note
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-MNTIEWKF.js";
|
|
10
9
|
|
|
11
10
|
// src/peek.ts
|
|
12
11
|
import { PREAMBLE, wrapPeek, CLI_NAME } from "@scp-dev/core";
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
activeRelay,
|
|
4
4
|
checkRelayUrl,
|
|
5
5
|
configDir,
|
|
6
|
+
joinMode,
|
|
6
7
|
loginMain,
|
|
7
8
|
logoutMain,
|
|
8
9
|
readCredentials,
|
|
@@ -10,16 +11,16 @@ import {
|
|
|
10
11
|
relayVerb,
|
|
11
12
|
removeCredential,
|
|
12
13
|
saveCredential,
|
|
14
|
+
setJoinMode,
|
|
13
15
|
writePrivateJson
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-E53YHYEP.js";
|
|
17
|
-
import "./chunk-M2DCR2J4.js";
|
|
16
|
+
} from "./chunk-E7JG5PJB.js";
|
|
17
|
+
import "./chunk-MNTIEWKF.js";
|
|
18
18
|
export {
|
|
19
19
|
DEFAULT_RELAY,
|
|
20
20
|
activeRelay,
|
|
21
21
|
checkRelayUrl,
|
|
22
22
|
configDir,
|
|
23
|
+
joinMode,
|
|
23
24
|
loginMain,
|
|
24
25
|
logoutMain,
|
|
25
26
|
readCredentials,
|
|
@@ -27,5 +28,6 @@ export {
|
|
|
27
28
|
relayVerb,
|
|
28
29
|
removeCredential,
|
|
29
30
|
saveCredential,
|
|
31
|
+
setJoinMode,
|
|
30
32
|
writePrivateJson
|
|
31
33
|
};
|
|
@@ -9,11 +9,9 @@ import {
|
|
|
9
9
|
machinesVerb,
|
|
10
10
|
openCloud,
|
|
11
11
|
readCloudFile
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-E53YHYEP.js";
|
|
16
|
-
import "./chunk-M2DCR2J4.js";
|
|
12
|
+
} from "./chunk-ZDU53ZRF.js";
|
|
13
|
+
import "./chunk-E7JG5PJB.js";
|
|
14
|
+
import "./chunk-MNTIEWKF.js";
|
|
17
15
|
export {
|
|
18
16
|
CloudRelayClient,
|
|
19
17
|
CloudUsage,
|
|
@@ -15,13 +15,12 @@ import {
|
|
|
15
15
|
verifyMount,
|
|
16
16
|
verifyMusePlugin,
|
|
17
17
|
whichOnPath
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-RXKBND3T.js";
|
|
18
|
+
} from "./chunk-NOYMSD4F.js";
|
|
19
|
+
import "./chunk-F5QVHJIT.js";
|
|
20
|
+
import "./chunk-OTO6DBU6.js";
|
|
22
21
|
import "./chunk-YYSLYVNZ.js";
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-E7JG5PJB.js";
|
|
23
|
+
import "./chunk-MNTIEWKF.js";
|
|
25
24
|
export {
|
|
26
25
|
SETUP_HARNESSES,
|
|
27
26
|
SETUP_HELP,
|
|
@@ -29,17 +29,16 @@ import {
|
|
|
29
29
|
steerArgv,
|
|
30
30
|
transcriptReplies,
|
|
31
31
|
workerName
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-G2SQPY6E.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-RXKBND3T.js";
|
|
36
|
+
import "./chunk-NOYMSD4F.js";
|
|
37
|
+
import "./chunk-F5QVHJIT.js";
|
|
38
|
+
import "./chunk-OTO6DBU6.js";
|
|
40
39
|
import "./chunk-YYSLYVNZ.js";
|
|
41
|
-
import "./chunk-
|
|
42
|
-
import "./chunk-
|
|
40
|
+
import "./chunk-E7JG5PJB.js";
|
|
41
|
+
import "./chunk-MNTIEWKF.js";
|
|
43
42
|
export {
|
|
44
43
|
MESSAGING,
|
|
45
44
|
SPAWN_HELP,
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
RelayUsage,
|
|
2
3
|
activeRelay,
|
|
3
4
|
relayCredential
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import
|
|
6
|
-
RelayUsage
|
|
7
|
-
} from "./chunk-3V3DRXB2.js";
|
|
8
|
-
import "./chunk-E53YHYEP.js";
|
|
9
|
-
import "./chunk-M2DCR2J4.js";
|
|
5
|
+
} from "./chunk-E7JG5PJB.js";
|
|
6
|
+
import "./chunk-MNTIEWKF.js";
|
|
10
7
|
|
|
11
8
|
// src/up.ts
|
|
12
9
|
import { CLI_NAME } from "@scp-dev/core";
|
|
@@ -17,16 +14,16 @@ async function up(positionals, values, cwd, brokerStatus) {
|
|
|
17
14
|
const { url } = activeRelay(process.env);
|
|
18
15
|
const headless = values.token !== void 0 || Boolean(process.env.SCP_TOKEN?.trim());
|
|
19
16
|
if (headless || !relayCredential(process.env, url).token) {
|
|
20
|
-
const code = await (await import("./login-
|
|
17
|
+
const code = await (await import("./login-IPS75GLQ.js")).login({
|
|
21
18
|
...values.token !== void 0 ? { token: values.token } : {},
|
|
22
19
|
...values.label !== void 0 ? { label: values.label } : {},
|
|
23
20
|
...values["no-browser"] ? { "no-browser": true } : {}
|
|
24
21
|
});
|
|
25
22
|
if (code !== 0) return code;
|
|
26
23
|
} else out(`already logged in to ${url}`);
|
|
27
|
-
const enabled = await (await import("./remote-
|
|
24
|
+
const enabled = await (await import("./remote-NTHRHVEP.js")).cloudMain(["enable"], values.machine !== void 0 ? { machine: values.machine } : {}, brokerStatus);
|
|
28
25
|
if (enabled !== 0) return enabled;
|
|
29
|
-
const setup = (await import("./setup-
|
|
26
|
+
const setup = (await import("./setup-H7GGUID2.js")).relaySetupCommand(["--write"], cwd, out);
|
|
30
27
|
if (setup !== 0) return setup;
|
|
31
28
|
const broker = await brokerStatus();
|
|
32
29
|
if (!broker.enabled) out(`the broker is still local-only; run \`${CLI_NAME} daemon restart\` to link it to ${url}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scp-dev/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "The swarm command line tool.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://scp.dev",
|
|
@@ -24,13 +24,16 @@
|
|
|
24
24
|
"typecheck": "tsc -p ."
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@scp-dev/core": "0.1.
|
|
28
|
-
"@scp-dev/broker": "0.1.
|
|
29
|
-
"@scp-dev/hub": "0.
|
|
30
|
-
"@scp-dev/mcp": "0.1.
|
|
27
|
+
"@scp-dev/core": "0.1.3",
|
|
28
|
+
"@scp-dev/broker": "0.1.4",
|
|
29
|
+
"@scp-dev/hub": "0.3.0",
|
|
30
|
+
"@scp-dev/mcp": "0.1.4",
|
|
31
31
|
"smol-toml": "^1.9.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
+
"@openai/codex": "0.159.0",
|
|
35
|
+
"@scp-dev/mesh": "0.0.1",
|
|
36
|
+
"opencode-ai": "1.18.34",
|
|
34
37
|
"tsup": "^8.5.1"
|
|
35
38
|
},
|
|
36
39
|
"publishConfig": {
|