@bastani/atomic 0.8.26-alpha.6 → 0.8.26-alpha.7

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 (240) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +7 -4
  3. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  4. package/dist/builtin/intercom/package.json +2 -2
  5. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  6. package/dist/builtin/mcp/package.json +3 -3
  7. package/dist/builtin/subagents/CHANGELOG.md +6 -0
  8. package/dist/builtin/subagents/agents/codebase-online-researcher.md +9 -9
  9. package/dist/builtin/subagents/agents/debugger.md +6 -6
  10. package/dist/builtin/subagents/package.json +4 -4
  11. package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +1 -1
  12. package/dist/builtin/subagents/skills/browser/EXAMPLES.md +151 -0
  13. package/dist/builtin/subagents/skills/browser/LICENSE.txt +21 -0
  14. package/dist/builtin/subagents/skills/browser/REFERENCE.md +451 -0
  15. package/dist/builtin/subagents/skills/browser/SKILL.md +170 -0
  16. package/dist/builtin/subagents/skills/subagent/SKILL.md +4 -4
  17. package/dist/builtin/web-access/CHANGELOG.md +6 -0
  18. package/dist/builtin/web-access/package.json +2 -2
  19. package/dist/builtin/workflows/CHANGELOG.md +11 -0
  20. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +4 -1
  21. package/dist/builtin/workflows/builtin/goal.ts +127 -99
  22. package/dist/builtin/workflows/builtin/open-claude-design.ts +224 -147
  23. package/dist/builtin/workflows/builtin/ralph.ts +160 -197
  24. package/dist/builtin/workflows/package.json +2 -2
  25. package/dist/builtin/workflows/skills/research-codebase/SKILL.md +1 -1
  26. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +9 -0
  27. package/dist/core/agent-session.d.ts +28 -1
  28. package/dist/core/agent-session.d.ts.map +1 -1
  29. package/dist/core/agent-session.js +110 -28
  30. package/dist/core/agent-session.js.map +1 -1
  31. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  32. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  33. package/dist/core/compaction/branch-summarization.js +6 -3
  34. package/dist/core/compaction/branch-summarization.js.map +1 -1
  35. package/dist/core/compaction/compaction.d.ts.map +1 -1
  36. package/dist/core/compaction/compaction.js +23 -10
  37. package/dist/core/compaction/compaction.js.map +1 -1
  38. package/dist/core/compaction/context-compaction.d.ts +61 -0
  39. package/dist/core/compaction/context-compaction.d.ts.map +1 -0
  40. package/dist/core/compaction/context-compaction.js +602 -0
  41. package/dist/core/compaction/context-compaction.js.map +1 -0
  42. package/dist/core/compaction/index.d.ts +1 -0
  43. package/dist/core/compaction/index.d.ts.map +1 -1
  44. package/dist/core/compaction/index.js +1 -0
  45. package/dist/core/compaction/index.js.map +1 -1
  46. package/dist/core/index.d.ts +1 -1
  47. package/dist/core/index.d.ts.map +1 -1
  48. package/dist/core/index.js.map +1 -1
  49. package/dist/core/session-manager.d.ts +41 -1
  50. package/dist/core/session-manager.d.ts.map +1 -1
  51. package/dist/core/session-manager.js +146 -7
  52. package/dist/core/session-manager.js.map +1 -1
  53. package/dist/core/slash-commands.d.ts.map +1 -1
  54. package/dist/core/slash-commands.js +1 -0
  55. package/dist/core/slash-commands.js.map +1 -1
  56. package/dist/index.d.ts +3 -3
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -2
  59. package/dist/index.js.map +1 -1
  60. package/dist/modes/index.d.ts +1 -1
  61. package/dist/modes/index.d.ts.map +1 -1
  62. package/dist/modes/index.js.map +1 -1
  63. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  64. package/dist/modes/interactive/components/chat-session-host.js +17 -0
  65. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  66. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  67. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  68. package/dist/modes/interactive/interactive-mode.js +74 -0
  69. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  70. package/dist/modes/rpc/rpc-client.d.ts +12 -7
  71. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  72. package/dist/modes/rpc/rpc-client.js +8 -1
  73. package/dist/modes/rpc/rpc-client.js.map +1 -1
  74. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  75. package/dist/modes/rpc/rpc-mode.js +4 -0
  76. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  77. package/dist/modes/rpc/rpc-types.d.ts +13 -2
  78. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  79. package/dist/modes/rpc/rpc-types.js.map +1 -1
  80. package/docs/compaction.md +42 -23
  81. package/docs/custom-provider.md +11 -9
  82. package/docs/extensions.md +35 -35
  83. package/docs/index.md +1 -8
  84. package/docs/json.md +14 -11
  85. package/docs/packages.md +2 -0
  86. package/docs/providers.md +4 -1
  87. package/docs/quickstart.md +5 -12
  88. package/docs/rpc.md +44 -8
  89. package/docs/sdk.md +1 -8
  90. package/docs/session-format.md +25 -12
  91. package/docs/sessions.md +2 -1
  92. package/docs/skills.md +1 -15
  93. package/docs/termux.md +9 -10
  94. package/docs/themes.md +2 -2
  95. package/docs/tmux.md +3 -3
  96. package/docs/tui.md +19 -32
  97. package/docs/usage.md +2 -0
  98. package/docs/workflows.md +44 -2
  99. package/package.json +4 -12
  100. package/dist/builtin/subagents/skills/browser-use/SKILL.md +0 -234
  101. package/dist/builtin/subagents/skills/browser-use/references/cdp-python.md +0 -76
  102. package/dist/builtin/subagents/skills/browser-use/references/multi-session.md +0 -92
  103. package/node_modules/@earendil-works/pi-tui/README.md +0 -779
  104. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +0 -54
  105. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +0 -1
  106. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +0 -632
  107. package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +0 -1
  108. package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts +0 -22
  109. package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts.map +0 -1
  110. package/node_modules/@earendil-works/pi-tui/dist/components/box.js +0 -104
  111. package/node_modules/@earendil-works/pi-tui/dist/components/box.js.map +0 -1
  112. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts +0 -22
  113. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts.map +0 -1
  114. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js +0 -35
  115. package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js.map +0 -1
  116. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +0 -249
  117. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +0 -1
  118. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +0 -1857
  119. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +0 -1
  120. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts +0 -28
  121. package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +0 -1
  122. package/node_modules/@earendil-works/pi-tui/dist/components/image.js +0 -89
  123. package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +0 -1
  124. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts +0 -37
  125. package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +0 -1
  126. package/node_modules/@earendil-works/pi-tui/dist/components/input.js +0 -378
  127. package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +0 -1
  128. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts +0 -31
  129. package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts.map +0 -1
  130. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js +0 -69
  131. package/node_modules/@earendil-works/pi-tui/dist/components/loader.js.map +0 -1
  132. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +0 -96
  133. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +0 -1
  134. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +0 -644
  135. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +0 -1
  136. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +0 -50
  137. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +0 -1
  138. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +0 -159
  139. package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +0 -1
  140. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts +0 -50
  141. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts.map +0 -1
  142. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js +0 -185
  143. package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js.map +0 -1
  144. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts +0 -12
  145. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts.map +0 -1
  146. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js +0 -23
  147. package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js.map +0 -1
  148. package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts +0 -19
  149. package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts.map +0 -1
  150. package/node_modules/@earendil-works/pi-tui/dist/components/text.js +0 -89
  151. package/node_modules/@earendil-works/pi-tui/dist/components/text.js.map +0 -1
  152. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts +0 -13
  153. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts.map +0 -1
  154. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js +0 -51
  155. package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js.map +0 -1
  156. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts +0 -39
  157. package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts.map +0 -1
  158. package/node_modules/@earendil-works/pi-tui/dist/editor-component.js +0 -2
  159. package/node_modules/@earendil-works/pi-tui/dist/editor-component.js.map +0 -1
  160. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +0 -16
  161. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +0 -1
  162. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +0 -110
  163. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +0 -1
  164. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +0 -23
  165. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +0 -1
  166. package/node_modules/@earendil-works/pi-tui/dist/index.js +0 -32
  167. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +0 -1
  168. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +0 -193
  169. package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +0 -1
  170. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +0 -174
  171. package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +0 -1
  172. package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts +0 -184
  173. package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +0 -1
  174. package/node_modules/@earendil-works/pi-tui/dist/keys.js +0 -1173
  175. package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +0 -1
  176. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts +0 -28
  177. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts.map +0 -1
  178. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js +0 -44
  179. package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js.map +0 -1
  180. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts +0 -3
  181. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts.map +0 -1
  182. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js +0 -53
  183. package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js.map +0 -1
  184. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +0 -50
  185. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +0 -1
  186. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +0 -361
  187. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +0 -1
  188. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -90
  189. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +0 -1
  190. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +0 -366
  191. package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +0 -1
  192. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +0 -113
  193. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +0 -1
  194. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +0 -472
  195. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +0 -1
  196. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +0 -227
  197. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +0 -1
  198. package/node_modules/@earendil-works/pi-tui/dist/tui.js +0 -1106
  199. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +0 -1
  200. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts +0 -17
  201. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts.map +0 -1
  202. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js +0 -25
  203. package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js.map +0 -1
  204. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +0 -84
  205. package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +0 -1
  206. package/node_modules/@earendil-works/pi-tui/dist/utils.js +0 -1029
  207. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +0 -1
  208. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +0 -25
  209. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +0 -1
  210. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +0 -96
  211. package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +0 -1
  212. package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
  213. package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
  214. package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  215. package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  216. package/node_modules/@earendil-works/pi-tui/package.json +0 -47
  217. package/node_modules/get-east-asian-width/index.d.ts +0 -60
  218. package/node_modules/get-east-asian-width/index.js +0 -30
  219. package/node_modules/get-east-asian-width/license +0 -9
  220. package/node_modules/get-east-asian-width/lookup-data.js +0 -21
  221. package/node_modules/get-east-asian-width/lookup.js +0 -138
  222. package/node_modules/get-east-asian-width/package.json +0 -71
  223. package/node_modules/get-east-asian-width/readme.md +0 -65
  224. package/node_modules/get-east-asian-width/utilities.js +0 -24
  225. package/node_modules/marked/LICENSE.md +0 -44
  226. package/node_modules/marked/README.md +0 -106
  227. package/node_modules/marked/bin/main.js +0 -282
  228. package/node_modules/marked/bin/marked.js +0 -15
  229. package/node_modules/marked/lib/marked.cjs +0 -2211
  230. package/node_modules/marked/lib/marked.cjs.map +0 -7
  231. package/node_modules/marked/lib/marked.d.cts +0 -728
  232. package/node_modules/marked/lib/marked.d.ts +0 -728
  233. package/node_modules/marked/lib/marked.esm.js +0 -2189
  234. package/node_modules/marked/lib/marked.esm.js.map +0 -7
  235. package/node_modules/marked/lib/marked.umd.js +0 -2213
  236. package/node_modules/marked/lib/marked.umd.js.map +0 -7
  237. package/node_modules/marked/man/marked.1 +0 -111
  238. package/node_modules/marked/man/marked.1.md +0 -92
  239. package/node_modules/marked/marked.min.js +0 -69
  240. package/node_modules/marked/package.json +0 -111
@@ -208,7 +208,7 @@ models: [{
208
208
  id: "custom-model",
209
209
  // ...
210
210
  reasoning: true,
211
- thinkingLevelMap: { // map pi levels to provider values; null hides unsupported levels
211
+ thinkingLevelMap: { // map Atomic thinking levels to provider values; null hides unsupported levels
212
212
  minimal: null,
213
213
  low: null,
214
214
  medium: null,
@@ -345,12 +345,14 @@ interface OAuthCredentials {
345
345
  For providers with non-standard APIs, implement `streamSimple`. Study the existing provider implementations before writing your own:
346
346
 
347
347
  **Reference implementations:**
348
- - [anthropic.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/anthropic.ts) - Anthropic Messages API
349
- - [mistral.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/mistral.ts) - Mistral Conversations API
350
- - [openai-completions.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/openai-completions.ts) - OpenAI Chat Completions
351
- - [openai-responses.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/openai-responses.ts) - OpenAI Responses API
352
- - [google.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/google.ts) - Google Generative AI
353
- - [amazon-bedrock.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/providers/amazon-bedrock.ts) - AWS Bedrock
348
+
349
+ Atomic uses provider implementations from its installed `@earendil-works/pi-ai` dependency. Inspect the compiled declarations and JavaScript under `node_modules/@earendil-works/pi-ai/dist/providers/`, including:
350
+ - `anthropic.d.ts` / `anthropic.js` - Anthropic Messages API
351
+ - `mistral.d.ts` / `mistral.js` - Mistral Conversations API
352
+ - `openai-completions.d.ts` / `openai-completions.js` - OpenAI Chat Completions
353
+ - `openai-responses.d.ts` / `openai-responses.js` - OpenAI Responses API
354
+ - `google.d.ts` / `google.js` - Google Generative AI
355
+ - `amazon-bedrock.d.ts` / `amazon-bedrock.js` - AWS Bedrock
354
356
 
355
357
  ### Stream Pattern
356
358
 
@@ -522,7 +524,7 @@ pi.registerProvider("my-provider", {
522
524
 
523
525
  ## Testing Your Implementation
524
526
 
525
- Test your provider against the same test suites used by built-in providers. Copy and adapt these test files from [packages/ai/test/](https://github.com/earendil-works/pi-mono/tree/main/packages/ai/test):
527
+ Test your provider against focused tests that mirror Atomic's provider contract. If you are working from the source checkout, note that provider internals come from `@earendil-works/pi-ai`; this monorepo does not contain a `packages/ai/test` directory to copy from directly:
526
528
 
527
529
  | Test | Purpose |
528
530
  |------|---------|
@@ -602,7 +604,7 @@ interface ProviderModelConfig {
602
604
  /** Whether the model supports extended thinking. */
603
605
  reasoning: boolean;
604
606
 
605
- /** Maps pi thinking levels to provider/model-specific values; null marks a level unsupported. */
607
+ /** Maps Atomic thinking levels to provider/model-specific values; null marks a level unsupported. */
606
608
  thinkingLevelMap?: Partial<Record<"off" | "minimal" | "low" | "medium" | "high" | "xhigh", string | null>>;
607
609
 
608
610
  /** Supported input types. */
@@ -144,17 +144,10 @@ To share extensions via npm or git as Atomic packages, see [Atomic packages](/pa
144
144
  | `@earendil-works/pi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
145
145
  | `@earendil-works/pi-tui` | TUI components for custom rendering |
146
146
 
147
- npm dependencies work too. Add a `package.json` next to your extension (or in a parent directory), then install dependencies with npm, Bun, or pnpm:
147
+ Registry dependencies work too. Add a `package.json` next to your extension (or in a parent directory), then install dependencies with Bun:
148
148
 
149
149
  ```bash
150
- # npm
151
- npm install
152
-
153
- # Bun
154
150
  bun install
155
-
156
- # pnpm
157
- pnpm install
158
151
  ```
159
152
 
160
153
  Imports from `node_modules/` are resolved automatically.
@@ -175,7 +168,7 @@ export default function (pi: ExtensionAPI) {
175
168
  pi.on("event_name", async (event, ctx) => {
176
169
  // ctx.ui for user interaction
177
170
  const ok = await ctx.ui.confirm("Title", "Are you sure?");
178
- ctx.ui.notify("Done!", "success");
171
+ ctx.ui.notify("Done!", "info");
179
172
  ctx.ui.setStatus("my-ext", "Processing..."); // Footer status
180
173
  ctx.ui.setWidget("my-ext", ["Line 1", "Line 2"]); // Widget above editor (default)
181
174
  });
@@ -254,7 +247,7 @@ This pattern makes the fetched models available during normal startup and to `at
254
247
  ~/.atomic/agent/extensions/
255
248
  └── my-extension/
256
249
  ├── package.json # Declares dependencies and entry points
257
- ├── package-lock.json
250
+ ├── bun.lock
258
251
  ├── node_modules/ # After dependency install
259
252
  └── src/
260
253
  └── index.ts
@@ -274,7 +267,7 @@ This pattern makes the fetched models available during normal startup and to `at
274
267
  }
275
268
  ```
276
269
 
277
- The manifest key is the configured Atomic app name (`atomic` here, from the running Atomic package/config), not the extension package's own `"name"` field. The legacy `pi` key is still accepted as a compatibility shim. Run `npm install`, `bun install`, or `pnpm install` in the extension directory, then imports from `node_modules/` work automatically.
270
+ The manifest key is the configured Atomic app name (`atomic` here, from the running Atomic package/config), not the extension package's own `"name"` field. The legacy `pi` key is still accepted as a compatibility shim. Run `bun install` in the extension directory, then imports from `node_modules/` work automatically.
278
271
 
279
272
  ## Events
280
273
 
@@ -398,7 +391,7 @@ pi.on("session_before_switch", async (event, ctx) => {
398
391
  });
399
392
  ```
400
393
 
401
- After a successful switch or new-session action, pi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "new" | "resume"` and `previousSessionFile`.
394
+ After a successful switch or new-session action, Atomic emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "new" | "resume"` and `previousSessionFile`.
402
395
  Do cleanup work in `session_shutdown`, then reestablish any in-memory state in `session_start`.
403
396
 
404
397
  #### session_before_fork
@@ -415,7 +408,7 @@ pi.on("session_before_fork", async (event, ctx) => {
415
408
  });
416
409
  ```
417
410
 
418
- After a successful fork or clone, pi emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "fork"` and `previousSessionFile`.
411
+ After a successful fork or clone, Atomic emits `session_shutdown` for the old extension instance, reloads and rebinds extensions for the new session, then emits `session_start` with `reason: "fork"` and `previousSessionFile`.
419
412
  Do cleanup work in `session_shutdown`, then reestablish any in-memory state in `session_start`.
420
413
 
421
414
  #### session_before_compact / session_compact
@@ -509,7 +502,7 @@ pi.on("before_agent_start", async (event, ctx) => {
509
502
  });
510
503
  ```
511
504
 
512
- The `systemPromptOptions` field gives extensions access to the same structured data Pi uses to build the system prompt. This lets you inspect what Pi has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
505
+ The `systemPromptOptions` field gives extensions access to the same structured data Atomic uses to build the system prompt. This lets you inspect what Atomic has loaded — custom prompts, guidelines, tool snippets, context files, skills — without re-discovering resources or re-parsing flags. Use it when your extension needs to make deep, informed changes to the system prompt while respecting user-provided configuration.
513
506
 
514
507
  Inside `before_agent_start`, `event.systemPrompt` and `ctx.getSystemPrompt()` both reflect the chained system prompt as of the current handler. Later `before_agent_start` handlers can still modify it again.
515
508
 
@@ -904,7 +897,7 @@ Use this for abort-aware nested work started by extension handlers, for example:
904
897
  - file or process helpers that accept `AbortSignal`
905
898
 
906
899
  `ctx.signal` is typically defined during active turn events such as `tool_call`, `tool_result`, `message_update`, and `turn_end`.
907
- It is usually `undefined` in idle or non-turn contexts such as session events, extension commands, and shortcuts fired while pi is idle.
900
+ It is usually `undefined` in idle or non-turn contexts such as session events, extension commands, and shortcuts fired while Atomic is idle.
908
901
 
909
902
  ```typescript
910
903
  pi.on("tool_result", async (event, ctx) => {
@@ -925,7 +918,7 @@ Control flow helpers.
925
918
 
926
919
  ### ctx.shutdown()
927
920
 
928
- Request a graceful shutdown of pi.
921
+ Request a graceful shutdown of Atomic.
929
922
 
930
923
  - **Interactive mode:** Deferred until the agent becomes idle (after processing all queued steering and follow-up messages).
931
924
  - **RPC mode:** Deferred until the next idle state (after completing the current command response, when waiting for the next command).
@@ -1389,7 +1382,7 @@ Labels persist in the session and survive restarts. Use them to mark important p
1389
1382
 
1390
1383
  Register a command.
1391
1384
 
1392
- If multiple extensions register the same command name, pi keeps them all and assigns numeric invocation suffixes in load order, for example `/review:1` and `/review:2`.
1385
+ If multiple extensions register the same command name, Atomic keeps them all and assigns numeric invocation suffixes in load order, for example `/review:1` and `/review:2`.
1393
1386
 
1394
1387
  ```typescript
1395
1388
  pi.registerCommand("stats", {
@@ -1790,7 +1783,7 @@ async execute(toolCallId, params) {
1790
1783
 
1791
1784
  **Important:** Use `StringEnum` from `@earendil-works/pi-ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
1792
1785
 
1793
- **Argument preparation:** `prepareArguments(args)` is optional. If defined, it runs before schema validation and before `execute()`. Use it to mimic an older accepted input shape when pi resumes an older session whose stored tool call arguments no longer match the current schema. Return the object you want validated against `parameters`. Keep the public schema strict. Do not add deprecated compatibility fields to `parameters` just to keep old resumed sessions working.
1786
+ **Argument preparation:** `prepareArguments(args)` is optional. If defined, it runs before schema validation and before `execute()`. Use it to mimic an older accepted input shape when Atomic resumes an older session whose stored tool call arguments no longer match the current schema. Return the object you want validated against `parameters`. Keep the public schema strict. Do not add deprecated compatibility fields to `parameters` just to keep old resumed sessions working.
1794
1787
 
1795
1788
  Example: an older session may contain an `edit` tool call with top-level `oldText` and `newText`, while the current schema only accepts `edits: [{ oldText, newText }]`.
1796
1789
 
@@ -1861,13 +1854,13 @@ See [examples/extensions/tool-override.ts](https://github.com/bastani-inc/atomic
1861
1854
  **Your implementation must match the exact result shape**, including the `details` type. The UI and session logic depend on these shapes for rendering and state tracking.
1862
1855
 
1863
1856
  Built-in tool implementations:
1864
- - [read.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/read.ts) - `ReadToolDetails`
1865
- - [bash.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/bash.ts) - `BashToolDetails`
1866
- - [edit.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/edit.ts)
1867
- - [write.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/write.ts)
1868
- - [grep.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/grep.ts) - `GrepToolDetails`
1869
- - [find.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/find.ts) - `FindToolDetails`
1870
- - [ls.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/tools/ls.ts) - `LsToolDetails`
1857
+ - [read.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/tools/read.ts) - `ReadToolDetails`
1858
+ - [bash.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/tools/bash.ts) - `BashToolDetails`
1859
+ - [edit.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/tools/edit.ts)
1860
+ - [write.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/tools/write.ts)
1861
+ - [grep.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/tools/grep.ts) - `GrepToolDetails`
1862
+ - [find.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/tools/find.ts) - `FindToolDetails`
1863
+ - [ls.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/tools/ls.ts) - `LsToolDetails`
1871
1864
 
1872
1865
  ### Remote Execution
1873
1866
 
@@ -1990,7 +1983,7 @@ export default function (pi: ExtensionAPI) {
1990
1983
 
1991
1984
  ### Custom Rendering
1992
1985
 
1993
- Tools can provide `renderCall` and `renderResult` for custom TUI display. See [TUI components](/tui) for the full component API and [tool-execution.ts](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how tool rows are composed.
1986
+ Tools can provide `renderCall` and `renderResult` for custom TUI display. See [TUI components](/tui) for the full component API and [tool-execution.ts](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how tool rows are composed.
1994
1987
 
1995
1988
  By default, tool output is wrapped in a `Box` that handles padding and background. A defined `renderCall` or `renderResult` must return a `Component`. If a slot renderer is not defined, `tool-execution.ts` uses fallback rendering for that slot.
1996
1989
 
@@ -2345,18 +2338,25 @@ See [github-issue-autocomplete.ts](https://github.com/bastani-inc/atomic/blob/ma
2345
2338
  For complex UI, use `ctx.ui.custom()`. This temporarily replaces the editor with your component until `done()` is called:
2346
2339
 
2347
2340
  ```typescript
2348
- import { Text, Component } from "@earendil-works/pi-tui";
2341
+ import { Text, type Component } from "@earendil-works/pi-tui";
2349
2342
 
2350
- const result = await ctx.ui.custom<boolean>((tui, theme, keybindings, done) => {
2351
- const text = new Text("Enter Confirm · Escape Cancel", 1, 1);
2343
+ class ConfirmPrompt implements Component {
2344
+ render(width: number): string[] {
2345
+ return new Text("Enter Confirm · Escape Cancel", 1, 1).render(width);
2346
+ }
2352
2347
 
2353
- text.onKey = (key) => {
2354
- if (key === "return") done(true);
2355
- if (key === "escape") done(false);
2356
- return true;
2357
- };
2348
+ invalidate(): void {}
2358
2349
 
2359
- return text;
2350
+ handleInput(data: string): void {
2351
+ if (data === "\r") this.done(true);
2352
+ if (data === "\x1b") this.done(false);
2353
+ }
2354
+
2355
+ constructor(private readonly done: (value: boolean) => void) {}
2356
+ }
2357
+
2358
+ const result = await ctx.ui.custom<boolean>((_tui, _theme, _keybindings, done) => {
2359
+ return new ConfirmPrompt(done);
2360
2360
  });
2361
2361
 
2362
2362
  if (result) {
package/docs/index.md CHANGED
@@ -9,17 +9,10 @@ Atomic is a minimal terminal coding harness. It is designed to stay small at the
9
9
 
10
10
  ## Quick start
11
11
 
12
- Install Atomic with npm, Bun, or pnpm:
12
+ Install Atomic with Bun:
13
13
 
14
14
  ```bash
15
- # npm
16
- npm install -g @bastani/atomic
17
-
18
- # Bun
19
15
  bun install -g @bastani/atomic
20
-
21
- # pnpm
22
- pnpm add -g @bastani/atomic
23
16
  ```
24
17
 
25
18
  Atomic does not require package install scripts. If you want to disable dependency lifecycle scripts during the Atomic install, you can add `--ignore-scripts` to the install command.
package/docs/json.md CHANGED
@@ -1,28 +1,31 @@
1
1
  # JSON Event Stream Mode
2
2
 
3
3
  ```bash
4
- pi --mode json "Your prompt"
4
+ atomic --mode json "Your prompt"
5
5
  ```
6
6
 
7
- Outputs all session events as JSON lines to stdout. Useful for integrating pi into other tools or custom UIs.
7
+ Outputs all session events as JSON lines to stdout. Useful for integrating Atomic into other tools or custom UIs.
8
8
 
9
9
  ## Event Types
10
10
 
11
- Events are defined in [`AgentSessionEvent`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
11
+ Events are defined in [`AgentSessionEvent`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/agent-session.ts#L152):
12
12
 
13
13
  ```typescript
14
14
  type AgentSessionEvent =
15
15
  | AgentEvent
16
16
  | { type: "queue_update"; steering: readonly string[]; followUp: readonly string[] }
17
17
  | { type: "compaction_start"; reason: "manual" | "threshold" | "overflow" }
18
+ | { type: "session_info_changed"; name: string | undefined }
19
+ | { type: "model_changed"; model: Model<Api>; previousModel: Model<Api> | undefined; source: "set" | "cycle" | "restore" }
20
+ | { type: "thinking_level_changed"; level: ThinkingLevel }
18
21
  | { type: "compaction_end"; reason: "manual" | "threshold" | "overflow"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; errorMessage?: string }
19
22
  | { type: "auto_retry_start"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string }
20
23
  | { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string };
21
24
  ```
22
25
 
23
- `queue_update` emits the full pending steering and follow-up queues whenever they change. `compaction_start` and `compaction_end` cover both manual and automatic compaction.
26
+ `queue_update` emits the full pending steering and follow-up queues whenever they change. `session_info_changed`, `model_changed`, and `thinking_level_changed` report interactive session metadata changes. `compaction_start` and `compaction_end` cover both manual and automatic compaction.
24
27
 
25
- Base events from [`AgentEvent`](https://github.com/earendil-works/pi-mono/blob/main/packages/agent/src/types.ts#L179):
28
+ Base events come from `AgentEvent` in `@earendil-works/pi-agent-core` (installed as an Atomic dependency):
26
29
 
27
30
  ```typescript
28
31
  type AgentEvent =
@@ -44,12 +47,12 @@ type AgentEvent =
44
47
 
45
48
  ## Message Types
46
49
 
47
- Base messages from [`packages/ai/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/types.ts#L134):
48
- - `UserMessage` (line 134)
49
- - `AssistantMessage` (line 140)
50
- - `ToolResultMessage` (line 152)
50
+ Base messages come from `@earendil-works/pi-ai` (installed as an Atomic dependency):
51
+ - `UserMessage`
52
+ - `AssistantMessage`
53
+ - `ToolResultMessage`
51
54
 
52
- Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts#L29):
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):
53
56
  - `BashExecutionMessage` (line 29)
54
57
  - `CustomMessage` (line 46)
55
58
  - `BranchSummaryMessage` (line 55)
@@ -78,5 +81,5 @@ Followed by events as they occur:
78
81
  ## Example
79
82
 
80
83
  ```bash
81
- pi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
84
+ atomic --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'
82
85
  ```
package/docs/packages.md CHANGED
@@ -178,6 +178,8 @@ Atomic bundles core packages for extensions and skills. If you import any of the
178
178
 
179
179
  Workflow packages should author workflow files with `import { defineWorkflow, Type } from "@bastani/workflows"` and export definitions produced by `defineWorkflow(...).compile()`. Do not use the removed `runWorkflow` object-form API, and do not hand-roll objects with `__piWorkflow: true`; discovery accepts only compiled definitions. `@bastani/workflows` is not a separate npm package: its types resolve through `@bastani/atomic`, so list `@bastani/atomic` and `typebox` in `peerDependencies` (the workflow SDK's emitted types reference `typebox`). A pure workflow-only package also adds the one-line ambient opt-in noted above; a package that imports `@bastani/atomic` elsewhere picks the types up automatically.
180
180
 
181
+ Package-authored workflows should follow the same guiding principles as project workflows mentioned in docs/workflows.md.
182
+
181
183
  Other Atomic packages must be bundled in your tarball. Add them to `dependencies` and `bundledDependencies`, then reference their resources through `node_modules/` paths. Atomic loads packages with separate module roots, so separate installs do not collide or share modules.
182
184
 
183
185
  Example:
package/docs/providers.md CHANGED
@@ -57,6 +57,7 @@ atomic
57
57
  | OpenAI | `OPENAI_API_KEY` | `openai` |
58
58
  | DeepSeek | `DEEPSEEK_API_KEY` | `deepseek` |
59
59
  | Google Gemini | `GEMINI_API_KEY` | `google` |
60
+ | Google Vertex AI | `GOOGLE_CLOUD_API_KEY` | `google-vertex` |
60
61
  | Mistral | `MISTRAL_API_KEY` | `mistral` |
61
62
  | Groq | `GROQ_API_KEY` | `groq` |
62
63
  | Cerebras | `CEREBRAS_API_KEY` | `cerebras` |
@@ -74,12 +75,14 @@ atomic
74
75
  | Kimi For Coding | `KIMI_API_KEY` | `kimi-coding` |
75
76
  | MiniMax | `MINIMAX_API_KEY` | `minimax` |
76
77
  | MiniMax (China) | `MINIMAX_CN_API_KEY` | `minimax-cn` |
78
+ | Moonshot AI | `MOONSHOT_API_KEY` | `moonshotai` |
79
+ | Moonshot AI (China) | `MOONSHOT_API_KEY` | `moonshotai-cn` |
77
80
  | Xiaomi MiMo | `XIAOMI_API_KEY` | `xiaomi` |
78
81
  | Xiaomi MiMo Token Plan (China) | `XIAOMI_TOKEN_PLAN_CN_API_KEY` | `xiaomi-token-plan-cn` |
79
82
  | Xiaomi MiMo Token Plan (Amsterdam) | `XIAOMI_TOKEN_PLAN_AMS_API_KEY` | `xiaomi-token-plan-ams` |
80
83
  | Xiaomi MiMo Token Plan (Singapore) | `XIAOMI_TOKEN_PLAN_SGP_API_KEY` | `xiaomi-token-plan-sgp` |
81
84
 
82
- Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/env-api-keys.ts).
85
+ Reference for environment variables and `auth.json` keys: `findEnvKeys()` / `getEnvApiKey()` in the installed `@earendil-works/pi-ai` dependency (`node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts`). The private provider map those functions use is in `node_modules/@earendil-works/pi-ai/dist/env-api-keys.js`; Atomic does not include a separate `packages/ai` source directory in this monorepo.
83
86
 
84
87
  #### Auth File
85
88
 
@@ -4,23 +4,16 @@ This page gets you from install to a useful first Atomic session.
4
4
 
5
5
  ## Prerequisites
6
6
 
7
- - **Node.js 24 LTS or newer** — Atomic requires the latest Node LTS runtime. Check with `node --version`.
8
- - **A package manager** — use npm (included with Node), pnpm, Yarn, or Bun. Use Bun 1.3.14+ for Bun installs or workflow-authoring examples.
7
+ - **Node.js 20.6 or newer** — required when running Atomic from the published npm package. Check with `node --version`.
8
+ - **Bun 1.3.14 or newer** — use Bun for installation, Atomic repository development, validation commands, and workflow-authoring examples.
9
9
  - **Model-provider access** — Use `/login` after startup. Supports provider subscriptions and APIs.
10
10
 
11
11
  ## Install
12
12
 
13
- Atomic is distributed through npm-compatible package managers. Choose one:
13
+ Install the published package with Bun:
14
14
 
15
15
  ```bash
16
- # npm
17
- npm install -g @bastani/atomic
18
-
19
- # Bun
20
16
  bun install -g @bastani/atomic
21
-
22
- # pnpm
23
- pnpm add -g @bastani/atomic
24
17
  ```
25
18
 
26
19
  Atomic does not require package install scripts. If you want to disable dependency lifecycle scripts during the Atomic install, you can add `--ignore-scripts` to the install command.
@@ -174,7 +167,7 @@ Atomic loads context files at startup. Add an `AGENTS.md` file to tell it how to
174
167
  ```markdown
175
168
  # Project Instructions
176
169
 
177
- - Run `npm run check` after code changes.
170
+ - Run `bun run typecheck` after code changes.
178
171
  - Do not run production migrations locally.
179
172
  - Keep responses concise.
180
173
  ```
@@ -204,7 +197,7 @@ Images can be pasted with CTRL+V (ALT+V on Windows) or dragged into supported te
204
197
  In interactive mode:
205
198
 
206
199
  ```text
207
- !npm run lint
200
+ !bun run lint
208
201
  ```
209
202
 
210
203
  The command output is sent to the model. Use `!!command` to run a command without adding its output to the model context.
package/docs/rpc.md CHANGED
@@ -378,6 +378,37 @@ Response:
378
378
  }
379
379
  ```
380
380
 
381
+ #### context_compact
382
+
383
+ Run deletion-only context compaction. This command has no prompt/config fields; send no custom instructions. Atomic asks the selected model for deletion targets using a fixed internal prompt, validates them, appends a `context_compaction` entry, and rebuilds active context.
384
+
385
+ ```json
386
+ {"type": "context_compact"}
387
+ ```
388
+
389
+ Response:
390
+ ```json
391
+ {
392
+ "type": "response",
393
+ "command": "context_compact",
394
+ "success": true,
395
+ "data": {
396
+ "promptVersion": 1,
397
+ "deletedTargets": [{ "kind": "entry", "entryId": "abc123" }],
398
+ "protectedEntryIds": ["user-task-entry"],
399
+ "stats": {
400
+ "objectsBefore": 20,
401
+ "objectsAfter": 19,
402
+ "objectsDeleted": 1,
403
+ "tokensBefore": 150000,
404
+ "tokensAfter": 120000,
405
+ "percentReduction": 20
406
+ },
407
+ "backupPath": "/path/to/session.jsonl.2026-06-06T00-00-00-000Z.context-compact.bak"
408
+ }
409
+ }
410
+ ```
411
+
381
412
  #### set_auto_compaction
382
413
 
383
414
  Enable or disable automatic compaction when context is nearly full.
@@ -455,7 +486,7 @@ If output was truncated, includes `fullOutputPath`:
455
486
  "exitCode": 0,
456
487
  "cancelled": false,
457
488
  "truncated": true,
458
- "fullOutputPath": "/tmp/pi-bash-abc123.log"
489
+ "fullOutputPath": "/tmp/atomic-bash-abc123.log"
459
490
  }
460
491
  }
461
492
  ```
@@ -756,8 +787,10 @@ Events are streamed to stdout as JSON lines during agent operation. Events do NO
756
787
  | `tool_execution_update` | Tool execution progress (streaming output) |
757
788
  | `tool_execution_end` | Tool completes |
758
789
  | `queue_update` | Pending steering/follow-up queue changed |
759
- | `compaction_start` | Compaction begins |
760
- | `compaction_end` | Compaction completes |
790
+ | `compaction_start` | Summary compaction begins |
791
+ | `compaction_end` | Summary compaction completes |
792
+ | `context_compaction_start` | Deletion-only context compaction begins |
793
+ | `context_compaction_end` | Deletion-only context compaction completes |
761
794
  | `auto_retry_start` | Auto-retry begins (after transient error) |
762
795
  | `auto_retry_end` | Auto-retry completes (success or final failure) |
763
796
  | `extension_error` | Extension threw an error |
@@ -936,6 +969,10 @@ If compaction was aborted, `result` is `null` and `aborted` is `true`.
936
969
 
937
970
  If compaction failed (e.g., API quota exceeded), `result` is `null`, `aborted` is `false`, and `errorMessage` contains the error description.
938
971
 
972
+ ### context_compaction_start / context_compaction_end
973
+
974
+ Emitted for `/context-compact` and RPC `context_compact`. The shape mirrors manual compaction events, but `reason` is always `"manual"` and the `result` contains `deletedTargets`, `protectedEntryIds`, `stats`, `promptVersion`, and optional `backupPath` instead of a summary.
975
+
939
976
  ### auto_retry_start / auto_retry_end
940
977
 
941
978
  Emitted when automatic retry is triggered after a transient error (overloaded, rate limit, 5xx).
@@ -1199,9 +1236,9 @@ Parse errors:
1199
1236
 
1200
1237
  ## Types
1201
1238
 
1202
- Source files:
1203
- - [`packages/ai/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/types.ts) - `Model`, `UserMessage`, `AssistantMessage`, `ToolResultMessage`
1204
- - [`packages/agent/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/agent/src/types.ts) - `AgentMessage`, `AgentEvent`
1239
+ Source files and installed definitions:
1240
+ - `node_modules/@earendil-works/pi-ai/dist/types.d.ts` - `Model`, `UserMessage`, `AssistantMessage`, `ToolResultMessage`
1241
+ - `node_modules/@earendil-works/pi-agent-core/dist/types.d.ts` - `AgentMessage`, `AgentEvent`
1205
1242
  - [`src/core/messages.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/messages.ts) - `BashExecutionMessage`
1206
1243
  - [`src/modes/rpc/rpc-types.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/modes/rpc/rpc-types.ts) - RPC command/response types, extension UI request/response types
1207
1244
 
@@ -1233,8 +1270,7 @@ Source files:
1233
1270
  {
1234
1271
  "role": "user",
1235
1272
  "content": "Hello!",
1236
- "timestamp": 1733234567890,
1237
- "attachments": []
1273
+ "timestamp": 1733234567890
1238
1274
  }
1239
1275
  ```
1240
1276
 
package/docs/sdk.md CHANGED
@@ -39,17 +39,10 @@ await session.prompt("What files are in the current directory?");
39
39
 
40
40
  ## Installation
41
41
 
42
- Choose npm, Bun, or pnpm:
42
+ Install the SDK package with Bun:
43
43
 
44
44
  ```bash
45
- # npm
46
- npm install @bastani/atomic
47
-
48
- # Bun
49
45
  bun add @bastani/atomic
50
-
51
- # pnpm
52
- pnpm add @bastani/atomic
53
46
  ```
54
47
 
55
48
  Atomic does not require package install scripts. If you want to disable dependency lifecycle scripts during the Atomic install, you can add `--ignore-scripts` to the install command.
@@ -28,13 +28,11 @@ Existing sessions are automatically migrated to the current version (v3) when lo
28
28
 
29
29
  ## Source Files
30
30
 
31
- Source on GitHub ([pi-mono](https://github.com/earendil-works/pi-mono)):
32
- - [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
33
- - [`packages/coding-agent/src/core/messages.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
34
- - [`packages/ai/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
35
- - [`packages/agent/src/types.ts`](https://github.com/earendil-works/pi-mono/blob/main/packages/agent/src/types.ts) - AgentMessage union type
31
+ Source on GitHub ([atomic](https://github.com/bastani-inc/atomic)):
32
+ - [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
33
+ - [`packages/coding-agent/src/core/messages.ts`](https://github.com/bastani-inc/atomic/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
36
34
 
37
- For TypeScript definitions in your project, inspect `node_modules/@bastani/atomic/dist/` and `node_modules/@earendil-works/pi-ai/dist/`.
35
+ Base message and agent event types are provided by Atomic's installed runtime dependencies (`@earendil-works/pi-ai` and `@earendil-works/pi-agent-core`), not by separate `packages/ai` or `packages/agent` directories in this monorepo. For TypeScript definitions in your project, inspect `node_modules/@bastani/atomic/dist/`, `node_modules/@earendil-works/pi-ai/dist/`, and `node_modules/@earendil-works/pi-agent-core/dist/`.
38
36
 
39
37
  ## Message Types
40
38
 
@@ -69,7 +67,7 @@ interface ToolCall {
69
67
  }
70
68
  ```
71
69
 
72
- ### Base Message Types (from pi-ai)
70
+ ### Base Message Types (from `@earendil-works/pi-ai`)
73
71
 
74
72
  ```typescript
75
73
  interface UserMessage {
@@ -116,7 +114,7 @@ interface Usage {
116
114
  }
117
115
  ```
118
116
 
119
- ### Extended Message Types (from pi-coding-agent)
117
+ ### Extended Message Types (from Atomic coding-agent)
120
118
 
121
119
  ```typescript
122
120
  interface BashExecutionMessage {
@@ -233,7 +231,17 @@ Created when context is compacted. Stores a summary of earlier messages.
233
231
 
234
232
  Optional fields:
235
233
  - `details`: Implementation-specific data (e.g., `{ readFiles: string[], modifiedFiles: string[] }` for default, or custom data for extensions)
236
- - `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
234
+ - `fromHook`: `true` if generated by an extension, `false`/`undefined` if Atomic-generated (legacy field name)
235
+
236
+ ### ContextCompactionEntry
237
+
238
+ Created by `/context-compact`. Stores validated logical deletion targets, not replacement text. During `buildSessionContext()`, matching entries/content blocks are filtered from active LLM context while retained content remains verbatim.
239
+
240
+ ```json
241
+ {"type":"context_compaction","id":"ctx12345","parentId":"f6g7h8i9","timestamp":"2024-12-03T14:12:00.000Z","promptVersion":1,"deletedTargets":[{"kind":"entry","entryId":"b2c3d4e5"}],"protectedEntryIds":["a1b2c3d4"],"stats":{"objectsBefore":20,"objectsAfter":19,"objectsDeleted":1,"tokensBefore":50000,"tokensAfter":43000,"percentReduction":14},"backupPath":"/path/session.jsonl.2024-12-03T14-12-00-000Z.context-compact.bak"}
242
+ ```
243
+
244
+ `deletedTargets` entries are either whole entries (`{ kind: "entry", entryId }`) or content blocks (`{ kind: "content_block", entryId, blockIndex }`). The JSONL file remains append-only; this is logical deletion for active context rebuild.
237
245
 
238
246
  ### BranchSummaryEntry
239
247
 
@@ -245,7 +253,7 @@ Created when switching branches via `/tree` with an LLM generated summary of the
245
253
 
246
254
  Optional fields:
247
255
  - `details`: File tracking data (`{ readFiles: string[], modifiedFiles: string[] }`) for default, or custom data for extensions
248
- - `fromHook`: `true` if generated by an extension, `false`/`undefined` if pi-generated (legacy field name)
256
+ - `fromHook`: `true` if generated by an extension, `false`/`undefined` if Atomic-generated (legacy field name)
249
257
 
250
258
  ### CustomEntry
251
259
 
@@ -314,7 +322,8 @@ Entries form a tree:
314
322
  - Emits the summary first
315
323
  - Then messages from `firstKeptEntryId` to compaction
316
324
  - Then messages after compaction
317
- 4. Converts `BranchSummaryEntry` and `CustomMessageEntry` to appropriate message formats
325
+ 4. Applies `ContextCompactionEntry` logical deletions recorded after the latest summary compaction
326
+ 5. Converts `BranchSummaryEntry` and `CustomMessageEntry` to appropriate message formats
318
327
 
319
328
  ## Parsing Example
320
329
 
@@ -336,6 +345,9 @@ for (const line of lines) {
336
345
  case "compaction":
337
346
  console.log(`[${entry.id}] Compaction: ${entry.tokensBefore} tokens summarized`);
338
347
  break;
348
+ case "context_compaction":
349
+ console.log(`[${entry.id}] Context compaction: ${entry.stats.objectsDeleted} objects deleted`);
350
+ break;
339
351
  case "branch_summary":
340
352
  console.log(`[${entry.id}] Branch from ${entry.fromId}`);
341
353
  break;
@@ -382,7 +394,8 @@ Key methods for working with sessions programmatically.
382
394
  - `appendMessage(message)` - Add message
383
395
  - `appendThinkingLevelChange(level)` - Record thinking change
384
396
  - `appendModelChange(provider, modelId)` - Record model change
385
- - `appendCompaction(summary, firstKeptEntryId, tokensBefore, details?, fromHook?)` - Add compaction
397
+ - `appendCompaction(summary, firstKeptEntryId, tokensBefore, details?, fromHook?)` - Add summary compaction
398
+ - `appendContextCompaction(deletedTargets, protectedEntryIds, stats, backupPath?)` - Add logical deletion compaction
386
399
  - `appendCustomEntry(customType, data?)` - Extension state (not in context)
387
400
  - `appendSessionInfo(name)` - Set session display name
388
401
  - `appendCustomMessageEntry(customType, content, display, details?)` - Extension message (in context)
package/docs/sessions.md CHANGED
@@ -30,6 +30,7 @@ For the JSONL file format and SessionManager API, see [Session Format](/session-
30
30
  | `/fork` | Create a new session from a previous user message |
31
31
  | `/clone` | Duplicate the current active branch into a new session |
32
32
  | `/compact [prompt]` | Summarize older context; see [Compaction](/compaction) |
33
+ | `/context-compact` | Apply validated deletion-only logical compaction; no arguments |
33
34
  | `/export [file]` | Export session to HTML |
34
35
  | `/share` | Upload as private GitHub gist with shareable HTML link |
35
36
 
@@ -132,6 +133,6 @@ See [Compaction](/compaction) for branch summarization internals and extension h
132
133
 
133
134
  ## Session Format
134
135
 
135
- Session files are JSONL and contain message entries, model changes, thinking-level changes, labels, compactions, branch summaries, and extension entries.
136
+ Session files are JSONL and contain message entries, model changes, thinking-level changes, labels, summary compactions, context compactions, branch summaries, and extension entries.
136
137
 
137
138
  For parsers, extensions, SDK usage, and the full SessionManager API, see [Session Format](/session-format).