shadok-ai 0.13.11 → 0.13.13
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 +35 -0
- package/context/agents-skill/SKILL.md +27 -1
- package/context/agents-skill/pilotctl.mjs +112 -11
- package/dist/channels.d.ts +6 -0
- package/dist/channels.js.map +1 -1
- package/dist/peers.d.ts +66 -0
- package/dist/peers.js +127 -0
- package/dist/peers.js.map +1 -0
- package/dist/server.js +122 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/public/index.html +128 -0
package/README.md
CHANGED
|
@@ -359,6 +359,41 @@ every 25s (tunable with `SHADOK_WS_PING_MS`) to keep the connection warm, so no
|
|
|
359
359
|
proxy change is normally needed; if your proxy still cuts it, raise
|
|
360
360
|
`proxy_read_timeout` above the ping interval.
|
|
361
361
|
|
|
362
|
+
### Cross-instance peers
|
|
363
|
+
|
|
364
|
+
Agents can spawn and drive agents on **another** instance — another of yours, or
|
|
365
|
+
a teammate's. It is opt-in and gated like an account.
|
|
366
|
+
|
|
367
|
+
On the instance being reached (call it **B**), an admin **invites an agent** —
|
|
368
|
+
in the **Users** panel, exactly like inviting a person, except the invitee is a
|
|
369
|
+
machine so it gets a **prompt to paste** instead of a login link. Give it a name
|
|
370
|
+
and, optionally, a brief (what you want it to do); B mints a named, revocable
|
|
371
|
+
credential and hands you a ready-to-paste block: the cockpit URL, the key, the
|
|
372
|
+
brief, and the commands to join. Copy it into whatever agent you're inviting.
|
|
373
|
+
|
|
374
|
+
(The same thing over the API: `POST /peers {name, brief}` returns
|
|
375
|
+
`{ name, token, invitePrompt }` — the token is shown once.)
|
|
376
|
+
|
|
377
|
+
On the calling instance **A**, the invited agent registers B and drives it with
|
|
378
|
+
`pilotctl --peer` (the pasted prompt spells this out):
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
pilotctl peer add B https://B <token>
|
|
382
|
+
pilotctl spawn --peer B --profile dev --cwd /workspace
|
|
383
|
+
pilotctl prompt <id> "run the migration" --peer B
|
|
384
|
+
pilotctl diff <id> --peer B
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
The token is a **non-expiring, revocable** credential (an HMAC of the peer name;
|
|
388
|
+
`DELETE /peers?name=instance-a` on B kills it immediately — future calls **and**
|
|
389
|
+
the live link). A peer is **scoped to the agents it creates**: it can never see,
|
|
390
|
+
resume, drive or diff B's other agents, nor reach B's vault, profiles or crons.
|
|
391
|
+
|
|
392
|
+
**This is remote code execution by a third party** — a peer that can `spawn`
|
|
393
|
+
runs commands on B's machine. It is a deliberate admin grant, and a container per
|
|
394
|
+
instance stays the real boundary (see *Exposing it beyond this machine*). Manage
|
|
395
|
+
peers only for instances you trust to that degree.
|
|
396
|
+
|
|
362
397
|
### Signing in to Claude
|
|
363
398
|
|
|
364
399
|
A fresh machine — most often a fresh container — has two things in its way, and
|
|
@@ -113,10 +113,36 @@ time, and the information comes to you.
|
|
|
113
113
|
`--parent none` spawns an agent deliberately unattached; `--parent <id>`
|
|
114
114
|
attaches it elsewhere.
|
|
115
115
|
|
|
116
|
+
## Driving agents on ANOTHER instance (`--peer`)
|
|
117
|
+
|
|
118
|
+
You can spawn and drive agents on a **different** shadok instance — another one
|
|
119
|
+
of your own, or a teammate's — over an authenticated link. Add `--peer <alias>`
|
|
120
|
+
**after the command** (like `--profile`/`--cwd`) and it runs against that
|
|
121
|
+
instance instead of this one:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
pilotctl peer add brasdroit1 https://brasdroit1.example.com <token> # once
|
|
125
|
+
pilotctl spawn --peer brasdroit1 --profile dev --cwd /workspace # spawn there
|
|
126
|
+
pilotctl prompt <id> "run the migration" --peer brasdroit1 # drive it
|
|
127
|
+
pilotctl diff <id> --peer brasdroit1 # read its work
|
|
128
|
+
pilotctl stop <id> --peer brasdroit1
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- The **token** is minted by the REMOTE instance's admin (a human, in its
|
|
132
|
+
cockpit — `POST /peers`). Paste it in once with `peer add`; it is kept in a
|
|
133
|
+
600 file, `peer list` never prints it. You cannot mint your own — that is the
|
|
134
|
+
point: the other instance decides who may reach it.
|
|
135
|
+
- A peer is **scoped to the agents it creates**: `--peer X` can only resume /
|
|
136
|
+
drive / diff / stop agents YOU spawned on X, never its other agents. A refusal
|
|
137
|
+
comes back as `peer-scope`.
|
|
138
|
+
- `list` is not available over `--peer` (a peer sees only its own agents) — track
|
|
139
|
+
the ids you `spawn` and drive them by id.
|
|
140
|
+
|
|
116
141
|
## Guardrails
|
|
117
142
|
|
|
118
143
|
- NEVER `stop` a session this conversation did not create: it may belong to the
|
|
119
|
-
user in the web UI. `stop` ends the session for all its clients.
|
|
144
|
+
user in the web UI. `stop` ends the session for all its clients. (Over `--peer`
|
|
145
|
+
the server enforces this for you: you can only touch your own remote agents.)
|
|
120
146
|
- Every agent consumes the Claude quota like an ordinary session. Do not
|
|
121
147
|
multiply agents without an explicit request from the user.
|
|
122
148
|
- `prompt` on a session whose turn is already running → the error "a response is
|
|
@@ -30,8 +30,45 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
30
30
|
export const REPO_ROOT = path.resolve(__dirname, "..", "..", "..");
|
|
31
31
|
|
|
32
32
|
export const port = () => Number(process.env.SHADOK_PORT ?? 3789);
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
// A REMOTE peer to target for this command, set from `--peer <alias>` (or
|
|
35
|
+
// `--peer-url`/`--peer-token`). When set, every call goes to the peer's URL and
|
|
36
|
+
// authenticates with `x-shadok-peer` instead of the local session key — an agent
|
|
37
|
+
// on THIS instance driving an agent on ANOTHER. Null = the local server, as ever.
|
|
38
|
+
let PEER = null; // { url, token }
|
|
39
|
+
export function setPeer(p) { PEER = p; }
|
|
40
|
+
|
|
41
|
+
export const httpBase = () => (PEER ? PEER.url : `http://localhost:${port()}`);
|
|
42
|
+
export const wsUrl = () =>
|
|
43
|
+
PEER ? PEER.url.replace(/^http/, "ws") + "/ws" : `ws://localhost:${port()}/ws`;
|
|
44
|
+
|
|
45
|
+
// The per-instance outbound-peers file the server hands us as SHADOK_PEERS_FILE
|
|
46
|
+
// (a plain agent's cwd is a worktree, so it cannot derive its launch dir). A
|
|
47
|
+
// hand-run pilotctl with no such env falls back to a machine-global file.
|
|
48
|
+
export const peersFile = () =>
|
|
49
|
+
(process.env.SHADOK_PEERS_FILE || "").trim() ||
|
|
50
|
+
path.join(os.homedir(), ".shadok-ai", "peers-out.json");
|
|
51
|
+
export function loadPeersOut() {
|
|
52
|
+
try {
|
|
53
|
+
const j = JSON.parse(fs.readFileSync(peersFile(), "utf8"));
|
|
54
|
+
return j && typeof j === "object" ? j : {};
|
|
55
|
+
} catch {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function savePeersOut(map) {
|
|
60
|
+
fs.mkdirSync(path.dirname(peersFile()), { recursive: true });
|
|
61
|
+
const tmp = peersFile() + ".tmp";
|
|
62
|
+
fs.writeFileSync(tmp, JSON.stringify(map, null, 2), { mode: 0o600 });
|
|
63
|
+
fs.renameSync(tmp, peersFile());
|
|
64
|
+
}
|
|
65
|
+
/** Pure: the {url, token} for an alias, or null. Trailing slashes trimmed so
|
|
66
|
+
* `${url}/ws` and `${url}/diff` never double up. */
|
|
67
|
+
export function resolvePeer(peersOut, alias) {
|
|
68
|
+
const p = peersOut && peersOut[alias];
|
|
69
|
+
if (!p || typeof p.url !== "string" || typeof p.token !== "string" || !p.url || !p.token) return null;
|
|
70
|
+
return { url: p.url.replace(/\/+$/, ""), token: p.token };
|
|
71
|
+
}
|
|
35
72
|
// When a GUI password is set, the server injects SHADOK_AUTH=sk_auth=<token>
|
|
36
73
|
// into every agent's env; loopback HTTP + WS calls must present it as the cookie
|
|
37
74
|
// or the password gate 401s them — exactly what secret.py / schedule.py and the
|
|
@@ -43,12 +80,17 @@ export const wsUrl = () => `ws://localhost:${port()}/ws`;
|
|
|
43
80
|
// session id, verifies for as long as the agent runs, and grants exactly what
|
|
44
81
|
// the cookie did. Both are sent: the cookie still works, and an older server
|
|
45
82
|
// that does not know the header simply ignores it.
|
|
46
|
-
export const authHeaders = () =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
83
|
+
export const authHeaders = () =>
|
|
84
|
+
PEER
|
|
85
|
+
? // Targeting a remote peer: the ONLY credential it accepts is the peer token.
|
|
86
|
+
// Never leak the local cookie/session key to another instance.
|
|
87
|
+
{ "x-shadok-peer": PEER.token }
|
|
88
|
+
: {
|
|
89
|
+
...(process.env.SHADOK_AUTH ? { cookie: process.env.SHADOK_AUTH } : {}),
|
|
90
|
+
...(process.env.SHADOK_SESSION_KEY
|
|
91
|
+
? { "x-shadok-session-key": process.env.SHADOK_SESSION_KEY }
|
|
92
|
+
: {}),
|
|
93
|
+
};
|
|
52
94
|
export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
53
95
|
|
|
54
96
|
// The built-in WebSocket is WHATWG (addEventListener + event.data); the rest of
|
|
@@ -113,7 +155,10 @@ export function parseArgs(argv) {
|
|
|
113
155
|
for (let i = 0; i < rest.length; i++) {
|
|
114
156
|
const a = rest[i];
|
|
115
157
|
if (a === "--worktree" || a === "--continue" || a === "--readonly") flags[a.slice(2)] = true;
|
|
116
|
-
else if (
|
|
158
|
+
else if (
|
|
159
|
+
a === "--cwd" || a === "--resume" || a === "--timeout" || a === "--profile" || a === "--parent" ||
|
|
160
|
+
a === "--peer" || a === "--peer-url" || a === "--peer-token"
|
|
161
|
+
) flags[a.slice(2)] = rest[++i];
|
|
117
162
|
else pos.push(a);
|
|
118
163
|
}
|
|
119
164
|
return { cmd, pos, flags };
|
|
@@ -221,6 +266,10 @@ async function serverUp() {
|
|
|
221
266
|
}
|
|
222
267
|
|
|
223
268
|
export async function ensureServer() {
|
|
269
|
+
// Targeting a remote peer (`--peer`): it is someone else's server — never probe
|
|
270
|
+
// or auto-start a local one. If the peer is unreachable the connection fails
|
|
271
|
+
// with a clear error, which is the honest outcome.
|
|
272
|
+
if (PEER) return;
|
|
224
273
|
if (await serverUp()) return;
|
|
225
274
|
if (process.env.SHADOK_NO_AUTOSTART)
|
|
226
275
|
throw new Error(`shadok-ai server unreachable on :${port()}`);
|
|
@@ -263,7 +312,10 @@ export async function ensureHolder(id, cwd) {
|
|
|
263
312
|
const child = spawnChild(process.execPath, args, {
|
|
264
313
|
detached: true,
|
|
265
314
|
stdio: ["ignore", "pipe", "ignore"],
|
|
266
|
-
|
|
315
|
+
// A holder for a REMOTE agent must connect to the peer, not the local server.
|
|
316
|
+
// The detached child gets no `--peer` flag, so carry it in the ENV (never
|
|
317
|
+
// argv — a token in argv is world-readable via `ps`); `run()` reads it back.
|
|
318
|
+
env: PEER ? { ...process.env, SHADOK_PEER_URL: PEER.url, SHADOK_PEER_TOKEN: PEER.token } : process.env,
|
|
267
319
|
});
|
|
268
320
|
try {
|
|
269
321
|
await new Promise((resolve, reject) => {
|
|
@@ -504,10 +556,59 @@ async function cmdScreen(id, flags) {
|
|
|
504
556
|
}
|
|
505
557
|
|
|
506
558
|
const HELP =
|
|
507
|
-
"usage: pilotctl <spawn|prompt|dialog|choose|toggle|confirm|freetext|list|diff|stop|screen|profile-prompt>
|
|
559
|
+
"usage: pilotctl <spawn|prompt|dialog|choose|toggle|confirm|freetext|list|diff|stop|screen|profile-prompt|peer> …\n" +
|
|
560
|
+
" add --peer <alias> to any command to run it against another instance's agents\n" +
|
|
561
|
+
" pilotctl peer <add <alias> <url> <token>|list|rm <alias>>";
|
|
562
|
+
|
|
563
|
+
// Manage the outbound-peers file: aliases → { url, token }. The token is minted by
|
|
564
|
+
// the REMOTE instance's admin (POST /peers there) and pasted in here once. Local
|
|
565
|
+
// only, no server involved. `list` never prints tokens.
|
|
566
|
+
export function cmdPeer(pos) {
|
|
567
|
+
const [sub, alias, url, token] = pos;
|
|
568
|
+
const map = loadPeersOut();
|
|
569
|
+
if (sub === "add") {
|
|
570
|
+
if (!alias || !url || !token) throw new Error("usage: pilotctl peer add <alias> <url> <token>");
|
|
571
|
+
map[alias] = { url, token };
|
|
572
|
+
savePeersOut(map);
|
|
573
|
+
return { ok: true, alias, url };
|
|
574
|
+
}
|
|
575
|
+
if (sub === "rm") {
|
|
576
|
+
if (!alias) throw new Error("usage: pilotctl peer rm <alias>");
|
|
577
|
+
delete map[alias];
|
|
578
|
+
savePeersOut(map);
|
|
579
|
+
return { ok: true, alias };
|
|
580
|
+
}
|
|
581
|
+
if (sub === "list" || sub === undefined)
|
|
582
|
+
return { peers: Object.entries(map).map(([a, p]) => ({ alias: a, url: p?.url })) };
|
|
583
|
+
throw new Error("usage: pilotctl peer <add|rm|list> …");
|
|
584
|
+
}
|
|
508
585
|
|
|
509
586
|
export async function run(argv) {
|
|
510
587
|
const { cmd, pos, flags } = parseArgs(argv);
|
|
588
|
+
// Manage the outbound-peers file (local, no server).
|
|
589
|
+
if (cmd === "peer") return cmdPeer(pos);
|
|
590
|
+
// Target a REMOTE peer for this command — every call then goes to its URL with
|
|
591
|
+
// the peer token instead of the local session key. `--peer <alias>` resolves
|
|
592
|
+
// the outbound file; `--peer-url/--peer-token` is a one-off; SHADOK_PEER_URL/
|
|
593
|
+
// _TOKEN in the env is how a detached holder child inherits the peer.
|
|
594
|
+
if (flags.peer || flags["peer-url"] || process.env.SHADOK_PEER_URL) {
|
|
595
|
+
const target = flags["peer-url"]
|
|
596
|
+
? flags["peer-token"]
|
|
597
|
+
? { url: flags["peer-url"].replace(/\/+$/, ""), token: flags["peer-token"] }
|
|
598
|
+
: null
|
|
599
|
+
: flags.peer
|
|
600
|
+
? resolvePeer(loadPeersOut(), flags.peer)
|
|
601
|
+
: process.env.SHADOK_PEER_URL && process.env.SHADOK_PEER_TOKEN
|
|
602
|
+
? { url: process.env.SHADOK_PEER_URL.replace(/\/+$/, ""), token: process.env.SHADOK_PEER_TOKEN }
|
|
603
|
+
: null;
|
|
604
|
+
if (!target)
|
|
605
|
+
throw new Error(
|
|
606
|
+
flags["peer-url"]
|
|
607
|
+
? "--peer-url needs a --peer-token"
|
|
608
|
+
: `unknown peer "${flags.peer}" — add it with: pilotctl peer add <alias> <url> <token>`,
|
|
609
|
+
);
|
|
610
|
+
setPeer(target);
|
|
611
|
+
}
|
|
511
612
|
switch (cmd) {
|
|
512
613
|
case "spawn":
|
|
513
614
|
return cmdSpawn(flags);
|
package/dist/channels.d.ts
CHANGED
|
@@ -44,6 +44,12 @@ export interface Channel {
|
|
|
44
44
|
* blink, chime). Client-owned like `name`/`group`, stored here so the mute
|
|
45
45
|
* survives a reload and follows the user's other devices. */
|
|
46
46
|
muted?: boolean;
|
|
47
|
+
/** The PEER (another instance/harness) that spawned this agent, when a remote
|
|
48
|
+
* party created it via `x-shadok-peer`. A peer is scoped to agents it created,
|
|
49
|
+
* so this is the ownership key: only that peer may resume/drive/diff it, and
|
|
50
|
+
* this instance's admin sees who is driving what. Server-owned; absent for a
|
|
51
|
+
* locally-spawned agent. See `src/peers.ts`. */
|
|
52
|
+
createdByPeer?: string;
|
|
47
53
|
}
|
|
48
54
|
/**
|
|
49
55
|
* Should this channel be mirrored into Telegram?
|
package/dist/channels.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAyD7B;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,CAAU;IACnC,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClC,CAAC;AAED,+EAA+E;AAC/E,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAU,CAAC;AAE1G;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,CAAqC;IACjE,IAAI,CAAC,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAmB,EAAE,SAAiB;IACvE,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,MAAM,CAChE,CAAC;IACF,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAmB;IACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzD,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;IACrD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,KAAY;IAC3C,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAe;IACvC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YAAE,SAAS;QACpC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AACD,MAAM,UAAU,YAAY;IAC1B,+EAA+E;IAC/E,8EAA8E;IAC9E,0EAA0E;IAC1E,OAAO,gBAAgB,CACrB,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,EACnF,OAAO,CAAC,GAAG,EAAE,CACd,CAAC;AACJ,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,IAAe;IAC1C,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,SAAoC;IACzF,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,SAAS,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAAC,OAAsB,EAAE,iBAA0B;IAC7E,OAAO,OAAO,IAAI,IAAI,IAAI,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACjE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAe,EAAE,SAAiB;IACjE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;;;;;GAKG;AACH,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,IAAe,EAAE,KAA+C;IACzF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,KAAK,SAAS;gBAAG,GAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAA+C;IAC3E,YAAY,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,YAAY,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CAAC,IAAe,EAAE,MAAc,EAAE,QAAiB;IACpF,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,SAAS,CAAC,KAAK,QAAQ,CACrG,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,QAAiB;IAClE,OAAO,mBAAmB,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,UAAqB,EAAE,OAAoB;IAC1F,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5D,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;YAAE,SAAS;QACpD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YAAE,SAAS,CAAC,uDAAuD;QAC5F,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,wCAAwC;YACxD,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAY,EAAE,GAAG,CAAC,EAAE,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,YAAY;YAAE,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAG,MAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YAAE,SAAS;QACpC,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B;IAC1F,CAAC;IACD,6EAA6E;IAC7E,0EAA0E;IAC1E,0EAA0E;IAC1E,wEAAwE;IACxE,6EAA6E;IAC7E,sDAAsD;IACtD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI;YAAE,SAAS;QACzD,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;aACzC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;YAAE,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC;IACpD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,UAAqB,EAAE,OAAoB;IAC7E,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAClE,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC;AACD,MAAM,UAAU,UAAU,CAAC,IAAW;IACpC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;+EAC+E;AAC/E,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,SAAS,CAAC,gBAAgB,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;AACzE,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,IAAc,EAAE,GAAW,EAAE,EAAW;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IAC9C,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,cAAc,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,EAAW;IACjD,SAAS,CAAC,gBAAgB,EAAE,WAAW,CAAC,cAAc,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1C,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,MAAqB;IAC/C,SAAS,CAAC,gBAAgB,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,QAAQ,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;AAC1E,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,SAAS,CAAC,iBAAiB,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AACD,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;IACzB,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,YAAY,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IAChC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,oCAAoC;IAC9C,CAAC;IACD,IAAI,QAAe,CAAC;IACpB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACzE,aAAa,CAAC;oBACZ,SAAS,EAAE,CAAC,CAAC,SAAS;oBACtB,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;iBACpG,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC;AAqBD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA4B,EAC5B,SAAiB,EACjB,WAAmB;IAEnB,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;IAC3D,OAAO;QACL,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,WAAW;QACnC,OAAO,EAAE,EAAE,EAAE,OAAO,IAAI,IAAI;QAC5B,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,IAAI;QAC1B,IAAI,EAAE,EAAE,EAAE,IAAI,IAAI,IAAI;QACtB,KAAK,EAAE,CAAC,CAAC,EAAE;KACZ,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAC1B,QAA4B,EAC5B,SAAiB,EACjB,IAAsD,EACtD,WAAmB;IAEnB,MAAM,CAAC,GAAG,oBAAoB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,CAAC;IACrF,OAAO;QACL,GAAG,CAAC;QACJ,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI;QAC/C,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI;KAC1C,CAAC;AACJ,CAAC"}
|
package/dist/peers.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PEERS — other instances (or harnesses) allowed to reach THIS one's agents.
|
|
3
|
+
*
|
|
4
|
+
* A peer is the cross-instance twin of a web account (`accounts.ts`): named,
|
|
5
|
+
* revocable, per launch dir. Its credential is a token shaped exactly like the
|
|
6
|
+
* agent session key (invariant 33): an HMAC of the name, **non-expiring** (a
|
|
7
|
+
* cross-instance link is persistent and must not hit the 7-day cookie cliff) and
|
|
8
|
+
* **revocable by the registry** — the token embeds the name, and verifying
|
|
9
|
+
* requires that name to still be listed here. Delete the row ⇒ every token for
|
|
10
|
+
* it is dead, with no server state to keep. No secret is stored (it is derived),
|
|
11
|
+
* same as the session key. See docs/superpowers/specs/2026-09-26-cross-instance-
|
|
12
|
+
* agent-collaboration-design.md.
|
|
13
|
+
*
|
|
14
|
+
* A peer that connects is a DISTINCT principal, scoped by the caller to the
|
|
15
|
+
* agents it created (`Channel.createdByPeer`) — never B's whole fleet.
|
|
16
|
+
*/
|
|
17
|
+
export interface Peer {
|
|
18
|
+
name: string;
|
|
19
|
+
createdAt: number;
|
|
20
|
+
note?: string;
|
|
21
|
+
}
|
|
22
|
+
/** INBOUND registry, per launch dir, 600 — peers allowed to reach THIS instance. */
|
|
23
|
+
export declare function peerFileFor(cwd?: string): string;
|
|
24
|
+
/** OUTBOUND registry, per launch dir, 600 — peers THIS instance can reach
|
|
25
|
+
* (`{ alias: { url, token } }`, managed by `pilotctl peer add`). The server
|
|
26
|
+
* hands its path to every agent as SHADOK_PEERS_FILE (twin of the ledger file),
|
|
27
|
+
* since an agent's cwd is a worktree, not the launch dir. Read by the client
|
|
28
|
+
* (pilotctl); the server only needs to compute the path. */
|
|
29
|
+
export declare function peersOutFileFor(cwd?: string): string;
|
|
30
|
+
export declare function loadPeers(file: string): Peer[];
|
|
31
|
+
export declare function savePeers(file: string, peers: Peer[]): void;
|
|
32
|
+
/** A peer name is a slug: lowercased, safe chars, non-empty. null if nothing
|
|
33
|
+
* usable survives — an empty/invalid name must never become a live credential. */
|
|
34
|
+
export declare function normPeerName(name: unknown): string | null;
|
|
35
|
+
/** Pure: add (or supersede) a peer by name. */
|
|
36
|
+
export declare function addPeer(peers: Peer[], name: string, now: number, note?: string): Peer[];
|
|
37
|
+
/** Pure: drop a peer by name (revocation). */
|
|
38
|
+
export declare function removePeer(peers: Peer[], name: string): Peer[];
|
|
39
|
+
/** The peer token: `<b64url(name)>.<hmac("peer:"+b64)>`, twin of `signSessionKey`. */
|
|
40
|
+
export declare function signPeerToken(name: string, secret: Buffer): string;
|
|
41
|
+
/** Pure: the name a token attests to by its MAC alone, or null. Does NOT check
|
|
42
|
+
* the registry — that is `peerFromToken`. */
|
|
43
|
+
export declare function readPeerToken(token: string, secret: Buffer): string | null;
|
|
44
|
+
/** The peer a token authenticates: a valid MAC AND a name still in the registry.
|
|
45
|
+
* A token whose row was deleted is refused — that is the revocation. */
|
|
46
|
+
export declare function peerFromToken(token: string, secret: Buffer, peers: Peer[]): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* The ownership rule — a peer may only touch an agent IT created. The single
|
|
49
|
+
* named check behind every peer scope (resume, stop, /diff): a channel with a
|
|
50
|
+
* different `createdByPeer`, or none (a local agent), is NOT this peer's.
|
|
51
|
+
*/
|
|
52
|
+
export declare function ownedByPeer(channel: {
|
|
53
|
+
createdByPeer?: string;
|
|
54
|
+
} | undefined, peer: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* The copy-paste invitation for an AGENT — the peer equivalent of a user's
|
|
57
|
+
* single-use link. The invitee is an agent, not a human, so instead of a page
|
|
58
|
+
* where it picks a password it gets a PROMPT to paste into its own session: the
|
|
59
|
+
* cockpit URL, its key, the brief, and exactly how to join and report back.
|
|
60
|
+
* `brief` is the human's task (empty allowed). Pure so the wording is tested.
|
|
61
|
+
*/
|
|
62
|
+
export declare function agentInvitePrompt(opts: {
|
|
63
|
+
url: string;
|
|
64
|
+
token: string;
|
|
65
|
+
brief?: string;
|
|
66
|
+
}): string;
|
package/dist/peers.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { instanceKey } from "./paths.js";
|
|
6
|
+
/** INBOUND registry, per launch dir, 600 — peers allowed to reach THIS instance. */
|
|
7
|
+
export function peerFileFor(cwd = process.cwd()) {
|
|
8
|
+
return path.join(os.homedir(), ".shadok-ai", "peers", instanceKey(cwd) + ".json");
|
|
9
|
+
}
|
|
10
|
+
/** OUTBOUND registry, per launch dir, 600 — peers THIS instance can reach
|
|
11
|
+
* (`{ alias: { url, token } }`, managed by `pilotctl peer add`). The server
|
|
12
|
+
* hands its path to every agent as SHADOK_PEERS_FILE (twin of the ledger file),
|
|
13
|
+
* since an agent's cwd is a worktree, not the launch dir. Read by the client
|
|
14
|
+
* (pilotctl); the server only needs to compute the path. */
|
|
15
|
+
export function peersOutFileFor(cwd = process.cwd()) {
|
|
16
|
+
return path.join(os.homedir(), ".shadok-ai", "peers-out", instanceKey(cwd) + ".json");
|
|
17
|
+
}
|
|
18
|
+
export function loadPeers(file) {
|
|
19
|
+
try {
|
|
20
|
+
const j = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
21
|
+
return Array.isArray(j) ? j.filter((p) => p && typeof p.name === "string") : [];
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function savePeers(file, peers) {
|
|
28
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
29
|
+
const tmp = file + ".tmp";
|
|
30
|
+
fs.writeFileSync(tmp, JSON.stringify(peers, null, 2), { mode: 0o600 });
|
|
31
|
+
fs.renameSync(tmp, file);
|
|
32
|
+
}
|
|
33
|
+
/** A peer name is a slug: lowercased, safe chars, non-empty. null if nothing
|
|
34
|
+
* usable survives — an empty/invalid name must never become a live credential. */
|
|
35
|
+
export function normPeerName(name) {
|
|
36
|
+
const s = String(name ?? "")
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.trim()
|
|
39
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
40
|
+
.replace(/^-+|-+$/g, "");
|
|
41
|
+
return s || null;
|
|
42
|
+
}
|
|
43
|
+
/** Pure: add (or supersede) a peer by name. */
|
|
44
|
+
export function addPeer(peers, name, now, note) {
|
|
45
|
+
const row = { name, createdAt: now, ...(note ? { note } : {}) };
|
|
46
|
+
return [...peers.filter((p) => p.name !== name), row];
|
|
47
|
+
}
|
|
48
|
+
/** Pure: drop a peer by name (revocation). */
|
|
49
|
+
export function removePeer(peers, name) {
|
|
50
|
+
return peers.filter((p) => p.name !== name);
|
|
51
|
+
}
|
|
52
|
+
/** The peer token: `<b64url(name)>.<hmac("peer:"+b64)>`, twin of `signSessionKey`. */
|
|
53
|
+
export function signPeerToken(name, secret) {
|
|
54
|
+
const n = Buffer.from(name, "utf8").toString("base64url");
|
|
55
|
+
return `${n}.${createHmac("sha256", secret).update(`peer:${n}`).digest("hex")}`;
|
|
56
|
+
}
|
|
57
|
+
/** Pure: the name a token attests to by its MAC alone, or null. Does NOT check
|
|
58
|
+
* the registry — that is `peerFromToken`. */
|
|
59
|
+
export function readPeerToken(token, secret) {
|
|
60
|
+
const parts = String(token ?? "").split(".");
|
|
61
|
+
if (parts.length !== 2)
|
|
62
|
+
return null;
|
|
63
|
+
const [n, mac] = parts;
|
|
64
|
+
if (!n || !mac)
|
|
65
|
+
return null;
|
|
66
|
+
const want = createHmac("sha256", secret).update(`peer:${n}`).digest("hex");
|
|
67
|
+
// Length first: timingSafeEqual THROWS on a length mismatch (invariant in
|
|
68
|
+
// readSessionKey), which would be a 500 instead of a clean refusal.
|
|
69
|
+
if (mac.length !== want.length)
|
|
70
|
+
return null;
|
|
71
|
+
if (!timingSafeEqual(Buffer.from(mac), Buffer.from(want)))
|
|
72
|
+
return null;
|
|
73
|
+
try {
|
|
74
|
+
return Buffer.from(n, "base64url").toString("utf8") || null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** The peer a token authenticates: a valid MAC AND a name still in the registry.
|
|
81
|
+
* A token whose row was deleted is refused — that is the revocation. */
|
|
82
|
+
export function peerFromToken(token, secret, peers) {
|
|
83
|
+
const name = readPeerToken(token, secret);
|
|
84
|
+
if (!name)
|
|
85
|
+
return null;
|
|
86
|
+
return peers.some((p) => p.name === name) ? name : null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The ownership rule — a peer may only touch an agent IT created. The single
|
|
90
|
+
* named check behind every peer scope (resume, stop, /diff): a channel with a
|
|
91
|
+
* different `createdByPeer`, or none (a local agent), is NOT this peer's.
|
|
92
|
+
*/
|
|
93
|
+
export function ownedByPeer(channel, peer) {
|
|
94
|
+
return !!channel && channel.createdByPeer === peer;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The copy-paste invitation for an AGENT — the peer equivalent of a user's
|
|
98
|
+
* single-use link. The invitee is an agent, not a human, so instead of a page
|
|
99
|
+
* where it picks a password it gets a PROMPT to paste into its own session: the
|
|
100
|
+
* cockpit URL, its key, the brief, and exactly how to join and report back.
|
|
101
|
+
* `brief` is the human's task (empty allowed). Pure so the wording is tested.
|
|
102
|
+
*/
|
|
103
|
+
export function agentInvitePrompt(opts) {
|
|
104
|
+
const url = opts.url.replace(/\/+$/, "");
|
|
105
|
+
const brief = (opts.brief ?? "").trim();
|
|
106
|
+
return [
|
|
107
|
+
"You've been invited to collaborate with a shadok-ai cockpit as a peer agent.",
|
|
108
|
+
"",
|
|
109
|
+
`Cockpit: ${url}`,
|
|
110
|
+
`Your peer key: ${opts.token}`,
|
|
111
|
+
"(Keep the key secret — it authenticates you as this peer, and it can be revoked at any time.)",
|
|
112
|
+
"",
|
|
113
|
+
"To join, use the shadok-ai-agents skill (pilotctl):",
|
|
114
|
+
` pilotctl peer add host ${url} ${opts.token}`,
|
|
115
|
+
" pilotctl spawn --peer host --cwd /workspace # start an agent on the cockpit",
|
|
116
|
+
' pilotctl prompt <id> "<your work>" --peer host # drive it',
|
|
117
|
+
" pilotctl diff <id> --peer host # read what it changed",
|
|
118
|
+
"",
|
|
119
|
+
"You can only see and drive the agents you spawn there — nothing else on that cockpit.",
|
|
120
|
+
"",
|
|
121
|
+
brief ? "Your brief:" : "No brief was included — ask your inviter what they need before you start.",
|
|
122
|
+
...(brief ? ["", brief] : []),
|
|
123
|
+
"",
|
|
124
|
+
"When the task is done, or if you get blocked, report back to whoever invited you.",
|
|
125
|
+
].join("\n");
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=peers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peers.js","sourceRoot":"","sources":["../src/peers.ts"],"names":[],"mappings":"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"}
|