@bastani/atomic 0.8.27 → 0.8.28-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +120 -118
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +2 -2
  5. package/dist/builtin/subagents/package.json +1 -1
  6. package/dist/builtin/web-access/package.json +1 -1
  7. package/dist/builtin/workflows/CHANGELOG.md +22 -0
  8. package/dist/builtin/workflows/README.md +11 -9
  9. package/dist/builtin/workflows/builtin/open-claude-design.ts +150 -13
  10. package/dist/builtin/workflows/package.json +1 -1
  11. package/dist/builtin/workflows/src/authoring.d.ts +5 -2
  12. package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +3 -1
  13. package/dist/builtin/workflows/src/extension/hil-answer-notifications.ts +17 -25
  14. package/dist/builtin/workflows/src/extension/index.ts +133 -18
  15. package/dist/builtin/workflows/src/extension/render-result.ts +22 -2
  16. package/dist/builtin/workflows/src/extension/workflow-schema.ts +3 -3
  17. package/dist/builtin/workflows/src/runs/foreground/executor.ts +210 -16
  18. package/dist/builtin/workflows/src/sdk-surface.ts +1 -1
  19. package/dist/builtin/workflows/src/shared/authoring-contract.d.ts +42 -5
  20. package/dist/builtin/workflows/src/shared/store-types.ts +8 -2
  21. package/dist/builtin/workflows/src/shared/store.ts +51 -0
  22. package/dist/builtin/workflows/src/shared/types.ts +14 -4
  23. package/dist/builtin/workflows/src/tui/chat-surface.ts +32 -33
  24. package/dist/builtin/workflows/src/tui/graph-view.ts +4 -1
  25. package/dist/builtin/workflows/src/tui/prompt-card.ts +6 -0
  26. package/dist/builtin/workflows/src/tui/run-detail.ts +11 -4
  27. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +11 -1
  28. package/dist/builtin/workflows/src/tui/status-list.ts +32 -2
  29. package/dist/cli/args.d.ts +4 -0
  30. package/dist/cli/args.d.ts.map +1 -1
  31. package/dist/cli/args.js +35 -0
  32. package/dist/cli/args.js.map +1 -1
  33. package/dist/cli/project-trust.d.ts +10 -0
  34. package/dist/cli/project-trust.d.ts.map +1 -0
  35. package/dist/cli/project-trust.js +36 -0
  36. package/dist/cli/project-trust.js.map +1 -0
  37. package/dist/cli/startup-ui.d.ts +7 -0
  38. package/dist/cli/startup-ui.d.ts.map +1 -0
  39. package/dist/cli/startup-ui.js +57 -0
  40. package/dist/cli/startup-ui.js.map +1 -0
  41. package/dist/config.d.ts.map +1 -1
  42. package/dist/config.js +24 -3
  43. package/dist/config.js.map +1 -1
  44. package/dist/core/agent-session-runtime.d.ts +3 -1
  45. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  46. package/dist/core/agent-session-runtime.js +1 -0
  47. package/dist/core/agent-session-runtime.js.map +1 -1
  48. package/dist/core/agent-session-services.d.ts +2 -1
  49. package/dist/core/agent-session-services.d.ts.map +1 -1
  50. package/dist/core/agent-session-services.js +2 -2
  51. package/dist/core/agent-session-services.js.map +1 -1
  52. package/dist/core/agent-session.d.ts +9 -5
  53. package/dist/core/agent-session.d.ts.map +1 -1
  54. package/dist/core/agent-session.js +205 -51
  55. package/dist/core/agent-session.js.map +1 -1
  56. package/dist/core/auth-guidance.d.ts +10 -1
  57. package/dist/core/auth-guidance.d.ts.map +1 -1
  58. package/dist/core/auth-guidance.js +26 -1
  59. package/dist/core/auth-guidance.js.map +1 -1
  60. package/dist/core/auth-storage.d.ts.map +1 -1
  61. package/dist/core/auth-storage.js +4 -3
  62. package/dist/core/auth-storage.js.map +1 -1
  63. package/dist/core/compaction/branch-summarization.d.ts +5 -3
  64. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  65. package/dist/core/compaction/branch-summarization.js +16 -10
  66. package/dist/core/compaction/branch-summarization.js.map +1 -1
  67. package/dist/core/compaction/compaction.d.ts +4 -84
  68. package/dist/core/compaction/compaction.d.ts.map +1 -1
  69. package/dist/core/compaction/compaction.js +20 -502
  70. package/dist/core/compaction/compaction.js.map +1 -1
  71. package/dist/core/compaction/context-compaction.d.ts.map +1 -1
  72. package/dist/core/compaction/context-compaction.js +39 -82
  73. package/dist/core/compaction/context-compaction.js.map +1 -1
  74. package/dist/core/compaction/index.d.ts +1 -1
  75. package/dist/core/compaction/index.d.ts.map +1 -1
  76. package/dist/core/compaction/index.js +1 -1
  77. package/dist/core/compaction/index.js.map +1 -1
  78. package/dist/core/compaction/utils.d.ts +1 -1
  79. package/dist/core/compaction/utils.d.ts.map +1 -1
  80. package/dist/core/compaction/utils.js +1 -1
  81. package/dist/core/compaction/utils.js.map +1 -1
  82. package/dist/core/experimental.d.ts +2 -0
  83. package/dist/core/experimental.d.ts.map +1 -0
  84. package/dist/core/experimental.js +5 -0
  85. package/dist/core/experimental.js.map +1 -0
  86. package/dist/core/export-html/template.js +19 -6
  87. package/dist/core/extensions/index.d.ts +1 -1
  88. package/dist/core/extensions/index.d.ts.map +1 -1
  89. package/dist/core/extensions/index.js.map +1 -1
  90. package/dist/core/extensions/loader.d.ts +1 -1
  91. package/dist/core/extensions/loader.d.ts.map +1 -1
  92. package/dist/core/extensions/loader.js +6 -4
  93. package/dist/core/extensions/loader.js.map +1 -1
  94. package/dist/core/extensions/runner.d.ts +11 -4
  95. package/dist/core/extensions/runner.d.ts.map +1 -1
  96. package/dist/core/extensions/runner.js +53 -3
  97. package/dist/core/extensions/runner.js.map +1 -1
  98. package/dist/core/extensions/types.d.ts +44 -12
  99. package/dist/core/extensions/types.d.ts.map +1 -1
  100. package/dist/core/extensions/types.js.map +1 -1
  101. package/dist/core/footer-data-provider.d.ts +2 -0
  102. package/dist/core/footer-data-provider.d.ts.map +1 -1
  103. package/dist/core/footer-data-provider.js +27 -1
  104. package/dist/core/footer-data-provider.js.map +1 -1
  105. package/dist/core/index.d.ts +2 -1
  106. package/dist/core/index.d.ts.map +1 -1
  107. package/dist/core/index.js +1 -0
  108. package/dist/core/index.js.map +1 -1
  109. package/dist/core/messages.d.ts +1 -11
  110. package/dist/core/messages.d.ts.map +1 -1
  111. package/dist/core/messages.js +10 -25
  112. package/dist/core/messages.js.map +1 -1
  113. package/dist/core/model-registry.d.ts.map +1 -1
  114. package/dist/core/model-registry.js +64 -7
  115. package/dist/core/model-registry.js.map +1 -1
  116. package/dist/core/model-resolver.d.ts.map +1 -1
  117. package/dist/core/model-resolver.js +1 -0
  118. package/dist/core/model-resolver.js.map +1 -1
  119. package/dist/core/output-guard.d.ts +1 -0
  120. package/dist/core/output-guard.d.ts.map +1 -1
  121. package/dist/core/output-guard.js +52 -22
  122. package/dist/core/output-guard.js.map +1 -1
  123. package/dist/core/package-manager.d.ts +1 -0
  124. package/dist/core/package-manager.d.ts.map +1 -1
  125. package/dist/core/package-manager.js +20 -8
  126. package/dist/core/package-manager.js.map +1 -1
  127. package/dist/core/project-trust.d.ts +15 -0
  128. package/dist/core/project-trust.d.ts.map +1 -0
  129. package/dist/core/project-trust.js +58 -0
  130. package/dist/core/project-trust.js.map +1 -0
  131. package/dist/core/prompt-templates.d.ts +5 -4
  132. package/dist/core/prompt-templates.d.ts.map +1 -1
  133. package/dist/core/prompt-templates.js +30 -29
  134. package/dist/core/prompt-templates.js.map +1 -1
  135. package/dist/core/provider-attribution.d.ts +4 -0
  136. package/dist/core/provider-attribution.d.ts.map +1 -0
  137. package/dist/core/provider-attribution.js +73 -0
  138. package/dist/core/provider-attribution.js.map +1 -0
  139. package/dist/core/provider-display-names.d.ts.map +1 -1
  140. package/dist/core/provider-display-names.js +3 -0
  141. package/dist/core/provider-display-names.js.map +1 -1
  142. package/dist/core/resolve-config-value.d.ts +9 -1
  143. package/dist/core/resolve-config-value.d.ts.map +1 -1
  144. package/dist/core/resolve-config-value.js +134 -11
  145. package/dist/core/resolve-config-value.js.map +1 -1
  146. package/dist/core/resource-loader.d.ts +12 -2
  147. package/dist/core/resource-loader.d.ts.map +1 -1
  148. package/dist/core/resource-loader.js +108 -18
  149. package/dist/core/resource-loader.js.map +1 -1
  150. package/dist/core/sdk.d.ts.map +1 -1
  151. package/dist/core/sdk.js +12 -42
  152. package/dist/core/sdk.js.map +1 -1
  153. package/dist/core/session-manager.d.ts +11 -15
  154. package/dist/core/session-manager.d.ts.map +1 -1
  155. package/dist/core/session-manager.js +111 -111
  156. package/dist/core/session-manager.js.map +1 -1
  157. package/dist/core/settings-manager.d.ts +15 -5
  158. package/dist/core/settings-manager.d.ts.map +1 -1
  159. package/dist/core/settings-manager.js +69 -14
  160. package/dist/core/settings-manager.js.map +1 -1
  161. package/dist/core/slash-commands.d.ts.map +1 -1
  162. package/dist/core/slash-commands.js +1 -0
  163. package/dist/core/slash-commands.js.map +1 -1
  164. package/dist/core/system-prompt.d.ts.map +1 -1
  165. package/dist/core/system-prompt.js +0 -3
  166. package/dist/core/system-prompt.js.map +1 -1
  167. package/dist/core/tools/bash.d.ts.map +1 -1
  168. package/dist/core/tools/bash.js +2 -1
  169. package/dist/core/tools/bash.js.map +1 -1
  170. package/dist/core/tools/edit.d.ts.map +1 -1
  171. package/dist/core/tools/edit.js +7 -10
  172. package/dist/core/tools/edit.js.map +1 -1
  173. package/dist/core/tools/find.d.ts.map +1 -1
  174. package/dist/core/tools/find.js +1 -1
  175. package/dist/core/tools/find.js.map +1 -1
  176. package/dist/core/tools/grep.d.ts.map +1 -1
  177. package/dist/core/tools/grep.js +1 -1
  178. package/dist/core/tools/grep.js.map +1 -1
  179. package/dist/core/tools/ls.d.ts.map +1 -1
  180. package/dist/core/tools/ls.js +1 -1
  181. package/dist/core/tools/ls.js.map +1 -1
  182. package/dist/core/tools/oversized-tool-result.d.ts +53 -0
  183. package/dist/core/tools/oversized-tool-result.d.ts.map +1 -0
  184. package/dist/core/tools/oversized-tool-result.js +206 -0
  185. package/dist/core/tools/oversized-tool-result.js.map +1 -0
  186. package/dist/core/tools/read.d.ts +12 -0
  187. package/dist/core/tools/read.d.ts.map +1 -1
  188. package/dist/core/tools/read.js +99 -34
  189. package/dist/core/tools/read.js.map +1 -1
  190. package/dist/core/tools/render-utils.d.ts +6 -0
  191. package/dist/core/tools/render-utils.d.ts.map +1 -1
  192. package/dist/core/tools/render-utils.js +17 -1
  193. package/dist/core/tools/render-utils.js.map +1 -1
  194. package/dist/core/tools/tool-definition-wrapper.d.ts +6 -0
  195. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  196. package/dist/core/tools/tool-definition-wrapper.js +2 -0
  197. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  198. package/dist/core/tools/tool-limits.d.ts +25 -0
  199. package/dist/core/tools/tool-limits.d.ts.map +1 -0
  200. package/dist/core/tools/tool-limits.js +25 -0
  201. package/dist/core/tools/tool-limits.js.map +1 -0
  202. package/dist/core/tools/write.d.ts.map +1 -1
  203. package/dist/core/tools/write.js +1 -1
  204. package/dist/core/tools/write.js.map +1 -1
  205. package/dist/core/trust-manager.d.ts +31 -0
  206. package/dist/core/trust-manager.d.ts.map +1 -0
  207. package/dist/core/trust-manager.js +196 -0
  208. package/dist/core/trust-manager.js.map +1 -0
  209. package/dist/index.d.ts +12 -7
  210. package/dist/index.d.ts.map +1 -1
  211. package/dist/index.js +8 -4
  212. package/dist/index.js.map +1 -1
  213. package/dist/main.d.ts.map +1 -1
  214. package/dist/main.js +142 -30
  215. package/dist/main.js.map +1 -1
  216. package/dist/migrations.d.ts +3 -1
  217. package/dist/migrations.d.ts.map +1 -1
  218. package/dist/migrations.js +325 -7
  219. package/dist/migrations.js.map +1 -1
  220. package/dist/modes/index.d.ts +1 -1
  221. package/dist/modes/index.d.ts.map +1 -1
  222. package/dist/modes/index.js.map +1 -1
  223. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  224. package/dist/modes/interactive/components/bash-execution.js +2 -2
  225. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  226. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -5
  227. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  228. package/dist/modes/interactive/components/chat-message-renderer.js +5 -9
  229. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  230. package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
  231. package/dist/modes/interactive/components/chat-session-host.js +0 -3
  232. package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
  233. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  234. package/dist/modes/interactive/components/footer.js +6 -0
  235. package/dist/modes/interactive/components/footer.js.map +1 -1
  236. package/dist/modes/interactive/components/index.d.ts +1 -1
  237. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  238. package/dist/modes/interactive/components/index.js +1 -1
  239. package/dist/modes/interactive/components/index.js.map +1 -1
  240. package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  241. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  242. package/dist/modes/interactive/components/login-dialog.js +9 -16
  243. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  244. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  245. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  246. package/dist/modes/interactive/components/settings-selector.js +20 -0
  247. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  248. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  249. package/dist/modes/interactive/components/tool-execution.js +22 -0
  250. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  251. package/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  252. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
  253. package/dist/modes/interactive/components/trust-selector.js +85 -0
  254. package/dist/modes/interactive/components/trust-selector.js.map +1 -0
  255. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  256. package/dist/modes/interactive/components/user-message.js +1 -1
  257. package/dist/modes/interactive/components/user-message.js.map +1 -1
  258. package/dist/modes/interactive/interactive-mode.d.ts +9 -0
  259. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  260. package/dist/modes/interactive/interactive-mode.js +134 -36
  261. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  262. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  263. package/dist/modes/interactive/theme/theme.js +10 -0
  264. package/dist/modes/interactive/theme/theme.js.map +1 -1
  265. package/dist/modes/print-mode.d.ts.map +1 -1
  266. package/dist/modes/print-mode.js +1 -0
  267. package/dist/modes/print-mode.js.map +1 -1
  268. package/dist/modes/rpc/rpc-client.d.ts +4 -1
  269. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  270. package/dist/modes/rpc/rpc-client.js +52 -8
  271. package/dist/modes/rpc/rpc-client.js.map +1 -1
  272. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  273. package/dist/modes/rpc/rpc-mode.js +24 -5
  274. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  275. package/dist/modes/rpc/rpc-types.d.ts +1 -1
  276. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  277. package/dist/modes/rpc/rpc-types.js.map +1 -1
  278. package/dist/package-manager-cli.d.ts +6 -2
  279. package/dist/package-manager-cli.d.ts.map +1 -1
  280. package/dist/package-manager-cli.js +104 -10
  281. package/dist/package-manager-cli.js.map +1 -1
  282. package/dist/utils/changelog.d.ts +1 -0
  283. package/dist/utils/changelog.d.ts.map +1 -1
  284. package/dist/utils/changelog.js +72 -0
  285. package/dist/utils/changelog.js.map +1 -1
  286. package/dist/utils/deprecation.d.ts +4 -0
  287. package/dist/utils/deprecation.d.ts.map +1 -0
  288. package/dist/utils/deprecation.js +13 -0
  289. package/dist/utils/deprecation.js.map +1 -0
  290. package/dist/utils/git.d.ts.map +1 -1
  291. package/dist/utils/git.js +54 -22
  292. package/dist/utils/git.js.map +1 -1
  293. package/dist/utils/json.d.ts +3 -0
  294. package/dist/utils/json.d.ts.map +1 -0
  295. package/dist/utils/json.js +7 -0
  296. package/dist/utils/json.js.map +1 -0
  297. package/dist/utils/open-browser.d.ts +9 -0
  298. package/dist/utils/open-browser.d.ts.map +1 -0
  299. package/dist/utils/open-browser.js +22 -0
  300. package/dist/utils/open-browser.js.map +1 -0
  301. package/docs/compaction.md +210 -181
  302. package/docs/containerization.md +111 -0
  303. package/docs/custom-provider.md +9 -9
  304. package/docs/development.md +1 -1
  305. package/docs/docs.json +2 -0
  306. package/docs/extensions.md +71 -24
  307. package/docs/index.md +2 -0
  308. package/docs/json.md +3 -4
  309. package/docs/models.md +10 -10
  310. package/docs/packages.md +1 -1
  311. package/docs/prompt-templates.md +9 -2
  312. package/docs/providers.md +18 -5
  313. package/docs/quickstart.md +1 -0
  314. package/docs/rpc.md +3 -2
  315. package/docs/sdk.md +5 -0
  316. package/docs/security.md +56 -0
  317. package/docs/session-format.md +14 -23
  318. package/docs/sessions.md +11 -1
  319. package/docs/settings.md +23 -9
  320. package/docs/skills.md +1 -1
  321. package/docs/terminal-setup.md +44 -2
  322. package/docs/themes.md +1 -1
  323. package/docs/tmux.md +4 -2
  324. package/docs/tui.md +14 -5
  325. package/docs/usage.md +17 -3
  326. package/docs/workflows.md +11 -9
  327. package/examples/README.md +1 -1
  328. package/examples/extensions/README.md +9 -6
  329. package/examples/extensions/bash-spawn-hook.ts +1 -1
  330. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  331. package/examples/extensions/claude-rules.ts +1 -1
  332. package/examples/extensions/commands.ts +1 -1
  333. package/examples/extensions/custom-compaction.ts +43 -106
  334. package/examples/extensions/custom-header.ts +1 -1
  335. package/examples/extensions/custom-provider-anthropic/index.ts +3 -3
  336. package/examples/extensions/custom-provider-anthropic/package-lock.json +4 -4
  337. package/examples/extensions/custom-provider-anthropic/package.json +6 -6
  338. package/examples/extensions/custom-provider-gitlab-duo/index.ts +55 -4
  339. package/examples/extensions/custom-provider-gitlab-duo/package.json +3 -3
  340. package/examples/extensions/doom-overlay/README.md +1 -1
  341. package/examples/extensions/doom-overlay/index.ts +2 -2
  342. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  343. package/examples/extensions/gondolin/index.ts +523 -0
  344. package/examples/extensions/gondolin/package-lock.json +185 -0
  345. package/examples/extensions/gondolin/package.json +19 -0
  346. package/examples/extensions/handoff.ts +7 -45
  347. package/examples/extensions/hidden-thinking-label.ts +1 -1
  348. package/examples/extensions/inline-bash.ts +2 -2
  349. package/examples/extensions/input-transform-streaming.ts +39 -0
  350. package/examples/extensions/input-transform.ts +3 -3
  351. package/examples/extensions/interactive-shell.ts +2 -2
  352. package/examples/extensions/mac-system-theme.ts +2 -2
  353. package/examples/extensions/minimal-mode.ts +1 -1
  354. package/examples/extensions/modal-editor.ts +1 -1
  355. package/examples/extensions/model-status.ts +1 -1
  356. package/examples/extensions/overlay-qa-tests.ts +198 -179
  357. package/examples/extensions/overlay-test.ts +1 -1
  358. package/examples/extensions/pirate.ts +1 -1
  359. package/examples/extensions/preset.ts +14 -12
  360. package/examples/extensions/project-trust.ts +64 -0
  361. package/examples/extensions/prompt-customizer.ts +1 -1
  362. package/examples/extensions/qna.ts +1 -1
  363. package/examples/extensions/question.ts +1 -1
  364. package/examples/extensions/questionnaire.ts +1 -1
  365. package/examples/extensions/rainbow-editor.ts +1 -1
  366. package/examples/extensions/sandbox/index.ts +16 -14
  367. package/examples/extensions/sandbox/package-lock.json +90 -90
  368. package/examples/extensions/sandbox/package.json +17 -17
  369. package/examples/extensions/snake.ts +1 -1
  370. package/examples/extensions/space-invaders.ts +1 -1
  371. package/examples/extensions/ssh.ts +2 -2
  372. package/examples/extensions/subagent/README.md +13 -13
  373. package/examples/extensions/subagent/agents.ts +4 -2
  374. package/examples/extensions/subagent/index.ts +6 -6
  375. package/examples/extensions/summarize.ts +1 -1
  376. package/examples/extensions/tic-tac-toe.ts +1 -1
  377. package/examples/extensions/titlebar-spinner.ts +1 -1
  378. package/examples/extensions/todo.ts +1 -1
  379. package/examples/extensions/tool-override.ts +1 -1
  380. package/examples/extensions/tools.ts +6 -1
  381. package/examples/extensions/trigger-compact.ts +5 -4
  382. package/examples/extensions/with-deps/package-lock.json +4 -4
  383. package/examples/extensions/with-deps/package.json +7 -7
  384. package/examples/extensions/working-indicator.ts +4 -4
  385. package/examples/extensions/working-message-test.ts +1 -1
  386. package/examples/sdk/01-minimal.ts +1 -1
  387. package/examples/sdk/03-custom-prompt.ts +1 -1
  388. package/examples/sdk/04-skills.ts +1 -1
  389. package/examples/sdk/06-extensions.ts +2 -2
  390. package/examples/sdk/08-prompt-templates.ts +1 -1
  391. package/examples/sdk/09-api-keys-and-oauth.ts +2 -2
  392. package/examples/sdk/README.md +2 -2
  393. package/package.json +8 -8
  394. package/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -16
  395. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +0 -1
  396. package/dist/modes/interactive/components/compaction-summary-message.js +0 -43
  397. package/dist/modes/interactive/components/compaction-summary-message.js.map +0 -1
@@ -5,7 +5,7 @@
5
5
  * that lists all available slash commands in the current session.
6
6
  *
7
7
  * Usage:
8
- * 1. Copy this file to ~/.pi/agent/extensions/ or your project's .pi/extensions/
8
+ * 1. Copy this file to ~/.atomic/agent/extensions/ or your project's .atomic/extensions/ (legacy .pi/extensions/ also works)
9
9
  * 2. Use /commands to see available commands
10
10
  * 3. Use /commands extensions to filter by source
11
11
  */
@@ -1,127 +1,64 @@
1
1
  /**
2
- * Custom Compaction Extension
2
+ * Custom Compaction Deletion Policy Extension
3
3
  *
4
- * Replaces the default compaction behavior with a full summary of the entire context.
5
- * Instead of keeping the last 20k tokens of conversation turns, this extension:
6
- * 1. Summarizes ALL messages (messagesToSummarize + turnPrefixMessages)
7
- * 2. Discards all old turns completely, keeping only the summary
4
+ * Verbatim Compaction is deletion-only: extensions cannot replace history with a
5
+ * generated summary. This example shows how to provide an exact deletion request
6
+ * before Atomic's internal planner runs. Atomic still validates the requested
7
+ * entry IDs locally before appending a context_compaction entry.
8
8
  *
9
- * This example also demonstrates using a different model (Gemini Flash) for summarization,
10
- * which can be cheaper/faster than the main conversation model.
9
+ * This policy deletes older, unprotected, successful bash execution entries once
10
+ * they are large enough to matter. If no safe candidates are present, it returns
11
+ * nothing and Atomic uses its default deletion planner.
11
12
  *
12
13
  * Usage:
13
- * pi --extension examples/extensions/custom-compaction.ts
14
+ * atomic --extension examples/extensions/custom-compaction.ts
14
15
  */
15
16
 
16
- import { complete } from "@earendil-works/pi-ai";
17
- import type { ExtensionAPI } from "@bastani/atomic";
18
- import { convertToLlm, serializeConversation } from "@bastani/atomic";
17
+ import type { ContextDeletionRequest, ExtensionAPI } from "@bastani/atomic";
18
+
19
+ const MIN_BASH_OUTPUT_TOKENS = 250;
20
+ const MAX_DELETIONS_PER_RUN = 12;
19
21
 
20
22
  export default function (pi: ExtensionAPI) {
21
23
  pi.on("session_before_compact", async (event, ctx) => {
22
- ctx.ui.notify("Custom compaction extension triggered", "info");
23
-
24
- const { preparation, branchEntries: _, signal } = event;
25
- const { messagesToSummarize, turnPrefixMessages, tokensBefore, firstKeptEntryId, previousSummary } = preparation;
26
-
27
- // Use Gemini Flash for summarization (cheaper/faster than most conversation models)
28
- const model = ctx.modelRegistry.find("google", "gemini-2.5-flash");
29
- if (!model) {
30
- ctx.ui.notify(`Could not find Gemini Flash model, using default compaction`, "warning");
24
+ const { preparation, reason, mode } = event;
25
+ const candidates = preparation.transcript.entries
26
+ .filter((entry) => !entry.protected)
27
+ .filter((entry) => entry.message.role === "bashExecution" && entry.message.exitCode === 0)
28
+ .filter((entry) => entry.tokenEstimate >= MIN_BASH_OUTPUT_TOKENS)
29
+ .slice(0, MAX_DELETIONS_PER_RUN);
30
+
31
+ if (candidates.length === 0) {
32
+ if (ctx.hasUI) {
33
+ ctx.ui.notify("Custom compaction policy found no safe bash output to delete; using default planner", "info");
34
+ }
31
35
  return;
32
36
  }
33
37
 
34
- // Resolve request auth for the summarization model
35
- const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
36
- if (!auth.ok) {
37
- ctx.ui.notify(`Compaction auth failed: ${auth.error}`, "warning");
38
- return;
39
- }
40
- if (!auth.apiKey) {
41
- ctx.ui.notify(`No API key for ${model.provider}, using default compaction`, "warning");
42
- return;
38
+ const deletions: ContextDeletionRequest["deletions"] = candidates.map((entry) => ({
39
+ kind: "entry",
40
+ entryId: entry.entryId,
41
+ rationale: "Large successful bash output selected by custom compaction policy",
42
+ }));
43
+
44
+ if (ctx.hasUI) {
45
+ const tokenEstimate = candidates.reduce((sum, entry) => sum + entry.tokenEstimate, 0);
46
+ ctx.ui.notify(
47
+ `Custom compaction (${reason ?? "manual"}/${mode}): requesting ${deletions.length} deletion(s), about ${tokenEstimate.toLocaleString()} tokens`,
48
+ "info",
49
+ );
43
50
  }
44
51
 
45
- // Combine all messages for full summary
46
- const allMessages = [...messagesToSummarize, ...turnPrefixMessages];
52
+ return {
53
+ deletionRequest: { deletions },
54
+ };
55
+ });
47
56
 
57
+ pi.on("session_compact", async (event, ctx) => {
58
+ if (!ctx.hasUI || !event.fromExtension) return;
48
59
  ctx.ui.notify(
49
- `Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${model.id}...`,
60
+ `Custom compaction policy deleted ${event.result.stats.objectsDeleted} object(s)`,
50
61
  "info",
51
62
  );
52
-
53
- // Convert messages to readable text format
54
- const conversationText = serializeConversation(convertToLlm(allMessages));
55
-
56
- // Include previous summary context if available
57
- const previousContext = previousSummary ? `\n\nPrevious session summary for context:\n${previousSummary}` : "";
58
-
59
- // Build messages that ask for a comprehensive summary
60
- const summaryMessages = [
61
- {
62
- role: "user" as const,
63
- content: [
64
- {
65
- type: "text" as const,
66
- text: `You are a conversation summarizer. Create a comprehensive summary of this conversation that captures:${previousContext}
67
-
68
- 1. The main goals and objectives discussed
69
- 2. Key decisions made and their rationale
70
- 3. Important code changes, file modifications, or technical details
71
- 4. Current state of any ongoing work
72
- 5. Any blockers, issues, or open questions
73
- 6. Next steps that were planned or suggested
74
-
75
- Be thorough but concise. The summary will replace the ENTIRE conversation history, so include all information needed to continue the work effectively.
76
-
77
- Format the summary as structured markdown with clear sections.
78
-
79
- <conversation>
80
- ${conversationText}
81
- </conversation>`,
82
- },
83
- ],
84
- timestamp: Date.now(),
85
- },
86
- ];
87
-
88
- try {
89
- // Pass signal to honor abort requests (e.g., user cancels compaction)
90
- const response = await complete(
91
- model,
92
- { messages: summaryMessages },
93
- {
94
- apiKey: auth.apiKey,
95
- headers: auth.headers,
96
- maxTokens: 8192,
97
- signal,
98
- },
99
- );
100
-
101
- const summary = response.content
102
- .filter((c): c is { type: "text"; text: string } => c.type === "text")
103
- .map((c) => c.text)
104
- .join("\n");
105
-
106
- if (!summary.trim()) {
107
- if (!signal.aborted) ctx.ui.notify("Compaction summary was empty, using default compaction", "warning");
108
- return;
109
- }
110
-
111
- // Return compaction content - SessionManager adds id/parentId
112
- // Use firstKeptEntryId from preparation to keep recent messages
113
- return {
114
- compaction: {
115
- summary,
116
- firstKeptEntryId,
117
- tokensBefore,
118
- },
119
- };
120
- } catch (error) {
121
- const message = error instanceof Error ? error.message : String(error);
122
- ctx.ui.notify(`Compaction failed: ${message}`, "error");
123
- // Fall back to default compaction on error
124
- return;
125
- }
126
63
  });
127
64
  }
@@ -47,7 +47,7 @@ function getPiMascot(theme: Theme): string[] {
47
47
  export default function (pi: ExtensionAPI) {
48
48
  // Set custom header immediately on load (if UI is available)
49
49
  pi.on("session_start", async (_event, ctx) => {
50
- if (ctx.hasUI) {
50
+ if (ctx.mode === "tui") {
51
51
  ctx.ui.setHeader((_tui, theme) => {
52
52
  return {
53
53
  render(_width: number): string[] {
@@ -13,10 +13,10 @@
13
13
  * cd packages/coding-agent/examples/extensions/custom-provider && npm install
14
14
  *
15
15
  * # With OAuth (run /login custom-anthropic first)
16
- * pi -e ./packages/coding-agent/examples/extensions/custom-provider
16
+ * atomic -e ./packages/coding-agent/examples/extensions/custom-provider
17
17
  *
18
18
  * # With API key
19
- * CUSTOM_ANTHROPIC_API_KEY=sk-ant-... pi -e ./packages/coding-agent/examples/extensions/custom-provider
19
+ * CUSTOM_ANTHROPIC_API_KEY=sk-ant-... atomic -e ./packages/coding-agent/examples/extensions/custom-provider
20
20
  *
21
21
  * Then use /model to select custom-anthropic/claude-sonnet-4-5
22
22
  */
@@ -568,7 +568,7 @@ function streamCustomAnthropic(
568
568
  export default function (pi: ExtensionAPI) {
569
569
  pi.registerProvider("custom-anthropic", {
570
570
  baseUrl: "https://api.anthropic.com",
571
- apiKey: "CUSTOM_ANTHROPIC_API_KEY",
571
+ apiKey: "$CUSTOM_ANTHROPIC_API_KEY",
572
572
  api: "custom-anthropic-api",
573
573
 
574
574
  models: [
@@ -1,12 +1,12 @@
1
1
  {
2
- "name": "pi-extension-custom-provider",
3
- "version": "0.74.0",
2
+ "name": "atomic-extension-custom-provider-anthropic",
3
+ "version": "0.79.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
- "name": "pi-extension-custom-provider",
9
- "version": "0.74.0",
8
+ "name": "atomic-extension-custom-provider-anthropic",
9
+ "version": "0.79.1",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.52.0"
12
12
  }
@@ -1,19 +1,19 @@
1
1
  {
2
- "name": "pi-extension-custom-provider-anthropic",
2
+ "name": "atomic-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.74.0",
4
+ "version": "0.79.1",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
8
8
  "build": "echo 'nothing to build'",
9
9
  "check": "echo 'nothing to check'"
10
10
  },
11
- "pi": {
11
+ "dependencies": {
12
+ "@anthropic-ai/sdk": "^0.52.0"
13
+ },
14
+ "atomic": {
12
15
  "extensions": [
13
16
  "./index.ts"
14
17
  ]
15
- },
16
- "dependencies": {
17
- "@anthropic-ai/sdk": "^0.52.0"
18
18
  }
19
19
  }
@@ -5,7 +5,7 @@
5
5
  * Delegates to pi-ai's built-in Anthropic and OpenAI streaming implementations.
6
6
  *
7
7
  * Usage:
8
- * pi -e ./packages/coding-agent/examples/extensions/custom-provider-gitlab-duo
8
+ * atomic -e ./packages/coding-agent/examples/extensions/custom-provider-gitlab-duo
9
9
  * # Then /login gitlab-duo, or set GITLAB_TOKEN=glpat-...
10
10
  */
11
11
 
@@ -20,6 +20,7 @@ import {
20
20
  type SimpleStreamOptions,
21
21
  streamSimpleAnthropic,
22
22
  streamSimpleOpenAIResponses,
23
+ type ThinkingLevelMap,
23
24
  } from "@earendil-works/pi-ai";
24
25
  import type { ExtensionAPI } from "@bastani/atomic";
25
26
 
@@ -49,6 +50,7 @@ interface GitLabModel {
49
50
  backend: Backend;
50
51
  baseUrl: string;
51
52
  reasoning: boolean;
53
+ thinkingLevelMap?: ThinkingLevelMap;
52
54
  input: ("text" | "image")[];
53
55
  cost: { input: number; output: number; cacheRead: number; cacheWrite: number };
54
56
  contextWindow: number;
@@ -57,12 +59,37 @@ interface GitLabModel {
57
59
 
58
60
  export const MODELS: GitLabModel[] = [
59
61
  // Anthropic
62
+ {
63
+ id: "claude-opus-4-8",
64
+ name: "Claude Opus 4.8",
65
+ backend: "anthropic",
66
+ baseUrl: ANTHROPIC_PROXY_URL,
67
+ reasoning: true,
68
+ thinkingLevelMap: { xhigh: "max" },
69
+ input: ["text", "image"],
70
+ cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
71
+ contextWindow: 1000000,
72
+ maxTokens: 128000,
73
+ },
74
+ {
75
+ id: "claude-sonnet-4-6",
76
+ name: "Claude Sonnet 4.6",
77
+ backend: "anthropic",
78
+ baseUrl: ANTHROPIC_PROXY_URL,
79
+ reasoning: true,
80
+ thinkingLevelMap: { xhigh: "max" },
81
+ input: ["text", "image"],
82
+ cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
83
+ contextWindow: 1000000,
84
+ maxTokens: 64000,
85
+ },
60
86
  {
61
87
  id: "claude-opus-4-5-20251101",
62
88
  name: "Claude Opus 4.5",
63
89
  backend: "anthropic",
64
90
  baseUrl: ANTHROPIC_PROXY_URL,
65
91
  reasoning: true,
92
+ thinkingLevelMap: { xhigh: "max" },
66
93
  input: ["text", "image"],
67
94
  cost: { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
68
95
  contextWindow: 200000,
@@ -74,6 +101,7 @@ export const MODELS: GitLabModel[] = [
74
101
  backend: "anthropic",
75
102
  baseUrl: ANTHROPIC_PROXY_URL,
76
103
  reasoning: true,
104
+ thinkingLevelMap: { xhigh: "max" },
77
105
  input: ["text", "image"],
78
106
  cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
79
107
  contextWindow: 200000,
@@ -85,12 +113,24 @@ export const MODELS: GitLabModel[] = [
85
113
  backend: "anthropic",
86
114
  baseUrl: ANTHROPIC_PROXY_URL,
87
115
  reasoning: true,
116
+ thinkingLevelMap: { xhigh: "max" },
88
117
  input: ["text", "image"],
89
118
  cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
90
119
  contextWindow: 200000,
91
120
  maxTokens: 8192,
92
121
  },
93
122
  // OpenAI (all use Responses API)
123
+ {
124
+ id: "gpt-5.5-2026-04-23",
125
+ name: "GPT-5.5",
126
+ backend: "openai",
127
+ baseUrl: OPENAI_PROXY_URL,
128
+ reasoning: true,
129
+ input: ["text", "image"],
130
+ cost: { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 },
131
+ contextWindow: 272000,
132
+ maxTokens: 128000,
133
+ },
94
134
  {
95
135
  id: "gpt-5.1-2025-11-13",
96
136
  name: "GPT-5.1",
@@ -285,7 +325,17 @@ export function streamGitLabDuo(
285
325
 
286
326
  const innerStream =
287
327
  cfg.backend === "anthropic"
288
- ? streamSimpleAnthropic(modelWithBaseUrl as Model<"anthropic-messages">, context, streamOptions)
328
+ ? streamSimpleAnthropic(
329
+ {
330
+ ...(modelWithBaseUrl as Model<"anthropic-messages">),
331
+ compat: {
332
+ ...(modelWithBaseUrl as Model<"anthropic-messages">).compat,
333
+ forceAdaptiveThinking: true,
334
+ },
335
+ },
336
+ context,
337
+ streamOptions,
338
+ )
289
339
  : streamSimpleOpenAIResponses(modelWithBaseUrl as Model<"openai-responses">, context, streamOptions);
290
340
 
291
341
  for await (const event of innerStream) stream.push(event);
@@ -327,12 +377,13 @@ export function streamGitLabDuo(
327
377
  export default function (pi: ExtensionAPI) {
328
378
  pi.registerProvider("gitlab-duo", {
329
379
  baseUrl: AI_GATEWAY_URL,
330
- apiKey: "GITLAB_TOKEN",
380
+ apiKey: "$GITLAB_TOKEN",
331
381
  api: "gitlab-duo-api",
332
- models: MODELS.map(({ id, name, reasoning, input, cost, contextWindow, maxTokens }) => ({
382
+ models: MODELS.map(({ id, name, reasoning, thinkingLevelMap, input, cost, contextWindow, maxTokens }) => ({
333
383
  id,
334
384
  name,
335
385
  reasoning,
386
+ thinkingLevelMap,
336
387
  input,
337
388
  cost,
338
389
  contextWindow,
@@ -1,14 +1,14 @@
1
1
  {
2
- "name": "pi-extension-custom-provider-gitlab-duo",
2
+ "name": "atomic-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.74.0",
4
+ "version": "0.79.1",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
8
8
  "build": "echo 'nothing to build'",
9
9
  "check": "echo 'nothing to check'"
10
10
  },
11
- "pi": {
11
+ "atomic": {
12
12
  "extensions": [
13
13
  "./index.ts"
14
14
  ]
@@ -5,7 +5,7 @@ Play DOOM as an overlay in pi. Demonstrates that the overlay system can handle r
5
5
  ## Usage
6
6
 
7
7
  ```bash
8
- pi --extension ./examples/extensions/doom-overlay
8
+ atomic --extension ./examples/extensions/doom-overlay
9
9
  ```
10
10
 
11
11
  Then run:
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * DOOM Overlay Demo - Play DOOM as an overlay
3
3
  *
4
- * Usage: pi --extension ./examples/extensions/doom-overlay
4
+ * Usage: atomic --extension ./examples/extensions/doom-overlay
5
5
  *
6
6
  * Commands:
7
7
  * /doom-overlay - Play DOOM in an overlay (Q to pause/exit)
@@ -23,7 +23,7 @@ export default function (pi: ExtensionAPI) {
23
23
  description: "Play DOOM as an overlay. Q to pause and exit.",
24
24
 
25
25
  handler: async (args, ctx) => {
26
- if (!ctx.hasUI) {
26
+ if (ctx.mode !== "tui") {
27
27
  ctx.ui.notify("DOOM requires interactive mode", "error");
28
28
  return;
29
29
  }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Merge and Resolve
3
+ *
4
+ * Keeps the working branch up to date with its upstream tracking ref.
5
+ * After each agent turn, fetches and merges. Clean merges complete
6
+ * silently. When conflicts arise, the working tree is left dirty and
7
+ * the agent receives a follow-up message listing each conflict block
8
+ * with file, line range, and ours/theirs sections so it can resolve them.
9
+ * Also re-sends unresolved conflicts from a previous incomplete merge.
10
+ *
11
+ * Start Atomic with this extension:
12
+ * atomic -e ./examples/extensions/git-merge-and-resolve.ts
13
+ */
14
+ import { createReadStream } from "node:fs";
15
+ import { join } from "node:path";
16
+ import { createInterface } from "node:readline";
17
+ import type { ExtensionAPI } from "@bastani/atomic";
18
+
19
+ interface ConflictBlock {
20
+ file: string;
21
+ startLine: number;
22
+ separatorLine: number;
23
+ endLine: number;
24
+ }
25
+
26
+ /** Parse conflict markers from working tree files with unmerged paths. */
27
+ async function findConflicts(pi: ExtensionAPI, cwd: string): Promise<ConflictBlock[]> {
28
+ const { stdout, code } = await pi.exec("git", ["diff", "--name-only", "--diff-filter=U"]);
29
+ if (code !== 0 || !stdout.trim()) return [];
30
+
31
+ const blocks: ConflictBlock[] = [];
32
+ for (const file of stdout.trim().split("\n")) {
33
+ try {
34
+ const rl = createInterface({ input: createReadStream(join(cwd, file), "utf-8") });
35
+ let lineNo = 0;
36
+ let blockStart: number | undefined;
37
+ let separatorLine: number | undefined;
38
+ for await (const line of rl) {
39
+ lineNo++;
40
+ if (line.startsWith("<<<<<<<")) {
41
+ blockStart = lineNo;
42
+ separatorLine = undefined;
43
+ } else if (line.startsWith("=======") && blockStart !== undefined) {
44
+ separatorLine = lineNo;
45
+ } else if (line.startsWith(">>>>>>>") && blockStart !== undefined && separatorLine !== undefined) {
46
+ blocks.push({ file, startLine: blockStart, separatorLine, endLine: lineNo });
47
+ blockStart = undefined;
48
+ separatorLine = undefined;
49
+ }
50
+ }
51
+ } catch {}
52
+ }
53
+ return blocks;
54
+ }
55
+
56
+ function formatRange(start: number, end: number): string {
57
+ if (start > end) return "empty";
58
+ if (start === end) return `${start}`;
59
+ return `${start}-${end}`;
60
+ }
61
+
62
+ function formatConflicts(ref: string, blocks: ConflictBlock[]): string {
63
+ const lines = [`Merged ${ref} with conflicts:`, ""];
64
+ for (const b of blocks) {
65
+ const ours = formatRange(b.startLine + 1, b.separatorLine - 1);
66
+ const theirs = formatRange(b.separatorLine + 1, b.endLine - 1);
67
+ lines.push(` ${b.file}:${b.startLine}-${b.endLine} (ours ${ours}, theirs ${theirs})`);
68
+ }
69
+ lines.push("", "Resolve these conflicts.");
70
+ return lines.join("\n");
71
+ }
72
+
73
+ export default function (pi: ExtensionAPI) {
74
+ pi.on("agent_end", async (_event, ctx) => {
75
+ const { code: revParseCode } = await pi.exec("git", ["rev-parse", "--git-dir"]);
76
+ if (revParseCode !== 0) return;
77
+
78
+ let ref = "MERGE_HEAD";
79
+
80
+ // If not already in a merge, attempt one
81
+ const { code: mergeHeadCode } = await pi.exec("git", ["rev-parse", "MERGE_HEAD"]);
82
+ if (mergeHeadCode !== 0) {
83
+ // Only attempt a new merge if the working tree is clean
84
+ const { stdout: status } = await pi.exec("git", ["status", "--porcelain"]);
85
+ if (status.trim()) return;
86
+
87
+ const { stdout: upstream, code: upstreamCode } = await pi.exec("git", [
88
+ "rev-parse",
89
+ "--abbrev-ref",
90
+ "--symbolic-full-name",
91
+ "@{u}",
92
+ ]);
93
+ if (upstreamCode !== 0) return;
94
+
95
+ ref = upstream.trim();
96
+ const remote = ref.split("/")[0];
97
+ ctx.ui.notify(`git-merge-and-resolve: fetching ${remote}, merging ${ref}`, "info");
98
+
99
+ const { code: fetchCode, stderr: fetchErr } = await pi.exec("git", ["fetch", remote]);
100
+ if (fetchCode !== 0) {
101
+ ctx.ui.notify(`git-merge-and-resolve: fetch failed: ${fetchErr.trim()}`, "warning");
102
+ return;
103
+ }
104
+
105
+ const { code: mergeCode } = await pi.exec("git", ["merge", "--no-ff", ref]);
106
+ if (mergeCode === 0) return;
107
+ }
108
+
109
+ // Either we just merged with conflicts, or we were already in an unfinished merge
110
+ const conflicts = await findConflicts(pi, ctx.cwd);
111
+ if (conflicts.length === 0) return;
112
+
113
+ pi.sendUserMessage(formatConflicts(ref, conflicts), { deliverAs: "followUp" });
114
+ });
115
+ }