@rynx-ai/runtime 0.1.10 → 0.1.11-beta.10

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 (40) hide show
  1. package/dist/claude/models.d.ts +0 -5
  2. package/dist/claude/models.js +1 -7
  3. package/dist/claude/native-bridge.js +3 -8
  4. package/dist/claude/native-integration.d.ts +12 -1
  5. package/dist/claude/native-integration.js +16 -2
  6. package/dist/claude/transcript.d.ts +0 -7
  7. package/dist/claude/transcript.js +6 -20
  8. package/dist/codex-app-server/client.d.ts +2 -1
  9. package/dist/codex-app-server/forwarder.d.ts +4 -1
  10. package/dist/codex-app-server/forwarder.js +19 -1
  11. package/dist/codex-app-server/protocol.d.ts +45 -1
  12. package/dist/codex-home.d.ts +9 -26
  13. package/dist/codex-home.js +37 -65
  14. package/dist/codex-session-store.d.ts +22 -10
  15. package/dist/codex-session-store.js +277 -12
  16. package/dist/host.d.ts +48 -47
  17. package/dist/host.js +810 -355
  18. package/dist/index.d.ts +2 -3
  19. package/dist/index.js +1 -2
  20. package/dist/models-catalog.d.ts +3 -1
  21. package/dist/models-catalog.js +125 -4
  22. package/dist/provider-workspace.d.ts +56 -0
  23. package/dist/provider-workspace.js +83 -0
  24. package/dist/runner/child.d.ts +59 -6
  25. package/dist/runner/child.js +138 -19
  26. package/dist/runner/manager.d.ts +104 -19
  27. package/dist/runner/manager.js +922 -89
  28. package/dist/runner/protocol.d.ts +7 -18
  29. package/dist/runner-main.js +12 -4
  30. package/dist/runtime-state-paths.d.ts +10 -0
  31. package/dist/runtime-state-paths.js +53 -0
  32. package/dist/terminal/claude-tui.d.ts +10 -1
  33. package/dist/terminal/claude-tui.js +9 -1
  34. package/dist/terminal/codex-tui.d.ts +5 -1
  35. package/dist/terminal/codex-tui.js +12 -3
  36. package/dist/terminal/tmux.d.ts +11 -1
  37. package/dist/terminal/tmux.js +61 -12
  38. package/package.json +3 -3
  39. package/dist/codex/rollout-synth.d.ts +0 -42
  40. package/dist/codex/rollout-synth.js +0 -245
package/dist/index.d.ts CHANGED
@@ -6,14 +6,13 @@
6
6
  */
7
7
  export { LocalAgentHost, CodexRuntimeError, SpawnCodexCommandRunner, FileCodexSessionStore, resolveCodexSessionStorePath, } from "./host.js";
8
8
  export type { CodexCapabilities, CapabilityResult, CodexRuntimeStatus, } from "./host.js";
9
- export type { CodexSessionStore, CodexSessionRecord } from "./codex-session-store.js";
10
- export { ensureCodexResumeRollout } from "./codex/rollout-synth.js";
9
+ export type { ClaudeForkIntent, CodexSessionStore, CodexSessionRecord, } from "./codex-session-store.js";
11
10
  export { RunnerManager, TerminalOpenError } from "./runner/manager.js";
12
11
  export type { RunnerManagerOptions, RunnerSessionContext, RunnerSessionContextProvider, OpenTerminalOptions, ParentTerminal, } from "./runner/manager.js";
13
12
  export type { InjectOutcome, TerminalOpenErrorCode, TerminalRole } from "./runner/protocol.js";
14
13
  export type { ResolveInteractionResult, RuntimeInteractionEvent, RuntimeInteractionListener, } from "./interactions.js";
15
14
  export { probeRuntimeStatus } from "./runtime-status.js";
16
15
  export { listRuntimeModels } from "./models-catalog.js";
17
- export { TmuxTerminal, isTmuxAvailable } from "./terminal/tmux.js";
16
+ export { TmuxTerminal, isTmuxAvailable, terminateTmuxServer, tmuxSocketPath, } from "./terminal/tmux.js";
18
17
  export type { TerminalAttachment, TmuxTerminalOptions } from "./terminal/tmux.js";
19
18
  export { TerminalRegistry } from "./terminal/registry.js";
package/dist/index.js CHANGED
@@ -5,7 +5,6 @@
5
5
  * nothing about any channel.
6
6
  */
7
7
  export { LocalAgentHost, CodexRuntimeError, SpawnCodexCommandRunner, FileCodexSessionStore, resolveCodexSessionStorePath, } from "./host.js";
8
- export { ensureCodexResumeRollout } from "./codex/rollout-synth.js";
9
8
  // Runner subprocess layer: the parent-side manager (an `AgentExecutor` +
10
9
  // `AgentCapabilities` that spawns per-session runner children) plus the wire
11
10
  // types. The composition root uses `RunnerManager` in place of `LocalAgentHost`.
@@ -13,5 +12,5 @@ export { RunnerManager, TerminalOpenError } from "./runner/manager.js";
13
12
  export { probeRuntimeStatus } from "./runtime-status.js";
14
13
  export { listRuntimeModels } from "./models-catalog.js";
15
14
  // Live-terminal subsystem (Phase C): tmux-backed terminals + per-runner registry.
16
- export { TmuxTerminal, isTmuxAvailable } from "./terminal/tmux.js";
15
+ export { TmuxTerminal, isTmuxAvailable, terminateTmuxServer, tmuxSocketPath, } from "./terminal/tmux.js";
17
16
  export { TerminalRegistry } from "./terminal/registry.js";
@@ -1,10 +1,12 @@
1
1
  import { type AgentRuntimeId, type AppConfig } from "@rynx-ai/core";
2
2
  import type { ModelListResponse } from "./codex-app-server/protocol.js";
3
3
  export interface RuntimeModelCatalogDeps {
4
+ readCodexModels?: () => Promise<unknown>;
4
5
  readTraexModels?: () => Promise<unknown>;
6
+ readTraexDebugModels?: () => Promise<unknown>;
5
7
  }
6
8
  /**
7
9
  * The model list for a runtime, without an execution backend.
8
- * Falls back to the configured model if live Traex discovery is unavailable.
10
+ * Falls back to the configured model if local/native discovery is unavailable.
9
11
  */
10
12
  export declare function listRuntimeModels(config: AppConfig, runtime: AgentRuntimeId, deps?: RuntimeModelCatalogDeps): Promise<ModelListResponse | null>;
@@ -3,28 +3,51 @@
3
3
  *
4
4
  * The parent control plane no longer holds an app-server, so `/models` can't be
5
5
  * a live `model/list` RPC anymore. Following reference implementation's static-catalog model, we
6
- * serve a config-derived Codex list and Traex's native `models --json` catalog.
6
+ * serve Codex's local model cache and Traex's native `models --json` catalog.
7
7
  * claude already has its own static list ({@link listClaudeModels}).
8
8
  */
9
9
  import { execFile } from "node:child_process";
10
+ import { readFile } from "node:fs/promises";
11
+ import { join } from "node:path";
10
12
  import { promisify } from "node:util";
11
- import { resolveRuntimeBinary, resolveRuntimeModel, } from "@rynx-ai/core";
13
+ import { getRuntimeProfile, resolveRuntimeBinary, resolveRuntimeHome, resolveRuntimeModel, } from "@rynx-ai/core";
12
14
  import { listClaudeModels } from "./claude/models.js";
13
15
  const execFileAsync = promisify(execFile);
14
16
  const TRAEX_MODELS_TIMEOUT_MS = 8_000;
15
17
  const TRAEX_MODELS_MAX_BYTES = 2 * 1024 * 1024;
16
18
  /**
17
19
  * The model list for a runtime, without an execution backend.
18
- * Falls back to the configured model if live Traex discovery is unavailable.
20
+ * Falls back to the configured model if local/native discovery is unavailable.
19
21
  */
20
22
  export async function listRuntimeModels(config, runtime, deps = {}) {
21
23
  if (runtime === "claude") {
22
24
  return listClaudeModels();
23
25
  }
26
+ if (runtime === "codex") {
27
+ try {
28
+ const configuredDefault = resolveRuntimeModel(config, runtime).trim();
29
+ const models = normalizeCodexModels(await (deps.readCodexModels ?? readCodexModels)(), configuredDefault);
30
+ if (models.length > 0)
31
+ return { data: models };
32
+ }
33
+ catch {
34
+ // Keep the configured fallback usable before Codex has populated its cache.
35
+ }
36
+ }
24
37
  if (runtime === "traex") {
25
38
  try {
26
39
  const value = await (deps.readTraexModels ?? readTraexModels)();
27
- const models = normalizeTraexModels(value, resolveRuntimeModel(config, runtime).trim());
40
+ const configuredDefault = resolveRuntimeModel(config, runtime).trim();
41
+ const defaultModel = configuredDefault || resolveTraexNativeDefault(await (deps.readTraexDebugModels ?? readTraexDebugModels)());
42
+ if (!configuredDefault &&
43
+ (!Array.isArray(value) ||
44
+ !value.some((item) => item &&
45
+ typeof item === "object" &&
46
+ !Array.isArray(item) &&
47
+ item.name === defaultModel))) {
48
+ throw new Error(`Traex native default is missing from the public catalog: ${defaultModel}`);
49
+ }
50
+ const models = normalizeTraexModels(value, defaultModel);
28
51
  if (models.length > 0)
29
52
  return { data: models };
30
53
  }
@@ -38,6 +61,72 @@ export async function listRuntimeModels(config, runtime, deps = {}) {
38
61
  }
39
62
  return { data: [{ id: model, model, isDefault: true }] };
40
63
  }
64
+ async function readCodexModels() {
65
+ const cachePath = join(resolveRuntimeHome(getRuntimeProfile("codex")), "models_cache.json");
66
+ return JSON.parse(await readFile(cachePath, "utf8"));
67
+ }
68
+ function normalizeCodexModels(value, configuredDefault) {
69
+ if (!value || typeof value !== "object" || Array.isArray(value))
70
+ return [];
71
+ const entries = value.models;
72
+ if (!Array.isArray(entries))
73
+ return [];
74
+ const models = [];
75
+ const seen = new Set();
76
+ for (const item of entries) {
77
+ if (!item || typeof item !== "object" || Array.isArray(item))
78
+ continue;
79
+ const record = item;
80
+ const id = typeof record.slug === "string" ? record.slug.trim() : "";
81
+ if (!id || seen.has(id) || record.visibility === "hide")
82
+ continue;
83
+ seen.add(id);
84
+ const supportedReasoningEfforts = Array.isArray(record.supported_reasoning_levels)
85
+ ? record.supported_reasoning_levels.flatMap((raw) => {
86
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
87
+ return [];
88
+ const effort = typeof raw.effort === "string"
89
+ ? raw.effort.trim()
90
+ : "";
91
+ if (!effort)
92
+ return [];
93
+ const description = raw.description;
94
+ return [{
95
+ reasoningEffort: effort,
96
+ ...(typeof description === "string" && description.trim()
97
+ ? { description: description.trim() }
98
+ : {}),
99
+ }];
100
+ })
101
+ : [];
102
+ const displayName = typeof record.display_name === "string"
103
+ ? record.display_name.trim()
104
+ : "";
105
+ const description = typeof record.description === "string"
106
+ ? record.description.trim()
107
+ : "";
108
+ const defaultReasoningEffort = typeof record.default_reasoning_level === "string"
109
+ ? record.default_reasoning_level.trim()
110
+ : "";
111
+ models.push({
112
+ id,
113
+ model: id,
114
+ ...(displayName ? { displayName } : {}),
115
+ ...(description ? { description } : {}),
116
+ isDefault: id === configuredDefault,
117
+ ...(supportedReasoningEfforts.length > 0 ? { supportedReasoningEfforts } : {}),
118
+ ...(defaultReasoningEffort ? { defaultReasoningEffort } : {}),
119
+ });
120
+ }
121
+ if (configuredDefault && !seen.has(configuredDefault)) {
122
+ models.unshift({
123
+ id: configuredDefault,
124
+ model: configuredDefault,
125
+ isDefault: true,
126
+ });
127
+ }
128
+ return models;
129
+ }
41
130
  async function readTraexModels() {
42
131
  const { stdout } = await execFileAsync(resolveRuntimeBinary("traex"), ["models", "--json"], {
43
132
  encoding: "utf8",
@@ -46,6 +135,38 @@ async function readTraexModels() {
46
135
  });
47
136
  return JSON.parse(stdout);
48
137
  }
138
+ async function readTraexDebugModels() {
139
+ const { stdout } = await execFileAsync(resolveRuntimeBinary("traex"), ["debug", "models"], {
140
+ encoding: "utf8",
141
+ timeout: TRAEX_MODELS_TIMEOUT_MS,
142
+ maxBuffer: TRAEX_MODELS_MAX_BYTES,
143
+ });
144
+ return JSON.parse(stdout);
145
+ }
146
+ function resolveTraexNativeDefault(value) {
147
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
148
+ throw new Error("Traex debug model catalog is invalid");
149
+ }
150
+ const models = value.models;
151
+ if (!Array.isArray(models)) {
152
+ throw new Error("Traex debug model catalog is invalid");
153
+ }
154
+ const defaults = models.filter((item) => item &&
155
+ typeof item === "object" &&
156
+ !Array.isArray(item) &&
157
+ item.business_metadata &&
158
+ typeof item.business_metadata === "object" &&
159
+ item.business_metadata
160
+ .backend_is_default === true);
161
+ if (defaults.length !== 1) {
162
+ throw new Error(`Traex debug model catalog has ${defaults.length} native defaults`);
163
+ }
164
+ const name = defaults[0].config_name;
165
+ if (typeof name !== "string" || !name.trim()) {
166
+ throw new Error("Traex native default has no config_name");
167
+ }
168
+ return name.trim();
169
+ }
49
170
  function normalizeTraexModels(value, configuredDefault) {
50
171
  if (!Array.isArray(value))
51
172
  return [];
@@ -0,0 +1,56 @@
1
+ import type { AgentRuntimeId, SandboxMode } from "@rynx-ai/core";
2
+ import type { PermissionProfileSelectionParams, SandboxPolicy } from "./codex-app-server/protocol.js";
3
+ /** Structural view of the immutable Session workspace snapshot. The canonical
4
+ * type lives in core; keeping the adapter input structural avoids inventing a
5
+ * second domain model in the Provider layer. */
6
+ export interface ProviderWorkspace {
7
+ readonly cwd: string;
8
+ readonly allowedDirs: readonly string[];
9
+ }
10
+ /** Canonical roots projected without mutating the Session snapshot, with the
11
+ * primary working directory first for every Provider. */
12
+ export declare function providerWorkspaceRoots(workspace: ProviderWorkspace): string[];
13
+ export declare function providerAdditionalDirs(workspace: ProviderWorkspace): string[];
14
+ export declare function sandboxPolicyForWorkspace(mode: SandboxMode, workspace: ProviderWorkspace): SandboxPolicy;
15
+ export declare function codexThreadWorkspaceParams(workspace: ProviderWorkspace): {
16
+ cwd: string;
17
+ runtimeWorkspaceRoots: string[];
18
+ };
19
+ export declare function codexTurnWorkspaceParams(workspace: ProviderWorkspace, mode: SandboxMode): {
20
+ cwd: string;
21
+ runtimeWorkspaceRoots: string[];
22
+ sandboxPolicy: SandboxPolicy;
23
+ };
24
+ /** Traex has no runtimeWorkspaceRoots field. For a multi-root writable
25
+ * workspace, use the bounded named-profile modification supported by Traex
26
+ * 0.200; never combine it with the legacy sandbox field. */
27
+ export declare function traexThreadWorkspaceParams(workspace: ProviderWorkspace, mode: SandboxMode): {
28
+ cwd: string;
29
+ permissions: PermissionProfileSelectionParams;
30
+ } | {
31
+ cwd: string;
32
+ sandbox: SandboxMode;
33
+ };
34
+ /** Turn equivalent of {@link traexThreadWorkspaceParams}; `permissions` and
35
+ * `sandboxPolicy` are intentionally mutually exclusive. */
36
+ export declare function traexTurnWorkspaceParams(workspace: ProviderWorkspace, mode: SandboxMode): {
37
+ cwd: string;
38
+ permissions: PermissionProfileSelectionParams;
39
+ } | {
40
+ cwd: string;
41
+ sandboxPolicy: SandboxPolicy;
42
+ };
43
+ export declare function threadWorkspaceParams(runtime: Exclude<AgentRuntimeId, "claude">, workspace: ProviderWorkspace, mode: SandboxMode): {
44
+ cwd: string;
45
+ permissions: PermissionProfileSelectionParams;
46
+ } | {
47
+ cwd: string;
48
+ sandbox: SandboxMode;
49
+ };
50
+ export declare function turnWorkspaceParams(runtime: Exclude<AgentRuntimeId, "claude">, workspace: ProviderWorkspace, mode: SandboxMode): {
51
+ cwd: string;
52
+ permissions: PermissionProfileSelectionParams;
53
+ } | {
54
+ cwd: string;
55
+ sandboxPolicy: SandboxPolicy;
56
+ };
@@ -0,0 +1,83 @@
1
+ /** Canonical roots projected without mutating the Session snapshot, with the
2
+ * primary working directory first for every Provider. */
3
+ export function providerWorkspaceRoots(workspace) {
4
+ return [...new Set([workspace.cwd, ...workspace.allowedDirs])];
5
+ }
6
+ export function providerAdditionalDirs(workspace) {
7
+ return providerWorkspaceRoots(workspace).filter((dir) => dir !== workspace.cwd);
8
+ }
9
+ export function sandboxPolicyForWorkspace(mode, workspace) {
10
+ switch (mode) {
11
+ case "read-only":
12
+ return { type: "readOnly", networkAccess: false };
13
+ case "workspace-write":
14
+ return {
15
+ type: "workspaceWrite",
16
+ writableRoots: providerWorkspaceRoots(workspace),
17
+ networkAccess: true,
18
+ excludeTmpdirEnvVar: false,
19
+ excludeSlashTmp: false,
20
+ };
21
+ case "danger-full-access":
22
+ return { type: "dangerFullAccess" };
23
+ }
24
+ }
25
+ export function codexThreadWorkspaceParams(workspace) {
26
+ return {
27
+ cwd: workspace.cwd,
28
+ runtimeWorkspaceRoots: providerWorkspaceRoots(workspace),
29
+ };
30
+ }
31
+ export function codexTurnWorkspaceParams(workspace, mode) {
32
+ return {
33
+ ...codexThreadWorkspaceParams(workspace),
34
+ sandboxPolicy: sandboxPolicyForWorkspace(mode, workspace),
35
+ };
36
+ }
37
+ function traexWorkspacePermissions(workspace) {
38
+ const additionalDirs = providerAdditionalDirs(workspace);
39
+ if (additionalDirs.length === 0)
40
+ return undefined;
41
+ return {
42
+ type: "profile",
43
+ id: ":workspace",
44
+ modifications: additionalDirs.map((path) => ({
45
+ type: "additionalWritableRoot",
46
+ path,
47
+ })),
48
+ };
49
+ }
50
+ /** Traex has no runtimeWorkspaceRoots field. For a multi-root writable
51
+ * workspace, use the bounded named-profile modification supported by Traex
52
+ * 0.200; never combine it with the legacy sandbox field. */
53
+ export function traexThreadWorkspaceParams(workspace, mode) {
54
+ const permissions = mode === "workspace-write"
55
+ ? traexWorkspacePermissions(workspace)
56
+ : undefined;
57
+ return permissions
58
+ ? { cwd: workspace.cwd, permissions }
59
+ : { cwd: workspace.cwd, sandbox: mode };
60
+ }
61
+ /** Turn equivalent of {@link traexThreadWorkspaceParams}; `permissions` and
62
+ * `sandboxPolicy` are intentionally mutually exclusive. */
63
+ export function traexTurnWorkspaceParams(workspace, mode) {
64
+ const permissions = mode === "workspace-write"
65
+ ? traexWorkspacePermissions(workspace)
66
+ : undefined;
67
+ return permissions
68
+ ? { cwd: workspace.cwd, permissions }
69
+ : {
70
+ cwd: workspace.cwd,
71
+ sandboxPolicy: sandboxPolicyForWorkspace(mode, workspace),
72
+ };
73
+ }
74
+ export function threadWorkspaceParams(runtime, workspace, mode) {
75
+ return runtime === "traex"
76
+ ? traexThreadWorkspaceParams(workspace, mode)
77
+ : { ...codexThreadWorkspaceParams(workspace), sandbox: mode };
78
+ }
79
+ export function turnWorkspaceParams(runtime, workspace, mode) {
80
+ return runtime === "traex"
81
+ ? traexTurnWorkspaceParams(workspace, mode)
82
+ : codexTurnWorkspaceParams(workspace, mode);
83
+ }
@@ -7,12 +7,61 @@
7
7
  * per-thread capabilities, answered against the same backend so the parent never
8
8
  * needs an app-server of its own.
9
9
  */
10
- import { type AgentCapabilities } from "@rynx-ai/core";
10
+ import { type AgentCapabilities, type ResolvedExecutionSnapshot, type RuntimeUserInput, type SessionInteractionResolution, type SessionWorkspaceSnapshot } from "@rynx-ai/core";
11
+ import type { SessionEvent } from "@rynx-ai/core";
12
+ import type { TerminalInjector } from "../claude/native-integration.js";
13
+ import type { ResolveInteractionResult } from "../interactions.js";
14
+ import { type InjectOutcome } from "./protocol.js";
11
15
  import type { ChildTransport } from "./transport.js";
16
+ /** Re-target the mirror to a freshly minted rynx session (claude `/clear`·`/fork`)
17
+ * + record the terminal transfer with the daemon. The child owns the transport,
18
+ * so it supplies this to the host. */
19
+ type RetargetMirror = (newSessionId: string, meta: {
20
+ kind: "clear" | "fork";
21
+ workspace: SessionWorkspaceSnapshot;
22
+ execution: ResolvedExecutionSnapshot;
23
+ parentSessionId?: string;
24
+ }) => void;
25
+ /** Codex-native live-session methods the executor (a `LocalAgentHost`) exposes
26
+ * beyond the `AgentExecutor`/`AgentCapabilities` contract. Duck-typed so the
27
+ * runner works with any executor (a claude-only host simply lacks them). */
28
+ interface LiveCodexProvider {
29
+ codexTerminalSpec?(localThreadId: string): Promise<{
30
+ command: string;
31
+ args: string[];
32
+ cwd: string;
33
+ env?: Record<string, string>;
34
+ skipTraexStartupPrompts?: boolean;
35
+ } | null>;
36
+ ensureLiveCodexSession?(localThreadId: string, emit: (event: SessionEvent) => void, opts: {
37
+ workspace: SessionWorkspaceSnapshot;
38
+ execution: ResolvedExecutionSnapshot;
39
+ retargetMirror?: RetargetMirror;
40
+ }): Promise<boolean>;
41
+ waitLiveReady?(localThreadId: string, timeoutMs?: number): Promise<boolean>;
42
+ waitTerminalReady?(localThreadId: string, timeoutMs?: number): Promise<boolean>;
43
+ liveSessionError?(localThreadId: string): string | undefined;
44
+ injectMessage?(localThreadId: string, input: RuntimeUserInput | string): Promise<InjectOutcome>;
45
+ interruptLive?(localThreadId: string): Promise<boolean>;
46
+ stopLiveCodexSession?(localThreadId: string, opts?: {
47
+ deferClaudeInteractionCleanup?: boolean;
48
+ }): void;
49
+ finalizeStoppedLiveSessions?(): void;
50
+ resolveInteraction?(localThreadId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<ResolveInteractionResult>;
51
+ /** claude-native: hand the session's tmux pane injector to the host (which
52
+ * doesn't own tmux). No-op for codex sessions (they inject via app-server). */
53
+ attachTerminalInjector?(localThreadId: string, injector: TerminalInjector): void;
54
+ /** Internal Provider operation used only by MachineSessionService through
55
+ * RunnerManager. It is deliberately absent from public AgentCapabilities. */
56
+ forkSession?(currentLocalThreadId: string, newLocalThreadId: string, options: {
57
+ workspace: SessionWorkspaceSnapshot;
58
+ execution: ResolvedExecutionSnapshot;
59
+ }): Promise<import("@rynx-ai/core").CapabilityResult>;
60
+ }
12
61
  export interface RunnerSessionDeps {
13
62
  transport: ChildTransport;
14
63
  /** The single-backend capability + live co-drive surface (a `LocalAgentHost`). */
15
- executor: AgentCapabilities;
64
+ executor: AgentCapabilities & LiveCodexProvider;
16
65
  /** Invoked on a `shutdown` message (default: close transport). */
17
66
  onShutdown?: () => void;
18
67
  }
@@ -23,6 +72,8 @@ export declare class RunnerSession {
23
72
  /** Live terminals hosted by this session, and per-attach client handles. */
24
73
  private readonly terminals;
25
74
  private readonly attachments;
75
+ private readonly attachmentThreadIds;
76
+ private readonly traexStartupWatchers;
26
77
  /** Opens are async; a close received before attach resolves tombstones the id. */
27
78
  private readonly pendingTerminalOpens;
28
79
  private readonly cancelledTerminalOpens;
@@ -42,10 +93,9 @@ export declare class RunnerSession {
42
93
  /**
43
94
  * Eagerly bring up a session's codex-native live view: start the persistent
44
95
  * forwarder connection (which resume-subscribes to mirror every turn) and
45
- * launch the detached `codex --remote` TUI, which CREATES the codex thread. The
46
- * forwarder's connection sees the TUI's broadcast `thread/started`, binds, and
47
- * subscribes — so the TUI is usable immediately (a fresh `--remote` needs no
48
- * rollout) and its turns mirror to chat (reference implementation's model).
96
+ * launch the detached `codex --remote resume` TUI against the thread the
97
+ * structured runtime created. The forwarder subscribes to that same thread,
98
+ * so the TUI is usable immediately and its turns mirror to chat.
49
99
  */
50
100
  private ensureLive;
51
101
  private inject;
@@ -54,6 +104,8 @@ export declare class RunnerSession {
54
104
  * `codexTerminalSpec`. Shares the `${id}-main` terminal id with `term.open`,
55
105
  * so the web attach reuses the same detached pane. */
56
106
  private launchCodexPane;
107
+ private cancelTraexStartupWatcher;
108
+ private skipTraexStartupPrompts;
57
109
  private stopLive;
58
110
  /** Stop event forwarding, kill native terminals/hooks, then synchronously
59
111
  * scrub provider handoff files before the child process is allowed to exit. */
@@ -64,3 +116,4 @@ export declare class RunnerSession {
64
116
  private runCap;
65
117
  private dispatchCap;
66
118
  }
119
+ export {};