@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
@@ -42,7 +42,7 @@ export default function (pi: ExtensionAPI) {
42
42
  pi.registerProvider("my-provider", {
43
43
  name: "My Provider",
44
44
  baseUrl: "https://api.example.com",
45
- apiKey: "MY_API_KEY",
45
+ apiKey: "$MY_API_KEY",
46
46
  api: "openai-completions",
47
47
  models: [
48
48
  {
@@ -82,7 +82,7 @@ pi.registerProvider("openai", {
82
82
  pi.registerProvider("google", {
83
83
  baseUrl: "https://ai-gateway.corp.com/google",
84
84
  headers: {
85
- "X-Corp-Auth": "CORP_AUTH_TOKEN" // env var or literal
85
+ "X-Corp-Auth": "$CORP_AUTH_TOKEN" // resolves from env; omit $ for a literal
86
86
  }
87
87
  });
88
88
  ```
@@ -111,7 +111,7 @@ export default async function (pi: ExtensionAPI) {
111
111
 
112
112
  pi.registerProvider("local-openai", {
113
113
  baseUrl: "http://localhost:1234/v1",
114
- apiKey: "LOCAL_OPENAI_API_KEY",
114
+ apiKey: "$LOCAL_OPENAI_API_KEY",
115
115
  api: "openai-completions",
116
116
  models: payload.data.map((model) => ({
117
117
  id: model.id,
@@ -131,7 +131,7 @@ This registers the fetched models before startup finishes.
131
131
  ```typescript
132
132
  pi.registerProvider("my-llm", {
133
133
  baseUrl: "https://api.my-llm.com/v1",
134
- apiKey: "MY_LLM_API_KEY", // env var name or literal value
134
+ apiKey: "$MY_LLM_API_KEY", // env var reference; omit $ for a literal value
135
135
  api: "openai-completions", // which streaming API to use
136
136
  models: [
137
137
  {
@@ -162,7 +162,7 @@ Use `pi.unregisterProvider(name)` to remove a provider that was previously regis
162
162
  // Register
163
163
  pi.registerProvider("my-llm", {
164
164
  baseUrl: "https://api.my-llm.com/v1",
165
- apiKey: "MY_LLM_API_KEY",
165
+ apiKey: "$MY_LLM_API_KEY",
166
166
  api: "openai-completions",
167
167
  models: [
168
168
  {
@@ -240,7 +240,7 @@ If your provider expects `Authorization: Bearer <key>` but doesn't use a standar
240
240
  ```typescript
241
241
  pi.registerProvider("custom-api", {
242
242
  baseUrl: "https://api.example.com",
243
- apiKey: "MY_API_KEY",
243
+ apiKey: "$MY_API_KEY",
244
244
  authHeader: true, // adds Authorization: Bearer header
245
245
  api: "openai-completions",
246
246
  models: [...]
@@ -515,7 +515,7 @@ Register your stream function:
515
515
  ```typescript
516
516
  pi.registerProvider("my-provider", {
517
517
  baseUrl: "https://api.example.com",
518
- apiKey: "MY_API_KEY",
518
+ apiKey: "$MY_API_KEY",
519
519
  api: "my-custom-api",
520
520
  models: [...],
521
521
  streamSimple: streamMyProvider
@@ -552,7 +552,7 @@ interface ProviderConfig {
552
552
  /** API endpoint URL. Required when defining models. */
553
553
  baseUrl?: string;
554
554
 
555
- /** API key or environment variable name. Required when defining models (unless oauth). */
555
+ /** API key literal or config value (for env vars use "$ENV_VAR" or "${ENV_VAR}"). Required when defining models (unless oauth). */
556
556
  apiKey?: string;
557
557
 
558
558
  /** API type for streaming. Required at provider or model level when defining models. */
@@ -565,7 +565,7 @@ interface ProviderConfig {
565
565
  options?: SimpleStreamOptions
566
566
  ) => AssistantMessageEventStream;
567
567
 
568
- /** Custom headers to include in requests. Values can be env var names. */
568
+ /** Custom headers to include in requests. Values use the same config-value syntax as apiKey. */
569
569
  headers?: Record<string, string>;
570
570
 
571
571
  /** If true, adds Authorization: Bearer header with the resolved API key. */
@@ -11,7 +11,7 @@ bun install
11
11
  bun run typecheck
12
12
  ```
13
13
 
14
- Run package scripts from the monorepo root or package directory with Bun, for example:
14
+ This monorepo uses Bun for development commands; avoid npm/yarn/pnpm except for npm registry publishing. Run package scripts from the monorepo root or package directory with Bun, for example:
15
15
 
16
16
  ```bash
17
17
  bun run test:unit
package/docs/docs.json CHANGED
@@ -18,6 +18,8 @@
18
18
  "quickstart",
19
19
  "usage",
20
20
  "providers",
21
+ "security",
22
+ "containerization",
21
23
  "settings",
22
24
  "keybindings",
23
25
  "sessions",
@@ -8,7 +8,7 @@ Extensions are TypeScript modules that extend Atomic's behavior. They can subscr
8
8
 
9
9
  **Key capabilities:**
10
10
  - **Custom tools** - Register tools the LLM can call via `pi.registerTool()`
11
- - **Event interception** - Block or modify tool calls, inject context, customize legacy summary compaction and branch summaries
11
+ - **Event interception** - Block or modify tool calls, inject context, observe/cancel deletion-only compaction, and customize branch summaries
12
12
  - **User interaction** - Prompt users via `ctx.ui` (select, confirm, input, notify)
13
13
  - **Custom UI components** - Full TUI components with keyboard input via `ctx.ui.custom()` for complex interactions
14
14
  - **Custom commands** - Register commands like `/mycommand` via `pi.registerCommand()`
@@ -19,7 +19,7 @@ Extensions are TypeScript modules that extend Atomic's behavior. They can subscr
19
19
  - Permission gates (confirm before `rm -rf`, `sudo`, etc.)
20
20
  - Git checkpointing (stash at each turn, restore on branch)
21
21
  - Path protection (block writes to `.env`, `node_modules/`)
22
- - Legacy custom summary compaction (summarize older context your way)
22
+ - Compaction policies (cancel compaction or provide exact deletion targets)
23
23
  - Conversation summaries (see `summarize.ts` example)
24
24
  - Interactive tools (questions, wizards, custom dialogs)
25
25
  - Stateful tools (todo lists, connection pools)
@@ -205,7 +205,7 @@ export default async function (pi: ExtensionAPI) {
205
205
 
206
206
  pi.registerProvider("local-openai", {
207
207
  baseUrl: "http://localhost:1234/v1",
208
- apiKey: "LOCAL_OPENAI_API_KEY",
208
+ apiKey: "$LOCAL_OPENAI_API_KEY",
209
209
  api: "openai-completions",
210
210
  models: payload.data.map((model) => ({
211
211
  id: model.id,
@@ -276,6 +276,7 @@ The manifest key is the configured Atomic app name (`atomic` here, from the runn
276
276
  ```
277
277
  Atomic starts
278
278
 
279
+ ├─► project_trust (user/global and CLI extensions only, before project resources load)
279
280
  ├─► session_start { reason: "startup" }
280
281
  └─► resources_discover { reason: "startup" }
281
282
 
@@ -322,11 +323,9 @@ user sends another prompt ◄─────────────────
322
323
  └─► resources_discover { reason: "startup" }
323
324
 
324
325
  /compact or auto-compaction
325
- └─► compaction_start / compaction_end (deletion-only context compaction)
326
-
327
- legacy summary compaction APIs
328
- ├─► session_before_compact (can cancel or customize)
329
- └─► session_compact
326
+ ├─► compaction_start / compaction_end (deletion-only context compaction status)
327
+ ├─► session_before_compact (can cancel or provide a deletion request)
328
+ └─► session_compact (after the context_compaction entry is persisted)
330
329
 
331
330
  /tree navigation
332
331
  ├─► session_before_tree (can cancel or customize)
@@ -343,6 +342,25 @@ exit (CTRL+C, CTRL+D, SIGHUP, SIGTERM)
343
342
  └─► session_shutdown
344
343
  ```
345
344
 
345
+ ### Startup Events
346
+
347
+ #### project_trust
348
+
349
+ Fired before Atomic decides whether to trust a project with dynamic configs (`.atomic`, legacy `.pi`, or `.agents/skills`). It runs during startup and when session replacement (for example `/resume`) enters a cwd whose trust has not been resolved in the current process. Only user/global extensions and CLI `-e` extensions participate; project-local extensions are not loaded until after trust is resolved.
350
+
351
+ ```typescript
352
+ pi.on("project_trust", async (event, ctx) => {
353
+ // event.cwd - current working directory
354
+ // ctx has a limited trust context: cwd, mode, hasUI, and select/confirm/input/notify UI helpers
355
+ if (ctx.hasUI && await ctx.ui.confirm("Trust project?", event.cwd)) {
356
+ return { trusted: "yes", remember: true };
357
+ }
358
+ return { trusted: "undecided" };
359
+ });
360
+ ```
361
+
362
+ A `project_trust` handler must return `{ trusted: "yes" | "no" | "undecided" }`. A user/global or CLI extension that returns `"yes"` or `"no"` owns the decision; the first yes/no decision wins and suppresses the built-in trust prompt. Use `remember: true` to persist a yes/no decision; otherwise it applies only to the current process. Return `"undecided"` to let later handlers or the built-in trust flow decide. Check `ctx.hasUI` before prompting. If no handler returns yes/no, normal trust resolution continues: saved `trust.json` decisions apply first, then `defaultProjectTrust` controls whether Atomic asks, trusts, or declines by default.
363
+
346
364
  ### Resource Events
347
365
 
348
366
  #### resources_discover
@@ -416,28 +434,41 @@ Do cleanup work in `session_shutdown`, then reestablish any in-memory state in `
416
434
 
417
435
  #### session_before_compact / session_compact
418
436
 
419
- Fired by the legacy summary compaction pipeline. `/compact` and auto-compaction now use deletion-only context compaction by default, so extensions should not rely on these events for default compaction. See [Compaction](/compaction) for details.
437
+ Fired by `/compact` and auto-compaction. Compaction is deletion-only: extensions can cancel the run or return exact entry/content-block deletion targets for Atomic to validate locally. Extensions cannot return generated summaries.
420
438
 
421
439
  ```typescript
422
440
  pi.on("session_before_compact", async (event, ctx) => {
423
- const { preparation, branchEntries, customInstructions, signal } = event;
441
+ const { preparation, branchEntries, reason, mode, signal } = event;
442
+ const { transcript } = preparation;
443
+
444
+ // transcript.entries - compactable entries on the active branch
445
+ // transcript.protectedEntryIds - entries protected from standard compaction
446
+ // transcript.tokensBefore - token estimate before compaction
447
+ // branchEntries - raw session entries on the current branch
448
+ // reason - "manual" | "threshold" | "overflow"
449
+ // mode - "standard" | "critical_overflow"
424
450
 
425
- // Cancel:
451
+ if (signal.aborted) return { cancel: true };
452
+
453
+ // Cancel compaction:
426
454
  return { cancel: true };
427
455
 
428
- // Custom summary:
456
+ // Or provide a deletion request. Atomic validates IDs, protected targets,
457
+ // tool-call/tool-result pairing, and non-empty remaining context before saving.
429
458
  return {
430
- compaction: {
431
- summary: "...",
432
- firstKeptEntryId: preparation.firstKeptEntryId,
433
- tokensBefore: preparation.tokensBefore,
434
- }
459
+ deletionRequest: {
460
+ deletions: [
461
+ { kind: "entry", entryId: "abc123", rationale: "Old successful command output" },
462
+ { kind: "content_block", entryId: "def456", blockIndex: 2, rationale: "Verbose obsolete log" },
463
+ ],
464
+ },
435
465
  };
436
466
  });
437
467
 
438
468
  pi.on("session_compact", async (event, ctx) => {
439
- // event.compactionEntry - the saved compaction
440
- // event.fromExtension - whether extension provided it
469
+ // event.result - ContextCompactionResult with deletedTargets/protectedEntryIds/stats
470
+ // event.contextCompactionEntry - the saved context_compaction entry
471
+ // event.fromExtension - true if session_before_compact provided deletionRequest
441
472
  });
442
473
  ```
443
474
 
@@ -856,7 +887,7 @@ pi.on("input", async (event, ctx) => {
856
887
  - `transform` - modify text/images, then continue to expansion
857
888
  - `handled` - skip agent entirely (first handler to return this wins)
858
889
 
859
- Transforms chain across handlers. See [input-transform.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/examples/extensions/input-transform.ts).
890
+ Transforms chain across handlers. See [input-transform.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/examples/extensions/input-transform.ts) and [input-transform-streaming.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/examples/extensions/input-transform-streaming.ts) for `streamingBehavior`-aware routing.
860
891
 
861
892
  ## ExtensionContext
862
893
 
@@ -919,6 +950,19 @@ pi.on("tool_result", async (event, ctx) => {
919
950
 
920
951
  Control flow helpers.
921
952
 
953
+ ### ctx.isProjectTrusted()
954
+
955
+ Returns whether project-local trust is active for the current extension context. Use this before reading project-local config, loading project-local resources, or exposing actions that should only run after the user has trusted the cwd.
956
+
957
+ ```typescript
958
+ pi.registerCommand("project-status", {
959
+ description: "Show trust state",
960
+ handler: async (_args, ctx) => {
961
+ ctx.ui.notify(ctx.isProjectTrusted() ? "Project is trusted" : "Project is not trusted", "info");
962
+ },
963
+ });
964
+ ```
965
+
922
966
  ### ctx.shutdown()
923
967
 
924
968
  Request a graceful shutdown of Atomic.
@@ -963,7 +1007,7 @@ ctx.compact({
963
1007
  });
964
1008
  ```
965
1009
 
966
- `customInstructions` is deprecated. Passing a non-empty value to default compaction fails because Verbatim Compaction does not accept custom summary instructions.
1010
+ Verbatim Compaction uses a fixed internal prompt; no custom summary text can be injected.
967
1011
 
968
1012
  ### ctx.getSystemPrompt()
969
1013
 
@@ -1564,7 +1608,7 @@ If you need to discover models from a remote endpoint, prefer an async extension
1564
1608
  pi.registerProvider("my-proxy", {
1565
1609
  name: "My Proxy",
1566
1610
  baseUrl: "https://proxy.example.com",
1567
- apiKey: "PROXY_API_KEY", // env var name or literal
1611
+ apiKey: "$PROXY_API_KEY", // env var reference; omit $ for a literal
1568
1612
  api: "anthropic-messages",
1569
1613
  models: [
1570
1614
  {
@@ -1611,7 +1655,7 @@ pi.registerProvider("corporate-ai", {
1611
1655
  **Config options:**
1612
1656
  - `name` - Display name for the provider in UI such as `/login`.
1613
1657
  - `baseUrl` - API endpoint URL. Required when defining models.
1614
- - `apiKey` - API key or environment variable name. Required when defining models (unless `oauth` provided).
1658
+ - `apiKey` - API key literal or explicit environment variable reference (`$ENV_VAR` or `${ENV_VAR}`). Required when defining models (unless `oauth` provided).
1615
1659
  - `api` - API type: `"anthropic-messages"`, `"openai-completions"`, `"openai-responses"`, etc.
1616
1660
  - `headers` - Custom headers to include in requests.
1617
1661
  - `authHeader` - If true, adds `Authorization: Bearer` header automatically.
@@ -2565,6 +2609,8 @@ All examples in [examples/extensions/](https://github.com/bastani-inc/atomic/tre
2565
2609
  | `confirm-destructive.ts` | Confirm session changes | `on("session_before_switch")`, `on("session_before_fork")` |
2566
2610
  | `dirty-repo-guard.ts` | Warn on dirty git repo | `on("session_before_*")`, `exec` |
2567
2611
  | `input-transform.ts` | Transform user input | `on("input")` |
2612
+ | `input-transform-streaming.ts` | Streaming-aware input transform | `on("input")`, `streamingBehavior` |
2613
+ | `project-trust.ts` | Decide or defer project trust from a user/global or CLI extension | `on("project_trust")`, trust UI, required trust result |
2568
2614
  | `model-status.ts` | React to model changes | `on("model_select")`, `setStatus` |
2569
2615
  | `provider-payload.ts` | Inspect payloads and provider response headers | `on("before_provider_request")`, `on("after_provider_response")` |
2570
2616
  | `system-prompt-header.ts` | Display system prompt info | `on("agent_start")`, `getSystemPrompt` |
@@ -2572,7 +2618,7 @@ All examples in [examples/extensions/](https://github.com/bastani-inc/atomic/tre
2572
2618
  | `prompt-customizer.ts` | Add context-aware tool guidance using `systemPromptOptions` | `on("before_agent_start")`, `BuildSystemPromptOptions` |
2573
2619
  | `file-trigger.ts` | File watcher triggers messages | `sendMessage` |
2574
2620
  | **Compaction & Sessions** |||
2575
- | `custom-compaction.ts` | Legacy custom compaction summary | `on("session_before_compact")` |
2621
+ | `custom-compaction.ts` | Custom deletion-request compaction policy | `on("session_before_compact")` |
2576
2622
  | `trigger-compact.ts` | Trigger compaction manually | `compact()` |
2577
2623
  | `git-checkpoint.ts` | Git stash on turns | `on("turn_start")`, `on("session_before_fork")`, `exec` |
2578
2624
  | `auto-commit-on-exit.ts` | Commit on shutdown | `on("session_shutdown")`, `exec` |
@@ -2598,6 +2644,7 @@ All examples in [examples/extensions/](https://github.com/bastani-inc/atomic/tre
2598
2644
  | `ssh.ts` | SSH remote execution | `registerFlag`, `on("user_bash")`, `on("before_agent_start")`, tool operations |
2599
2645
  | `interactive-shell.ts` | Persistent shell session | `on("user_bash")` |
2600
2646
  | `sandbox/` | Sandboxed tool execution | Tool operations |
2647
+ | `gondolin/` | Route built-in tools and `!` commands into a Gondolin micro-VM | Tool operations, built-in tool overrides, `on("user_bash")` |
2601
2648
  | `subagent/` | Spawn sub-agents | `registerTool`, `exec` |
2602
2649
  | **Games** |||
2603
2650
  | `snake.ts` | Snake game | `registerCommand`, `ui.custom`, keyboard handling |
package/docs/index.md CHANGED
@@ -48,6 +48,8 @@ For the full first-run flow, see [Quickstart](/quickstart).
48
48
  - [Quickstart](/quickstart) - install, authenticate, and run a first session.
49
49
  - [Using Atomic](/usage) - interactive mode, slash commands, context files, and CLI reference.
50
50
  - [Providers](/providers) - subscription and API-key setup for built-in providers.
51
+ - [Security](/security) - project trust, sandbox boundaries, and vulnerability reporting.
52
+ - [Containerization](/containerization) - sandbox Atomic with OpenShell, Gondolin, or Docker.
51
53
  - [Settings](/settings) - global and project settings.
52
54
  - [Keybindings](/keybindings) - default shortcuts and custom keybindings.
53
55
  - [Sessions](/sessions) - session management, branching, and tree navigation.
package/docs/json.md CHANGED
@@ -53,10 +53,9 @@ Base messages come from `@earendil-works/pi-ai` (installed as an Atomic dependen
53
53
  - `ToolResultMessage`
54
54
 
55
55
  Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/messages.ts#L29):
56
- - `BashExecutionMessage` (line 29)
57
- - `CustomMessage` (line 46)
58
- - `BranchSummaryMessage` (line 55)
59
- - `CompactionSummaryMessage` (line 62)
56
+ - `BashExecutionMessage`
57
+ - `CustomMessage`
58
+ - `BranchSummaryMessage`
60
59
 
61
60
  ## Output Format
62
61
 
package/docs/models.md CHANGED
@@ -101,7 +101,7 @@ Use `google-generative-ai` with a `baseUrl` to add models from Google AI Studio,
101
101
  "my-google": {
102
102
  "baseUrl": "https://generativelanguage.googleapis.com/v1beta",
103
103
  "api": "google-generative-ai",
104
- "apiKey": "GEMINI_API_KEY",
104
+ "apiKey": "$GEMINI_API_KEY",
105
105
  "models": [
106
106
  {
107
107
  "id": "gemma-4-31b-it",
@@ -150,11 +150,11 @@ The `apiKey` and `headers` fields support three formats:
150
150
  "apiKey": "!security find-generic-password -ws 'anthropic'"
151
151
  "apiKey": "!op read 'op://vault/item/credential'"
152
152
  ```
153
- - **Environment variable:** Uses the value of the named variable
153
+ - **Environment variable:** Prefix the variable name with `$` (or use `${VAR}`) to resolve it from the environment
154
154
  ```json
155
- "apiKey": "MY_API_KEY"
155
+ "apiKey": "$MY_API_KEY"
156
156
  ```
157
- - **Literal value:** Used directly
157
+ - **Literal value:** Used directly; bare strings are not environment variable references
158
158
  ```json
159
159
  "apiKey": "sk-..."
160
160
  ```
@@ -172,10 +172,10 @@ If your command is slow, expensive, rate-limited, or should keep using a previou
172
172
  "providers": {
173
173
  "custom-proxy": {
174
174
  "baseUrl": "https://proxy.example.com/v1",
175
- "apiKey": "MY_API_KEY",
175
+ "apiKey": "$MY_API_KEY",
176
176
  "api": "anthropic-messages",
177
177
  "headers": {
178
- "x-portkey-api-key": "PORTKEY_API_KEY",
178
+ "x-portkey-api-key": "$PORTKEY_API_KEY",
179
179
  "x-secret": "!op read 'op://vault/item/secret'"
180
180
  },
181
181
  "models": [...]
@@ -268,7 +268,7 @@ To merge custom models into a built-in provider, include the `models` array:
268
268
  "providers": {
269
269
  "anthropic": {
270
270
  "baseUrl": "https://my-proxy.example.com/v1",
271
- "apiKey": "ANTHROPIC_API_KEY",
271
+ "apiKey": "$ANTHROPIC_API_KEY",
272
272
  "api": "anthropic-messages",
273
273
  "models": [...]
274
274
  }
@@ -325,7 +325,7 @@ By default, Atomic sends per-tool `eager_input_streaming: true`. If a proxy or A
325
325
  "anthropic-proxy": {
326
326
  "baseUrl": "https://proxy.example.com",
327
327
  "api": "anthropic-messages",
328
- "apiKey": "ANTHROPIC_PROXY_KEY",
328
+ "apiKey": "$ANTHROPIC_PROXY_KEY",
329
329
  "compat": {
330
330
  "supportsEagerToolInputStreaming": false,
331
331
  "supportsLongCacheRetention": true
@@ -399,7 +399,7 @@ Example:
399
399
  "providers": {
400
400
  "openrouter": {
401
401
  "baseUrl": "https://openrouter.ai/api/v1",
402
- "apiKey": "OPENROUTER_API_KEY",
402
+ "apiKey": "$OPENROUTER_API_KEY",
403
403
  "api": "openai-completions",
404
404
  "models": [
405
405
  {
@@ -449,7 +449,7 @@ Vercel AI Gateway example:
449
449
  "providers": {
450
450
  "vercel-ai-gateway": {
451
451
  "baseUrl": "https://ai-gateway.vercel.sh/v1",
452
- "apiKey": "AI_GATEWAY_API_KEY",
452
+ "apiKey": "$AI_GATEWAY_API_KEY",
453
453
  "api": "openai-completions",
454
454
  "models": [
455
455
  {
package/docs/packages.md CHANGED
@@ -43,7 +43,7 @@ atomic update npm:@foo/bar # update one package
43
43
  atomic update --extension npm:@foo/bar
44
44
  ```
45
45
 
46
- By default, `install` and `remove` write to global settings (`~/.atomic/agent/settings.json`). Use `-l` to write to project settings (`.atomic/settings.json`) instead. Project settings can be shared with your team, and Atomic installs any missing packages automatically on startup.
46
+ By default, `install` and `remove` write to global settings (`~/.atomic/agent/settings.json`). Use `-l` to write to project settings (`.atomic/settings.json`) instead. Project settings can be shared with your team, and Atomic installs any missing packages automatically on startup after the project is trusted.
47
47
 
48
48
  To try a package without installing it, use `--extension` or `-e`. This installs to a temporary directory for the current run only:
49
49
 
@@ -9,7 +9,7 @@ Prompt templates are Markdown snippets that expand into full prompts. Type `/nam
9
9
  Atomic loads prompt templates from:
10
10
 
11
11
  - Global: `~/.atomic/agent/prompts/*.md` (legacy `~/.pi/agent/prompts/*.md`)
12
- - Project: `.atomic/prompts/*.md` (legacy `.pi/prompts/*.md`)
12
+ - Project: `.atomic/prompts/*.md` (legacy `.pi/prompts/*.md`, only after the project is trusted)
13
13
  - Packages: `prompts/` directories, `atomic.prompts`, or legacy `pi.prompts` entries in `package.json`
14
14
  - Settings: `prompts` array with files or directories
15
15
  - CLI: `--prompt-template <path>` (repeatable)
@@ -64,10 +64,11 @@ Type `/` followed by the template name in the editor. Autocomplete shows availab
64
64
 
65
65
  ## Arguments
66
66
 
67
- Templates support positional arguments and simple slicing:
67
+ Templates support positional arguments, defaults, and simple slicing:
68
68
 
69
69
  - `$1`, `$2`, ... positional args
70
70
  - `$@` or `$ARGUMENTS` for all args joined
71
+ - `${1:-default}` uses arg 1 when present/non-empty, otherwise `default`
71
72
  - `${@:N}` for args from the Nth position (1-indexed)
72
73
  - `${@:N:L}` for `L` args starting at N
73
74
 
@@ -80,6 +81,12 @@ description: Create a component
80
81
  Create a React component named $1 with features: $@
81
82
  ```
82
83
 
84
+ Default values are useful for optional arguments:
85
+
86
+ ```markdown
87
+ Summarize the current state in ${1:-7} bullet points.
88
+ ```
89
+
83
90
  Usage: `/component Button "onClick handler" "disabled support"`
84
91
 
85
92
  ## Loading Rules
package/docs/providers.md CHANGED
@@ -53,9 +53,11 @@ atomic
53
53
  | Provider | Environment Variable | `auth.json` key |
54
54
  |----------|----------------------|------------------|
55
55
  | Anthropic | `ANTHROPIC_API_KEY` | `anthropic` |
56
+ | Ant Ling | `ANT_LING_API_KEY` | `ant-ling` |
56
57
  | Azure OpenAI Responses | `AZURE_OPENAI_API_KEY` | `azure-openai-responses` |
57
58
  | OpenAI | `OPENAI_API_KEY` | `openai` |
58
59
  | DeepSeek | `DEEPSEEK_API_KEY` | `deepseek` |
60
+ | NVIDIA NIM | `NVIDIA_API_KEY` | `nvidia` |
59
61
  | Google Gemini | `GEMINI_API_KEY` | `google` |
60
62
  | Google Vertex AI | `GOOGLE_CLOUD_API_KEY` | `google-vertex` |
61
63
  | Mistral | `MISTRAL_API_KEY` | `mistral` |
@@ -67,6 +69,7 @@ atomic
67
69
  | OpenRouter | `OPENROUTER_API_KEY` | `openrouter` |
68
70
  | Vercel AI Gateway | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway` |
69
71
  | ZAI | `ZAI_API_KEY` | `zai` |
72
+ | ZAI Coding Plan (China) | `ZAI_CODING_CN_API_KEY` | `zai-coding-cn` |
70
73
  | OpenCode Zen | `OPENCODE_API_KEY` | `opencode` |
71
74
  | OpenCode Go | `OPENCODE_API_KEY` | `opencode-go` |
72
75
  | Hugging Face | `HF_TOKEN` | `huggingface` |
@@ -91,8 +94,10 @@ Store credentials in `~/.atomic/agent/auth.json`:
91
94
  ```json
92
95
  {
93
96
  "anthropic": { "type": "api_key", "key": "sk-ant-..." },
97
+ "ant-ling": { "type": "api_key", "key": "..." },
94
98
  "openai": { "type": "api_key", "key": "sk-..." },
95
99
  "deepseek": { "type": "api_key", "key": "sk-..." },
100
+ "nvidia": { "type": "api_key", "key": "nvapi-..." },
96
101
  "google": { "type": "api_key", "key": "..." },
97
102
  "opencode": { "type": "api_key", "key": "..." },
98
103
  "opencode-go": { "type": "api_key", "key": "..." },
@@ -108,23 +113,31 @@ The file is created with `0600` permissions (user read/write only). Auth file cr
108
113
 
109
114
  ### Key Resolution
110
115
 
111
- The `key` field supports three formats:
116
+ The `key` field supports command execution, environment interpolation, and literals:
112
117
 
113
- - **Shell command:** `"!command"` executes and uses stdout (cached for process lifetime)
118
+ - **Shell command:** `"!command"` at the start executes the whole value as a command and uses stdout (cached for process lifetime)
114
119
  ```json
115
120
  { "type": "api_key", "key": "!security find-generic-password -ws 'anthropic'" }
116
121
  { "type": "api_key", "key": "!op read 'op://vault/item/credential'" }
117
122
  ```
118
- - **Environment variable:** Uses the value of the named variable
123
+ - **Environment interpolation:** `"$ENV_VAR"` or `"${ENV_VAR}"` uses the value of the named variable. Interpolation works inside larger literals.
119
124
  ```json
120
- { "type": "api_key", "key": "MY_ANTHROPIC_KEY" }
125
+ { "type": "api_key", "key": "$MY_ANTHROPIC_KEY" }
126
+ { "type": "api_key", "key": "${KEY_PREFIX}_${KEY_SUFFIX}" }
127
+ ```
128
+ `$FOO_BAR` is the variable `FOO_BAR`; use `${FOO}_BAR` when `BAR` is literal text. Missing environment variables make the value unresolved.
129
+ - **Escapes:** `"$$"` emits a literal `"$"`; `"$!"` emits a literal `"!"` without triggering command execution.
130
+ ```json
131
+ { "type": "api_key", "key": "$$literal-dollar-prefix" }
132
+ { "type": "api_key", "key": "$!literal-bang-prefix" }
121
133
  ```
122
134
  - **Literal value:** Used directly
123
135
  ```json
124
136
  { "type": "api_key", "key": "sk-ant-..." }
137
+ { "type": "api_key", "key": "public" }
125
138
  ```
126
139
 
127
- OAuth credentials are also stored here after `/login` and managed automatically.
140
+ Legacy uppercase env-var-like values such as `MY_API_KEY` are migrated to `$MY_API_KEY` on startup only when that environment variable is present during migration; otherwise the value is preserved as a literal. OAuth credentials are also stored here after `/login` and managed automatically.
128
141
 
129
142
  ## Cloud Providers
130
143
 
@@ -227,6 +227,7 @@ Sessions are saved automatically:
227
227
  ```bash
228
228
  atomic -c # Continue most recent session
229
229
  atomic -r # Browse previous sessions
230
+ atomic --name "my task" # Set session display name at startup
230
231
  atomic --session <path|id> # Open a specific session
231
232
  ```
232
233
 
package/docs/rpc.md CHANGED
@@ -13,6 +13,7 @@ atomic --mode rpc [options]
13
13
  Common options:
14
14
  - `--provider <name>`: Set the LLM provider (anthropic, openai, google, etc.)
15
15
  - `--model <pattern>`: Model pattern or ID (supports `provider/id` and optional `:<thinking>`)
16
+ - `--name <name>` / `-n <name>`: Set the session display name at startup
16
17
  - `--no-session`: Disable session persistence
17
18
  - `--session-dir <path>`: Custom session storage directory
18
19
 
@@ -697,7 +698,7 @@ Response:
697
698
  }
698
699
  ```
699
700
 
700
- The current session name is available via `get_state` in the `sessionName` field.
701
+ The current session name is available via `get_state` in the `sessionName` field. To set the initial name when starting RPC mode, pass `--name <name>` or `-n <name>` to the `atomic --mode rpc` process.
701
702
 
702
703
  ### Commands
703
704
 
@@ -1018,7 +1019,7 @@ Some `ExtensionUIContext` methods are not supported or degraded in RPC mode beca
1018
1019
  - `getTheme()` returns `undefined`
1019
1020
  - `setTheme()` returns `{ success: false, error: "..." }`
1020
1021
 
1021
- Note: `ctx.hasUI` is `true` in RPC mode because the dialog and fire-and-forget methods are functional via the extension UI sub-protocol.
1022
+ Note: `ctx.mode` is `"rpc"` and `ctx.hasUI` is `true` in RPC mode because the dialog and fire-and-forget methods are functional via the extension UI sub-protocol. Use `ctx.mode === "tui"` to guard TUI-specific features like `custom()` that require a real terminal.
1022
1023
 
1023
1024
  ### Extension UI Requests (stdout)
1024
1025
 
package/docs/sdk.md CHANGED
@@ -1142,6 +1142,11 @@ createEventBus
1142
1142
 
1143
1143
  // Helpers
1144
1144
  defineTool
1145
+ getAgentDir
1146
+ getPackageDir
1147
+ getReadmePath
1148
+ getDocsPath
1149
+ getExamplesPath
1145
1150
 
1146
1151
  // Session management
1147
1152
  SessionManager
@@ -0,0 +1,56 @@
1
+ # Security
2
+
3
+ Atomic is a local coding agent. It runs with the permissions of the user account that starts it, and it treats files writable by that user as inside the same local trust boundary.
4
+
5
+ ## Project Trust
6
+
7
+ Project trust controls whether Atomic loads project-local settings, resources, packages, and extensions. It is not a sandbox and it does not restrict what the model can ask tools to do after you start working in a directory.
8
+
9
+ Atomic considers a project to have trust inputs when it finds any of these from the current working directory:
10
+
11
+ - `.atomic/` (or legacy `.pi/`) in the current directory
12
+ - `AGENTS.md` or `CLAUDE.md` in the current directory or an ancestor directory
13
+ - `.agents/skills` in the current directory or an ancestor directory
14
+
15
+ When an interactive session starts in a project with configs in `.atomic`/`.pi`, project-local context files, or `.agents/skills` and no saved decision for the current directory or a parent directory, Atomic follows `defaultProjectTrust` from global settings. The default value is `"ask"`, which asks whether to trust the project when UI is available. Saved decisions are stored by canonical directory in `~/.atomic/agent/trust.json`, and the closest saved decision on the current or parent path applies before the global default.
16
+
17
+ Trusting a project allows Atomic to load trust-gated project inputs, including:
18
+
19
+ - `.atomic/settings.json` (or legacy `.pi/settings.json`)
20
+ - `.atomic`/`.pi` resources such as extensions, skills, prompt templates, themes, and system prompt files
21
+ - missing project packages configured through project settings
22
+ - project-local extensions and project package-managed extensions
23
+
24
+ Declining trust skips protected resources. Atomic also skips project-local `AGENTS.md` and `CLAUDE.md` context-file discovery while the project is untrusted; global context and explicitly supplied CLI resources remain available. Before trust is resolved, Atomic only loads user/global extensions and explicit CLI `-e` extensions so those trusted extensions can handle the `project_trust` event; the first extension that returns a yes/no decision owns the decision.
25
+
26
+ Non-interactive modes (`-p`, `--mode json`, and `--mode rpc`) do not show a trust prompt. Without an applicable saved trust decision, `defaultProjectTrust: "ask"` and `"never"` ignore such resources, while `"always"` trusts them. Use `--approve`/`-a` or `--no-approve`/`-na` to override project trust for one run.
27
+
28
+ ## No Built-in Sandbox
29
+
30
+ Atomic does not include a built-in sandbox. Built-in tools can read files, write files, edit files, and run shell commands with the permissions of the Atomic process. Extensions are TypeScript modules that run with the same permissions. Package installs, shell commands, language servers, test commands, and other developer tools behave as ordinary local processes.
31
+
32
+ This is intentional. Atomic is designed to operate on local source trees, invoke project toolchains, and integrate with the user's existing development environment. A partial in-process sandbox would be easy to misunderstand as a security boundary while still depending on the host shell, filesystem, package managers, credentials, and extension code. Real isolation needs to come from the operating system or a virtualization/container boundary.
33
+
34
+ Project trust is only an input-loading guard. It prevents a repository from silently changing Atomic's settings or extensions before you approve it. It does not make untrusted code, untrusted prompts, or untrusted model output safe. Prompt injection from repository files, comments, documentation, context files, or build output is expected local-agent risk and cannot be reliably prevented by Atomic.
35
+
36
+ ## Running Untrusted or Unmonitored Work
37
+
38
+ For untrusted repositories, generated code you do not intend to monitor closely, or unattended automation, run Atomic in a contained environment. Use a container, VM, micro-VM, remote sandbox, or policy-controlled sandbox with only the files and credentials required for the task.
39
+
40
+ Common patterns are documented in [Containerization](/containerization):
41
+
42
+ - run the whole `atomic` process inside OpenShell or Docker
43
+ - run host Atomic while routing built-in tool execution into a Gondolin micro-VM
44
+ - mount only the workspace paths the agent should access
45
+ - avoid mounting host `~/.atomic/agent` unless the container should access host sessions, settings, and credentials
46
+ - pass the minimum required API keys or use short-lived credentials
47
+ - restrict network access when the task does not need it
48
+ - review diffs and outputs before copying results back to trusted systems
49
+
50
+ If you bind-mount a host workspace read/write, writes from inside the container or VM can still modify host files. Use read-only mounts or copy files into and out of the sandbox when you need stronger protection from unintended writes.
51
+
52
+ ## Reporting Security Issues
53
+
54
+ To report a security issue, follow the repository [Security Policy](https://github.com/bastani-inc/atomic/blob/main/SECURITY.md). Do not open a public issue for security-sensitive reports.
55
+
56
+ Expected local-agent behavior, lack of a built-in sandbox, prompt injection from untrusted content, and behavior of user-installed extensions or skills are generally outside the security boundary unless the report demonstrates a real privilege-boundary bypass or shows how Atomic grants access that the local user did not already have.