shadok-ai 0.13.12 → 0.13.14
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 +138 -11
- package/dist/channels.d.ts +6 -0
- package/dist/channels.js.map +1 -1
- package/dist/peers.d.ts +158 -0
- package/dist/peers.js +213 -0
- package/dist/peers.js.map +1 -0
- package/dist/server.js +150 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/public/index.html +90 -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,85 @@ 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> <ticket> [--token]|list|rm <alias>>";
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Manage the outbound-peers file: aliases → { url, token }.
|
|
565
|
+
*
|
|
566
|
+
* `add` takes the single-use TICKET from the invitation and ENROLS with it: it
|
|
567
|
+
* posts the ticket to the remote `POST /peers/enrol`, which consumes it and
|
|
568
|
+
* returns the durable token stored here. So the credential we keep is one this
|
|
569
|
+
* side obtained itself — the invitation, which gets pasted into a session and
|
|
570
|
+
* lives on in a transcript, only ever held something that dies on first use.
|
|
571
|
+
*
|
|
572
|
+
* A ticket that has already been redeemed, expired or never existed is refused
|
|
573
|
+
* by the remote with one indistinguishable message, and we store NOTHING: a
|
|
574
|
+
* saved credential that does not authenticate is worse than a clear error.
|
|
575
|
+
*
|
|
576
|
+
* `--token` skips the exchange and stores the value as a durable token, for a
|
|
577
|
+
* credential issued some other way. `list` never prints either.
|
|
578
|
+
*/
|
|
579
|
+
export async function cmdPeer(pos, flags = {}) {
|
|
580
|
+
const [sub, alias, url, secret] = pos;
|
|
581
|
+
const map = loadPeersOut();
|
|
582
|
+
if (sub === "add") {
|
|
583
|
+
if (!alias || !url || !secret)
|
|
584
|
+
throw new Error("usage: pilotctl peer add <alias> <url> <ticket> [--token]");
|
|
585
|
+
const base = String(url).replace(/\/+$/, "");
|
|
586
|
+
let token = secret;
|
|
587
|
+
if (!flags.token) {
|
|
588
|
+
const r = await fetch(`${base}/peers/enrol`, {
|
|
589
|
+
method: "POST",
|
|
590
|
+
headers: { "content-type": "application/json" },
|
|
591
|
+
body: JSON.stringify({ ticket: secret }),
|
|
592
|
+
});
|
|
593
|
+
const j = await r.json().catch(() => ({}));
|
|
594
|
+
if (!r.ok || !j?.token) throw new Error(j?.error || `enrolment refused (HTTP ${r.status})`);
|
|
595
|
+
token = j.token;
|
|
596
|
+
}
|
|
597
|
+
map[alias] = { url: base, token };
|
|
598
|
+
savePeersOut(map);
|
|
599
|
+
return { ok: true, alias, url: base, enrolled: !flags.token };
|
|
600
|
+
}
|
|
601
|
+
if (sub === "rm") {
|
|
602
|
+
if (!alias) throw new Error("usage: pilotctl peer rm <alias>");
|
|
603
|
+
delete map[alias];
|
|
604
|
+
savePeersOut(map);
|
|
605
|
+
return { ok: true, alias };
|
|
606
|
+
}
|
|
607
|
+
if (sub === "list" || sub === undefined)
|
|
608
|
+
return { peers: Object.entries(map).map(([a, p]) => ({ alias: a, url: p?.url })) };
|
|
609
|
+
throw new Error("usage: pilotctl peer <add|rm|list> …");
|
|
610
|
+
}
|
|
508
611
|
|
|
509
612
|
export async function run(argv) {
|
|
510
613
|
const { cmd, pos, flags } = parseArgs(argv);
|
|
614
|
+
// Manage the outbound-peers file (local, no server).
|
|
615
|
+
if (cmd === "peer") return cmdPeer(pos, flags);
|
|
616
|
+
// Target a REMOTE peer for this command — every call then goes to its URL with
|
|
617
|
+
// the peer token instead of the local session key. `--peer <alias>` resolves
|
|
618
|
+
// the outbound file; `--peer-url/--peer-token` is a one-off; SHADOK_PEER_URL/
|
|
619
|
+
// _TOKEN in the env is how a detached holder child inherits the peer.
|
|
620
|
+
if (flags.peer || flags["peer-url"] || process.env.SHADOK_PEER_URL) {
|
|
621
|
+
const target = flags["peer-url"]
|
|
622
|
+
? flags["peer-token"]
|
|
623
|
+
? { url: flags["peer-url"].replace(/\/+$/, ""), token: flags["peer-token"] }
|
|
624
|
+
: null
|
|
625
|
+
: flags.peer
|
|
626
|
+
? resolvePeer(loadPeersOut(), flags.peer)
|
|
627
|
+
: process.env.SHADOK_PEER_URL && process.env.SHADOK_PEER_TOKEN
|
|
628
|
+
? { url: process.env.SHADOK_PEER_URL.replace(/\/+$/, ""), token: process.env.SHADOK_PEER_TOKEN }
|
|
629
|
+
: null;
|
|
630
|
+
if (!target)
|
|
631
|
+
throw new Error(
|
|
632
|
+
flags["peer-url"]
|
|
633
|
+
? "--peer-url needs a --peer-token"
|
|
634
|
+
: `unknown peer "${flags.peer}" — add it with: pilotctl peer add <alias> <url> <token>`,
|
|
635
|
+
);
|
|
636
|
+
setPeer(target);
|
|
637
|
+
}
|
|
511
638
|
switch (cmd) {
|
|
512
639
|
case "spawn":
|
|
513
640
|
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":"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"}
|
package/dist/peers.d.ts
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
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`), and it
|
|
5
|
+
* enrols the same way: named, revocable, per launch dir, and reached through a
|
|
6
|
+
* **single-use ticket** that is CONSUMED on first use, exactly as a user's
|
|
7
|
+
* invitation link is. What the invitee keeps afterwards is a durable token it
|
|
8
|
+
* obtained itself — so the long-lived credential never travels through an
|
|
9
|
+
* invitation, a chat, or an invitee's transcript.
|
|
10
|
+
*
|
|
11
|
+
* Two properties are load-bearing, and the first one was missing at first.
|
|
12
|
+
*
|
|
13
|
+
* The token is salted PER PEER. It used to be `hmac(secret, "peer:"+name)`,
|
|
14
|
+
* which is deterministic: deleting a row revoked the token, but re-adding a peer
|
|
15
|
+
* under the SAME name minted the identical token again — handing a leaked
|
|
16
|
+
* credential straight back. Revocation was not rotation. The row now carries a
|
|
17
|
+
* random `salt` mixed into the MAC, so re-inviting the same name yields a
|
|
18
|
+
* different token, and the only way to rotate used to be renaming the peer or
|
|
19
|
+
* rotating the instance secret (which is shared with every user session).
|
|
20
|
+
*
|
|
21
|
+
* It stays **non-expiring** once enrolled — a cross-instance link is persistent
|
|
22
|
+
* and must not hit the 7-day cookie cliff — and **revocable by the registry**:
|
|
23
|
+
* verifying requires the name to still be listed here, so deleting the row
|
|
24
|
+
* kills every token for it. See docs/superpowers/specs/2026-09-26-cross-instance-
|
|
25
|
+
* agent-collaboration-design.md.
|
|
26
|
+
*
|
|
27
|
+
* A peer that connects is a DISTINCT principal, scoped by the caller to the
|
|
28
|
+
* agents it created (`Channel.createdByPeer`) — never B's whole fleet.
|
|
29
|
+
*/
|
|
30
|
+
/** A pending enrolment: the single-use ticket, and when it stops being usable. */
|
|
31
|
+
export interface PeerInvite {
|
|
32
|
+
ticket: string;
|
|
33
|
+
expiresAt: number;
|
|
34
|
+
}
|
|
35
|
+
export interface Peer {
|
|
36
|
+
name: string;
|
|
37
|
+
createdAt: number;
|
|
38
|
+
note?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Random, per peer, mixed into the token's MAC. Without it the token is a
|
|
41
|
+
* pure function of the name, so revoke-then-re-invite returns the SAME
|
|
42
|
+
* credential — see the note above. Absent on a row written before this
|
|
43
|
+
* existed; `withSalts` backfills one, which invalidates that row's old token
|
|
44
|
+
* (deliberately: a deterministic token is the thing being removed).
|
|
45
|
+
*/
|
|
46
|
+
salt?: string;
|
|
47
|
+
/** Present until the ticket is redeemed. While it is here the peer has NOT
|
|
48
|
+
* enrolled, and its durable token does not authenticate anything. */
|
|
49
|
+
invite?: PeerInvite;
|
|
50
|
+
/** When the ticket was redeemed and the durable token handed over. */
|
|
51
|
+
enrolledAt?: number;
|
|
52
|
+
}
|
|
53
|
+
/** How long a ticket stays redeemable. Long enough to reach an agent that is
|
|
54
|
+
* mid-task, short enough that a forgotten invitation is not a standing door. */
|
|
55
|
+
export declare const PEER_INVITE_TTL_MS: number;
|
|
56
|
+
/** INBOUND registry, per launch dir, 600 — peers allowed to reach THIS instance. */
|
|
57
|
+
export declare function peerFileFor(cwd?: string): string;
|
|
58
|
+
/** OUTBOUND registry, per launch dir, 600 — peers THIS instance can reach
|
|
59
|
+
* (`{ alias: { url, token } }`, managed by `pilotctl peer add`). The server
|
|
60
|
+
* hands its path to every agent as SHADOK_PEERS_FILE (twin of the ledger file),
|
|
61
|
+
* since an agent's cwd is a worktree, not the launch dir. Read by the client
|
|
62
|
+
* (pilotctl); the server only needs to compute the path. */
|
|
63
|
+
export declare function peersOutFileFor(cwd?: string): string;
|
|
64
|
+
export declare function loadPeers(file: string): Peer[];
|
|
65
|
+
export declare function savePeers(file: string, peers: Peer[]): void;
|
|
66
|
+
/** A peer name is a slug: lowercased, safe chars, non-empty. null if nothing
|
|
67
|
+
* usable survives — an empty/invalid name must never become a live credential. */
|
|
68
|
+
export declare function normPeerName(name: unknown): string | null;
|
|
69
|
+
/**
|
|
70
|
+
* Pure: add (or supersede) a peer by name, with a FRESH salt and a fresh
|
|
71
|
+
* single-use ticket.
|
|
72
|
+
*
|
|
73
|
+
* Superseding re-rolls the salt on purpose: re-inviting a name is exactly when
|
|
74
|
+
* the old credential must stop working. `salt`/`ticket` are injected so the
|
|
75
|
+
* result is testable; `newPeer` below supplies real randomness.
|
|
76
|
+
*/
|
|
77
|
+
export declare function addPeer(peers: Peer[], name: string, now: number, note: string | undefined, salt: string, ticket: string, ttlMs?: number): Peer[];
|
|
78
|
+
/** Impure twin of `addPeer`: draws the salt and the ticket. */
|
|
79
|
+
export declare function newPeer(peers: Peer[], name: string, now: number, note?: string): {
|
|
80
|
+
peers: Peer[];
|
|
81
|
+
ticket: string;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Backfill a salt on any row written before salts existed.
|
|
85
|
+
*
|
|
86
|
+
* Doing this INVALIDATES that row's existing token, and that is the point: the
|
|
87
|
+
* saltless token is the deterministic one being removed. A peer whose token
|
|
88
|
+
* stops working is re-invited; a peer whose leaked token kept working would not
|
|
89
|
+
* know to.
|
|
90
|
+
*/
|
|
91
|
+
export declare function withSalts(peers: Peer[], mint?: () => string): Peer[];
|
|
92
|
+
export type RedeemVerdict = {
|
|
93
|
+
ok: true;
|
|
94
|
+
name: string;
|
|
95
|
+
} | {
|
|
96
|
+
ok: false;
|
|
97
|
+
error: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Pure: may this ticket be redeemed right now?
|
|
101
|
+
*
|
|
102
|
+
* Refuses an unknown, an expired and an ALREADY-REDEEMED ticket with the same
|
|
103
|
+
* wording on purpose. Redemption deletes the ticket, so a used one and an
|
|
104
|
+
* invented one are indistinguishable from here — and saying which would tell a
|
|
105
|
+
* guesser that a ticket once existed. Same reasoning as the user invitation's
|
|
106
|
+
* "this link is no longer valid".
|
|
107
|
+
*/
|
|
108
|
+
export declare function redeemVerdict(peers: readonly Peer[], ticket: unknown, now: number): RedeemVerdict;
|
|
109
|
+
/** Pure: consume the ticket — the row stays (that is the peer), the invitation
|
|
110
|
+
* goes. This is what makes the ticket single-use. */
|
|
111
|
+
export declare function redeemPeer(peers: readonly Peer[], name: string, now: number): Peer[];
|
|
112
|
+
/** Pure: drop a peer by name (revocation). */
|
|
113
|
+
export declare function removePeer(peers: Peer[], name: string): Peer[];
|
|
114
|
+
/**
|
|
115
|
+
* The peer token: `<b64url(name)>.<hmac("peer:"+b64+":"+salt)>`, twin of
|
|
116
|
+
* `signSessionKey` but SALTED per peer — see the note at the top of this file.
|
|
117
|
+
*/
|
|
118
|
+
export declare function signPeerToken(name: string, secret: Buffer, salt: string): string;
|
|
119
|
+
/** Pure: the name a token CLAIMS, from its first half. Proves nothing on its
|
|
120
|
+
* own — the MAC is checked in `peerFromToken`, which needs the row's salt. */
|
|
121
|
+
export declare function peerTokenName(token: unknown): string | null;
|
|
122
|
+
/**
|
|
123
|
+
* The peer a token authenticates, or null.
|
|
124
|
+
*
|
|
125
|
+
* Three conditions, and each one is a different refusal:
|
|
126
|
+
* - the name is still in the registry — deleting the row is the revocation;
|
|
127
|
+
* - that row has ENROLLED (no pending invite left). A durable token for a peer
|
|
128
|
+
* that never redeemed its ticket authenticates nothing, which is what keeps
|
|
129
|
+
* the ticket the only way in;
|
|
130
|
+
* - the MAC verifies against THAT ROW's salt, so a token minted before a
|
|
131
|
+
* re-invitation is dead.
|
|
132
|
+
*/
|
|
133
|
+
export declare function peerFromToken(token: string, secret: Buffer, peers: readonly Peer[]): string | null;
|
|
134
|
+
/**
|
|
135
|
+
* The ownership rule — a peer may only touch an agent IT created. The single
|
|
136
|
+
* named check behind every peer scope (resume, stop, /diff): a channel with a
|
|
137
|
+
* different `createdByPeer`, or none (a local agent), is NOT this peer's.
|
|
138
|
+
*/
|
|
139
|
+
export declare function ownedByPeer(channel: {
|
|
140
|
+
createdByPeer?: string;
|
|
141
|
+
} | undefined, peer: string): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* The copy-paste invitation for an AGENT — the peer equivalent of a user's
|
|
144
|
+
* single-use link, and single-use in the same way. The invitee is an agent, not a
|
|
145
|
+
* human, so instead of a page where it picks a password it gets a PROMPT to paste
|
|
146
|
+
* into its own session: the cockpit URL, a TICKET, the brief, and exactly how to
|
|
147
|
+
* join and report back.
|
|
148
|
+
*
|
|
149
|
+
* It carries the ticket and never the durable token, which is the point: an
|
|
150
|
+
* invitation is copied, pasted and kept in a transcript, so what it holds must
|
|
151
|
+
* be worthless once used.
|
|
152
|
+
* `brief` is the human's task (empty allowed). Pure so the wording is tested.
|
|
153
|
+
*/
|
|
154
|
+
export declare function agentInvitePrompt(opts: {
|
|
155
|
+
url: string;
|
|
156
|
+
ticket: string;
|
|
157
|
+
brief?: string;
|
|
158
|
+
}): string;
|