@rynx-ai/runtime 0.1.0 → 0.1.9
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/claude/executor.d.ts +3 -5
- package/dist/claude/executor.js +3 -5
- package/dist/claude/native-bridge.d.ts +74 -17
- package/dist/claude/native-bridge.js +225 -30
- package/dist/claude/native-hook-main.js +291 -39
- package/dist/claude/native-hooks.d.ts +3 -2
- package/dist/claude/native-hooks.js +15 -6
- package/dist/claude/native-integration.d.ts +78 -5
- package/dist/claude/native-integration.js +417 -26
- package/dist/claude/settings.d.ts +8 -0
- package/dist/claude/settings.js +50 -0
- package/dist/claude/transcript.d.ts +2 -2
- package/dist/claude/transcript.js +3 -3
- package/dist/codex/rollout-synth.js +1 -1
- package/dist/codex-app-server/client.d.ts +26 -40
- package/dist/codex-app-server/client.js +1128 -99
- package/dist/codex-app-server/forwarder.d.ts +7 -7
- package/dist/codex-app-server/forwarder.js +11 -5
- package/dist/codex-app-server/mapping.d.ts +1 -1
- package/dist/codex-app-server/mapping.js +27 -2
- package/dist/codex-app-server/protocol.d.ts +238 -4
- package/dist/codex-app-server/transport.d.ts +20 -5
- package/dist/codex-app-server/transport.js +93 -40
- package/dist/codex-app-server/ws-channel.d.ts +3 -3
- package/dist/codex-app-server/ws-channel.js +23 -7
- package/dist/codex-child-env.js +33 -0
- package/dist/codex-home.d.ts +6 -6
- package/dist/codex-home.js +8 -9
- package/dist/codex-session-store.d.ts +2 -1
- package/dist/host.d.ts +34 -33
- package/dist/host.js +531 -91
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1 -1
- package/dist/interactions.d.ts +61 -0
- package/dist/interactions.js +236 -0
- package/dist/models-catalog.d.ts +1 -1
- package/dist/models-catalog.js +1 -1
- package/dist/runner/child.d.ts +9 -1
- package/dist/runner/child.js +93 -15
- package/dist/runner/manager.d.ts +59 -10
- package/dist/runner/manager.js +385 -41
- package/dist/runner/protocol.d.ts +18 -7
- package/dist/runner-main.js +9 -6
- package/dist/runtime-status.js +1 -1
- package/dist/terminal/claude-tui.d.ts +8 -3
- package/dist/terminal/claude-tui.js +6 -2
- package/dist/terminal/codex-tui.d.ts +3 -3
- package/dist/terminal/codex-tui.js +1 -1
- package/dist/terminal/registry.d.ts +1 -1
- package/dist/terminal/registry.js +1 -1
- package/dist/terminal/tmux.d.ts +6 -6
- package/dist/terminal/tmux.js +10 -10
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Persistent codex session forwarder — the heart of
|
|
2
|
+
* Persistent codex session forwarder — the heart of reference implementation's codex-native
|
|
3
3
|
* model, ported to rynx. It subscribes to a session's app-server for the whole
|
|
4
4
|
* session lifetime (not just one turn) and maps every thread notification to a
|
|
5
5
|
* typed {@link AgentEvent}, so turns started by ANY client — the web composer OR
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* (or a fatal error) closes it. The turn's codex `turnId` is surfaced on
|
|
11
11
|
* {@link CodexForwarderSink.onTurnStart} so the normalizer's `responseId` is
|
|
12
12
|
* DETERMINISTIC (`resp_codex_<turnId>`) — the same turn always maps to the same
|
|
13
|
-
* response id across snapshot/live, so items converge (
|
|
13
|
+
* response id across snapshot/live, so items converge (reference implementation's `codex_{turnId}`).
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* reference implementation's subscribe-then-mirror model (verified against real codex 0.142.5):
|
|
16
16
|
* the app-server delivers a thread's item/turn notifications to a connection that
|
|
17
17
|
* has `thread/resume`d it. A fresh TUI-created thread has no rollout until its
|
|
18
18
|
* first turn, so resume is parked until {@link CodexForwarderSink.onThreadActive}
|
|
@@ -41,7 +41,7 @@ export interface CodexForwarderSink {
|
|
|
41
41
|
* or a resume). The host persists the id + starts the subscribe loop. */
|
|
42
42
|
onThreadStarted?(threadId: string): void;
|
|
43
43
|
/** The thread showed activity (a turn/item began, so its rollout now exists).
|
|
44
|
-
* Fired once; lets a parked `thread/resume` retry (
|
|
44
|
+
* Fired once; lets a parked `thread/resume` retry (reference implementation's ready signal). */
|
|
45
45
|
onThreadActive?(): void;
|
|
46
46
|
}
|
|
47
47
|
export declare class CodexSessionForwarder {
|
|
@@ -54,10 +54,10 @@ export declare class CodexSessionForwarder {
|
|
|
54
54
|
private activeSignaled;
|
|
55
55
|
/** Completed-item dedup keys already mirrored (live vs resume backfill). Key =
|
|
56
56
|
* `threadId:turnId:item.id`; anonymous items use a per-(thread,turn) position
|
|
57
|
-
* counter. Mirrors
|
|
57
|
+
* counter. Mirrors reference implementation `_completed_item_key` + `synced_item_keys`. */
|
|
58
58
|
private readonly seenCompletedItems;
|
|
59
59
|
/** Per-(thread,turn) position counter for items lacking a stable codex id
|
|
60
|
-
* (peek-then-advance; advanced only on a successful claim).
|
|
60
|
+
* (peek-then-advance; advanced only on a successful claim). reference implementation anon path. */
|
|
61
61
|
private readonly anonCounters;
|
|
62
62
|
constructor(client: CodexAppServerClient, sink: CodexForwarderSink);
|
|
63
63
|
/** Begin mirroring. Idempotent. */
|
|
@@ -85,7 +85,7 @@ export declare class CodexSessionForwarder {
|
|
|
85
85
|
* `threadId:turnId:item.id` — identical across replay + live, so the second
|
|
86
86
|
* delivery is dropped. Items without a codex id fall back to a per-(thread,turn)
|
|
87
87
|
* position counter (peeked here; advanced only on a successful claim, via
|
|
88
|
-
* {@link advanceAnonCounter}). Mirrors
|
|
88
|
+
* {@link advanceAnonCounter}). Mirrors reference implementation `_completed_item_key`. */
|
|
89
89
|
private completedItemKey;
|
|
90
90
|
private advanceAnonCounter;
|
|
91
91
|
private ensureTurn;
|
|
@@ -19,7 +19,7 @@ function userMessageText(item) {
|
|
|
19
19
|
return text || undefined;
|
|
20
20
|
}
|
|
21
21
|
/** Whether a notification implies the thread is now active (its first turn has
|
|
22
|
-
* begun, so the rollout exists). Mirrors
|
|
22
|
+
* begun, so the rollout exists). Mirrors reference implementation's `_event_indicates_thread_active`. */
|
|
23
23
|
function indicatesActive(method, params) {
|
|
24
24
|
if (method.startsWith("turn/") || method.startsWith("item/"))
|
|
25
25
|
return true;
|
|
@@ -39,10 +39,10 @@ export class CodexSessionForwarder {
|
|
|
39
39
|
activeSignaled = false;
|
|
40
40
|
/** Completed-item dedup keys already mirrored (live vs resume backfill). Key =
|
|
41
41
|
* `threadId:turnId:item.id`; anonymous items use a per-(thread,turn) position
|
|
42
|
-
* counter. Mirrors
|
|
42
|
+
* counter. Mirrors reference implementation `_completed_item_key` + `synced_item_keys`. */
|
|
43
43
|
seenCompletedItems = new Set();
|
|
44
44
|
/** Per-(thread,turn) position counter for items lacking a stable codex id
|
|
45
|
-
* (peek-then-advance; advanced only on a successful claim).
|
|
45
|
+
* (peek-then-advance; advanced only on a successful claim). reference implementation anon path. */
|
|
46
46
|
anonCounters = new Map();
|
|
47
47
|
constructor(client, sink) {
|
|
48
48
|
this.client = client;
|
|
@@ -91,8 +91,14 @@ export class CodexSessionForwarder {
|
|
|
91
91
|
this.ensureTurn();
|
|
92
92
|
for (const item of turn.items ?? [])
|
|
93
93
|
this.processCompletedItem(item);
|
|
94
|
+
if (turn.status === "inProgress")
|
|
95
|
+
continue;
|
|
96
|
+
const mapped = mapCodexNotification("turn/completed", { turn });
|
|
94
97
|
this.turnOpen = false;
|
|
95
|
-
|
|
98
|
+
if (mapped.fatalError)
|
|
99
|
+
this.sink.onTurnError(mapped.fatalError);
|
|
100
|
+
else
|
|
101
|
+
this.sink.onTurnEnd(mapped.usage);
|
|
96
102
|
}
|
|
97
103
|
}
|
|
98
104
|
handle(method, params) {
|
|
@@ -166,7 +172,7 @@ export class CodexSessionForwarder {
|
|
|
166
172
|
* `threadId:turnId:item.id` — identical across replay + live, so the second
|
|
167
173
|
* delivery is dropped. Items without a codex id fall back to a per-(thread,turn)
|
|
168
174
|
* position counter (peeked here; advanced only on a successful claim, via
|
|
169
|
-
* {@link advanceAnonCounter}). Mirrors
|
|
175
|
+
* {@link advanceAnonCounter}). Mirrors reference implementation `_completed_item_key`. */
|
|
170
176
|
completedItemKey(item) {
|
|
171
177
|
const threadId = this.currentThreadIdValue ?? "thread";
|
|
172
178
|
const turnId = this.currentTurnIdValue ?? "turn";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Pure codex app-server notification → {@link AgentEvent} mapping. Extracted from
|
|
3
3
|
* the executor so BOTH the per-turn executor and the persistent session
|
|
4
4
|
* forwarder (which mirrors every thread turn — web- AND TUI-initiated — into the
|
|
5
|
-
* canonical log,
|
|
5
|
+
* canonical log, reference implementation's codex-native model) share one mapping.
|
|
6
6
|
*/
|
|
7
7
|
import type { AgentEvent } from "@rynx-ai/core";
|
|
8
8
|
import type { ThreadItem } from "./protocol.js";
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
function turnError(error, fallback) {
|
|
2
|
+
if (typeof error === "string" && error.trim())
|
|
3
|
+
return new Error(error);
|
|
4
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
5
|
+
const message = error.message;
|
|
6
|
+
if (typeof message === "string" && message.trim())
|
|
7
|
+
return new Error(message);
|
|
8
|
+
}
|
|
9
|
+
return new Error(fallback);
|
|
10
|
+
}
|
|
1
11
|
/** Map one thread item (`item/started` | `item/completed`) to events. */
|
|
2
12
|
export function mapCodexItem(method, item) {
|
|
3
13
|
const events = [];
|
|
@@ -112,12 +122,27 @@ export function mapCodexNotification(method, params) {
|
|
|
112
122
|
switch (typed.method) {
|
|
113
123
|
case "thread/started":
|
|
114
124
|
return { events };
|
|
125
|
+
case "serverRequest/resolved":
|
|
126
|
+
// Interaction lifecycle is handled by CodexAppServerClient. It is not
|
|
127
|
+
// model output and must never open or close a Turn in the forwarder.
|
|
128
|
+
return { events };
|
|
115
129
|
case "turn/started":
|
|
116
130
|
return { events };
|
|
117
131
|
case "turn/completed": {
|
|
118
132
|
const turnPayload = typed.params?.turn;
|
|
119
|
-
if (turnPayload?.status === "failed"
|
|
120
|
-
return {
|
|
133
|
+
if (turnPayload?.status === "failed") {
|
|
134
|
+
return {
|
|
135
|
+
events,
|
|
136
|
+
fatalError: turnError(turnPayload.error, "Codex turn failed"),
|
|
137
|
+
turnCompleted: true,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (turnPayload?.status === "interrupted") {
|
|
141
|
+
return {
|
|
142
|
+
events,
|
|
143
|
+
fatalError: turnError(turnPayload.error, "Codex turn was interrupted"),
|
|
144
|
+
turnCompleted: true,
|
|
145
|
+
};
|
|
121
146
|
}
|
|
122
147
|
return { events, turnCompleted: true };
|
|
123
148
|
}
|
|
@@ -58,7 +58,8 @@ export interface GetAuthStatusResponse {
|
|
|
58
58
|
}
|
|
59
59
|
export type AskForApproval = "untrusted" | "on-failure" | "on-request" | "never";
|
|
60
60
|
export type SandboxMode = "read-only" | "workspace-write" | "danger-full-access";
|
|
61
|
-
|
|
61
|
+
/** Open since Codex App Server 0.144; values are advertised by `model/list`. */
|
|
62
|
+
export type ReasoningEffort = string;
|
|
62
63
|
export interface ThreadStartParams {
|
|
63
64
|
model?: string | null;
|
|
64
65
|
modelProvider?: string | null;
|
|
@@ -75,13 +76,15 @@ export interface ThreadResumeParams extends ThreadStartParams {
|
|
|
75
76
|
/** When true, the resume response omits the thread's `turns` backlog (used to
|
|
76
77
|
* SUBSCRIBE without re-replaying history). When false/absent, the response
|
|
77
78
|
* carries `thread.turns[].items[]` — the backfill the forwarder replays for a
|
|
78
|
-
* fresh thread's first turn (
|
|
79
|
+
* fresh thread's first turn (reference implementation's `_replay_resume_response`). */
|
|
79
80
|
excludeTurns?: boolean;
|
|
80
81
|
}
|
|
81
82
|
/** One turn in a resumed thread's backlog (`thread/resume` response). */
|
|
82
83
|
export interface ResumedTurn {
|
|
83
84
|
id?: string;
|
|
84
85
|
turnId?: string;
|
|
86
|
+
status: TurnStatus;
|
|
87
|
+
error?: unknown;
|
|
85
88
|
items?: ThreadItem[];
|
|
86
89
|
}
|
|
87
90
|
/** The `thread` object a `thread/resume` response carries (id + optional backlog). */
|
|
@@ -256,6 +259,11 @@ export interface ModelInfo {
|
|
|
256
259
|
hidden?: boolean;
|
|
257
260
|
isDefault?: boolean;
|
|
258
261
|
supportsPersonality?: boolean;
|
|
262
|
+
supportedReasoningEfforts?: Array<{
|
|
263
|
+
reasoningEffort: ReasoningEffort;
|
|
264
|
+
description?: string;
|
|
265
|
+
}>;
|
|
266
|
+
defaultReasoningEffort?: ReasoningEffort;
|
|
259
267
|
[key: string]: unknown;
|
|
260
268
|
}
|
|
261
269
|
export interface ModelListResponse {
|
|
@@ -450,11 +458,26 @@ export interface CommandExecutionRequestApprovalParams {
|
|
|
450
458
|
itemId: string;
|
|
451
459
|
startedAtMs: number;
|
|
452
460
|
approvalId?: string | null;
|
|
461
|
+
environmentId: string | null;
|
|
453
462
|
reason?: string | null;
|
|
463
|
+
networkApprovalContext?: NetworkApprovalContext | null;
|
|
454
464
|
command?: string | null;
|
|
455
465
|
cwd?: string | null;
|
|
456
|
-
|
|
457
|
-
|
|
466
|
+
commandActions?: Array<Record<string, unknown>> | null;
|
|
467
|
+
additionalPermissions?: AdditionalPermissionProfile | null;
|
|
468
|
+
proposedExecpolicyAmendment?: string[] | null;
|
|
469
|
+
proposedNetworkPolicyAmendments?: NetworkPolicyAmendment[] | null;
|
|
470
|
+
availableDecisions?: CommandExecutionApprovalDecision[] | null;
|
|
471
|
+
}
|
|
472
|
+
export type CommandExecutionApprovalDecision = "accept" | "acceptForSession" | {
|
|
473
|
+
acceptWithExecpolicyAmendment: {
|
|
474
|
+
execpolicy_amendment: string[];
|
|
475
|
+
};
|
|
476
|
+
} | {
|
|
477
|
+
applyNetworkPolicyAmendment: {
|
|
478
|
+
network_policy_amendment: NetworkPolicyAmendment;
|
|
479
|
+
};
|
|
480
|
+
} | "decline" | "cancel";
|
|
458
481
|
export interface CommandExecutionRequestApprovalResponse {
|
|
459
482
|
decision: CommandExecutionApprovalDecision;
|
|
460
483
|
}
|
|
@@ -470,3 +493,214 @@ export type FileChangeApprovalDecision = "accept" | "acceptForSession" | "declin
|
|
|
470
493
|
export interface FileChangeRequestApprovalResponse {
|
|
471
494
|
decision: FileChangeApprovalDecision;
|
|
472
495
|
}
|
|
496
|
+
/** Legacy/experimental app-server approval methods still emitted by current
|
|
497
|
+
* Codex builds alongside the v2 item approval methods. */
|
|
498
|
+
export interface ExecCommandApprovalParams {
|
|
499
|
+
conversationId: string;
|
|
500
|
+
callId: string;
|
|
501
|
+
approvalId: string | null;
|
|
502
|
+
command: string[];
|
|
503
|
+
cwd: string;
|
|
504
|
+
reason: string | null;
|
|
505
|
+
}
|
|
506
|
+
export interface ApplyPatchApprovalParams {
|
|
507
|
+
conversationId: string;
|
|
508
|
+
callId: string;
|
|
509
|
+
fileChanges: Record<string, {
|
|
510
|
+
type: "add" | "delete";
|
|
511
|
+
content: string;
|
|
512
|
+
} | {
|
|
513
|
+
type: "update";
|
|
514
|
+
unified_diff: string;
|
|
515
|
+
move_path: string | null;
|
|
516
|
+
}>;
|
|
517
|
+
reason: string | null;
|
|
518
|
+
grantRoot: string | null;
|
|
519
|
+
}
|
|
520
|
+
export type LegacyReviewDecision = "approved" | "approved_for_session" | "denied" | "timed_out" | "abort";
|
|
521
|
+
export interface LegacyApprovalResponse {
|
|
522
|
+
decision: LegacyReviewDecision;
|
|
523
|
+
}
|
|
524
|
+
/** EXPERIMENTAL request_user_input question advertised by Codex app-server. */
|
|
525
|
+
export interface ToolRequestUserInputQuestion {
|
|
526
|
+
id: string;
|
|
527
|
+
header: string;
|
|
528
|
+
question: string;
|
|
529
|
+
isOther: boolean;
|
|
530
|
+
isSecret: boolean;
|
|
531
|
+
options: Array<{
|
|
532
|
+
label: string;
|
|
533
|
+
description: string;
|
|
534
|
+
}> | null;
|
|
535
|
+
}
|
|
536
|
+
export interface ToolRequestUserInputParams {
|
|
537
|
+
threadId: string;
|
|
538
|
+
turnId: string;
|
|
539
|
+
itemId: string;
|
|
540
|
+
questions: ToolRequestUserInputQuestion[];
|
|
541
|
+
autoResolutionMs: number | null;
|
|
542
|
+
}
|
|
543
|
+
export interface ToolRequestUserInputResponse {
|
|
544
|
+
answers: Record<string, {
|
|
545
|
+
answers: string[];
|
|
546
|
+
}>;
|
|
547
|
+
}
|
|
548
|
+
export interface McpElicitationConstOption {
|
|
549
|
+
const: string;
|
|
550
|
+
title: string;
|
|
551
|
+
}
|
|
552
|
+
export type McpElicitationPrimitiveSchema = {
|
|
553
|
+
type: "string";
|
|
554
|
+
title?: string;
|
|
555
|
+
description?: string;
|
|
556
|
+
minLength?: number;
|
|
557
|
+
maxLength?: number;
|
|
558
|
+
format?: "email" | "uri" | "date" | "date-time";
|
|
559
|
+
default?: string;
|
|
560
|
+
} | {
|
|
561
|
+
type: "string";
|
|
562
|
+
title?: string;
|
|
563
|
+
description?: string;
|
|
564
|
+
enum: string[];
|
|
565
|
+
enumNames?: string[];
|
|
566
|
+
default?: string;
|
|
567
|
+
} | {
|
|
568
|
+
type: "string";
|
|
569
|
+
title?: string;
|
|
570
|
+
description?: string;
|
|
571
|
+
oneOf: McpElicitationConstOption[];
|
|
572
|
+
default?: string;
|
|
573
|
+
} | {
|
|
574
|
+
type: "array";
|
|
575
|
+
title?: string;
|
|
576
|
+
description?: string;
|
|
577
|
+
minItems?: number;
|
|
578
|
+
maxItems?: number;
|
|
579
|
+
items: {
|
|
580
|
+
type: "string";
|
|
581
|
+
enum: string[];
|
|
582
|
+
} | {
|
|
583
|
+
anyOf: McpElicitationConstOption[];
|
|
584
|
+
};
|
|
585
|
+
default?: string[];
|
|
586
|
+
} | {
|
|
587
|
+
type: "number" | "integer";
|
|
588
|
+
title?: string;
|
|
589
|
+
description?: string;
|
|
590
|
+
minimum?: number;
|
|
591
|
+
maximum?: number;
|
|
592
|
+
default?: number;
|
|
593
|
+
} | {
|
|
594
|
+
type: "boolean";
|
|
595
|
+
title?: string;
|
|
596
|
+
description?: string;
|
|
597
|
+
default?: boolean;
|
|
598
|
+
};
|
|
599
|
+
export interface McpElicitationSchema {
|
|
600
|
+
$schema?: string;
|
|
601
|
+
type: "object";
|
|
602
|
+
properties: Record<string, McpElicitationPrimitiveSchema>;
|
|
603
|
+
required?: string[];
|
|
604
|
+
}
|
|
605
|
+
/** MCP elicitation request. `openai/form` deliberately keeps its schema open. */
|
|
606
|
+
export type McpServerElicitationRequestParams = {
|
|
607
|
+
threadId: string;
|
|
608
|
+
turnId: string | null;
|
|
609
|
+
serverName: string;
|
|
610
|
+
} & ({
|
|
611
|
+
mode: "form";
|
|
612
|
+
message: string;
|
|
613
|
+
requestedSchema: McpElicitationSchema;
|
|
614
|
+
_meta: unknown;
|
|
615
|
+
} | {
|
|
616
|
+
mode: "openai/form";
|
|
617
|
+
message: string;
|
|
618
|
+
requestedSchema: Record<string, unknown>;
|
|
619
|
+
_meta: unknown;
|
|
620
|
+
} | {
|
|
621
|
+
mode: "url";
|
|
622
|
+
message: string;
|
|
623
|
+
url: string;
|
|
624
|
+
elicitationId: string;
|
|
625
|
+
_meta: unknown;
|
|
626
|
+
});
|
|
627
|
+
export interface McpServerElicitationRequestResponse {
|
|
628
|
+
action: "accept" | "decline" | "cancel";
|
|
629
|
+
content: unknown | null;
|
|
630
|
+
_meta: unknown | null;
|
|
631
|
+
}
|
|
632
|
+
export interface AdditionalNetworkPermissions {
|
|
633
|
+
enabled: boolean | null;
|
|
634
|
+
}
|
|
635
|
+
export type FileSystemSpecialPath = {
|
|
636
|
+
kind: "root";
|
|
637
|
+
} | {
|
|
638
|
+
kind: "minimal";
|
|
639
|
+
} | {
|
|
640
|
+
kind: "project_roots";
|
|
641
|
+
subpath: string | null;
|
|
642
|
+
} | {
|
|
643
|
+
kind: "tmpdir";
|
|
644
|
+
} | {
|
|
645
|
+
kind: "slash_tmp";
|
|
646
|
+
} | {
|
|
647
|
+
kind: "unknown";
|
|
648
|
+
path: string;
|
|
649
|
+
subpath: string | null;
|
|
650
|
+
};
|
|
651
|
+
export type FileSystemPath = {
|
|
652
|
+
type: "path";
|
|
653
|
+
path: string;
|
|
654
|
+
} | {
|
|
655
|
+
type: "glob_pattern";
|
|
656
|
+
pattern: string;
|
|
657
|
+
} | {
|
|
658
|
+
type: "special";
|
|
659
|
+
value: FileSystemSpecialPath;
|
|
660
|
+
};
|
|
661
|
+
export interface FileSystemSandboxEntry {
|
|
662
|
+
path: FileSystemPath;
|
|
663
|
+
access: "read" | "write" | "deny";
|
|
664
|
+
}
|
|
665
|
+
export interface AdditionalFileSystemPermissions {
|
|
666
|
+
read: string[] | null;
|
|
667
|
+
write: string[] | null;
|
|
668
|
+
globScanMaxDepth?: number;
|
|
669
|
+
entries?: FileSystemSandboxEntry[];
|
|
670
|
+
}
|
|
671
|
+
export interface AdditionalPermissionProfile {
|
|
672
|
+
network: AdditionalNetworkPermissions | null;
|
|
673
|
+
fileSystem: AdditionalFileSystemPermissions | null;
|
|
674
|
+
}
|
|
675
|
+
export interface NetworkApprovalContext {
|
|
676
|
+
host: string;
|
|
677
|
+
protocol: "http" | "https" | "socks5Tcp" | "socks5Udp";
|
|
678
|
+
}
|
|
679
|
+
export interface NetworkPolicyAmendment {
|
|
680
|
+
host: string;
|
|
681
|
+
action: "allow" | "deny";
|
|
682
|
+
}
|
|
683
|
+
export type RequestPermissionProfile = AdditionalPermissionProfile;
|
|
684
|
+
export interface PermissionsRequestApprovalParams {
|
|
685
|
+
threadId: string;
|
|
686
|
+
turnId: string;
|
|
687
|
+
itemId: string;
|
|
688
|
+
environmentId: string | null;
|
|
689
|
+
startedAtMs: number;
|
|
690
|
+
cwd: string;
|
|
691
|
+
reason: string | null;
|
|
692
|
+
permissions: RequestPermissionProfile;
|
|
693
|
+
}
|
|
694
|
+
export interface PermissionsRequestApprovalResponse {
|
|
695
|
+
permissions: {
|
|
696
|
+
network?: AdditionalNetworkPermissions;
|
|
697
|
+
fileSystem?: AdditionalFileSystemPermissions;
|
|
698
|
+
};
|
|
699
|
+
scope: "turn" | "session";
|
|
700
|
+
strictAutoReview?: boolean;
|
|
701
|
+
}
|
|
702
|
+
/** A different app-server client (usually the native TUI) answered first. */
|
|
703
|
+
export interface ServerRequestResolvedNotificationParams {
|
|
704
|
+
threadId?: string;
|
|
705
|
+
requestId: RequestId;
|
|
706
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
|
-
import type { SandboxMode } from "./protocol.js";
|
|
2
|
+
import type { RequestId, SandboxMode } from "./protocol.js";
|
|
3
3
|
export declare function buildAppServerSpawnArgs(sandboxMode: SandboxMode, listen?: string): string[];
|
|
4
4
|
/** app-server args WITHOUT `--listen` — for a channel that appends its own
|
|
5
5
|
* transport endpoint (e.g. {@link import("./ws-channel.js").WsRpcChannel}). */
|
|
@@ -29,7 +29,7 @@ export interface RpcChannel {
|
|
|
29
29
|
/** Establish the channel (connect / await readiness). */
|
|
30
30
|
start(): Promise<void>;
|
|
31
31
|
/** Write one framed message (already newline-terminated). */
|
|
32
|
-
send(line: string): void
|
|
32
|
+
send(line: string): void | Promise<void>;
|
|
33
33
|
/** Register the inbound-line handler (one framed message per call). */
|
|
34
34
|
onLine(cb: (line: string) => void): void;
|
|
35
35
|
/** Register the close/error handler. */
|
|
@@ -64,8 +64,17 @@ export declare class CodexTransportError extends Error {
|
|
|
64
64
|
readonly data?: unknown;
|
|
65
65
|
constructor(message: string, code?: number, data?: unknown);
|
|
66
66
|
}
|
|
67
|
-
export type ServerRequestHandler = (method: string, params: unknown) => Promise<unknown> | unknown;
|
|
67
|
+
export type ServerRequestHandler = (method: string, params: unknown, requestId: RequestId) => Promise<unknown | typeof NO_SERVER_RESPONSE> | unknown | typeof NO_SERVER_RESPONSE;
|
|
68
|
+
/** A server request was resolved by another app-server client. In that case the
|
|
69
|
+
* local handler must settle without sending a second JSON-RPC response. */
|
|
70
|
+
export declare const NO_SERVER_RESPONSE: unique symbol;
|
|
68
71
|
export type ServerNotificationHandler = (method: string, params: unknown) => void;
|
|
72
|
+
export type ServerRequestResponseDeliveryHandler = (requestId: RequestId, result: {
|
|
73
|
+
delivered: true;
|
|
74
|
+
} | {
|
|
75
|
+
delivered: false;
|
|
76
|
+
error: Error;
|
|
77
|
+
}) => void;
|
|
69
78
|
export interface CodexAppServerTransportOptions {
|
|
70
79
|
/** Default stdio transport: spawns `app-server --listen stdio://`. Mutually
|
|
71
80
|
* exclusive with {@link channel}; provide exactly one. */
|
|
@@ -83,6 +92,10 @@ export interface CodexAppServerTransportOptions {
|
|
|
83
92
|
* propagated back to the server.
|
|
84
93
|
*/
|
|
85
94
|
onNotification?: ServerNotificationHandler;
|
|
95
|
+
/** Reports whether a server-request response was actually handed to the
|
|
96
|
+
* transport. Provider acknowledgement still arrives separately as
|
|
97
|
+
* `serverRequest/resolved`. */
|
|
98
|
+
onServerRequestResponseDelivery?: ServerRequestResponseDeliveryHandler;
|
|
86
99
|
}
|
|
87
100
|
interface TransportEvents {
|
|
88
101
|
exit: [code: number | null, signal: NodeJS.Signals | null];
|
|
@@ -109,6 +122,7 @@ export declare class CodexAppServerTransport extends EventEmitter {
|
|
|
109
122
|
private readonly logger;
|
|
110
123
|
private readonly onServerRequest?;
|
|
111
124
|
private readonly onNotification?;
|
|
125
|
+
private readonly onServerRequestResponseDelivery?;
|
|
112
126
|
private child;
|
|
113
127
|
private rl;
|
|
114
128
|
private stderrRl;
|
|
@@ -116,14 +130,14 @@ export declare class CodexAppServerTransport extends EventEmitter {
|
|
|
116
130
|
private readonly pending;
|
|
117
131
|
private startPromise;
|
|
118
132
|
private exited;
|
|
119
|
-
constructor({ spawner, channel, logger, onServerRequest, onNotification, }: CodexAppServerTransportOptions);
|
|
133
|
+
constructor({ spawner, channel, logger, onServerRequest, onNotification, onServerRequestResponseDelivery, }: CodexAppServerTransportOptions);
|
|
120
134
|
emit<K extends keyof TransportEvents>(event: K, ...args: TransportEvents[K]): boolean;
|
|
121
135
|
on<K extends keyof TransportEvents>(event: K, listener: (...args: TransportEvents[K]) => void): this;
|
|
122
136
|
off<K extends keyof TransportEvents>(event: K, listener: (...args: TransportEvents[K]) => void): this;
|
|
123
137
|
isRunning(): boolean;
|
|
124
138
|
ensureStarted(): Promise<void>;
|
|
125
139
|
sendRequest<TResult = unknown>(method: string, params?: unknown): Promise<TResult>;
|
|
126
|
-
sendNotification(method: string, params?: unknown): void
|
|
140
|
+
sendNotification(method: string, params?: unknown): Promise<void>;
|
|
127
141
|
stop(signal?: NodeJS.Signals): Promise<void>;
|
|
128
142
|
private startTransport;
|
|
129
143
|
private startChild;
|
|
@@ -134,6 +148,7 @@ export declare class CodexAppServerTransport extends EventEmitter {
|
|
|
134
148
|
private handleErrorEnvelope;
|
|
135
149
|
private handleServerRequest;
|
|
136
150
|
private respondToServerRequest;
|
|
151
|
+
private notifyServerRequestResponseDelivery;
|
|
137
152
|
private handleNotification;
|
|
138
153
|
}
|
|
139
154
|
export {};
|