clawmini 0.0.7 → 0.0.9

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 (367) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +14 -0
  3. package/.github/workflows/release.yml +49 -0
  4. package/CHANGELOG.md +36 -0
  5. package/README.md +5 -4
  6. package/dist/adapter-discord/index.d.mts.map +1 -1
  7. package/dist/adapter-discord/index.mjs +465 -282
  8. package/dist/adapter-discord/index.mjs.map +1 -1
  9. package/dist/adapter-google-chat/index.mjs +367 -243
  10. package/dist/adapter-google-chat/index.mjs.map +1 -1
  11. package/dist/cli/index.mjs +684 -24
  12. package/dist/cli/index.mjs.map +1 -1
  13. package/dist/cli/lite.mjs +43 -13
  14. package/dist/cli/lite.mjs.map +1 -1
  15. package/dist/cli/{propose-policy.mjs → manage-policies.mjs} +270 -47
  16. package/dist/cli/manage-policies.mjs.map +1 -0
  17. package/dist/cli/run-host.d.mts +1 -0
  18. package/dist/cli/run-host.mjs +3090 -0
  19. package/dist/cli/run-host.mjs.map +1 -0
  20. package/dist/config-CPFQIGdG.mjs +57 -0
  21. package/dist/config-CPFQIGdG.mjs.map +1 -0
  22. package/dist/config-Dvl-Pov4.mjs +76 -0
  23. package/dist/config-Dvl-Pov4.mjs.map +1 -0
  24. package/dist/daemon/index.d.mts.map +1 -1
  25. package/dist/daemon/index.mjs +970 -332
  26. package/dist/daemon/index.mjs.map +1 -1
  27. package/dist/supervisor-actions-CiW56eLi.mjs +843 -0
  28. package/dist/supervisor-actions-CiW56eLi.mjs.map +1 -0
  29. package/dist/turn-log-buffer-DRgW53gl.mjs +767 -0
  30. package/dist/turn-log-buffer-DRgW53gl.mjs.map +1 -0
  31. package/dist/web/_app/immutable/chunks/{Drm9vgeP.js → 3AZlWB6U.js} +1 -1
  32. package/dist/web/_app/immutable/chunks/BhRSsUCh.js +2 -0
  33. package/dist/web/_app/immutable/chunks/BiLeM2i1.js +1 -0
  34. package/{web/.svelte-kit/output/client/_app/immutable/chunks/CME08kGM.js → dist/web/_app/immutable/chunks/BmBj85Ll.js} +1 -1
  35. package/dist/web/_app/immutable/chunks/BrERcKAH.js +1 -0
  36. package/dist/web/_app/immutable/chunks/Bv9252RM.js +1 -0
  37. package/dist/web/_app/immutable/chunks/CIXNBPKi.js +1 -0
  38. package/dist/web/_app/immutable/chunks/DISKL3GN.js +2 -0
  39. package/dist/web/_app/immutable/chunks/{Zeh-C-mx.js → DcpaLzmX.js} +1 -1
  40. package/dist/web/_app/immutable/chunks/DnQ3vS13.js +1 -0
  41. package/dist/web/_app/immutable/chunks/KsloHTKS.js +1 -0
  42. package/{web/.svelte-kit/output/client/_app/immutable/chunks/Ck-be5J2.js → dist/web/_app/immutable/chunks/RsHsUj-8.js} +2 -2
  43. package/dist/web/_app/immutable/chunks/{G_zz-Gou.js → wpfV79dV.js} +1 -1
  44. package/dist/web/_app/immutable/entry/app.CIw1Qj0n.js +2 -0
  45. package/dist/web/_app/immutable/entry/start.Di0-Jhte.js +1 -0
  46. package/dist/web/_app/immutable/nodes/{0.CYS8iApT.js → 0.DYyUA1au.js} +1 -1
  47. package/dist/web/_app/immutable/nodes/1.D-3QEMMZ.js +1 -0
  48. package/dist/web/_app/immutable/nodes/{2.BnwnD1Ki.js → 2.4olHnH7U.js} +1 -1
  49. package/{web/.svelte-kit/output/client/_app/immutable/nodes/3.Dr0ot9sV.js → dist/web/_app/immutable/nodes/3.4w0bE-m2.js} +3 -3
  50. package/dist/web/_app/immutable/nodes/4.CZvjhVHt.js +60 -0
  51. package/dist/web/_app/immutable/nodes/{5.BBGQ_i84.js → 5.DLbPVJY2.js} +1 -1
  52. package/dist/web/_app/version.json +1 -1
  53. package/dist/web/index.html +12 -12
  54. package/dist/workspace-oWmVh5mi.mjs +1001 -0
  55. package/dist/workspace-oWmVh5mi.mjs.map +1 -0
  56. package/docs/23_adapter_slash_autocomplete/development_log.md +19 -0
  57. package/docs/23_adapter_slash_autocomplete/notes.md +18 -0
  58. package/docs/23_adapter_slash_autocomplete/prd.md +46 -0
  59. package/docs/23_adapter_slash_autocomplete/questions.md +6 -0
  60. package/docs/23_adapter_slash_autocomplete/tickets.md +21 -0
  61. package/docs/24_subagent_job_policy_fixes/development_log.md +22 -0
  62. package/docs/24_subagent_job_policy_fixes/notes.md +28 -0
  63. package/docs/24_subagent_job_policy_fixes/prd.md +59 -0
  64. package/docs/24_subagent_job_policy_fixes/questions.md +3 -0
  65. package/docs/24_subagent_job_policy_fixes/tickets.md +49 -0
  66. package/docs/25_e2e_test_improvements/development_log.md +30 -0
  67. package/docs/25_e2e_test_improvements/notes.md +29 -0
  68. package/docs/25_e2e_test_improvements/prd.md +43 -0
  69. package/docs/25_e2e_test_improvements/questions.md +12 -0
  70. package/docs/25_e2e_test_improvements/tickets-2.md +22 -0
  71. package/docs/25_e2e_test_improvements/tickets.md +22 -0
  72. package/docs/25_policy_cwd/development_log.md +30 -0
  73. package/docs/25_policy_cwd/notes.md +28 -0
  74. package/docs/25_policy_cwd/prd.md +77 -0
  75. package/docs/25_policy_cwd/questions.md +6 -0
  76. package/docs/25_policy_cwd/tickets.md +77 -0
  77. package/docs/CLI_REFERENCE.md +3 -1
  78. package/docs/PHILOSOPHY.md +35 -0
  79. package/docs/adapter-visibility/SPEC.md +461 -0
  80. package/docs/adapter-visibility/SPEC_v2.md +202 -0
  81. package/docs/auto-update/SPEC.md +344 -0
  82. package/docs/backups/SPEC.md +296 -0
  83. package/docs/backups/clawmini.gitignore +69 -0
  84. package/docs/guides/assets/clawmini-avatar.png +0 -0
  85. package/docs/guides/backups.md +332 -0
  86. package/docs/guides/discord_adapter_setup.md +1 -1
  87. package/docs/guides/google_chat_adapter_setup.md +81 -0
  88. package/docs/unified-startup/SPEC.md +203 -0
  89. package/e2e/_helpers/test-environment.test.ts +49 -0
  90. package/e2e/_helpers/test-environment.ts +548 -0
  91. package/e2e/adapters/_google-chat-fixtures.ts +340 -0
  92. package/{src/cli/e2e → e2e/adapters}/adapter-discord.test.ts +22 -23
  93. package/e2e/adapters/adapter-google-chat-downtime.test.ts +157 -0
  94. package/e2e/adapters/adapter-google-chat-inbound.test.ts +697 -0
  95. package/e2e/adapters/adapter-google-chat-outbound.test.ts +297 -0
  96. package/e2e/adapters/adapter-google-chat-roundtrip.test.ts +56 -0
  97. package/e2e/adapters/adapter-google-chat-threads.test.ts +1078 -0
  98. package/e2e/agents/custom-api-env.test.ts +80 -0
  99. package/e2e/agents/export-lite-func.test.ts +104 -0
  100. package/e2e/agents/fallbacks.test.ts +124 -0
  101. package/e2e/agents/interrupt.test.ts +50 -0
  102. package/e2e/agents/no-reply-necessary.test.ts +57 -0
  103. package/e2e/agents/session-timeout-subagents.test.ts +76 -0
  104. package/e2e/agents/subagent-authorization.test.ts +246 -0
  105. package/e2e/agents/subagent-env.test.ts +49 -0
  106. package/e2e/agents/subagent-lifecycle.test.ts +782 -0
  107. package/e2e/agents/subagents-depth.test.ts +47 -0
  108. package/e2e/cli/agents.test.ts +176 -0
  109. package/e2e/cli/auto-update.test.ts +741 -0
  110. package/e2e/cli/basic.test.ts +44 -0
  111. package/{src/cli/e2e → e2e/cli}/export-lite.test.ts +16 -12
  112. package/e2e/cli/init-gitignore.test.ts +86 -0
  113. package/e2e/cli/init.test.ts +76 -0
  114. package/e2e/cli/messages.test.ts +363 -0
  115. package/e2e/cli/serve.test.ts +76 -0
  116. package/{src/cli/e2e → e2e/cli}/skills.test.ts +11 -10
  117. package/{src/cli/e2e → e2e/daemon}/daemon.test.ts +57 -195
  118. package/e2e/jobs/agent-jobs.test.ts +216 -0
  119. package/e2e/jobs/cron.test.ts +64 -0
  120. package/e2e/jobs/restart.test.ts +108 -0
  121. package/e2e/policies/approval-session.test.ts +69 -0
  122. package/e2e/policies/auto-create-policies-file.test.ts +35 -0
  123. package/e2e/policies/builtin-manage-policies.test.ts +184 -0
  124. package/e2e/policies/builtin-run-host.test.ts +180 -0
  125. package/e2e/policies/environment-policies.test.ts +177 -0
  126. package/e2e/policies/manage-policies.test.ts +566 -0
  127. package/e2e/policies/output-size.test.ts +98 -0
  128. package/e2e/policies/policies-context-cwd.test.ts +160 -0
  129. package/e2e/policies/relative-script-path.test.ts +60 -0
  130. package/e2e/policies/requests-show.test.ts +135 -0
  131. package/e2e/policies/requests.test.ts +208 -0
  132. package/e2e/policies/slash-policies.test.ts +308 -0
  133. package/e2e/policies/startup-cleanup.test.ts +48 -0
  134. package/e2e/routers/session-timeout.test.ts +106 -0
  135. package/e2e/routers/slash-model.test.ts +152 -0
  136. package/e2e/routers/slash-new.test.ts +50 -0
  137. package/e2e/routers/slash-restart-adapter.test.ts +96 -0
  138. package/e2e/routers/slash-restart.test.ts +114 -0
  139. package/e2e/routers/slash-shutdown.test.ts +55 -0
  140. package/e2e/routers/slash-stop.test.ts +232 -0
  141. package/e2e/routers/slash-upgrade.test.ts +88 -0
  142. package/{src/cli/e2e → e2e/sandbox}/environments.test.ts +14 -13
  143. package/eslint.config.js +6 -0
  144. package/napkin.md +1 -1
  145. package/package.json +8 -3
  146. package/src/adapter-discord/commands.test.ts +42 -0
  147. package/src/adapter-discord/commands.ts +33 -0
  148. package/src/adapter-discord/config.ts +12 -0
  149. package/src/adapter-discord/forwarder.test.ts +499 -21
  150. package/src/adapter-discord/forwarder.ts +343 -124
  151. package/src/adapter-discord/inbound-cache.test.ts +47 -0
  152. package/src/adapter-discord/inbound-cache.ts +37 -0
  153. package/src/adapter-discord/index.test.ts +67 -2
  154. package/src/adapter-discord/index.ts +84 -216
  155. package/src/adapter-discord/interactions.test.ts +54 -3
  156. package/src/adapter-discord/interactions.ts +97 -53
  157. package/src/adapter-discord/processMessage.ts +239 -0
  158. package/src/adapter-discord/state.ts +1 -0
  159. package/src/adapter-google-chat/auth.test.ts +9 -5
  160. package/src/adapter-google-chat/auth.ts +29 -23
  161. package/src/adapter-google-chat/cards.ts +7 -2
  162. package/src/adapter-google-chat/client.test.ts +37 -2
  163. package/src/adapter-google-chat/client.ts +138 -38
  164. package/src/adapter-google-chat/config.ts +19 -0
  165. package/src/adapter-google-chat/forwarder.test.ts +81 -56
  166. package/src/adapter-google-chat/forwarder.ts +394 -185
  167. package/src/adapter-google-chat/inbound-cache.test.ts +61 -0
  168. package/src/adapter-google-chat/inbound-cache.ts +36 -0
  169. package/src/adapter-google-chat/state.test.ts +1 -0
  170. package/src/adapter-google-chat/state.ts +9 -1
  171. package/src/adapter-google-chat/subscriptions.ts +8 -6
  172. package/src/cli/builtin-policies.ts +44 -0
  173. package/src/cli/commands/agents.ts +59 -5
  174. package/src/cli/commands/down.ts +54 -2
  175. package/src/cli/commands/environments.ts +8 -2
  176. package/src/cli/commands/init.ts +31 -0
  177. package/src/cli/commands/logs.ts +116 -0
  178. package/src/cli/commands/policies.ts +6 -4
  179. package/src/cli/commands/serve.test.ts +67 -0
  180. package/src/cli/commands/serve.ts +284 -0
  181. package/src/cli/commands/up.ts +122 -2
  182. package/src/cli/commands/web-api/agents.ts +3 -2
  183. package/src/cli/index.ts +4 -0
  184. package/src/cli/install-detection.test.ts +72 -0
  185. package/src/cli/install-detection.ts +48 -0
  186. package/src/cli/lite.ts +54 -22
  187. package/src/cli/manage-policies-utils.ts +104 -0
  188. package/src/cli/manage-policies.ts +291 -0
  189. package/src/cli/run-host.ts +45 -0
  190. package/src/cli/supervisor-actions.ts +267 -0
  191. package/src/cli/supervisor-control.test.ts +129 -0
  192. package/src/cli/supervisor-control.ts +155 -0
  193. package/src/cli/supervisor-pid.ts +68 -0
  194. package/src/cli/supervisor.ts +277 -0
  195. package/src/daemon/agent/agent-context.ts +11 -11
  196. package/src/daemon/agent/agent-session.ts +8 -1
  197. package/src/daemon/agent/chat-logger.test.ts +78 -9
  198. package/src/daemon/agent/chat-logger.ts +25 -5
  199. package/src/daemon/agent/turn-registry.test.ts +89 -0
  200. package/src/daemon/agent/turn-registry.ts +94 -0
  201. package/src/daemon/agent/types.ts +2 -0
  202. package/src/daemon/api/agent-policy-endpoints.ts +263 -0
  203. package/src/daemon/api/agent-router.ts +47 -126
  204. package/src/daemon/api/index.test.ts +1 -0
  205. package/src/daemon/api/policy-request.test.ts +7 -5
  206. package/src/daemon/api/router-utils.ts +6 -5
  207. package/src/daemon/api/subagent-router.ts +110 -74
  208. package/src/daemon/api/subagent-utils.test.ts +60 -0
  209. package/src/daemon/api/subagent-utils.ts +113 -87
  210. package/src/daemon/api/user-router.ts +34 -8
  211. package/src/daemon/auth.ts +1 -0
  212. package/src/daemon/cron.test.ts +62 -4
  213. package/src/daemon/cron.ts +42 -16
  214. package/src/daemon/events.ts +65 -0
  215. package/src/daemon/index.ts +24 -1
  216. package/src/daemon/message-interruption.test.ts +1 -0
  217. package/src/daemon/message-jobs.test.ts +1 -0
  218. package/src/daemon/message.ts +78 -14
  219. package/src/daemon/observation.test.ts +26 -18
  220. package/src/daemon/pending-replies.test.ts +112 -0
  221. package/src/daemon/pending-replies.ts +162 -0
  222. package/src/daemon/policy-request-service.ts +3 -1
  223. package/src/daemon/policy-utils.test.ts +66 -1
  224. package/src/daemon/policy-utils.ts +126 -1
  225. package/src/daemon/request-store.ts +31 -0
  226. package/src/daemon/routers/session-timeout.ts +4 -0
  227. package/src/daemon/routers/slash-model.test.ts +344 -0
  228. package/src/daemon/routers/slash-model.ts +207 -0
  229. package/src/daemon/routers/slash-policies.test.ts +38 -32
  230. package/src/daemon/routers/slash-policies.ts +84 -33
  231. package/src/daemon/routers/slash-restart.test.ts +69 -0
  232. package/src/daemon/routers/slash-restart.ts +36 -0
  233. package/src/daemon/routers/slash-shutdown.test.ts +50 -0
  234. package/src/daemon/routers/slash-shutdown.ts +28 -0
  235. package/src/daemon/routers/slash-upgrade.test.ts +116 -0
  236. package/src/daemon/routers/slash-upgrade.ts +76 -0
  237. package/src/daemon/routers/types.ts +7 -0
  238. package/src/daemon/routers.ts +16 -0
  239. package/src/shared/adapters/blockquote.test.ts +28 -0
  240. package/src/shared/adapters/blockquote.ts +20 -0
  241. package/src/shared/adapters/filtering.test.ts +224 -10
  242. package/src/shared/adapters/filtering.ts +95 -7
  243. package/src/shared/adapters/inbound-cache.test.ts +48 -0
  244. package/src/shared/adapters/inbound-cache.ts +54 -0
  245. package/src/shared/adapters/turn-log-buffer.ts +266 -0
  246. package/src/shared/adapters/turn-log.test.ts +389 -0
  247. package/src/shared/adapters/turn-log.ts +357 -0
  248. package/src/shared/agent-utils.ts +12 -5
  249. package/src/shared/chats.test.ts +4 -0
  250. package/src/shared/chats.ts +9 -0
  251. package/src/shared/config.ts +16 -1
  252. package/src/shared/lite.ts +76 -2
  253. package/src/shared/policies.ts +26 -0
  254. package/src/shared/template-manifest.ts +267 -0
  255. package/src/shared/utils/shell.ts +61 -0
  256. package/src/shared/version.ts +34 -0
  257. package/src/shared/workspace.test.ts +217 -0
  258. package/src/shared/workspace.ts +626 -48
  259. package/templates/environments/cladding/allowlist-domain.mjs +125 -0
  260. package/templates/environments/cladding/env.json +21 -1
  261. package/templates/environments/cladding/run-with-network.mjs +54 -0
  262. package/templates/environments/macos-proxy/allowlist-domain.mjs +95 -0
  263. package/templates/environments/macos-proxy/env.json +8 -1
  264. package/templates/environments/macos-proxy/proxy.mjs +42 -13
  265. package/templates/gemini/template.json +5 -0
  266. package/templates/gemini-claw/template.json +13 -0
  267. package/templates/skills/clawmini-requests/SKILL.md +69 -10
  268. package/templates/skills/run-host/SKILL.md +51 -0
  269. package/templates/skills/skill-creator/SKILL.md +4 -3
  270. package/templates/skills/skill-creator/scripts/validate.sh +52 -0
  271. package/tsdown.config.ts +10 -1
  272. package/vitest.config.ts +2 -2
  273. package/web/.svelte-kit/ambient.d.ts +292 -176
  274. package/web/.svelte-kit/generated/server/internal.js +1 -1
  275. package/web/.svelte-kit/output/client/.vite/manifest.json +127 -137
  276. package/web/.svelte-kit/output/client/_app/immutable/chunks/{Drm9vgeP.js → 3AZlWB6U.js} +1 -1
  277. package/web/.svelte-kit/output/client/_app/immutable/chunks/BhRSsUCh.js +2 -0
  278. package/web/.svelte-kit/output/client/_app/immutable/chunks/BiLeM2i1.js +1 -0
  279. package/{dist/web/_app/immutable/chunks/CME08kGM.js → web/.svelte-kit/output/client/_app/immutable/chunks/BmBj85Ll.js} +1 -1
  280. package/web/.svelte-kit/output/client/_app/immutable/chunks/BrERcKAH.js +1 -0
  281. package/web/.svelte-kit/output/client/_app/immutable/chunks/Bv9252RM.js +1 -0
  282. package/web/.svelte-kit/output/client/_app/immutable/chunks/CIXNBPKi.js +1 -0
  283. package/web/.svelte-kit/output/client/_app/immutable/chunks/DISKL3GN.js +2 -0
  284. package/web/.svelte-kit/output/client/_app/immutable/chunks/{Zeh-C-mx.js → DcpaLzmX.js} +1 -1
  285. package/web/.svelte-kit/output/client/_app/immutable/chunks/DnQ3vS13.js +1 -0
  286. package/web/.svelte-kit/output/client/_app/immutable/chunks/KsloHTKS.js +1 -0
  287. package/{dist/web/_app/immutable/chunks/Ck-be5J2.js → web/.svelte-kit/output/client/_app/immutable/chunks/RsHsUj-8.js} +2 -2
  288. package/web/.svelte-kit/output/client/_app/immutable/chunks/{G_zz-Gou.js → wpfV79dV.js} +1 -1
  289. package/web/.svelte-kit/output/client/_app/immutable/entry/app.CIw1Qj0n.js +2 -0
  290. package/web/.svelte-kit/output/client/_app/immutable/entry/start.Di0-Jhte.js +1 -0
  291. package/web/.svelte-kit/output/client/_app/immutable/nodes/{0.CYS8iApT.js → 0.DYyUA1au.js} +1 -1
  292. package/web/.svelte-kit/output/client/_app/immutable/nodes/1.D-3QEMMZ.js +1 -0
  293. package/web/.svelte-kit/output/client/_app/immutable/nodes/{2.BnwnD1Ki.js → 2.4olHnH7U.js} +1 -1
  294. package/{dist/web/_app/immutable/nodes/3.Dr0ot9sV.js → web/.svelte-kit/output/client/_app/immutable/nodes/3.4w0bE-m2.js} +3 -3
  295. package/web/.svelte-kit/output/client/_app/immutable/nodes/4.CZvjhVHt.js +60 -0
  296. package/web/.svelte-kit/output/client/_app/immutable/nodes/{5.BBGQ_i84.js → 5.DLbPVJY2.js} +1 -1
  297. package/web/.svelte-kit/output/client/_app/version.json +1 -1
  298. package/web/.svelte-kit/output/server/.vite/manifest.json +12 -10
  299. package/web/.svelte-kit/output/server/chunks/Icon.js +1 -1
  300. package/web/.svelte-kit/output/server/chunks/client.js +1 -1
  301. package/web/.svelte-kit/output/server/chunks/exports.js +1 -1
  302. package/web/.svelte-kit/output/server/chunks/index-server.js +2 -1
  303. package/web/.svelte-kit/output/server/chunks/internal.js +1 -1
  304. package/web/.svelte-kit/output/server/chunks/render-context.js +77 -0
  305. package/web/.svelte-kit/output/server/chunks/root.js +739 -788
  306. package/web/.svelte-kit/output/server/chunks/shared.js +234 -21
  307. package/web/.svelte-kit/output/server/index.js +126 -90
  308. package/web/.svelte-kit/output/server/manifest-full.js +1 -1
  309. package/web/.svelte-kit/output/server/manifest.js +1 -1
  310. package/web/.svelte-kit/output/server/nodes/0.js +1 -1
  311. package/web/.svelte-kit/output/server/nodes/1.js +1 -1
  312. package/web/.svelte-kit/output/server/nodes/2.js +1 -1
  313. package/web/.svelte-kit/output/server/nodes/3.js +1 -1
  314. package/web/.svelte-kit/output/server/nodes/4.js +1 -1
  315. package/web/.svelte-kit/output/server/nodes/5.js +1 -1
  316. package/web/.svelte-kit/output/server/remote-entry.js +245 -81
  317. package/web/.svelte-kit/tsconfig.json +4 -1
  318. package/dist/cli/propose-policy.mjs.map +0 -1
  319. package/dist/lite-CBxOT1y5.mjs +0 -241
  320. package/dist/lite-CBxOT1y5.mjs.map +0 -1
  321. package/dist/routing-D8rTxtaV.mjs +0 -245
  322. package/dist/routing-D8rTxtaV.mjs.map +0 -1
  323. package/dist/web/_app/immutable/chunks/B6YN0Nuq.js +0 -1
  324. package/dist/web/_app/immutable/chunks/BmRlVmv6.js +0 -1
  325. package/dist/web/_app/immutable/chunks/CK9JZLaG.js +0 -2
  326. package/dist/web/_app/immutable/chunks/Ck3rYNON.js +0 -1
  327. package/dist/web/_app/immutable/chunks/DMtIqaiV.js +0 -2
  328. package/dist/web/_app/immutable/chunks/DhD271EB.js +0 -1
  329. package/dist/web/_app/immutable/chunks/DpuLqk8d.js +0 -1
  330. package/dist/web/_app/immutable/chunks/DsIToJCP.js +0 -1
  331. package/dist/web/_app/immutable/chunks/bBmtyQMj.js +0 -1
  332. package/dist/web/_app/immutable/entry/app.CJmSwntr.js +0 -2
  333. package/dist/web/_app/immutable/entry/start.ZpUrT2ak.js +0 -1
  334. package/dist/web/_app/immutable/nodes/1.Bli0Hqzn.js +0 -1
  335. package/dist/web/_app/immutable/nodes/4.oBhvQhcA.js +0 -60
  336. package/dist/workspace-BJmJBfKi.mjs +0 -456
  337. package/dist/workspace-BJmJBfKi.mjs.map +0 -1
  338. package/src/cli/e2e/agents.test.ts +0 -140
  339. package/src/cli/e2e/basic.test.ts +0 -43
  340. package/src/cli/e2e/cron.test.ts +0 -132
  341. package/src/cli/e2e/export-lite-func.test.ts +0 -206
  342. package/src/cli/e2e/fallbacks.test.ts +0 -175
  343. package/src/cli/e2e/init.test.ts +0 -77
  344. package/src/cli/e2e/messages.test.ts +0 -332
  345. package/src/cli/e2e/propose-policy.test.ts +0 -203
  346. package/src/cli/e2e/requests.test.ts +0 -180
  347. package/src/cli/e2e/session-timeout.test.ts +0 -192
  348. package/src/cli/e2e/slash-new.test.ts +0 -93
  349. package/src/cli/e2e/subagents.test.ts +0 -106
  350. package/src/cli/e2e/utils.ts +0 -66
  351. package/src/cli/propose-policy.ts +0 -91
  352. package/web/.svelte-kit/output/client/_app/immutable/chunks/B6YN0Nuq.js +0 -1
  353. package/web/.svelte-kit/output/client/_app/immutable/chunks/BmRlVmv6.js +0 -1
  354. package/web/.svelte-kit/output/client/_app/immutable/chunks/CK9JZLaG.js +0 -2
  355. package/web/.svelte-kit/output/client/_app/immutable/chunks/Ck3rYNON.js +0 -1
  356. package/web/.svelte-kit/output/client/_app/immutable/chunks/DMtIqaiV.js +0 -2
  357. package/web/.svelte-kit/output/client/_app/immutable/chunks/DhD271EB.js +0 -1
  358. package/web/.svelte-kit/output/client/_app/immutable/chunks/DpuLqk8d.js +0 -1
  359. package/web/.svelte-kit/output/client/_app/immutable/chunks/DsIToJCP.js +0 -1
  360. package/web/.svelte-kit/output/client/_app/immutable/chunks/bBmtyQMj.js +0 -1
  361. package/web/.svelte-kit/output/client/_app/immutable/entry/app.CJmSwntr.js +0 -2
  362. package/web/.svelte-kit/output/client/_app/immutable/entry/start.ZpUrT2ak.js +0 -1
  363. package/web/.svelte-kit/output/client/_app/immutable/nodes/1.Bli0Hqzn.js +0 -1
  364. package/web/.svelte-kit/output/client/_app/immutable/nodes/4.oBhvQhcA.js +0 -60
  365. package/web/.svelte-kit/output/server/chunks/false.js +0 -4
  366. /package/dist/cli/{propose-policy.d.mts → manage-policies.d.mts} +0 -0
  367. /package/{src/cli/e2e → e2e/_helpers}/global-setup.ts +0 -0
@@ -0,0 +1,767 @@
1
+ import http from "node:http";
2
+
3
+ //#region src/shared/adapters/filtering.ts
4
+ /**
5
+ * Legacy boolean. Returns true if the message role is permitted to be
6
+ * displayed at all; adapters that haven't migrated to `routeMessage` keep
7
+ * using this unchanged.
8
+ */
9
+ function shouldDisplayMessage(message, config) {
10
+ const overrides = config.filters || {};
11
+ if (message.subagentId && overrides["subagent"] !== true) return false;
12
+ if (message.displayRole === "agent" || message.role === "agent" || message.role === "legacy_log" || message.role === "policy" && message.status === "pending") return true;
13
+ if (message.subagentId && overrides["subagent"] === true && (message.role === "user" || message.displayRole === "user")) return true;
14
+ if (overrides[message.role] === true || message.displayRole && overrides[message.displayRole] === true) return true;
15
+ return false;
16
+ }
17
+ function defaultDestinationForRole(message) {
18
+ if (message.role === "user") return { kind: "drop" };
19
+ if (message.role === "agent") return { kind: "top-level" };
20
+ if (message.role === "legacy_log") return { kind: "top-level" };
21
+ if (message.role === "tool") return { kind: "thread-log" };
22
+ if (message.role === "subagent_status") return { kind: "thread-log" };
23
+ if (message.role === "command") return { kind: "drop" };
24
+ if (message.role === "policy") return message.status === "pending" ? { kind: "top-level" } : { kind: "thread-log" };
25
+ if (message.role === "system") {
26
+ if (message.event === "cron") return { kind: "drop" };
27
+ if (message.event === "policy_approved" || message.event === "policy_rejected") return { kind: "thread-log" };
28
+ if (message.event === "subagent_update") return { kind: "thread-log" };
29
+ return { kind: "top-level" };
30
+ }
31
+ return { kind: "drop" };
32
+ }
33
+ /**
34
+ * Return the destination for a chat message given the adapter's filtering
35
+ * config. Adapters that support threaded activity logs (Google Chat) use this
36
+ * to decide whether each message becomes a top-level post, a thread-log entry,
37
+ * or is dropped entirely.
38
+ *
39
+ * A filter override of `true` on a role whose default destination is `drop`
40
+ * promotes it to `top-level` (matching the legacy "opted in → show" behavior).
41
+ * A filter override of `false` drops the role.
42
+ *
43
+ * Subagent messages route to their default destination when that default is a
44
+ * thread one (tool calls, command logs, status updates all belong in the turn
45
+ * log). They are dropped when the default is top-level — subagent prompts and
46
+ * final replies are orchestration, not user-facing content — unless
47
+ * `filters.subagent` is `true`, which surfaces them at top-level for debugging.
48
+ */
49
+ function routeMessage(message, config) {
50
+ const overrides = config.filters || {};
51
+ const defaultDest = defaultDestinationForRole(message);
52
+ if (message.subagentId) {
53
+ if (overrides["subagent"] === true) return defaultDest.kind === "drop" ? { kind: "top-level" } : defaultDest;
54
+ return { kind: "thread-log" };
55
+ }
56
+ if (message.displayRole === "agent" || message.role === "agent" || message.role === "legacy_log" || message.role === "policy" && message.status === "pending") return defaultDest;
57
+ const roleFilter = overrides[message.role];
58
+ const displayRoleFilter = message.displayRole ? overrides[message.displayRole] : void 0;
59
+ if (roleFilter === false || displayRoleFilter === false) return { kind: "drop" };
60
+ if (roleFilter === true || displayRoleFilter === true) return defaultDest.kind === "drop" ? { kind: "top-level" } : defaultDest;
61
+ return defaultDest;
62
+ }
63
+ function formatMessage(message) {
64
+ if (message.role === "system" && !message.displayRole && !message.subagentId) return `[SYSTEM] ${message.content}`;
65
+ if (!message.subagentId) return message.content;
66
+ if (message.role === "user" || message.displayRole === "user") return `[To:${message.subagentId}]\n${message.content}`;
67
+ return `[From:${message.subagentId}]\n${message.content}`;
68
+ }
69
+
70
+ //#endregion
71
+ //#region src/shared/adapters/inbound-cache.ts
72
+ function createInboundCache(ttlMs) {
73
+ const cache = /* @__PURE__ */ new Map();
74
+ const sweep = (now) => {
75
+ for (const [key, entry] of cache) if (now - entry.receivedAt > ttlMs) cache.delete(key);
76
+ };
77
+ return {
78
+ record(key, value) {
79
+ const now = Date.now();
80
+ sweep(now);
81
+ cache.set(key, {
82
+ value,
83
+ receivedAt: now
84
+ });
85
+ },
86
+ resolve(key) {
87
+ const entry = cache.get(key);
88
+ if (!entry) return null;
89
+ if (Date.now() - entry.receivedAt > ttlMs) {
90
+ cache.delete(key);
91
+ return null;
92
+ }
93
+ return entry.value;
94
+ },
95
+ reset() {
96
+ cache.clear();
97
+ }
98
+ };
99
+ }
100
+
101
+ //#endregion
102
+ //#region src/shared/adapters/commands.ts
103
+ const VALID_ROLES = new Set([
104
+ "subagent",
105
+ "command",
106
+ "system",
107
+ "tool",
108
+ "policy",
109
+ "subagent_status",
110
+ "legacy_log"
111
+ ]);
112
+ async function handleAdapterCommand(content, config, trpcClient, chatId) {
113
+ const trimmed = content.trim();
114
+ if (trimmed === "/show all") {
115
+ const newConfig = { filters: { ...config.filters } };
116
+ for (const role of VALID_ROLES) newConfig.filters[role] = true;
117
+ return {
118
+ type: "text",
119
+ text: "Configuration updated: Showing all messages.",
120
+ newConfig
121
+ };
122
+ }
123
+ if (trimmed === "/hide all") return {
124
+ type: "text",
125
+ text: "Configuration updated: Hidden all overrides (using defaults).",
126
+ newConfig: { filters: {} }
127
+ };
128
+ if (trimmed === "/show" || trimmed === "/hide") return {
129
+ type: "text",
130
+ text: `Valid options for ${trimmed}: ${Array.from(VALID_ROLES).join(", ")}`
131
+ };
132
+ if (trimmed.startsWith("/show ")) {
133
+ const role = trimmed.slice(6).trim();
134
+ if (!VALID_ROLES.has(role)) return {
135
+ type: "text",
136
+ text: `Error: '${role}' is not a valid message role or special value. Valid options: ${Array.from(VALID_ROLES).join(", ")}`
137
+ };
138
+ return {
139
+ type: "text",
140
+ text: `Configuration updated: Showing messages for '${role}'.`,
141
+ newConfig: { filters: {
142
+ ...config.filters,
143
+ [role]: true
144
+ } }
145
+ };
146
+ }
147
+ if (trimmed.startsWith("/hide ")) {
148
+ const role = trimmed.slice(6).trim();
149
+ if (!VALID_ROLES.has(role)) return {
150
+ type: "text",
151
+ text: `Error: '${role}' is not a valid message role or special value. Valid options: ${Array.from(VALID_ROLES).join(", ")}`
152
+ };
153
+ return {
154
+ type: "text",
155
+ text: `Configuration updated: Hiding messages for '${role}'.`,
156
+ newConfig: { filters: {
157
+ ...config.filters,
158
+ [role]: false
159
+ } }
160
+ };
161
+ }
162
+ if (trimmed === "/debug" || trimmed.startsWith("/debug ")) {
163
+ const match = trimmed.match(/^\/debug\s+(\d+)$/);
164
+ const limit = match ? parseInt(match[1], 10) : 5;
165
+ const messages = await trpcClient.getMessages.query({
166
+ chatId,
167
+ limit: limit * 10
168
+ });
169
+ const ignoredMessages = [];
170
+ for (let i = messages.length - 1; i >= 0; i--) {
171
+ const msg = messages[i];
172
+ if (!msg) continue;
173
+ if ((msg.role === "user" || msg.displayRole === "user") && !msg.subagentId) continue;
174
+ if (!shouldDisplayMessage(msg, config)) {
175
+ ignoredMessages.push(msg);
176
+ if (ignoredMessages.length >= limit) break;
177
+ }
178
+ }
179
+ ignoredMessages.reverse();
180
+ return {
181
+ type: "debug",
182
+ messages: ignoredMessages
183
+ };
184
+ }
185
+ return null;
186
+ }
187
+
188
+ //#endregion
189
+ //#region src/shared/adapters/routing.ts
190
+ async function handleRoutingCommand(content, externalContextId, currentChannelChatMap, adapterName, trpcClient) {
191
+ const trimmed = content.trim();
192
+ if (trimmed.startsWith("/chat")) {
193
+ const chatId = trimmed.split(/\s+/).slice(1)[0];
194
+ const availableChats = await trpcClient.getChats.query();
195
+ if (!chatId || !availableChats.includes(chatId)) return {
196
+ type: "reply",
197
+ text: `Available chats:\n${availableChats.length > 0 ? availableChats.map((c) => `- ${c}`).join("\n") : "No chats available."}\n\nPlease specify a valid chat ID: \`/chat [chat-id]\``
198
+ };
199
+ for (const [channelId, mappedId] of Object.entries(currentChannelChatMap)) if (mappedId === chatId && channelId !== externalContextId) return {
200
+ type: "reply",
201
+ text: `Error: Chat \`${chatId}\` is already mapped to another channel/space. Strict 1:1 mapping is required.`
202
+ };
203
+ return {
204
+ type: "mapped",
205
+ text: `Successfully mapped this channel/space to chat \`${chatId}\`.`,
206
+ newChatId: chatId
207
+ };
208
+ }
209
+ if (trimmed.startsWith("/agent")) {
210
+ const agentId = trimmed.split(/\s+/).slice(1)[0];
211
+ const availableAgents = await trpcClient.getAgents.query();
212
+ if (!agentId || !availableAgents.includes(agentId)) return {
213
+ type: "reply",
214
+ text: `Available agents:\n${availableAgents.length > 0 ? availableAgents.map((a) => `- ${a}`).join("\n") : "No agents available."}\n\nPlease specify a valid agent ID: \`/agent [agent-id]\``
215
+ };
216
+ const availableChats = await trpcClient.getChats.query();
217
+ let newChatId = `${agentId}-${adapterName}`;
218
+ let counter = 1;
219
+ while (availableChats.includes(newChatId)) {
220
+ newChatId = `${agentId}-${adapterName}-${counter}`;
221
+ counter++;
222
+ }
223
+ await trpcClient.createChat.mutate({
224
+ chatId: newChatId,
225
+ agent: agentId
226
+ });
227
+ return {
228
+ type: "mapped",
229
+ text: `Successfully created new chat \`${newChatId}\` with agent \`${agentId}\` and mapped it to this channel/space.`,
230
+ newChatId
231
+ };
232
+ }
233
+ return null;
234
+ }
235
+
236
+ //#endregion
237
+ //#region src/shared/adapters/blockquote.ts
238
+ /**
239
+ * Format `quoted` as a markdown blockquote prefixed before `body`.
240
+ *
241
+ * Each line of `quoted` is prefixed with `> `, and a blank line separates the
242
+ * quote from the body — CommonMark requires the blank line to terminate the
243
+ * blockquote, otherwise the body is lazily folded into it. If `sender` is
244
+ * provided, an attribution line (`> **{sender} said:**`) is rendered as the
245
+ * first line of the quote. Both inputs are trimmed.
246
+ */
247
+ function prependBlockquote(quoted, body, sender) {
248
+ const trimmedBody = body.trim();
249
+ const lines = quoted.trim().split("\n").map((line) => `> ${line}`);
250
+ if (sender) lines.unshift(`> **${sender} said:**`);
251
+ return `${lines.join("\n")}\n\n${trimmedBody}`;
252
+ }
253
+
254
+ //#endregion
255
+ //#region src/shared/event-source.ts
256
+ function createUnixSocketEventSource(socketPath) {
257
+ return class UnixSocketEventSource {
258
+ readyState = 0;
259
+ CONNECTING = 0;
260
+ OPEN = 1;
261
+ CLOSED = 2;
262
+ req = null;
263
+ listeners = {};
264
+ constructor(url, init) {
265
+ const parsedUrl = new URL(url);
266
+ const options = {
267
+ socketPath,
268
+ path: parsedUrl.pathname + parsedUrl.search,
269
+ method: "GET",
270
+ headers: {
271
+ Accept: "text/event-stream",
272
+ "Cache-Control": "no-cache",
273
+ ...init?.headers
274
+ }
275
+ };
276
+ this.req = http.request(options, (res) => {
277
+ if (res.statusCode === 200) {
278
+ this.readyState = this.OPEN;
279
+ this.dispatchEvent({ type: "open" });
280
+ } else {
281
+ this.readyState = this.CLOSED;
282
+ this.dispatchEvent({
283
+ type: "error",
284
+ message: `Unexpected status code: ${res.statusCode}`
285
+ });
286
+ return;
287
+ }
288
+ let buffer = "";
289
+ res.on("data", (chunk) => {
290
+ buffer += chunk.toString("utf-8");
291
+ const lines = buffer.split(/\r?\n\r?\n/);
292
+ buffer = lines.pop() || "";
293
+ for (const block of lines) this.parseBlock(block);
294
+ });
295
+ res.on("end", () => {
296
+ if (buffer) this.parseBlock(buffer);
297
+ this.readyState = this.CLOSED;
298
+ this.dispatchEvent({ type: "close" });
299
+ });
300
+ });
301
+ this.req.on("error", (err) => {
302
+ this.readyState = this.CLOSED;
303
+ this.dispatchEvent({
304
+ type: "error",
305
+ error: err
306
+ });
307
+ });
308
+ this.req.end();
309
+ }
310
+ parseBlock(block) {
311
+ if (!block.trim()) return;
312
+ const lines = block.split(/\r?\n/);
313
+ let eventType = "message";
314
+ let data = "";
315
+ let id = "";
316
+ for (const line of lines) if (line.startsWith("event: ")) eventType = line.slice(7).trim();
317
+ else if (line.startsWith("data: ")) data += (data ? "\n" : "") + line.slice(6);
318
+ else if (line.startsWith("id: ")) id = line.slice(4).trim();
319
+ if (data) this.dispatchEvent({
320
+ type: eventType,
321
+ data,
322
+ lastEventId: id
323
+ });
324
+ }
325
+ addEventListener(type, listener) {
326
+ if (!this.listeners[type]) this.listeners[type] = [];
327
+ this.listeners[type].push(listener);
328
+ }
329
+ removeEventListener(type, listener) {
330
+ if (!this.listeners[type]) return;
331
+ this.listeners[type] = this.listeners[type].filter((l) => l !== listener);
332
+ }
333
+ dispatchEvent(event) {
334
+ const type = event.type;
335
+ if (this.listeners[type]) for (const listener of this.listeners[type]) listener(event);
336
+ }
337
+ close() {
338
+ this.readyState = this.CLOSED;
339
+ if (this.req) this.req.destroy();
340
+ }
341
+ };
342
+ }
343
+
344
+ //#endregion
345
+ //#region src/shared/adapters/turn-log.ts
346
+ const DEFAULT_MAX_TOOL_PREVIEW = 400;
347
+ const TRUNCATED_SUFFIX = "…[truncated]";
348
+ const ROLLOVER_MARKER = "• …log continues";
349
+ function pad2(n) {
350
+ return n < 10 ? `0${n}` : String(n);
351
+ }
352
+ function formatRelative(deltaMs) {
353
+ const sec = Math.max(0, Math.floor(deltaMs / 1e3));
354
+ if (sec < 60) return `${sec}s`;
355
+ const m = Math.floor(sec / 60);
356
+ const s = sec % 60;
357
+ return s === 0 ? `${m}m` : `${m}m${s}s`;
358
+ }
359
+ function formatTimestamp(iso, turnStartedAt) {
360
+ if (turnStartedAt) {
361
+ const start = new Date(turnStartedAt).getTime();
362
+ const now = iso ? new Date(iso).getTime() : Date.now();
363
+ if (!Number.isNaN(start) && !Number.isNaN(now)) return formatRelative(now - start);
364
+ }
365
+ const d = iso ? new Date(iso) : /* @__PURE__ */ new Date();
366
+ const valid = !Number.isNaN(d.getTime()) ? d : /* @__PURE__ */ new Date();
367
+ return `${pad2(valid.getHours())}:${pad2(valid.getMinutes())}:${pad2(valid.getSeconds())}`;
368
+ }
369
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
370
+ function shortSubagentId(id) {
371
+ return UUID_RE.test(id) ? id.slice(0, 8) : id;
372
+ }
373
+ /**
374
+ * Extract a (verb, principal-arg) pair from a tool message so the turn log
375
+ * can render `read: foo.md` instead of `read_file({ "file_path": "foo.md" })`.
376
+ * Unknown tool names fall back to `<name>: <stringified-payload>` so we don't
377
+ * silently lose information.
378
+ */
379
+ function extractToolPrincipal(name, payload) {
380
+ const p = payload ?? {};
381
+ const str = (v) => v == null ? "" : String(v);
382
+ switch (name) {
383
+ case "read_file":
384
+ case "Read": return {
385
+ verb: "read",
386
+ arg: str(p.file_path ?? p.path)
387
+ };
388
+ case "write_file":
389
+ case "create_file":
390
+ case "Write": return {
391
+ verb: "write",
392
+ arg: str(p.file_path ?? p.path)
393
+ };
394
+ case "edit_file":
395
+ case "Edit": return {
396
+ verb: "edit",
397
+ arg: str(p.file_path ?? p.path)
398
+ };
399
+ case "run_shell_command":
400
+ case "shell":
401
+ case "Bash": return {
402
+ verb: "shell",
403
+ arg: str(p.command)
404
+ };
405
+ case "activate_skill":
406
+ case "Skill": return {
407
+ verb: "skill",
408
+ arg: str(p.name ?? p.skill)
409
+ };
410
+ case "glob":
411
+ case "Glob": return {
412
+ verb: "glob",
413
+ arg: str(p.pattern)
414
+ };
415
+ case "grep":
416
+ case "Grep": return {
417
+ verb: "grep",
418
+ arg: str(p.pattern)
419
+ };
420
+ case "web_fetch":
421
+ case "WebFetch": return {
422
+ verb: "fetch",
423
+ arg: str(p.url)
424
+ };
425
+ }
426
+ return {
427
+ verb: name,
428
+ arg: payload === void 0 || payload === null ? "" : JSON.stringify(payload)
429
+ };
430
+ }
431
+ function statusSigil(status) {
432
+ return status === "completed" ? "✅" : "❌";
433
+ }
434
+ /** Emoji for messages crossing the subagent boundary. */
435
+ const SUBAGENT_TO = "👉";
436
+ const SUBAGENT_FROM = "👈";
437
+ /**
438
+ * Emoji that stands in for a known tool verb. When present, it replaces the
439
+ * verb word entirely (`🐚 sleep 20` instead of `shell: sleep 20`). Unknown
440
+ * tools fall through to the `<name>: <arg>` form, preserving accessibility.
441
+ */
442
+ const VERB_EMOJI = {
443
+ read: "📖",
444
+ write: "✍️",
445
+ edit: "✏️",
446
+ shell: "🧑‍💻",
447
+ skill: "📚",
448
+ glob: "📁",
449
+ grep: "🔎",
450
+ fetch: "🌐"
451
+ };
452
+ const SUBAGENT_MARKER = "🤖";
453
+ /** Emoji rendered on the turn's opening entry (posted when the turn starts). */
454
+ const TURN_START_EMOJI = "▶️";
455
+ /**
456
+ * Entries produced *inside* a subagent (a tool call, policy, system event
457
+ * with `subagentId` set) need a marker so the reader knows the activity
458
+ * happened inside the delegated turn. Boundary events (prompt, reply, status)
459
+ * already name the subagent via 👉/👈/✅, so they're excluded.
460
+ */
461
+ function needsSubagentMarker(entry) {
462
+ if (!entry.subagentId) return false;
463
+ return entry.messageRole !== "user" && entry.messageRole !== "agent" && entry.messageRole !== "subagent_status";
464
+ }
465
+ function truncate(s, max) {
466
+ if (s.length <= max) return s;
467
+ const budget = Math.max(0, max - 12);
468
+ return s.slice(0, budget) + TRUNCATED_SUFFIX;
469
+ }
470
+ function sanitize(s) {
471
+ return s.replace(/\s*\r?\n\s*/g, " ").trim();
472
+ }
473
+ function renderEntry(entry) {
474
+ const prefix = needsSubagentMarker(entry) ? `${SUBAGENT_MARKER} ${shortSubagentId(entry.subagentId)} ` : "";
475
+ return `• ${entry.timestamp} ${prefix}${entry.summary}`;
476
+ }
477
+ /**
478
+ * Build the first entry posted into a turn's activity log so the thread
479
+ * appears as soon as `turnStarted` fires, rather than waiting for the first
480
+ * real event.
481
+ */
482
+ function buildTurnStartEntry() {
483
+ const summary = `${TURN_START_EMOJI} Started processing…`;
484
+ return {
485
+ timestamp: "0s",
486
+ kind: "system",
487
+ summary,
488
+ rawLength: summary.length,
489
+ messageRole: "turn_start"
490
+ };
491
+ }
492
+ function formatTurnLogEntry(message, opts = {}) {
493
+ const maxToolPreview = opts.maxToolPreview ?? DEFAULT_MAX_TOOL_PREVIEW;
494
+ const timestamp = formatTimestamp(message.timestamp, opts.turnStartedAt);
495
+ if (message.role === "user" || message.role === "agent") {
496
+ if (!message.subagentId) return null;
497
+ const direction = message.role === "user" ? SUBAGENT_TO : SUBAGENT_FROM;
498
+ const content = sanitize(message.content);
499
+ return {
500
+ timestamp,
501
+ kind: "subagent",
502
+ summary: `${direction} ${shortSubagentId(message.subagentId)}: ${truncate(content, maxToolPreview)}`,
503
+ rawLength: content.length,
504
+ messageRole: message.role,
505
+ subagentId: message.subagentId
506
+ };
507
+ }
508
+ if (message.role === "tool") {
509
+ const { verb, arg } = extractToolPrincipal(message.name, message.payload);
510
+ const cleanArg = sanitize(arg);
511
+ const emoji = VERB_EMOJI[verb];
512
+ const argPreview = cleanArg ? truncate(cleanArg, maxToolPreview) : "";
513
+ let summary;
514
+ if (emoji) summary = argPreview ? `${emoji} ${argPreview}` : emoji;
515
+ else summary = argPreview ? `${verb}: ${argPreview}` : verb;
516
+ const entry = {
517
+ timestamp,
518
+ kind: "tool",
519
+ summary,
520
+ rawLength: cleanArg.length,
521
+ messageRole: message.role
522
+ };
523
+ if (message.subagentId) entry.subagentId = message.subagentId;
524
+ return entry;
525
+ }
526
+ if (message.role === "subagent_status") {
527
+ const id = shortSubagentId(message.subagentId);
528
+ const summary = `${statusSigil(message.status)} ${id}`;
529
+ return {
530
+ timestamp,
531
+ kind: "subagent",
532
+ summary,
533
+ rawLength: summary.length,
534
+ messageRole: message.role,
535
+ subagentId: message.subagentId
536
+ };
537
+ }
538
+ if (message.role === "policy") {
539
+ const body = `${message.commandName} ${message.args.join(" ")}`.trim();
540
+ const summary = `policy ${message.status}: ${body}`;
541
+ const entry = {
542
+ timestamp,
543
+ kind: "policy",
544
+ summary: truncate(sanitize(summary), maxToolPreview),
545
+ rawLength: summary.length,
546
+ messageRole: message.role
547
+ };
548
+ if (message.subagentId) entry.subagentId = message.subagentId;
549
+ return entry;
550
+ }
551
+ if (message.role === "system") {
552
+ if (message.event === "subagent_update") return null;
553
+ const content = sanitize(message.content || "");
554
+ const summary = content ? `${message.event}: ${content}` : message.event;
555
+ const entry = {
556
+ timestamp,
557
+ kind: "system",
558
+ summary: truncate(summary, maxToolPreview),
559
+ rawLength: summary.length,
560
+ messageRole: message.role
561
+ };
562
+ if (message.subagentId) entry.subagentId = message.subagentId;
563
+ return entry;
564
+ }
565
+ if (message.role === "command") return null;
566
+ if (message.role === "legacy_log") {
567
+ const content = sanitize(message.content);
568
+ const entry = {
569
+ timestamp,
570
+ kind: "system",
571
+ summary: truncate(content ? `log: ${content}` : "log", maxToolPreview),
572
+ rawLength: content.length,
573
+ messageRole: message.role
574
+ };
575
+ if (message.subagentId) entry.subagentId = message.subagentId;
576
+ return entry;
577
+ }
578
+ return null;
579
+ }
580
+ function joinLines(entries) {
581
+ return entries.map(renderEntry).join("\n");
582
+ }
583
+ function condenseTurnLog(entries, opts) {
584
+ const snapshot = entries.slice();
585
+ if (snapshot.length === 0) return {
586
+ kind: "fits",
587
+ text: ""
588
+ };
589
+ const fullText = joinLines(snapshot);
590
+ if (fullText.length <= opts.maxChars) return {
591
+ kind: "fits",
592
+ text: fullText
593
+ };
594
+ const budget = Math.max(0, opts.maxChars - 17);
595
+ const kept = [];
596
+ let runningLength = 0;
597
+ for (let i = 0; i < snapshot.length; i++) {
598
+ const line = renderEntry(snapshot[i]);
599
+ const next = runningLength === 0 ? line.length : runningLength + 1 + line.length;
600
+ if (next > budget) {
601
+ if (kept.length === 0) return {
602
+ kind: "rollover",
603
+ finalText: truncate(line, opts.maxChars),
604
+ carryEntries: snapshot.slice(i + 1)
605
+ };
606
+ const carryEntries = snapshot.slice(i);
607
+ return {
608
+ kind: "rollover",
609
+ finalText: `${joinLines(kept)}\n${ROLLOVER_MARKER}`,
610
+ carryEntries
611
+ };
612
+ }
613
+ runningLength = next;
614
+ kept.push(snapshot[i]);
615
+ }
616
+ return {
617
+ kind: "fits",
618
+ text: fullText
619
+ };
620
+ }
621
+
622
+ //#endregion
623
+ //#region src/shared/adapters/turn-log-buffer.ts
624
+ function createTurnLogBuffer(deps) {
625
+ const { options, threadsEnabled, postThreaded, editThreaded, isMissingMessageError } = deps;
626
+ const ctxs = /* @__PURE__ */ new Map();
627
+ const engaged = (ctx) => threadsEnabled && !ctx.threadsDisabled && !ctx.aborted;
628
+ const runFlush = async (ctx) => {
629
+ if (!engaged(ctx)) {
630
+ ctx.entries = [];
631
+ return;
632
+ }
633
+ if (ctx.anchor === void 0) return;
634
+ if (ctx.entries.length === 0) return;
635
+ let result = condenseTurnLog(ctx.entries, { maxChars: options.maxLogMessageChars });
636
+ const send = async () => {
637
+ const text = result.kind === "fits" ? result.text : result.finalText;
638
+ if (!ctx.activityLogMessageId) {
639
+ try {
640
+ const id = await postThreaded(ctx.anchor, text);
641
+ if (id) ctx.activityLogMessageId = id;
642
+ } catch (err) {
643
+ console.error(`Failed to open thread-log for turn ${ctx.turnId}; dropping further thread-log events for this turn.`, err);
644
+ ctx.aborted = true;
645
+ ctx.entries = [];
646
+ }
647
+ return;
648
+ }
649
+ try {
650
+ await editThreaded(ctx.anchor, ctx.activityLogMessageId, text);
651
+ } catch (err) {
652
+ if (isMissingMessageError(err)) {
653
+ console.warn("Log message missing on edit — opening a fresh log message.");
654
+ ctx.activityLogMessageId = void 0;
655
+ try {
656
+ const id = await postThreaded(ctx.anchor, text);
657
+ if (id) ctx.activityLogMessageId = id;
658
+ } catch (innerErr) {
659
+ console.error("Failed to re-open log message after missing edit:", innerErr);
660
+ ctx.activityLogMessageId = void 0;
661
+ }
662
+ } else {
663
+ await new Promise((resolve) => setTimeout(resolve, 500));
664
+ try {
665
+ await editThreaded(ctx.anchor, ctx.activityLogMessageId, text);
666
+ } catch (retryErr) {
667
+ console.warn("Edit failed twice — finalizing log message.", retryErr);
668
+ ctx.activityLogMessageId = void 0;
669
+ }
670
+ }
671
+ }
672
+ };
673
+ await send();
674
+ while (!ctx.aborted && result.kind === "rollover") {
675
+ const prevLen = ctx.entries.length;
676
+ ctx.entries = result.carryEntries.slice();
677
+ ctx.activityLogMessageId = void 0;
678
+ if (ctx.entries.length === 0) break;
679
+ if (ctx.entries.length >= prevLen) {
680
+ console.warn(`Turn-log entry larger than maxLogMessageChars — dropping head for turn ${ctx.turnId}`);
681
+ ctx.entries = ctx.entries.slice(1);
682
+ if (ctx.entries.length === 0) break;
683
+ }
684
+ result = condenseTurnLog(ctx.entries, { maxChars: options.maxLogMessageChars });
685
+ await send();
686
+ }
687
+ };
688
+ const enqueueFlush = (ctx) => {
689
+ ctx.flushChain = ctx.flushChain.then(() => runFlush(ctx)).catch((err) => console.error("Flush error:", err));
690
+ };
691
+ const scheduleFlush = (ctx) => {
692
+ if (!engaged(ctx)) return;
693
+ if (ctx.editTimer) return;
694
+ ctx.editTimer = setTimeout(() => {
695
+ ctx.editTimer = null;
696
+ enqueueFlush(ctx);
697
+ }, options.editDebounceMs);
698
+ };
699
+ return {
700
+ start(params) {
701
+ const ctx = {
702
+ turnId: params.turnId,
703
+ threadsDisabled: params.threadsDisabled,
704
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
705
+ anchor: params.anchorThread,
706
+ activityLogMessageId: void 0,
707
+ entries: threadsEnabled && !params.threadsDisabled ? [buildTurnStartEntry()] : [],
708
+ editTimer: null,
709
+ flushChain: Promise.resolve(),
710
+ aborted: false
711
+ };
712
+ ctxs.set(params.turnId, ctx);
713
+ if (ctx.anchor !== void 0 && engaged(ctx)) enqueueFlush(ctx);
714
+ },
715
+ append(turnId, message) {
716
+ const ctx = ctxs.get(turnId);
717
+ if (!ctx) return;
718
+ if (!engaged(ctx)) return;
719
+ const entry = formatTurnLogEntry(message, {
720
+ maxToolPreview: options.maxToolPreview,
721
+ turnStartedAt: ctx.startedAt
722
+ });
723
+ if (!entry) return;
724
+ ctx.entries.push(entry);
725
+ if (ctx.anchor !== void 0) scheduleFlush(ctx);
726
+ },
727
+ assignAnchor(turnId, anchor) {
728
+ const ctx = ctxs.get(turnId);
729
+ if (!ctx) return;
730
+ if (ctx.anchor !== void 0) return;
731
+ ctx.anchor = anchor;
732
+ if (engaged(ctx) && ctx.entries.length > 0) enqueueFlush(ctx);
733
+ },
734
+ async end(turnId) {
735
+ const ctx = ctxs.get(turnId);
736
+ if (!ctx) return;
737
+ if (ctx.editTimer) {
738
+ clearTimeout(ctx.editTimer);
739
+ ctx.editTimer = null;
740
+ }
741
+ enqueueFlush(ctx);
742
+ try {
743
+ await ctx.flushChain;
744
+ } catch (err) {
745
+ console.error("Final flush error:", err);
746
+ }
747
+ ctxs.delete(turnId);
748
+ },
749
+ has(turnId) {
750
+ return ctxs.has(turnId);
751
+ },
752
+ isAnchored(turnId) {
753
+ return ctxs.get(turnId)?.anchor !== void 0;
754
+ },
755
+ threadsDisabledFor(turnId) {
756
+ return ctxs.get(turnId)?.threadsDisabled ?? false;
757
+ },
758
+ shutdown() {
759
+ for (const ctx of ctxs.values()) if (ctx.editTimer) clearTimeout(ctx.editTimer);
760
+ ctxs.clear();
761
+ }
762
+ };
763
+ }
764
+
765
+ //#endregion
766
+ export { handleAdapterCommand as a, routeMessage as c, handleRoutingCommand as i, createUnixSocketEventSource as n, createInboundCache as o, prependBlockquote as r, formatMessage as s, createTurnLogBuffer as t };
767
+ //# sourceMappingURL=turn-log-buffer-DRgW53gl.mjs.map