codex-chatgpt-control 0.1.0-alpha.1

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 (179) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +21 -0
  3. package/README.md +54 -0
  4. package/contracts/v1/fixtures/backend-capabilities.json +54 -0
  5. package/contracts/v1/fixtures/backend-error-event-missing-stream-input.json +10 -0
  6. package/contracts/v1/fixtures/backend-error-missing-run-input.json +10 -0
  7. package/contracts/v1/fixtures/backend-runner-plan-request.json +12 -0
  8. package/contracts/v1/fixtures/backend-version.json +10 -0
  9. package/contracts/v1/fixtures/command-descriptors.json +803 -0
  10. package/contracts/v1/fixtures/describe-runner-run.json +31 -0
  11. package/contracts/v1/fixtures/doctor-bridge-upload.json +34 -0
  12. package/contracts/v1/fixtures/help-root.json +6 -0
  13. package/contracts/v1/fixtures/named-plan-two-turn.json +39 -0
  14. package/contracts/v1/fixtures/output-json-parse-success.json +115 -0
  15. package/contracts/v1/fixtures/primitive-bootstrap-blocker.json +43 -0
  16. package/contracts/v1/fixtures/report-redaction-default.json +16 -0
  17. package/contracts/v1/fixtures/reports-create-redacted.json +16 -0
  18. package/contracts/v1/fixtures/reports-summarize-redacted.json +26 -0
  19. package/contracts/v1/fixtures/responses-basic-success.json +27 -0
  20. package/contracts/v1/fixtures/responses-hidden-instructions-unsupported.json +22 -0
  21. package/contracts/v1/fixtures/responses-unknown-field-unsupported.json +22 -0
  22. package/contracts/v1/fixtures/responses-unsupported-previous-response-id.json +22 -0
  23. package/contracts/v1/fixtures/responses-unsupported-temperature.json +22 -0
  24. package/contracts/v1/fixtures/run-basic-success.json +36 -0
  25. package/contracts/v1/fixtures/run-browser-bridge-blocker.json +180 -0
  26. package/contracts/v1/fixtures/run-file-attach-success.json +63 -0
  27. package/contracts/v1/fixtures/run-report-redacted.json +52 -0
  28. package/contracts/v1/fixtures/run-selector-drift-blocker.json +60 -0
  29. package/contracts/v1/fixtures/run-timeout-partial.json +81 -0
  30. package/contracts/v1/fixtures/run-two-turn-success.json +83 -0
  31. package/contracts/v1/fixtures/run-upload-permission-blocker.json +56 -0
  32. package/contracts/v1/fixtures/runner-budget-blocker.json +106 -0
  33. package/contracts/v1/fixtures/runner-full-agent-config.json +50 -0
  34. package/contracts/v1/fixtures/runner-input-items-and-files-plan.json +53 -0
  35. package/contracts/v1/fixtures/runner-metadata-only-plan.json +31 -0
  36. package/contracts/v1/fixtures/runner-visible-prefix-plan.json +28 -0
  37. package/contracts/v1/fixtures/runner-visible-setup-plan.json +37 -0
  38. package/contracts/v1/fixtures/stream-basic.ndjson +3 -0
  39. package/contracts/v1/fixtures/stream-blocked.ndjson +2 -0
  40. package/contracts/v1/fixtures/stream-submitted-completed.ndjson +3 -0
  41. package/contracts/v1/fixtures/workflow-ask-success.json +67 -0
  42. package/contracts/v1/manifest.json +210 -0
  43. package/contracts/v1/parity-suite.json +635 -0
  44. package/contracts/v1/schemas/agent.schema.json +52 -0
  45. package/contracts/v1/schemas/backend-event.schema.json +74 -0
  46. package/contracts/v1/schemas/backend-request.schema.json +59 -0
  47. package/contracts/v1/schemas/backend-response.schema.json +42 -0
  48. package/contracts/v1/schemas/capabilities.schema.json +33 -0
  49. package/contracts/v1/schemas/command-descriptor.schema.json +31 -0
  50. package/contracts/v1/schemas/command-result.schema.json +99 -0
  51. package/contracts/v1/schemas/manifest.schema.json +69 -0
  52. package/contracts/v1/schemas/response.schema.json +51 -0
  53. package/contracts/v1/schemas/run-result.schema.json +138 -0
  54. package/contracts/v1/schemas/sequence-plan.schema.json +44 -0
  55. package/contracts/v1/schemas/stream-event.schema.json +25 -0
  56. package/dist/codex-chatgpt-control-backend.mjs +5284 -0
  57. package/dist/codex-chatgpt-control.bundle.mjs +6013 -0
  58. package/dist/src/backend/client.d.ts +129 -0
  59. package/dist/src/backend/client.js +415 -0
  60. package/dist/src/backend/protocol.d.ts +74 -0
  61. package/dist/src/backend/protocol.js +128 -0
  62. package/dist/src/backend/session.d.ts +11 -0
  63. package/dist/src/backend/session.js +223 -0
  64. package/dist/src/backend/stdio-server.d.ts +9 -0
  65. package/dist/src/backend/stdio-server.js +88 -0
  66. package/dist/src/browser/attach.d.ts +8 -0
  67. package/dist/src/browser/attach.js +456 -0
  68. package/dist/src/browser/clipboard.d.ts +2 -0
  69. package/dist/src/browser/clipboard.js +26 -0
  70. package/dist/src/browser/downloads.d.ts +7 -0
  71. package/dist/src/browser/downloads.js +29 -0
  72. package/dist/src/browser/page-state.d.ts +17 -0
  73. package/dist/src/browser/page-state.js +66 -0
  74. package/dist/src/client.d.ts +167 -0
  75. package/dist/src/client.js +666 -0
  76. package/dist/src/commands/confirmations.d.ts +9 -0
  77. package/dist/src/commands/confirmations.js +33 -0
  78. package/dist/src/commands/context.d.ts +2 -0
  79. package/dist/src/commands/context.js +32 -0
  80. package/dist/src/commands/doctor.d.ts +16 -0
  81. package/dist/src/commands/doctor.js +120 -0
  82. package/dist/src/commands/files.d.ts +4 -0
  83. package/dist/src/commands/files.js +314 -0
  84. package/dist/src/commands/helpers.d.ts +16 -0
  85. package/dist/src/commands/helpers.js +128 -0
  86. package/dist/src/commands/messages.d.ts +16 -0
  87. package/dist/src/commands/messages.js +538 -0
  88. package/dist/src/commands/modes.d.ts +9 -0
  89. package/dist/src/commands/modes.js +323 -0
  90. package/dist/src/commands/output.d.ts +5 -0
  91. package/dist/src/commands/output.js +31 -0
  92. package/dist/src/commands/registry.d.ts +17 -0
  93. package/dist/src/commands/registry.js +275 -0
  94. package/dist/src/commands/reports.d.ts +14 -0
  95. package/dist/src/commands/reports.js +47 -0
  96. package/dist/src/commands/response-actions.d.ts +2 -0
  97. package/dist/src/commands/response-actions.js +141 -0
  98. package/dist/src/commands/sequence.d.ts +9 -0
  99. package/dist/src/commands/sequence.js +228 -0
  100. package/dist/src/commands/session.d.ts +2 -0
  101. package/dist/src/commands/session.js +25 -0
  102. package/dist/src/commands/threads.d.ts +6 -0
  103. package/dist/src/commands/threads.js +300 -0
  104. package/dist/src/dom/fixtures.d.ts +1 -0
  105. package/dist/src/dom/fixtures.js +8 -0
  106. package/dist/src/dom/menus.d.ts +8 -0
  107. package/dist/src/dom/menus.js +40 -0
  108. package/dist/src/dom/message-format.d.ts +30 -0
  109. package/dist/src/dom/message-format.js +593 -0
  110. package/dist/src/dom/messages.d.ts +40 -0
  111. package/dist/src/dom/messages.js +127 -0
  112. package/dist/src/dom/selectors.d.ts +20 -0
  113. package/dist/src/dom/selectors.js +72 -0
  114. package/dist/src/dom/visible-text.d.ts +5 -0
  115. package/dist/src/dom/visible-text.js +27 -0
  116. package/dist/src/errors.d.ts +32 -0
  117. package/dist/src/errors.js +127 -0
  118. package/dist/src/index.d.ts +34 -0
  119. package/dist/src/index.js +34 -0
  120. package/dist/src/logger.d.ts +15 -0
  121. package/dist/src/logger.js +25 -0
  122. package/dist/src/runner/agent.d.ts +2 -0
  123. package/dist/src/runner/agent.js +17 -0
  124. package/dist/src/runner/index.d.ts +7 -0
  125. package/dist/src/runner/index.js +7 -0
  126. package/dist/src/runner/interruptions.d.ts +3 -0
  127. package/dist/src/runner/interruptions.js +65 -0
  128. package/dist/src/runner/responses.d.ts +30 -0
  129. package/dist/src/runner/responses.js +171 -0
  130. package/dist/src/runner/result.d.ts +3 -0
  131. package/dist/src/runner/result.js +128 -0
  132. package/dist/src/runner/resume.d.ts +11 -0
  133. package/dist/src/runner/resume.js +26 -0
  134. package/dist/src/runner/stream.d.ts +13 -0
  135. package/dist/src/runner/stream.js +66 -0
  136. package/dist/src/runner/types.d.ts +264 -0
  137. package/dist/src/runner/types.js +1 -0
  138. package/dist/src/safety/blockers.d.ts +7 -0
  139. package/dist/src/safety/blockers.js +60 -0
  140. package/dist/src/safety/redaction.d.ts +2 -0
  141. package/dist/src/safety/redaction.js +18 -0
  142. package/dist/src/safety/report-redaction.d.ts +8 -0
  143. package/dist/src/safety/report-redaction.js +74 -0
  144. package/dist/src/safety/risk.d.ts +26 -0
  145. package/dist/src/safety/risk.js +28 -0
  146. package/dist/src/scripts/backend-server.d.ts +2 -0
  147. package/dist/src/scripts/backend-server.js +7 -0
  148. package/dist/src/scripts/check-parity-suite.d.ts +1 -0
  149. package/dist/src/scripts/check-parity-suite.js +10 -0
  150. package/dist/src/scripts/continue-thread.d.ts +27 -0
  151. package/dist/src/scripts/continue-thread.js +388 -0
  152. package/dist/src/scripts/live-smoke/harness.d.ts +11 -0
  153. package/dist/src/scripts/live-smoke/harness.js +151 -0
  154. package/dist/src/scripts/live-smoke/scenarios.d.ts +3 -0
  155. package/dist/src/scripts/live-smoke/scenarios.js +648 -0
  156. package/dist/src/scripts/live-smoke/types.d.ts +53 -0
  157. package/dist/src/scripts/live-smoke/types.js +1 -0
  158. package/dist/src/scripts/live-smoke-module.d.ts +3 -0
  159. package/dist/src/scripts/live-smoke-module.js +2 -0
  160. package/dist/src/scripts/live-smoke.d.ts +1 -0
  161. package/dist/src/scripts/live-smoke.js +54 -0
  162. package/dist/src/scripts/smoke-attach-file.d.ts +1 -0
  163. package/dist/src/scripts/smoke-attach-file.js +39 -0
  164. package/dist/src/scripts/smoke-hi.d.ts +1 -0
  165. package/dist/src/scripts/smoke-hi.js +25 -0
  166. package/dist/src/scripts/smoke-search-open-read.d.ts +1 -0
  167. package/dist/src/scripts/smoke-search-open-read.js +41 -0
  168. package/dist/src/testing/parity-suite.d.ts +12 -0
  169. package/dist/src/testing/parity-suite.js +213 -0
  170. package/dist/src/types.d.ts +495 -0
  171. package/dist/src/types.js +1 -0
  172. package/package.json +81 -0
  173. package/references/agents-runner.md +32 -0
  174. package/references/backend-protocol.md +238 -0
  175. package/references/python-parity.md +168 -0
  176. package/references/responses-adapter.md +28 -0
  177. package/references/safety.md +14 -0
  178. package/references/streaming.md +15 -0
  179. package/references/troubleshooting.md +91 -0
@@ -0,0 +1,495 @@
1
+ export type CommandStatus = "ok" | "partial" | "timeout" | "blocked" | "needs_confirmation" | "not_found" | "unsupported" | "error";
2
+ export type BlockerKind = "browser_bridge_unavailable" | "login_required" | "captcha" | "rate_limit" | "modal" | "permission" | "confirmation" | "selector_drift" | "download_unavailable" | "upload_failed" | "not_found" | "unknown";
3
+ export type CommandContext = {
4
+ url?: string;
5
+ conversationId?: string;
6
+ title?: string;
7
+ turnCount?: number;
8
+ assistantTurnCount?: number;
9
+ browserName?: string;
10
+ tabId?: string;
11
+ timestamp: string;
12
+ };
13
+ export type CommandResult<T = unknown> = {
14
+ ok: boolean;
15
+ status: CommandStatus;
16
+ data?: T;
17
+ output_text?: string;
18
+ warnings: string[];
19
+ reportPath?: string;
20
+ error?: {
21
+ name: string;
22
+ message: string;
23
+ recoverable: boolean;
24
+ };
25
+ blocker?: {
26
+ kind: BlockerKind;
27
+ message: string;
28
+ visibleText?: string;
29
+ code?: string;
30
+ fieldPath?: string;
31
+ remediation?: Array<{
32
+ label: string;
33
+ instruction: string;
34
+ userActionRequired: boolean;
35
+ }>;
36
+ candidates?: Array<{
37
+ label: string;
38
+ role?: string;
39
+ }>;
40
+ resumable?: boolean;
41
+ };
42
+ context: CommandContext;
43
+ steps?: SequenceStepResult[];
44
+ };
45
+ export type SequencePolicy = {
46
+ stopOnError: boolean;
47
+ returnPartial: boolean;
48
+ defaultTimeoutMs: number;
49
+ screenshotOnBlocker: boolean;
50
+ allowPromptResubmit: "never" | "only_if_no_matching_user_turn";
51
+ };
52
+ export type ThreadTarget = {
53
+ query?: string;
54
+ title?: string;
55
+ conversationId?: string;
56
+ url?: string;
57
+ };
58
+ export type ExistingTabTarget = {
59
+ type: "selected";
60
+ host?: "chatgpt";
61
+ } | {
62
+ type: "tabId";
63
+ tabId: string;
64
+ } | {
65
+ type: "conversationId";
66
+ conversationId: string;
67
+ } | {
68
+ type: "conversation_id";
69
+ conversationId: string;
70
+ } | {
71
+ type: "url";
72
+ url: string;
73
+ } | {
74
+ type: "title";
75
+ title: string;
76
+ exact?: boolean;
77
+ };
78
+ export type ExistingTabPolicy = {
79
+ target?: ExistingTabTarget;
80
+ ifMissing?: "block" | "create" | "open";
81
+ ifMultiple?: "block" | "first";
82
+ requireChatGPT?: boolean;
83
+ };
84
+ export type BootstrapArgs = {
85
+ existingTab?: boolean | ExistingTabPolicy;
86
+ preferExistingTab?: boolean;
87
+ url?: string;
88
+ timeoutMs?: number;
89
+ };
90
+ export type BootstrapData = {
91
+ browserName: string;
92
+ tabId: string;
93
+ url: string;
94
+ loggedIn: boolean;
95
+ };
96
+ export type NewThreadArgs = {
97
+ timeoutMs?: number;
98
+ };
99
+ export type SearchThreadsArgs = {
100
+ query: string;
101
+ limit?: number;
102
+ timeoutMs?: number;
103
+ };
104
+ export type ThreadSearchResult = {
105
+ title: string;
106
+ snippet?: string;
107
+ href: string;
108
+ conversationId?: string;
109
+ };
110
+ export type SearchThreadsData = {
111
+ query: string;
112
+ results: ThreadSearchResult[];
113
+ };
114
+ export type OpenThreadArgs = {
115
+ conversationId?: string;
116
+ url?: string;
117
+ title?: string;
118
+ fromStep?: string;
119
+ select?: "first" | {
120
+ index: number;
121
+ } | {
122
+ title: string;
123
+ };
124
+ timeoutMs?: number;
125
+ };
126
+ export type OpenThreadData = {
127
+ conversationId?: string;
128
+ url: string;
129
+ title?: string;
130
+ };
131
+ export type ComposeArgs = {
132
+ text: string;
133
+ mode?: "replace" | "append";
134
+ timeoutMs?: number;
135
+ };
136
+ export type ComposeData = {
137
+ text: string;
138
+ };
139
+ export type SubmitArgs = {
140
+ text?: string;
141
+ previousTurnCount?: number;
142
+ timeoutMs?: number;
143
+ };
144
+ export type SubmitData = {
145
+ submitted: boolean;
146
+ userTurnText?: string;
147
+ turnCount?: number;
148
+ };
149
+ export type WaitArgs = {
150
+ afterTurnCount?: number;
151
+ afterAssistantTurnCount?: number;
152
+ afterStep?: string;
153
+ timeoutMs?: number;
154
+ stableMs?: number;
155
+ pollMs?: number;
156
+ mode?: "normal" | "deep_research";
157
+ };
158
+ export type WaitData = {
159
+ complete: boolean;
160
+ responseText?: string;
161
+ assistantTurnCount: number;
162
+ elapsedMs: number;
163
+ };
164
+ export type ResponseFormat = "markdown" | "text" | "normalized_text" | "visible_text" | "html" | "blocks" | "all";
165
+ export type ResponseCitation = {
166
+ text: string;
167
+ href: string;
168
+ };
169
+ export type ResponseCodeBlock = {
170
+ language?: string;
171
+ text: string;
172
+ };
173
+ export type ResponseTable = {
174
+ headers: string[];
175
+ rows: string[][];
176
+ };
177
+ export type ResponseCaptureSource = "semantic_dom" | "clipboard";
178
+ export type ResponseCaptureFidelity = "clipboard_markdown" | "semantic_markdown" | "visible_text" | "normalized_text" | "html" | "blocks" | "all";
179
+ export type ResponseBranchState = {
180
+ current?: number;
181
+ total?: number;
182
+ label?: string;
183
+ canGoPrevious?: boolean;
184
+ canGoNext?: boolean;
185
+ };
186
+ export type ResponseActionType = "previous_response" | "next_response" | "copy_response" | "sources" | "good_response" | "bad_response" | "more_actions" | "unknown";
187
+ export type ResponseAction = {
188
+ type: ResponseActionType;
189
+ label: string;
190
+ ariaLabel?: string;
191
+ text?: string;
192
+ testId?: string;
193
+ disabled?: boolean;
194
+ };
195
+ export type ResponseBlock = {
196
+ type: "heading";
197
+ depth: number;
198
+ text: string;
199
+ } | {
200
+ type: "paragraph";
201
+ text: string;
202
+ } | {
203
+ type: "list";
204
+ ordered: boolean;
205
+ items: string[];
206
+ } | ({
207
+ type: "code";
208
+ } & ResponseCodeBlock) | ({
209
+ type: "table";
210
+ } & ResponseTable) | {
211
+ type: "quote";
212
+ text: string;
213
+ } | {
214
+ type: "unknown";
215
+ text: string;
216
+ };
217
+ export type ReadLatestArgs = {
218
+ role?: "assistant" | "user";
219
+ format?: ResponseFormat;
220
+ maxChars?: number;
221
+ };
222
+ export type ReadLatestData = {
223
+ role: "assistant" | "user";
224
+ text: string;
225
+ format: Exclude<ResponseFormat, "text">;
226
+ source?: ResponseCaptureSource;
227
+ fidelity?: ResponseCaptureFidelity;
228
+ warnings?: string[];
229
+ markdown?: string;
230
+ visibleText?: string;
231
+ normalizedText?: string;
232
+ html?: string;
233
+ blocks?: ResponseBlock[];
234
+ citations?: ResponseCitation[];
235
+ codeBlocks?: ResponseCodeBlock[];
236
+ tables?: ResponseTable[];
237
+ branch?: ResponseBranchState;
238
+ actions?: ResponseAction[];
239
+ thoughtDurationText?: string;
240
+ sourcesAvailable?: boolean;
241
+ };
242
+ export type WaitAndReadArgs = WaitArgs & ReadLatestArgs;
243
+ export type AskArgs = {
244
+ text: string;
245
+ wait?: boolean | WaitArgs;
246
+ read?: boolean | ReadLatestArgs;
247
+ timeoutMs?: number;
248
+ };
249
+ export type AskReadData = {
250
+ prompt: string;
251
+ responseText?: string;
252
+ complete?: boolean;
253
+ conversationId?: string;
254
+ title?: string;
255
+ };
256
+ export type AttachFilesArgs = {
257
+ paths: string[];
258
+ timeoutMs?: number;
259
+ };
260
+ export type AttachedFile = {
261
+ path: string;
262
+ name: string;
263
+ bytes: number;
264
+ };
265
+ export type AttachFilesData = {
266
+ files: AttachedFile[];
267
+ };
268
+ export type DownloadLatestArgs = {
269
+ destDir: string;
270
+ filenamePattern?: string;
271
+ from?: "latest_assistant" | "visible_conversation" | {
272
+ assistantIndex: number;
273
+ };
274
+ timeoutMs?: number;
275
+ };
276
+ export type DownloadedFile = {
277
+ path: string;
278
+ suggestedFilename?: string;
279
+ bytes: number;
280
+ };
281
+ export type CopyResponseArgs = {
282
+ which?: "latest" | {
283
+ assistantIndex: number;
284
+ };
285
+ prefer?: "clipboard" | "dom";
286
+ format?: ResponseFormat;
287
+ timeoutMs?: number;
288
+ };
289
+ export type CopiedResponse = {
290
+ text: string;
291
+ source: "clipboard" | "dom";
292
+ format: Exclude<ResponseFormat, "text">;
293
+ fidelity?: ResponseCaptureFidelity;
294
+ warnings?: string[];
295
+ markdown?: string;
296
+ visibleText?: string;
297
+ normalizedText?: string;
298
+ html?: string;
299
+ blocks?: ResponseBlock[];
300
+ citations?: ResponseCitation[];
301
+ codeBlocks?: ResponseCodeBlock[];
302
+ tables?: ResponseTable[];
303
+ branch?: ResponseBranchState;
304
+ actions?: ResponseAction[];
305
+ thoughtDurationText?: string;
306
+ sourcesAvailable?: boolean;
307
+ fallbackReason?: string;
308
+ };
309
+ export type SetModeArgs = {
310
+ model?: string;
311
+ effort?: string;
312
+ timeoutMs?: number;
313
+ };
314
+ export type SelectToolArgs = {
315
+ tool: "web_search" | "deep_research" | "create_image" | string;
316
+ timeoutMs?: number;
317
+ };
318
+ export type SequenceStep = {
319
+ id: string;
320
+ command: "session.bootstrap";
321
+ args?: BootstrapArgs;
322
+ } | {
323
+ id: string;
324
+ command: "threads.search";
325
+ args: SearchThreadsArgs;
326
+ } | {
327
+ id: string;
328
+ command: "threads.open";
329
+ args: OpenThreadArgs;
330
+ } | {
331
+ id: string;
332
+ command: "threads.new";
333
+ args?: NewThreadArgs;
334
+ } | {
335
+ id: string;
336
+ command: "messages.compose";
337
+ args: ComposeArgs;
338
+ } | {
339
+ id: string;
340
+ command: "messages.submit";
341
+ args?: SubmitArgs;
342
+ } | {
343
+ id: string;
344
+ command: "messages.ask";
345
+ args: AskArgs;
346
+ } | {
347
+ id: string;
348
+ command: "messages.wait";
349
+ args: WaitArgs;
350
+ } | {
351
+ id: string;
352
+ command: "messages.readLatest";
353
+ args?: ReadLatestArgs;
354
+ } | {
355
+ id: string;
356
+ command: "messages.waitAndRead";
357
+ args: WaitAndReadArgs;
358
+ } | {
359
+ id: string;
360
+ command: "files.attach";
361
+ args: AttachFilesArgs;
362
+ } | {
363
+ id: string;
364
+ command: "files.downloadLatest";
365
+ args: DownloadLatestArgs;
366
+ } | {
367
+ id: string;
368
+ command: "response.copy";
369
+ args?: CopyResponseArgs;
370
+ } | {
371
+ id: string;
372
+ command: "modes.set";
373
+ args: SetModeArgs;
374
+ } | {
375
+ id: string;
376
+ command: "tools.select";
377
+ args: SelectToolArgs;
378
+ };
379
+ export type SequencePlan = {
380
+ name: string;
381
+ input?: Record<string, unknown>;
382
+ policy?: Partial<SequencePolicy>;
383
+ steps: SequenceStep[];
384
+ };
385
+ export type SequenceStepResult = {
386
+ id: string;
387
+ command: SequenceStep["command"];
388
+ status: CommandStatus;
389
+ ok: boolean;
390
+ startedAt: string;
391
+ endedAt: string;
392
+ dataPreview?: unknown;
393
+ warnings: string[];
394
+ };
395
+ export type RuntimeEnv = {
396
+ agent?: unknown;
397
+ browser?: BrowserLike;
398
+ page?: PageLike;
399
+ clipboard?: ClipboardLike;
400
+ now?: () => Date;
401
+ };
402
+ export type ClipboardLike = {
403
+ read: () => Promise<string>;
404
+ waitForChange: (before: string | undefined, timeoutMs: number) => Promise<string | undefined>;
405
+ };
406
+ export type BrowserLike = {
407
+ name?: string;
408
+ user?: {
409
+ openTabs?: () => Promise<BrowserUserTabInfo[]> | BrowserUserTabInfo[];
410
+ claimTab?: (tab: string | BrowserUserTabInfo) => Promise<PageLike> | PageLike;
411
+ };
412
+ tabs?: {
413
+ create?: (url: string) => Promise<PageLike> | PageLike;
414
+ new?: (url: string) => Promise<PageLike> | PageLike;
415
+ selected?: () => Promise<PageLike | undefined> | PageLike | undefined;
416
+ list?: () => Promise<PageLike[]> | PageLike[];
417
+ get?: (id: string) => Promise<PageLike> | PageLike;
418
+ };
419
+ newPage?: () => Promise<PageLike> | PageLike;
420
+ };
421
+ export type BrowserUserTabInfo = {
422
+ id: string;
423
+ lastOpened?: string;
424
+ tabGroup?: string;
425
+ title?: string;
426
+ url?: string;
427
+ };
428
+ export type LocatorLike = {
429
+ click?: (options?: unknown) => Promise<void>;
430
+ fill?: (value: string, options?: unknown) => Promise<void>;
431
+ textContent?: (options?: unknown) => Promise<string | null>;
432
+ innerText?: (options?: unknown) => Promise<string>;
433
+ innerHTML?: (options?: unknown) => Promise<string>;
434
+ count?: () => Promise<number>;
435
+ nth?: (index: number) => LocatorLike;
436
+ first?: () => LocatorLike;
437
+ last?: () => LocatorLike;
438
+ isVisible?: (options?: unknown) => Promise<boolean>;
439
+ evaluate?: <T>(fn: (element: Element) => T) => Promise<T>;
440
+ locator?: (selector: string) => LocatorLike;
441
+ filter?: (options: Record<string, unknown>) => LocatorLike;
442
+ getByRole?: (role: string, options?: Record<string, unknown>) => LocatorLike;
443
+ getByText?: (text: string | RegExp, options?: Record<string, unknown>) => LocatorLike;
444
+ setInputFiles?: (paths: string[]) => Promise<void>;
445
+ };
446
+ export type FileChooserLike = {
447
+ isMultiple?: () => boolean | Promise<boolean>;
448
+ setFiles: (paths: string[]) => Promise<void>;
449
+ };
450
+ export type WaitForEventOptions = {
451
+ timeout?: number;
452
+ timeoutMs?: number;
453
+ };
454
+ export type PageLike = {
455
+ url?: () => string | Promise<string>;
456
+ goto?: (url: string, options?: unknown) => Promise<unknown>;
457
+ title?: () => Promise<string>;
458
+ locator?: (selector: string) => LocatorLike;
459
+ getByRole?: (role: string, options?: Record<string, unknown>) => LocatorLike;
460
+ getByPlaceholder?: (text: string | RegExp, options?: Record<string, unknown>) => LocatorLike;
461
+ getByText?: (text: string | RegExp, options?: Record<string, unknown>) => LocatorLike;
462
+ keyboard?: {
463
+ press?: (key: string) => Promise<void>;
464
+ };
465
+ waitForTimeout?: (ms: number) => Promise<void>;
466
+ waitForEvent?: (event: string, optionsOrCallback?: WaitForEventOptions | unknown) => Promise<unknown>;
467
+ evaluate?: <T, A = unknown>(fn: (arg: A) => T | Promise<T>, arg?: A) => Promise<T>;
468
+ content?: () => Promise<string>;
469
+ };
470
+ export type AskHelperArgs = AskArgs & {
471
+ thread?: ThreadTarget;
472
+ };
473
+ export type AskInThreadArgs = AskHelperArgs & {
474
+ thread: ThreadTarget;
475
+ };
476
+ export type SendAndWaitArgs = {
477
+ text: string;
478
+ wait?: WaitArgs;
479
+ };
480
+ export type PrecannedResponseArgs = AskInThreadArgs & {
481
+ label?: string;
482
+ };
483
+ export type AttachAskReadArgs = AskInThreadArgs & {
484
+ files: string[];
485
+ };
486
+ export type SearchOpenCopyArgs = {
487
+ thread: ThreadTarget;
488
+ };
489
+ export type TwoTurnExchangeArgs = AskInThreadArgs & {
490
+ followupText: string;
491
+ };
492
+ export type TwoTurnData = {
493
+ first?: AskReadData;
494
+ second?: AskReadData;
495
+ };
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "codex-chatgpt-control",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "Unofficial SDK for Codex agents controlling visible ChatGPT web sessions.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/adamallcock/codex-chatgpt-control.git",
10
+ "directory": "packages/node"
11
+ },
12
+ "homepage": "https://github.com/adamallcock/codex-chatgpt-control#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/adamallcock/codex-chatgpt-control/issues"
15
+ },
16
+ "keywords": [
17
+ "codex",
18
+ "chatgpt",
19
+ "browser-automation",
20
+ "visible-ui",
21
+ "agents",
22
+ "sdk"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc -p tsconfig.json",
26
+ "bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/codex-chatgpt-control.bundle.mjs",
27
+ "bundle:backend": "esbuild src/scripts/backend-server.ts --bundle --platform=node --format=esm --outfile=dist/codex-chatgpt-control-backend.mjs",
28
+ "bundle:live-smoke": "esbuild src/scripts/live-smoke-module.ts --bundle --platform=node --format=esm --outfile=dist/codex-chatgpt-control-live-smoke.bundle.mjs",
29
+ "contract:validate": "node scripts/validate-contract.mjs",
30
+ "parity:fixtures": "node scripts/check-parity-fixtures.mjs",
31
+ "parity:suite": "tsx src/scripts/check-parity-suite.ts",
32
+ "test:backend-conformance": "vitest run tests/unit/backend-conformance.test.ts",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest",
35
+ "thread": "tsx src/scripts/continue-thread.ts",
36
+ "smoke:hi": "tsx src/scripts/smoke-hi.ts",
37
+ "smoke:search": "tsx src/scripts/smoke-search-open-read.ts",
38
+ "smoke:attach": "tsx src/scripts/smoke-attach-file.ts",
39
+ "smoke:live": "tsx src/scripts/live-smoke.ts"
40
+ },
41
+ "exports": {
42
+ ".": {
43
+ "types": "./dist/src/index.d.ts",
44
+ "import": "./dist/src/index.js"
45
+ },
46
+ "./backend": {
47
+ "types": "./dist/src/backend/client.d.ts",
48
+ "import": "./dist/src/backend/client.js"
49
+ },
50
+ "./contracts/v1/manifest.json": "./contracts/v1/manifest.json"
51
+ },
52
+ "types": "./dist/src/index.d.ts",
53
+ "bin": {
54
+ "codex-chatgpt-control-backend": "dist/src/scripts/backend-server.js"
55
+ },
56
+ "files": [
57
+ "dist/src/**/*.js",
58
+ "dist/src/**/*.d.ts",
59
+ "dist/codex-chatgpt-control.bundle.mjs",
60
+ "dist/codex-chatgpt-control-backend.mjs",
61
+ "contracts/v1/**/*.json",
62
+ "contracts/v1/**/*.ndjson",
63
+ "references/**/*.md",
64
+ "README.md",
65
+ "LICENSE",
66
+ "CHANGELOG.md",
67
+ "package.json"
68
+ ],
69
+ "engines": {
70
+ "node": ">=20"
71
+ },
72
+ "sideEffects": false,
73
+ "devDependencies": {
74
+ "@types/node": "^24.13.1",
75
+ "ajv": "^8.17.1",
76
+ "esbuild": "^0.28.0",
77
+ "tsx": "^4.20.0",
78
+ "typescript": "^5.8.0",
79
+ "vitest": "^4.1.8"
80
+ }
81
+ }
@@ -0,0 +1,32 @@
1
+ # Agents Runner
2
+
3
+ `ChatGPTAgent` is a browser-control task profile for operating visible ChatGPT web. It is not an OpenAI API Agent, not a model instance, and not a hidden system-prompt container.
4
+
5
+ `instructions` are visible by default through `instructionsMode: "visible_prefix"`.
6
+
7
+ Use:
8
+
9
+ ```ts
10
+ const chatgpt = createChatGPT({ agent: globalThis.agent });
11
+ const reviewer = chatgpt.agent({ name: "reviewer", instructions: "Review deeply." });
12
+ const plan = chatgpt.runner.plan(reviewer, {
13
+ input: "Review this design.",
14
+ thread: { type: "new" }
15
+ });
16
+ const result = await chatgpt.runner.run(reviewer, {
17
+ input: "Review this design.",
18
+ thread: { type: "new" }
19
+ });
20
+ ```
21
+
22
+ `instructionsMode` controls how instructions are exposed to visible ChatGPT:
23
+
24
+ - `visible_prefix`: include instructions in the same submitted user message.
25
+ - `visible_setup_message`: submit instructions as a separate visible setup turn before the user request.
26
+ - `metadata_only`: keep instructions local; they are not sent to ChatGPT.
27
+
28
+ `runner.run()` returns a `ChatGPTRunResult` with `output_text`, `finalOutput`, `output`, `interruptions`, and `state`. Browser-control blockers are surfaced as resumable interruptions when the underlying command can be retried after user approval, login, or permission repair.
29
+
30
+ For milestone streaming, call `chatgpt.runner.run(agent, input, { stream: true })` and iterate events before awaiting `stream.completed`. This is milestone streaming only, not token-delta streaming.
31
+
32
+ Do not pass API-only model controls such as `temperature`, `logprobs`, `seed`, or hidden system instructions.