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
@@ -32,6 +32,8 @@
32
32
  // epoch, and neither erases the other. Same rule as beats in
33
33
  // shared/dashboard.mjs.
34
34
 
35
+ import { resolveEdits } from './message-edits.mjs';
36
+
35
37
  /* ------------------------------- lifecycle ------------------------------- */
36
38
  // The only states the claim machinery reasons about. Everything else about what
37
39
  // a work item is (kind, labels) is free-form text the layer above interprets.
@@ -155,6 +157,16 @@ export const WORK_ITEM_FIELDS = [
155
157
  // mark on ONE line rather than a value the row holds, so the fold skips it;
156
158
  // the chat reads it per line (renderer/src/thread-history.ts).
157
159
  'inReplyTo',
160
+ // AN EDIT OR A DELETION OF ONE MESSAGE: `{ on, text }` or `{ on, gone: true }`,
161
+ // where `on` is the message's line uid. A delta like `react`, read back as
162
+ // `edits` and only from the message's own author (shared/message-edits.mjs).
163
+ 'edit',
164
+ // WHICH COMMAND FROM HER PHONE WROTE THIS LINE (docs/cloud/PHONE-PLAN.md):
165
+ // the command's id, on the line of the reply or the new thread it made. It
166
+ // is how the computer, starting again after stopping half way through a
167
+ // command, knows for certain whether that command already landed, rather
168
+ // than guessing from the words (Codex's third review of step 1, finding 5).
169
+ 'fromPhone',
158
170
  ];
159
171
 
160
172
  // THE SUMMARY IS SHARED BETWEEN THE PERSON AND THE AGENT. Everywhere else the
@@ -366,6 +378,14 @@ function str(value, max) {
366
378
  return trimmed.slice(0, lo) + mark(trimmed.length - lo);
367
379
  }
368
380
 
381
+ // A text field whose empty string MEANS something: nothing chosen. Only a
382
+ // string may clear it, so a `null` that reached here without going through
383
+ // `answerItem` is still dropped rather than guessed at.
384
+ function clearable(value, max) {
385
+ if (typeof value !== 'string') return undefined;
386
+ return value.trim() ? str(value, max) : '';
387
+ }
388
+
369
389
  function coerceField(field, value) {
370
390
  switch (field) {
371
391
  case 'title': return str(value, MAX_TITLE);
@@ -388,7 +408,28 @@ function coerceField(field, value) {
388
408
  // shared/effort-levels.mjs, and the spawn gates on them, so a value this
389
409
  // module does not recognise is a run at Claude Code's own choice rather
390
410
  // than a row that never runs.
391
- case 'kind': case 'product': case 'parent': case 'engine': case 'model': case 'effort': return str(value, MAX_SHORT);
411
+ case 'kind': case 'product': case 'parent': return str(value, MAX_SHORT);
412
+ // THESE TWO ARE CLEARED BY WRITING '' AND SO '' IS A REAL VALUE, exactly
413
+ // as runAt's 0 and start's 'now' are, and for the same reason: a field that
414
+ // coerces to undefined is dropped by the fold, so without a falsy value
415
+ // that survives, a model could be chosen and never unchosen.
416
+ //
417
+ // They used to sit on the line above, which cost us the most common crash
418
+ // of launch week. The reply box's drawer hands a pick back as null for
419
+ // "nothing chosen" and sends `{ model, effort }` whenever it was touched at
420
+ // all; `answerItem` turns null into '' because `modelForEngine` reads the
421
+ // empty string as nothing chosen. `str()` then dropped it, `pickFields`
422
+ // answered null, and `buildLine` threw — before the answer was written,
423
+ // because the model is written first on purpose. So opening the drawer,
424
+ // picking a model and pressing send lost the message, with nothing on
425
+ // screen to say so. Five of the 14 crashes since the Oct 6 launch, on two
426
+ // installs (PostHog, 2026-10-08).
427
+ //
428
+ // `engine` JOINED THEM WHEN A REPLY COULD FIRST CARRY ONE (w-c9da359466).
429
+ // It is written beside the model by the same call, so clearing it back to
430
+ // the workspace default would have thrown in exactly the place described
431
+ // above, before the answer was written, losing the message.
432
+ case 'model': case 'effort': case 'engine': return clearable(value, MAX_SHORT);
392
433
  case 'status': return WORK_ITEM_STATUSES.includes(value) ? value : undefined;
393
434
  case 'priority': return Number.isFinite(value) ? Math.trunc(value) : undefined;
394
435
  // When this item may next be acted on, in epoch ms. 0 means unscheduled,
@@ -416,10 +457,11 @@ function coerceField(field, value) {
416
457
  // A ts rather than a flag, so her NEXT answer outdates it by carrying a
417
458
  // later one, with nothing to clear and nobody who has to remember to.
418
459
  case 'answeredThrough': return Number.isFinite(value) ? Math.trunc(value) : undefined;
460
+ // An empty list is a real value: it is how the last label, `ship` above
461
+ // all, comes off.
419
462
  case 'labels': {
420
463
  if (!Array.isArray(value)) return undefined;
421
- const labels = value.map((l) => str(l, MAX_SHORT)).filter(Boolean).slice(0, MAX_LABELS);
422
- return labels.length ? labels : undefined;
464
+ return value.map((l) => str(l, MAX_SHORT)).filter(Boolean).slice(0, MAX_LABELS);
423
465
  }
424
466
  case 'assignee': case 'runner': return shortId(value) ?? undefined;
425
467
  case 'due': return calendarDay(value);
@@ -440,6 +482,15 @@ function coerceField(field, value) {
440
482
  return value.off === true ? { on, emoji, off: true } : { on, emoji };
441
483
  }
442
484
  case 'inReplyTo': return shortId(value) ?? undefined;
485
+ case 'edit': {
486
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
487
+ const on = shortId(value.on);
488
+ if (!on) return undefined;
489
+ if (value.gone === true) return { on, gone: true };
490
+ const text = str(value.text, MAX_TEXT_BYTES);
491
+ return text ? { on, text } : undefined;
492
+ }
493
+ case 'fromPhone': return typeof value === 'string' && /^[0-9a-f-]{8,64}$/i.test(value) ? value : undefined;
443
494
  case 'visibility': return value === 'private' || value === 'team' || value === 'people' ? value : undefined;
444
495
  // An empty list is a real value: it is how the last chosen person comes
445
496
  // off a thread, and the thread then reaches nobody until she names one.
@@ -497,12 +548,67 @@ function rollUpReactions(presses) {
497
548
  return out;
498
549
  }
499
550
 
500
- export function foldWorkItems(lines, now = Date.now()) {
501
- const items = new Map();
551
+ // Lease expiry is computed at READ time, never written. A held claim whose
552
+ // lease has lapsed reads as open again, which is what makes an abandoned item
553
+ // recoverable without anyone having to notice it was abandoned.
554
+ //
555
+ // The same derivation covers a released claim, and that is the point: only an
556
+ // item still sitting at `claimed` with nobody holding it goes back to open.
557
+ // Any status a worker or the founder actually chose (done, blocked, or one we
558
+ // have not invented yet) is theirs, and nothing about giving a claim back
559
+ // overwrites it.
560
+ export function finishItem(raw, now = Date.now()) {
561
+ // A copy, one level deep, so the raw item can be folded on and a finished
562
+ // one handed out is never changed under its holder.
563
+ const item = {};
564
+ for (const [k, v] of Object.entries(raw)) {
565
+ item[k] = Array.isArray(v) ? [...v]
566
+ : v instanceof Map ? new Map(v)
567
+ : v instanceof Set ? new Set(v)
568
+ : v && Object.getPrototypeOf(v) === Object.prototype ? { ...v } : v;
569
+ }
570
+ item.claimExpired = !!(item.claim && item.claim.leaseUntil < now);
571
+ if (item.status === 'claimed' && (!item.claim || item.claimExpired)) item.status = 'open';
572
+ if (item.reacts) {
573
+ const chips = rollUpReactions(item.reacts);
574
+ delete item.reacts;
575
+ if (chips) item.reactions = chips;
576
+ }
577
+ const closes = item.closes;
578
+ delete item.closes;
579
+ const editLines = item.editLines;
580
+ delete item.editLines;
581
+ const edits = editLines ? resolveEdits(item.said ?? [], editLines) : null;
582
+ if (edits?.size) item.edits = Object.fromEntries(edits);
583
+ if (item.said) {
584
+ const said = edits?.size ? item.said.flatMap((s) => {
585
+ const e = s.uid ? edits.get(s.uid) : null;
586
+ if (!e) return [s];
587
+ return e.gone ? [] : [{ ...s, text: e.text.trim().slice(0, TALK_TEXT) }];
588
+ }) : item.said;
589
+ delete item.said;
590
+ if (Array.isArray(item.people) && item.people.length) {
591
+ item.talk = talkOf(said);
592
+ const settled = settledBy(closes ?? [], said);
593
+ if (settled) item.talk.settled = settled;
594
+ }
595
+ }
596
+ return item;
597
+ }
502
598
 
599
+ /** A line that writes the row's short name and nothing else (see the fold's foot). */
600
+ function onlyTheName(line) {
601
+ if (line.claim || line.release || line.heartbeat) return false;
602
+ const fields = Object.keys(line.patch ?? {});
603
+ return fields.length === 1 && fields[0] === 'label';
604
+ }
605
+
606
+ /** Lines folded onto `items` in place, unfinished: `finishItem` makes each one readable. */
607
+ export function foldRawInto(items, lines, touched = null) {
503
608
  for (const raw of Array.isArray(lines) ? lines : []) {
504
609
  const line = normalizeLine(raw);
505
610
  if (!line) continue;
611
+ touched?.add(line.id);
506
612
 
507
613
  let item = items.get(line.id);
508
614
  if (!item) {
@@ -560,6 +666,11 @@ export function foldWorkItems(lines, now = Date.now()) {
560
666
  if (line.by && words && words.trim()) {
561
667
  (item.said ??= []).push({ uid: line.uid ?? null, by: line.by, ts: line.ts, text: words.trim().slice(0, TALK_TEXT), inReplyTo: patch.inReplyTo ?? null, body: typeof patch.answer !== 'string' });
562
668
  }
669
+ // Who closed the chat and when, so `whatWaits` can tell a reopen by your own
670
+ // message (still settled) from an undo of the close (not).
671
+ if (line.by && typeof patch.status === 'string') {
672
+ (item.closes ??= []).push({ by: line.by, ts: line.ts, done: patch.status === 'done', spoke: !!(words && words.trim()) });
673
+ }
563
674
 
564
675
  for (const [field, value] of Object.entries(patch)) {
565
676
  // A REACTION IS ACCUMULATED, NOT HELD. Every other field below keeps one
@@ -581,6 +692,10 @@ export function foldWorkItems(lines, now = Date.now()) {
581
692
  // WHICH MESSAGE A REPLY ANSWERS belongs to that reply's line alone. Held
582
693
  // as a value, the row would carry the newest reply's parent forever.
583
694
  if (field === 'inReplyTo') continue;
695
+ if (field === 'edit') {
696
+ (item.editLines ??= []).push({ on: value.on, by: line.by ?? null, ts: line.ts, ...(value.gone ? { gone: true } : { text: value.text }) });
697
+ continue;
698
+ }
584
699
  const held = item.wrote[field];
585
700
  // There used to be an exception here, for machinery spending a one-off
586
701
  // permission mode over the founder's own grant. That field is not on the
@@ -593,34 +708,23 @@ export function foldWorkItems(lines, now = Date.now()) {
593
708
  if (line.by) item.wrote[field].by = line.by;
594
709
  }
595
710
 
596
- item.updatedAt = Math.max(item.updatedAt, line.ts);
711
+ // THE APP WRITING A ROW'S NAME IS NOT NEWS ABOUT THE ROW. Lists break ties
712
+ // on `updatedAt`, so every unnamed thread the namer reached climbed to the
713
+ // top reading "updated just now". Read here rather than at the write, as
714
+ // the heartbeat rule above is, because the lines that did it are in the
715
+ // ledger already. Only the name ALONE: a line that carries it with anything
716
+ // else carries that too.
717
+ if (!onlyTheName(line)) item.updatedAt = Math.max(item.updatedAt, line.ts);
597
718
  if (line.ts < item.createdAt) item.createdAt = line.ts;
598
719
  }
599
720
 
600
- // Lease expiry is computed at READ time, never written. A held claim whose
601
- // lease has lapsed reads as open again, which is what makes an abandoned item
602
- // recoverable without anyone having to notice it was abandoned.
603
- //
604
- // The same derivation covers a released claim, and that is the point: only an
605
- // item still sitting at `claimed` with nobody holding it goes back to open.
606
- // Any status a worker or the founder actually chose (done, blocked, or one we
607
- // have not invented yet) is theirs, and nothing about giving a claim back
608
- // overwrites it.
609
- for (const item of items.values()) {
610
- item.claimExpired = !!(item.claim && item.claim.leaseUntil < now);
611
- if (item.status === 'claimed' && (!item.claim || item.claimExpired)) item.status = 'open';
612
- if (item.reacts) {
613
- const chips = rollUpReactions(item.reacts);
614
- delete item.reacts;
615
- if (chips) item.reactions = chips;
616
- }
617
- if (item.said) {
618
- const said = item.said;
619
- delete item.said;
620
- if (Array.isArray(item.people) && item.people.length) item.talk = talkOf(said);
621
- }
622
- }
721
+ }
623
722
 
723
+ export function foldWorkItems(lines, now = Date.now()) {
724
+ const raw = new Map();
725
+ foldRawInto(raw, lines);
726
+ const items = new Map();
727
+ for (const [id, item] of raw) items.set(id, finishItem(item, now));
624
728
  return items;
625
729
  }
626
730
 
@@ -640,6 +744,23 @@ const TALK_KEEP = 100;
640
744
  * `whatWaits` (shared/team-rules.mjs) and the row's one line; the messages
641
745
  * themselves are read off the ledger by the thread view, as before.
642
746
  */
747
+ /**
748
+ * For each person, the moment they last marked the chat done, or nothing if
749
+ * they reopened it since without saying anything (an undo). A reopen that
750
+ * carries their words keeps the moment: speaking is not taking the close back.
751
+ * So does one that follows their words since the close, because sending
752
+ * writes the message and the reopen as two lines (`answerItem`, main/store.mjs).
753
+ */
754
+ function settledBy(closes, said = []) {
755
+ const at = {};
756
+ const spokeSince = (by, from, to) => said.some((s) => s.by === by && !s.body && s.ts > from && s.ts <= to);
757
+ for (const c of [...closes].sort((a, b) => a.ts - b.ts)) {
758
+ if (c.done) at[c.by] = c.ts;
759
+ else if (!c.spoke && !spokeSince(c.by, at[c.by], c.ts)) delete at[c.by];
760
+ }
761
+ return Object.keys(at).length ? at : null;
762
+ }
763
+
643
764
  function talkOf(said) {
644
765
  const lines = [...said].sort((a, b) => a.ts - b.ts);
645
766
  const chat = [];