cueline 0.1.6 → 0.2.0

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 (188) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +50 -0
  4. package/README.ja.md +77 -30
  5. package/README.ko.md +77 -30
  6. package/README.md +71 -29
  7. package/README.zh-CN.md +77 -30
  8. package/README.zh-TW.md +74 -29
  9. package/config/routing.schema.json +3 -0
  10. package/dist/src/api-caller-work.js +58 -14
  11. package/dist/src/api-caller-work.js.map +1 -1
  12. package/dist/src/api-contracts.d.ts +56 -0
  13. package/dist/src/api-controller-handoff.d.ts +5 -1
  14. package/dist/src/api-controller-handoff.js +178 -38
  15. package/dist/src/api-controller-handoff.js.map +1 -1
  16. package/dist/src/api-run-verification.d.ts +3 -0
  17. package/dist/src/api-run-verification.js +174 -0
  18. package/dist/src/api-run-verification.js.map +1 -0
  19. package/dist/src/api-runtime-lifecycle.d.ts +6 -1
  20. package/dist/src/api-runtime-lifecycle.js +97 -8
  21. package/dist/src/api-runtime-lifecycle.js.map +1 -1
  22. package/dist/src/api.d.ts +26 -4
  23. package/dist/src/api.js +111 -40
  24. package/dist/src/api.js.map +1 -1
  25. package/dist/src/browser/browser-adapter.d.ts +41 -0
  26. package/dist/src/browser/codex-iab/bootstrap.d.ts +21 -0
  27. package/dist/src/browser/codex-iab/bootstrap.js +174 -9
  28. package/dist/src/browser/codex-iab/bootstrap.js.map +1 -1
  29. package/dist/src/browser/codex-iab/chatgpt-client.d.ts +3 -0
  30. package/dist/src/browser/codex-iab/chatgpt-client.js +216 -70
  31. package/dist/src/browser/codex-iab/chatgpt-client.js.map +1 -1
  32. package/dist/src/browser/codex-iab/probe.d.ts +36 -0
  33. package/dist/src/browser/codex-iab/probe.js +217 -0
  34. package/dist/src/browser/codex-iab/probe.js.map +1 -0
  35. package/dist/src/browser/codex-iab/recovery-evidence.d.ts +1 -1
  36. package/dist/src/browser/codex-iab/recovery-evidence.js +7 -10
  37. package/dist/src/browser/codex-iab/recovery-evidence.js.map +1 -1
  38. package/dist/src/browser/codex-iab/selectors.d.ts +1 -0
  39. package/dist/src/browser/codex-iab/selectors.js +1 -0
  40. package/dist/src/browser/codex-iab/selectors.js.map +1 -1
  41. package/dist/src/browser/codex-iab/send-button.d.ts +5 -0
  42. package/dist/src/browser/codex-iab/send-button.js +62 -0
  43. package/dist/src/browser/codex-iab/send-button.js.map +1 -0
  44. package/dist/src/browser/codex-iab/submission-url.js +6 -15
  45. package/dist/src/browser/codex-iab/submission-url.js.map +1 -1
  46. package/dist/src/browser/codex-iab/tab-discovery.js +45 -12
  47. package/dist/src/browser/codex-iab/tab-discovery.js.map +1 -1
  48. package/dist/src/browser/codex-iab/timing-options.d.ts +1 -0
  49. package/dist/src/browser/codex-iab/timing-options.js +5 -0
  50. package/dist/src/browser/codex-iab/timing-options.js.map +1 -0
  51. package/dist/src/cli/health-commands.d.ts +2 -0
  52. package/dist/src/cli/health-commands.js +265 -0
  53. package/dist/src/cli/health-commands.js.map +1 -0
  54. package/dist/src/cli/io.d.ts +4 -0
  55. package/dist/src/cli/io.js +2 -0
  56. package/dist/src/cli/io.js.map +1 -0
  57. package/dist/src/cli/main.d.ts +1 -5
  58. package/dist/src/cli/main.js +187 -84
  59. package/dist/src/cli/main.js.map +1 -1
  60. package/dist/src/cli/observation-commands.d.ts +2 -0
  61. package/dist/src/cli/observation-commands.js +350 -0
  62. package/dist/src/cli/observation-commands.js.map +1 -0
  63. package/dist/src/cli/run-status-view.d.ts +87 -0
  64. package/dist/src/cli/run-status-view.js +121 -0
  65. package/dist/src/cli/run-status-view.js.map +1 -0
  66. package/dist/src/core/controller-command-execution.d.ts +2 -2
  67. package/dist/src/core/controller-command-execution.js +82 -16
  68. package/dist/src/core/controller-command-execution.js.map +1 -1
  69. package/dist/src/core/controller-conversation-archive.d.ts +11 -0
  70. package/dist/src/core/controller-conversation-archive.js +109 -0
  71. package/dist/src/core/controller-conversation-archive.js.map +1 -0
  72. package/dist/src/core/controller-loop.d.ts +7 -1
  73. package/dist/src/core/controller-loop.js +136 -23
  74. package/dist/src/core/controller-loop.js.map +1 -1
  75. package/dist/src/core/controller-turn.d.ts +21 -3
  76. package/dist/src/core/controller-turn.js +182 -41
  77. package/dist/src/core/controller-turn.js.map +1 -1
  78. package/dist/src/core/controller-types.d.ts +2 -0
  79. package/dist/src/core/conversation-url.d.ts +3 -0
  80. package/dist/src/core/conversation-url.js +34 -0
  81. package/dist/src/core/conversation-url.js.map +1 -0
  82. package/dist/src/core/run-status.d.ts +17 -2
  83. package/dist/src/core/run-status.js +64 -25
  84. package/dist/src/core/run-status.js.map +1 -1
  85. package/dist/src/core/state-machine.d.ts +36 -1
  86. package/dist/src/core/state-machine.js +242 -13
  87. package/dist/src/core/state-machine.js.map +1 -1
  88. package/dist/src/core/timing.d.ts +9 -0
  89. package/dist/src/core/timing.js +22 -0
  90. package/dist/src/core/timing.js.map +1 -0
  91. package/dist/src/diagnostics/run-doctor.d.ts +22 -0
  92. package/dist/src/diagnostics/run-doctor.js +197 -0
  93. package/dist/src/diagnostics/run-doctor.js.map +1 -0
  94. package/dist/src/jobs/status.d.ts +5 -2
  95. package/dist/src/jobs/status.js +172 -12
  96. package/dist/src/jobs/status.js.map +1 -1
  97. package/dist/src/jobs/supervisor.js +57 -8
  98. package/dist/src/jobs/supervisor.js.map +1 -1
  99. package/dist/src/observation/run-diff.d.ts +39 -0
  100. package/dist/src/observation/run-diff.js +67 -0
  101. package/dist/src/observation/run-diff.js.map +1 -0
  102. package/dist/src/observation/run-graph.d.ts +17 -0
  103. package/dist/src/observation/run-graph.js +77 -0
  104. package/dist/src/observation/run-graph.js.map +1 -0
  105. package/dist/src/observation/run-handoff.d.ts +86 -0
  106. package/dist/src/observation/run-handoff.js +309 -0
  107. package/dist/src/observation/run-handoff.js.map +1 -0
  108. package/dist/src/observation/run-status-at.d.ts +41 -0
  109. package/dist/src/observation/run-status-at.js +65 -0
  110. package/dist/src/observation/run-status-at.js.map +1 -0
  111. package/dist/src/observation/run-timeline.d.ts +32 -0
  112. package/dist/src/observation/run-timeline.js +279 -0
  113. package/dist/src/observation/run-timeline.js.map +1 -0
  114. package/dist/src/observation/run-watch.d.ts +15 -0
  115. package/dist/src/observation/run-watch.js +82 -0
  116. package/dist/src/observation/run-watch.js.map +1 -0
  117. package/dist/src/protocol/limits.d.ts +3 -0
  118. package/dist/src/protocol/limits.js +4 -0
  119. package/dist/src/protocol/limits.js.map +1 -0
  120. package/dist/src/protocol/lint-command.d.ts +24 -0
  121. package/dist/src/protocol/lint-command.js +210 -0
  122. package/dist/src/protocol/lint-command.js.map +1 -0
  123. package/dist/src/protocol/parse-command.js +4 -0
  124. package/dist/src/protocol/parse-command.js.map +1 -1
  125. package/dist/src/protocol/types.d.ts +12 -0
  126. package/dist/src/protocol/validate-command.js +76 -3
  127. package/dist/src/protocol/validate-command.js.map +1 -1
  128. package/dist/src/router/config-loader.js +23 -2
  129. package/dist/src/router/config-loader.js.map +1 -1
  130. package/dist/src/router/explain.d.ts +28 -0
  131. package/dist/src/router/explain.js +86 -0
  132. package/dist/src/router/explain.js.map +1 -0
  133. package/dist/src/router/resolver.d.ts +2 -1
  134. package/dist/src/router/resolver.js +11 -6
  135. package/dist/src/router/resolver.js.map +1 -1
  136. package/dist/src/runners/process-runner.js +55 -12
  137. package/dist/src/runners/process-runner.js.map +1 -1
  138. package/dist/src/runners/runner-adapter.d.ts +2 -0
  139. package/dist/src/runners/runner-adapter.js.map +1 -1
  140. package/dist/src/state/atomic-write.d.ts +6 -0
  141. package/dist/src/state/atomic-write.js +43 -2
  142. package/dist/src/state/atomic-write.js.map +1 -1
  143. package/dist/src/state/cancellation.js +38 -4
  144. package/dist/src/state/cancellation.js.map +1 -1
  145. package/dist/src/state/event-log.js +5 -4
  146. package/dist/src/state/event-log.js.map +1 -1
  147. package/dist/src/state/private-directory.d.ts +5 -0
  148. package/dist/src/state/private-directory.js +37 -0
  149. package/dist/src/state/private-directory.js.map +1 -0
  150. package/dist/src/state/runtime-lease.js +19 -39
  151. package/dist/src/state/runtime-lease.js.map +1 -1
  152. package/dist/src/state/runtime-record-validation.d.ts +6 -0
  153. package/dist/src/state/runtime-record-validation.js +44 -0
  154. package/dist/src/state/runtime-record-validation.js.map +1 -0
  155. package/dist/src/state/runtime-retirement.js +58 -18
  156. package/dist/src/state/runtime-retirement.js.map +1 -1
  157. package/dist/src/state/runtime-takeover-intent.js +2 -2
  158. package/dist/src/state/runtime-takeover-intent.js.map +1 -1
  159. package/dist/src/state/store.d.ts +1 -0
  160. package/dist/src/state/store.js +12 -6
  161. package/dist/src/state/store.js.map +1 -1
  162. package/dist/src/version.d.ts +1 -1
  163. package/dist/src/version.js +1 -1
  164. package/docs/architecture.md +4 -4
  165. package/docs/assets/README.md +3 -1
  166. package/docs/assets/cueline-architecture-en.svg +63 -0
  167. package/docs/assets/cueline-architecture-ja.svg +63 -0
  168. package/docs/assets/cueline-architecture-ko.svg +63 -0
  169. package/docs/assets/cueline-architecture-zh-CN.svg +63 -0
  170. package/docs/assets/cueline-architecture-zh-TW.svg +63 -0
  171. package/docs/assets/cueline-states-en.svg +50 -0
  172. package/docs/assets/cueline-states-ja.svg +48 -0
  173. package/docs/assets/cueline-states-ko.svg +48 -0
  174. package/docs/assets/cueline-states-zh-CN.svg +48 -0
  175. package/docs/assets/cueline-states-zh-TW.svg +48 -0
  176. package/docs/compatibility.md +1 -1
  177. package/docs/controller-protocol.md +44 -7
  178. package/docs/experiments/protocol-lint.md +40 -0
  179. package/docs/experiments/run-doctor.md +39 -0
  180. package/docs/experiments/run-handoff.md +39 -0
  181. package/docs/experiments/run-timeline.md +35 -0
  182. package/docs/experiments/run-watch.md +31 -0
  183. package/docs/multi-model-routing.md +256 -0
  184. package/docs/runner-contract.md +4 -3
  185. package/docs/state-and-recovery.md +45 -5
  186. package/package.json +1 -1
  187. package/schemas/controller-command.schema.json +89 -4
  188. package/skills/cueline/SKILL.md +13 -7
@@ -0,0 +1,217 @@
1
+ import { isExactChatGptConversationUrl as isConversationUrl, normalizedConversationUrl, sameChatGptConversationUrl, } from "../../core/conversation-url.js";
2
+ import { CueLineError } from "../../core/errors.js";
3
+ import { readPageProbeState, resolveIabBrowser, } from "./bootstrap.js";
4
+ import { isProLabel, isProModelSlug, } from "./recovery-evidence.js";
5
+ import { CHATGPT_URL } from "./selectors.js";
6
+ function isChatGptUrl(value) {
7
+ try {
8
+ const parsed = new URL(value);
9
+ return (parsed.protocol === "https:" &&
10
+ parsed.hostname === new URL(CHATGPT_URL).hostname &&
11
+ parsed.username === "" &&
12
+ parsed.password === "" &&
13
+ parsed.port === "");
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ function matchesTarget(url, target) {
20
+ if (target === undefined)
21
+ return isChatGptUrl(url);
22
+ return sameChatGptConversationUrl(url, target);
23
+ }
24
+ function uniqueCandidates(candidates, target) {
25
+ const seen = new Set();
26
+ return candidates.filter((candidate) => {
27
+ const url = String(candidate.url ?? "");
28
+ if (!matchesTarget(url, target))
29
+ return false;
30
+ const normalized = normalizedConversationUrl(url);
31
+ const key = isConversationUrl(normalized) ? normalized : candidate.id ?? normalized;
32
+ if (seen.has(key))
33
+ return false;
34
+ seen.add(key);
35
+ return true;
36
+ });
37
+ }
38
+ async function existingTab(browser, target) {
39
+ let attachFailed = false;
40
+ try {
41
+ const selected = await browser.tabs.selected?.();
42
+ if (selected && matchesTarget((await selected.url()) ?? "", target)) {
43
+ return { status: "ready", tab: selected, source: "selected" };
44
+ }
45
+ }
46
+ catch {
47
+ attachFailed = true;
48
+ }
49
+ let sessionCandidates = [];
50
+ try {
51
+ sessionCandidates = uniqueCandidates((await browser.tabs.list?.()) ?? [], target);
52
+ }
53
+ catch {
54
+ attachFailed = true;
55
+ }
56
+ let userCandidates = [];
57
+ try {
58
+ userCandidates = uniqueCandidates((await browser.user?.openTabs?.()) ?? [], target);
59
+ }
60
+ catch {
61
+ attachFailed = true;
62
+ }
63
+ const bySurfaceKey = new Map();
64
+ const addCandidate = (candidate, surface) => {
65
+ const url = normalizedConversationUrl(String(candidate.url ?? ""));
66
+ const key = isConversationUrl(url) ? url : candidate.id ?? url;
67
+ const existing = bySurfaceKey.get(key) ?? {};
68
+ existing[surface] = candidate;
69
+ bySurfaceKey.set(key, existing);
70
+ };
71
+ for (const candidate of sessionCandidates)
72
+ addCandidate(candidate, "session");
73
+ for (const candidate of userCandidates)
74
+ addCandidate(candidate, "user");
75
+ if (bySurfaceKey.size > 1)
76
+ return { status: "ambiguous" };
77
+ const only = bySurfaceKey.values().next().value;
78
+ if (only?.session !== undefined) {
79
+ const candidate = only.session;
80
+ if (candidate.id === undefined || browser.tabs.get === undefined) {
81
+ return { status: "attach_failed" };
82
+ }
83
+ try {
84
+ const tab = await browser.tabs.get(candidate.id);
85
+ if (!matchesTarget((await tab.url()) ?? "", target))
86
+ return { status: "attach_failed" };
87
+ return { status: "ready", tab, source: "session" };
88
+ }
89
+ catch {
90
+ return { status: "attach_failed" };
91
+ }
92
+ }
93
+ if (only?.user !== undefined) {
94
+ if (browser.user?.claimTab === undefined)
95
+ return { status: "attach_failed" };
96
+ try {
97
+ const tab = await browser.user.claimTab(only.user);
98
+ if (!matchesTarget((await tab.url()) ?? "", target))
99
+ return { status: "attach_failed" };
100
+ return { status: "ready", tab, source: "user" };
101
+ }
102
+ catch {
103
+ return { status: "attach_failed" };
104
+ }
105
+ }
106
+ return { status: attachFailed ? "attach_failed" : "not_found" };
107
+ }
108
+ function browserSource(options) {
109
+ if (options.browser !== undefined)
110
+ return "injected";
111
+ if (globalThis.browser !== undefined)
112
+ return "global_browser";
113
+ if (globalThis.iab !== undefined)
114
+ return "legacy_iab";
115
+ if (globalThis.agent?.browsers?.get !== undefined)
116
+ return "agent";
117
+ return null;
118
+ }
119
+ function unavailable(status, errorCode, source, target) {
120
+ return {
121
+ status,
122
+ errorCode,
123
+ browserSource: source,
124
+ tabSource: null,
125
+ targetConversationUrl: target,
126
+ page: null,
127
+ };
128
+ }
129
+ function safeModelSlug(value) {
130
+ return value !== null &&
131
+ /^(?:gpt-[a-z0-9][a-z0-9._-]{0,71}|chatgpt-[a-z0-9][a-z0-9._-]{0,67}|o[1-9][0-9]?(?:-[a-z0-9][a-z0-9._-]{0,72})?)$/i.test(value)
132
+ ? value
133
+ : null;
134
+ }
135
+ function modelEvidence(state, assistantModelSlug) {
136
+ if (state.modelLabelCount > 1)
137
+ return "ambiguous";
138
+ if (state.selectedModelLabel === null && assistantModelSlug === null)
139
+ return "missing";
140
+ const composerIsPro = isProLabel(state.selectedModelLabel);
141
+ const responseIsPro = isProModelSlug(assistantModelSlug);
142
+ if (state.selectedModelLabel === null) {
143
+ return responseIsPro ? "pro_response_only" : "non_pro";
144
+ }
145
+ if (assistantModelSlug === null)
146
+ return composerIsPro ? "pro" : "non_pro";
147
+ if (composerIsPro !== responseIsPro)
148
+ return "conflict";
149
+ return composerIsPro ? "pro" : "non_pro";
150
+ }
151
+ /**
152
+ * Inspect an existing ChatGPT tab without creating, navigating, filling, or
153
+ * clicking. The result is deliberately redacted and safe for diagnostics.
154
+ */
155
+ export async function probeCodexIab(options = {}) {
156
+ const source = browserSource(options);
157
+ if (options.conversationUrl !== undefined &&
158
+ !isConversationUrl(options.conversationUrl)) {
159
+ return unavailable("target_invalid", "IAB_CONVERSATION_URL_INVALID", source, null);
160
+ }
161
+ const target = options.conversationUrl === undefined
162
+ ? null
163
+ : normalizedConversationUrl(options.conversationUrl);
164
+ let browser;
165
+ try {
166
+ browser = await resolveIabBrowser(options.browser);
167
+ }
168
+ catch (error) {
169
+ if (error instanceof CueLineError && error.code === "IAB_BROWSER_MISSING") {
170
+ return unavailable("browser_missing", error.code, null, target);
171
+ }
172
+ return unavailable("attach_failed", "IAB_BROWSER_ATTACH_FAILED", source, target);
173
+ }
174
+ const located = await existingTab(browser, target ?? undefined);
175
+ if (located.status === "not_found") {
176
+ return unavailable("tab_not_found", "IAB_CHATGPT_TAB_NOT_FOUND", source, target);
177
+ }
178
+ if (located.status === "ambiguous") {
179
+ return unavailable("tab_ambiguous", "IAB_CHATGPT_TAB_AMBIGUOUS", source, target);
180
+ }
181
+ if (located.status === "attach_failed" || located.tab === undefined || located.source === undefined) {
182
+ return unavailable("attach_failed", "IAB_ATTACH_FAILED", source, target);
183
+ }
184
+ try {
185
+ const state = await readPageProbeState(located.tab);
186
+ const observedUrl = normalizedConversationUrl(state.pageUrl);
187
+ if (!matchesTarget(observedUrl, target ?? undefined)) {
188
+ return unavailable("attach_failed", "IAB_PROBE_TARGET_CHANGED", source, target);
189
+ }
190
+ const assistantModelSlug = safeModelSlug(state.assistantModelSlug);
191
+ return {
192
+ status: "ready",
193
+ errorCode: null,
194
+ browserSource: source,
195
+ tabSource: located.source,
196
+ targetConversationUrl: target,
197
+ page: {
198
+ url: observedUrl,
199
+ isConversation: isConversationUrl(observedUrl),
200
+ isAnswering: state.isAnswering,
201
+ assistantMessageCount: state.assistantMessageCount,
202
+ lastMessageRole: state.lastMessageRole,
203
+ assistantModelSlug,
204
+ selectedModelLabel: state.selectedModelLabel,
205
+ modelEvidence: modelEvidence(state, assistantModelSlug),
206
+ composerState: state.composerState,
207
+ inlineTextLength: state.inlineTextLength,
208
+ attachmentCount: state.attachmentCount,
209
+ sendButtonState: state.sendButtonState,
210
+ },
211
+ };
212
+ }
213
+ catch {
214
+ return unavailable("attach_failed", "IAB_PAGE_PROBE_FAILED", source, target);
215
+ }
216
+ }
217
+ //# sourceMappingURL=probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/probe.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { ExpectedControllerIdentity } from "../../protocol/types.js";
2
- export declare function normalizedConversationUrl(url: string): string;
2
+ export { normalizedConversationUrl } from "../../core/conversation-url.js";
3
3
  export declare function isProLabel(label: string | null): label is string;
4
4
  export declare function isProModelSlug(slug: string | null): slug is string;
5
5
  export declare function normalizedMessageText(value: string | null): string;
@@ -1,13 +1,5 @@
1
+ export { normalizedConversationUrl } from "../../core/conversation-url.js";
1
2
  const CONTROL_ENVELOPE = /<CueLineControl>([\s\S]*?)<\/CueLineControl>/g;
2
- export function normalizedConversationUrl(url) {
3
- try {
4
- const parsed = new URL(url);
5
- return `${parsed.origin}${parsed.pathname}`;
6
- }
7
- catch {
8
- return url;
9
- }
10
- }
11
3
  export function isProLabel(label) {
12
4
  return /^Pro(?:\s+(?:Standard|Extended))?$/i.test(label ?? "");
13
5
  }
@@ -15,7 +7,12 @@ export function isProModelSlug(slug) {
15
7
  return /^gpt-\d+(?:[.-]\d+)*-pro$/i.test(slug ?? "");
16
8
  }
17
9
  export function normalizedMessageText(value) {
18
- return (value ?? "").replace(/\r\n/g, "\n").trim();
10
+ return (value ?? "")
11
+ .replace(/\u00a0/g, " ")
12
+ .replace(/\r\n?/g, "\n")
13
+ .replace(/[ \t]+\n/g, "\n")
14
+ .replace(/\n(?:[ \t]*\n)+/g, "\n")
15
+ .trim();
19
16
  }
20
17
  export function hasExactControllerEnvelopeIdentity(text, expected) {
21
18
  let body;
@@ -1 +1 @@
1
- {"version":3,"file":"recovery-evidence.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/recovery-evidence.ts"],"names":[],"mappings":"AAEA,MAAM,gBAAgB,GAAG,+CAA+C,CAAC;AAEzE,MAAM,UAAU,yBAAyB,CAAC,GAAW;IACnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,OAAO,qCAAqC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAmB;IAChD,OAAO,4BAA4B,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAoB;IACxD,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,IAAY,EACZ,QAAoC;IAEpC,IAAI,IAAwB,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACrE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAA4B,CAAC;QAClE,OAAO,CACL,MAAM,CAAC,QAAQ,KAAK,aAAa;YACjC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK;YAChC,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK;YAC/B,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,SAAS,CACzC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"recovery-evidence.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/recovery-evidence.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,gBAAgB,GAAG,+CAA+C,CAAC;AAEzE,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,OAAO,qCAAqC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAmB;IAChD,OAAO,4BAA4B,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAoB;IACxD,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;SACjB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC;SACvB,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC;SAC1B,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC;SACjC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,IAAY,EACZ,QAAoC;IAEpC,IAAI,IAAwB,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACrE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAA4B,CAAC;QAClE,OAAO,CACL,MAAM,CAAC,QAAQ,KAAK,aAAa;YACjC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK;YAChC,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK;YAC/B,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,SAAS,CACzC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export declare const COMPOSER_TEXTBOX_NAMES: readonly ["Message ChatGPT", "Chat with ChatGPT", "與 ChatGPT 對話", "傳訊息給 ChatGPT", "和 ChatGPT 聊天"];
2
2
  export declare const SEND_BUTTON_NAMES: readonly ["Send prompt", "Send message", "傳送提示", "傳送訊息", "送出提示", "送出訊息"];
3
+ export declare const ARCHIVE_MENUITEM_NAMES: readonly ["Archive", "封存"];
3
4
  export declare const CHATGPT_URL = "https://chatgpt.com/";
@@ -13,5 +13,6 @@ export const SEND_BUTTON_NAMES = [
13
13
  "送出提示",
14
14
  "送出訊息",
15
15
  ];
16
+ export const ARCHIVE_MENUITEM_NAMES = ["Archive", "封存"];
16
17
  export const CHATGPT_URL = "https://chatgpt.com/";
17
18
  //# sourceMappingURL=selectors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/selectors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,iBAAiB;IACjB,mBAAmB;IACnB,cAAc;IACd,cAAc;IACd,cAAc;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,aAAa;IACb,cAAc;IACd,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACE,CAAC;AAEX,MAAM,CAAC,MAAM,WAAW,GAAG,sBAAsB,CAAC"}
1
+ {"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/selectors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,iBAAiB;IACjB,mBAAmB;IACnB,cAAc;IACd,cAAc;IACd,cAAc;CACN,CAAC;AAEX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,aAAa;IACb,cAAc;IACd,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;CACE,CAAC;AAEX,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,SAAS,EAAE,IAAI,CAAU,CAAC;AAEjE,MAAM,CAAC,MAAM,WAAW,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { IabTab } from "./bootstrap.js";
2
+ export declare function findVisibleSendButtonCoordinates(tab: IabTab): Promise<{
3
+ x: number;
4
+ y: number;
5
+ } | undefined>;
@@ -0,0 +1,62 @@
1
+ import { SEND_BUTTON_NAMES } from "./selectors.js";
2
+ export async function findVisibleSendButtonCoordinates(tab) {
3
+ if (!tab.cua?.click)
4
+ return undefined;
5
+ const target = await tab.playwright.evaluate(({ sendButtonNames }) => {
6
+ const normalize = (value) => String(value ?? "").trim().replace(/\s+/g, " ");
7
+ const candidates = Array.from(document.querySelectorAll("button")).filter((element) => {
8
+ const button = element;
9
+ const style = window.getComputedStyle(button);
10
+ const rect = button.getBoundingClientRect();
11
+ const label = normalize(button.getAttribute("aria-label") ?? button.innerText ?? button.textContent);
12
+ const checkVisibility = button.checkVisibility;
13
+ if (typeof checkVisibility === "function") {
14
+ try {
15
+ if (!checkVisibility.call(button, {
16
+ checkOpacity: true,
17
+ checkVisibilityCSS: true,
18
+ })) {
19
+ return false;
20
+ }
21
+ }
22
+ catch {
23
+ // Explicit style and geometry checks below remain the fallback.
24
+ }
25
+ }
26
+ return (sendButtonNames.some((name) => name === label) &&
27
+ !button.disabled &&
28
+ !button.hidden &&
29
+ button.getAttribute("aria-disabled") !== "true" &&
30
+ button.getAttribute("aria-hidden") !== "true" &&
31
+ button.closest('[hidden], [aria-hidden="true"], [inert]') === null &&
32
+ style.display !== "none" &&
33
+ style.visibility !== "hidden" &&
34
+ style.visibility !== "collapse" &&
35
+ style.pointerEvents !== "none" &&
36
+ Number(style.opacity) !== 0 &&
37
+ rect.width > 0 &&
38
+ rect.height > 0 &&
39
+ button.getClientRects().length > 0 &&
40
+ rect.right > 0 &&
41
+ rect.bottom > 0 &&
42
+ rect.left < window.innerWidth &&
43
+ rect.top < window.innerHeight);
44
+ });
45
+ if (candidates.length !== 1)
46
+ return null;
47
+ const rect = candidates[0].getBoundingClientRect();
48
+ return {
49
+ x: rect.left + rect.width / 2,
50
+ y: rect.top + rect.height / 2,
51
+ };
52
+ }, { sendButtonNames: [...SEND_BUTTON_NAMES] }).catch(() => null);
53
+ if (target === null ||
54
+ !Number.isFinite(target.x) ||
55
+ !Number.isFinite(target.y) ||
56
+ target.x < 0 ||
57
+ target.y < 0) {
58
+ return undefined;
59
+ }
60
+ return { x: Math.round(target.x), y: Math.round(target.y) };
61
+ }
62
+ //# sourceMappingURL=send-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-button.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/send-button.ts"],"names":[],"mappings":"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"}
@@ -1,21 +1,10 @@
1
1
  import { CueLineError } from "../../core/errors.js";
2
+ import { isExactChatGptConversationUrl, sameChatGptConversationUrl, } from "../../core/conversation-url.js";
2
3
  // ChatGPT can spend several seconds converting a large composer payload into
3
4
  // an attachment before the new `/c/...` route becomes visible. Keep this below
4
5
  // the common 30-second outer tool window while leaving enough time for that
5
6
  // real transition.
6
7
  const CAPTURE_TIMEOUT_MS = 15_000;
7
- function isConversationUrl(url) {
8
- return /^https:\/\/chatgpt\.com\/c\/[A-Za-z0-9-]+/.test(url);
9
- }
10
- function normalizedConversationUrl(url) {
11
- try {
12
- const parsed = new URL(url);
13
- return `${parsed.origin}${parsed.pathname}`;
14
- }
15
- catch {
16
- return url;
17
- }
18
- }
19
8
  function wait(milliseconds, signal) {
20
9
  return new Promise((resolve, reject) => {
21
10
  if (signal?.aborted === true) {
@@ -34,13 +23,15 @@ function wait(milliseconds, signal) {
34
23
  });
35
24
  }
36
25
  export async function captureConversationUrlAfterSubmit(tab, knownUrl, timeoutMs, pollIntervalMs, signal) {
37
- const expectedUrl = knownUrl !== undefined && isConversationUrl(knownUrl) ? knownUrl : undefined;
26
+ const expectedUrl = knownUrl !== undefined && isExactChatGptConversationUrl(knownUrl)
27
+ ? knownUrl
28
+ : undefined;
38
29
  const deadline = Date.now() + Math.min(timeoutMs, CAPTURE_TIMEOUT_MS);
39
30
  do {
40
31
  const currentUrl = (await tab.url().catch(() => "")) ?? "";
41
- if (isConversationUrl(currentUrl)) {
32
+ if (isExactChatGptConversationUrl(currentUrl)) {
42
33
  if (expectedUrl !== undefined &&
43
- normalizedConversationUrl(currentUrl) !== normalizedConversationUrl(expectedUrl)) {
34
+ !sameChatGptConversationUrl(currentUrl, expectedUrl)) {
44
35
  throw new CueLineError("CONTROLLER_RECONCILIATION_CONVERSATION_MISMATCH", "ChatGPT navigated to a different conversation after the single send click. Refusing to bind either conversation or click again.", {
45
36
  details: {
46
37
  expected_conversation_url: expectedUrl,
@@ -1 +1 @@
1
- {"version":3,"file":"submission-url.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/submission-url.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"submission-url.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/submission-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AAGxC,6EAA6E;AAC7E,+EAA+E;AAC/E,4EAA4E;AAC5E,mBAAmB;AACnB,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,SAAS,IAAI,CAAC,YAAoB,EAAE,MAAoB;IACtD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,YAAY,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC;YAC7E,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,YAAY,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAChF,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,YAAY,CAAC,CAAC;QACjB,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,GAAW,EACX,QAA4B,EAC5B,SAAiB,EACjB,cAAsB,EACtB,MAAoB;IAEpB,MAAM,WAAW,GACf,QAAQ,KAAK,SAAS,IAAI,6BAA6B,CAAC,QAAQ,CAAC;QAC/D,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IACtE,GAAG,CAAC;QACF,MAAM,UAAU,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3D,IAAI,6BAA6B,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9C,IACE,WAAW,KAAK,SAAS;gBACzB,CAAC,0BAA0B,CAAC,UAAU,EAAE,WAAW,CAAC,EACpD,CAAC;gBACD,MAAM,IAAI,YAAY,CACpB,iDAAiD,EACjD,iIAAiI,EACjI;oBACE,OAAO,EAAE;wBACP,yBAAyB,EAAE,WAAW;wBACtC,yBAAyB,EAAE,UAAU;qBACtC;iBACF,CACF,CAAC;YACJ,CAAC;YACD,OAAO,WAAW,IAAI,UAAU,CAAC;QACnC,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE;IAChC,MAAM,IAAI,YAAY,CACpB,yCAAyC,EACzC,kKAAkK,CACnK,CAAC;AACJ,CAAC"}
@@ -1,6 +1,18 @@
1
- import { normalizedConversationUrl } from "./recovery-evidence.js";
1
+ import { CueLineError } from "../../core/errors.js";
2
+ import { sameChatGptConversationUrl } from "../../core/conversation-url.js";
2
3
  import { CHATGPT_URL } from "./selectors.js";
3
4
  const TAB_DISCOVERY_RETRY_MS = 100;
5
+ function uniqueTabListings(candidates) {
6
+ const seenIds = new Set();
7
+ return candidates.filter((candidate) => {
8
+ if (candidate.id === undefined)
9
+ return true;
10
+ if (seenIds.has(candidate.id))
11
+ return false;
12
+ seenIds.add(candidate.id);
13
+ return true;
14
+ });
15
+ }
4
16
  export function isTabUnavailableError(error) {
5
17
  const message = error instanceof Error ? error.message : String(error);
6
18
  return /tab not found|existing tabs: none|webview.*attach|cdp operation exceeded|target closed|page closed|browser.*disconnected/i.test(message);
@@ -8,12 +20,13 @@ export function isTabUnavailableError(error) {
8
20
  export async function acquireChatGptTab(browser, conversationUrl) {
9
21
  const matchesTarget = (url) => conversationUrl === undefined
10
22
  ? url.startsWith(CHATGPT_URL)
11
- : normalizedConversationUrl(url) === normalizedConversationUrl(conversationUrl);
23
+ : sameChatGptConversationUrl(url, conversationUrl);
12
24
  const canDiscover = browser.tabs.selected !== undefined ||
13
25
  browser.tabs.list !== undefined ||
14
26
  browser.user?.openTabs !== undefined;
15
27
  const discoveryPasses = canDiscover ? 2 : 1;
16
28
  let discoveryError;
29
+ let ambiguousCandidates;
17
30
  for (let pass = 0; pass < discoveryPasses; pass += 1) {
18
31
  try {
19
32
  const selected = await browser.tabs.selected?.();
@@ -27,24 +40,44 @@ export async function acquireChatGptTab(browser, conversationUrl) {
27
40
  throw error;
28
41
  discoveryError = error;
29
42
  }
30
- const sessionTabs = (await browser.tabs.list?.()) ?? [];
31
- const sessionCandidate = sessionTabs.find((candidate) => matchesTarget(String(candidate.url ?? "")));
32
- if (sessionCandidate?.id && browser.tabs.get) {
33
- const tab = await browser.tabs.get(sessionCandidate.id);
43
+ const getSessionTab = browser.tabs.get;
44
+ const sessionCandidates = uniqueTabListings(((await browser.tabs.list?.()) ?? []).filter((candidate) => candidate.id !== undefined &&
45
+ getSessionTab !== undefined &&
46
+ matchesTarget(String(candidate.url ?? ""))));
47
+ if (sessionCandidates.length === 1) {
48
+ const tab = await getSessionTab(sessionCandidates[0].id);
34
49
  await waitUntilLoaded(tab);
35
50
  return tab;
36
51
  }
37
- const openTabs = (await browser.user?.openTabs?.()) ?? [];
38
- const userCandidate = openTabs.find((candidate) => matchesTarget(String(candidate.url ?? "")));
39
- if (userCandidate && browser.user?.claimTab) {
40
- const tab = await browser.user.claimTab(userCandidate);
41
- await waitUntilLoaded(tab);
42
- return tab;
52
+ if (sessionCandidates.length > 1) {
53
+ ambiguousCandidates = { source: "session", count: sessionCandidates.length };
54
+ }
55
+ if (sessionCandidates.length === 0) {
56
+ const claimUserTab = browser.user?.claimTab;
57
+ const userCandidates = uniqueTabListings(((await browser.user?.openTabs?.()) ?? []).filter((candidate) => claimUserTab !== undefined &&
58
+ matchesTarget(String(candidate.url ?? ""))));
59
+ if (userCandidates.length === 1) {
60
+ const tab = await claimUserTab(userCandidates[0]);
61
+ await waitUntilLoaded(tab);
62
+ return tab;
63
+ }
64
+ if (userCandidates.length > 1) {
65
+ ambiguousCandidates = { source: "user", count: userCandidates.length };
66
+ }
43
67
  }
44
68
  if (pass < discoveryPasses - 1) {
45
69
  await new Promise((resolve) => setTimeout(resolve, TAB_DISCOVERY_RETRY_MS));
46
70
  }
47
71
  }
72
+ if (ambiguousCandidates !== undefined) {
73
+ throw new CueLineError("IAB_CHATGPT_TAB_AMBIGUOUS", "Multiple matching ChatGPT tabs are available and no selected tab disambiguates them. Select the intended tab and retry; CueLine will not guess or send.", {
74
+ details: {
75
+ source: ambiguousCandidates.source,
76
+ matching_tabs: ambiguousCandidates.count,
77
+ exact_conversation_requested: conversationUrl !== undefined,
78
+ },
79
+ });
80
+ }
48
81
  if (discoveryError !== undefined)
49
82
  throw discoveryError;
50
83
  const tab = await browser.tabs.new();
@@ -1 +1 @@
1
- {"version":3,"file":"tab-discovery.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/tab-discovery.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tab-discovery.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/tab-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAE5E,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,SAAS,iBAAiB,CAAC,UAAiC;IAC1D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;QACrC,IAAI,SAAS,CAAC,EAAE,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,2HAA2H,CAAC,IAAI,CACrI,OAAO,CACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAmB,EACnB,eAAwB;IAExB,MAAM,aAAa,GAAG,CAAC,GAAW,EAAW,EAAE,CAC7C,eAAe,KAAK,SAAS;QAC3B,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC;QAC7B,CAAC,CAAC,0BAA0B,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACvD,MAAM,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;QACnC,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS;QAC/B,OAAO,CAAC,IAAI,EAAE,QAAQ,KAAK,SAAS,CAAC;IACvC,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,IAAI,cAAuB,CAAC;IAC5B,IAAI,mBAA8E,CAAC;IAEnF,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,eAAe,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACjD,IAAI,QAAQ,IAAI,aAAa,CAAC,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC5D,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;gBAChC,OAAO,QAAQ,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YAC/C,cAAc,GAAG,KAAK,CAAC;QACzB,CAAC;QAED,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;QACvC,MAAM,iBAAiB,GAAG,iBAAiB,CACzC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAC1C,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,EAAE,KAAK,SAAS;YAC1B,aAAa,KAAK,SAAS;YAC3B,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAC7C,CACF,CAAC;QACF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,MAAM,aAAc,CAAC,iBAAiB,CAAC,CAAC,CAAE,CAAC,EAAG,CAAC,CAAC;YAC5D,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;YAC3B,OAAO,GAAG,CAAC;QACb,CAAC;QACD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,mBAAmB,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,CAAC,MAAM,EAAE,CAAC;QAC/E,CAAC;QAED,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;YAC5C,MAAM,cAAc,GAAG,iBAAiB,CACtC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAC/C,CAAC,SAAS,EAAE,EAAE,CACZ,YAAY,KAAK,SAAS;gBAC1B,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAC7C,CACF,CAAC;YACF,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,MAAM,YAAa,CAAC,cAAc,CAAC,CAAC,CAAE,CAAC,CAAC;gBACpD,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;gBAC3B,OAAO,GAAG,CAAC;YACb,CAAC;YACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,mBAAmB,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC;YACzE,CAAC;QACH,CAAC;QAED,IAAI,IAAI,GAAG,eAAe,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,YAAY,CACpB,2BAA2B,EAC3B,yJAAyJ,EACzJ;YACE,OAAO,EAAE;gBACP,MAAM,EAAE,mBAAmB,CAAC,MAAM;gBAClC,aAAa,EAAE,mBAAmB,CAAC,KAAK;gBACxC,4BAA4B,EAAE,eAAe,KAAK,SAAS;aAC5D;SACF,CACF,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,KAAK,SAAS;QAAE,MAAM,cAAc,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACrC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,WAAW,CAAC,CAAC;IAC/C,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW;IACxC,MAAM,GAAG,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACtC,KAAK,EAAE,kBAAkB;QACzB,SAAS,EAAE,MAAM;KAClB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function validatedTimingOption(name: "timeoutMs" | "pollIntervalMs" | "stableMs", value: number, minimum: 0 | 1, code: string): number;
@@ -0,0 +1,5 @@
1
+ import { validatedTimerDelay } from "../../core/timing.js";
2
+ export function validatedTimingOption(name, value, minimum, code) {
3
+ return validatedTimerDelay(value, { code, name, minimum });
4
+ }
5
+ //# sourceMappingURL=timing-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing-options.js","sourceRoot":"","sources":["../../../../src/browser/codex-iab/timing-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,UAAU,qBAAqB,CACnC,IAAiD,EACjD,KAAa,EACb,OAAc,EACd,IAAY;IAEZ,OAAO,mBAAmB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CliIo } from "./io.js";
2
+ export declare function handleHealthCommand(args: readonly string[], environment: NodeJS.ProcessEnv, io: CliIo): Promise<number | undefined>;