codex-chatgpt-control 0.3.0-alpha.1 → 0.5.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 (214) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +42 -2
  3. package/contracts/v1/fixtures/backend-capabilities.json +10 -0
  4. package/contracts/v1/fixtures/command-descriptors.json +257 -6
  5. package/contracts/v1/fixtures/describe-runner-run.json +5 -2
  6. package/contracts/v1/fixtures/doctor-scenario-preflight.json +34 -2
  7. package/contracts/v1/fixtures/help-root.json +1 -1
  8. package/contracts/v1/fixtures/output-json-parse-success.json +9 -0
  9. package/contracts/v1/fixtures/run-timeout-partial.json +15 -4
  10. package/contracts/v1/fixtures/stream-in-progress.ndjson +3 -0
  11. package/contracts/v1/fixtures/stream-submitted-completed.ndjson +1 -1
  12. package/contracts/v1/fixtures/surface-chat-legacy.json +35 -0
  13. package/contracts/v1/fixtures/surface-chat-simplified.json +37 -0
  14. package/contracts/v1/fixtures/surface-sidebar-false-positive.json +29 -0
  15. package/contracts/v1/fixtures/surface-work-advanced.json +45 -0
  16. package/contracts/v1/fixtures/surface-work-basic.json +38 -0
  17. package/contracts/v1/fixtures/workflow-ask-success.json +8 -0
  18. package/contracts/v1/manifest.json +32 -1
  19. package/contracts/v1/parity-suite.json +113 -0
  20. package/contracts/v1/schemas/backend-request.schema.json +15 -0
  21. package/contracts/v1/schemas/manifest.schema.json +6 -3
  22. package/contracts/v1/schemas/surface-profile.schema.json +166 -0
  23. package/dist/codex-chatgpt-control-backend.mjs +2045 -227
  24. package/dist/codex-chatgpt-control.bundle.mjs +3817 -1960
  25. package/dist/src/backend/client.d.ts +26 -1
  26. package/dist/src/backend/client.js +23 -1
  27. package/dist/src/backend/protocol.d.ts +1 -1
  28. package/dist/src/backend/protocol.js +10 -0
  29. package/dist/src/backend/session.js +20 -0
  30. package/dist/src/browser/attach.d.ts +1 -0
  31. package/dist/src/browser/attach.js +3 -3
  32. package/dist/src/browser/page-state.js +5 -2
  33. package/dist/src/client.d.ts +31 -1
  34. package/dist/src/client.js +69 -14
  35. package/dist/src/commands/artifacts.js +1 -7
  36. package/dist/src/commands/configuration.d.ts +15 -0
  37. package/dist/src/commands/configuration.js +674 -0
  38. package/dist/src/commands/doctor.js +38 -1
  39. package/dist/src/commands/experience.d.ts +12 -0
  40. package/dist/src/commands/experience.js +288 -0
  41. package/dist/src/commands/files.js +1 -7
  42. package/dist/src/commands/messages.d.ts +2 -1
  43. package/dist/src/commands/messages.js +138 -16
  44. package/dist/src/commands/modes.js +28 -14
  45. package/dist/src/commands/registry.js +69 -7
  46. package/dist/src/commands/response-actions.js +1 -7
  47. package/dist/src/commands/sequence.js +24 -1
  48. package/dist/src/commands/session.d.ts +2 -0
  49. package/dist/src/commands/session.js +50 -1
  50. package/dist/src/commands/threads.js +1 -7
  51. package/dist/src/commands/work.d.ts +6 -0
  52. package/dist/src/commands/work.js +338 -0
  53. package/dist/src/dom/locale/am.d.ts +2 -1
  54. package/dist/src/dom/locale/am.js +2 -1
  55. package/dist/src/dom/locale/ar.d.ts +2 -1
  56. package/dist/src/dom/locale/ar.js +2 -1
  57. package/dist/src/dom/locale/bg.d.ts +2 -1
  58. package/dist/src/dom/locale/bg.js +2 -1
  59. package/dist/src/dom/locale/bn.d.ts +2 -1
  60. package/dist/src/dom/locale/bn.js +2 -1
  61. package/dist/src/dom/locale/bs.d.ts +2 -1
  62. package/dist/src/dom/locale/bs.js +2 -1
  63. package/dist/src/dom/locale/ca.d.ts +2 -1
  64. package/dist/src/dom/locale/ca.js +2 -1
  65. package/dist/src/dom/locale/cs.d.ts +2 -1
  66. package/dist/src/dom/locale/cs.js +2 -1
  67. package/dist/src/dom/locale/da.d.ts +2 -1
  68. package/dist/src/dom/locale/da.js +2 -1
  69. package/dist/src/dom/locale/de.d.ts +4 -3
  70. package/dist/src/dom/locale/de.js +4 -3
  71. package/dist/src/dom/locale/el.d.ts +2 -1
  72. package/dist/src/dom/locale/el.js +2 -1
  73. package/dist/src/dom/locale/en.d.ts +27 -2
  74. package/dist/src/dom/locale/en.js +28 -2
  75. package/dist/src/dom/locale/es-419.d.ts +2 -1
  76. package/dist/src/dom/locale/es-419.js +2 -1
  77. package/dist/src/dom/locale/es-ES.d.ts +2 -1
  78. package/dist/src/dom/locale/es-ES.js +2 -1
  79. package/dist/src/dom/locale/et.d.ts +2 -1
  80. package/dist/src/dom/locale/et.js +2 -1
  81. package/dist/src/dom/locale/fa.d.ts +2 -1
  82. package/dist/src/dom/locale/fa.js +2 -1
  83. package/dist/src/dom/locale/fi.d.ts +2 -1
  84. package/dist/src/dom/locale/fi.js +2 -1
  85. package/dist/src/dom/locale/fr-CA.d.ts +2 -1
  86. package/dist/src/dom/locale/fr-CA.js +2 -1
  87. package/dist/src/dom/locale/fr-FR.d.ts +3 -3
  88. package/dist/src/dom/locale/fr-FR.js +3 -3
  89. package/dist/src/dom/locale/gu.d.ts +2 -1
  90. package/dist/src/dom/locale/gu.js +2 -1
  91. package/dist/src/dom/locale/hi.d.ts +2 -1
  92. package/dist/src/dom/locale/hi.js +2 -1
  93. package/dist/src/dom/locale/hr.d.ts +2 -1
  94. package/dist/src/dom/locale/hr.js +2 -1
  95. package/dist/src/dom/locale/hu.d.ts +2 -1
  96. package/dist/src/dom/locale/hu.js +2 -1
  97. package/dist/src/dom/locale/hy.d.ts +2 -1
  98. package/dist/src/dom/locale/hy.js +2 -1
  99. package/dist/src/dom/locale/id.d.ts +2 -1
  100. package/dist/src/dom/locale/id.js +2 -1
  101. package/dist/src/dom/locale/index.d.ts +17 -2
  102. package/dist/src/dom/locale/index.js +65 -0
  103. package/dist/src/dom/locale/is.d.ts +2 -1
  104. package/dist/src/dom/locale/is.js +2 -1
  105. package/dist/src/dom/locale/it.d.ts +2 -1
  106. package/dist/src/dom/locale/it.js +2 -1
  107. package/dist/src/dom/locale/ja.d.ts +2 -1
  108. package/dist/src/dom/locale/ja.js +2 -1
  109. package/dist/src/dom/locale/ka.d.ts +2 -1
  110. package/dist/src/dom/locale/ka.js +2 -1
  111. package/dist/src/dom/locale/kk.d.ts +2 -1
  112. package/dist/src/dom/locale/kk.js +2 -1
  113. package/dist/src/dom/locale/kn.d.ts +2 -1
  114. package/dist/src/dom/locale/kn.js +2 -1
  115. package/dist/src/dom/locale/ko.d.ts +2 -1
  116. package/dist/src/dom/locale/ko.js +2 -1
  117. package/dist/src/dom/locale/lt.d.ts +2 -1
  118. package/dist/src/dom/locale/lt.js +2 -1
  119. package/dist/src/dom/locale/lv.d.ts +2 -1
  120. package/dist/src/dom/locale/lv.js +2 -1
  121. package/dist/src/dom/locale/mk.d.ts +2 -1
  122. package/dist/src/dom/locale/mk.js +2 -1
  123. package/dist/src/dom/locale/ml.d.ts +2 -1
  124. package/dist/src/dom/locale/ml.js +2 -1
  125. package/dist/src/dom/locale/mn.d.ts +2 -1
  126. package/dist/src/dom/locale/mn.js +2 -1
  127. package/dist/src/dom/locale/mr.d.ts +2 -1
  128. package/dist/src/dom/locale/mr.js +2 -1
  129. package/dist/src/dom/locale/ms.d.ts +2 -1
  130. package/dist/src/dom/locale/ms.js +2 -1
  131. package/dist/src/dom/locale/my.d.ts +2 -1
  132. package/dist/src/dom/locale/my.js +2 -1
  133. package/dist/src/dom/locale/nb.d.ts +2 -1
  134. package/dist/src/dom/locale/nb.js +2 -1
  135. package/dist/src/dom/locale/nl.d.ts +2 -1
  136. package/dist/src/dom/locale/nl.js +2 -1
  137. package/dist/src/dom/locale/pa.d.ts +2 -1
  138. package/dist/src/dom/locale/pa.js +2 -1
  139. package/dist/src/dom/locale/pl.d.ts +2 -1
  140. package/dist/src/dom/locale/pl.js +2 -1
  141. package/dist/src/dom/locale/pt-BR.d.ts +2 -1
  142. package/dist/src/dom/locale/pt-BR.js +2 -1
  143. package/dist/src/dom/locale/pt-PT.d.ts +2 -1
  144. package/dist/src/dom/locale/pt-PT.js +2 -1
  145. package/dist/src/dom/locale/ro.d.ts +2 -1
  146. package/dist/src/dom/locale/ro.js +2 -1
  147. package/dist/src/dom/locale/ru.d.ts +2 -1
  148. package/dist/src/dom/locale/ru.js +2 -1
  149. package/dist/src/dom/locale/sk.d.ts +2 -1
  150. package/dist/src/dom/locale/sk.js +2 -1
  151. package/dist/src/dom/locale/sl.d.ts +2 -1
  152. package/dist/src/dom/locale/sl.js +2 -1
  153. package/dist/src/dom/locale/so.d.ts +2 -1
  154. package/dist/src/dom/locale/so.js +2 -1
  155. package/dist/src/dom/locale/sq.d.ts +2 -1
  156. package/dist/src/dom/locale/sq.js +2 -1
  157. package/dist/src/dom/locale/sr.d.ts +2 -1
  158. package/dist/src/dom/locale/sr.js +2 -1
  159. package/dist/src/dom/locale/sv.d.ts +2 -1
  160. package/dist/src/dom/locale/sv.js +2 -1
  161. package/dist/src/dom/locale/sw.d.ts +2 -1
  162. package/dist/src/dom/locale/sw.js +2 -1
  163. package/dist/src/dom/locale/ta.d.ts +2 -1
  164. package/dist/src/dom/locale/ta.js +2 -1
  165. package/dist/src/dom/locale/te.d.ts +2 -1
  166. package/dist/src/dom/locale/te.js +2 -1
  167. package/dist/src/dom/locale/th.d.ts +2 -1
  168. package/dist/src/dom/locale/th.js +2 -1
  169. package/dist/src/dom/locale/tl.d.ts +4 -5
  170. package/dist/src/dom/locale/tl.js +4 -5
  171. package/dist/src/dom/locale/tr.d.ts +2 -1
  172. package/dist/src/dom/locale/tr.js +2 -1
  173. package/dist/src/dom/locale/types.d.ts +18 -1
  174. package/dist/src/dom/locale/uk.d.ts +2 -1
  175. package/dist/src/dom/locale/uk.js +2 -1
  176. package/dist/src/dom/locale/ur.d.ts +2 -1
  177. package/dist/src/dom/locale/ur.js +2 -1
  178. package/dist/src/dom/locale/vi.d.ts +2 -1
  179. package/dist/src/dom/locale/vi.js +2 -1
  180. package/dist/src/dom/locale/zh-HK.d.ts +2 -1
  181. package/dist/src/dom/locale/zh-HK.js +4 -3
  182. package/dist/src/dom/locale/zh-Hans.d.ts +2 -1
  183. package/dist/src/dom/locale/zh-Hans.js +2 -1
  184. package/dist/src/dom/locale/zh-TW.d.ts +2 -1
  185. package/dist/src/dom/locale/zh-TW.js +2 -1
  186. package/dist/src/dom/selectors.js +6 -1
  187. package/dist/src/index.d.ts +3 -0
  188. package/dist/src/index.js +3 -0
  189. package/dist/src/runner/responses.d.ts +3 -1
  190. package/dist/src/runner/responses.js +16 -1
  191. package/dist/src/runner/result.js +129 -4
  192. package/dist/src/runner/stream.d.ts +1 -1
  193. package/dist/src/runner/stream.js +6 -0
  194. package/dist/src/runner/types.d.ts +35 -1
  195. package/dist/src/safety/risk.d.ts +10 -0
  196. package/dist/src/safety/risk.js +10 -0
  197. package/dist/src/scripts/apply-intelligence-locale-captures.d.ts +6 -0
  198. package/dist/src/scripts/apply-intelligence-locale-captures.js +53 -7
  199. package/dist/src/scripts/capture-intelligence-locales.d.ts +3 -0
  200. package/dist/src/scripts/capture-intelligence-locales.js +372 -3
  201. package/dist/src/scripts/capture-surface-profile.d.ts +23 -0
  202. package/dist/src/scripts/capture-surface-profile.js +304 -0
  203. package/dist/src/scripts/live-smoke/scenarios.js +34 -1
  204. package/dist/src/scripts/live-smoke.js +1 -0
  205. package/dist/src/types.d.ts +245 -2
  206. package/package.json +3 -2
  207. package/references/2026-07-16-chat-work-surfaces.md +87 -0
  208. package/references/agents-runner.md +13 -2
  209. package/references/backend-protocol.md +15 -5
  210. package/references/language-coverage.md +40 -3
  211. package/references/localization.md +34 -6
  212. package/references/python-parity.md +11 -1
  213. package/references/responses-adapter.md +12 -1
  214. package/references/troubleshooting.md +22 -2
@@ -6,7 +6,7 @@ import type { ChatGPTResponsesCreateArgs } from "../runner/responses.js";
6
6
  import type { ChatGPTRunStream } from "../runner/stream.js";
7
7
  import type { ChatGPTAgent, ChatGPTAgentConfig, ChatGPTResponse, ChatGPTRunInput, ChatGPTRunResult } from "../runner/types.js";
8
8
  import type { ReportRedactionOptions } from "../safety/report-redaction.js";
9
- import type { ArtifactDownloadArgs, ArtifactWaitArgs, BootstrapArgs, CommandResult, CopyResponseArgs, DownloadLatestArgs, ListArtifactsArgs, NewThreadArgs, OpenThreadArgs, ReadLatestArgs, SearchThreadsArgs, SelectToolArgs, SequencePlan, SetModeArgs, WaitArgs } from "../types.js";
9
+ import type { ArtifactDownloadArgs, ArtifactWaitArgs, ApplyConfigurationData, ApplyConfigurationArgs, BootstrapArgs, ChatGPTExperience, CommandResult, ConfigurationInspectionData, CopyResponseArgs, DetectExperienceArgs, DetectExperienceData, DownloadLatestArgs, GetModeArgs, GetModeData, InspectConfigurationArgs, ListArtifactsArgs, MessageStatusArgs, NewThreadArgs, OpenThreadArgs, OpenExperienceData, ReadLatestArgs, ReadWorkLatestArgs, ReadWorkLatestData, SearchThreadsArgs, SelectToolArgs, SequencePlan, SetModeArgs, StartWorkArgs, StartWorkData, SteerWorkArgs, SteerWorkData, WaitArgs, WorkStatusArgs, WorkStatusData, WorkWaitArgs, WorkWaitData } from "../types.js";
10
10
  import { type BackendEvent, type BackendRequest, type BackendResponse } from "./protocol.js";
11
11
  export type BackendTransport = {
12
12
  request(request: BackendRequest): Promise<BackendResponse>;
@@ -60,6 +60,29 @@ export type ChatGPTBackendClient = {
60
60
  session: {
61
61
  bootstrap(args?: BootstrapArgs): Promise<CommandResult<unknown>>;
62
62
  };
63
+ experience: {
64
+ detect(args?: DetectExperienceArgs): Promise<CommandResult<DetectExperienceData>>;
65
+ open(args: {
66
+ experience: Exclude<ChatGPTExperience, "unknown">;
67
+ timeoutMs?: number;
68
+ }): Promise<CommandResult<OpenExperienceData>>;
69
+ };
70
+ configuration: {
71
+ inspect(args?: InspectConfigurationArgs): Promise<CommandResult<ConfigurationInspectionData>>;
72
+ apply(args: ApplyConfigurationArgs): Promise<CommandResult<ApplyConfigurationData>>;
73
+ };
74
+ work: {
75
+ start(args: StartWorkArgs): Promise<CommandResult<StartWorkData>>;
76
+ status(args?: WorkStatusArgs): Promise<CommandResult<WorkStatusData>>;
77
+ wait(args?: WorkWaitArgs): Promise<CommandResult<WorkWaitData>>;
78
+ steer(args: SteerWorkArgs): Promise<CommandResult<SteerWorkData>>;
79
+ readLatest(args?: ReadWorkLatestArgs): Promise<CommandResult<ReadWorkLatestData>>;
80
+ artifacts: {
81
+ listLatest(args?: ListArtifactsArgs): Promise<CommandResult<unknown>>;
82
+ wait(args?: ArtifactWaitArgs): Promise<CommandResult<unknown>>;
83
+ downloadLatest(args: ArtifactDownloadArgs): Promise<CommandResult<unknown>>;
84
+ };
85
+ };
63
86
  threads: {
64
87
  "new"(args?: NewThreadArgs): Promise<CommandResult<unknown>>;
65
88
  search(args: SearchThreadsArgs): Promise<CommandResult<unknown>>;
@@ -84,6 +107,7 @@ export type ChatGPTBackendClient = {
84
107
  }): Promise<CommandResult<unknown>>;
85
108
  wait(args?: WaitArgs): Promise<CommandResult<unknown>>;
86
109
  readLatest(args?: ReadLatestArgs): Promise<CommandResult<unknown>>;
110
+ status(args?: MessageStatusArgs): Promise<CommandResult<unknown>>;
87
111
  waitAndRead(args?: WaitArgs & ReadLatestArgs): Promise<CommandResult<unknown>>;
88
112
  };
89
113
  files: {
@@ -95,6 +119,7 @@ export type ChatGPTBackendClient = {
95
119
  };
96
120
  modes: {
97
121
  set(args: SetModeArgs): Promise<CommandResult<unknown>>;
122
+ get(args?: GetModeArgs): Promise<CommandResult<GetModeData>>;
98
123
  };
99
124
  tools: {
100
125
  select(args: SelectToolArgs): Promise<CommandResult<unknown>>;
@@ -63,6 +63,26 @@ export function createChatGPTBackendClient(transport) {
63
63
  session: {
64
64
  bootstrap: args => request("session.bootstrap", args ?? {})
65
65
  },
66
+ experience: {
67
+ detect: args => request("experience.detect", args ?? {}),
68
+ open: args => request("experience.open", args)
69
+ },
70
+ configuration: {
71
+ inspect: args => request("configuration.inspect", args ?? {}),
72
+ apply: args => request("configuration.apply", args)
73
+ },
74
+ work: {
75
+ start: args => request("work.start", args),
76
+ status: args => request("work.status", args ?? {}),
77
+ wait: args => request("work.wait", args ?? {}),
78
+ steer: args => request("work.steer", args),
79
+ readLatest: args => request("work.readLatest", args ?? {}),
80
+ artifacts: {
81
+ listLatest: args => request("artifacts.listLatest", args ?? {}),
82
+ wait: args => request("artifacts.wait", args ?? {}),
83
+ downloadLatest: args => request("artifacts.downloadLatest", args)
84
+ }
85
+ },
66
86
  threads: {
67
87
  new: args => request("threads.new", args ?? {}),
68
88
  search: args => request("threads.search", args),
@@ -74,6 +94,7 @@ export function createChatGPTBackendClient(transport) {
74
94
  ask: args => request("messages.ask", args),
75
95
  wait: args => request("messages.wait", args ?? {}),
76
96
  readLatest: args => request("messages.readLatest", args ?? {}),
97
+ status: args => request("messages.status", args ?? {}),
77
98
  waitAndRead: args => request("messages.waitAndRead", args)
78
99
  },
79
100
  artifacts: {
@@ -86,7 +107,8 @@ export function createChatGPTBackendClient(transport) {
86
107
  downloadLatest: args => request("files.downloadLatest", args)
87
108
  },
88
109
  modes: {
89
- set: args => request("modes.set", args)
110
+ set: args => request("modes.set", args),
111
+ get: args => request("modes.get", args ?? {})
90
112
  },
91
113
  tools: {
92
114
  select: args => request("tools.select", args)
@@ -1,7 +1,7 @@
1
1
  export declare const BACKEND_REQUEST_SCHEMA_VERSION: "chatgpt.browser_control.backend_request.v1";
2
2
  export declare const BACKEND_RESPONSE_SCHEMA_VERSION: "chatgpt.browser_control.backend_response.v1";
3
3
  export declare const BACKEND_EVENT_SCHEMA_VERSION: "chatgpt.browser_control.backend_event.v1";
4
- export declare const backendCommands: readonly ["backend.version", "backend.health", "backend.capabilities", "runner.run", "runner.plan", "runner.stream", "responses.create", "ask", "askInThread", "askWithFiles", "askAndDownload", "runMessages", "openThread", "readLatest", "copyLatest", "downloadLatest", "runPlan", "doctor", "createReport", "reports.create", "reports.redact", "reports.summarize", "commands", "describe", "help", "session.bootstrap", "threads.new", "threads.search", "threads.open", "messages.compose", "messages.submit", "messages.ask", "messages.wait", "messages.readLatest", "messages.waitAndRead", "artifacts.listLatest", "artifacts.wait", "artifacts.downloadLatest", "files.preflight", "files.attach", "files.downloadLatest", "projects.sources.list", "projects.sources.planAdd", "projects.sources.add", "modes.set", "modes.get", "tools.select", "response.copy"];
4
+ export declare const backendCommands: readonly ["backend.version", "backend.health", "backend.capabilities", "runner.run", "runner.plan", "runner.stream", "responses.create", "ask", "askInThread", "askWithFiles", "askAndDownload", "runMessages", "openThread", "readLatest", "copyLatest", "downloadLatest", "runPlan", "doctor", "createReport", "reports.create", "reports.redact", "reports.summarize", "commands", "describe", "help", "session.bootstrap", "experience.detect", "experience.open", "configuration.inspect", "configuration.apply", "work.start", "work.status", "work.wait", "work.steer", "work.readLatest", "threads.new", "threads.search", "threads.open", "messages.compose", "messages.submit", "messages.ask", "messages.wait", "messages.readLatest", "messages.status", "messages.waitAndRead", "artifacts.listLatest", "artifacts.wait", "artifacts.downloadLatest", "files.preflight", "files.attach", "files.downloadLatest", "projects.sources.list", "projects.sources.planAdd", "projects.sources.add", "modes.set", "modes.get", "tools.select", "response.copy"];
5
5
  export type BackendCommand = typeof backendCommands[number];
6
6
  export type BackendRequest = {
7
7
  schemaVersion: typeof BACKEND_REQUEST_SCHEMA_VERSION;
@@ -28,6 +28,15 @@ export const backendCommands = [
28
28
  "describe",
29
29
  "help",
30
30
  "session.bootstrap",
31
+ "experience.detect",
32
+ "experience.open",
33
+ "configuration.inspect",
34
+ "configuration.apply",
35
+ "work.start",
36
+ "work.status",
37
+ "work.wait",
38
+ "work.steer",
39
+ "work.readLatest",
31
40
  "threads.new",
32
41
  "threads.search",
33
42
  "threads.open",
@@ -36,6 +45,7 @@ export const backendCommands = [
36
45
  "messages.ask",
37
46
  "messages.wait",
38
47
  "messages.readLatest",
48
+ "messages.status",
39
49
  "messages.waitAndRead",
40
50
  "artifacts.listLatest",
41
51
  "artifacts.wait",
@@ -123,6 +123,24 @@ async function dispatchBackendCommand(client, request) {
123
123
  return client.reports.summarize(requiredRecord(payload, "result"), optionalRecord(payload, "args"));
124
124
  case "session.bootstrap":
125
125
  return client.session.bootstrap(emptyToUndefined(payload));
126
+ case "experience.detect":
127
+ return client.experience.detect(emptyToUndefined(payload));
128
+ case "experience.open":
129
+ return client.experience.open(payload);
130
+ case "configuration.inspect":
131
+ return client.configuration.inspect(emptyToUndefined(payload));
132
+ case "configuration.apply":
133
+ return client.configuration.apply(payload);
134
+ case "work.start":
135
+ return client.work.start(payload);
136
+ case "work.status":
137
+ return client.work.status(emptyToUndefined(payload));
138
+ case "work.wait":
139
+ return client.work.wait(emptyToUndefined(payload));
140
+ case "work.steer":
141
+ return client.work.steer(payload);
142
+ case "work.readLatest":
143
+ return client.work.readLatest(emptyToUndefined(payload));
126
144
  case "threads.new":
127
145
  return client.threads.new(emptyToUndefined(payload));
128
146
  case "threads.search":
@@ -139,6 +157,8 @@ async function dispatchBackendCommand(client, request) {
139
157
  return client.messages.wait(emptyToUndefined(payload));
140
158
  case "messages.readLatest":
141
159
  return client.messages.readLatest(emptyToUndefined(payload));
160
+ case "messages.status":
161
+ return client.messages.status(emptyToUndefined(payload));
142
162
  case "messages.waitAndRead":
143
163
  return client.messages.waitAndRead(payload);
144
164
  case "artifacts.listLatest":
@@ -6,3 +6,4 @@ export type AttachedBrowser = {
6
6
  tabId?: string;
7
7
  };
8
8
  export declare function attachChatGPTBrowser(env: RuntimeEnv, args?: BootstrapArgs): Promise<AttachedBrowser>;
9
+ export declare function tabIdFromPage(page: PageLike): string | undefined;
@@ -16,7 +16,7 @@ export async function attachChatGPTBrowser(env, args = {}) {
16
16
  page,
17
17
  browserName: browser.name ?? "chrome"
18
18
  };
19
- const tabId = getTabId(page);
19
+ const tabId = tabIdFromPage(page);
20
20
  if (tabId !== undefined) {
21
21
  attached.tabId = tabId;
22
22
  }
@@ -332,7 +332,7 @@ function mismatchReasonForNoMatches(policy, tabs, chatgptTabs) {
332
332
  async function pageMatchesExistingTarget(page, policy) {
333
333
  const url = await Promise.resolve(page.url?.()).catch(() => undefined);
334
334
  const title = await Promise.resolve(page.title?.()).catch(() => undefined);
335
- const tab = { id: getTabId(page) ?? "" };
335
+ const tab = { id: tabIdFromPage(page) ?? "" };
336
336
  if (url !== undefined)
337
337
  tab.url = url;
338
338
  if (title !== undefined)
@@ -557,7 +557,7 @@ function normalizePage(pageOrTab) {
557
557
  }
558
558
  return pageOrTab;
559
559
  }
560
- function getTabId(page) {
560
+ export function tabIdFromPage(page) {
561
561
  const maybe = page;
562
562
  const id = maybe.id ?? maybe.tabId;
563
563
  return typeof id === "string" ? id : undefined;
@@ -22,8 +22,11 @@ export async function readPageState(page) {
22
22
  const rawTitle = typeof page.title === "function" ? await page.title().catch(() => undefined) : undefined;
23
23
  const title = typeof rawTitle === "string" ? rawTitle : undefined;
24
24
  const visibleText = await readVisibleText(page);
25
- const blocker = classifyVisibleText(visibleText);
26
- const signedIn = isLikelySignedIn(visibleText) && blocker?.kind !== "login_required";
25
+ const signedIn = isLikelySignedIn(visibleText);
26
+ const classifiedBlocker = classifyVisibleText(visibleText);
27
+ const blocker = classifiedBlocker?.kind === "login_required" && signedIn
28
+ ? undefined
29
+ : classifiedBlocker;
27
30
  const conversationId = parseConversationId(url);
28
31
  const state = {
29
32
  url,
@@ -1,4 +1,4 @@
1
- import type { AskArgs, ArtifactDownloadArgs, ArtifactWaitArgs, AttachFilesArgs, BootstrapArgs, CommandResult, CopyResponseArgs, DownloadLatestArgs, FilePreflightArgs, FilePreflightData, GetModeArgs, GetModeData, ListArtifactsArgs, NewThreadArgs, OpenThreadArgs, ProjectSourcesAddArgs, ProjectSourcesAddData, ProjectSourcesAddPlanData, ProjectSourcesListArgs, ProjectSourcesListData, ProjectSourcesPlanAddArgs, ReadLatestArgs, RuntimeEnv, SearchThreadsArgs, SelectToolArgs, SequencePlan, SetModeArgs, ThreadTarget, WaitArgs } from "./types.js";
1
+ import type { AskArgs, ArtifactDownloadArgs, ArtifactWaitArgs, ApplyConfigurationData, ApplyConfigurationArgs, AttachFilesArgs, BootstrapArgs, ChatGPTExperience, CommandResult, ConfigurationInspectionData, ConfigurationSelection, CopyResponseArgs, DetectExperienceArgs, DetectExperienceData, DownloadLatestArgs, FilePreflightArgs, FilePreflightData, GetModeArgs, GetModeData, InspectConfigurationArgs, ListArtifactsArgs, MessageStatusArgs, NewThreadArgs, OpenThreadArgs, OpenExperienceData, ProjectSourcesAddArgs, ProjectSourcesAddData, ProjectSourcesAddPlanData, ProjectSourcesListArgs, ProjectSourcesListData, ProjectSourcesPlanAddArgs, ReadLatestArgs, RuntimeEnv, ReadWorkLatestArgs, ReadWorkLatestData, SearchThreadsArgs, SelectToolArgs, SequencePlan, SetModeArgs, StartWorkArgs, StartWorkData, SteerWorkArgs, SteerWorkData, ThreadTarget, WaitArgs, WorkStatusArgs, WorkStatusData, WorkWaitArgs, WorkWaitData } from "./types.js";
2
2
  import { type DoctorArgs, type DoctorReport } from "./commands/doctor.js";
3
3
  import { type RunReportData, type RunReportOptions } from "./commands/reports.js";
4
4
  import { type CommandDescriptor } from "./commands/registry.js";
@@ -8,6 +8,8 @@ import { type ReportRedactionOptions } from "./safety/report-redaction.js";
8
8
  import { type BlockerExplanation, type ExplainBlockerOptions } from "./diagnostics/blockers.js";
9
9
  export type ChatGPTClientOptions = RuntimeEnv & {
10
10
  defaults?: {
11
+ experience?: Exclude<ChatGPTExperience, "unknown">;
12
+ configuration?: ConfigurationSelection;
11
13
  mode?: SetModeArgs;
12
14
  wait?: boolean | WaitArgs;
13
15
  read?: boolean | ReadLatestArgs;
@@ -59,6 +61,8 @@ export type AskWorkflowArgs = {
59
61
  thread?: WorkflowThread;
60
62
  existingTab?: BootstrapArgs["existingTab"];
61
63
  preferExistingTab?: boolean;
64
+ experience?: Exclude<ChatGPTExperience, "unknown">;
65
+ configuration?: ConfigurationSelection;
62
66
  mode?: SetModeArgs;
63
67
  tools?: SelectToolArgs[];
64
68
  files?: FileInput[];
@@ -83,6 +87,8 @@ export type RunMessagesArgs = {
83
87
  thread?: WorkflowThread;
84
88
  existingTab?: BootstrapArgs["existingTab"];
85
89
  preferExistingTab?: boolean;
90
+ experience?: Exclude<ChatGPTExperience, "unknown">;
91
+ configuration?: ConfigurationSelection;
86
92
  mode?: SetModeArgs;
87
93
  messages: Array<{
88
94
  id?: string;
@@ -136,6 +142,29 @@ export type ChatGPTClient = {
136
142
  session: {
137
143
  bootstrap(args?: BootstrapArgs): Promise<CommandResult<unknown>>;
138
144
  };
145
+ experience: {
146
+ detect(args?: DetectExperienceArgs): Promise<CommandResult<DetectExperienceData>>;
147
+ open(args: {
148
+ experience: Exclude<ChatGPTExperience, "unknown">;
149
+ timeoutMs?: number;
150
+ }): Promise<CommandResult<OpenExperienceData>>;
151
+ };
152
+ configuration: {
153
+ inspect(args?: InspectConfigurationArgs): Promise<CommandResult<ConfigurationInspectionData>>;
154
+ apply(args: ApplyConfigurationArgs): Promise<CommandResult<ApplyConfigurationData>>;
155
+ };
156
+ work: {
157
+ start(args: StartWorkArgs): Promise<CommandResult<StartWorkData>>;
158
+ status(args?: WorkStatusArgs): Promise<CommandResult<WorkStatusData>>;
159
+ wait(args?: WorkWaitArgs): Promise<CommandResult<WorkWaitData>>;
160
+ steer(args: SteerWorkArgs): Promise<CommandResult<SteerWorkData>>;
161
+ readLatest(args?: ReadWorkLatestArgs): Promise<CommandResult<ReadWorkLatestData>>;
162
+ artifacts: {
163
+ listLatest(args?: ListArtifactsArgs): Promise<CommandResult<unknown>>;
164
+ wait(args?: ArtifactWaitArgs): Promise<CommandResult<unknown>>;
165
+ downloadLatest(args: ArtifactDownloadArgs): Promise<CommandResult<unknown>>;
166
+ };
167
+ };
139
168
  threads: {
140
169
  "new"(args?: NewThreadArgs): Promise<CommandResult<unknown>>;
141
170
  search(args: SearchThreadsArgs): Promise<CommandResult<unknown>>;
@@ -155,6 +184,7 @@ export type ChatGPTClient = {
155
184
  ask(args: AskArgs): Promise<CommandResult<unknown>>;
156
185
  wait(args?: WaitArgs): Promise<CommandResult<unknown>>;
157
186
  readLatest(args?: ReadLatestArgs): Promise<CommandResult<unknown>>;
187
+ status(args?: MessageStatusArgs): Promise<CommandResult<unknown>>;
158
188
  waitAndRead(args?: WaitArgs & ReadLatestArgs): Promise<CommandResult<unknown>>;
159
189
  };
160
190
  files: {
@@ -2,14 +2,17 @@ import { downloadLatestArtifact, listLatestArtifacts, waitForArtifact } from "./
2
2
  import { attachFiles, downloadLatestFile, preflightFiles } from "./commands/files.js";
3
3
  import { addProjectSources, buildProjectSourceAddPlan, listProjectSources } from "./commands/project-sources.js";
4
4
  import { doctor } from "./commands/doctor.js";
5
- import { askMessage, composeMessage, readLatest, submitMessage, waitAndRead, waitForMessage } from "./commands/messages.js";
5
+ import { askMessage, composeMessage, messageStatus, readLatest, submitMessage, waitAndRead, waitForMessage } from "./commands/messages.js";
6
6
  import { getMode, selectTool, setMode } from "./commands/modes.js";
7
+ import { applyConfiguration, inspectConfiguration } from "./commands/configuration.js";
8
+ import { detectExperience, openExperience } from "./commands/experience.js";
7
9
  import { createRunReport } from "./commands/reports.js";
8
10
  import { copyResponse } from "./commands/response-actions.js";
9
11
  import { commandDescriptors, describeCommand, helpText } from "./commands/registry.js";
10
12
  import { runSequence } from "./commands/sequence.js";
11
13
  import { bootstrap } from "./commands/session.js";
12
14
  import { newThread, openThread, searchThreads } from "./commands/threads.js";
15
+ import { readLatestWork, startWork, steerWork, waitForWork, workStatus } from "./commands/work.js";
13
16
  import { resultError, resultOk } from "./errors.js";
14
17
  import { createChatGPTAgent } from "./runner/agent.js";
15
18
  import { toRunResult } from "./runner/result.js";
@@ -60,6 +63,26 @@ export function createChatGPT(options = {}) {
60
63
  session: {
61
64
  bootstrap: args => bootstrap(env, args)
62
65
  },
66
+ experience: {
67
+ detect: args => detectExperience(env, args),
68
+ open: args => openExperience(env, args)
69
+ },
70
+ configuration: {
71
+ inspect: args => inspectConfiguration(env, args),
72
+ apply: args => applyConfiguration(env, args)
73
+ },
74
+ work: {
75
+ start: args => startWork(env, args),
76
+ status: args => workStatus(env, args),
77
+ wait: args => waitForWork(env, args),
78
+ steer: args => steerWork(env, args),
79
+ readLatest: args => readLatestWork(env, args),
80
+ artifacts: {
81
+ listLatest: args => listLatestArtifacts(env, args),
82
+ wait: args => waitForArtifact(env, args),
83
+ downloadLatest: args => downloadLatestArtifact(env, args)
84
+ }
85
+ },
63
86
  threads: {
64
87
  new: args => newThread(env, args),
65
88
  search: args => searchThreads(env, args),
@@ -71,6 +94,7 @@ export function createChatGPT(options = {}) {
71
94
  ask: args => askMessage(env, args),
72
95
  wait: args => waitForMessage(env, args),
73
96
  readLatest: args => readLatest(env, args),
97
+ status: args => messageStatus(env, args),
74
98
  waitAndRead: args => waitAndRead(env, args)
75
99
  },
76
100
  files: {
@@ -166,6 +190,30 @@ function pathsFromAttachStep(step) {
166
190
  const paths = step.args.paths;
167
191
  return paths.every(item => typeof item === "string") ? paths : [];
168
192
  }
193
+ function appendSurfaceConfigurationSteps(steps, preferences) {
194
+ if (preferences.experience !== undefined) {
195
+ steps.push({
196
+ id: "experience",
197
+ command: "experience.open",
198
+ args: { experience: preferences.experience }
199
+ });
200
+ }
201
+ if (preferences.configuration !== undefined) {
202
+ steps.push({
203
+ id: "configuration",
204
+ command: "configuration.apply",
205
+ args: {
206
+ ...(preferences.experience === undefined ? {} : { experience: preferences.experience }),
207
+ desired: preferences.configuration,
208
+ strict: true
209
+ }
210
+ });
211
+ return;
212
+ }
213
+ if (preferences.mode !== undefined) {
214
+ steps.push({ id: "mode", command: "modes.set", args: preferences.mode });
215
+ }
216
+ }
169
217
  function normalizeLimits(limits) {
170
218
  return {
171
219
  maxPromptsPerRun: limits?.maxPromptsPerRun ?? 5,
@@ -178,7 +226,7 @@ function normalizeLimits(limits) {
178
226
  function checkRunBudget(plan, limits) {
179
227
  const prompts = plan.steps.filter(step => step.command === "messages.ask" || step.command === "messages.submit").length;
180
228
  const threads = plan.steps.filter(step => step.command === "threads.new" || step.command === "threads.open").length;
181
- const reads = plan.steps.filter(step => step.command === "messages.readLatest" || step.command === "messages.waitAndRead" || step.command === "response.copy").length
229
+ const reads = plan.steps.filter(step => step.command === "messages.readLatest" || step.command === "messages.status" || step.command === "messages.waitAndRead" || step.command === "response.copy").length
182
230
  + plan.steps.filter(step => step.command === "messages.ask" && askStepReads(step.args)).length;
183
231
  const violations = [];
184
232
  if (prompts > limits.maxPromptsPerRun)
@@ -270,10 +318,11 @@ function planAgentWorkflowFromNormalized(agent, input, defaults = {}) {
270
318
  bootstrapStepForWorkflow(thread, input.existingTab ?? agent.defaults.existingTab ?? defaults.existingTab, input.preferExistingTab ?? agent.defaults.preferExistingTab ?? defaults.preferExistingTab),
271
319
  ...threadSteps(thread)
272
320
  ];
273
- const mode = input.mode ?? agent.defaults.mode ?? defaults.mode;
274
- if (mode !== undefined) {
275
- steps.push({ id: "mode", command: "modes.set", args: mode });
276
- }
321
+ appendSurfaceConfigurationSteps(steps, {
322
+ experience: input.experience ?? agent.defaults.experience ?? defaults.experience,
323
+ configuration: input.configuration ?? agent.defaults.configuration ?? defaults.configuration,
324
+ mode: input.mode ?? agent.defaults.mode ?? defaults.mode
325
+ });
277
326
  for (const [index, tool] of input.tools.entries()) {
278
327
  steps.push({ id: `tool${index + 1}`, command: "tools.select", args: tool });
279
328
  }
@@ -338,6 +387,10 @@ function normalizeRunnerInput(agent, input) {
338
387
  normalized.existingTab = args.existingTab;
339
388
  if (args.preferExistingTab !== undefined)
340
389
  normalized.preferExistingTab = args.preferExistingTab;
390
+ if (args.experience !== undefined)
391
+ normalized.experience = args.experience;
392
+ if (args.configuration !== undefined)
393
+ normalized.configuration = args.configuration;
341
394
  if (mode !== undefined)
342
395
  normalized.mode = mode;
343
396
  if (args.response !== undefined)
@@ -458,10 +511,11 @@ function planAskWorkflow(args, defaults = {}) {
458
511
  bootstrapStepForWorkflow(thread, args.existingTab ?? defaults.existingTab, args.preferExistingTab ?? defaults.preferExistingTab),
459
512
  ...threadSteps(thread)
460
513
  ];
461
- const mode = args.mode ?? defaults.mode;
462
- if (mode !== undefined) {
463
- steps.push({ id: "mode", command: "modes.set", args: mode });
464
- }
514
+ appendSurfaceConfigurationSteps(steps, {
515
+ experience: args.experience ?? defaults.experience,
516
+ configuration: args.configuration ?? defaults.configuration,
517
+ mode: args.mode ?? defaults.mode
518
+ });
465
519
  for (const [index, tool] of (args.tools ?? []).entries()) {
466
520
  steps.push({ id: `tool${index + 1}`, command: "tools.select", args: tool });
467
521
  }
@@ -529,10 +583,11 @@ function planRunMessages(args, defaults = {}) {
529
583
  bootstrapStepForWorkflow(thread, args.existingTab ?? defaults.existingTab, args.preferExistingTab ?? defaults.preferExistingTab),
530
584
  ...threadSteps(thread)
531
585
  ];
532
- const mode = args.mode ?? defaults.mode;
533
- if (mode !== undefined) {
534
- steps.push({ id: "mode", command: "modes.set", args: mode });
535
- }
586
+ appendSurfaceConfigurationSteps(steps, {
587
+ experience: args.experience ?? defaults.experience,
588
+ configuration: args.configuration ?? defaults.configuration,
589
+ mode: args.mode ?? defaults.mode
590
+ });
536
591
  args.messages.forEach((message, index) => {
537
592
  steps.push({
538
593
  id: message.id ?? `message${index + 1}`,
@@ -7,7 +7,7 @@ import { cssSelectors, requiredLocator } from "../dom/selectors.js";
7
7
  import { localeLabels } from "../dom/locale-labels.js";
8
8
  import { resultOk } from "../errors.js";
9
9
  import { contextFromPage } from "./context.js";
10
- import { bootstrap } from "./session.js";
10
+ import { ensurePage } from "./session.js";
11
11
  import { localGuardTimeout, withTimeout } from "./timeouts.js";
12
12
  export async function listLatestArtifacts(env, args = {}) {
13
13
  const boot = await ensurePage(env);
@@ -408,12 +408,6 @@ function artifactDownloadBlocker(error, context) {
408
408
  context
409
409
  };
410
410
  }
411
- async function ensurePage(env) {
412
- if (env.page !== undefined) {
413
- return resultOk({}, await contextFromPage(env.page));
414
- }
415
- return bootstrap(env, { preferExistingTab: true });
416
- }
417
411
  async function hasStopControl(page, timeoutMs) {
418
412
  if (typeof page.evaluate !== "function")
419
413
  return false;
@@ -0,0 +1,15 @@
1
+ import { type MenuItem } from "../dom/menus.js";
2
+ import type { ApplyConfigurationArgs, ApplyConfigurationData, ChatGPTExperience, CommandResult, ConfigurationAxis, ConfigurationInspectionData, ConfigurationSelection, InspectConfigurationArgs, RuntimeEnv, SurfaceSelectorProfile } from "../types.js";
3
+ export type ConfigurationPanelSnapshot = {
4
+ openerLabel?: string;
5
+ axisRows: Array<{
6
+ axis: ConfigurationAxis;
7
+ label: string;
8
+ value?: string;
9
+ }>;
10
+ advancedVisible: boolean;
11
+ };
12
+ export declare function inspectConfiguration(env: RuntimeEnv, args?: InspectConfigurationArgs): Promise<CommandResult<ConfigurationInspectionData>>;
13
+ export declare function applyConfiguration(env: RuntimeEnv, args: ApplyConfigurationArgs): Promise<CommandResult<ApplyConfigurationData>>;
14
+ export declare function configurationInspectionFromSurface(experience: ChatGPTExperience, detectedProfile: SurfaceSelectorProfile, evidence: ConfigurationInspectionData["evidence"], panel: ConfigurationPanelSnapshot, menuItems: MenuItem[]): ConfigurationInspectionData;
15
+ export declare function configurationMatchesSelection(inspection: ConfigurationInspectionData, desired: ConfigurationSelection): boolean;