cli-jaw 2.2.2 → 2.2.3

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 (240) hide show
  1. package/README.ja.md +13 -9
  2. package/README.ko.md +5 -5
  3. package/README.md +7 -6
  4. package/README.zh-CN.md +5 -5
  5. package/dist/bin/commands/goal.js +14 -1
  6. package/dist/bin/commands/goal.js.map +1 -1
  7. package/dist/src/agent/agy-bootstrap.js +104 -0
  8. package/dist/src/agent/agy-bootstrap.js.map +1 -0
  9. package/dist/src/agent/agy-capabilities.js +103 -0
  10. package/dist/src/agent/agy-capabilities.js.map +1 -0
  11. package/dist/src/agent/agy-transcript-watcher.js +11 -0
  12. package/dist/src/agent/agy-transcript-watcher.js.map +1 -1
  13. package/dist/src/agent/args.js +32 -13
  14. package/dist/src/agent/args.js.map +1 -1
  15. package/dist/src/agent/events/claude.js +8 -4
  16. package/dist/src/agent/events/claude.js.map +1 -1
  17. package/dist/src/agent/events/helpers.js +13 -0
  18. package/dist/src/agent/events/helpers.js.map +1 -1
  19. package/dist/src/agent/events/index.js +24 -4
  20. package/dist/src/agent/events/index.js.map +1 -1
  21. package/dist/src/agent/lifecycle-handler.js +25 -4
  22. package/dist/src/agent/lifecycle-handler.js.map +1 -1
  23. package/dist/src/agent/spawn/queue.js +11 -5
  24. package/dist/src/agent/spawn/queue.js.map +1 -1
  25. package/dist/src/agent/spawn.js +49 -13
  26. package/dist/src/agent/spawn.js.map +1 -1
  27. package/dist/src/browser/web-ai/ax-snapshot.js +131 -8
  28. package/dist/src/browser/web-ai/ax-snapshot.js.map +1 -1
  29. package/dist/src/browser/web-ai/candidate-reconcile.js +61 -0
  30. package/dist/src/browser/web-ai/candidate-reconcile.js.map +1 -0
  31. package/dist/src/browser/web-ai/capability-probe.js +92 -0
  32. package/dist/src/browser/web-ai/capability-probe.js.map +1 -0
  33. package/dist/src/browser/web-ai/chatgpt-archive.js +90 -0
  34. package/dist/src/browser/web-ai/chatgpt-archive.js.map +1 -0
  35. package/dist/src/browser/web-ai/chatgpt-attachments.js +70 -3
  36. package/dist/src/browser/web-ai/chatgpt-attachments.js.map +1 -1
  37. package/dist/src/browser/web-ai/chatgpt-composer.js +97 -11
  38. package/dist/src/browser/web-ai/chatgpt-composer.js.map +1 -1
  39. package/dist/src/browser/web-ai/chatgpt-deep-research-report.js +63 -0
  40. package/dist/src/browser/web-ai/chatgpt-deep-research-report.js.map +1 -0
  41. package/dist/src/browser/web-ai/chatgpt-deep-research.js +76 -13
  42. package/dist/src/browser/web-ai/chatgpt-deep-research.js.map +1 -1
  43. package/dist/src/browser/web-ai/chatgpt-files.js +328 -0
  44. package/dist/src/browser/web-ai/chatgpt-files.js.map +1 -0
  45. package/dist/src/browser/web-ai/chatgpt-images.js +281 -0
  46. package/dist/src/browser/web-ai/chatgpt-images.js.map +1 -0
  47. package/dist/src/browser/web-ai/chatgpt-model.js +35 -14
  48. package/dist/src/browser/web-ai/chatgpt-model.js.map +1 -1
  49. package/dist/src/browser/web-ai/chatgpt-multi-turn.js +28 -4
  50. package/dist/src/browser/web-ai/chatgpt-multi-turn.js.map +1 -1
  51. package/dist/src/browser/web-ai/chatgpt-project-sources.js +191 -0
  52. package/dist/src/browser/web-ai/chatgpt-project-sources.js.map +1 -0
  53. package/dist/src/browser/web-ai/chatgpt-response-dom.js +64 -0
  54. package/dist/src/browser/web-ai/chatgpt-response-dom.js.map +1 -0
  55. package/dist/src/browser/web-ai/chatgpt-response-observer.js +170 -0
  56. package/dist/src/browser/web-ai/chatgpt-response-observer.js.map +1 -0
  57. package/dist/src/browser/web-ai/chatgpt-response.js +99 -60
  58. package/dist/src/browser/web-ai/chatgpt-response.js.map +1 -1
  59. package/dist/src/browser/web-ai/chatgpt-tools.js +48 -1
  60. package/dist/src/browser/web-ai/chatgpt-tools.js.map +1 -1
  61. package/dist/src/browser/web-ai/chatgpt-upload-surface.js +202 -0
  62. package/dist/src/browser/web-ai/chatgpt-upload-surface.js.map +1 -0
  63. package/dist/src/browser/web-ai/chatgpt.js +93 -12
  64. package/dist/src/browser/web-ai/chatgpt.js.map +1 -1
  65. package/dist/src/browser/web-ai/code-artifact.js +32 -10
  66. package/dist/src/browser/web-ai/code-artifact.js.map +1 -1
  67. package/dist/src/browser/web-ai/code-mode.js +40 -4
  68. package/dist/src/browser/web-ai/code-mode.js.map +1 -1
  69. package/dist/src/browser/web-ai/contract-audit.js +7 -22
  70. package/dist/src/browser/web-ai/contract-audit.js.map +1 -1
  71. package/dist/src/browser/web-ai/control-summary.js +43 -0
  72. package/dist/src/browser/web-ai/control-summary.js.map +1 -0
  73. package/dist/src/browser/web-ai/copy-markdown.js +10 -0
  74. package/dist/src/browser/web-ai/copy-markdown.js.map +1 -1
  75. package/dist/src/browser/web-ai/diagnostics.js +7 -0
  76. package/dist/src/browser/web-ai/diagnostics.js.map +1 -1
  77. package/dist/src/browser/web-ai/errors.js +17 -0
  78. package/dist/src/browser/web-ai/errors.js.map +1 -1
  79. package/dist/src/browser/web-ai/gemini-capabilities.js +46 -0
  80. package/dist/src/browser/web-ai/gemini-capabilities.js.map +1 -0
  81. package/dist/src/browser/web-ai/gemini-live.js +6 -0
  82. package/dist/src/browser/web-ai/gemini-live.js.map +1 -1
  83. package/dist/src/browser/web-ai/gemini-model.js +41 -0
  84. package/dist/src/browser/web-ai/gemini-model.js.map +1 -1
  85. package/dist/src/browser/web-ai/grok-capabilities.js +41 -0
  86. package/dist/src/browser/web-ai/grok-capabilities.js.map +1 -0
  87. package/dist/src/browser/web-ai/grok-live.js +5 -0
  88. package/dist/src/browser/web-ai/grok-live.js.map +1 -1
  89. package/dist/src/browser/web-ai/grok-model.js +38 -0
  90. package/dist/src/browser/web-ai/grok-model.js.map +1 -1
  91. package/dist/src/browser/web-ai/index.js +10 -0
  92. package/dist/src/browser/web-ai/index.js.map +1 -1
  93. package/dist/src/browser/web-ai/navigation-ready.js +123 -0
  94. package/dist/src/browser/web-ai/navigation-ready.js.map +1 -0
  95. package/dist/src/browser/web-ai/observation-bundle.js +26 -1
  96. package/dist/src/browser/web-ai/observation-bundle.js.map +1 -1
  97. package/dist/src/browser/web-ai/provider-adapter.js.map +1 -1
  98. package/dist/src/browser/web-ai/session-artifacts.js +156 -0
  99. package/dist/src/browser/web-ai/session-artifacts.js.map +1 -0
  100. package/dist/src/browser/web-ai/session-doctor.js +101 -0
  101. package/dist/src/browser/web-ai/session-doctor.js.map +1 -0
  102. package/dist/src/browser/web-ai/session-store.js +94 -17
  103. package/dist/src/browser/web-ai/session-store.js.map +1 -1
  104. package/dist/src/browser/web-ai/session.js +73 -0
  105. package/dist/src/browser/web-ai/session.js.map +1 -1
  106. package/dist/src/browser/web-ai/tab-inspect.js +143 -0
  107. package/dist/src/browser/web-ai/tab-inspect.js.map +1 -0
  108. package/dist/src/browser/web-ai/tab-lease-store.js +114 -4
  109. package/dist/src/browser/web-ai/tab-lease-store.js.map +1 -1
  110. package/dist/src/browser/web-ai/tier-timeout.js +58 -0
  111. package/dist/src/browser/web-ai/tier-timeout.js.map +1 -0
  112. package/dist/src/browser/web-ai/vendor-editor-contract.js +6 -3
  113. package/dist/src/browser/web-ai/vendor-editor-contract.js.map +1 -1
  114. package/dist/src/browser/web-ai/watcher-lock.js +125 -0
  115. package/dist/src/browser/web-ai/watcher-lock.js.map +1 -0
  116. package/dist/src/browser/web-ai/watcher.js +23 -4
  117. package/dist/src/browser/web-ai/watcher.js.map +1 -1
  118. package/dist/src/cli/handlers-workflows.js +14 -3
  119. package/dist/src/cli/handlers-workflows.js.map +1 -1
  120. package/dist/src/core/cli-detection.js +2 -3
  121. package/dist/src/core/cli-detection.js.map +1 -1
  122. package/dist/src/core/settings-merge.js +2 -2
  123. package/dist/src/core/settings-merge.js.map +1 -1
  124. package/dist/src/goal/heartbeat.js +13 -7
  125. package/dist/src/goal/heartbeat.js.map +1 -1
  126. package/dist/src/goal/pause-gate.js +22 -0
  127. package/dist/src/goal/pause-gate.js.map +1 -0
  128. package/dist/src/goal/store.js +5 -0
  129. package/dist/src/goal/store.js.map +1 -1
  130. package/dist/src/manager/lifecycle.js +2 -1
  131. package/dist/src/manager/lifecycle.js.map +1 -1
  132. package/dist/src/manager/preview-origin-proxy.js +36 -6
  133. package/dist/src/manager/preview-origin-proxy.js.map +1 -1
  134. package/dist/src/manager/proxy.js +25 -4
  135. package/dist/src/manager/proxy.js.map +1 -1
  136. package/dist/src/manager/registry.js +36 -3
  137. package/dist/src/manager/registry.js.map +1 -1
  138. package/dist/src/manager/routes/runtime-monitor.js +2 -0
  139. package/dist/src/manager/routes/runtime-monitor.js.map +1 -1
  140. package/dist/src/manager/routes/telegram-hub.js +120 -0
  141. package/dist/src/manager/routes/telegram-hub.js.map +1 -0
  142. package/dist/src/manager/server.js +4 -0
  143. package/dist/src/manager/server.js.map +1 -1
  144. package/dist/src/manager/telegram-hub/hub-bot.js +409 -0
  145. package/dist/src/manager/telegram-hub/hub-bot.js.map +1 -0
  146. package/dist/src/manager/telegram-hub/routing-store.js +24 -0
  147. package/dist/src/manager/telegram-hub/routing-store.js.map +1 -0
  148. package/dist/src/manager/telegram-hub/types.js +5 -0
  149. package/dist/src/manager/telegram-hub/types.js.map +1 -0
  150. package/dist/src/messaging/thread-target.js +21 -0
  151. package/dist/src/messaging/thread-target.js.map +1 -0
  152. package/dist/src/orchestrator/gateway.js +10 -7
  153. package/dist/src/orchestrator/gateway.js.map +1 -1
  154. package/dist/src/orchestrator/pipeline.js +19 -0
  155. package/dist/src/orchestrator/pipeline.js.map +1 -1
  156. package/dist/src/orchestrator/worker-registry.js.map +1 -1
  157. package/dist/src/routes/command.js +58 -2
  158. package/dist/src/routes/command.js.map +1 -1
  159. package/dist/src/routes/goal.js +6 -3
  160. package/dist/src/routes/goal.js.map +1 -1
  161. package/dist/src/routes/messaging.js +7 -2
  162. package/dist/src/routes/messaging.js.map +1 -1
  163. package/dist/src/routes/orchestrate.js +2 -0
  164. package/dist/src/routes/orchestrate.js.map +1 -1
  165. package/dist/src/telegram/bot.js +59 -4
  166. package/dist/src/telegram/bot.js.map +1 -1
  167. package/dist/src/telegram/forwarder.js +4 -1
  168. package/dist/src/telegram/forwarder.js.map +1 -1
  169. package/dist/src/telegram/hub-callback.js +21 -0
  170. package/dist/src/telegram/hub-callback.js.map +1 -0
  171. package/dist/src/telegram/rich-message.js +20 -0
  172. package/dist/src/telegram/rich-message.js.map +1 -0
  173. package/dist/src/telegram/telegram-file.js +4 -3
  174. package/dist/src/telegram/telegram-file.js.map +1 -1
  175. package/dist/src/workflows/status.js +14 -4
  176. package/dist/src/workflows/status.js.map +1 -1
  177. package/package.json +5 -5
  178. package/public/dist/assets/{Agent-wJtedbz4.js → Agent-Ci12HWhE.js} +1 -1
  179. package/public/dist/assets/{Heartbeat-CjgQ-0p8.js → Heartbeat-D-Rfp094.js} +1 -1
  180. package/public/dist/assets/{Memory-6o-wyhAT.js → Memory-VH4ZJCMW.js} +1 -1
  181. package/public/dist/assets/ModelProvider-_tUCghOF.js +1 -0
  182. package/public/dist/assets/TelegramHub-CuJoPPib.js +1 -0
  183. package/public/dist/assets/{agent-meta-g8UDRdWA.js → agent-meta-DqBTGRRQ.js} +1 -1
  184. package/public/dist/assets/{app-CLrfEHAk.js → app-DaORcAyD.js} +4 -4
  185. package/public/dist/assets/bgtask-badge-B3HLOZae.js +1 -0
  186. package/public/dist/assets/{bgtask-badge-xWbw-l-0.js → bgtask-badge-BtUXEe1T.js} +1 -1
  187. package/public/dist/assets/constants-DkJ3E63Y.js +1 -0
  188. package/public/dist/assets/{employees-C5GPj3d3.js → employees-CZSyvJbx.js} +1 -1
  189. package/public/dist/assets/manager-D3waO_XX.css +1 -0
  190. package/public/dist/assets/manager-DB5qTw1A.js +13 -0
  191. package/public/dist/assets/memory-BEruUlfu.js +1 -0
  192. package/public/dist/assets/{memory-CcnjBuo-.js → memory-cWI_Htbn.js} +1 -1
  193. package/public/dist/assets/message-history-DU1V9ZAW.js +142 -0
  194. package/public/dist/assets/message-history-tjkyOp_K.js +1 -0
  195. package/public/dist/assets/{render-C2g_qvCg.js → render-Bp8eyqCf.js} +1 -1
  196. package/public/dist/assets/settings-B-GgyJZI.js +1 -0
  197. package/public/dist/assets/{settings-DxClXVD0.js → settings-DLkP7qRV.js} +1 -1
  198. package/public/dist/assets/{settings-core-CSUV4-QG.js → settings-core-B5XRRNcX.js} +1 -1
  199. package/public/dist/assets/settings-core-Cw1av-Ox.js +1 -0
  200. package/public/dist/assets/{sidebar-CJz_SnMW.js → sidebar-CsogFOse.js} +3 -3
  201. package/public/dist/assets/skills-CLcoop6W.js +1 -0
  202. package/public/dist/assets/{skills-PKg2h1N4.js → skills-Dmf4v9rj.js} +1 -1
  203. package/public/dist/assets/slash-commands-DY6-hzq6.js +1 -0
  204. package/public/dist/assets/{slash-commands-FMOOfedZ.js → slash-commands-vcf7FuPD.js} +1 -1
  205. package/public/dist/assets/{trace-drawer-BoU1ucw7.js → trace-drawer-DuQQ0SNq.js} +1 -1
  206. package/public/dist/assets/{ui-BX-IfLze.js → ui-BKYuBdZE.js} +1 -1
  207. package/public/dist/assets/ui-CqlGwgUo.js +1 -0
  208. package/public/dist/index.html +1 -1
  209. package/public/dist/manager/index.html +2 -2
  210. package/public/js/constants.ts +2 -3
  211. package/public/js/features/process-block.ts +61 -9
  212. package/public/manager/src/code/code-composer.css +1 -0
  213. package/public/manager/src/code/code.css +7 -2
  214. package/public/manager/src/dashboard-settings/DashboardSettingsSidebar.tsx +6 -2
  215. package/public/manager/src/dashboard-settings/DashboardSettingsWorkspace.tsx +91 -2
  216. package/public/manager/src/goal-status/GoalPabcdStatusPanel.tsx +9 -1
  217. package/public/manager/src/goal-status/goal-pabcd-status-client.ts +9 -0
  218. package/public/manager/src/settings/SettingsShell.tsx +1 -0
  219. package/public/manager/src/settings/SettingsSidebar.tsx +1 -0
  220. package/public/manager/src/settings/pages/TelegramHub.tsx +179 -0
  221. package/public/manager/src/settings/pages/components/PerCliRow.tsx +23 -13
  222. package/public/manager/src/settings/pages/components/agent/agent-meta.ts +3 -1
  223. package/public/manager/src/settings/types.ts +1 -0
  224. package/public/manager/src/settings-shell.css +11 -0
  225. package/public/sw.js +1 -1
  226. package/scripts/bundle-sidecar.sh +6 -1
  227. package/public/dist/assets/ModelProvider-CNu6WOjM.js +0 -1
  228. package/public/dist/assets/bgtask-badge-4OjtCvDq.js +0 -1
  229. package/public/dist/assets/constants-CCiCctGV.js +0 -1
  230. package/public/dist/assets/manager-Ceg2x8D0.js +0 -13
  231. package/public/dist/assets/manager-CwAlpgV7.css +0 -1
  232. package/public/dist/assets/memory-B1beDKbo.js +0 -1
  233. package/public/dist/assets/message-history-BSWJwi__.js +0 -142
  234. package/public/dist/assets/message-history-CzaziSe8.js +0 -1
  235. package/public/dist/assets/settings-Dst1mUjn.js +0 -1
  236. package/public/dist/assets/settings-core-BW5mtFPE.js +0 -1
  237. package/public/dist/assets/skills-B2io6S_4.js +0 -1
  238. package/public/dist/assets/slash-commands-D1IS00Eg.js +0 -1
  239. package/public/dist/assets/ui-C-al0etg.js +0 -1
  240. /package/public/dist/assets/{TerminalPanel-B7WRXPsE.js → TerminalPanel-DSCJeGjp.js} +0 -0
@@ -0,0 +1,328 @@
1
+ import { trySaveFileArtifact } from './session-artifacts.js';
2
+ import { appendSessionArtifact } from './session.js';
3
+ /** Hosts that may serve ChatGPT downloadable files. */
4
+ const ALLOWED_HOSTS = new Set(['chatgpt.com', 'chat.openai.com']);
5
+ const DEFAULT_ORIGIN = 'https://chatgpt.com';
6
+ /** `/backend-api/files/<id>/download` or `/content` (id is opaque, charset-limited). */
7
+ const FILES_PATH = /^\/backend-api\/files\/[A-Za-z0-9_-]+\/(download|content)$/;
8
+ function hasUnsafeChars(s) {
9
+ return s.includes('\0') || s.includes('\\');
10
+ }
11
+ function safeDecode(s) {
12
+ try {
13
+ return decodeURIComponent(s);
14
+ }
15
+ catch {
16
+ return s;
17
+ }
18
+ }
19
+ function containsTraversal(s) {
20
+ if (typeof s !== 'string')
21
+ return true;
22
+ return s.includes('..') || safeDecode(s).includes('..');
23
+ }
24
+ /** Validate a `/mnt/data/...` sandbox path: under `/mnt/data/` with no traversal. */
25
+ function isSafeSandboxPath(p) {
26
+ if (typeof p !== 'string' || p === '')
27
+ return false;
28
+ if (hasUnsafeChars(p) || containsTraversal(p))
29
+ return false;
30
+ return p.startsWith('/mnt/data/');
31
+ }
32
+ function isAllowedFileEndpoint(u) {
33
+ const p = u.pathname;
34
+ if (p === '/backend-api/sandbox/download') {
35
+ const pathParam = u.searchParams.get('path');
36
+ return pathParam !== null && isSafeSandboxPath(pathParam);
37
+ }
38
+ if (FILES_PATH.test(p))
39
+ return true;
40
+ if (p === '/backend-api/estuary/content') {
41
+ const id = u.searchParams.get('id');
42
+ return id !== null && /^file_[A-Za-z0-9_-]+$/.test(id);
43
+ }
44
+ return false;
45
+ }
46
+ /** Convert a safe `sandbox:/mnt/data/...` reference into an absolute download URL, else null. */
47
+ export function normalizeChatGptSandboxUrl(value) {
48
+ if (typeof value !== 'string')
49
+ return null;
50
+ const raw = value.trim();
51
+ if (!raw.toLowerCase().startsWith('sandbox:'))
52
+ return null;
53
+ const p = raw.slice('sandbox:'.length);
54
+ if (!isSafeSandboxPath(p))
55
+ return null;
56
+ const u = new URL('/backend-api/sandbox/download', DEFAULT_ORIGIN);
57
+ u.searchParams.set('path', p);
58
+ return u.toString();
59
+ }
60
+ /**
61
+ * Normalize and validate a ChatGPT downloadable-file URL from the DOM. Returns the
62
+ * canonical absolute URL string, or null if it is not a known, safe ChatGPT endpoint.
63
+ */
64
+ export function normalizeChatGptFileDownloadUrl(value) {
65
+ if (typeof value !== 'string')
66
+ return null;
67
+ const raw = value.trim();
68
+ if (raw === '' || hasUnsafeChars(raw))
69
+ return null;
70
+ if (raw.toLowerCase().startsWith('sandbox:'))
71
+ return normalizeChatGptSandboxUrl(raw);
72
+ let u;
73
+ try {
74
+ u = raw.startsWith('/') ? new URL(raw, DEFAULT_ORIGIN) : new URL(raw);
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ if (u.protocol !== 'https:')
80
+ return null;
81
+ if (!ALLOWED_HOSTS.has(u.hostname))
82
+ return null;
83
+ if (u.port !== '')
84
+ return null;
85
+ if (containsTraversal(u.pathname))
86
+ return null;
87
+ if (!isAllowedFileEndpoint(u))
88
+ return null;
89
+ return u.toString();
90
+ }
91
+ const CONVERSATION_TURN_SELECTOR = 'article[data-testid^="conversation-turn"], div[data-testid^="conversation-turn"], section[data-testid^="conversation-turn"]';
92
+ const ASSISTANT_ROOT_SELECTOR = '[data-message-author-role="assistant"], [data-turn="assistant"], [data-testid*="assistant" i]';
93
+ const FILENAME_FALLBACK_PREFIX = 'chatgpt-file';
94
+ /**
95
+ * Build the in-page expression that harvests candidate download anchors from assistant
96
+ * turns after `baselineAssistantCount`. Endpoint allowlisting happens in Node.
97
+ */
98
+ export function buildDownloadableFileDetectionExpression(baselineAssistantCount = 0) {
99
+ const minIdx = Number.isFinite(Number(baselineAssistantCount))
100
+ ? Math.max(0, Math.floor(Number(baselineAssistantCount)))
101
+ : 0;
102
+ return `(() => {
103
+ const MIN_ASSISTANT_INDEX = ${minIdx};
104
+ const CONVERSATION_SELECTOR = ${JSON.stringify(CONVERSATION_TURN_SELECTOR)};
105
+ const ASSISTANT_SELECTOR = ${JSON.stringify(ASSISTANT_ROOT_SELECTOR)};
106
+ const isAssistantTurn = (node) => {
107
+ if (!(node instanceof HTMLElement)) return false;
108
+ if (String(node.getAttribute('data-turn') || '').toLowerCase() === 'assistant') return true;
109
+ if (String(node.getAttribute('data-message-author-role') || '').toLowerCase() === 'assistant') return true;
110
+ if (String(node.getAttribute('data-testid') || '').toLowerCase().includes('assistant')) return true;
111
+ return Boolean(node.querySelector(ASSISTANT_SELECTOR));
112
+ };
113
+ const pushUniqueRoot = (roots, node) => {
114
+ if (!(node instanceof HTMLElement)) return;
115
+ if (roots.some(root => root === node || root.contains(node))) return;
116
+ for (let i = roots.length - 1; i >= 0; i -= 1) {
117
+ if (node.contains(roots[i])) roots.splice(i, 1);
118
+ }
119
+ roots.push(node);
120
+ };
121
+ const roots = [];
122
+ for (const node of document.querySelectorAll(CONVERSATION_SELECTOR)) {
123
+ if (isAssistantTurn(node)) pushUniqueRoot(roots, node);
124
+ }
125
+ for (const node of document.querySelectorAll(ASSISTANT_SELECTOR)) {
126
+ if (isAssistantTurn(node)) pushUniqueRoot(roots, node);
127
+ }
128
+ roots.sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING ? 1 : -1);
129
+ const relevant = roots.slice(MIN_ASSISTANT_INDEX);
130
+ const out = [];
131
+ for (const msg of relevant) {
132
+ for (const a of msg.querySelectorAll('a[href], a[download]')) {
133
+ const href = a.getAttribute('href') || '';
134
+ if (!href) continue;
135
+ out.push({
136
+ href,
137
+ download: a.getAttribute('download') || '',
138
+ text: String(a.textContent || '').replace(/\\s+/g, ' ').trim().slice(0, 200),
139
+ });
140
+ }
141
+ }
142
+ return out;
143
+ })()`;
144
+ }
145
+ /** Deduplicate raw candidates by normalized ChatGPT file URL; drop non-allowlisted hrefs. */
146
+ export function dedupeDownloadCandidates(candidates) {
147
+ const seen = new Set();
148
+ const out = [];
149
+ for (const c of Array.isArray(candidates) ? candidates : []) {
150
+ const sourceUrl = normalizeChatGptFileDownloadUrl(c?.href);
151
+ if (!sourceUrl || seen.has(sourceUrl))
152
+ continue;
153
+ seen.add(sourceUrl);
154
+ out.push({ sourceUrl, download: String(c?.download || ''), text: String(c?.text || '') });
155
+ }
156
+ return out;
157
+ }
158
+ /** Reduce an arbitrary candidate filename to a safe basename. */
159
+ export function sanitizeDownloadFilename(name) {
160
+ if (typeof name !== 'string')
161
+ return '';
162
+ const base = (name.split(/[\\/]/).pop() || '').replace(/\0/g, '');
163
+ const cleaned = base.replace(/[<>:"|?*]/g, '_').replace(/^\.+/, '').trim();
164
+ return cleaned === '' || cleaned === '.' ? '' : cleaned;
165
+ }
166
+ /** Extract a filename from a `Content-Disposition` header (filename* preferred). */
167
+ export function filenameFromContentDisposition(headerValue) {
168
+ if (typeof headerValue !== 'string' || headerValue === '')
169
+ return null;
170
+ const star = headerValue.match(/filename\*\s*=\s*(?:UTF-8'[^']*')?([^;]+)/i);
171
+ const starCap = star?.[1];
172
+ if (starCap) {
173
+ try {
174
+ const safe = sanitizeDownloadFilename(decodeURIComponent(starCap.trim().replace(/^"|"$/g, '')));
175
+ if (safe)
176
+ return safe;
177
+ }
178
+ catch { /* fall through to plain filename */ }
179
+ }
180
+ const plain = headerValue.match(/filename\s*=\s*"?([^";]+)"?/i);
181
+ const plainCap = plain?.[1];
182
+ if (plainCap) {
183
+ const safe = sanitizeDownloadFilename(plainCap.trim());
184
+ if (safe)
185
+ return safe;
186
+ }
187
+ return null;
188
+ }
189
+ function filenameFromUrl(url) {
190
+ if (typeof url !== 'string')
191
+ return '';
192
+ try {
193
+ const u = new URL(url);
194
+ const sandboxPath = u.searchParams.get('path');
195
+ if (sandboxPath)
196
+ return sanitizeDownloadFilename(sandboxPath.split('/').pop() || '');
197
+ const last = u.pathname.split('/').filter(Boolean).pop() || '';
198
+ if (last === 'download' || last === 'content')
199
+ return '';
200
+ return sanitizeDownloadFilename(last);
201
+ }
202
+ catch {
203
+ return '';
204
+ }
205
+ }
206
+ /** Resolve the saved filename: Content-Disposition → download attr → URL basename → fallback. */
207
+ export function resolveDownloadFilename(opts = {}) {
208
+ const { contentDisposition, downloadAttr, sourceUrl, index = 0 } = opts;
209
+ const fromCd = filenameFromContentDisposition(contentDisposition);
210
+ if (fromCd)
211
+ return fromCd;
212
+ const fromAttr = sanitizeDownloadFilename(downloadAttr || '');
213
+ if (fromAttr)
214
+ return fromAttr;
215
+ const fromUrl = filenameFromUrl(sourceUrl || '');
216
+ if (fromUrl)
217
+ return fromUrl;
218
+ return `${FILENAME_FALLBACK_PREFIX}-${index + 1}`;
219
+ }
220
+ /** Scan assistant turns after the baseline; return deduped, allowlisted candidates. */
221
+ export async function readAssistantDownloadableFiles(cdpSession, opts = {}) {
222
+ const evalRes = (await cdpSession.send('Runtime.evaluate', {
223
+ expression: buildDownloadableFileDetectionExpression(opts.baselineAssistantCount ?? 0),
224
+ returnByValue: true,
225
+ }));
226
+ const value = evalRes.result?.value;
227
+ let raw;
228
+ try {
229
+ raw = Array.isArray(value) ? value : JSON.parse(typeof value === 'string' ? value : '[]');
230
+ }
231
+ catch {
232
+ return [];
233
+ }
234
+ return dedupeDownloadCandidates(Array.isArray(raw) ? raw : []);
235
+ }
236
+ const DOWNLOAD_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36';
237
+ const DEFAULT_PER_DOWNLOAD_TIMEOUT_MS = 30_000;
238
+ async function getChatGptCookieHeader(cdpSession) {
239
+ try {
240
+ const res = (await cdpSession.send('Network.getCookies', { urls: ['https://chatgpt.com/'] }));
241
+ return (res.cookies || []).map((c) => `${c.name}=${c.value}`).join('; ');
242
+ }
243
+ catch {
244
+ return '';
245
+ }
246
+ }
247
+ async function fetchDownload(url, cookieHeader, timeoutMs) {
248
+ const controller = new AbortController();
249
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
250
+ try {
251
+ const resp = await fetch(url, {
252
+ headers: { Cookie: cookieHeader, 'User-Agent': DOWNLOAD_USER_AGENT },
253
+ redirect: 'follow',
254
+ signal: controller.signal,
255
+ });
256
+ if (!resp.ok)
257
+ return { failed: true };
258
+ const contentDisposition = resp.headers.get('content-disposition');
259
+ const mimeType = (resp.headers.get('content-type') || 'application/octet-stream').split(';')[0]?.trim()
260
+ || 'application/octet-stream';
261
+ const buffer = Buffer.from(await resp.arrayBuffer());
262
+ return { buffer, mimeType, contentDisposition };
263
+ }
264
+ catch (err) {
265
+ if (err?.name === 'AbortError')
266
+ return { timedOut: true };
267
+ return { failed: true };
268
+ }
269
+ finally {
270
+ clearTimeout(timer);
271
+ }
272
+ }
273
+ /**
274
+ * Capture generic downloadable files from the current assistant turn and persist them as
275
+ * `kind:'file'` session artifacts. Downloads run sequentially; once one times out,
276
+ * attribution stops so a late completion is never attached to the next candidate.
277
+ */
278
+ export async function saveAssistantDownloadableFiles(cdpSession, _deps, opts = {}) {
279
+ const { sessionId = null, baselineAssistantCount = 0, perDownloadTimeoutMs = DEFAULT_PER_DOWNLOAD_TIMEOUT_MS } = opts;
280
+ const candidates = await readAssistantDownloadableFiles(cdpSession, { baselineAssistantCount });
281
+ if (!candidates.length)
282
+ return { ok: true, files: [], warnings: [] };
283
+ if (!sessionId)
284
+ return { ok: true, files: [], warnings: ['file-artifact-no-session'] };
285
+ const cookieHeader = await getChatGptCookieHeader(cdpSession);
286
+ const files = [];
287
+ const warnings = [];
288
+ let attributionStopped = false;
289
+ for (let i = 0; i < candidates.length; i += 1) {
290
+ const c = candidates[i];
291
+ if (!c)
292
+ continue;
293
+ if (attributionStopped) {
294
+ warnings.push(`file-artifact-skipped-after-timeout:${c.sourceUrl}`);
295
+ continue;
296
+ }
297
+ const got = await fetchDownload(c.sourceUrl, cookieHeader, perDownloadTimeoutMs);
298
+ if ('timedOut' in got) {
299
+ attributionStopped = true;
300
+ warnings.push(`file-artifact-timeout:${c.sourceUrl}`);
301
+ continue;
302
+ }
303
+ if ('failed' in got) {
304
+ warnings.push(`file-artifact-fetch-failed:${c.sourceUrl}`);
305
+ continue;
306
+ }
307
+ const filename = resolveDownloadFilename({
308
+ contentDisposition: got.contentDisposition,
309
+ downloadAttr: c.download,
310
+ sourceUrl: c.sourceUrl,
311
+ index: i,
312
+ });
313
+ const res = trySaveFileArtifact(sessionId, {
314
+ filename,
315
+ buffer: got.buffer,
316
+ mimeType: got.mimeType,
317
+ sourceUrl: c.sourceUrl,
318
+ });
319
+ if (!res.ok) {
320
+ warnings.push(`file-artifact-save-failed:${res.stage}`);
321
+ continue;
322
+ }
323
+ appendSessionArtifact(sessionId, res.descriptor);
324
+ files.push(res.descriptor);
325
+ }
326
+ return { ok: true, files, warnings };
327
+ }
328
+ //# sourceMappingURL=chatgpt-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatgpt-files.js","sourceRoot":"","sources":["../../../../src/browser/web-ai/chatgpt-files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,281 @@
1
+ import { writeFileSync, existsSync, mkdirSync } from 'node:fs';
2
+ import { dirname, extname, join } from 'node:path';
3
+ import { resolveArtifactsDir, saveImageArtifact } from './session-artifacts.js';
4
+ import { appendSessionArtifact } from './session.js';
5
+ // Parity catalog 102 (generated images, P1). Strict-TS port of agbrowse
6
+ // web-ai/chatgpt-images.mjs. cli-jaw had image *tool-selection* but no output capture;
7
+ // this detects DALL·E/estuary generated images in assistant turns and downloads them
8
+ // (explicit --output paths or session artifacts). Pure detection-expression builder,
9
+ // URL allowlist, output-path derivation, and chrome-text classifier are fully testable.
10
+ // Artifact capture uses cli-jaw's saveImageArtifact → appendSessionArtifact (not agbrowse
11
+ // appendArtifactRecord).
12
+ const ESTUARY_PATTERN = /backend-api\/estuary\/content\?id=(file_[A-Za-z0-9_-]+)/;
13
+ const ALLOWED_HOST = 'chatgpt.com';
14
+ const DEFAULT_IMAGE_WAIT_TIMEOUT_MS = 60_000;
15
+ const CONVERSATION_TURN_SELECTOR = 'article[data-testid^="conversation-turn"], div[data-testid^="conversation-turn"], section[data-testid^="conversation-turn"]';
16
+ const ASSISTANT_ROOT_SELECTOR = '[data-message-author-role="assistant"], [data-turn="assistant"], [data-testid*="assistant" i]';
17
+ export function buildGeneratedImageDetectionExpression(baselineAssistantCount = 0) {
18
+ const minAssistantLiteral = Number.isFinite(Number(baselineAssistantCount))
19
+ ? Math.max(0, Math.floor(Number(baselineAssistantCount)))
20
+ : 0;
21
+ return `(() => {
22
+ const MIN_ASSISTANT_INDEX = ${minAssistantLiteral};
23
+ const CONVERSATION_SELECTOR = ${JSON.stringify(CONVERSATION_TURN_SELECTOR)};
24
+ const ASSISTANT_SELECTOR = ${JSON.stringify(ASSISTANT_ROOT_SELECTOR)};
25
+ const isGeneratedImage = (img) => {
26
+ const src = img?.currentSrc || img?.src || '';
27
+ if (!src.includes('/backend-api/estuary/content?id=file_')) return false;
28
+ const alt = String(img.alt || '').toLowerCase();
29
+ if (alt.includes('generated image')) return true;
30
+ let node = img;
31
+ while (node instanceof HTMLElement) {
32
+ const id = String(node.id || '');
33
+ const className = String(node.className || '');
34
+ if (id.startsWith('image-')) return true;
35
+ if (className.includes('imagegen-image')) return true;
36
+ node = node.parentElement;
37
+ }
38
+ return Boolean(img.closest?.(ASSISTANT_SELECTOR));
39
+ };
40
+ const isAssistantTurn = (node) => {
41
+ if (!(node instanceof HTMLElement)) return false;
42
+ const turn = String(node.getAttribute('data-turn') || node.dataset?.turn || '').toLowerCase();
43
+ if (turn === 'assistant') return true;
44
+ const role = String(node.getAttribute('data-message-author-role') || node.dataset?.messageAuthorRole || '').toLowerCase();
45
+ if (role === 'assistant') return true;
46
+ const testId = String(node.getAttribute('data-testid') || '').toLowerCase();
47
+ if (testId.includes('assistant')) return true;
48
+ return Boolean(node.querySelector(ASSISTANT_SELECTOR));
49
+ };
50
+ const sortByDocumentOrder = (nodes) => nodes.sort((a, b) => {
51
+ if (a === b) return 0;
52
+ return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING ? 1 : -1;
53
+ });
54
+ const pushUniqueRoot = (roots, node) => {
55
+ if (!(node instanceof HTMLElement)) return;
56
+ if (roots.some(root => root === node || root.contains(node))) return;
57
+ for (let i = roots.length - 1; i >= 0; i -= 1) {
58
+ if (node.contains(roots[i])) roots.splice(i, 1);
59
+ }
60
+ roots.push(node);
61
+ };
62
+ const roots = [];
63
+ for (const node of document.querySelectorAll(CONVERSATION_SELECTOR)) {
64
+ if (isAssistantTurn(node)) pushUniqueRoot(roots, node);
65
+ }
66
+ for (const node of document.querySelectorAll(ASSISTANT_SELECTOR)) {
67
+ if (isAssistantTurn(node)) pushUniqueRoot(roots, node);
68
+ }
69
+ sortByDocumentOrder(roots);
70
+ const relevant = roots.slice(MIN_ASSISTANT_INDEX);
71
+ const imgs = [];
72
+ for (const msg of relevant) {
73
+ for (const img of msg.querySelectorAll('img')) {
74
+ if (!isGeneratedImage(img)) continue;
75
+ const src = img.currentSrc || img.src || '';
76
+ const match = src.match(/backend-api\\/estuary\\/content\\?id=(file_[A-Za-z0-9_-]+)/);
77
+ if (match) {
78
+ imgs.push({
79
+ url: src,
80
+ fileId: match[1],
81
+ alt: img.alt || '',
82
+ width: img.naturalWidth || 0,
83
+ height: img.naturalHeight || 0,
84
+ });
85
+ }
86
+ }
87
+ }
88
+ if (!imgs.length) {
89
+ const boundary = MIN_ASSISTANT_INDEX > 0 ? roots[MIN_ASSISTANT_INDEX - 1] : null;
90
+ for (const img of document.querySelectorAll('img')) {
91
+ if (!isGeneratedImage(img)) continue;
92
+ if (boundary && !(boundary.compareDocumentPosition(img) & Node.DOCUMENT_POSITION_FOLLOWING)) continue;
93
+ const src = img.currentSrc || img.src || '';
94
+ const match = src.match(/backend-api\\/estuary\\/content\\?id=(file_[A-Za-z0-9_-]+)/);
95
+ if (!match) continue;
96
+ imgs.push({
97
+ url: src,
98
+ fileId: match[1],
99
+ alt: img.alt || '',
100
+ width: img.naturalWidth || 0,
101
+ height: img.naturalHeight || 0,
102
+ });
103
+ }
104
+ }
105
+ const deduped = new Map();
106
+ for (const img of imgs) {
107
+ const existing = deduped.get(img.fileId);
108
+ if (!existing || (img.width * img.height) > (existing.width * existing.height)) {
109
+ deduped.set(img.fileId, img);
110
+ }
111
+ }
112
+ return Array.from(deduped.values());
113
+ })()`;
114
+ }
115
+ /** Detect generated images in assistant messages after a baseline count. */
116
+ export async function detectGeneratedImages(cdpSession, { baselineAssistantCount = 0 } = {}) {
117
+ const res = (await cdpSession.send('Runtime.evaluate', {
118
+ expression: buildGeneratedImageDetectionExpression(baselineAssistantCount),
119
+ returnByValue: true,
120
+ }));
121
+ const value = res?.result?.value;
122
+ if (!value)
123
+ return [];
124
+ try {
125
+ const raw = Array.isArray(value) ? value : JSON.parse(String(value));
126
+ if (!Array.isArray(raw))
127
+ return [];
128
+ return raw
129
+ .map((img) => ({
130
+ url: String(img?.['url'] || ''),
131
+ fileId: String(img?.['fileId'] || ''),
132
+ alt: String(img?.['alt'] || ''),
133
+ width: Number(img?.['width'] || 0),
134
+ height: Number(img?.['height'] || 0),
135
+ }))
136
+ .filter((img) => img.url && img.fileId);
137
+ }
138
+ catch {
139
+ return [];
140
+ }
141
+ }
142
+ export function isAllowedChatGptImageUrl(url) {
143
+ try {
144
+ const parsed = new URL(url);
145
+ return parsed.hostname === ALLOWED_HOST && ESTUARY_PATTERN.test(parsed.pathname + parsed.search);
146
+ }
147
+ catch {
148
+ return false;
149
+ }
150
+ }
151
+ /** Derive sibling output paths: "out.png" → ["out.png", "out-2.png", "out-3.png"]. */
152
+ export function deriveGeneratedImageOutputPaths(outputPath, count) {
153
+ if (count <= 1)
154
+ return [outputPath];
155
+ const ext = extname(outputPath);
156
+ const base = outputPath.slice(0, -ext.length || undefined);
157
+ return Array.from({ length: count }, (_, i) => i === 0 ? outputPath : `${base}-${i + 1}${ext}`);
158
+ }
159
+ export function resolveGeneratedImageWaitTimeoutMs(waitTimeoutMs) {
160
+ const parsed = Number(waitTimeoutMs);
161
+ if (!Number.isFinite(parsed) || parsed <= 0)
162
+ return DEFAULT_IMAGE_WAIT_TIMEOUT_MS;
163
+ return Math.max(5_000, parsed);
164
+ }
165
+ /**
166
+ * ChatGPT image-only turns often expose only UI chrome text such as "Edit". Treat that
167
+ * as metadata, not as the assistant answer.
168
+ */
169
+ export function isImageOnlyGeneratedImageChromeText(text) {
170
+ const normalized = String(text || '').toLowerCase().replace(/\s+/g, ' ').trim();
171
+ return normalized === ''
172
+ || normalized === 'edit'
173
+ || normalized === 'creating image'
174
+ || normalized === 'stopped thinking'
175
+ || normalized === 'stopped thinking edit';
176
+ }
177
+ /** Download detected images using ChatGPT cookies (explicit paths or session artifacts). */
178
+ export async function downloadGeneratedImages(cdpSession, images, { outputPath, sessionId } = {}) {
179
+ if (!images.length)
180
+ return [];
181
+ const cookieRes = (await cdpSession.send('Network.getCookies', {
182
+ urls: ['https://chatgpt.com/'],
183
+ }));
184
+ const cookieHeader = (cookieRes.cookies || [])
185
+ .map((c) => `${c.name}=${c.value}`)
186
+ .join('; ');
187
+ const results = [];
188
+ const outputPaths = outputPath ? deriveGeneratedImageOutputPaths(outputPath, images.length) : [];
189
+ for (let i = 0; i < images.length; i++) {
190
+ const img = images[i];
191
+ if (!isAllowedChatGptImageUrl(img.url))
192
+ continue;
193
+ try {
194
+ const resp = await fetch(img.url, {
195
+ headers: {
196
+ Cookie: cookieHeader,
197
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
198
+ },
199
+ redirect: 'follow',
200
+ });
201
+ if (!resp.ok)
202
+ continue;
203
+ const contentType = resp.headers.get('content-type') || 'image/png';
204
+ const ext = contentType.includes('jpeg') || contentType.includes('jpg') ? '.jpg'
205
+ : contentType.includes('webp') ? '.webp'
206
+ : contentType.includes('gif') ? '.gif'
207
+ : '.png';
208
+ const buffer = Buffer.from(await resp.arrayBuffer());
209
+ let savePath;
210
+ const explicitPath = outputPaths[i];
211
+ if (explicitPath) {
212
+ const dir = dirname(explicitPath);
213
+ if (!existsSync(dir))
214
+ mkdirSync(dir, { recursive: true });
215
+ writeFileSync(explicitPath, buffer);
216
+ savePath = explicitPath;
217
+ }
218
+ else if (sessionId) {
219
+ const desc = saveImageArtifact(sessionId, {
220
+ filename: `image-${i + 1}${ext}`,
221
+ buffer,
222
+ mimeType: contentType,
223
+ sourceUrl: img.url,
224
+ });
225
+ appendSessionArtifact(sessionId, desc);
226
+ savePath = join(resolveArtifactsDir(sessionId), desc.path);
227
+ }
228
+ else {
229
+ continue;
230
+ }
231
+ results.push({
232
+ path: savePath,
233
+ mimeType: contentType,
234
+ sizeBytes: buffer.length,
235
+ sourceUrl: img.url,
236
+ fileId: img.fileId,
237
+ });
238
+ }
239
+ catch {
240
+ continue;
241
+ }
242
+ }
243
+ return results;
244
+ }
245
+ /** Collect generated images from a ChatGPT response (detect → wait → download). */
246
+ export async function collectImages(cdpSession, { baselineAssistantCount = 0, outputPath = null, sessionId = null, waitTimeoutMs = DEFAULT_IMAGE_WAIT_TIMEOUT_MS, } = {}) {
247
+ const explicitOutputRequested = outputPath !== null && outputPath !== undefined;
248
+ let images = await detectGeneratedImages(cdpSession, { baselineAssistantCount });
249
+ if (!images.length && (outputPath || sessionId)) {
250
+ const deadline = Date.now() + resolveGeneratedImageWaitTimeoutMs(waitTimeoutMs);
251
+ while (Date.now() < deadline) {
252
+ await new Promise((r) => setTimeout(r, 1500));
253
+ images = await detectGeneratedImages(cdpSession, { baselineAssistantCount });
254
+ if (images.length)
255
+ break;
256
+ }
257
+ }
258
+ if (!images.length) {
259
+ return {
260
+ images: [],
261
+ savedPaths: [],
262
+ markdownSuffix: '',
263
+ warnings: [],
264
+ errors: explicitOutputRequested ? ['no generated image detected for explicit output path'] : [],
265
+ explicitOutputRequested,
266
+ };
267
+ }
268
+ const downloaded = await downloadGeneratedImages(cdpSession, images, { outputPath, sessionId });
269
+ const savedPaths = downloaded.map((d) => d.path);
270
+ const errors = explicitOutputRequested && savedPaths.length === 0
271
+ ? ['generated images were detected but no image file could be saved']
272
+ : [];
273
+ const warnings = !explicitOutputRequested && images.length > 0 && savedPaths.length === 0
274
+ ? ['generated images were detected but implicit artifact save failed or was unavailable']
275
+ : [];
276
+ const markdownSuffix = savedPaths.length
277
+ ? '\n\n' + savedPaths.map((p, i) => `![Generated image ${i + 1}](${p})`).join('\n')
278
+ : '';
279
+ return { images, savedPaths, markdownSuffix, warnings, errors, explicitOutputRequested };
280
+ }
281
+ //# sourceMappingURL=chatgpt-images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatgpt-images.js","sourceRoot":"","sources":["../../../../src/browser/web-ai/chatgpt-images.ts"],"names":[],"mappings":"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"}