@bastani/atomic 0.8.27 → 0.8.28-alpha.2

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 (397) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +120 -118
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +2 -2
  5. package/dist/builtin/subagents/package.json +1 -1
  6. package/dist/builtin/web-access/package.json +1 -1
  7. package/dist/builtin/workflows/CHANGELOG.md +22 -0
  8. package/dist/builtin/workflows/README.md +11 -9
  9. package/dist/builtin/workflows/builtin/open-claude-design.ts +150 -13
  10. package/dist/builtin/workflows/package.json +1 -1
  11. package/dist/builtin/workflows/src/authoring.d.ts +5 -2
  12. package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +3 -1
  13. package/dist/builtin/workflows/src/extension/hil-answer-notifications.ts +17 -25
  14. package/dist/builtin/workflows/src/extension/index.ts +133 -18
  15. package/dist/builtin/workflows/src/extension/render-result.ts +22 -2
  16. package/dist/builtin/workflows/src/extension/workflow-schema.ts +3 -3
  17. package/dist/builtin/workflows/src/runs/foreground/executor.ts +210 -16
  18. package/dist/builtin/workflows/src/sdk-surface.ts +1 -1
  19. package/dist/builtin/workflows/src/shared/authoring-contract.d.ts +42 -5
  20. package/dist/builtin/workflows/src/shared/store-types.ts +8 -2
  21. package/dist/builtin/workflows/src/shared/store.ts +51 -0
  22. package/dist/builtin/workflows/src/shared/types.ts +14 -4
  23. package/dist/builtin/workflows/src/tui/chat-surface.ts +32 -33
  24. package/dist/builtin/workflows/src/tui/graph-view.ts +4 -1
  25. package/dist/builtin/workflows/src/tui/prompt-card.ts +6 -0
  26. package/dist/builtin/workflows/src/tui/run-detail.ts +11 -4
  27. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +11 -1
  28. package/dist/builtin/workflows/src/tui/status-list.ts +32 -2
  29. package/dist/cli/args.d.ts +4 -0
  30. package/dist/cli/args.d.ts.map +1 -1
  31. package/dist/cli/args.js +35 -0
  32. package/dist/cli/args.js.map +1 -1
  33. package/dist/cli/project-trust.d.ts +10 -0
  34. package/dist/cli/project-trust.d.ts.map +1 -0
  35. package/dist/cli/project-trust.js +36 -0
  36. package/dist/cli/project-trust.js.map +1 -0
  37. package/dist/cli/startup-ui.d.ts +7 -0
  38. package/dist/cli/startup-ui.d.ts.map +1 -0
  39. package/dist/cli/startup-ui.js +57 -0
  40. package/dist/cli/startup-ui.js.map +1 -0
  41. package/dist/config.d.ts.map +1 -1
  42. package/dist/config.js +24 -3
  43. package/dist/config.js.map +1 -1
  44. package/dist/core/agent-session-runtime.d.ts +3 -1
  45. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  46. package/dist/core/agent-session-runtime.js +1 -0
  47. package/dist/core/agent-session-runtime.js.map +1 -1
  48. package/dist/core/agent-session-services.d.ts +2 -1
  49. package/dist/core/agent-session-services.d.ts.map +1 -1
  50. package/dist/core/agent-session-services.js +2 -2
  51. package/dist/core/agent-session-services.js.map +1 -1
  52. package/dist/core/agent-session.d.ts +9 -5
  53. package/dist/core/agent-session.d.ts.map +1 -1
  54. package/dist/core/agent-session.js +205 -51
  55. package/dist/core/agent-session.js.map +1 -1
  56. package/dist/core/auth-guidance.d.ts +10 -1
  57. package/dist/core/auth-guidance.d.ts.map +1 -1
  58. package/dist/core/auth-guidance.js +26 -1
  59. package/dist/core/auth-guidance.js.map +1 -1
  60. package/dist/core/auth-storage.d.ts.map +1 -1
  61. package/dist/core/auth-storage.js +4 -3
  62. package/dist/core/auth-storage.js.map +1 -1
  63. package/dist/core/compaction/branch-summarization.d.ts +5 -3
  64. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  65. package/dist/core/compaction/branch-summarization.js +16 -10
  66. package/dist/core/compaction/branch-summarization.js.map +1 -1
  67. package/dist/core/compaction/compaction.d.ts +4 -84
  68. package/dist/core/compaction/compaction.d.ts.map +1 -1
  69. package/dist/core/compaction/compaction.js +20 -502
  70. package/dist/core/compaction/compaction.js.map +1 -1
  71. package/dist/core/compaction/context-compaction.d.ts.map +1 -1
  72. package/dist/core/compaction/context-compaction.js +39 -82
  73. package/dist/core/compaction/context-compaction.js.map +1 -1
  74. package/dist/core/compaction/index.d.ts +1 -1
  75. package/dist/core/compaction/index.d.ts.map +1 -1
  76. package/dist/core/compaction/index.js +1 -1
  77. package/dist/core/compaction/index.js.map +1 -1
  78. package/dist/core/compaction/utils.d.ts +1 -1
  79. package/dist/core/compaction/utils.d.ts.map +1 -1
  80. package/dist/core/compaction/utils.js +1 -1
  81. package/dist/core/compaction/utils.js.map +1 -1
  82. package/dist/core/experimental.d.ts +2 -0
  83. package/dist/core/experimental.d.ts.map +1 -0
  84. package/dist/core/experimental.js +5 -0
  85. package/dist/core/experimental.js.map +1 -0
  86. package/dist/core/export-html/template.js +19 -6
  87. package/dist/core/extensions/index.d.ts +1 -1
  88. package/dist/core/extensions/index.d.ts.map +1 -1
  89. package/dist/core/extensions/index.js.map +1 -1
  90. package/dist/core/extensions/loader.d.ts +1 -1
  91. package/dist/core/extensions/loader.d.ts.map +1 -1
  92. package/dist/core/extensions/loader.js +6 -4
  93. package/dist/core/extensions/loader.js.map +1 -1
  94. package/dist/core/extensions/runner.d.ts +11 -4
  95. package/dist/core/extensions/runner.d.ts.map +1 -1
  96. package/dist/core/extensions/runner.js +53 -3
  97. package/dist/core/extensions/runner.js.map +1 -1
  98. package/dist/core/extensions/types.d.ts +44 -12
  99. package/dist/core/extensions/types.d.ts.map +1 -1
  100. package/dist/core/extensions/types.js.map +1 -1
  101. package/dist/core/footer-data-provider.d.ts +2 -0
  102. package/dist/core/footer-data-provider.d.ts.map +1 -1
  103. package/dist/core/footer-data-provider.js +27 -1
  104. package/dist/core/footer-data-provider.js.map +1 -1
  105. package/dist/core/index.d.ts +2 -1
  106. package/dist/core/index.d.ts.map +1 -1
  107. package/dist/core/index.js +1 -0
  108. package/dist/core/index.js.map +1 -1
  109. package/dist/core/messages.d.ts +1 -11
  110. package/dist/core/messages.d.ts.map +1 -1
  111. package/dist/core/messages.js +10 -25
  112. package/dist/core/messages.js.map +1 -1
  113. package/dist/core/model-registry.d.ts.map +1 -1
  114. package/dist/core/model-registry.js +64 -7
  115. package/dist/core/model-registry.js.map +1 -1
  116. package/dist/core/model-resolver.d.ts.map +1 -1
  117. package/dist/core/model-resolver.js +1 -0
  118. package/dist/core/model-resolver.js.map +1 -1
  119. package/dist/core/output-guard.d.ts +1 -0
  120. package/dist/core/output-guard.d.ts.map +1 -1
  121. package/dist/core/output-guard.js +52 -22
  122. package/dist/core/output-guard.js.map +1 -1
  123. package/dist/core/package-manager.d.ts +1 -0
  124. package/dist/core/package-manager.d.ts.map +1 -1
  125. package/dist/core/package-manager.js +20 -8
  126. package/dist/core/package-manager.js.map +1 -1
  127. package/dist/core/project-trust.d.ts +15 -0
  128. package/dist/core/project-trust.d.ts.map +1 -0
  129. package/dist/core/project-trust.js +58 -0
  130. package/dist/core/project-trust.js.map +1 -0
  131. package/dist/core/prompt-templates.d.ts +5 -4
  132. package/dist/core/prompt-templates.d.ts.map +1 -1
  133. package/dist/core/prompt-templates.js +30 -29
  134. package/dist/core/prompt-templates.js.map +1 -1
  135. package/dist/core/provider-attribution.d.ts +4 -0
  136. package/dist/core/provider-attribution.d.ts.map +1 -0
  137. package/dist/core/provider-attribution.js +73 -0
  138. package/dist/core/provider-attribution.js.map +1 -0
  139. package/dist/core/provider-display-names.d.ts.map +1 -1
  140. package/dist/core/provider-display-names.js +3 -0
  141. package/dist/core/provider-display-names.js.map +1 -1
  142. package/dist/core/resolve-config-value.d.ts +9 -1
  143. package/dist/core/resolve-config-value.d.ts.map +1 -1
  144. package/dist/core/resolve-config-value.js +134 -11
  145. package/dist/core/resolve-config-value.js.map +1 -1
  146. package/dist/core/resource-loader.d.ts +12 -2
  147. package/dist/core/resource-loader.d.ts.map +1 -1
  148. package/dist/core/resource-loader.js +108 -18
  149. package/dist/core/resource-loader.js.map +1 -1
  150. package/dist/core/sdk.d.ts.map +1 -1
  151. package/dist/core/sdk.js +12 -42
  152. package/dist/core/sdk.js.map +1 -1
  153. package/dist/core/session-manager.d.ts +11 -15
  154. package/dist/core/session-manager.d.ts.map +1 -1
  155. package/dist/core/session-manager.js +111 -111
  156. package/dist/core/session-manager.js.map +1 -1
  157. package/dist/core/settings-manager.d.ts +15 -5
  158. package/dist/core/settings-manager.d.ts.map +1 -1
  159. package/dist/core/settings-manager.js +69 -14
  160. package/dist/core/settings-manager.js.map +1 -1
  161. package/dist/core/slash-commands.d.ts.map +1 -1
  162. package/dist/core/slash-commands.js +1 -0
  163. package/dist/core/slash-commands.js.map +1 -1
  164. package/dist/core/system-prompt.d.ts.map +1 -1
  165. package/dist/core/system-prompt.js +0 -3
  166. package/dist/core/system-prompt.js.map +1 -1
  167. package/dist/core/tools/bash.d.ts.map +1 -1
  168. package/dist/core/tools/bash.js +2 -1
  169. package/dist/core/tools/bash.js.map +1 -1
  170. package/dist/core/tools/edit.d.ts.map +1 -1
  171. package/dist/core/tools/edit.js +7 -10
  172. package/dist/core/tools/edit.js.map +1 -1
  173. package/dist/core/tools/find.d.ts.map +1 -1
  174. package/dist/core/tools/find.js +1 -1
  175. package/dist/core/tools/find.js.map +1 -1
  176. package/dist/core/tools/grep.d.ts.map +1 -1
  177. package/dist/core/tools/grep.js +1 -1
  178. package/dist/core/tools/grep.js.map +1 -1
  179. package/dist/core/tools/ls.d.ts.map +1 -1
  180. package/dist/core/tools/ls.js +1 -1
  181. package/dist/core/tools/ls.js.map +1 -1
  182. package/dist/core/tools/oversized-tool-result.d.ts +53 -0
  183. package/dist/core/tools/oversized-tool-result.d.ts.map +1 -0
  184. package/dist/core/tools/oversized-tool-result.js +206 -0
  185. package/dist/core/tools/oversized-tool-result.js.map +1 -0
  186. package/dist/core/tools/read.d.ts +12 -0
  187. package/dist/core/tools/read.d.ts.map +1 -1
  188. package/dist/core/tools/read.js +99 -34
  189. package/dist/core/tools/read.js.map +1 -1
  190. package/dist/core/tools/render-utils.d.ts +6 -0
  191. package/dist/core/tools/render-utils.d.ts.map +1 -1
  192. package/dist/core/tools/render-utils.js +17 -1
  193. package/dist/core/tools/render-utils.js.map +1 -1
  194. package/dist/core/tools/tool-definition-wrapper.d.ts +6 -0
  195. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  196. package/dist/core/tools/tool-definition-wrapper.js +2 -0
  197. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  198. package/dist/core/tools/tool-limits.d.ts +25 -0
  199. package/dist/core/tools/tool-limits.d.ts.map +1 -0
  200. package/dist/core/tools/tool-limits.js +25 -0
  201. package/dist/core/tools/tool-limits.js.map +1 -0
  202. package/dist/core/tools/write.d.ts.map +1 -1
  203. package/dist/core/tools/write.js +1 -1
  204. package/dist/core/tools/write.js.map +1 -1
  205. package/dist/core/trust-manager.d.ts +31 -0
  206. package/dist/core/trust-manager.d.ts.map +1 -0
  207. package/dist/core/trust-manager.js +196 -0
  208. package/dist/core/trust-manager.js.map +1 -0
  209. package/dist/index.d.ts +12 -7
  210. package/dist/index.d.ts.map +1 -1
  211. package/dist/index.js +8 -4
  212. package/dist/index.js.map +1 -1
  213. package/dist/main.d.ts.map +1 -1
  214. package/dist/main.js +142 -30
  215. package/dist/main.js.map +1 -1
  216. package/dist/migrations.d.ts +3 -1
  217. package/dist/migrations.d.ts.map +1 -1
  218. package/dist/migrations.js +325 -7
  219. package/dist/migrations.js.map +1 -1
  220. package/dist/modes/index.d.ts +1 -1
  221. package/dist/modes/index.d.ts.map +1 -1
  222. package/dist/modes/index.js.map +1 -1
  223. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  224. package/dist/modes/interactive/components/bash-execution.js +2 -2
  225. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  226. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -5
  227. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  228. package/dist/modes/interactive/components/chat-message-renderer.js +5 -9
  229. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  230. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  231. package/dist/modes/interactive/components/chat-session-host.js +0 -3
  232. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  233. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  234. package/dist/modes/interactive/components/footer.js +6 -0
  235. package/dist/modes/interactive/components/footer.js.map +1 -1
  236. package/dist/modes/interactive/components/index.d.ts +1 -1
  237. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  238. package/dist/modes/interactive/components/index.js +1 -1
  239. package/dist/modes/interactive/components/index.js.map +1 -1
  240. package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  241. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  242. package/dist/modes/interactive/components/login-dialog.js +9 -16
  243. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  244. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  245. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  246. package/dist/modes/interactive/components/settings-selector.js +20 -0
  247. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  248. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  249. package/dist/modes/interactive/components/tool-execution.js +22 -0
  250. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  251. package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  252. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
  253. package/dist/modes/interactive/components/trust-selector.js +85 -0
  254. package/dist/modes/interactive/components/trust-selector.js.map +1 -0
  255. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  256. package/dist/modes/interactive/components/user-message.js +1 -1
  257. package/dist/modes/interactive/components/user-message.js.map +1 -1
  258. package/dist/modes/interactive/interactive-mode.d.ts +9 -0
  259. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  260. package/dist/modes/interactive/interactive-mode.js +134 -36
  261. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  262. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  263. package/dist/modes/interactive/theme/theme.js +10 -0
  264. package/dist/modes/interactive/theme/theme.js.map +1 -1
  265. package/dist/modes/print-mode.d.ts.map +1 -1
  266. package/dist/modes/print-mode.js +1 -0
  267. package/dist/modes/print-mode.js.map +1 -1
  268. package/dist/modes/rpc/rpc-client.d.ts +4 -1
  269. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  270. package/dist/modes/rpc/rpc-client.js +52 -8
  271. package/dist/modes/rpc/rpc-client.js.map +1 -1
  272. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  273. package/dist/modes/rpc/rpc-mode.js +24 -5
  274. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  275. package/dist/modes/rpc/rpc-types.d.ts +1 -1
  276. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  277. package/dist/modes/rpc/rpc-types.js.map +1 -1
  278. package/dist/package-manager-cli.d.ts +6 -2
  279. package/dist/package-manager-cli.d.ts.map +1 -1
  280. package/dist/package-manager-cli.js +104 -10
  281. package/dist/package-manager-cli.js.map +1 -1
  282. package/dist/utils/changelog.d.ts +1 -0
  283. package/dist/utils/changelog.d.ts.map +1 -1
  284. package/dist/utils/changelog.js +72 -0
  285. package/dist/utils/changelog.js.map +1 -1
  286. package/dist/utils/deprecation.d.ts +4 -0
  287. package/dist/utils/deprecation.d.ts.map +1 -0
  288. package/dist/utils/deprecation.js +13 -0
  289. package/dist/utils/deprecation.js.map +1 -0
  290. package/dist/utils/git.d.ts.map +1 -1
  291. package/dist/utils/git.js +54 -22
  292. package/dist/utils/git.js.map +1 -1
  293. package/dist/utils/json.d.ts +3 -0
  294. package/dist/utils/json.d.ts.map +1 -0
  295. package/dist/utils/json.js +7 -0
  296. package/dist/utils/json.js.map +1 -0
  297. package/dist/utils/open-browser.d.ts +9 -0
  298. package/dist/utils/open-browser.d.ts.map +1 -0
  299. package/dist/utils/open-browser.js +22 -0
  300. package/dist/utils/open-browser.js.map +1 -0
  301. package/docs/compaction.md +210 -181
  302. package/docs/containerization.md +111 -0
  303. package/docs/custom-provider.md +9 -9
  304. package/docs/development.md +1 -1
  305. package/docs/docs.json +2 -0
  306. package/docs/extensions.md +71 -24
  307. package/docs/index.md +2 -0
  308. package/docs/json.md +3 -4
  309. package/docs/models.md +10 -10
  310. package/docs/packages.md +1 -1
  311. package/docs/prompt-templates.md +9 -2
  312. package/docs/providers.md +18 -5
  313. package/docs/quickstart.md +1 -0
  314. package/docs/rpc.md +3 -2
  315. package/docs/sdk.md +5 -0
  316. package/docs/security.md +56 -0
  317. package/docs/session-format.md +14 -23
  318. package/docs/sessions.md +11 -1
  319. package/docs/settings.md +23 -9
  320. package/docs/skills.md +1 -1
  321. package/docs/terminal-setup.md +44 -2
  322. package/docs/themes.md +1 -1
  323. package/docs/tmux.md +4 -2
  324. package/docs/tui.md +14 -5
  325. package/docs/usage.md +17 -3
  326. package/docs/workflows.md +11 -9
  327. package/examples/README.md +1 -1
  328. package/examples/extensions/README.md +9 -6
  329. package/examples/extensions/bash-spawn-hook.ts +1 -1
  330. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  331. package/examples/extensions/claude-rules.ts +1 -1
  332. package/examples/extensions/commands.ts +1 -1
  333. package/examples/extensions/custom-compaction.ts +43 -106
  334. package/examples/extensions/custom-header.ts +1 -1
  335. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  336. package/examples/extensions/custom-provider-anthropic/package-lock.json +4 -4
  337. package/examples/extensions/custom-provider-anthropic/package.json +6 -6
  338. package/examples/extensions/custom-provider-gitlab-duo/index.ts +55 -4
  339. package/examples/extensions/custom-provider-gitlab-duo/package.json +3 -3
  340. package/examples/extensions/doom-overlay/README.md +1 -1
  341. package/examples/extensions/doom-overlay/index.ts +2 -2
  342. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  343. package/examples/extensions/gondolin/index.ts +523 -0
  344. package/examples/extensions/gondolin/package-lock.json +185 -0
  345. package/examples/extensions/gondolin/package.json +19 -0
  346. package/examples/extensions/handoff.ts +7 -45
  347. package/examples/extensions/hidden-thinking-label.ts +1 -1
  348. package/examples/extensions/inline-bash.ts +2 -2
  349. package/examples/extensions/input-transform-streaming.ts +39 -0
  350. package/examples/extensions/input-transform.ts +3 -3
  351. package/examples/extensions/interactive-shell.ts +2 -2
  352. package/examples/extensions/mac-system-theme.ts +2 -2
  353. package/examples/extensions/minimal-mode.ts +1 -1
  354. package/examples/extensions/modal-editor.ts +1 -1
  355. package/examples/extensions/model-status.ts +1 -1
  356. package/examples/extensions/overlay-qa-tests.ts +198 -179
  357. package/examples/extensions/overlay-test.ts +1 -1
  358. package/examples/extensions/pirate.ts +1 -1
  359. package/examples/extensions/preset.ts +14 -12
  360. package/examples/extensions/project-trust.ts +64 -0
  361. package/examples/extensions/prompt-customizer.ts +1 -1
  362. package/examples/extensions/qna.ts +1 -1
  363. package/examples/extensions/question.ts +1 -1
  364. package/examples/extensions/questionnaire.ts +1 -1
  365. package/examples/extensions/rainbow-editor.ts +1 -1
  366. package/examples/extensions/sandbox/index.ts +16 -14
  367. package/examples/extensions/sandbox/package-lock.json +90 -90
  368. package/examples/extensions/sandbox/package.json +17 -17
  369. package/examples/extensions/snake.ts +1 -1
  370. package/examples/extensions/space-invaders.ts +1 -1
  371. package/examples/extensions/ssh.ts +2 -2
  372. package/examples/extensions/subagent/README.md +13 -13
  373. package/examples/extensions/subagent/agents.ts +4 -2
  374. package/examples/extensions/subagent/index.ts +6 -6
  375. package/examples/extensions/summarize.ts +1 -1
  376. package/examples/extensions/tic-tac-toe.ts +1 -1
  377. package/examples/extensions/titlebar-spinner.ts +1 -1
  378. package/examples/extensions/todo.ts +1 -1
  379. package/examples/extensions/tool-override.ts +1 -1
  380. package/examples/extensions/tools.ts +6 -1
  381. package/examples/extensions/trigger-compact.ts +5 -4
  382. package/examples/extensions/with-deps/package-lock.json +4 -4
  383. package/examples/extensions/with-deps/package.json +7 -7
  384. package/examples/extensions/working-indicator.ts +4 -4
  385. package/examples/extensions/working-message-test.ts +1 -1
  386. package/examples/sdk/01-minimal.ts +1 -1
  387. package/examples/sdk/03-custom-prompt.ts +1 -1
  388. package/examples/sdk/04-skills.ts +1 -1
  389. package/examples/sdk/06-extensions.ts +2 -2
  390. package/examples/sdk/08-prompt-templates.ts +1 -1
  391. package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
  392. package/examples/sdk/README.md +2 -2
  393. package/package.json +8 -8
  394. package/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -16
  395. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +0 -1
  396. package/dist/modes/interactive/components/compaction-summary-message.js +0 -43
  397. package/dist/modes/interactive/components/compaction-summary-message.js.map +0 -1
@@ -1,10 +1,11 @@
1
1
  import { randomBytes, randomUUID } from "crypto";
2
- import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, statSync, writeFileSync, } from "fs";
2
+ import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readdirSync, readSync, statSync, writeFileSync, } from "fs";
3
3
  import { readdir, readFile, stat } from "fs/promises";
4
4
  import { join, resolve } from "path";
5
+ import { StringDecoder } from "string_decoder";
5
6
  import { getAgentDir as getDefaultAgentDir, getSessionsDir } from "../config.js";
6
7
  import { normalizePath, resolvePath } from "../utils/paths.js";
7
- import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "./messages.js";
8
+ import { createBranchSummaryMessage, createCustomMessage, } from "./messages.js";
8
9
  export const CURRENT_SESSION_VERSION = 3;
9
10
  function createUuidV7() {
10
11
  const bytes = randomBytes(16);
@@ -23,6 +24,11 @@ function createUuidV7() {
23
24
  function createSessionId() {
24
25
  return createUuidV7();
25
26
  }
27
+ export function assertValidSessionId(id) {
28
+ if (!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id)) {
29
+ throw new Error("Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character");
30
+ }
31
+ }
26
32
  /** Generate a unique short ID (8 hex chars, collision-checked) */
27
33
  function generateId(byId) {
28
34
  for (let i = 0; i < 100; i++) {
@@ -110,18 +116,10 @@ export function parseSessionEntries(content) {
110
116
  }
111
117
  return entries;
112
118
  }
113
- export function getLatestCompactionEntry(entries) {
114
- for (let i = entries.length - 1; i >= 0; i--) {
115
- if (entries[i].type === "compaction") {
116
- return entries[i];
117
- }
118
- }
119
- return null;
120
- }
121
119
  export function getLatestCompactionBoundaryEntry(entries) {
122
120
  for (let i = entries.length - 1; i >= 0; i--) {
123
121
  const entry = entries[i];
124
- if (entry.type === "compaction" || entry.type === "context_compaction") {
122
+ if (entry.type === "context_compaction") {
125
123
  return entry;
126
124
  }
127
125
  }
@@ -184,7 +182,6 @@ function filterMessageContentBlocks(message, deletedBlocks) {
184
182
  }
185
183
  case "bashExecution":
186
184
  case "branchSummary":
187
- case "compactionSummary":
188
185
  return message;
189
186
  }
190
187
  }
@@ -222,7 +219,7 @@ export function buildContextDeletionFilteredPath(path, filters = buildContextDel
222
219
  /**
223
220
  * Build the session context from entries using tree traversal.
224
221
  * If leafId is provided, walks from that entry to root.
225
- * Handles compaction and branch summaries along the path.
222
+ * Applies context-deletion filtering and includes branch summaries along the path.
226
223
  */
227
224
  export function buildSessionContext(entries, leafId, byId) {
228
225
  // Build uuid index if not available
@@ -255,10 +252,9 @@ export function buildSessionContext(entries, leafId, byId) {
255
252
  path.unshift(current);
256
253
  current = current.parentId ? byId.get(current.parentId) : undefined;
257
254
  }
258
- // Extract settings and find compaction
255
+ // Extract settings
259
256
  let thinkingLevel = "off";
260
257
  let model = null;
261
- let compaction = null;
262
258
  for (const entry of path) {
263
259
  if (entry.type === "thinking_level_change") {
264
260
  thinkingLevel = entry.thinkingLevel;
@@ -269,25 +265,12 @@ export function buildSessionContext(entries, leafId, byId) {
269
265
  else if (entry.type === "message" && entry.message.role === "assistant") {
270
266
  model = { provider: entry.message.provider, modelId: entry.message.model };
271
267
  }
272
- else if (entry.type === "compaction") {
273
- compaction = entry;
274
- }
275
268
  }
276
- const latestCompactionIndex = compaction
277
- ? path.findIndex((e) => e.type === "compaction" && e.id === compaction.id)
278
- : -1;
279
269
  const filteredPath = buildContextDeletionFilteredPath(path);
280
- const filteredEntryById = new Map(filteredPath.map((entry) => [entry.id, entry]));
281
- // Build messages and collect corresponding entries
282
- // When there's a compaction, we need to:
283
- // 1. Emit summary first (entry = compaction)
284
- // 2. Emit kept messages (from firstKeptEntryId up to compaction)
285
- // 3. Emit messages after compaction
270
+ // Build active context messages from the filtered path. Legacy "compaction"
271
+ // entries are archival metadata and intentionally inert here.
286
272
  const messages = [];
287
- const appendMessage = (rawEntry) => {
288
- const entry = filteredEntryById.get(rawEntry.id);
289
- if (!entry)
290
- return;
273
+ const appendMessage = (entry) => {
291
274
  let message;
292
275
  if (entry.type === "message") {
293
276
  message = entry.message;
@@ -301,33 +284,8 @@ export function buildSessionContext(entries, leafId, byId) {
301
284
  if (message)
302
285
  messages.push(message);
303
286
  };
304
- if (compaction) {
305
- // Emit summary first. Summary compaction entries are not deletion targets for
306
- // logical context compaction, so existing /compact rebuild behavior is preserved.
307
- messages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));
308
- const compactionIdx = latestCompactionIndex;
309
- // Emit kept messages (before compaction, starting from firstKeptEntryId)
310
- let foundFirstKept = false;
311
- for (let i = 0; i < compactionIdx; i++) {
312
- const entry = path[i];
313
- if (entry.id === compaction.firstKeptEntryId) {
314
- foundFirstKept = true;
315
- }
316
- if (foundFirstKept) {
317
- appendMessage(entry);
318
- }
319
- }
320
- // Emit messages after compaction
321
- for (let i = compactionIdx + 1; i < path.length; i++) {
322
- const entry = path[i];
323
- appendMessage(entry);
324
- }
325
- }
326
- else {
327
- // No compaction - emit all messages, handle branch summaries and custom messages
328
- for (const entry of path) {
329
- appendMessage(entry);
330
- }
287
+ for (const entry of filteredPath) {
288
+ appendMessage(entry);
331
289
  }
332
290
  return { messages, thinkingLevel, model };
333
291
  }
@@ -335,34 +293,64 @@ export function buildSessionContext(entries, leafId, byId) {
335
293
  * Compute the default session directory for a cwd.
336
294
  * Encodes cwd into a safe directory name under ~/.atomic/agent/sessions/.
337
295
  */
338
- export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
296
+ function getDefaultSessionDirPath(cwd, agentDir = getDefaultAgentDir()) {
339
297
  const resolvedCwd = resolvePath(cwd);
340
298
  const resolvedAgentDir = resolvePath(agentDir);
341
299
  const safePath = `--${resolvedCwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
342
- const sessionDir = join(resolvedAgentDir, "sessions", safePath);
300
+ return join(resolvedAgentDir, "sessions", safePath);
301
+ }
302
+ export function getDefaultSessionDir(cwd, agentDir = getDefaultAgentDir()) {
303
+ const sessionDir = getDefaultSessionDirPath(cwd, agentDir);
343
304
  if (!existsSync(sessionDir)) {
344
305
  mkdirSync(sessionDir, { recursive: true });
345
306
  }
346
307
  return sessionDir;
347
308
  }
309
+ const SESSION_READ_BUFFER_SIZE = 1024 * 1024;
310
+ function parseSessionEntryLine(line) {
311
+ if (!line.trim())
312
+ return null;
313
+ try {
314
+ return JSON.parse(line);
315
+ }
316
+ catch {
317
+ return null;
318
+ }
319
+ }
348
320
  /** Exported for testing */
349
321
  export function loadEntriesFromFile(filePath) {
350
322
  const resolvedFilePath = normalizePath(filePath);
351
323
  if (!existsSync(resolvedFilePath))
352
324
  return [];
353
- const content = readFileSync(resolvedFilePath, "utf8");
354
325
  const entries = [];
355
- const lines = content.trim().split("\n");
356
- for (const line of lines) {
357
- if (!line.trim())
358
- continue;
359
- try {
360
- const entry = JSON.parse(line);
361
- entries.push(entry);
362
- }
363
- catch {
364
- // Skip malformed lines
326
+ const fd = openSync(resolvedFilePath, "r");
327
+ try {
328
+ const decoder = new StringDecoder("utf8");
329
+ const buffer = Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);
330
+ let pending = "";
331
+ while (true) {
332
+ const bytesRead = readSync(fd, buffer, 0, buffer.length, null);
333
+ if (bytesRead === 0)
334
+ break;
335
+ pending += decoder.write(buffer.subarray(0, bytesRead));
336
+ let lineStart = 0;
337
+ let newlineIndex = pending.indexOf("\n", lineStart);
338
+ while (newlineIndex !== -1) {
339
+ const entry = parseSessionEntryLine(pending.slice(lineStart, newlineIndex));
340
+ if (entry)
341
+ entries.push(entry);
342
+ lineStart = newlineIndex + 1;
343
+ newlineIndex = pending.indexOf("\n", lineStart);
344
+ }
345
+ pending = pending.slice(lineStart);
365
346
  }
347
+ pending += decoder.end();
348
+ const finalEntry = parseSessionEntryLine(pending);
349
+ if (finalEntry)
350
+ entries.push(finalEntry);
351
+ }
352
+ finally {
353
+ closeSync(fd);
366
354
  }
367
355
  // Validate session header
368
356
  if (entries.length === 0)
@@ -373,7 +361,7 @@ export function loadEntriesFromFile(filePath) {
373
361
  }
374
362
  return entries;
375
363
  }
376
- function isValidSessionFile(filePath) {
364
+ function readSessionHeader(filePath) {
377
365
  try {
378
366
  const fd = openSync(filePath, "r");
379
367
  const buffer = Buffer.alloc(512);
@@ -381,23 +369,36 @@ function isValidSessionFile(filePath) {
381
369
  closeSync(fd);
382
370
  const firstLine = buffer.toString("utf8", 0, bytesRead).split("\n")[0];
383
371
  if (!firstLine)
384
- return false;
372
+ return null;
385
373
  const header = JSON.parse(firstLine);
386
- return header.type === "session" && typeof header.id === "string";
374
+ if (header.type !== "session" || typeof header.id !== "string") {
375
+ return null;
376
+ }
377
+ return header;
387
378
  }
388
379
  catch {
389
- return false;
380
+ return null;
390
381
  }
391
382
  }
383
+ function getSessionHeaderCwd(header) {
384
+ const cwd = header.cwd;
385
+ return typeof cwd === "string" ? cwd : undefined;
386
+ }
387
+ function sessionCwdMatches(cwd, resolvedCwd) {
388
+ return cwd !== undefined && cwd !== "" && resolvePath(cwd) === resolvedCwd;
389
+ }
392
390
  /** Exported for testing */
393
- export function findMostRecentSession(sessionDir) {
391
+ export function findMostRecentSession(sessionDir, cwd) {
394
392
  const resolvedSessionDir = normalizePath(sessionDir);
393
+ const resolvedCwd = cwd ? resolvePath(cwd) : undefined;
395
394
  try {
396
395
  const files = readdirSync(resolvedSessionDir)
397
396
  .filter((f) => f.endsWith(".jsonl"))
398
397
  .map((f) => join(resolvedSessionDir, f))
399
- .filter(isValidSessionFile)
400
- .map((path) => ({ path, mtime: statSync(path).mtime }))
398
+ .map((path) => ({ path, header: readSessionHeader(path) }))
399
+ .filter((file) => file.header !== null &&
400
+ (!resolvedCwd || sessionCwdMatches(getSessionHeaderCwd(file.header), resolvedCwd)))
401
+ .map(({ path }) => ({ path, mtime: statSync(path).mtime }))
401
402
  .sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
402
403
  return files[0]?.path || null;
403
404
  }
@@ -554,10 +555,10 @@ async function listSessionsFromDir(dir, onProgress, progressOffset = 0, progress
554
555
  * modifying history.
555
556
  *
556
557
  * Use buildSessionContext() to get the resolved message list for the LLM, which
557
- * handles compaction summaries and follows the path from root to current leaf.
558
+ * applies context-deletion filtering and follows the path from root to current leaf.
558
559
  */
559
560
  export class SessionManager {
560
- constructor(cwd, sessionDir, sessionFile, persist) {
561
+ constructor(cwd, sessionDir, sessionFile, persist, newSessionOptions) {
561
562
  this.sessionId = "";
562
563
  this.flushed = false;
563
564
  this.fileEntries = [];
@@ -575,7 +576,7 @@ export class SessionManager {
575
576
  this.setSessionFile(sessionFile);
576
577
  }
577
578
  else {
578
- this.newSession();
579
+ this.newSession(newSessionOptions);
579
580
  }
580
581
  }
581
582
  /** Switch to a different session file (used for resume and branching) */
@@ -608,6 +609,9 @@ export class SessionManager {
608
609
  }
609
610
  }
610
611
  newSession(options) {
612
+ if (options?.id !== undefined) {
613
+ assertValidSessionId(options.id);
614
+ }
611
615
  this.sessionId = options?.id ?? createSessionId();
612
616
  const timestamp = new Date().toISOString();
613
617
  const header = {
@@ -666,6 +670,9 @@ export class SessionManager {
666
670
  getSessionDir() {
667
671
  return this.sessionDir;
668
672
  }
673
+ usesDefaultSessionDir() {
674
+ return this.sessionDir === getDefaultSessionDirPath(this.cwd);
675
+ }
669
676
  getSessionId() {
670
677
  return this.sessionId;
671
678
  }
@@ -698,10 +705,10 @@ export class SessionManager {
698
705
  this._persist(entry);
699
706
  }
700
707
  /** Append a message as child of current leaf, then advance leaf. Returns entry id.
701
- * Does not allow writing CompactionSummaryMessage and BranchSummaryMessage directly.
708
+ * Does not allow writing branch summaries or context compaction metadata as regular messages.
702
709
  * Reason: we want these to be top-level entries in the session, not message session entries,
703
710
  * so it is easier to find them.
704
- * These need to be appended via appendCompaction() and appendBranchSummary() methods.
711
+ * Branch summaries are appended via appendBranchSummary(), and context compaction metadata via appendContextCompaction().
705
712
  */
706
713
  appendMessage(message) {
707
714
  const entry = {
@@ -739,22 +746,6 @@ export class SessionManager {
739
746
  this._appendEntry(entry);
740
747
  return entry.id;
741
748
  }
742
- /** Append a compaction summary as child of current leaf, then advance leaf. Returns entry id. */
743
- appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook) {
744
- const entry = {
745
- type: "compaction",
746
- id: generateId(this.byId),
747
- parentId: this.leafId,
748
- timestamp: new Date().toISOString(),
749
- summary,
750
- firstKeptEntryId,
751
- tokensBefore,
752
- details,
753
- fromHook,
754
- };
755
- this._appendEntry(entry);
756
- return entry.id;
757
- }
758
749
  /** Append logical deletion metadata for deletion-only context compaction. */
759
750
  appendContextCompaction(deletedTargets, protectedEntryIds, stats, backupPath) {
760
751
  const entry = {
@@ -1122,9 +1113,9 @@ export class SessionManager {
1122
1113
  * @param cwd Working directory (stored in session header)
1123
1114
  * @param sessionDir Optional session directory. If omitted, uses default (~/.atomic/agent/sessions/<encoded-cwd>/).
1124
1115
  */
1125
- static create(cwd, sessionDir) {
1116
+ static create(cwd, sessionDir, options) {
1126
1117
  const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
1127
- return new SessionManager(cwd, dir, undefined, true);
1118
+ return new SessionManager(cwd, dir, undefined, true, options);
1128
1119
  }
1129
1120
  /**
1130
1121
  * Open a specific session file.
@@ -1149,7 +1140,8 @@ export class SessionManager {
1149
1140
  */
1150
1141
  static continueRecent(cwd, sessionDir) {
1151
1142
  const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
1152
- const mostRecent = findMostRecentSession(dir);
1143
+ const filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);
1144
+ const mostRecent = findMostRecentSession(dir, filterCwd ? cwd : undefined);
1153
1145
  if (mostRecent) {
1154
1146
  return new SessionManager(cwd, dir, mostRecent, true);
1155
1147
  }
@@ -1166,7 +1158,7 @@ export class SessionManager {
1166
1158
  * @param targetCwd Target working directory (where the new session will be stored)
1167
1159
  * @param sessionDir Optional session directory. If omitted, uses default for targetCwd.
1168
1160
  */
1169
- static forkFrom(sourcePath, targetCwd, sessionDir) {
1161
+ static forkFrom(sourcePath, targetCwd, sessionDir, options) {
1170
1162
  const resolvedSourcePath = resolvePath(sourcePath);
1171
1163
  const resolvedTargetCwd = resolvePath(targetCwd);
1172
1164
  const sourceEntries = loadEntriesFromFile(resolvedSourcePath);
@@ -1182,7 +1174,10 @@ export class SessionManager {
1182
1174
  mkdirSync(dir, { recursive: true });
1183
1175
  }
1184
1176
  // Create new session file with new ID but forked content
1185
- const newSessionId = createSessionId();
1177
+ if (options?.id !== undefined) {
1178
+ assertValidSessionId(options.id);
1179
+ }
1180
+ const newSessionId = options?.id ?? createSessionId();
1186
1181
  const timestamp = new Date().toISOString();
1187
1182
  const fileTimestamp = timestamp.replace(/[:.]/g, "-");
1188
1183
  const newSessionFile = join(dir, `${fileTimestamp}_${newSessionId}.jsonl`);
@@ -1212,15 +1207,20 @@ export class SessionManager {
1212
1207
  */
1213
1208
  static async list(cwd, sessionDir, onProgress) {
1214
1209
  const dir = sessionDir ? normalizePath(sessionDir) : getDefaultSessionDir(cwd);
1215
- const sessions = await listSessionsFromDir(dir, onProgress);
1210
+ const filterCwd = sessionDir !== undefined && dir !== getDefaultSessionDirPath(cwd);
1211
+ const resolvedCwd = resolvePath(cwd);
1212
+ const sessions = (await listSessionsFromDir(dir, onProgress)).filter((session) => !filterCwd || sessionCwdMatches(session.cwd, resolvedCwd));
1216
1213
  sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
1217
1214
  return sessions;
1218
1215
  }
1219
- /**
1220
- * List all sessions across all project directories.
1221
- * @param onProgress Optional callback for progress updates (loaded, total)
1222
- */
1223
- static async listAll(onProgress) {
1216
+ static async listAll(sessionDirOrOnProgress, onProgress) {
1217
+ const customSessionDir = typeof sessionDirOrOnProgress === "string" ? normalizePath(sessionDirOrOnProgress) : undefined;
1218
+ const progress = typeof sessionDirOrOnProgress === "function" ? sessionDirOrOnProgress : onProgress;
1219
+ if (customSessionDir) {
1220
+ const sessions = await listSessionsFromDir(customSessionDir, progress);
1221
+ sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
1222
+ return sessions;
1223
+ }
1224
1224
  const sessionsDir = getSessionsDir();
1225
1225
  try {
1226
1226
  if (!existsSync(sessionsDir)) {
@@ -1248,7 +1248,7 @@ export class SessionManager {
1248
1248
  const results = await Promise.all(allFiles.map(async (file) => {
1249
1249
  const info = await buildSessionInfo(file);
1250
1250
  loaded++;
1251
- onProgress?.(loaded, totalFiles);
1251
+ progress?.(loaded, totalFiles);
1252
1252
  return info;
1253
1253
  }));
1254
1254
  for (const info of results) {