cyberlegion 0.1.0 → 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/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;
@@ -23,8 +26,11 @@ interface AgentRecord {
23
26
  root: string;
24
27
  branch?: string;
25
28
  } | null;
26
- tmux?: {
27
- pane: string;
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;
28
34
  window?: string;
29
35
  session?: string;
30
36
  } | null;
@@ -35,14 +41,20 @@ interface AgentRecord {
35
41
  brief?: string;
36
42
  spawnedBy?: string;
37
43
  /** Absent ⇒ session (backward compat, no migration). 'standing' = a session-independent,
38
- * prune-exempt owner inbox minted by `identity owner`. */
44
+ * prune-exempt owner inbox minted by `unit register --standing`. */
39
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;
40
52
  }
41
53
  interface InboxSnapshot {
42
54
  unread: Message[];
43
55
  read: Message[];
44
56
  }
45
- /** The seam all mailbox + registry + brief/result access goes through. */
57
+ /** The seam all mailbox + registry + brief access goes through. */
46
58
  interface Store {
47
59
  /** This store's root (for path-relative concerns the Store itself doesn't cover, e.g. spawning
48
60
  * a worktree under a project-local root distinct from this hub). */
@@ -71,22 +83,19 @@ interface Store {
71
83
  removePaneIndex(pane: string): void;
72
84
  writeBrief(agentId: string, text: string): void;
73
85
  readBrief(agentId: string): string | undefined;
74
- /** Path this dispatch's result file would live at (computed only — no IO; existence not implied). */
75
- resultPath(id: string): string;
76
- /** Write a dispatch's result as JSON text. */
77
- writeResult(id: string, value: unknown): void;
78
- /** Read a dispatch's result JSON text, or undefined if not yet written. */
79
- 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;
80
91
  }
81
92
  //#endregion
82
93
  //#region src/identity.d.ts
83
- /** Runs a command synchronously; returns trimmed stdout, or null on any failure. */
84
- type Exec = (cmd: string, args: string[]) => string | null;
85
- declare const realExec: Exec;
94
+ declare const realExec: Exec$1;
86
95
  interface IdContext {
87
96
  store: Store;
88
97
  env?: NodeJS.ProcessEnv;
89
- exec?: Exec;
98
+ exec?: Exec$1;
90
99
  now?: () => number;
91
100
  }
92
101
  declare function loadAgent(store: Store, id: string): AgentRecord | undefined;
@@ -94,10 +103,11 @@ declare function listAgents(store: Store): AgentRecord[];
94
103
  /** Detect the harness: explicit wins, then env probes, then the tmux pane command. */
95
104
  declare function detectHarness(explicit: string | undefined, ctx: IdContext): Harness | undefined;
96
105
  /**
97
- * Recover the calling agent's own id. In tmux the pane index is authoritative — a pane with no
98
- * pane entry is simply unregistered and must NOT adopt `$CYBERLEGION_AGENT_ID` (that env fallback
99
- * applies only when there is no `$TMUX_PANE`). There is no shared bare "self" file — self-id is
100
- * always pane-keyed or explicit via the env var.
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.
101
111
  */
102
112
  declare function resolveSelfId(ctx: IdContext): string | undefined;
103
113
  interface RegisterInput {
@@ -106,7 +116,8 @@ interface RegisterInput {
106
116
  }
107
117
  /** Register (or idempotently refresh) this session's identity. */
108
118
  declare function register(ctx: IdContext, input: RegisterInput): AgentRecord;
109
- /** 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. */
110
121
  declare function resolveRecipient(store: Store, to: string): string;
111
122
  /**
112
123
  * Resolve a unit reference by id, handle, or its worktree branch (the unit↔CR join key: an
@@ -117,7 +128,9 @@ declare function resolveAgent(store: Store, ref: string): AgentRecord;
117
128
  declare function bumpLastSeen(ctx: IdContext, id: string): void;
118
129
  /** Refresh this session's own last-seen if it is registered — best-effort, never throws. */
119
130
  declare function touch(ctx: IdContext): void;
120
- /** 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). */
121
134
  declare function prune(ctx: IdContext): AgentRecord[];
122
135
  //#endregion
123
136
  //#region src/agentdef/resolve.d.ts
@@ -168,143 +181,6 @@ interface RealizedLaunch {
168
181
  * `--model` when known, `--append-system-prompt` carrying the def's instructions body) since the
169
182
  * exact per-harness flag surface is realized later by the launching caller, not by cyberlegion. */
170
183
  declare function realizeLaunch(def: AgentDef, opts?: RealizeLaunchOptions): RealizedLaunch;
171
- interface RealizeSubagentOptions {
172
- /** File the spawned subagent reads its brief from. */
173
- briefFile: string;
174
- /** File the spawned subagent writes its result JSON to. */
175
- resultFile: string;
176
- }
177
- /** Build the instruction string a parent model uses to spawn its OWN harness Task subagent for
178
- * `def` — cyberlegion never invokes the Task tool itself. Names `subagent_type: <def.name>` for a
179
- * harness that recognizes it, but always inlines the model + full instructions too so the same
180
- * instruction string is correct even when the harness has no such named subagent type. */
181
- declare function realizeSubagentInstruction(def: AgentDef, opts: RealizeSubagentOptions): string;
182
- //#endregion
183
- //#region src/console/worktree.d.ts
184
- /** Generic multiplexer/worktree seam — no legion-specific concepts. */
185
- interface WorktreeAddOptions {
186
- /** The primary checkout's root — the repo `git worktree add` runs against. */
187
- primaryRoot: string;
188
- /** Where the new worktree should be checked out. */
189
- path: string;
190
- /** Branch to create the worktree on. */
191
- branch: string;
192
- }
193
- interface Worktree {
194
- root: string;
195
- branch: string;
196
- }
197
- interface WorktreeRemoveOptions {
198
- primaryRoot: string;
199
- }
200
- interface WorktreeAdapter {
201
- add(exec: Exec, opts: WorktreeAddOptions): Worktree;
202
- remove(exec: Exec, path: string, opts: WorktreeRemoveOptions): void;
203
- }
204
- /** The only worktree backend at MVP — plain `git worktree`. */
205
- declare const gitWorktreeAdapter: WorktreeAdapter;
206
- /**
207
- * Resolve the primary checkout's root regardless of whether the caller's cwd is the primary
208
- * checkout or a linked worktree — `--git-common-dir` always points at the main repo's `.git`.
209
- */
210
- declare function resolvePrimaryRoot(exec: Exec): string;
211
- /**
212
- * Refuse the primary checkout: a spawned unit's resolved worktree root must never be the primary
213
- * checkout itself. A unit is never run in the primary checkout.
214
- */
215
- declare function assertDistinctFromPrimary(worktreeRoot: string, primaryRoot: string): void;
216
- //#endregion
217
- //#region src/console/session.d.ts
218
- /** Generic multiplexer seam — no legion-specific concepts, so this composes with any host. */
219
- /** Where a new pane/window/session should be placed relative to the caller's current one.
220
- * `'workspace'` opens a genuinely separate workspace/session (herdr: `workspace create`; tmux: a
221
- * new detached session) — the caller's current workspace/session is left untouched, unlike every
222
- * other placement, which adds a pane/window inside it. */
223
- type SessionPlacement = 'pane:right' | 'pane:down' | 'tab' | 'window' | 'workspace';
224
- interface SessionOpenOptions {
225
- /** Working directory the new pane/window/session should start in. */
226
- cwd: string;
227
- /** Command line to launch inside the new pane once it is open. */
228
- launch: string;
229
- /** Placement relative to the caller; defaults to 'pane:right'. */
230
- at?: SessionPlacement;
231
- }
232
- /** Opaque handle to an open pane/window/session; backend-specific id lives in `id`. */
233
- interface SessionTarget {
234
- id: string;
235
- }
236
- interface SessionReadOptions {
237
- /** How many trailing lines of output to capture; omit for the backend's default. */
238
- lines?: number;
239
- }
240
- interface OpenInNewWorktreeOptions {
241
- /** The primary checkout's root — the repo the new worktree branches from. */
242
- primaryRoot: string;
243
- /** Branch to create the worktree on. */
244
- branch: string;
245
- /** Where the new worktree should be checked out. */
246
- path: string;
247
- /** Command line to launch inside the new session once it is open. */
248
- launch: string;
249
- }
250
- interface SessionAdapter {
251
- /** Backend name, e.g. "tmux" or "herdr". */
252
- readonly name: string;
253
- /** Create a new pane/window running `opts.launch` in `opts.cwd`; returns its target handle. */
254
- open(exec: Exec, opts: SessionOpenOptions): SessionTarget;
255
- /**
256
- * Atomically create a new worktree AND open it in a genuinely new workspace/session, when the
257
- * backend has a native primitive for that combination (herdr's `worktree create` both creates
258
- * the worktree and nests it under its source workspace in one call — a real organizational
259
- * improvement over a separate worktree-add followed by a plain `open()`). Backends without such
260
- * a primitive (tmux has none) omit this; callers fall back to creating the worktree themselves
261
- * and then calling `open()` with `at: 'workspace'`.
262
- */
263
- openInNewWorktree?(exec: Exec, opts: OpenInNewWorktreeOptions): {
264
- target: SessionTarget;
265
- worktree: Worktree;
266
- };
267
- /** Type text into the target session (submitted, not queued). */
268
- send(exec: Exec, target: SessionTarget, text: string): void;
269
- /** Capture the target session's current output. */
270
- read(exec: Exec, target: SessionTarget, opts?: SessionReadOptions): string;
271
- /** Move input focus to the target session; best-effort (may no-op if the backend can't). */
272
- focus(exec: Exec, target: SessionTarget): void;
273
- /** Close the target session. */
274
- teardown(exec: Exec, target: SessionTarget): void;
275
- }
276
- //#endregion
277
- //#region src/console/index.d.ts
278
- /**
279
- * Backend selection via the two-mode mux probe (`$CYBERLEGION_MUX` fast-path/override, else
280
- * ancestry discovery from `$$` falling back to the `$TMUX`/`$HERDR_ENV` hint when the walk is
281
- * inconclusive) — tmux/herdr map to their existing adapters; anything else is a clear error.
282
- */
283
- declare function selectSessionAdapter(env: NodeJS.ProcessEnv, exec?: Exec): SessionAdapter;
284
- //#endregion
285
- //#region src/console/mux-probe.d.ts
286
- type Mux = 'tmux' | 'herdr' | 'screen' | 'none';
287
- interface MuxProbe {
288
- mux: Mux;
289
- pane?: string;
290
- /** 'env' — trusted the $CYBERLEGION_MUX fast-path/override. 'ancestry' — walked the process tree. */
291
- via: 'env' | 'ancestry';
292
- }
293
- /**
294
- * Two-mode multiplexer detection.
295
- *
296
- * Fast-path: `$CYBERLEGION_MUX` (tmux | herdr | screen | none) is trusted outright — this also
297
- * serves as an OVERRIDE (`=none` forces no-mux even inside a real multiplexer). `$CYBERLEGION_MUX_PANE`
298
- * carries the pane id alongside it.
299
- *
300
- * Discovery (else): walk the process ancestry from `$$` via `ps -o ppid=,comm= -p <pid>`, since the
301
- * tool's own shell may not be the human's pane. `$TMUX`/`$HERDR_ENV` are NOT trusted alone — they
302
- * are used only as a fast-positive hint the ancestry walk falls back to when the walk itself is
303
- * inconclusive (e.g. `ps` unavailable), never as a substitute for it.
304
- */
305
- declare function probeMultiplexer(exec: Exec, env: NodeJS.ProcessEnv, opts?: {
306
- discover?: boolean;
307
- }): MuxProbe;
308
184
  //#endregion
309
185
  //#region src/decommission.d.ts
310
186
  interface DecommissionInput {
@@ -326,78 +202,6 @@ interface DecommissionResult {
326
202
  */
327
203
  declare function decommission(ctx: IdContext, input: DecommissionInput): DecommissionResult;
328
204
  //#endregion
329
- //#region src/dispatch/prep.d.ts
330
- interface DispatchContext {
331
- store: Store;
332
- }
333
- interface PrepInput {
334
- /** Resolve an agent def (`.agents/agents/<name>.md`) to build the instruction from. */
335
- agent?: string;
336
- /** Read an exact agent def file instead of resolving by name (plugin-scoped escape hatch). */
337
- agentFile?: string;
338
- /** Role label folded into the generic instruction when no agent def is given. */
339
- role?: string;
340
- /** Brief body text. */
341
- briefText?: string;
342
- /** Read the brief from a file, or `-` for stdin. */
343
- briefFile?: string;
344
- /** JSON schema file the eventual result must satisfy — carried through by callers that validate. */
345
- verdictSchema?: string;
346
- /** Thread id correlating a channel-path reply; defaults to the minted dispatch id. */
347
- thread?: string;
348
- }
349
- interface DispatchEnvelope {
350
- id: string;
351
- thread: string;
352
- briefFile: string;
353
- resultFile: string;
354
- instruction: string;
355
- }
356
- /**
357
- * Allocate a dispatch: mint an id (thread defaults to it), write the brief into the Store, compute
358
- * the result-slot path, and build the instruction from a resolved agent def (or a generic one).
359
- * Spawns nothing — the envelope is handed to whatever spawns next (a Task tool, `channel()`, a
360
- * human).
361
- */
362
- declare function prep(ctx: DispatchContext, input: PrepInput, readStdin?: () => string): DispatchEnvelope;
363
- //#endregion
364
- //#region src/dispatch/channel.d.ts
365
- interface ChannelInput extends PrepInput {
366
- /** Block for the mail-thread reply and return a validated `DispatchResult`; without it, the peer
367
- * is spawned and the envelope is returned so the caller can `mail await` later. */
368
- wait?: boolean;
369
- /** Placement relative to the caller; defaults to 'pane:right'. */
370
- at?: SessionPlacement;
371
- timeoutMs?: number;
372
- maxWaitS?: number;
373
- }
374
- interface DispatchResult {
375
- id: string;
376
- verdict?: unknown;
377
- body: string;
378
- ts: number;
379
- }
380
- /** Thrown by a `--wait` channel call when its internal poll-cycle cap is hit with no reply yet — a
381
- * clean, re-armable sentinel (mirrors `mail await`'s "waiting" outcome), never a failure. */
382
- declare class DispatchWaitingError extends Error {
383
- readonly thread: string;
384
- constructor(thread: string);
385
- }
386
- /**
387
- * `prep()` + spawn a peer session realized from the same agent def + (optionally) `awaitReply` on
388
- * the thread. Requires `--agent`/`--agent-file` (a channel peer needs a real launch to realize).
389
- */
390
- declare function channel(ctx: IdContext, input: ChannelInput, readStdin?: () => string): Promise<DispatchResult | DispatchEnvelope>;
391
- //#endregion
392
- //#region src/dispatch/collect.d.ts
393
- interface CollectContext {
394
- store: Store;
395
- now?: () => number;
396
- }
397
- /** Read + validate a dispatch's result file. Throws (fail-loud) when the file is not yet written,
398
- * or when it fails the optional verdict schema. */
399
- declare function collect(ctx: CollectContext, id: string, verdictSchema?: string): DispatchResult;
400
- //#endregion
401
205
  //#region src/runtime/inject-inbox.d.ts
402
206
  type HookEvent = 'SessionStart' | 'PostToolUse';
403
207
  interface InjectPayload {
@@ -423,7 +227,7 @@ interface InstallResult {
423
227
  status: InstallStatus;
424
228
  }
425
229
  /** Register the surfacing hook into one harness's config, idempotently. */
426
- declare function install(harness: Harness, projectDir?: string): InstallResult[];
230
+ declare function install(harness: Harness, projectDir?: string, pin?: string): InstallResult[];
427
231
  //#endregion
428
232
  //#region src/message.d.ts
429
233
  interface MsgContext {
@@ -461,6 +265,21 @@ declare function ack(ctx: MsgContext, meId: string, msgId: string): Message;
461
265
  /** Permanently remove a message (unread or already-acked) from the caller's inbox. */
462
266
  declare function deleteMessage(ctx: MsgContext, meId: string, msgId: string): void;
463
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
464
283
  //#region src/output.d.ts
465
284
  type Format = 'toon' | 'json';
466
285
  /** One TOON-encoded object: `key: value` lines, blank/undefined fields dropped. */
@@ -488,13 +307,13 @@ declare function fail(msg: string): never;
488
307
  /** Walk up from `cwd` to the nearest git repo root; fall back to `cwd`. */
489
308
  declare function projectRoot(cwd?: string): string;
490
309
  /** Runs a command synchronously in `cwd`; returns trimmed stdout, or null on any failure. */
491
- type Exec$1 = (cmd: string, args: string[]) => string | null;
310
+ type Exec$2 = (cmd: string, args: string[]) => string | null;
492
311
  interface RootOptions {
493
312
  root?: string;
494
313
  space?: string;
495
314
  cwd?: string;
496
315
  env?: NodeJS.ProcessEnv;
497
- exec?: Exec$1;
316
+ exec?: Exec$2;
498
317
  }
499
318
  /**
500
319
  * Resolve the cyberlegion hub root. Precedence: explicit --root/--space, then `$CYBERLEGION_ROOT`,
@@ -525,7 +344,7 @@ declare const paths: {
525
344
  inboxReadDir: (root: string, id: string) => string;
526
345
  dataDir: (root: string, id: string) => string;
527
346
  briefFile: (root: string, id: string) => string;
528
- resultFile: (root: string, id: string) => string;
347
+ mainPaneFile: (root: string) => string;
529
348
  };
530
349
  //#endregion
531
350
  //#region src/session.d.ts
@@ -548,8 +367,8 @@ interface SpawnInput {
548
367
  /** Spawn into this existing directory instead — creates no worktree. Mutually exclusive with
549
368
  * `branch`/`worktreePath` (those create a worktree; this reuses one). */
550
369
  cwd?: string;
551
- /** Placement relative to the caller; defaults to 'pane:right'. */
552
- at?: SessionPlacement;
370
+ /** Placement relative to the caller; defaults to 'tab'. */
371
+ at?: MuxPlacement;
553
372
  }
554
373
  interface SpawnResult {
555
374
  agent: AgentRecord;
@@ -591,9 +410,8 @@ declare class FileStore implements Store {
591
410
  removePaneIndex(pane: string): void;
592
411
  writeBrief(agentId: string, text: string): void;
593
412
  readBrief(agentId: string): string | undefined;
594
- resultPath(id: string): string;
595
- writeResult(id: string, value: unknown): void;
596
- readResult(id: string): string | undefined;
413
+ setMainPane(pane: string | null): void;
414
+ getMainPane(): string | undefined;
597
415
  }
598
416
  //#endregion
599
417
  //#region src/wake/await.d.ts
@@ -630,46 +448,6 @@ type AwaitOutcome = {
630
448
  */
631
449
  declare function awaitReply(ctx: MsgContext, input: AwaitInput): Promise<AwaitOutcome>;
632
450
  //#endregion
633
- //#region src/wake/wake-path.d.ts
634
- /**
635
- * The wake-matrix path a gateway would drive a turn through. Pure decision helper — no I/O, no
636
- * polling, no session backend calls; the gateway (`legion-gateway-legate`, CR-5) composes this with
637
- * the actual `mail await` / `session nudge` primitives.
638
- *
639
- * - **A** — a single unbounded `mail await` (not returned here; superseded by A-loop everywhere the
640
- * gateway drives this decision, since a raw A risks a harness tool-timeout SIGKILL).
641
- * - **A-loop** — the portable default: a bounded `mail await` cycle, re-armed by the caller.
642
- * - **A-prime** — Claude Code with an observable background task: run `await` via
643
- * `run_in_background` and poll its result instead of blocking the turn.
644
- * - **B** — a live foreign session behind a verified multiplexer: ring the doorbell
645
- * (`session nudge`) instead of polling. Never selected without a mux.
646
- * - **C** — own-the-PTY (dropped from the shipped matrix; kept as a type for completeness).
647
- * - **D** — `/loop`-style external re-invocation (dropped from the shipped matrix).
648
- * - **E** — hook surfacing at a turn boundary (selected by the caller directly, not by this
649
- * function — it has no wait/poll shape to decide between).
650
- */
651
- type WakePath = 'A' | 'A-loop' | 'A-prime' | 'B' | 'C' | 'D' | 'E';
652
- interface WakePathInput {
653
- /** The calling harness, e.g. 'claude' | 'cursor' | 'codex'. */
654
- harness: string;
655
- mux: MuxProbe;
656
- /** The harness can observe a backgrounded task's result without blocking the turn. */
657
- observable?: boolean;
658
- /** The target is a live, foreign interactive session that can be rung rather than polled. */
659
- dedicatedListener?: boolean;
660
- }
661
- interface WakePathResult {
662
- path: WakePath;
663
- why: string;
664
- }
665
- /**
666
- * Select a wake path from the shipped matrix. Rule order: a `mux.mux === 'none'` caller can never
667
- * get **B** — it always falls through to the bounded poll. Claude Code + an observable background
668
- * task prefers **A-prime**. A live foreign session behind a verified mux prefers **B**. Otherwise
669
- * the portable default is **A-loop**.
670
- */
671
- declare function selectWakePath(input: WakePathInput): WakePathResult;
672
- //#endregion
673
451
  //#region src/wake/watch.d.ts
674
452
  interface WatchInput {
675
453
  meId: string;
@@ -688,4 +466,4 @@ interface WatchOptions {
688
466
  */
689
467
  declare function watchMail(ctx: MsgContext, input: WatchInput, onMessage: (msg: InboxItem) => void, opts?: WatchOptions): Promise<void>;
690
468
  //#endregion
691
- export { type AgentDef, type AgentRecord, type AwaitInput, type AwaitOutcome, type ChannelInput, type DecommissionInput, type DecommissionResult, type DispatchEnvelope, type DispatchResult, DispatchWaitingError, type Exec, FileStore, type Format, type Harness, type HookEvent, type IdContext, type InboxItem, type InboxQuery, type InboxSnapshot, type Message, type MuxProbe, type PrepInput, type RegisterInput, type RootOptions, type SendInput, type SpawnInput, type SpawnResult, type Store, type WakePathInput, type WakePathResult, 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 };
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 detectHarness, C as resolveAgentDef, D as selectSessionAdapter, E as spawn, F as register, G as resolveProjectLocalRoot, H as ensureMarker, J as gitWorktreeAdapter, K as resolveRoot, L as resolveAgent, M as loadAgent, N as prune, O as probeMultiplexer, P as realExec, R as resolveRecipient, S as listAgentDefs, T as realizeSubagentInstruction, U as paths, V as touch, W as projectRoot, Y as resolvePrimaryRoot, _ as inbox, a as fail, b as send, c as toonObject, d as DispatchWaitingError, f as channel, g as deleteMessage, h as ack, i as emit, j as listAgents, k as bumpLastSeen, l as install, m as awaitReply, n as FileStore, o as nextStep, p as prep, q as assertDistinctFromPrimary, r as injectInbox, s as toonList, t as watchMail, u as collect, v as peek, w as realizeLaunch, x as decommission, y as resolveBody, z as resolveSelfId } from "./watch-BuYsdwhx.mjs";
2
- //#region src/wake/wake-path.ts
3
- /**
4
- * Select a wake path from the shipped matrix. Rule order: a `mux.mux === 'none'` caller can never
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 };