agentbox-app 0.1.12 → 0.1.16

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 (370) hide show
  1. package/README.md +24 -9
  2. package/bin/agentbox.mjs +23 -1
  3. package/briefs/message-rules.md +36 -8
  4. package/briefs/worker.md +46 -23
  5. package/main/account-discovery.mjs +122 -30
  6. package/main/account-tooling.mjs +29 -1
  7. package/main/account-usage.mjs +46 -0
  8. package/main/acp.mjs +296 -0
  9. package/main/agent-homes.mjs +158 -0
  10. package/main/agent-sessions.mjs +311 -260
  11. package/main/agent-updates.mjs +9 -22
  12. package/main/agents.mjs +179 -466
  13. package/main/analytics.mjs +42 -2
  14. package/main/answer-modes.mjs +103 -37
  15. package/main/approval-prompt-core.mjs +197 -0
  16. package/main/approval-prompt-server.mjs +4 -138
  17. package/main/approvals.mjs +101 -297
  18. package/main/artifact-path.mjs +47 -18
  19. package/main/claude-bin.mjs +45 -311
  20. package/main/claude-input.mjs +57 -7
  21. package/main/claude-launch-env.mjs +54 -0
  22. package/main/claude-models.mjs +39 -7
  23. package/main/claude-plan.mjs +64 -16
  24. package/main/claude-session-open.mjs +28 -0
  25. package/main/claude-usage-process.mjs +40 -0
  26. package/main/claude-usage.mjs +94 -59
  27. package/main/cloud/account.mjs +179 -0
  28. package/main/cloud/aws.mjs +127 -0
  29. package/main/cloud/browser-return.mjs +58 -0
  30. package/main/cloud/clients.mjs +15 -0
  31. package/main/cloud/codex-cloud.mjs +53 -0
  32. package/main/cloud/config.mjs +107 -0
  33. package/main/cloud/docs.mjs +219 -0
  34. package/main/cloud/exec.mjs +27 -0
  35. package/main/cloud/host.mjs +165 -0
  36. package/main/cloud/kit.mjs +80 -0
  37. package/main/cloud/logins.mjs +543 -0
  38. package/main/cloud/managed.mjs +115 -0
  39. package/main/cloud/marker.mjs +104 -0
  40. package/main/cloud/org.mjs +53 -0
  41. package/main/cloud/reuse.mjs +208 -0
  42. package/main/cloud/run-cli.mjs +177 -0
  43. package/main/cloud/run.mjs +1934 -0
  44. package/main/cloud/usage.mjs +76 -0
  45. package/main/cloud-permission.mjs +51 -0
  46. package/main/codex-account.mjs +78 -0
  47. package/main/codex-app-server.mjs +276 -409
  48. package/main/codex-approvals.mjs +148 -433
  49. package/main/codex-bin.mjs +51 -249
  50. package/main/codex-models.mjs +20 -2
  51. package/main/codex-session.mjs +246 -506
  52. package/main/codex-threads-worker.mjs +12 -0
  53. package/main/codex-threads.mjs +112 -11
  54. package/main/codex-usage-file.mjs +5 -3
  55. package/main/codex-usage.mjs +56 -7
  56. package/main/codex-watch.mjs +83 -5
  57. package/main/codex.mjs +95 -363
  58. package/main/config.mjs +37 -5
  59. package/main/corner-tag.mjs +810 -0
  60. package/main/crash-report.mjs +26 -3
  61. package/main/dev-window.mjs +1 -1
  62. package/main/engine-bin.mjs +545 -0
  63. package/main/engine-setup.mjs +25 -24
  64. package/main/feedback.mjs +14 -31
  65. package/main/folder-pictures.mjs +2 -2
  66. package/main/freeze-recorder-thread.mjs +86 -0
  67. package/main/freeze-recorder.mjs +146 -0
  68. package/main/fresh-user.mjs +20 -9
  69. package/main/git-change-offthread.mjs +17 -3
  70. package/main/git-change-thread.mjs +5 -2
  71. package/main/harnesses/claude-stream.mjs +208 -0
  72. package/main/harnesses/claude.mjs +105 -0
  73. package/main/harnesses/codex.mjs +72 -0
  74. package/main/harnesses/common.mjs +78 -0
  75. package/main/harnesses/instructions-file.mjs +116 -0
  76. package/main/harnesses/opencode.mjs +234 -0
  77. package/main/harnesses.mjs +65 -0
  78. package/main/importable-threads.mjs +96 -0
  79. package/main/ipc.mjs +520 -135
  80. package/main/leftovers.mjs +117 -25
  81. package/main/liquid-glass.mjs +26 -0
  82. package/main/live-replies.mjs +10 -4
  83. package/main/local-app-frames.mjs +82 -0
  84. package/main/main-went-red.mjs +330 -0
  85. package/main/main.mjs +248 -37
  86. package/main/memory-gate-history.mjs +85 -20
  87. package/main/memory-gate-server.mjs +129 -11
  88. package/main/memory-gate.mjs +62 -8
  89. package/main/memory-log.mjs +124 -0
  90. package/main/menu.mjs +4 -2
  91. package/main/message-priority.mjs +2 -2
  92. package/main/mic.mjs +38 -0
  93. package/main/native/liquid-glass/build/liquid-glass.node +0 -0
  94. package/main/new-chats-watch.mjs +110 -0
  95. package/main/new-user-window.mjs +25 -0
  96. package/main/notify.mjs +64 -5
  97. package/main/opencode-server.mjs +271 -0
  98. package/main/opencode.mjs +287 -0
  99. package/main/phone-alerts.mjs +117 -0
  100. package/main/phone-inbox.mjs +625 -0
  101. package/main/phone-link.mjs +571 -0
  102. package/main/phone-uploads.mjs +476 -0
  103. package/main/picture-shape.mjs +114 -0
  104. package/main/quit-sequence.mjs +143 -0
  105. package/main/refresh-agent-models.mjs +15 -2
  106. package/main/relay-address.mjs +28 -0
  107. package/main/relay-client.mjs +314 -0
  108. package/main/repeats.mjs +10 -4
  109. package/main/row-label.mjs +18 -47
  110. package/main/run-change.mjs +13 -0
  111. package/main/run-ledger.mjs +135 -0
  112. package/main/runs-on.mjs +32 -35
  113. package/main/save-attachments.mjs +41 -0
  114. package/main/serve.mjs +155 -9
  115. package/main/settings.mjs +364 -50
  116. package/main/shell-path.mjs +234 -0
  117. package/main/ship-conflict-brief.mjs +119 -0
  118. package/main/ship-queue.mjs +134 -20
  119. package/main/sign-in-files.mjs +3 -7
  120. package/main/source-updater.mjs +45 -11
  121. package/main/stage-attachment.mjs +68 -0
  122. package/main/stall-watch.mjs +50 -0
  123. package/main/start-hold.mjs +73 -0
  124. package/main/store/home.mjs +87 -232
  125. package/main/store/paths.mjs +11 -0
  126. package/main/store/teammates-files.mjs +99 -0
  127. package/main/store/work-items.mjs +231 -13
  128. package/main/store.mjs +227 -53
  129. package/main/supervisor.mjs +3865 -699
  130. package/main/task-commands.mjs +13 -17
  131. package/main/task-folders-offthread.mjs +6 -1
  132. package/main/task-folders.mjs +897 -105
  133. package/main/task-terminals.mjs +147 -41
  134. package/main/team/index.mjs +114 -10
  135. package/main/team/memory-cloud.mjs +183 -1
  136. package/main/team/room-hours.mjs +48 -0
  137. package/main/team/room-setup.mjs +31 -0
  138. package/main/team/rooms-memory.mjs +454 -0
  139. package/main/team/rooms-shape.mjs +42 -0
  140. package/main/team/rooms-supabase.mjs +324 -0
  141. package/main/team/rooms.mjs +575 -0
  142. package/main/team/session.mjs +96 -26
  143. package/main/team/supabase-backend.mjs +180 -0
  144. package/main/team/sync.mjs +109 -1
  145. package/main/teammates.mjs +580 -0
  146. package/main/terminal-host.mjs +143 -0
  147. package/main/terminal-hosts.mjs +261 -0
  148. package/main/transcript-search.mjs +80 -0
  149. package/main/updater.mjs +71 -9
  150. package/main/webview-guard.mjs +45 -0
  151. package/main/worktree-include.mjs +365 -0
  152. package/mcp/core/documents.mjs +3 -1
  153. package/mcp/core/repeats.mjs +88 -0
  154. package/mcp/core/teammates.mjs +222 -0
  155. package/mcp/core/work.mjs +76 -4
  156. package/mcp/stdio.mjs +24 -11
  157. package/mcp/tools.mjs +116 -8
  158. package/package.json +30 -5
  159. package/renderer/dist/assets/abnfDiagram-YUKMZFIV-CoWB6YUK.js +1 -0
  160. package/renderer/dist/assets/arc-Ch0NrCul.js +1 -0
  161. package/renderer/dist/assets/architectureDiagram-47P4ROYG-CXz9M5tQ.js +36 -0
  162. package/renderer/dist/assets/blockDiagram-E7TT5TSB-DchGUuHH.js +140 -0
  163. package/renderer/dist/assets/c4Diagram-CRA5TL53-Cip-zNyr.js +38 -0
  164. package/renderer/dist/assets/channel-BQuQSL--.js +1 -0
  165. package/renderer/dist/assets/chunk-2Q5K7J3B-BoXid_2r.js +1 -0
  166. package/renderer/dist/assets/chunk-5VM5RSS4-Cpez1rRz.js +15 -0
  167. package/renderer/dist/assets/chunk-7TKQ45FW-DKA84YkE.js +1 -0
  168. package/renderer/dist/assets/chunk-AW2ZBBNX-Dg-SumPG.js +88 -0
  169. package/renderer/dist/assets/chunk-FVRAUYC3-06TCvPm1.js +2 -0
  170. package/renderer/dist/assets/chunk-HTAEGDNF-CMEBy1Td.js +1 -0
  171. package/renderer/dist/assets/chunk-JWPE2WC7-BJ2ObmV-.js +1 -0
  172. package/renderer/dist/assets/chunk-KQW6MTUR-CGWOYXUE.js +1 -0
  173. package/renderer/dist/assets/chunk-XXDRQBXY-CiZp07XC.js +1 -0
  174. package/renderer/dist/assets/classDiagram-v2-K4WV4PDN-DJNIX719.js +217 -0
  175. package/renderer/dist/assets/cornerTag-CPgvu-q3.js +1 -0
  176. package/renderer/dist/assets/cornerTag-oMfEjzCO.css +1 -0
  177. package/renderer/dist/assets/cose-bilkent-JH36ORCC-CbkyZOUH.js +1 -0
  178. package/renderer/dist/assets/cynefin-EF2NZ3EQ-78iOroZO.js +141 -0
  179. package/renderer/dist/assets/cynefinDiagram-3GCD6N5R-GcCopMs7.js +62 -0
  180. package/renderer/dist/assets/cytoscape.esm-C5JX3QLV.js +331 -0
  181. package/renderer/dist/assets/dagre-W4DXFKR2-DHLlXLkz.js +4 -0
  182. package/renderer/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  183. package/renderer/dist/assets/diagram-2UJZ2QOL-DuZSUHcH.js +200 -0
  184. package/renderer/dist/assets/diagram-OVF4WLC6-Ckxu3cqH.js +24 -0
  185. package/renderer/dist/assets/diagram-PFPMY2P6-CsTw9Ycn.js +30 -0
  186. package/renderer/dist/assets/diagram-UMYRVEAY-CTXd8qVg.js +24 -0
  187. package/renderer/dist/assets/diagram-YEKJPTXX-CJs1T_9m.js +41 -0
  188. package/renderer/dist/assets/diagram-ZIFT7M5P-CvjI23mf.js +3 -0
  189. package/renderer/dist/assets/ebnfDiagram-VR2GEFS7-d_IeAzOJ.js +1 -0
  190. package/renderer/dist/assets/elk-IJKZMXRS-zo9KFP3N.js +27 -0
  191. package/renderer/dist/assets/erDiagram-O2IAPWRE-DqfYf5Dt.js +99 -0
  192. package/renderer/dist/assets/flowDiagram-OXPTDLAJ-DAWsMLmo.js +213 -0
  193. package/renderer/dist/assets/ganttDiagram-R7TSEDQI-4ml_bhwR.js +292 -0
  194. package/renderer/dist/assets/gitGraphDiagram-XJZIOB7I-B_WcqSId.js +106 -0
  195. package/renderer/dist/assets/graph-DGbsTEsI.js +1 -0
  196. package/renderer/dist/assets/infoDiagram-5W2HQ5XZ-CI-jYqzc.js +2 -0
  197. package/renderer/dist/assets/init-Gi6I4Gst.js +1 -0
  198. package/renderer/dist/assets/ishikawaDiagram-K3B6WC7H-B56VWRlV.js +70 -0
  199. package/renderer/dist/assets/journeyDiagram-COXZFDF6-D1-p09Lr.js +139 -0
  200. package/renderer/dist/assets/kanban-definition-P3RFRI5V-Cv3w7JoN.js +89 -0
  201. package/renderer/dist/assets/katex-C5jXJg4s.js +257 -0
  202. package/renderer/dist/assets/linear-C35V2Spi.js +1 -0
  203. package/renderer/dist/assets/main-BcoBiGwv.css +32 -0
  204. package/renderer/dist/assets/main-CLnIOulD.js +1191 -0
  205. package/renderer/dist/assets/mermaid.core-BzGT5Vo9.js +314 -0
  206. package/renderer/dist/assets/mindmap-definition-LZFPQGKD-BZUfuymC.js +96 -0
  207. package/renderer/dist/assets/ordinal-Cboi1Yqb.js +1 -0
  208. package/renderer/dist/assets/pegDiagram-BGZESJAR-DFh9XNGe.js +1 -0
  209. package/renderer/dist/assets/pieDiagram-CAPJLFHJ-C65tPVsy.js +39 -0
  210. package/renderer/dist/assets/product-name-CSNW6d7s.js +40 -0
  211. package/renderer/dist/assets/quadrantDiagram-GDMTTRAM-Cushj_nk.js +7 -0
  212. package/renderer/dist/assets/railroadDiagram-SM67HX2B-DZGebGx5.js +1 -0
  213. package/renderer/dist/assets/requirementDiagram-X7JNWC4A-DpAB0MNo.js +84 -0
  214. package/renderer/dist/assets/sankeyDiagram-UM26HJRW-D-29rHra.js +40 -0
  215. package/renderer/dist/assets/sequenceDiagram-ZO4K6R2Y-FfOQAZol.js +169 -0
  216. package/renderer/dist/assets/sizeCapture-INFHLROL-C_n6fDBY.js +1 -0
  217. package/renderer/dist/assets/stateDiagram-v2-TBUQTH76-BZjenzJG.js +291 -0
  218. package/renderer/dist/assets/swimlanes-N4OXWK64-DxaMU9vX.js +1 -0
  219. package/renderer/dist/assets/swimlanesDiagram-K3J5GTZL-Cb2kM6rr.js +8 -0
  220. package/renderer/dist/assets/timeline-definition-YOQAKGHF-DTg5HJKz.js +120 -0
  221. package/renderer/dist/assets/usecaseDiagram-VIAY4XPW-Bc3MZDsl.js +370 -0
  222. package/renderer/dist/assets/vennDiagram-BLWOH2XV-GIVGk9Id.js +34 -0
  223. package/renderer/dist/assets/wardleyDiagram-YMQ3BMBF-NmJnbQOg.js +78 -0
  224. package/renderer/dist/assets/xychartDiagram-TAQBALBS-p-kfGfnW.js +7 -0
  225. package/renderer/dist/corner-tag.html +13 -0
  226. package/renderer/dist/emulator/audio-rules.mjs +74 -0
  227. package/renderer/dist/emulator/data/compression/README.md +11 -0
  228. package/renderer/dist/emulator/data/compression/extract7z.js +1 -0
  229. package/renderer/dist/emulator/data/compression/extractzip.js +1 -0
  230. package/renderer/dist/emulator/data/compression/libunrar.js +519 -0
  231. package/renderer/dist/emulator/data/compression/libunrar.wasm +0 -0
  232. package/renderer/dist/emulator/data/cores/README.md +22 -0
  233. package/renderer/dist/emulator/data/cores/mgba-legacy-wasm.data +0 -0
  234. package/renderer/dist/emulator/data/cores/mgba-thread-legacy-wasm.data +0 -0
  235. package/renderer/dist/emulator/data/cores/mgba-thread-wasm.data +0 -0
  236. package/renderer/dist/emulator/data/cores/mgba-wasm.data +0 -0
  237. package/renderer/dist/emulator/data/cores/package.json +65 -0
  238. package/renderer/dist/emulator/data/cores/reports/mgba.json +1 -0
  239. package/renderer/dist/emulator/data/emulator.css +1614 -0
  240. package/renderer/dist/emulator/data/loader.js +170 -0
  241. package/renderer/dist/emulator/data/localization/README.md +63 -0
  242. package/renderer/dist/emulator/data/localization/af-FR.json +339 -0
  243. package/renderer/dist/emulator/data/localization/ar-AR.json +301 -0
  244. package/renderer/dist/emulator/data/localization/ben-BEN.json +301 -0
  245. package/renderer/dist/emulator/data/localization/de-GER.json +301 -0
  246. package/renderer/dist/emulator/data/localization/el-GR.json +301 -0
  247. package/renderer/dist/emulator/data/localization/en-US.json +339 -0
  248. package/renderer/dist/emulator/data/localization/es-ES.json +310 -0
  249. package/renderer/dist/emulator/data/localization/fa-AF.json +310 -0
  250. package/renderer/dist/emulator/data/localization/hi-HI.json +301 -0
  251. package/renderer/dist/emulator/data/localization/it-IT.json +302 -0
  252. package/renderer/dist/emulator/data/localization/ja-JA.json +301 -0
  253. package/renderer/dist/emulator/data/localization/jv-JV.json +301 -0
  254. package/renderer/dist/emulator/data/localization/ko-KO.json +336 -0
  255. package/renderer/dist/emulator/data/localization/pt-BR.json +361 -0
  256. package/renderer/dist/emulator/data/localization/retroarch.json +617 -0
  257. package/renderer/dist/emulator/data/localization/ro-RO.json +310 -0
  258. package/renderer/dist/emulator/data/localization/ru-RU.json +301 -0
  259. package/renderer/dist/emulator/data/localization/tr-TR.json +310 -0
  260. package/renderer/dist/emulator/data/localization/vi-VN.json +302 -0
  261. package/renderer/dist/emulator/data/localization/zh-CN.json +351 -0
  262. package/renderer/dist/emulator/data/src/GameManager.js +464 -0
  263. package/renderer/dist/emulator/data/src/compression.js +142 -0
  264. package/renderer/dist/emulator/data/src/emulator.js +6158 -0
  265. package/renderer/dist/emulator/data/src/gamepad.js +167 -0
  266. package/renderer/dist/emulator/data/src/nipplejs.js +1 -0
  267. package/renderer/dist/emulator/data/src/shaders.js +236 -0
  268. package/renderer/dist/emulator/data/src/socket.io.min.js +7 -0
  269. package/renderer/dist/emulator/data/src/storage.js +125 -0
  270. package/renderer/dist/emulator/data/version.json +5 -0
  271. package/renderer/dist/emulator/host.js +297 -0
  272. package/renderer/dist/emulator/index.html +28 -0
  273. package/renderer/dist/emulator/provenance.json +6 -0
  274. package/renderer/dist/index.html +16 -3
  275. package/scripts/after-install.mjs +30 -8
  276. package/scripts/approval-server.sh +24 -5
  277. package/scripts/before-publish.mjs +12 -10
  278. package/scripts/cloud-shim.pl +57 -0
  279. package/shared/account-names.d.mts +6 -0
  280. package/shared/account-names.mjs +15 -0
  281. package/shared/agent-hours.mjs +136 -0
  282. package/shared/agent-import.mjs +62 -34
  283. package/shared/agents.d.mts +1 -0
  284. package/shared/agents.mjs +126 -522
  285. package/shared/analytics-events.mjs +12 -0
  286. package/shared/approval-card.mjs +36 -0
  287. package/shared/bridge-map.mjs +45 -1
  288. package/shared/claude-code-shape.mjs +6 -0
  289. package/shared/claude-commands.generated.mjs +6 -4
  290. package/shared/claude-models.generated.mjs +6 -4
  291. package/shared/claude-usage.d.mts +1 -0
  292. package/shared/claude-usage.mjs +42 -1
  293. package/shared/cloud-hand-back.d.mts +7 -0
  294. package/shared/cloud-hand-back.mjs +20 -0
  295. package/shared/cloud-kit.d.mts +219 -0
  296. package/shared/cloud-kit.mjs +341 -0
  297. package/shared/cloud-login-name.mjs +4 -0
  298. package/shared/cloud-start.mjs +17 -0
  299. package/shared/cloud-versions.mjs +23 -0
  300. package/shared/codex-import.mjs +2 -2
  301. package/shared/codex-modes.d.mts +22 -9
  302. package/shared/codex-modes.mjs +67 -11
  303. package/shared/codex-usage.mjs +108 -2
  304. package/shared/corner-tag.d.mts +36 -0
  305. package/shared/corner-tag.mjs +396 -0
  306. package/shared/dead-run-trace.mjs +19 -2
  307. package/shared/engines.mjs +76 -300
  308. package/shared/feedback.d.mts +7 -0
  309. package/shared/feedback.mjs +25 -0
  310. package/shared/first-run-practice.mjs +17 -24
  311. package/shared/harness-definitions.mjs +111 -0
  312. package/shared/instruction-defaults.json +2 -2
  313. package/shared/key-caps.d.mts +14 -0
  314. package/shared/key-caps.mjs +68 -0
  315. package/shared/message-edits.d.mts +7 -0
  316. package/shared/message-edits.mjs +35 -0
  317. package/shared/move-thread.d.mts +24 -0
  318. package/shared/move-thread.mjs +112 -0
  319. package/shared/named-threads.mjs +72 -0
  320. package/shared/not-shipped.d.mts +22 -0
  321. package/shared/not-shipped.mjs +89 -0
  322. package/shared/notify-rules.d.mts +31 -0
  323. package/shared/notify-rules.mjs +55 -8
  324. package/shared/phone-files.mjs +28 -0
  325. package/shared/phone-settings.mjs +118 -0
  326. package/shared/phone-snapshot.d.mts +16 -0
  327. package/shared/phone-snapshot.mjs +348 -0
  328. package/shared/picture-formats.d.mts +1 -0
  329. package/shared/picture-formats.mjs +13 -0
  330. package/shared/provider-commands.mjs +10 -2
  331. package/shared/rank.d.mts +4 -1
  332. package/shared/rank.mjs +82 -19
  333. package/shared/relay-address.mjs +6 -0
  334. package/shared/relay-crypto.mjs +165 -0
  335. package/shared/repeats.d.mts +8 -0
  336. package/shared/repeats.mjs +33 -2
  337. package/shared/room-cards.mjs +167 -0
  338. package/shared/room-links.d.mts +4 -0
  339. package/shared/room-links.mjs +21 -0
  340. package/shared/runs-on.d.mts +3 -13
  341. package/shared/runs-on.mjs +31 -52
  342. package/shared/shipped-note.d.mts +4 -0
  343. package/shared/shipped-note.mjs +6 -0
  344. package/shared/shortcuts.mjs +24 -10
  345. package/shared/spawn-trouble.d.mts +4 -0
  346. package/shared/spawn-trouble.mjs +484 -30
  347. package/shared/team-rules.mjs +9 -2
  348. package/shared/teammates.d.mts +19 -0
  349. package/shared/teammates.mjs +756 -0
  350. package/shared/terminal-focus.d.mts +1 -0
  351. package/shared/terminal-focus.mjs +13 -0
  352. package/shared/terminal-input.d.mts +1 -0
  353. package/shared/terminal-input.mjs +30 -0
  354. package/shared/terminal-keys.d.mts +1 -0
  355. package/shared/terminal-keys.mjs +16 -0
  356. package/shared/terminal-size.d.mts +4 -0
  357. package/shared/terminal-size.mjs +29 -0
  358. package/shared/thread-cards.mjs +4 -1
  359. package/shared/usage.d.mts +12 -0
  360. package/shared/usage.mjs +56 -3
  361. package/shared/websites.d.mts +15 -0
  362. package/shared/websites.mjs +61 -0
  363. package/shared/where-it-runs-from.d.mts +43 -0
  364. package/shared/where-it-runs-from.mjs +155 -0
  365. package/shared/work-items.mjs +150 -29
  366. package/shared/work-lines.mjs +93 -245
  367. package/shared/xterm-invalid-range.d.mts +2 -0
  368. package/shared/xterm-invalid-range.mjs +58 -0
  369. package/renderer/dist/assets/index-ChKsQkRw.js +0 -1169
  370. package/renderer/dist/assets/index-ClBXnq3B.css +0 -32
@@ -0,0 +1,287 @@
1
+ // READING AN OPENCODE RUN, IN OPENCODE'S OWN WORDS.
2
+ //
3
+ // The same five readers Claude Code and Codex each provide -- capture, live
4
+ // text, summary, trace, activity -- over OpenCode's `/event` stream. Nothing
5
+ // here translates an OpenCode event into a pretend Claude JSON line or a
6
+ // pretend Codex notification, for the reason docs/harnesses.md gives: the
7
+ // vocabularies are not the same shape and a fake one loses what the real one
8
+ // carries. OpenCode's `edit` approval, for instance, arrives with a whole
9
+ // unified diff in it, which neither of the other two does.
10
+ //
11
+ // EVERY SHAPE BELOW WAS READ OFF A RUNNING OPENCODE 1.18.35 ON 2026-10-07,
12
+ // not off the docs, which do not enumerate the event payloads at all. The
13
+ // ones that matter:
14
+ //
15
+ // session.updated properties.info.{cost,tokens,title,model,directory}
16
+ // message.part.updated properties.part.type: text | reasoning | tool |
17
+ // step-start | step-finish
18
+ // message.part.delta properties.{partID,field,delta} ("field":"text")
19
+ // permission.asked properties.{id,sessionID,permission,patterns,
20
+ // metadata:{command} | metadata:{filepath,diff}}
21
+ // session.idle properties.sessionID
22
+ // session.error properties.{sessionID,error}
23
+ //
24
+ // A tool part carries `state.status` of pending | running | completed | error,
25
+ // with `state.input`, `state.output` and `state.error` beside it.
26
+
27
+ /** How much streamed prose is kept before it is dropped, as the others do. */
28
+ const SAYING_CAP = 20_000;
29
+
30
+ /** Tool names worth naming on the row, in the words a person would use. */
31
+ const TOOL_WORDS = {
32
+ bash: 'Bash', edit: 'Edit', write: 'Write', read: 'Read', glob: 'Glob',
33
+ grep: 'Grep', list: 'List', webfetch: 'Fetch', websearch: 'Search',
34
+ task: 'Task', todowrite: 'Todo', patch: 'Edit', skill: 'Skill',
35
+ };
36
+
37
+ const toolWord = name => {
38
+ const id = String(name ?? '').trim();
39
+ if (!id) return null;
40
+ return TOOL_WORDS[id.toLowerCase()] ?? id;
41
+ };
42
+
43
+ const partOf = properties => (properties && typeof properties === 'object' ? properties.part ?? null : null);
44
+
45
+ /**
46
+ * WHAT THE RUN WAS, kept on the session as it goes.
47
+ *
48
+ * `sessionId` is the one OpenCode resumes by, and it is on nearly every event
49
+ * as `properties.sessionID`. It is taken from the first event that carries one
50
+ * rather than from the session-creation response, so a resumed run and a fresh
51
+ * one record it the same way.
52
+ *
53
+ * The result is the LAST assistant text of the turn. OpenCode has no single
54
+ * "here is the answer" event the way Codex's `turn/completed` does: prose
55
+ * arrives as `text` parts that are updated in place, and the final one is the
56
+ * answer. So each completed text part overwrites the last, and whatever is
57
+ * standing when the session goes idle is the result.
58
+ */
59
+ export function captureOpenCodeEvent(session, type, properties) {
60
+ try {
61
+ if (!session || typeof type !== 'string') return;
62
+ const p = properties ?? {};
63
+ if (!session.sessionId && typeof p.sessionID === 'string' && p.sessionID) session.sessionId = p.sessionID;
64
+
65
+ if (type === 'session.updated') {
66
+ const info = p.info ?? {};
67
+ if (Number.isFinite(info.cost)) session.opencodeCost = info.cost;
68
+ if (info.tokens && typeof info.tokens === 'object') session.opencodeTokens = info.tokens;
69
+ return;
70
+ }
71
+
72
+ if (type === 'session.error') {
73
+ session.result = openCodeErrorText(p.error) ?? 'OpenCode stopped with an error it did not name.';
74
+ session.resultIsError = true;
75
+ return;
76
+ }
77
+
78
+ if (type === 'message.part.updated') {
79
+ const part = partOf(p);
80
+ if (!part) return;
81
+ // A WRITE THIS RUN MADE, so the card can say what changed. The `edit` and
82
+ // `write` tools report the file they touched in `state.input.filePath`,
83
+ // which is the only place a path appears for a change OpenCode has
84
+ // already applied.
85
+ if (part.type === 'tool' && part.state?.status === 'completed') {
86
+ const path = part.state?.input?.filePath ?? part.state?.input?.path;
87
+ if (typeof path === 'string' && path && (part.tool === 'edit' || part.tool === 'write' || part.tool === 'patch')) {
88
+ session.opencodeChange ??= [];
89
+ if (!session.opencodeChange.includes(path)) session.opencodeChange.push(path);
90
+ }
91
+ }
92
+ if (part.type === 'step-finish') {
93
+ if (Number.isFinite(part.cost)) session.opencodeStepCost = part.cost;
94
+ if (part.tokens && typeof part.tokens === 'object') session.opencodeTokens = part.tokens;
95
+ }
96
+ // Only the assistant's prose is an answer. `reasoning` is the model
97
+ // thinking out loud and is never the result, which is why it is matched
98
+ // by name here rather than falling through to the text branch.
99
+ if (part.type === 'text') {
100
+ const text = String(part.text ?? '').trim();
101
+ if (text) { session.result = text; session.resultIsError = false; }
102
+ }
103
+ return;
104
+ }
105
+ } catch {
106
+ // A reader that throws kills a run that was going fine. Same rule as the
107
+ // other two harnesses: read what parses and ignore what does not.
108
+ }
109
+ }
110
+
111
+ /** The error on `session.error`, which is an object and not a string. */
112
+ export function openCodeErrorText(error) {
113
+ if (!error) return null;
114
+ if (typeof error === 'string') return error.trim() || null;
115
+ const name = typeof error.name === 'string' ? error.name : '';
116
+ const message = typeof error.data?.message === 'string' ? error.data.message
117
+ : typeof error.message === 'string' ? error.message : '';
118
+ const joined = [name, message].filter(Boolean).join(': ');
119
+ return joined || null;
120
+ }
121
+
122
+ /**
123
+ * THE PROSE AS IT IS TYPED, for the line on the row that moves.
124
+ *
125
+ * Deltas arrive as `message.part.delta` with a `field` saying which field of
126
+ * which part is growing. Only `text` is shown: `reasoning` deltas are the
127
+ * model's private thinking, and streaming those onto her row would put words
128
+ * on screen that are not what the run decided.
129
+ */
130
+ export function openCodeStreamingText(session, type, properties) {
131
+ try {
132
+ if (!session) return false;
133
+ const p = properties ?? {};
134
+
135
+ if (type === 'message.part.updated') {
136
+ const part = partOf(p);
137
+ // A tool starting means the talking stopped. What is already typed stays
138
+ // until the trace carries the same words, exactly as Codex's reader does.
139
+ if (part?.type === 'text' && !String(part.text ?? '')) { session.saying = ''; session.sayingAt = Date.now(); return true; }
140
+ return false;
141
+ }
142
+
143
+ if (type !== 'message.part.delta') return false;
144
+ if (p.field !== 'text') return false;
145
+ const piece = String(p.delta ?? '');
146
+ if (!piece) return false;
147
+ // A delta for a reasoning part has the same `field: "text"`, so the part it
148
+ // belongs to is what tells them apart. Without a remembered prose part id
149
+ // nothing is streamed, which is the quiet answer rather than the wrong one.
150
+ if (session.opencodeProsePart && p.partID && p.partID !== session.opencodeProsePart) return false;
151
+ if (!session.sayingAt) session.sayingAt = Date.now();
152
+ const next = (session.saying ?? '') + piece;
153
+ session.saying = next.length > SAYING_CAP ? '' : next;
154
+ return true;
155
+ } catch {
156
+ return false;
157
+ }
158
+ }
159
+
160
+ /** Which part the prose is going into, so reasoning deltas can be told apart. */
161
+ export function rememberOpenCodeProsePart(session, type, properties) {
162
+ if (!session || type !== 'message.part.updated') return;
163
+ const part = partOf(properties);
164
+ if (part?.type === 'text' && typeof part.id === 'string') session.opencodeProsePart = part.id;
165
+ if (part?.type === 'step-start') session.opencodeProsePart = null;
166
+ }
167
+
168
+ /** One short line for the row: what it just did. */
169
+ export function summarizeOpenCodeEvent(type, properties) {
170
+ try {
171
+ const p = properties ?? {};
172
+ if (type !== 'message.part.updated') return null;
173
+ const part = partOf(p);
174
+ if (!part) return null;
175
+ if (part.type === 'text') {
176
+ const text = String(part.text ?? '').trim();
177
+ return text ? text.slice(0, 300) : null;
178
+ }
179
+ if (part.type === 'tool' && part.state?.status === 'completed') {
180
+ const word = toolWord(part.tool);
181
+ return word ? `tool: ${word}` : null;
182
+ }
183
+ return null;
184
+ } catch {
185
+ return null;
186
+ }
187
+ }
188
+
189
+ /** One line for the run trace, the record she can open afterwards. */
190
+ export function traceOpenCodeEvent(type, properties) {
191
+ try {
192
+ const p = properties ?? {};
193
+ const at = new Date().toISOString().slice(11, 19);
194
+
195
+ if (type === 'session.error') {
196
+ const text = openCodeErrorText(p.error);
197
+ return text ? `${at} [error] ${text.slice(0, 300)}` : null;
198
+ }
199
+
200
+ if (type !== 'message.part.updated') return null;
201
+ const part = partOf(p);
202
+ if (!part) return null;
203
+
204
+ if (part.type === 'text') {
205
+ const text = String(part.text ?? '').trim();
206
+ return text ? `${at} ${text}` : null;
207
+ }
208
+
209
+ if (part.type === 'tool' && (part.state?.status === 'completed' || part.state?.status === 'error')) {
210
+ const word = toolWord(part.tool);
211
+ if (!word) return null;
212
+ const input = part.state?.input ?? {};
213
+ const detail = String(input.command ?? input.filePath ?? input.path ?? input.pattern ?? '').trim();
214
+ const failed = part.state?.status === 'error' ? ' (refused)' : '';
215
+ return `${at} [${word}]${failed}${detail ? ` ${detail.slice(0, 200)}` : ''}`;
216
+ }
217
+
218
+ return null;
219
+ } catch {
220
+ return null;
221
+ }
222
+ }
223
+
224
+ /** What it is doing right now, for the row's activity line. */
225
+ export function openCodeActivity(type, properties) {
226
+ try {
227
+ if (type !== 'message.part.updated') return null;
228
+ const part = partOf(properties);
229
+ if (part?.type !== 'tool') return null;
230
+ if (part.state?.status !== 'pending' && part.state?.status !== 'running') return null;
231
+ const word = toolWord(part.tool);
232
+ return word ? { tool: word } : null;
233
+ } catch {
234
+ return null;
235
+ }
236
+ }
237
+
238
+ /**
239
+ * THE APPROVAL, IN THE WORDS A CARD NEEDS.
240
+ *
241
+ * `bash` asks carry `metadata.command`. `edit` asks carry `metadata.filepath`
242
+ * AND `metadata.diff`, a whole unified diff of the change it wants to make --
243
+ * measured, not assumed. That is strictly more than a Codex patch approval
244
+ * arrives with, and it means an OpenCode card can show the change itself
245
+ * rather than a filename.
246
+ */
247
+ export function openCodeApprovalCard(properties) {
248
+ const p = properties ?? {};
249
+ const kind = typeof p.permission === 'string' ? p.permission : '';
250
+ const metadata = p.metadata ?? {};
251
+ const command = typeof metadata.command === 'string' ? metadata.command.trim() : '';
252
+ const filepath = typeof metadata.filepath === 'string' ? metadata.filepath.trim() : '';
253
+ const diff = typeof metadata.diff === 'string' ? metadata.diff : '';
254
+ const patterns = Array.isArray(p.patterns) ? p.patterns.filter(x => typeof x === 'string') : [];
255
+
256
+ if (command) return { kind: kind || 'bash', title: 'Run a command', detail: command, command, patterns };
257
+ if (filepath) return { kind: kind || 'edit', title: 'Change a file', detail: filepath, filepath, diff, patterns };
258
+ return { kind: kind || 'tool', title: 'Use a tool', detail: patterns.join(', ') || kind || 'a tool', patterns };
259
+ }
260
+
261
+ /**
262
+ * THE PERMISSION POLICY A WORKER RUNS UNDER, as OpenCode's own config.
263
+ *
264
+ * This is the whole reason Agentbox can draw a card for OpenCode at all.
265
+ * Measured 2026-10-07: with no permission config the server runs shell
266
+ * commands and writes files with no card; with this config it raises
267
+ * `permission.asked` and waits. The server reports back what it loaded at
268
+ * `GET /config`, which is how the adapter can tell the policy really took.
269
+ *
270
+ * `read`, `glob`, `grep` and `list` are deliberately left alone: a card for
271
+ * every file read is the 2026-08-05 card flood again, and reading inside the
272
+ * task's own folder is what the folder is for.
273
+ */
274
+ export function openCodePermissionConfig() {
275
+ return {
276
+ $schema: 'https://opencode.ai/config.json',
277
+ permission: {
278
+ bash: 'ask',
279
+ edit: 'ask',
280
+ webfetch: 'ask',
281
+ websearch: 'ask',
282
+ external_directory: 'ask',
283
+ task: 'allow',
284
+ todowrite: 'allow',
285
+ },
286
+ };
287
+ }
@@ -0,0 +1,117 @@
1
+ // ALERTS ON HER PHONE'S LOCK SCREEN, SENT BY THIS MAC.
2
+ //
3
+ // The arrivals are the desktop banner's (main/notify.mjs, from App.tsx's
4
+ // inbox), and so are the rules (shared/notify-rules.mjs): nothing while she
5
+ // has used this Mac in the last five minutes, once per stretch away, once
6
+ // more for a permission card. They go out from the phone pass, after it has
7
+ // published, so the thread an alert opens is already on the phone. The
8
+ // server-side sender in docs/mobile/PLAN.md, which alerts with every Mac
9
+ // shut, is a later phase.
10
+ //
11
+ // The words are the phone banner's (phoneBanner): the thread's title in bold,
12
+ // asked for on 2026-10-13 and again on 2026-10-23, and nothing else of it.
13
+ import { atTheComputer, shouldSpeak, phoneBanner } from '../shared/notify-rules.mjs';
14
+
15
+ export const EXPO_PUSH = 'https://exp.host/--/api/v2/push/send';
16
+ // Arrivals this close together are one alert.
17
+ export const FOLD_MS = 3000;
18
+ const DEADLINE_MS = 10_000;
19
+ const ALERTED_KEPT_MS = 30 * 24 * 3600_000;
20
+
21
+ // renderer/src/phone-rows.ts phoneSlug, which the phone opens a thread by.
22
+ const phoneSlugOf = (device, project) => `${project}@${device}`;
23
+ const stampOf = (item) => `${item.status ?? ''}:${item.wrote?.status?.ts ?? item.updatedAt ?? ''}`;
24
+
25
+ /** One request for every phone; Expo answers a ticket for each, in order. */
26
+ export async function sendToExpo(messages, { fetchImpl = fetch, url = EXPO_PUSH, deadlineMs = DEADLINE_MS } = {}) {
27
+ const res = await fetchImpl(url, { method: 'POST', headers: { 'content-type': 'application/json', accept: 'application/json' }, body: JSON.stringify(messages), signal: AbortSignal.timeout(deadlineMs) });
28
+ const said = await res.json().catch(() => null);
29
+ if (!res.ok || !Array.isArray(said?.data)) throw new Error(`Expo answered ${res.status}${said?.errors?.[0]?.message ? `: ${said.errors[0].message}` : ''}`);
30
+ return said.data;
31
+ }
32
+
33
+ export function createPhoneAlerts({ backend, owner, device, state, save, now, log, idleMs, send = sendToExpo, still = () => {} }) {
34
+ state.alerted ??= {};
35
+ // In memory, as the desktop's banner keeps them: an arrival is news once.
36
+ const queued = new Map();
37
+ let firstAt = 0;
38
+ let needsYou = [];
39
+ let spoke = false;
40
+ let spokeAsk = false;
41
+ const said = new Set();
42
+ const once = (kind, line) => { if (!said.has(kind)) log(line); said.add(kind); };
43
+ const away = () => { try { return !atTheComputer({ idleMs: idleMs() }); } catch { return true; } };
44
+
45
+ function seen() {
46
+ queued.clear();
47
+ spoke = false;
48
+ spokeAsk = false;
49
+ }
50
+
51
+ /** What the desktop's notifier was told arrived, and the inbox it arrived in. */
52
+ function arrived(list, inbox = []) {
53
+ if (!Array.isArray(list) || !list.length) return;
54
+ if (!away()) return seen();
55
+ if (Array.isArray(inbox)) needsYou = inbox.filter((r) => r && typeof r.id === 'string' && typeof r.product === 'string');
56
+ for (const a of list) {
57
+ if (!a || typeof a.id !== 'string' || typeof a.product !== 'string') continue;
58
+ const ask = a.kind === 'approval';
59
+ const item = ask ? a.item : a.id;
60
+ if (typeof item !== 'string') continue;
61
+ if (!queued.size) firstAt = now();
62
+ queued.set(ask ? `ask:${a.id}` : `${a.product}:${a.id}`, { ask, product: a.product, item, title: a.title, thread: a.thread });
63
+ }
64
+ }
65
+
66
+ // `carried(slug, id)` is the thread's row when the phone has it, else null.
67
+ async function pass(carried) {
68
+ if (!away()) return seen();
69
+ if (!queued.size || now() - firstAt < FOLD_MS) return;
70
+ const fresh = [];
71
+ for (const [key, q] of queued) {
72
+ const row = carried(q.product, q.item);
73
+ if (!row) continue;
74
+ const stamp = q.ask ? 'asked' : stampOf(row);
75
+ if (state.alerted[key]?.stamp !== stamp) fresh.push({ key, stamp, ...q, named: row.title });
76
+ }
77
+ queued.clear();
78
+ if (!fresh.length || !shouldSpeak({ spoke, spokeAsk, waiting: fresh.map((f) => ({ kind: f.ask ? 'approval' : 'item' })) })) return;
79
+ still();
80
+ let phones;
81
+ try { phones = await backend.pushDevices(owner); } catch (err) { once('read', `phone: could not read the phones to alert: ${err?.message ?? err}`); return; }
82
+ if (!phones.length) return;
83
+ const threads = [...new Set(fresh.map((f) => `${f.product}\0${f.item}`))];
84
+ const [product, item] = threads[0].split('\0');
85
+ const badge = new Set(needsYou.filter((r) => carried(r.product, r.id)).map((r) => `${r.product}\0${r.id}`)).size;
86
+ const data = threads.length === 1 ? { product: phoneSlugOf(device, product), id: item } : {};
87
+ const say = phoneBanner(fresh.map((f) => (f.ask
88
+ ? { kind: 'approval', title: f.title, thread: f.thread || f.named }
89
+ : { kind: 'item', title: f.title || f.named })));
90
+ const messages = phones.map((p) => ({ to: p.token, title: say.title, body: say.body, sound: 'default', badge, priority: 'high', channelId: 'default', data }));
91
+ still();
92
+ let tickets;
93
+ try { tickets = await send(messages); } catch (err) { once('send', `phone: could not send an alert: ${err?.message ?? err}`); return; }
94
+ let reached = 0;
95
+ for (const [i, t] of (tickets ?? []).entries()) {
96
+ if (t?.status === 'ok') { reached += 1; continue; }
97
+ const why = t?.details?.error ?? t?.message ?? 'no answer';
98
+ if (why === 'DeviceNotRegistered') {
99
+ try { await backend.dropPushDevice(messages[i].to, owner); } catch (err) { once('drop', `phone: could not forget a phone that stopped taking alerts: ${err?.message ?? err}`); }
100
+ } else once(`ticket:${why}`, `phone: Expo did not take an alert: ${why}`);
101
+ }
102
+ if (!reached) return;
103
+ said.clear();
104
+ spoke = true;
105
+ if (fresh.some((f) => f.ask)) spokeAsk = true;
106
+ for (const f of fresh) state.alerted[f.key] = { stamp: f.stamp, at: now() };
107
+ for (const [k, v] of Object.entries(state.alerted)) if (!(now() - (v?.at ?? 0) < ALERTED_KEPT_MS)) delete state.alerted[k];
108
+ save();
109
+ }
110
+
111
+ return {
112
+ arrived,
113
+ pass,
114
+ /** She answered from her phone, so she has seen what it holds. */
115
+ phoneUsed: () => { spoke = false; spokeAsk = false; },
116
+ };
117
+ }