@rynx-ai/runtime 0.1.11-beta.4 → 0.1.11-beta.41

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.
Files changed (65) hide show
  1. package/dist/claude/executor.d.ts +19 -5
  2. package/dist/claude/executor.js +56 -12
  3. package/dist/claude/models.d.ts +0 -5
  4. package/dist/claude/models.js +1 -7
  5. package/dist/claude/native-bridge.d.ts +103 -1
  6. package/dist/claude/native-bridge.js +445 -30
  7. package/dist/claude/native-hook-main.js +81 -1
  8. package/dist/claude/native-hooks.js +7 -0
  9. package/dist/claude/native-integration.d.ts +178 -26
  10. package/dist/claude/native-integration.js +1528 -170
  11. package/dist/claude/session-status.d.ts +39 -0
  12. package/dist/claude/session-status.js +163 -0
  13. package/dist/claude/transcript-clone.d.ts +18 -0
  14. package/dist/claude/transcript-clone.js +497 -0
  15. package/dist/claude/transcript.d.ts +27 -4
  16. package/dist/claude/transcript.js +158 -47
  17. package/dist/codex-app-server/client.d.ts +10 -6
  18. package/dist/codex-app-server/client.js +67 -15
  19. package/dist/codex-app-server/forwarder.d.ts +92 -3
  20. package/dist/codex-app-server/forwarder.js +532 -57
  21. package/dist/codex-app-server/mapping.d.ts +3 -6
  22. package/dist/codex-app-server/mapping.js +206 -36
  23. package/dist/codex-app-server/mcp-startup.d.ts +13 -0
  24. package/dist/codex-app-server/mcp-startup.js +63 -0
  25. package/dist/codex-app-server/process-registry.d.ts +36 -0
  26. package/dist/codex-app-server/process-registry.js +320 -0
  27. package/dist/codex-app-server/protocol.d.ts +64 -7
  28. package/dist/codex-app-server/ws-channel.d.ts +7 -0
  29. package/dist/codex-app-server/ws-channel.js +104 -28
  30. package/dist/codex-home.d.ts +35 -3
  31. package/dist/codex-home.js +323 -18
  32. package/dist/codex-session-store.d.ts +23 -0
  33. package/dist/codex-session-store.js +21 -0
  34. package/dist/host.d.ts +103 -46
  35. package/dist/host.js +1988 -634
  36. package/dist/index.d.ts +3 -3
  37. package/dist/index.js +1 -1
  38. package/dist/input-resources.d.ts +4 -0
  39. package/dist/input-resources.js +21 -5
  40. package/dist/models-catalog.d.ts +2 -1
  41. package/dist/models-catalog.js +94 -6
  42. package/dist/runner/child.d.ts +97 -28
  43. package/dist/runner/child.js +1486 -100
  44. package/dist/runner/manager.d.ts +110 -29
  45. package/dist/runner/manager.js +1481 -246
  46. package/dist/runner/protocol.d.ts +212 -24
  47. package/dist/runner/protocol.js +5 -0
  48. package/dist/runner/startup-policy.d.ts +7 -0
  49. package/dist/runner/startup-policy.js +10 -0
  50. package/dist/runner/transport.d.ts +18 -2
  51. package/dist/runner/transport.js +82 -3
  52. package/dist/runner-main.js +8 -3
  53. package/dist/terminal/claude-tui.d.ts +3 -1
  54. package/dist/terminal/claude-tui.js +3 -1
  55. package/dist/terminal/codex-tui.d.ts +4 -0
  56. package/dist/terminal/codex-tui.js +5 -0
  57. package/dist/terminal/control-parser.d.ts +39 -0
  58. package/dist/terminal/control-parser.js +172 -0
  59. package/dist/terminal/registry.d.ts +18 -15
  60. package/dist/terminal/registry.js +44 -23
  61. package/dist/terminal/spool.d.ts +47 -0
  62. package/dist/terminal/spool.js +231 -0
  63. package/dist/terminal/tmux.d.ts +126 -74
  64. package/dist/terminal/tmux.js +807 -211
  65. package/package.json +4 -4
@@ -8,6 +8,23 @@ export interface CodexSessionRecord {
8
8
  * metadata remains self-contained; this only tells a runner where the
9
9
  * Provider persisted its rollout/state. */
10
10
  runtimeHomeOwnerSessionId?: string;
11
+ /** Claude hook/forwarder rendezvous ownership. A rotated target keeps the
12
+ * physical pane's bridge while the retired logical source is re-keyed to an
13
+ * isolated bridge; both may still share one Provider runtime home. */
14
+ bridgeOwnerSessionId?: string;
15
+ /** Durable recovery edge for a Claude-native `/clear`·`/fork`. The target
16
+ * binding is written before IPC publication; `published` is flipped only
17
+ * after the parent durably creates the logical target. */
18
+ nativeRotationSourceSessionId?: string;
19
+ /** Authoritative latest published target when this record is the source.
20
+ * Avoids choosing an arbitrary historical edge after repeated rotations. */
21
+ nativeRotationTargetSessionId?: string;
22
+ nativeRotationKind?: "clear" | "fork";
23
+ nativeRotationPublished?: boolean;
24
+ /** Stable transcript boundary captured by the rotating forwarder at the
25
+ * target SessionStart. Clear starts at zero; fork starts after the copied
26
+ * source prefix. Recovery must not replace this with a later file EOF. */
27
+ nativeRotationInitialTranscriptOffset?: number;
11
28
  updatedAt: string;
12
29
  }
13
30
  export interface ClaudeForkIntent {
@@ -15,6 +32,12 @@ export interface ClaudeForkIntent {
15
32
  sourceSessionId: string;
16
33
  sourceClaudeSessionId: string;
17
34
  targetClaudeSessionId: string;
35
+ /** Target transcript atomically cloned before the target runner starts. Its
36
+ * presence means recovery must resume this exact file, never re-clone a
37
+ * source that may have advanced since the fork boundary. */
38
+ forkTranscriptPath?: string;
39
+ /** Exact byte length of the cloned prefix, measured before Claude starts. */
40
+ forkTranscriptPrefixBytes?: number;
18
41
  updatedAt: string;
19
42
  }
20
43
  export interface CodexSessionStore {
@@ -107,6 +107,27 @@ export class FileCodexSessionStore {
107
107
  ...(record.runtimeHomeOwnerSessionId
108
108
  ? { runtimeHomeOwnerSessionId: record.runtimeHomeOwnerSessionId }
109
109
  : {}),
110
+ ...(record.bridgeOwnerSessionId
111
+ ? { bridgeOwnerSessionId: record.bridgeOwnerSessionId }
112
+ : {}),
113
+ ...(record.nativeRotationSourceSessionId
114
+ ? { nativeRotationSourceSessionId: record.nativeRotationSourceSessionId }
115
+ : {}),
116
+ ...(record.nativeRotationTargetSessionId
117
+ ? { nativeRotationTargetSessionId: record.nativeRotationTargetSessionId }
118
+ : {}),
119
+ ...(record.nativeRotationKind
120
+ ? { nativeRotationKind: record.nativeRotationKind }
121
+ : {}),
122
+ ...(record.nativeRotationPublished
123
+ ? { nativeRotationPublished: true }
124
+ : {}),
125
+ ...(Number.isSafeInteger(record.nativeRotationInitialTranscriptOffset) &&
126
+ record.nativeRotationInitialTranscriptOffset >= 0
127
+ ? {
128
+ nativeRotationInitialTranscriptOffset: record.nativeRotationInitialTranscriptOffset,
129
+ }
130
+ : {}),
110
131
  updatedAt: record.updatedAt,
111
132
  };
112
133
  }
package/dist/host.d.ts CHANGED
@@ -1,14 +1,35 @@
1
- import { type ResolvedExecutionSnapshot, type ResolvedExecutionBudget, type RuntimeUserInput, type SessionWorkspaceSnapshot, type SessionInteractionResolution, type SessionEvent } from "@rynx-ai/core";
1
+ import { type ResolvedExecutionSnapshot, type RuntimeTurnOptions, type RuntimeUserInput, type SessionCollaborationMode, type LiveSessionFailure, type SessionWorkspaceSnapshot, type SessionInteractionResolution, type SessionEvent } from "@rynx-ai/core";
2
2
  import { type AgentRuntimeId } from "@rynx-ai/core";
3
3
  import { type AppConfig } from "@rynx-ai/core";
4
4
  import { createCodexChildEnv } from "./codex-child-env.js";
5
- import type { InjectOutcome } from "./runner/protocol.js";
5
+ import type { InjectResult } from "./runner/protocol.js";
6
6
  import type { ResolveInteractionResult } from "./interactions.js";
7
7
  import { CodexAppServerClient } from "./codex-app-server/client.js";
8
8
  import type { ModelListResponse, ThreadGoal } from "./codex-app-server/protocol.js";
9
9
  import { type TerminalInjector } from "./claude/native-integration.js";
10
10
  import { FileCodexSessionStore, resolveCodexSessionStorePath, type ClaudeForkIntent, type CodexSessionRecord, type CodexSessionStore } from "./codex-session-store.js";
11
11
  import { AgentRuntimeError as CodexRuntimeError } from "@rynx-ai/core";
12
+ /** Delivery policy carried only inside the runner process. It is not part of
13
+ * the public SessionEvent protocol: the same canonical event has different
14
+ * retry semantics depending on whether it came from a transcript item, a
15
+ * terminal hook, or a best-effort live snapshot. */
16
+ export type MirrorDeliveryPolicy = "ordinary" | "terminal-status" | "best-effort" | "compaction" | "compaction-hook";
17
+ export type MirrorDeliveryOutcome = "confirmed" | "ambiguous" | "dropped" | "superseded";
18
+ export interface MirrorDeliveryOptions {
19
+ policy: MirrorDeliveryPolicy;
20
+ /** Stable local source key used by the Claude forwarder to checkpoint one
21
+ * item only after this delivery is handled. It is not sent to SQLite. */
22
+ sourceId?: string;
23
+ /** Independent retry lane. Claude native sub-agents use one lane each so a
24
+ * blocked child cannot stop its siblings or the parent transcript. */
25
+ lane?: string;
26
+ /** Claude-local write-only dead letter for an exhausted permanent ordinary
27
+ * item. No startup path replays this file automatically. */
28
+ deadLetterPath?: string;
29
+ /** Internal completion detail for state machines (not part of the wire). */
30
+ onOutcome?: (outcome: MirrorDeliveryOutcome) => void;
31
+ }
32
+ export type MirrorEmitter = (event: SessionEvent, delivery?: MirrorDeliveryOptions) => void | Promise<void>;
12
33
  export { FileCodexSessionStore, resolveCodexSessionStorePath, type CodexSessionRecord, type CodexSessionStore, type ClaudeForkIntent, };
13
34
  export interface CodexRuntimeStatus {
14
35
  codex_available: boolean;
@@ -99,7 +120,10 @@ export type RetargetMirror = (newSessionId: string, meta: {
99
120
  workspace: SessionWorkspaceSnapshot;
100
121
  execution: ResolvedExecutionSnapshot;
101
122
  parentSessionId?: string;
102
- }) => void;
123
+ /** Runs after parent target persistence + child resource transfer, but
124
+ * before the child proves `rotate.applied` to the parent. */
125
+ beforeApplied?: () => void | Promise<void>;
126
+ }) => void | Promise<void>;
103
127
  export interface LiveSessionOpts {
104
128
  /** Immutable Session-owned snapshots. Provider launch/resume never re-opens a
105
129
  * Project or Agent template. */
@@ -107,14 +131,6 @@ export interface LiveSessionOpts {
107
131
  execution: ResolvedExecutionSnapshot;
108
132
  retargetMirror?: RetargetMirror;
109
133
  }
110
- /**
111
- * The `OPENAI_*` retry env for a codex-lineage app-server spawn, or `undefined`
112
- * when the budget declares no retry or the runtime is claude. claude applies
113
- * its retry budget per-run in `buildOptions` (see the claude executor), so it
114
- * never needs a dedicated app-server.
115
- */
116
- export declare function codexRetryEnv(runtime: AgentRuntimeId, budget?: ResolvedExecutionBudget): Record<string, string> | undefined;
117
- export declare function codexBackendKey(runtime: AgentRuntimeId, budget?: ResolvedExecutionBudget): string;
118
134
  export declare class LocalAgentHost implements CodexCapabilities {
119
135
  private readonly config;
120
136
  private readonly sessionStore;
@@ -122,9 +138,10 @@ export declare class LocalAgentHost implements CodexCapabilities {
122
138
  private readonly defaultRuntime;
123
139
  private readonly injectedCommandRunner?;
124
140
  private readonly injectedAppServerClient?;
125
- private readonly clock;
126
- private readonly backendIdleTtlMs;
127
141
  private readonly forwarderClientFactory;
142
+ private readonly preloadClientFactory;
143
+ /** Builds one short-lived message/interrupt client. */
144
+ private readonly injectionClientFactory;
128
145
  private readonly backends;
129
146
  private readonly sessionId;
130
147
  private readonly runtimeHomeSessionId;
@@ -133,26 +150,31 @@ export declare class LocalAgentHost implements CodexCapabilities {
133
150
  private readonly runtimeHomes;
134
151
  private readonly liveSessions;
135
152
  private readonly liveClaudeSessions;
153
+ /** Exact pre-live startup failure, retained after the partial handle has been
154
+ * cleaned up so Core/plugin callers receive the failed phase, not a generic
155
+ * `live session unavailable` wrapper. */
156
+ private readonly liveStartupErrors;
136
157
  /** Claude forwarders stopped before their terminal is killed. Runner shutdown
137
158
  * finalizes these synchronously afterwards to scrub raw interaction answers. */
138
159
  private readonly pendingClaudeFinalizers;
160
+ private readonly pendingCleanupTasks;
139
161
  private readonly liveEnsuring;
140
162
  private readonly forkingTargets;
141
163
  /** Short-lived dedupe for managed fork notifications delivered after the
142
164
  * `thread/fork` response. Values are expected source Provider thread ids. */
143
165
  private readonly managedForkThreadStarts;
144
- constructor({ config, commandRunner, sessionStore, allowedRoots, appServerClient, now, backendIdleTtlMs, forwarderClientFactory, sessionId, runtimeHomeSessionId, }: {
166
+ constructor({ config, commandRunner, sessionStore, allowedRoots, appServerClient, forwarderClientFactory, preloadClientFactory, injectionClientFactory, sessionId, runtimeHomeSessionId, }: {
145
167
  config: AppConfig;
146
168
  commandRunner?: CodexCommandRunner;
147
169
  sessionStore?: CodexSessionStore;
148
170
  allowedRoots?: string[];
149
171
  appServerClient?: CodexAppServerClient | null;
150
- /** Monotonic-ish clock for idle reaping (tests inject a controllable one). */
151
- now?: () => number;
152
- /** Idle TTL after which a per-budget composite backend is reaped (ms). */
153
- backendIdleTtlMs?: number;
154
172
  /** Override the live-session forwarder connection factory (tests inject a fake). */
155
173
  forwarderClientFactory?: (appServerUrl: string) => CodexAppServerClient;
174
+ /** Override the short-lived known-thread preload connection factory. */
175
+ preloadClientFactory?: (appServerUrl: string) => CodexAppServerClient;
176
+ /** Override the short-lived message/interrupt connection factory. */
177
+ injectionClientFactory?: (appServerUrl: string) => CodexAppServerClient;
156
178
  /** The rynx session (localThreadId) this host serves — a per-session runner
157
179
  * child sets it from `RYNX_RUNNER_SESSION` so the private CODEX_HOME is
158
180
  * session-scoped. The shared `__cap__` child / tests fall back to a sentinel
@@ -164,20 +186,22 @@ export declare class LocalAgentHost implements CodexCapabilities {
164
186
  runtimeHomeSessionId?: string;
165
187
  });
166
188
  private getBackend;
167
- /**
168
- * Stop + drop per-budget composite backends that have been idle longer than
169
- * the TTL and have no in-flight run. Base per-runtime backends (key === the
170
- * bare runtime id) are never reaped — they live for the process lifetime, as
171
- * before. There are no per-conversation close hooks, so this lazy sweep (run
172
- * on every `getBackend`) is how dedicated app-servers get reclaimed.
173
- */
174
- private reapIdleBackends;
175
189
  private createBackend;
176
190
  /** This session's private native home, shared by its app-server + TUI. */
177
191
  private runtimeHome;
178
192
  private createAppServerClient;
179
193
  /** Resolve a pending native question/approval without opening a new Turn. */
180
194
  resolveInteraction(localThreadId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<ResolveInteractionResult>;
195
+ /** Apply collaboration mode to an already-loaded Codex-lineage thread. The
196
+ * caller persists only after this native RPC succeeds. */
197
+ updateCollaborationMode(localThreadId: string, mode: SessionCollaborationMode): Promise<void>;
198
+ /** Apply one explicit collaboration mode to the current native thread and
199
+ * remember only a successful RPC. A supplied client is already initialized
200
+ * and remains owned by its caller (used by cold-resume preload). */
201
+ private applyLiveCollaborationMode;
202
+ /** Apply pending explicit model/effort settings and, when requested, one
203
+ * collaboration mode in a single native update. */
204
+ private applyLiveThreadSettings;
181
205
  /**
182
206
  * The command to run in a session's live terminal so it co-drives the codex
183
207
  * app-server thread (Phase D). Returns `null` when live-terminal is off, the
@@ -187,11 +211,16 @@ export declare class LocalAgentHost implements CodexCapabilities {
187
211
  * SAME thread the structured data channel drives.
188
212
  */
189
213
  codexTerminalSpec(localThreadId: string): Promise<{
214
+ lifecycle: "required" | "auxiliary";
190
215
  command: string;
191
216
  args: string[];
192
217
  cwd: string;
193
218
  env?: Record<string, string>;
194
219
  skipTraexStartupPrompts?: boolean;
220
+ scrollback?: number;
221
+ tmuxAllowPassthrough?: boolean;
222
+ tmuxStartOnAttach?: boolean;
223
+ keepAliveAfterExit?: boolean;
195
224
  } | null>;
196
225
  /**
197
226
  * Bring up (idempotently) a session's persistent codex forwarder and emit its
@@ -207,31 +236,48 @@ export declare class LocalAgentHost implements CodexCapabilities {
207
236
  * existing session, the app-server resumes the persisted id. Rynx never writes
208
237
  * or repairs Codex's private rollout files.
209
238
  */
210
- ensureLiveCodexSession(localThreadId: string, emit: (event: SessionEvent) => void, opts: LiveSessionOpts): Promise<boolean>;
239
+ ensureLiveCodexSession(localThreadId: string, emit: MirrorEmitter, opts: LiveSessionOpts): Promise<boolean>;
211
240
  private startLiveCodexSession;
212
241
  /** Bind a session's codex thread id once known (TUI broadcast or store): persist
213
242
  * it, unblock injection, and kick off the resume-subscribe loop (once). */
214
243
  private onLiveThreadStarted;
244
+ /** Start the known-thread observer after the replacement TUI has launched.
245
+ * Fresh sessions already connected their discovery listener before launch;
246
+ * this is therefore an idempotent no-op for them and for a healthy observer. */
247
+ startLiveCodexObserver(localThreadId: string): void;
248
+ /** reference implementation treats the forwarder as a required component of one native
249
+ * lifecycle: if its transport dies, it closes the app-server instead of
250
+ * accepting turns that can no longer reach the canonical mirror. */
251
+ private failObserverLifecycle;
215
252
  private shouldIgnoreManagedForkThreadStarted;
216
253
  private rememberManagedForkThreadStart;
217
254
  /**
218
255
  * Subscribe the forwarder connection to a thread (reference implementation's
219
256
  * `_subscribe_until_ready`). A fresh TUI thread has no rollout until its first
220
257
  * turn, so `thread/resume` is retried: park until the forwarder observes the
221
- * thread active, then retry WITHOUT `excludeTurns` so the response backfills the
222
- * first turn's items (replayed, deduped against the live stream). Once resume
223
- * succeeds, subsequent turns arrive as live notifications on this connection.
258
+ * thread active, then retry. Like reference implementation, the first attempt always uses
259
+ * `excludeTurns`: a known-session cold resume therefore never reconstructs
260
+ * historical running/completed state. Only a fresh thread whose first attempt
261
+ * failed as not-ready retries without `excludeTurns`, backfilling the newly
262
+ * materialized first turn and de-duplicating it against live notifications.
224
263
  */
225
264
  private subscribeUntilReady;
226
- /** Await a live session's thread binding (bounded). Returns false on timeout /
265
+ /** Await a live session's thread binding. `null` leaves the deadline to the
266
+ * caller; a number keeps the Provider-local bound. Returns false on timeout /
227
267
  * no live session. Injection and the runner's `live.ready` gate on this. */
228
- waitLiveReady(localThreadId: string, timeoutMs?: number): Promise<boolean>;
229
- /** Await the stronger Terminal gate: another app-server connection has
230
- * successfully resumed the thread, so the detached TUI cannot race rollout
231
- * discovery or indexing. */
232
- waitTerminalReady(localThreadId: string, timeoutMs?: number): Promise<boolean>;
268
+ waitLiveReady(localThreadId: string, timeoutMs?: number | null): Promise<boolean>;
269
+ /** Await the observer subscription diagnostic. Codex/Traex Terminal startup
270
+ * deliberately does not gate on this promise: the dedicated preload owns resume,
271
+ * while the independent observer attaches in the background. */
272
+ waitTerminalReady(localThreadId: string, timeoutMs?: number | null): Promise<boolean>;
233
273
  /** Diagnostic from the provider adapter when native discovery/resume failed. */
234
274
  liveSessionError(localThreadId: string): string | undefined;
275
+ /** Structured phase + concrete cause used by the runner wire protocol. */
276
+ liveSessionFailure(localThreadId: string): LiveSessionFailure | undefined;
277
+ /** Publish the background TUI/thread discovery failure so an executor
278
+ * already waiting in the 60s bridge window exits immediately with the exact
279
+ * 30s discovery cause. */
280
+ failLiveStartup(localThreadId: string, error: Error): boolean;
235
281
  /**
236
282
  * Inject a user turn into a session's live codex thread — reference implementation's
237
283
  * single-writer web send. `turn/steer` when a turn is open (mid-turn
@@ -239,13 +285,13 @@ export declare class LocalAgentHost implements CodexCapabilities {
239
285
  * resumed from the persisted native id. Serialized per session so two
240
286
  * injects can't double-open a turn.
241
287
  *
242
- * Returns an {@link InjectOutcome}: `notLive` when this session has no live
288
+ * Returns an {@link InjectResult}: `notLive` when this session has no live
243
289
  * forwarder (caller may use the run path); `notReady`/`failed` are hard errors
244
290
  * the caller reports WITHOUT re-running (re-running double-writes alongside the
245
291
  * forwarder). Park-until-ready (~60s), aligning reference implementation's executor waiting for
246
292
  * the bridge instead of a short race that falls back to a second output path.
247
293
  */
248
- injectMessage(localThreadId: string, input: RuntimeUserInput | string): Promise<InjectOutcome>;
294
+ injectMessage(localThreadId: string, input: RuntimeUserInput | string, options?: RuntimeTurnOptions): Promise<InjectResult>;
249
295
  /**
250
296
  * Interrupt the session's active turn — the web Stop button. codex: the
251
297
  * app-server `turn/interrupt` on the active `{threadId, turnId}` (exactly what
@@ -259,9 +305,16 @@ export declare class LocalAgentHost implements CodexCapabilities {
259
305
  stopLiveCodexSession(localThreadId: string, opts?: {
260
306
  deferClaudeInteractionCleanup?: boolean;
261
307
  }): void;
308
+ /** Tear down one codex-lineage native runtime without deleting its durable
309
+ * session-store binding. reference implementation couples its auxiliary Terminal, observer,
310
+ * forwarder and per-session app-server as one disposable runtime envelope;
311
+ * the next message recreates that envelope and cold-resumes the native id. */
312
+ teardownLiveCodexSession(localThreadId: string, error?: Error): boolean;
313
+ teardownAuxiliaryTerminalRuntime(localThreadId: string): Promise<void>;
262
314
  /** Complete the second shutdown phase after the runner has killed all native
263
315
  * terminals and hook subprocesses. Must run before the runner process exits. */
264
- finalizeStoppedLiveSessions(): void;
316
+ finalizeStoppedLiveSessions(): Promise<void>;
317
+ private trackCleanup;
265
318
  /** The interactive `claude` TUI spec for a claude-native live session: the real
266
319
  * `claude` binary with rynx's hooks (`--settings`), resuming the bound session.
267
320
  * Trust is pre-seeded so the daemon-spawned TUI never blocks on a first-run
@@ -272,6 +325,11 @@ export declare class LocalAgentHost implements CodexCapabilities {
272
325
  * Provider startup never re-opens an Agent template or process-level plugin
273
326
  * snapshot. */
274
327
  private prepareExecutionSkills;
328
+ /** Repair the only cross-process crash window in native rotation. A target
329
+ * started through the Session registry proves that logical publication is
330
+ * durable; a published target in turn proves its source must no longer own
331
+ * the shared live bridge. */
332
+ private reconcileClaudeNativeRotation;
275
333
  private startLiveClaudeSession;
276
334
  /** Persist claude's discovered session id (reusing the `codexSessionId` store
277
335
  * field, as the claude executor already does) and release the readiness gate. */
@@ -280,7 +338,7 @@ export declare class LocalAgentHost implements CodexCapabilities {
280
338
  * serialized per session. Parks until the thread is ready AND the tmux injector
281
339
  * is (re)attached, then pastes; `injectViaTerminal` RAISES if the prompt never
282
340
  * appears (reference implementation RAISE), so a not-ready pane is a hard error — NOT a
283
- * fall-through-to-run signal. Returns {@link InjectOutcome}. */
341
+ * fall-through-to-run signal. Returns {@link InjectResult}. */
284
342
  private injectClaude;
285
343
  /** Park until the claude session's tmux injector is (re)attached by the
286
344
  * runner-child, or the deadline passes. Pane relaunch re-attaches it via
@@ -288,9 +346,12 @@ export declare class LocalAgentHost implements CodexCapabilities {
288
346
  * would fail and (pre-reference implementation) fall through to a second output path. */
289
347
  private waitInjector;
290
348
  /** Attach a session's tmux pane injector (from the runner-child, which owns the
291
- * terminal registry — the host does not hold tmux). Ignored for codex sessions
292
- * (they inject via the app-server). Idempotent. */
349
+ * terminal registry — the host does not hold tmux). Claude uses it for normal
350
+ * message injection; Codex uses it only to dismiss the exact TUI-local Plan
351
+ * picker after its synthetic Web form is submitted. Idempotent. */
293
352
  attachTerminalInjector(localThreadId: string, injector: TerminalInjector): void;
353
+ /** Close an active native response when its terminal or runner disappears. */
354
+ failLiveSession(localThreadId: string, error: Error): boolean;
294
355
  /** List the models a runtime exposes (App Server for codex/traex; static for claude). */
295
356
  listModels(runtime?: AgentRuntimeId): Promise<ModelListResponse | null>;
296
357
  /**
@@ -319,7 +380,3 @@ export declare function isUnsupportedMethodError(error: unknown): boolean;
319
380
  * — a fresh TUI thread before its first turn. Retryable (park until active).
320
381
  * Mirrors reference implementation's `_is_thread_not_ready_error`. */
321
382
  export declare function isThreadNotReadyError(error: unknown): boolean;
322
- /** A persisted thread id that a freshly started app-server cannot load yet.
323
- * During startup, both errors can be transient while the rollout index catches
324
- * up. Retry the same id; never use either error as permission to replace it. */
325
- export declare function isRetryableThreadResumeError(error: unknown): boolean;