cyberlegion 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +399 -193
- package/dist/index.d.mts +75 -262
- package/dist/index.mjs +4 -28
- package/dist/watch-nkm6F1_f.mjs +1560 -0
- package/package.json +7 -5
- package/readme.md +35 -30
- package/dist/watch-DA8I44dv.mjs +0 -1403
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { Exec, Exec as Exec$1, MuxAdapter, MuxPlacement, MuxProbe, probeMultiplexer } from "cyber-mux";
|
|
2
|
+
import { assertDistinctFromPrimary, gitWorktreeAdapter, resolvePrimaryRoot } from "cyber-mux/worktree";
|
|
3
|
+
|
|
1
4
|
//#region src/store/store.d.ts
|
|
2
5
|
interface Message {
|
|
3
6
|
id: string;
|
|
@@ -16,14 +19,18 @@ type AgentStatus = 'spawning' | 'active' | 'idle' | 'stale' | 'exited' | 'paused
|
|
|
16
19
|
interface AgentRecord {
|
|
17
20
|
id: string;
|
|
18
21
|
handle: string;
|
|
19
|
-
harness
|
|
22
|
+
/** Absent for a standing record (a human/owner principal — no claude/cursor/codex harness). */
|
|
23
|
+
harness?: Harness;
|
|
20
24
|
cwd: string;
|
|
21
25
|
worktree?: {
|
|
22
26
|
root: string;
|
|
23
27
|
branch?: string;
|
|
24
28
|
} | null;
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
/** Where this session lives, tagged with its multiplexer so `prune` runs the right liveness check.
|
|
30
|
+
* `null` for a session in no pane and for a standing record. `window`/`session` are tmux-only. */
|
|
31
|
+
pane?: {
|
|
32
|
+
mux: 'tmux' | 'herdr';
|
|
33
|
+
id: string;
|
|
27
34
|
window?: string;
|
|
28
35
|
session?: string;
|
|
29
36
|
} | null;
|
|
@@ -33,12 +40,21 @@ interface AgentRecord {
|
|
|
33
40
|
lastSeen: string;
|
|
34
41
|
brief?: string;
|
|
35
42
|
spawnedBy?: string;
|
|
43
|
+
/** Absent ⇒ session (backward compat, no migration). 'standing' = a session-independent,
|
|
44
|
+
* prune-exempt owner inbox minted by `unit register --standing`. */
|
|
45
|
+
kind?: 'session' | 'standing';
|
|
46
|
+
/** Only meaningful on a `kind: 'standing'` record — the id of the unit currently standing in for
|
|
47
|
+
* it (`unit claim`), a per-record singleton pointer that moves as the principal moves between
|
|
48
|
+
* units (last claim wins). Resolved live, never trusted: a presence unit that has exited reads as
|
|
49
|
+
* no presence bound, same as if none were ever claimed — nothing self-heals a stale pointer, it
|
|
50
|
+
* stays inert until re-claimed. Independent of the hub's `mainPane` (the human's read-pane). */
|
|
51
|
+
presence?: string;
|
|
36
52
|
}
|
|
37
53
|
interface InboxSnapshot {
|
|
38
54
|
unread: Message[];
|
|
39
55
|
read: Message[];
|
|
40
56
|
}
|
|
41
|
-
/** The seam all mailbox + registry + brief
|
|
57
|
+
/** The seam all mailbox + registry + brief access goes through. */
|
|
42
58
|
interface Store {
|
|
43
59
|
/** This store's root (for path-relative concerns the Store itself doesn't cover, e.g. spawning
|
|
44
60
|
* a worktree under a project-local root distinct from this hub). */
|
|
@@ -67,22 +83,19 @@ interface Store {
|
|
|
67
83
|
removePaneIndex(pane: string): void;
|
|
68
84
|
writeBrief(agentId: string, text: string): void;
|
|
69
85
|
readBrief(agentId: string): string | undefined;
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
readResult(id: string): string | undefined;
|
|
86
|
+
/** Set (or move) the hub's single main pane — the standing owner's live presence — or clear it
|
|
87
|
+
* (`null`, a no-op when already unbound). A hub-level singleton, independent of any agent record. */
|
|
88
|
+
setMainPane(pane: string | null): void;
|
|
89
|
+
/** The hub's currently bound main pane, or undefined when none is bound. */
|
|
90
|
+
getMainPane(): string | undefined;
|
|
76
91
|
}
|
|
77
92
|
//#endregion
|
|
78
93
|
//#region src/identity.d.ts
|
|
79
|
-
|
|
80
|
-
type Exec = (cmd: string, args: string[]) => string | null;
|
|
81
|
-
declare const realExec: Exec;
|
|
94
|
+
declare const realExec: Exec$1;
|
|
82
95
|
interface IdContext {
|
|
83
96
|
store: Store;
|
|
84
97
|
env?: NodeJS.ProcessEnv;
|
|
85
|
-
exec?: Exec;
|
|
98
|
+
exec?: Exec$1;
|
|
86
99
|
now?: () => number;
|
|
87
100
|
}
|
|
88
101
|
declare function loadAgent(store: Store, id: string): AgentRecord | undefined;
|
|
@@ -90,10 +103,11 @@ declare function listAgents(store: Store): AgentRecord[];
|
|
|
90
103
|
/** Detect the harness: explicit wins, then env probes, then the tmux pane command. */
|
|
91
104
|
declare function detectHarness(explicit: string | undefined, ctx: IdContext): Harness | undefined;
|
|
92
105
|
/**
|
|
93
|
-
* Recover the calling agent's own id.
|
|
94
|
-
* pane entry is simply unregistered and must NOT
|
|
95
|
-
*
|
|
96
|
-
*
|
|
106
|
+
* Recover the calling agent's own id, mux-agnostically. Inside any multiplexer pane (tmux or herdr)
|
|
107
|
+
* the pane index is authoritative — a pane with no pane entry is simply unregistered and must NOT
|
|
108
|
+
* adopt `$CYBERLEGION_AGENT_ID` (that env fallback applies ONLY when the session is in no
|
|
109
|
+
* multiplexer pane at all). There is no shared bare "self" file — self-id is always pane-keyed or
|
|
110
|
+
* explicit via the env var.
|
|
97
111
|
*/
|
|
98
112
|
declare function resolveSelfId(ctx: IdContext): string | undefined;
|
|
99
113
|
interface RegisterInput {
|
|
@@ -102,7 +116,8 @@ interface RegisterInput {
|
|
|
102
116
|
}
|
|
103
117
|
/** Register (or idempotently refresh) this session's identity. */
|
|
104
118
|
declare function register(ctx: IdContext, input: RegisterInput): AgentRecord;
|
|
105
|
-
/** Resolve a recipient argument (id or handle) to an agent id.
|
|
119
|
+
/** Resolve a recipient argument (id or handle) to an agent id. A handle resolves to live units
|
|
120
|
+
* only — mail addressed to an exited unit lands in an inbox nobody reads. */
|
|
106
121
|
declare function resolveRecipient(store: Store, to: string): string;
|
|
107
122
|
/**
|
|
108
123
|
* Resolve a unit reference by id, handle, or its worktree branch (the unit↔CR join key: an
|
|
@@ -113,7 +128,9 @@ declare function resolveAgent(store: Store, ref: string): AgentRecord;
|
|
|
113
128
|
declare function bumpLastSeen(ctx: IdContext, id: string): void;
|
|
114
129
|
/** Refresh this session's own last-seen if it is registered — best-effort, never throws. */
|
|
115
130
|
declare function touch(ctx: IdContext): void;
|
|
116
|
-
/** Mark agents whose pane is gone or whose last-seen is stale as exited.
|
|
131
|
+
/** Mark agents whose pane is gone or whose last-seen is stale as exited. Reconcile-culls against the
|
|
132
|
+
* current mux's live set first, then falls through to the per-record paneExists + staleness check
|
|
133
|
+
* (covers the other mux and sessions outside any multiplexer pane). */
|
|
117
134
|
declare function prune(ctx: IdContext): AgentRecord[];
|
|
118
135
|
//#endregion
|
|
119
136
|
//#region src/agentdef/resolve.d.ts
|
|
@@ -164,118 +181,6 @@ interface RealizedLaunch {
|
|
|
164
181
|
* `--model` when known, `--append-system-prompt` carrying the def's instructions body) since the
|
|
165
182
|
* exact per-harness flag surface is realized later by the launching caller, not by cyberlegion. */
|
|
166
183
|
declare function realizeLaunch(def: AgentDef, opts?: RealizeLaunchOptions): RealizedLaunch;
|
|
167
|
-
interface RealizeSubagentOptions {
|
|
168
|
-
/** File the spawned subagent reads its brief from. */
|
|
169
|
-
briefFile: string;
|
|
170
|
-
/** File the spawned subagent writes its result JSON to. */
|
|
171
|
-
resultFile: string;
|
|
172
|
-
}
|
|
173
|
-
/** Build the instruction string a parent model uses to spawn its OWN harness Task subagent for
|
|
174
|
-
* `def` — cyberlegion never invokes the Task tool itself. Names `subagent_type: <def.name>` for a
|
|
175
|
-
* harness that recognizes it, but always inlines the model + full instructions too so the same
|
|
176
|
-
* instruction string is correct even when the harness has no such named subagent type. */
|
|
177
|
-
declare function realizeSubagentInstruction(def: AgentDef, opts: RealizeSubagentOptions): string;
|
|
178
|
-
//#endregion
|
|
179
|
-
//#region src/console/session.d.ts
|
|
180
|
-
/** Generic multiplexer seam — no legion-specific concepts, so this composes with any host. */
|
|
181
|
-
/** Where a new pane/window/session should be placed relative to the caller's current one. */
|
|
182
|
-
type SessionPlacement = 'pane:right' | 'pane:down' | 'tab' | 'window';
|
|
183
|
-
interface SessionOpenOptions {
|
|
184
|
-
/** Working directory the new pane/window/session should start in. */
|
|
185
|
-
cwd: string;
|
|
186
|
-
/** Command line to launch inside the new pane once it is open. */
|
|
187
|
-
launch: string;
|
|
188
|
-
/** Placement relative to the caller; defaults to 'pane:right'. */
|
|
189
|
-
at?: SessionPlacement;
|
|
190
|
-
}
|
|
191
|
-
/** Opaque handle to an open pane/window/session; backend-specific id lives in `id`. */
|
|
192
|
-
interface SessionTarget {
|
|
193
|
-
id: string;
|
|
194
|
-
}
|
|
195
|
-
interface SessionReadOptions {
|
|
196
|
-
/** How many trailing lines of output to capture; omit for the backend's default. */
|
|
197
|
-
lines?: number;
|
|
198
|
-
}
|
|
199
|
-
interface SessionAdapter {
|
|
200
|
-
/** Backend name, e.g. "tmux" or "herdr". */
|
|
201
|
-
readonly name: string;
|
|
202
|
-
/** Create a new pane/window running `opts.launch` in `opts.cwd`; returns its target handle. */
|
|
203
|
-
open(exec: Exec, opts: SessionOpenOptions): SessionTarget;
|
|
204
|
-
/** Type text into the target session (submitted, not queued). */
|
|
205
|
-
send(exec: Exec, target: SessionTarget, text: string): void;
|
|
206
|
-
/** Capture the target session's current output. */
|
|
207
|
-
read(exec: Exec, target: SessionTarget, opts?: SessionReadOptions): string;
|
|
208
|
-
/** Move input focus to the target session; best-effort (may no-op if the backend can't). */
|
|
209
|
-
focus(exec: Exec, target: SessionTarget): void;
|
|
210
|
-
/** Close the target session. */
|
|
211
|
-
teardown(exec: Exec, target: SessionTarget): void;
|
|
212
|
-
}
|
|
213
|
-
//#endregion
|
|
214
|
-
//#region src/console/index.d.ts
|
|
215
|
-
/**
|
|
216
|
-
* Backend selection via the two-mode mux probe (`$CYBERLEGION_MUX` fast-path/override, else
|
|
217
|
-
* ancestry discovery from `$$` falling back to the `$TMUX`/`$HERDR_ENV` hint when the walk is
|
|
218
|
-
* inconclusive) — tmux/herdr map to their existing adapters; anything else is a clear error.
|
|
219
|
-
*/
|
|
220
|
-
declare function selectSessionAdapter(env: NodeJS.ProcessEnv, exec?: Exec): SessionAdapter;
|
|
221
|
-
//#endregion
|
|
222
|
-
//#region src/console/mux-probe.d.ts
|
|
223
|
-
type Mux = 'tmux' | 'herdr' | 'screen' | 'none';
|
|
224
|
-
interface MuxProbe {
|
|
225
|
-
mux: Mux;
|
|
226
|
-
pane?: string;
|
|
227
|
-
/** 'env' — trusted the $CYBERLEGION_MUX fast-path/override. 'ancestry' — walked the process tree. */
|
|
228
|
-
via: 'env' | 'ancestry';
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Two-mode multiplexer detection.
|
|
232
|
-
*
|
|
233
|
-
* Fast-path: `$CYBERLEGION_MUX` (tmux | herdr | screen | none) is trusted outright — this also
|
|
234
|
-
* serves as an OVERRIDE (`=none` forces no-mux even inside a real multiplexer). `$CYBERLEGION_MUX_PANE`
|
|
235
|
-
* carries the pane id alongside it.
|
|
236
|
-
*
|
|
237
|
-
* Discovery (else): walk the process ancestry from `$$` via `ps -o ppid=,comm= -p <pid>`, since the
|
|
238
|
-
* tool's own shell may not be the human's pane. `$TMUX`/`$HERDR_ENV` are NOT trusted alone — they
|
|
239
|
-
* are used only as a fast-positive hint the ancestry walk falls back to when the walk itself is
|
|
240
|
-
* inconclusive (e.g. `ps` unavailable), never as a substitute for it.
|
|
241
|
-
*/
|
|
242
|
-
declare function probeMultiplexer(exec: Exec, env: NodeJS.ProcessEnv, opts?: {
|
|
243
|
-
discover?: boolean;
|
|
244
|
-
}): MuxProbe;
|
|
245
|
-
//#endregion
|
|
246
|
-
//#region src/console/worktree.d.ts
|
|
247
|
-
/** Generic multiplexer/worktree seam — no legion-specific concepts. */
|
|
248
|
-
interface WorktreeAddOptions {
|
|
249
|
-
/** The primary checkout's root — the repo `git worktree add` runs against. */
|
|
250
|
-
primaryRoot: string;
|
|
251
|
-
/** Where the new worktree should be checked out. */
|
|
252
|
-
path: string;
|
|
253
|
-
/** Branch to create the worktree on. */
|
|
254
|
-
branch: string;
|
|
255
|
-
}
|
|
256
|
-
interface Worktree {
|
|
257
|
-
root: string;
|
|
258
|
-
branch: string;
|
|
259
|
-
}
|
|
260
|
-
interface WorktreeRemoveOptions {
|
|
261
|
-
primaryRoot: string;
|
|
262
|
-
}
|
|
263
|
-
interface WorktreeAdapter {
|
|
264
|
-
add(exec: Exec, opts: WorktreeAddOptions): Worktree;
|
|
265
|
-
remove(exec: Exec, path: string, opts: WorktreeRemoveOptions): void;
|
|
266
|
-
}
|
|
267
|
-
/** The only worktree backend at MVP — plain `git worktree`. */
|
|
268
|
-
declare const gitWorktreeAdapter: WorktreeAdapter;
|
|
269
|
-
/**
|
|
270
|
-
* Resolve the primary checkout's root regardless of whether the caller's cwd is the primary
|
|
271
|
-
* checkout or a linked worktree — `--git-common-dir` always points at the main repo's `.git`.
|
|
272
|
-
*/
|
|
273
|
-
declare function resolvePrimaryRoot(exec: Exec): string;
|
|
274
|
-
/**
|
|
275
|
-
* Refuse the primary checkout: a spawned unit's resolved worktree root must never be the primary
|
|
276
|
-
* checkout itself. A unit is never run in the primary checkout.
|
|
277
|
-
*/
|
|
278
|
-
declare function assertDistinctFromPrimary(worktreeRoot: string, primaryRoot: string): void;
|
|
279
184
|
//#endregion
|
|
280
185
|
//#region src/decommission.d.ts
|
|
281
186
|
interface DecommissionInput {
|
|
@@ -297,78 +202,6 @@ interface DecommissionResult {
|
|
|
297
202
|
*/
|
|
298
203
|
declare function decommission(ctx: IdContext, input: DecommissionInput): DecommissionResult;
|
|
299
204
|
//#endregion
|
|
300
|
-
//#region src/dispatch/prep.d.ts
|
|
301
|
-
interface DispatchContext {
|
|
302
|
-
store: Store;
|
|
303
|
-
}
|
|
304
|
-
interface PrepInput {
|
|
305
|
-
/** Resolve an agent def (`.agents/agents/<name>.md`) to build the instruction from. */
|
|
306
|
-
agent?: string;
|
|
307
|
-
/** Read an exact agent def file instead of resolving by name (plugin-scoped escape hatch). */
|
|
308
|
-
agentFile?: string;
|
|
309
|
-
/** Role label folded into the generic instruction when no agent def is given. */
|
|
310
|
-
role?: string;
|
|
311
|
-
/** Brief body text. */
|
|
312
|
-
briefText?: string;
|
|
313
|
-
/** Read the brief from a file, or `-` for stdin. */
|
|
314
|
-
briefFile?: string;
|
|
315
|
-
/** JSON schema file the eventual result must satisfy — carried through by callers that validate. */
|
|
316
|
-
verdictSchema?: string;
|
|
317
|
-
/** Thread id correlating a channel-path reply; defaults to the minted dispatch id. */
|
|
318
|
-
thread?: string;
|
|
319
|
-
}
|
|
320
|
-
interface DispatchEnvelope {
|
|
321
|
-
id: string;
|
|
322
|
-
thread: string;
|
|
323
|
-
briefFile: string;
|
|
324
|
-
resultFile: string;
|
|
325
|
-
instruction: string;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Allocate a dispatch: mint an id (thread defaults to it), write the brief into the Store, compute
|
|
329
|
-
* the result-slot path, and build the instruction from a resolved agent def (or a generic one).
|
|
330
|
-
* Spawns nothing — the envelope is handed to whatever spawns next (a Task tool, `channel()`, a
|
|
331
|
-
* human).
|
|
332
|
-
*/
|
|
333
|
-
declare function prep(ctx: DispatchContext, input: PrepInput, readStdin?: () => string): DispatchEnvelope;
|
|
334
|
-
//#endregion
|
|
335
|
-
//#region src/dispatch/channel.d.ts
|
|
336
|
-
interface ChannelInput extends PrepInput {
|
|
337
|
-
/** Block for the mail-thread reply and return a validated `DispatchResult`; without it, the peer
|
|
338
|
-
* is spawned and the envelope is returned so the caller can `mail await` later. */
|
|
339
|
-
wait?: boolean;
|
|
340
|
-
/** Placement relative to the caller; defaults to 'pane:right'. */
|
|
341
|
-
at?: SessionPlacement;
|
|
342
|
-
timeoutMs?: number;
|
|
343
|
-
maxWaitS?: number;
|
|
344
|
-
}
|
|
345
|
-
interface DispatchResult {
|
|
346
|
-
id: string;
|
|
347
|
-
verdict?: unknown;
|
|
348
|
-
body: string;
|
|
349
|
-
ts: number;
|
|
350
|
-
}
|
|
351
|
-
/** Thrown by a `--wait` channel call when its internal poll-cycle cap is hit with no reply yet — a
|
|
352
|
-
* clean, re-armable sentinel (mirrors `mail await`'s "waiting" outcome), never a failure. */
|
|
353
|
-
declare class DispatchWaitingError extends Error {
|
|
354
|
-
readonly thread: string;
|
|
355
|
-
constructor(thread: string);
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* `prep()` + spawn a peer session realized from the same agent def + (optionally) `awaitReply` on
|
|
359
|
-
* the thread. Requires `--agent`/`--agent-file` (a channel peer needs a real launch to realize).
|
|
360
|
-
*/
|
|
361
|
-
declare function channel(ctx: IdContext, input: ChannelInput, readStdin?: () => string): Promise<DispatchResult | DispatchEnvelope>;
|
|
362
|
-
//#endregion
|
|
363
|
-
//#region src/dispatch/collect.d.ts
|
|
364
|
-
interface CollectContext {
|
|
365
|
-
store: Store;
|
|
366
|
-
now?: () => number;
|
|
367
|
-
}
|
|
368
|
-
/** Read + validate a dispatch's result file. Throws (fail-loud) when the file is not yet written,
|
|
369
|
-
* or when it fails the optional verdict schema. */
|
|
370
|
-
declare function collect(ctx: CollectContext, id: string, verdictSchema?: string): DispatchResult;
|
|
371
|
-
//#endregion
|
|
372
205
|
//#region src/runtime/inject-inbox.d.ts
|
|
373
206
|
type HookEvent = 'SessionStart' | 'PostToolUse';
|
|
374
207
|
interface InjectPayload {
|
|
@@ -394,7 +227,7 @@ interface InstallResult {
|
|
|
394
227
|
status: InstallStatus;
|
|
395
228
|
}
|
|
396
229
|
/** Register the surfacing hook into one harness's config, idempotently. */
|
|
397
|
-
declare function install(harness: Harness, projectDir?: string): InstallResult[];
|
|
230
|
+
declare function install(harness: Harness, projectDir?: string, pin?: string): InstallResult[];
|
|
398
231
|
//#endregion
|
|
399
232
|
//#region src/message.d.ts
|
|
400
233
|
interface MsgContext {
|
|
@@ -432,6 +265,21 @@ declare function ack(ctx: MsgContext, meId: string, msgId: string): Message;
|
|
|
432
265
|
/** Permanently remove a message (unread or already-acked) from the caller's inbox. */
|
|
433
266
|
declare function deleteMessage(ctx: MsgContext, meId: string, msgId: string): void;
|
|
434
267
|
//#endregion
|
|
268
|
+
//#region src/mux-select.d.ts
|
|
269
|
+
/**
|
|
270
|
+
* Backend selection via cyber-mux's two-mode mux probe, normalized through the transitional
|
|
271
|
+
* `$CYBERLEGION_MUX*` → `$CYBER_MUX*` env seam (`mux-env.ts`) — tmux/herdr map to their existing
|
|
272
|
+
* cyber-mux adapters.
|
|
273
|
+
*
|
|
274
|
+
* cyber-mux detects MORE backends than `unit/registry`'s `AgentRecord.pane` can carry a locator
|
|
275
|
+
* under (`'tmux' | 'herdr'` only). A DETECTED wezterm/zellij is refused HERE, before anything opens,
|
|
276
|
+
* naming the backend it found (mux.feature: "a detected backend a unit record cannot carry is
|
|
277
|
+
* refused before opening anything") — driving it would open a real pane no record could name,
|
|
278
|
+
* stranding a live session `prune` can never reap and no caller can nudge. Anything else (`none`,
|
|
279
|
+
* `screen`) falls through to the plain "no backend" refusal, unchanged from before the migration.
|
|
280
|
+
*/
|
|
281
|
+
declare function selectSessionAdapter(env: NodeJS.ProcessEnv, exec?: Exec): MuxAdapter;
|
|
282
|
+
//#endregion
|
|
435
283
|
//#region src/output.d.ts
|
|
436
284
|
type Format = 'toon' | 'json';
|
|
437
285
|
/** One TOON-encoded object: `key: value` lines, blank/undefined fields dropped. */
|
|
@@ -459,13 +307,13 @@ declare function fail(msg: string): never;
|
|
|
459
307
|
/** Walk up from `cwd` to the nearest git repo root; fall back to `cwd`. */
|
|
460
308
|
declare function projectRoot(cwd?: string): string;
|
|
461
309
|
/** Runs a command synchronously in `cwd`; returns trimmed stdout, or null on any failure. */
|
|
462
|
-
type Exec$
|
|
310
|
+
type Exec$2 = (cmd: string, args: string[]) => string | null;
|
|
463
311
|
interface RootOptions {
|
|
464
312
|
root?: string;
|
|
465
313
|
space?: string;
|
|
466
314
|
cwd?: string;
|
|
467
315
|
env?: NodeJS.ProcessEnv;
|
|
468
|
-
exec?: Exec$
|
|
316
|
+
exec?: Exec$2;
|
|
469
317
|
}
|
|
470
318
|
/**
|
|
471
319
|
* Resolve the cyberlegion hub root. Precedence: explicit --root/--space, then `$CYBERLEGION_ROOT`,
|
|
@@ -475,9 +323,10 @@ interface RootOptions {
|
|
|
475
323
|
*/
|
|
476
324
|
declare function resolveRoot(opts?: RootOptions): string;
|
|
477
325
|
/**
|
|
478
|
-
* Resolve the primary checkout's project-local cyberlegion dir —
|
|
479
|
-
*
|
|
480
|
-
*
|
|
326
|
+
* Resolve the primary checkout's project-local cyberlegion dir — the tracked marker for a
|
|
327
|
+
* legion-enabled project (never the global hub, and never where spawned unit worktrees themselves
|
|
328
|
+
* are checked out — see `resolveUnitWorktreePath`), keyed off `git worktree`'s common-dir so it
|
|
329
|
+
* resolves the same from the primary checkout or from any of its linked worktrees.
|
|
481
330
|
*/
|
|
482
331
|
declare function resolveProjectLocalRoot(opts?: RootOptions): string;
|
|
483
332
|
/**
|
|
@@ -495,8 +344,7 @@ declare const paths: {
|
|
|
495
344
|
inboxReadDir: (root: string, id: string) => string;
|
|
496
345
|
dataDir: (root: string, id: string) => string;
|
|
497
346
|
briefFile: (root: string, id: string) => string;
|
|
498
|
-
|
|
499
|
-
worktreeDir: (root: string, id: string) => string;
|
|
347
|
+
mainPaneFile: (root: string) => string;
|
|
500
348
|
};
|
|
501
349
|
//#endregion
|
|
502
350
|
//#region src/session.d.ts
|
|
@@ -512,10 +360,15 @@ interface SpawnInput {
|
|
|
512
360
|
command?: string;
|
|
513
361
|
/** Branch to create the unit's worktree on; defaults to `cyberlegion/unit-<id>`. */
|
|
514
362
|
branch?: string;
|
|
515
|
-
/** Where to check out the unit's worktree; defaults
|
|
363
|
+
/** Where to check out the unit's worktree; defaults to a sibling of the primary checkout
|
|
364
|
+
* (`<parent>/<repo>.worktrees/legion-<id6>`, `id6` the same 6-char slice `handle` defaults to)
|
|
365
|
+
* — never nested inside the primary's own tree. */
|
|
516
366
|
worktreePath?: string;
|
|
517
|
-
/**
|
|
518
|
-
|
|
367
|
+
/** Spawn into this existing directory instead — creates no worktree. Mutually exclusive with
|
|
368
|
+
* `branch`/`worktreePath` (those create a worktree; this reuses one). */
|
|
369
|
+
cwd?: string;
|
|
370
|
+
/** Placement relative to the caller; defaults to 'tab'. */
|
|
371
|
+
at?: MuxPlacement;
|
|
519
372
|
}
|
|
520
373
|
interface SpawnResult {
|
|
521
374
|
agent: AgentRecord;
|
|
@@ -528,9 +381,10 @@ interface SpawnResult {
|
|
|
528
381
|
* its cwd set to that worktree, pre-register the peer, and drop its brief as a file the peer's own
|
|
529
382
|
* SessionStart hook reads — never typed into its prompt.
|
|
530
383
|
*
|
|
531
|
-
* Spawned unit worktrees live
|
|
532
|
-
* though the registry/mailbox itself lives in the global hub — the hub
|
|
533
|
-
* project and worktree boundaries, but a unit's checkout is necessarily
|
|
384
|
+
* Spawned unit worktrees live sibling to the primary checkout (`<parent>/<repo>.worktrees/legion-<id6>`),
|
|
385
|
+
* never nested inside it, even though the registry/mailbox itself lives in the global hub — the hub
|
|
386
|
+
* addresses units across project and worktree boundaries, but a unit's checkout is necessarily
|
|
387
|
+
* scoped to this one project's git remote.
|
|
534
388
|
*/
|
|
535
389
|
declare function spawn(ctx: IdContext, input: SpawnInput): SpawnResult;
|
|
536
390
|
//#endregion
|
|
@@ -556,9 +410,8 @@ declare class FileStore implements Store {
|
|
|
556
410
|
removePaneIndex(pane: string): void;
|
|
557
411
|
writeBrief(agentId: string, text: string): void;
|
|
558
412
|
readBrief(agentId: string): string | undefined;
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
readResult(id: string): string | undefined;
|
|
413
|
+
setMainPane(pane: string | null): void;
|
|
414
|
+
getMainPane(): string | undefined;
|
|
562
415
|
}
|
|
563
416
|
//#endregion
|
|
564
417
|
//#region src/wake/await.d.ts
|
|
@@ -595,46 +448,6 @@ type AwaitOutcome = {
|
|
|
595
448
|
*/
|
|
596
449
|
declare function awaitReply(ctx: MsgContext, input: AwaitInput): Promise<AwaitOutcome>;
|
|
597
450
|
//#endregion
|
|
598
|
-
//#region src/wake/wake-path.d.ts
|
|
599
|
-
/**
|
|
600
|
-
* The wake-matrix path a gateway would drive a turn through. Pure decision helper — no I/O, no
|
|
601
|
-
* polling, no session backend calls; the gateway (`legion-gateway-legate`, CR-5) composes this with
|
|
602
|
-
* the actual `mail await` / `session nudge` primitives.
|
|
603
|
-
*
|
|
604
|
-
* - **A** — a single unbounded `mail await` (not returned here; superseded by A-loop everywhere the
|
|
605
|
-
* gateway drives this decision, since a raw A risks a harness tool-timeout SIGKILL).
|
|
606
|
-
* - **A-loop** — the portable default: a bounded `mail await` cycle, re-armed by the caller.
|
|
607
|
-
* - **A-prime** — Claude Code with an observable background task: run `await` via
|
|
608
|
-
* `run_in_background` and poll its result instead of blocking the turn.
|
|
609
|
-
* - **B** — a live foreign session behind a verified multiplexer: ring the doorbell
|
|
610
|
-
* (`session nudge`) instead of polling. Never selected without a mux.
|
|
611
|
-
* - **C** — own-the-PTY (dropped from the shipped matrix; kept as a type for completeness).
|
|
612
|
-
* - **D** — `/loop`-style external re-invocation (dropped from the shipped matrix).
|
|
613
|
-
* - **E** — hook surfacing at a turn boundary (selected by the caller directly, not by this
|
|
614
|
-
* function — it has no wait/poll shape to decide between).
|
|
615
|
-
*/
|
|
616
|
-
type WakePath = 'A' | 'A-loop' | 'A-prime' | 'B' | 'C' | 'D' | 'E';
|
|
617
|
-
interface WakePathInput {
|
|
618
|
-
/** The calling harness, e.g. 'claude' | 'cursor' | 'codex'. */
|
|
619
|
-
harness: string;
|
|
620
|
-
mux: MuxProbe;
|
|
621
|
-
/** The harness can observe a backgrounded task's result without blocking the turn. */
|
|
622
|
-
observable?: boolean;
|
|
623
|
-
/** The target is a live, foreign interactive session that can be rung rather than polled. */
|
|
624
|
-
dedicatedListener?: boolean;
|
|
625
|
-
}
|
|
626
|
-
interface WakePathResult {
|
|
627
|
-
path: WakePath;
|
|
628
|
-
why: string;
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Select a wake path from the shipped matrix. Rule order: a `mux.mux === 'none'` caller can never
|
|
632
|
-
* get **B** — it always falls through to the bounded poll. Claude Code + an observable background
|
|
633
|
-
* task prefers **A-prime**. A live foreign session behind a verified mux prefers **B**. Otherwise
|
|
634
|
-
* the portable default is **A-loop**.
|
|
635
|
-
*/
|
|
636
|
-
declare function selectWakePath(input: WakePathInput): WakePathResult;
|
|
637
|
-
//#endregion
|
|
638
451
|
//#region src/wake/watch.d.ts
|
|
639
452
|
interface WatchInput {
|
|
640
453
|
meId: string;
|
|
@@ -653,4 +466,4 @@ interface WatchOptions {
|
|
|
653
466
|
*/
|
|
654
467
|
declare function watchMail(ctx: MsgContext, input: WatchInput, onMessage: (msg: InboxItem) => void, opts?: WatchOptions): Promise<void>;
|
|
655
468
|
//#endregion
|
|
656
|
-
export { type AgentDef, type AgentRecord, type AwaitInput, type AwaitOutcome, type
|
|
469
|
+
export { type AgentDef, type AgentRecord, type AwaitInput, type AwaitOutcome, type DecommissionInput, type DecommissionResult, type Exec, FileStore, type Format, type Harness, type HookEvent, type IdContext, type InboxItem, type InboxQuery, type InboxSnapshot, type Message, type MuxProbe, type RegisterInput, type RootOptions, type SendInput, type SpawnInput, type SpawnResult, type Store, ack, assertDistinctFromPrimary, awaitReply, bumpLastSeen, decommission, deleteMessage, detectHarness, emit, ensureMarker, fail, gitWorktreeAdapter, inbox, injectInbox, install, listAgentDefs, listAgents, loadAgent, nextStep, paths, peek, probeMultiplexer, projectRoot, prune, realExec, realizeLaunch, register, resolveAgent, resolveAgentDef, resolveBody, resolvePrimaryRoot, resolveProjectLocalRoot, resolveRecipient, resolveRoot, resolveSelfId, selectSessionAdapter, send, spawn, toonList, toonObject, touch, watchMail };
|
package/dist/index.mjs
CHANGED
|
@@ -1,28 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* get **B** — it always falls through to the bounded poll. Claude Code + an observable background
|
|
6
|
-
* task prefers **A-prime**. A live foreign session behind a verified mux prefers **B**. Otherwise
|
|
7
|
-
* the portable default is **A-loop**.
|
|
8
|
-
*/
|
|
9
|
-
function selectWakePath(input) {
|
|
10
|
-
if (input.mux.mux === "none") return {
|
|
11
|
-
path: "A-loop",
|
|
12
|
-
why: "no multiplexer detected — bounded poll only, B is never available"
|
|
13
|
-
};
|
|
14
|
-
if (input.harness === "claude" && input.observable) return {
|
|
15
|
-
path: "A-prime",
|
|
16
|
-
why: "Claude Code + an observable background task — await via run_in_background"
|
|
17
|
-
};
|
|
18
|
-
if (input.dedicatedListener) return {
|
|
19
|
-
path: "B",
|
|
20
|
-
why: `a live foreign session behind a verified ${input.mux.mux} mux — ring the doorbell`
|
|
21
|
-
};
|
|
22
|
-
return {
|
|
23
|
-
path: "A-loop",
|
|
24
|
-
why: "portable default — bounded mail await cycle"
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
//#endregion
|
|
28
|
-
export { DispatchWaitingError, FileStore, ack, assertDistinctFromPrimary, awaitReply, bumpLastSeen, channel, collect, decommission, deleteMessage, detectHarness, emit, ensureMarker, fail, gitWorktreeAdapter, inbox, injectInbox, install, listAgentDefs, listAgents, loadAgent, nextStep, paths, peek, prep, probeMultiplexer, projectRoot, prune, realExec, realizeLaunch, realizeSubagentInstruction, register, resolveAgent, resolveAgentDef, resolveBody, resolvePrimaryRoot, resolveProjectLocalRoot, resolveRecipient, resolveRoot, resolveSelfId, selectSessionAdapter, selectWakePath, send, spawn, toonList, toonObject, touch, watchMail };
|
|
1
|
+
import { A as loadAgent, B as resolveSelfId, C as spawn, F as register, G as projectRoot, H as touch, K as resolveProjectLocalRoot, L as resolveAgent, M as prune, N as realExec, O as detectHarness, T as bumpLastSeen, U as ensureMarker, W as paths, _ as install, a as emit, b as resolveAgentDef, c as toonList, d as deleteMessage, f as inbox, g as send, h as resolveBody, i as injectInbox, k as listAgents, l as toonObject, n as awaitReply, o as fail, p as peek, q as resolveRoot, r as FileStore, s as nextStep, t as watchMail, u as ack, v as decommission, w as selectSessionAdapter, x as realizeLaunch, y as listAgentDefs, z as resolveRecipient } from "./watch-nkm6F1_f.mjs";
|
|
2
|
+
import { probeMultiplexer } from "cyber-mux";
|
|
3
|
+
import { assertDistinctFromPrimary, gitWorktreeAdapter, resolvePrimaryRoot } from "cyber-mux/worktree";
|
|
4
|
+
export { FileStore, ack, assertDistinctFromPrimary, awaitReply, bumpLastSeen, decommission, deleteMessage, detectHarness, emit, ensureMarker, fail, gitWorktreeAdapter, inbox, injectInbox, install, listAgentDefs, listAgents, loadAgent, nextStep, paths, peek, probeMultiplexer, projectRoot, prune, realExec, realizeLaunch, register, resolveAgent, resolveAgentDef, resolveBody, resolvePrimaryRoot, resolveProjectLocalRoot, resolveRecipient, resolveRoot, resolveSelfId, selectSessionAdapter, send, spawn, toonList, toonObject, touch, watchMail };
|