@bastani/atomic 0.8.28-alpha.1 → 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 (349) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +120 -118
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +1 -1
  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 +8 -0
  8. package/dist/builtin/workflows/builtin/open-claude-design.ts +150 -13
  9. package/dist/builtin/workflows/package.json +1 -1
  10. package/dist/builtin/workflows/src/tui/chat-surface.ts +32 -33
  11. package/dist/builtin/workflows/src/tui/run-detail.ts +11 -4
  12. package/dist/builtin/workflows/src/tui/status-list.ts +32 -2
  13. package/dist/cli/args.d.ts +4 -0
  14. package/dist/cli/args.d.ts.map +1 -1
  15. package/dist/cli/args.js +35 -0
  16. package/dist/cli/args.js.map +1 -1
  17. package/dist/cli/project-trust.d.ts +10 -0
  18. package/dist/cli/project-trust.d.ts.map +1 -0
  19. package/dist/cli/project-trust.js +36 -0
  20. package/dist/cli/project-trust.js.map +1 -0
  21. package/dist/cli/startup-ui.d.ts +7 -0
  22. package/dist/cli/startup-ui.d.ts.map +1 -0
  23. package/dist/cli/startup-ui.js +57 -0
  24. package/dist/cli/startup-ui.js.map +1 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +24 -3
  27. package/dist/config.js.map +1 -1
  28. package/dist/core/agent-session-runtime.d.ts +3 -1
  29. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  30. package/dist/core/agent-session-runtime.js +1 -0
  31. package/dist/core/agent-session-runtime.js.map +1 -1
  32. package/dist/core/agent-session-services.d.ts +2 -1
  33. package/dist/core/agent-session-services.d.ts.map +1 -1
  34. package/dist/core/agent-session-services.js +2 -2
  35. package/dist/core/agent-session-services.js.map +1 -1
  36. package/dist/core/agent-session.d.ts +5 -1
  37. package/dist/core/agent-session.d.ts.map +1 -1
  38. package/dist/core/agent-session.js +58 -20
  39. package/dist/core/agent-session.js.map +1 -1
  40. package/dist/core/auth-storage.d.ts.map +1 -1
  41. package/dist/core/auth-storage.js +4 -3
  42. package/dist/core/auth-storage.js.map +1 -1
  43. package/dist/core/compaction/branch-summarization.d.ts +3 -1
  44. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  45. package/dist/core/compaction/branch-summarization.js +9 -3
  46. package/dist/core/compaction/branch-summarization.js.map +1 -1
  47. package/dist/core/compaction/compaction.d.ts.map +1 -1
  48. package/dist/core/compaction/compaction.js +18 -24
  49. package/dist/core/compaction/compaction.js.map +1 -1
  50. package/dist/core/compaction/utils.d.ts +1 -1
  51. package/dist/core/compaction/utils.d.ts.map +1 -1
  52. package/dist/core/compaction/utils.js +1 -1
  53. package/dist/core/compaction/utils.js.map +1 -1
  54. package/dist/core/experimental.d.ts +2 -0
  55. package/dist/core/experimental.d.ts.map +1 -0
  56. package/dist/core/experimental.js +5 -0
  57. package/dist/core/experimental.js.map +1 -0
  58. package/dist/core/export-html/template.js +19 -6
  59. package/dist/core/extensions/index.d.ts +1 -1
  60. package/dist/core/extensions/index.d.ts.map +1 -1
  61. package/dist/core/extensions/index.js.map +1 -1
  62. package/dist/core/extensions/loader.d.ts +1 -1
  63. package/dist/core/extensions/loader.d.ts.map +1 -1
  64. package/dist/core/extensions/loader.js +6 -4
  65. package/dist/core/extensions/loader.js.map +1 -1
  66. package/dist/core/extensions/runner.d.ts +11 -4
  67. package/dist/core/extensions/runner.d.ts.map +1 -1
  68. package/dist/core/extensions/runner.js +53 -3
  69. package/dist/core/extensions/runner.js.map +1 -1
  70. package/dist/core/extensions/types.d.ts +34 -4
  71. package/dist/core/extensions/types.d.ts.map +1 -1
  72. package/dist/core/extensions/types.js.map +1 -1
  73. package/dist/core/footer-data-provider.d.ts +2 -0
  74. package/dist/core/footer-data-provider.d.ts.map +1 -1
  75. package/dist/core/footer-data-provider.js +27 -1
  76. package/dist/core/footer-data-provider.js.map +1 -1
  77. package/dist/core/index.d.ts +1 -0
  78. package/dist/core/index.d.ts.map +1 -1
  79. package/dist/core/index.js +1 -0
  80. package/dist/core/index.js.map +1 -1
  81. package/dist/core/model-registry.d.ts.map +1 -1
  82. package/dist/core/model-registry.js +64 -7
  83. package/dist/core/model-registry.js.map +1 -1
  84. package/dist/core/model-resolver.d.ts.map +1 -1
  85. package/dist/core/model-resolver.js +1 -0
  86. package/dist/core/model-resolver.js.map +1 -1
  87. package/dist/core/output-guard.d.ts +1 -0
  88. package/dist/core/output-guard.d.ts.map +1 -1
  89. package/dist/core/output-guard.js +52 -22
  90. package/dist/core/output-guard.js.map +1 -1
  91. package/dist/core/package-manager.d.ts +1 -0
  92. package/dist/core/package-manager.d.ts.map +1 -1
  93. package/dist/core/package-manager.js +20 -8
  94. package/dist/core/package-manager.js.map +1 -1
  95. package/dist/core/project-trust.d.ts +15 -0
  96. package/dist/core/project-trust.d.ts.map +1 -0
  97. package/dist/core/project-trust.js +58 -0
  98. package/dist/core/project-trust.js.map +1 -0
  99. package/dist/core/prompt-templates.d.ts +5 -4
  100. package/dist/core/prompt-templates.d.ts.map +1 -1
  101. package/dist/core/prompt-templates.js +30 -29
  102. package/dist/core/prompt-templates.js.map +1 -1
  103. package/dist/core/provider-attribution.d.ts +4 -0
  104. package/dist/core/provider-attribution.d.ts.map +1 -0
  105. package/dist/core/provider-attribution.js +73 -0
  106. package/dist/core/provider-attribution.js.map +1 -0
  107. package/dist/core/provider-display-names.d.ts.map +1 -1
  108. package/dist/core/provider-display-names.js +3 -0
  109. package/dist/core/provider-display-names.js.map +1 -1
  110. package/dist/core/resolve-config-value.d.ts +9 -1
  111. package/dist/core/resolve-config-value.d.ts.map +1 -1
  112. package/dist/core/resolve-config-value.js +134 -11
  113. package/dist/core/resolve-config-value.js.map +1 -1
  114. package/dist/core/resource-loader.d.ts +12 -2
  115. package/dist/core/resource-loader.d.ts.map +1 -1
  116. package/dist/core/resource-loader.js +108 -18
  117. package/dist/core/resource-loader.js.map +1 -1
  118. package/dist/core/sdk.d.ts.map +1 -1
  119. package/dist/core/sdk.js +12 -42
  120. package/dist/core/sdk.js.map +1 -1
  121. package/dist/core/session-manager.d.ts +6 -7
  122. package/dist/core/session-manager.d.ts.map +1 -1
  123. package/dist/core/session-manager.js +99 -35
  124. package/dist/core/session-manager.js.map +1 -1
  125. package/dist/core/settings-manager.d.ts +15 -2
  126. package/dist/core/settings-manager.d.ts.map +1 -1
  127. package/dist/core/settings-manager.js +69 -10
  128. package/dist/core/settings-manager.js.map +1 -1
  129. package/dist/core/slash-commands.d.ts.map +1 -1
  130. package/dist/core/slash-commands.js +1 -0
  131. package/dist/core/slash-commands.js.map +1 -1
  132. package/dist/core/system-prompt.d.ts.map +1 -1
  133. package/dist/core/system-prompt.js +0 -3
  134. package/dist/core/system-prompt.js.map +1 -1
  135. package/dist/core/tools/bash.d.ts.map +1 -1
  136. package/dist/core/tools/bash.js +2 -1
  137. package/dist/core/tools/bash.js.map +1 -1
  138. package/dist/core/tools/edit.d.ts.map +1 -1
  139. package/dist/core/tools/edit.js +7 -10
  140. package/dist/core/tools/edit.js.map +1 -1
  141. package/dist/core/tools/find.d.ts.map +1 -1
  142. package/dist/core/tools/find.js +1 -1
  143. package/dist/core/tools/find.js.map +1 -1
  144. package/dist/core/tools/grep.d.ts.map +1 -1
  145. package/dist/core/tools/grep.js +1 -1
  146. package/dist/core/tools/grep.js.map +1 -1
  147. package/dist/core/tools/ls.d.ts.map +1 -1
  148. package/dist/core/tools/ls.js +1 -1
  149. package/dist/core/tools/ls.js.map +1 -1
  150. package/dist/core/tools/oversized-tool-result.d.ts +53 -0
  151. package/dist/core/tools/oversized-tool-result.d.ts.map +1 -0
  152. package/dist/core/tools/oversized-tool-result.js +206 -0
  153. package/dist/core/tools/oversized-tool-result.js.map +1 -0
  154. package/dist/core/tools/read.d.ts +12 -0
  155. package/dist/core/tools/read.d.ts.map +1 -1
  156. package/dist/core/tools/read.js +99 -34
  157. package/dist/core/tools/read.js.map +1 -1
  158. package/dist/core/tools/render-utils.d.ts +6 -0
  159. package/dist/core/tools/render-utils.d.ts.map +1 -1
  160. package/dist/core/tools/render-utils.js +17 -1
  161. package/dist/core/tools/render-utils.js.map +1 -1
  162. package/dist/core/tools/tool-definition-wrapper.d.ts +6 -0
  163. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  164. package/dist/core/tools/tool-definition-wrapper.js +2 -0
  165. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  166. package/dist/core/tools/tool-limits.d.ts +25 -0
  167. package/dist/core/tools/tool-limits.d.ts.map +1 -0
  168. package/dist/core/tools/tool-limits.js +25 -0
  169. package/dist/core/tools/tool-limits.js.map +1 -0
  170. package/dist/core/tools/write.d.ts.map +1 -1
  171. package/dist/core/tools/write.js +1 -1
  172. package/dist/core/tools/write.js.map +1 -1
  173. package/dist/core/trust-manager.d.ts +31 -0
  174. package/dist/core/trust-manager.d.ts.map +1 -0
  175. package/dist/core/trust-manager.js +196 -0
  176. package/dist/core/trust-manager.js.map +1 -0
  177. package/dist/index.d.ts +9 -4
  178. package/dist/index.d.ts.map +1 -1
  179. package/dist/index.js +5 -1
  180. package/dist/index.js.map +1 -1
  181. package/dist/main.d.ts.map +1 -1
  182. package/dist/main.js +142 -30
  183. package/dist/main.js.map +1 -1
  184. package/dist/migrations.d.ts +3 -1
  185. package/dist/migrations.d.ts.map +1 -1
  186. package/dist/migrations.js +325 -7
  187. package/dist/migrations.js.map +1 -1
  188. package/dist/modes/index.d.ts +1 -1
  189. package/dist/modes/index.d.ts.map +1 -1
  190. package/dist/modes/index.js.map +1 -1
  191. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  192. package/dist/modes/interactive/components/bash-execution.js +2 -2
  193. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  194. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  195. package/dist/modes/interactive/components/footer.js +6 -0
  196. package/dist/modes/interactive/components/footer.js.map +1 -1
  197. package/dist/modes/interactive/components/index.d.ts +1 -0
  198. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  199. package/dist/modes/interactive/components/index.js +1 -0
  200. package/dist/modes/interactive/components/index.js.map +1 -1
  201. package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  202. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  203. package/dist/modes/interactive/components/login-dialog.js +9 -16
  204. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  205. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  206. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  207. package/dist/modes/interactive/components/settings-selector.js +20 -0
  208. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  209. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  210. package/dist/modes/interactive/components/tool-execution.js +22 -0
  211. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  212. package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  213. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
  214. package/dist/modes/interactive/components/trust-selector.js +85 -0
  215. package/dist/modes/interactive/components/trust-selector.js.map +1 -0
  216. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  217. package/dist/modes/interactive/components/user-message.js +1 -1
  218. package/dist/modes/interactive/components/user-message.js.map +1 -1
  219. package/dist/modes/interactive/interactive-mode.d.ts +9 -0
  220. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  221. package/dist/modes/interactive/interactive-mode.js +130 -9
  222. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  223. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  224. package/dist/modes/interactive/theme/theme.js +10 -0
  225. package/dist/modes/interactive/theme/theme.js.map +1 -1
  226. package/dist/modes/print-mode.d.ts.map +1 -1
  227. package/dist/modes/print-mode.js +1 -0
  228. package/dist/modes/print-mode.js.map +1 -1
  229. package/dist/modes/rpc/rpc-client.d.ts +3 -0
  230. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  231. package/dist/modes/rpc/rpc-client.js +50 -6
  232. package/dist/modes/rpc/rpc-client.js.map +1 -1
  233. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  234. package/dist/modes/rpc/rpc-mode.js +23 -4
  235. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  236. package/dist/modes/rpc/rpc-types.d.ts +1 -0
  237. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  238. package/dist/modes/rpc/rpc-types.js.map +1 -1
  239. package/dist/package-manager-cli.d.ts +6 -2
  240. package/dist/package-manager-cli.d.ts.map +1 -1
  241. package/dist/package-manager-cli.js +104 -10
  242. package/dist/package-manager-cli.js.map +1 -1
  243. package/dist/utils/changelog.d.ts +1 -0
  244. package/dist/utils/changelog.d.ts.map +1 -1
  245. package/dist/utils/changelog.js +72 -0
  246. package/dist/utils/changelog.js.map +1 -1
  247. package/dist/utils/deprecation.d.ts +4 -0
  248. package/dist/utils/deprecation.d.ts.map +1 -0
  249. package/dist/utils/deprecation.js +13 -0
  250. package/dist/utils/deprecation.js.map +1 -0
  251. package/dist/utils/git.d.ts.map +1 -1
  252. package/dist/utils/git.js +54 -22
  253. package/dist/utils/git.js.map +1 -1
  254. package/dist/utils/json.d.ts +3 -0
  255. package/dist/utils/json.d.ts.map +1 -0
  256. package/dist/utils/json.js +7 -0
  257. package/dist/utils/json.js.map +1 -0
  258. package/dist/utils/open-browser.d.ts +9 -0
  259. package/dist/utils/open-browser.d.ts.map +1 -0
  260. package/dist/utils/open-browser.js +22 -0
  261. package/dist/utils/open-browser.js.map +1 -0
  262. package/docs/containerization.md +111 -0
  263. package/docs/custom-provider.md +9 -9
  264. package/docs/development.md +1 -1
  265. package/docs/docs.json +2 -0
  266. package/docs/extensions.md +40 -4
  267. package/docs/index.md +2 -0
  268. package/docs/models.md +10 -10
  269. package/docs/packages.md +1 -1
  270. package/docs/prompt-templates.md +9 -2
  271. package/docs/providers.md +18 -5
  272. package/docs/quickstart.md +1 -0
  273. package/docs/rpc.md +3 -2
  274. package/docs/sdk.md +5 -0
  275. package/docs/security.md +56 -0
  276. package/docs/session-format.md +2 -2
  277. package/docs/sessions.md +8 -0
  278. package/docs/settings.md +21 -4
  279. package/docs/skills.md +1 -1
  280. package/docs/terminal-setup.md +44 -2
  281. package/docs/themes.md +1 -1
  282. package/docs/tmux.md +4 -2
  283. package/docs/tui.md +14 -5
  284. package/docs/usage.md +17 -3
  285. package/examples/README.md +1 -1
  286. package/examples/extensions/README.md +8 -5
  287. package/examples/extensions/bash-spawn-hook.ts +1 -1
  288. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  289. package/examples/extensions/claude-rules.ts +1 -1
  290. package/examples/extensions/commands.ts +1 -1
  291. package/examples/extensions/custom-header.ts +1 -1
  292. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  293. package/examples/extensions/custom-provider-anthropic/package-lock.json +4 -4
  294. package/examples/extensions/custom-provider-anthropic/package.json +6 -6
  295. package/examples/extensions/custom-provider-gitlab-duo/index.ts +55 -4
  296. package/examples/extensions/custom-provider-gitlab-duo/package.json +3 -3
  297. package/examples/extensions/doom-overlay/README.md +1 -1
  298. package/examples/extensions/doom-overlay/index.ts +2 -2
  299. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  300. package/examples/extensions/gondolin/index.ts +523 -0
  301. package/examples/extensions/gondolin/package-lock.json +185 -0
  302. package/examples/extensions/gondolin/package.json +19 -0
  303. package/examples/extensions/handoff.ts +1 -1
  304. package/examples/extensions/hidden-thinking-label.ts +1 -1
  305. package/examples/extensions/inline-bash.ts +2 -2
  306. package/examples/extensions/input-transform-streaming.ts +39 -0
  307. package/examples/extensions/input-transform.ts +3 -3
  308. package/examples/extensions/interactive-shell.ts +2 -2
  309. package/examples/extensions/mac-system-theme.ts +2 -2
  310. package/examples/extensions/minimal-mode.ts +1 -1
  311. package/examples/extensions/modal-editor.ts +1 -1
  312. package/examples/extensions/model-status.ts +1 -1
  313. package/examples/extensions/overlay-qa-tests.ts +198 -179
  314. package/examples/extensions/overlay-test.ts +1 -1
  315. package/examples/extensions/pirate.ts +1 -1
  316. package/examples/extensions/preset.ts +14 -12
  317. package/examples/extensions/project-trust.ts +64 -0
  318. package/examples/extensions/prompt-customizer.ts +1 -1
  319. package/examples/extensions/qna.ts +1 -1
  320. package/examples/extensions/question.ts +1 -1
  321. package/examples/extensions/questionnaire.ts +1 -1
  322. package/examples/extensions/rainbow-editor.ts +1 -1
  323. package/examples/extensions/sandbox/index.ts +16 -14
  324. package/examples/extensions/sandbox/package-lock.json +90 -90
  325. package/examples/extensions/sandbox/package.json +17 -17
  326. package/examples/extensions/snake.ts +1 -1
  327. package/examples/extensions/space-invaders.ts +1 -1
  328. package/examples/extensions/ssh.ts +2 -2
  329. package/examples/extensions/subagent/README.md +13 -13
  330. package/examples/extensions/subagent/agents.ts +4 -2
  331. package/examples/extensions/subagent/index.ts +6 -6
  332. package/examples/extensions/summarize.ts +1 -1
  333. package/examples/extensions/tic-tac-toe.ts +1 -1
  334. package/examples/extensions/titlebar-spinner.ts +1 -1
  335. package/examples/extensions/todo.ts +1 -1
  336. package/examples/extensions/tool-override.ts +1 -1
  337. package/examples/extensions/tools.ts +6 -1
  338. package/examples/extensions/with-deps/package-lock.json +4 -4
  339. package/examples/extensions/with-deps/package.json +7 -7
  340. package/examples/extensions/working-indicator.ts +4 -4
  341. package/examples/extensions/working-message-test.ts +1 -1
  342. package/examples/sdk/01-minimal.ts +1 -1
  343. package/examples/sdk/03-custom-prompt.ts +1 -1
  344. package/examples/sdk/04-skills.ts +1 -1
  345. package/examples/sdk/06-extensions.ts +2 -2
  346. package/examples/sdk/08-prompt-templates.ts +1 -1
  347. package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
  348. package/examples/sdk/README.md +2 -2
  349. package/package.json +4 -4
@@ -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",
@@ -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
 
@@ -341,6 +342,25 @@ exit (CTRL+C, CTRL+D, SIGHUP, SIGTERM)
341
342
  └─► session_shutdown
342
343
  ```
343
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
+
344
364
  ### Resource Events
345
365
 
346
366
  #### resources_discover
@@ -867,7 +887,7 @@ pi.on("input", async (event, ctx) => {
867
887
  - `transform` - modify text/images, then continue to expansion
868
888
  - `handled` - skip agent entirely (first handler to return this wins)
869
889
 
870
- 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.
871
891
 
872
892
  ## ExtensionContext
873
893
 
@@ -930,6 +950,19 @@ pi.on("tool_result", async (event, ctx) => {
930
950
 
931
951
  Control flow helpers.
932
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
+
933
966
  ### ctx.shutdown()
934
967
 
935
968
  Request a graceful shutdown of Atomic.
@@ -1575,7 +1608,7 @@ If you need to discover models from a remote endpoint, prefer an async extension
1575
1608
  pi.registerProvider("my-proxy", {
1576
1609
  name: "My Proxy",
1577
1610
  baseUrl: "https://proxy.example.com",
1578
- apiKey: "PROXY_API_KEY", // env var name or literal
1611
+ apiKey: "$PROXY_API_KEY", // env var reference; omit $ for a literal
1579
1612
  api: "anthropic-messages",
1580
1613
  models: [
1581
1614
  {
@@ -1622,7 +1655,7 @@ pi.registerProvider("corporate-ai", {
1622
1655
  **Config options:**
1623
1656
  - `name` - Display name for the provider in UI such as `/login`.
1624
1657
  - `baseUrl` - API endpoint URL. Required when defining models.
1625
- - `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).
1626
1659
  - `api` - API type: `"anthropic-messages"`, `"openai-completions"`, `"openai-responses"`, etc.
1627
1660
  - `headers` - Custom headers to include in requests.
1628
1661
  - `authHeader` - If true, adds `Authorization: Bearer` header automatically.
@@ -2576,6 +2609,8 @@ All examples in [examples/extensions/](https://github.com/bastani-inc/atomic/tre
2576
2609
  | `confirm-destructive.ts` | Confirm session changes | `on("session_before_switch")`, `on("session_before_fork")` |
2577
2610
  | `dirty-repo-guard.ts` | Warn on dirty git repo | `on("session_before_*")`, `exec` |
2578
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 |
2579
2614
  | `model-status.ts` | React to model changes | `on("model_select")`, `setStatus` |
2580
2615
  | `provider-payload.ts` | Inspect payloads and provider response headers | `on("before_provider_request")`, `on("after_provider_response")` |
2581
2616
  | `system-prompt-header.ts` | Display system prompt info | `on("agent_start")`, `getSystemPrompt` |
@@ -2609,6 +2644,7 @@ All examples in [examples/extensions/](https://github.com/bastani-inc/atomic/tre
2609
2644
  | `ssh.ts` | SSH remote execution | `registerFlag`, `on("user_bash")`, `on("before_agent_start")`, tool operations |
2610
2645
  | `interactive-shell.ts` | Persistent shell session | `on("user_bash")` |
2611
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")` |
2612
2648
  | `subagent/` | Spawn sub-agents | `registerTool`, `exec` |
2613
2649
  | **Games** |||
2614
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/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.
@@ -12,7 +12,7 @@ Where `<path>` is the working directory with `/` replaced by `-`.
12
12
 
13
13
  ## Deleting Sessions
14
14
 
15
- Sessions can be removed by deleting their `.jsonl` files under `~/.atomic/agent/sessions/` (legacy `~/.pi/agent/sessions/` may exist from older installs).
15
+ Sessions can be removed by deleting their `.jsonl` files under `~/.atomic/agent/sessions/` (legacy `~/.pi/agent/sessions/` may exist from older Pi installs).
16
16
 
17
17
  Atomic also supports deleting sessions interactively from `/resume` (select a session and press `CTRL+D`, then confirm). When available, Atomic uses the `trash` CLI to avoid permanent deletion.
18
18
 
@@ -285,7 +285,7 @@ Set `label` to `undefined` to clear a label.
285
285
 
286
286
  ### SessionInfoEntry
287
287
 
288
- Session metadata (e.g., user-defined display name). Set via `/name` command or `pi.setSessionName()` in extensions.
288
+ Session metadata (e.g., user-defined display name). Set via `/name`, `--name` / `-n`, or `pi.setSessionName()` in extensions.
289
289
 
290
290
  ```json
291
291
  {"type":"session_info","id":"k1l2m3n4","parentId":"j0k1l2m3","timestamp":"2024-12-03T14:35:00.000Z","name":"Refactor auth module"}
package/docs/sessions.md CHANGED
@@ -10,6 +10,7 @@ Sessions auto-save to `~/.atomic/agent/sessions/`, organized by working director
10
10
  atomic -c # Continue most recent session
11
11
  atomic -r # Browse and select from past sessions
12
12
  atomic --no-session # Ephemeral mode; do not save
13
+ atomic --name "my task" # Set session display name at startup
13
14
  atomic --session <path|id> # Use a specific session file or partial session ID
14
15
  atomic --fork <path|id> # Fork a session file or partial session ID into a new session
15
16
  ```
@@ -56,6 +57,13 @@ Use `/name <name>` to set a human-readable session name:
56
57
  /name Refactor auth module
57
58
  ```
58
59
 
60
+ Set the name at startup with `--name` or `-n`:
61
+
62
+ ```bash
63
+ atomic --name "Refactor auth module"
64
+ atomic --name "CI audit" -p "Review this build failure"
65
+ ```
66
+
59
67
  Named sessions are easier to find in `/resume` and `atomic -r`.
60
68
 
61
69
  ## Branching with `/tree`
package/docs/settings.md CHANGED
@@ -7,7 +7,19 @@ Atomic uses JSON settings files with project settings overriding global settings
7
7
  | `~/.atomic/agent/settings.json` | Global (all projects) |
8
8
  | `.atomic/settings.json` | Project (current directory) |
9
9
 
10
- Edit directly or use `/settings` for common options. Atomic reads legacy `~/.pi/agent/settings.json` and `.pi/settings.json` as compatibility fallbacks, with `.atomic` paths taking precedence.
10
+ Edit directly or use `/settings` for common options. Atomic also reads legacy `~/.pi/agent/settings.json` and `.pi/settings.json` as compatibility fallbacks, with `.atomic` paths taking precedence.
11
+
12
+ ## Project Trust
13
+
14
+ On interactive startup, Atomic asks before trusting a project folder that contains trust-gated project inputs and has no saved decision for the folder or a parent folder in `~/.atomic/agent/trust.json`. Trusting a project allows Atomic to load project-local `.atomic/settings.json` and `.atomic` resources, legacy `.pi/settings.json` and `.pi` resources, project-local context files, install missing project packages, and execute project extensions.
15
+
16
+ Non-interactive modes (`-p`, `--mode json`, and `--mode rpc`) do not show a trust prompt. Without an applicable saved trust decision, they use `defaultProjectTrust` from global settings: `ask` (default) and `never` ignore trust-gated project inputs, while `always` trusts them. Pass `--approve`/`-a` or `--no-approve`/`-na` to override project trust for one run.
17
+
18
+ If no extension or saved decision applies, `defaultProjectTrust` controls the fallback behavior. Set it to `"ask"`, `"always"`, or `"never"` in `~/.atomic/agent/settings.json`, or change it with `/settings`.
19
+
20
+ `atomic config` and package commands use the same project trust flow. Pass `--approve` to trust project-local settings for one command or `--no-approve` to ignore them.
21
+
22
+ Use `/trust` in interactive mode to save a project trust decision for future sessions, including trust for the immediate parent folder. It writes `~/.atomic/agent/trust.json` only; the current session is not reloaded, so restart Atomic for changes to take effect.
11
23
 
12
24
  ## All Settings
13
25
 
@@ -58,13 +70,14 @@ Use `/fast` in interactive mode to edit these settings. Atomic applies fast mode
58
70
  |---------|------|---------|-------------|
59
71
  | `theme` | string | `"dark"` | Theme name (`"dark"`, `"light"`, a Catppuccin built-in, or custom) |
60
72
  | `quietStartup` | boolean | `false` | Hide startup header |
73
+ | `defaultProjectTrust` | string | `"ask"` | Fallback project trust behavior: `"ask"`, `"always"`, or `"never"`. Global setting only |
61
74
  | `collapseChangelog` | boolean | `false` | Show condensed changelog after updates |
62
75
  | `enableInstallTelemetry` | boolean | `true` | Send an anonymous install/update version ping after first install or changelog-detected updates. This does not control update checks |
63
76
  | `doubleEscapeAction` | string | `"tree"` | Action for double-escape: `"tree"`, `"fork"`, or `"none"` |
64
77
  | `treeFilterMode` | string | `"default"` | Default filter for `/tree`: `"default"`, `"no-tools"`, `"user-only"`, `"labeled-only"`, `"all"` |
65
78
  | `editorPaddingX` | number | `0` | Horizontal padding for input editor (0-3) |
66
79
  | `autocompleteMaxVisible` | number | `5` | Max visible items in autocomplete dropdown (3-20) |
67
- | `showHardwareCursor` | boolean | `false` | Show terminal cursor |
80
+ | `showHardwareCursor` | boolean | `false` | Show the terminal cursor while TUI positions it for IME support |
68
81
 
69
82
  ### Telemetry and update checks
70
83
 
@@ -117,11 +130,13 @@ Set `ATOMIC_SKIP_VERSION_CHECK=1` to disable the Atomic version update check. Us
117
130
  | `retry.maxRetries` | number | `3` | Maximum agent-level retry attempts |
118
131
  | `retry.baseDelayMs` | number | `2000` | Base delay for agent-level exponential backoff (2s, 4s, 8s) |
119
132
  | `retry.provider.timeoutMs` | number | SDK default | Provider/SDK request timeout in milliseconds |
120
- | `retry.provider.maxRetries` | number | SDK default | Provider/SDK retry attempts |
133
+ | `retry.provider.maxRetries` | number | `0` | Provider/SDK retry attempts |
121
134
  | `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay before failing (60s) |
122
135
 
123
136
  When a provider requests a retry delay longer than `retry.provider.maxRetryDelayMs` (e.g., Google's "quota will reset after 5h"), the request fails immediately with an informative error instead of waiting silently. Set to `0` to disable the cap.
124
137
 
138
+ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explicitly needed. Setting it above `0` can make SDK/provider retries handle out-of-usage-limit errors before Atomic sees them, which may block the agent until the provider quota resets in some circumstances.
139
+
125
140
  ```json
126
141
  {
127
142
  "retry": {
@@ -168,7 +183,9 @@ The `/settings` picker offers these presets:
168
183
  |---------|------|---------|-------------|
169
184
  | `steeringMode` | string | `"one-at-a-time"` | How steering messages are sent: `"all"` or `"one-at-a-time"` |
170
185
  | `followUpMode` | string | `"one-at-a-time"` | How follow-up messages are sent: `"all"` or `"one-at-a-time"` |
171
- | `transport` | string | `"sse"` | Preferred transport for providers that support multiple transports: `"sse"`, `"websocket"`, or `"auto"` |
186
+ | `transport` | string | `"auto"` | Preferred transport for providers that support multiple transports: `"sse"`, `"websocket"`, `"websocket-cached"`, or `"auto"` |
187
+ | `httpIdleTimeoutMs` | number | `300000` | HTTP header/body idle timeout in milliseconds, also used by providers with explicit stream idle timeouts. Set to `0` to disable. |
188
+ | `websocketConnectTimeoutMs` | number | `15000` | WebSocket connect/open handshake timeout in milliseconds for providers that support WebSocket transports. Set to `0` to disable. |
172
189
 
173
190
  ### Terminal & Images
174
191
 
package/docs/skills.md CHANGED
@@ -26,7 +26,7 @@ Atomic loads skills from:
26
26
  - Global:
27
27
  - `~/.atomic/agent/skills/` (legacy `~/.pi/agent/skills/`)
28
28
  - `~/.agents/skills/`
29
- - Project:
29
+ - Project (only after the project is trusted):
30
30
  - `.atomic/skills/` (legacy `.pi/skills/`)
31
31
  - `.agents/skills/` in `cwd` and ancestor directories (up to git repo root, or filesystem root when not in a repo)
32
32
  - Packages: `skills/` directories, `atomic.skills`, or legacy `pi.skills` entries in `package.json`