@epoch-ai/cli 2.2.5 → 2.2.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 (711) hide show
  1. package/.artifacts/unit/junit.xml +2823 -0
  2. package/.project-map/backups/20260530_223453/.project-map.json +90101 -0
  3. package/.project-map/backups/20260530_223507/.project-map.json +90101 -0
  4. package/.project-map/backups/20260530_223512/.project-map.json +90101 -0
  5. package/.project-map/backups/20260530_223512/map.toon +666 -0
  6. package/.project-map/backups/20260530_223516/.project-map.json +90101 -0
  7. package/.project-map/backups/20260530_223516/map.toon +666 -0
  8. package/.project-map/backups/20260530_223520/.project-map.json +90101 -0
  9. package/.project-map/backups/20260530_223520/map.toon +666 -0
  10. package/AGENTS.md +47 -0
  11. package/BUN_SHELL_MIGRATION_PLAN.md +136 -0
  12. package/Dockerfile +18 -0
  13. package/README.md +15 -0
  14. package/bunfig.toml +7 -0
  15. package/drizzle.config.ts +10 -0
  16. package/git +0 -0
  17. package/migration/20260127222353_familiar_lady_ursula/migration.sql +90 -0
  18. package/migration/20260127222353_familiar_lady_ursula/snapshot.json +796 -0
  19. package/migration/20260211171708_add_project_commands/migration.sql +1 -0
  20. package/migration/20260211171708_add_project_commands/snapshot.json +806 -0
  21. package/migration/20260213144116_wakeful_the_professor/migration.sql +11 -0
  22. package/migration/20260213144116_wakeful_the_professor/snapshot.json +897 -0
  23. package/migration/20260225215848_workspace/migration.sql +7 -0
  24. package/migration/20260225215848_workspace/snapshot.json +959 -0
  25. package/migration/20260227213759_add_session_workspace_id/migration.sql +2 -0
  26. package/migration/20260227213759_add_session_workspace_id/snapshot.json +983 -0
  27. package/migration/20260228203230_blue_harpoon/migration.sql +17 -0
  28. package/migration/20260228203230_blue_harpoon/snapshot.json +1102 -0
  29. package/migration/20260303231226_add_workspace_fields/migration.sql +5 -0
  30. package/migration/20260303231226_add_workspace_fields/snapshot.json +1013 -0
  31. package/migration/20260309230000_move_org_to_state/migration.sql +3 -0
  32. package/migration/20260309230000_move_org_to_state/snapshot.json +1156 -0
  33. package/migration/20260312043431_session_message_cursor/migration.sql +4 -0
  34. package/migration/20260312043431_session_message_cursor/snapshot.json +1168 -0
  35. package/migration/20260323234822_events/migration.sql +13 -0
  36. package/migration/20260323234822_events/snapshot.json +1271 -0
  37. package/migration/20260418092949_add_yolo_to_session/migration.sql +2 -0
  38. package/migration/20260418092949_add_yolo_to_session/snapshot.json +1199 -0
  39. package/migration/20260419120000_add_intervention_to_session/migration.sql +2 -0
  40. package/package.json +179 -18
  41. package/parsers-config.ts +290 -0
  42. package/script/build-node.ts +71 -0
  43. package/script/build.ts +255 -0
  44. package/script/check-migrations.ts +16 -0
  45. package/script/fix-node-pty.ts +28 -0
  46. package/script/publish.ts +182 -0
  47. package/script/schema.ts +63 -0
  48. package/script/seed-e2e.ts +60 -0
  49. package/script/upgrade-opentui.ts +64 -0
  50. package/specs/effect-migration.md +310 -0
  51. package/specs/tui-plugins.md +436 -0
  52. package/specs/v2.md +14 -0
  53. package/src/account/account.sql.ts +39 -0
  54. package/src/account/index.ts +465 -0
  55. package/src/account/repo.ts +163 -0
  56. package/src/account/schema.ts +91 -0
  57. package/src/acp/README.md +174 -0
  58. package/src/acp/agent.ts +1847 -0
  59. package/src/acp/session.ts +116 -0
  60. package/src/acp/types.ts +24 -0
  61. package/src/agent/agent.ts +445 -0
  62. package/src/agent/generate.txt +75 -0
  63. package/src/agent/prompt/compaction.txt +15 -0
  64. package/src/agent/prompt/explore.txt +9 -0
  65. package/src/agent/prompt/summary.txt +11 -0
  66. package/src/agent/prompt/title.txt +44 -0
  67. package/src/auth/index.ts +110 -0
  68. package/src/bus/bus-event.ts +40 -0
  69. package/src/bus/global.ts +10 -0
  70. package/src/bus/index.ts +232 -0
  71. package/src/cli/bootstrap.ts +17 -0
  72. package/src/cli/cmd/account.ts +257 -0
  73. package/src/cli/cmd/acp.ts +70 -0
  74. package/src/cli/cmd/agent.ts +245 -0
  75. package/src/cli/cmd/cmd.ts +7 -0
  76. package/src/cli/cmd/db.ts +119 -0
  77. package/src/cli/cmd/debug/agent.ts +167 -0
  78. package/src/cli/cmd/debug/config.ts +16 -0
  79. package/src/cli/cmd/debug/file.ts +97 -0
  80. package/src/cli/cmd/debug/index.ts +48 -0
  81. package/src/cli/cmd/debug/lsp.ts +53 -0
  82. package/src/cli/cmd/debug/ripgrep.ts +87 -0
  83. package/src/cli/cmd/debug/scrap.ts +16 -0
  84. package/src/cli/cmd/debug/skill.ts +16 -0
  85. package/src/cli/cmd/debug/snapshot.ts +52 -0
  86. package/src/cli/cmd/export.ts +89 -0
  87. package/src/cli/cmd/generate.ts +38 -0
  88. package/src/cli/cmd/github.ts +1639 -0
  89. package/src/cli/cmd/import.ts +169 -0
  90. package/src/cli/cmd/mcp.ts +754 -0
  91. package/src/cli/cmd/models.ts +78 -0
  92. package/src/cli/cmd/plug.ts +233 -0
  93. package/src/cli/cmd/pr.ts +127 -0
  94. package/src/cli/cmd/providers.ts +478 -0
  95. package/src/cli/cmd/run.ts +681 -0
  96. package/src/cli/cmd/serve.ts +24 -0
  97. package/src/cli/cmd/session.ts +159 -0
  98. package/src/cli/cmd/stats.ts +410 -0
  99. package/src/cli/cmd/tui/app.tsx +945 -0
  100. package/src/cli/cmd/tui/attach.ts +88 -0
  101. package/src/cli/cmd/tui/component/border.tsx +21 -0
  102. package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
  103. package/src/cli/cmd/tui/component/dialog-command.tsx +171 -0
  104. package/src/cli/cmd/tui/component/dialog-console-org.tsx +103 -0
  105. package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
  106. package/src/cli/cmd/tui/component/dialog-model.tsx +190 -0
  107. package/src/cli/cmd/tui/component/dialog-provider.tsx +364 -0
  108. package/src/cli/cmd/tui/component/dialog-session-list.tsx +108 -0
  109. package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
  110. package/src/cli/cmd/tui/component/dialog-skill.tsx +36 -0
  111. package/src/cli/cmd/tui/component/dialog-stash.tsx +87 -0
  112. package/src/cli/cmd/tui/component/dialog-status.tsx +168 -0
  113. package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
  114. package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
  115. package/src/cli/cmd/tui/component/dialog-variant.tsx +39 -0
  116. package/src/cli/cmd/tui/component/dialog-workspace-list.tsx +320 -0
  117. package/src/cli/cmd/tui/component/error-component.tsx +92 -0
  118. package/src/cli/cmd/tui/component/logo.tsx +85 -0
  119. package/src/cli/cmd/tui/component/plugin-route-missing.tsx +14 -0
  120. package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +672 -0
  121. package/src/cli/cmd/tui/component/prompt/frecency.tsx +90 -0
  122. package/src/cli/cmd/tui/component/prompt/history.tsx +109 -0
  123. package/src/cli/cmd/tui/component/prompt/index.tsx +1348 -0
  124. package/src/cli/cmd/tui/component/prompt/part.ts +16 -0
  125. package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
  126. package/src/cli/cmd/tui/component/spinner.tsx +24 -0
  127. package/src/cli/cmd/tui/component/startup-loading.tsx +63 -0
  128. package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
  129. package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
  130. package/src/cli/cmd/tui/component/workspace/dialog-session-list.tsx +151 -0
  131. package/src/cli/cmd/tui/context/args.tsx +15 -0
  132. package/src/cli/cmd/tui/context/directory.ts +13 -0
  133. package/src/cli/cmd/tui/context/exit.tsx +60 -0
  134. package/src/cli/cmd/tui/context/helper.tsx +25 -0
  135. package/src/cli/cmd/tui/context/keybind.tsx +105 -0
  136. package/src/cli/cmd/tui/context/kv.tsx +52 -0
  137. package/src/cli/cmd/tui/context/local.tsx +456 -0
  138. package/src/cli/cmd/tui/context/plugin-keybinds.ts +41 -0
  139. package/src/cli/cmd/tui/context/prompt.tsx +18 -0
  140. package/src/cli/cmd/tui/context/route.tsx +52 -0
  141. package/src/cli/cmd/tui/context/sdk.tsx +115 -0
  142. package/src/cli/cmd/tui/context/sync.tsx +516 -0
  143. package/src/cli/cmd/tui/context/theme/aura.json +69 -0
  144. package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
  145. package/src/cli/cmd/tui/context/theme/carbonfox.json +248 -0
  146. package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
  147. package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
  148. package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
  149. package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
  150. package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
  151. package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
  152. package/src/cli/cmd/tui/context/theme/epochcli.json +245 -0
  153. package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
  154. package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
  155. package/src/cli/cmd/tui/context/theme/github.json +233 -0
  156. package/src/cli/cmd/tui/context/theme/gruvbox.json +242 -0
  157. package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
  158. package/src/cli/cmd/tui/context/theme/lucent-orng.json +237 -0
  159. package/src/cli/cmd/tui/context/theme/material.json +235 -0
  160. package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
  161. package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
  162. package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
  163. package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
  164. package/src/cli/cmd/tui/context/theme/nord.json +223 -0
  165. package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
  166. package/src/cli/cmd/tui/context/theme/orng.json +249 -0
  167. package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
  168. package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
  169. package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
  170. package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
  171. package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
  172. package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
  173. package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
  174. package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
  175. package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
  176. package/src/cli/cmd/tui/context/theme.tsx +1236 -0
  177. package/src/cli/cmd/tui/context/tui-config.tsx +9 -0
  178. package/src/cli/cmd/tui/event.ts +48 -0
  179. package/src/cli/cmd/tui/feature-plugins/home/footer.tsx +93 -0
  180. package/src/cli/cmd/tui/feature-plugins/home/tips-view.tsx +145 -0
  181. package/src/cli/cmd/tui/feature-plugins/home/tips.tsx +50 -0
  182. package/src/cli/cmd/tui/feature-plugins/sidebar/context.tsx +82 -0
  183. package/src/cli/cmd/tui/feature-plugins/sidebar/files.tsx +62 -0
  184. package/src/cli/cmd/tui/feature-plugins/sidebar/footer.tsx +93 -0
  185. package/src/cli/cmd/tui/feature-plugins/sidebar/lsp.tsx +66 -0
  186. package/src/cli/cmd/tui/feature-plugins/sidebar/mcp.tsx +96 -0
  187. package/src/cli/cmd/tui/feature-plugins/sidebar/todo.tsx +48 -0
  188. package/src/cli/cmd/tui/feature-plugins/system/plugins.tsx +270 -0
  189. package/src/cli/cmd/tui/plugin/api.tsx +397 -0
  190. package/src/cli/cmd/tui/plugin/index.ts +3 -0
  191. package/src/cli/cmd/tui/plugin/internal.ts +27 -0
  192. package/src/cli/cmd/tui/plugin/runtime.ts +1031 -0
  193. package/src/cli/cmd/tui/plugin/slots.tsx +60 -0
  194. package/src/cli/cmd/tui/routes/home.tsx +94 -0
  195. package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +65 -0
  196. package/src/cli/cmd/tui/routes/session/dialog-message.tsx +110 -0
  197. package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +26 -0
  198. package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
  199. package/src/cli/cmd/tui/routes/session/footer.tsx +91 -0
  200. package/src/cli/cmd/tui/routes/session/index.tsx +2161 -0
  201. package/src/cli/cmd/tui/routes/session/permission.tsx +691 -0
  202. package/src/cli/cmd/tui/routes/session/question.tsx +468 -0
  203. package/src/cli/cmd/tui/routes/session/sidebar.tsx +70 -0
  204. package/src/cli/cmd/tui/routes/session/subagent-footer.tsx +131 -0
  205. package/src/cli/cmd/tui/thread.ts +241 -0
  206. package/src/cli/cmd/tui/ui/dialog-alert.tsx +59 -0
  207. package/src/cli/cmd/tui/ui/dialog-confirm.tsx +89 -0
  208. package/src/cli/cmd/tui/ui/dialog-export-options.tsx +211 -0
  209. package/src/cli/cmd/tui/ui/dialog-help.tsx +40 -0
  210. package/src/cli/cmd/tui/ui/dialog-prompt.tsx +115 -0
  211. package/src/cli/cmd/tui/ui/dialog-select.tsx +417 -0
  212. package/src/cli/cmd/tui/ui/dialog.tsx +192 -0
  213. package/src/cli/cmd/tui/ui/link.tsx +28 -0
  214. package/src/cli/cmd/tui/ui/spinner.ts +368 -0
  215. package/src/cli/cmd/tui/ui/toast.tsx +100 -0
  216. package/src/cli/cmd/tui/util/clipboard.ts +192 -0
  217. package/src/cli/cmd/tui/util/editor.ts +37 -0
  218. package/src/cli/cmd/tui/util/model.ts +23 -0
  219. package/src/cli/cmd/tui/util/provider-origin.ts +20 -0
  220. package/src/cli/cmd/tui/util/scroll.ts +23 -0
  221. package/src/cli/cmd/tui/util/selection.ts +25 -0
  222. package/src/cli/cmd/tui/util/signal.ts +7 -0
  223. package/src/cli/cmd/tui/util/terminal.ts +114 -0
  224. package/src/cli/cmd/tui/util/transcript.ts +112 -0
  225. package/src/cli/cmd/tui/win32.ts +129 -0
  226. package/src/cli/cmd/tui/worker.ts +195 -0
  227. package/src/cli/cmd/uninstall.ts +353 -0
  228. package/src/cli/cmd/upgrade.ts +73 -0
  229. package/src/cli/cmd/web.ts +81 -0
  230. package/src/cli/effect/prompt.ts +25 -0
  231. package/src/cli/error.ts +46 -0
  232. package/src/cli/heap.ts +59 -0
  233. package/src/cli/logo.ts +6 -0
  234. package/src/cli/network.ts +60 -0
  235. package/src/cli/ui.ts +133 -0
  236. package/src/cli/upgrade.ts +31 -0
  237. package/src/command/index.ts +197 -0
  238. package/src/command/template/initialize.txt +66 -0
  239. package/src/command/template/review.txt +101 -0
  240. package/src/config/config.ts +1610 -0
  241. package/src/config/console-state.ts +15 -0
  242. package/src/config/markdown.ts +99 -0
  243. package/src/config/paths.ts +167 -0
  244. package/src/config/tui-migrate.ts +155 -0
  245. package/src/config/tui-schema.ts +37 -0
  246. package/src/config/tui.ts +179 -0
  247. package/src/config/validator.ts +52 -0
  248. package/src/control-plane/adaptors/index.ts +20 -0
  249. package/src/control-plane/adaptors/worktree.ts +42 -0
  250. package/src/control-plane/schema.ts +17 -0
  251. package/src/control-plane/sse.ts +66 -0
  252. package/src/control-plane/types.ts +32 -0
  253. package/src/control-plane/workspace.sql.ts +17 -0
  254. package/src/control-plane/workspace.ts +168 -0
  255. package/src/effect/cross-spawn-spawner.ts +502 -0
  256. package/src/effect/instance-ref.ts +6 -0
  257. package/src/effect/instance-registry.ts +12 -0
  258. package/src/effect/instance-state.ts +82 -0
  259. package/src/effect/run-service.ts +33 -0
  260. package/src/effect/runner.ts +216 -0
  261. package/src/env/index.ts +28 -0
  262. package/src/file/ignore.ts +82 -0
  263. package/src/file/index.ts +686 -0
  264. package/src/file/protected.ts +59 -0
  265. package/src/file/ripgrep.ts +376 -0
  266. package/src/file/time.ts +133 -0
  267. package/src/file/watcher.ts +172 -0
  268. package/src/filesystem/index.ts +236 -0
  269. package/src/flag/flag.ts +157 -0
  270. package/src/format/formatter.ts +413 -0
  271. package/src/format/index.ts +203 -0
  272. package/src/git/index.ts +303 -0
  273. package/src/global/index.ts +54 -0
  274. package/src/id/id.ts +85 -0
  275. package/src/ide/index.ts +74 -0
  276. package/src/index.ts +253 -0
  277. package/src/installation/index.ts +355 -0
  278. package/src/installation/meta.ts +7 -0
  279. package/src/lsp/client.ts +256 -0
  280. package/src/lsp/index.ts +558 -0
  281. package/src/lsp/language.ts +120 -0
  282. package/src/lsp/launch.ts +21 -0
  283. package/src/lsp/server.ts +1968 -0
  284. package/src/mcp/auth.ts +173 -0
  285. package/src/mcp/index.ts +1250 -0
  286. package/src/mcp/oauth-callback.ts +216 -0
  287. package/src/mcp/oauth-provider.ts +185 -0
  288. package/src/mcp/schema-loader.ts +82 -0
  289. package/src/node.ts +1 -0
  290. package/src/npm/index.ts +188 -0
  291. package/src/patch/index.ts +680 -0
  292. package/src/permission/arity.ts +163 -0
  293. package/src/permission/evaluate.ts +15 -0
  294. package/src/permission/index.ts +323 -0
  295. package/src/permission/schema.ts +17 -0
  296. package/src/plugin/cloudflare.ts +67 -0
  297. package/src/plugin/codex.ts +608 -0
  298. package/src/plugin/github-copilot/copilot.ts +361 -0
  299. package/src/plugin/github-copilot/models.ts +144 -0
  300. package/src/plugin/index.ts +288 -0
  301. package/src/plugin/install.ts +439 -0
  302. package/src/plugin/loader.ts +174 -0
  303. package/src/plugin/meta.ts +188 -0
  304. package/src/plugin/shared.ts +323 -0
  305. package/src/project/bootstrap.ts +35 -0
  306. package/src/project/init-files.ts +328 -0
  307. package/src/project/instance.ts +175 -0
  308. package/src/project/project.sql.ts +16 -0
  309. package/src/project/project.ts +519 -0
  310. package/src/project/schema.ts +16 -0
  311. package/src/project/state.ts +70 -0
  312. package/src/project/vcs.ts +240 -0
  313. package/src/provider/auth.ts +253 -0
  314. package/src/provider/error.ts +297 -0
  315. package/src/provider/models.ts +162 -0
  316. package/src/provider/provider.ts +1776 -0
  317. package/src/provider/schema.ts +38 -0
  318. package/src/provider/sdk/copilot/README.md +5 -0
  319. package/src/provider/sdk/copilot/chat/convert-to-openai-compatible-chat-messages.ts +170 -0
  320. package/src/provider/sdk/copilot/chat/get-response-metadata.ts +15 -0
  321. package/src/provider/sdk/copilot/chat/map-openai-compatible-finish-reason.ts +19 -0
  322. package/src/provider/sdk/copilot/chat/openai-compatible-api-types.ts +64 -0
  323. package/src/provider/sdk/copilot/chat/openai-compatible-chat-language-model.ts +814 -0
  324. package/src/provider/sdk/copilot/chat/openai-compatible-chat-options.ts +28 -0
  325. package/src/provider/sdk/copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
  326. package/src/provider/sdk/copilot/chat/openai-compatible-prepare-tools.ts +83 -0
  327. package/src/provider/sdk/copilot/copilot-provider.ts +100 -0
  328. package/src/provider/sdk/copilot/index.ts +2 -0
  329. package/src/provider/sdk/copilot/openai-compatible-error.ts +27 -0
  330. package/src/provider/sdk/copilot/responses/convert-to-openai-responses-input.ts +335 -0
  331. package/src/provider/sdk/copilot/responses/map-openai-responses-finish-reason.ts +22 -0
  332. package/src/provider/sdk/copilot/responses/openai-config.ts +18 -0
  333. package/src/provider/sdk/copilot/responses/openai-error.ts +22 -0
  334. package/src/provider/sdk/copilot/responses/openai-responses-api-types.ts +214 -0
  335. package/src/provider/sdk/copilot/responses/openai-responses-language-model.ts +1769 -0
  336. package/src/provider/sdk/copilot/responses/openai-responses-prepare-tools.ts +173 -0
  337. package/src/provider/sdk/copilot/responses/openai-responses-settings.ts +1 -0
  338. package/src/provider/sdk/copilot/responses/tool/code-interpreter.ts +87 -0
  339. package/src/provider/sdk/copilot/responses/tool/file-search.ts +127 -0
  340. package/src/provider/sdk/copilot/responses/tool/image-generation.ts +114 -0
  341. package/src/provider/sdk/copilot/responses/tool/local-shell.ts +64 -0
  342. package/src/provider/sdk/copilot/responses/tool/web-search-preview.ts +103 -0
  343. package/src/provider/sdk/copilot/responses/tool/web-search.ts +102 -0
  344. package/src/provider/transform.ts +1124 -0
  345. package/src/pty/index.ts +397 -0
  346. package/src/pty/pty.bun.ts +26 -0
  347. package/src/pty/pty.node.ts +27 -0
  348. package/src/pty/pty.ts +25 -0
  349. package/src/pty/schema.ts +17 -0
  350. package/src/question/index.ts +224 -0
  351. package/src/question/schema.ts +17 -0
  352. package/src/server/error.ts +36 -0
  353. package/src/server/event.ts +7 -0
  354. package/src/server/instance.ts +315 -0
  355. package/src/server/mdns.ts +60 -0
  356. package/src/server/middleware.ts +33 -0
  357. package/src/server/projectors.ts +28 -0
  358. package/src/server/proxy.ts +130 -0
  359. package/src/server/router.ts +105 -0
  360. package/src/server/routes/config.ts +92 -0
  361. package/src/server/routes/event.ts +83 -0
  362. package/src/server/routes/experimental.ts +374 -0
  363. package/src/server/routes/file.ts +197 -0
  364. package/src/server/routes/global.ts +312 -0
  365. package/src/server/routes/mcp.ts +225 -0
  366. package/src/server/routes/permission.ts +69 -0
  367. package/src/server/routes/project.ts +118 -0
  368. package/src/server/routes/provider.ts +171 -0
  369. package/src/server/routes/pty.ts +210 -0
  370. package/src/server/routes/question.ts +99 -0
  371. package/src/server/routes/session.ts +984 -0
  372. package/src/server/routes/tui.ts +378 -0
  373. package/src/server/routes/workspace.ts +94 -0
  374. package/src/server/server.ts +353 -0
  375. package/src/session/compaction.ts +86 -0
  376. package/src/session/index.ts +904 -0
  377. package/src/session/instruction.ts +261 -0
  378. package/src/session/llm/monitor.ts +87 -0
  379. package/src/session/llm.ts +1676 -0
  380. package/src/session/message-v2.ts +1082 -0
  381. package/src/session/message.ts +191 -0
  382. package/src/session/overflow.ts +34 -0
  383. package/src/session/processor.ts +635 -0
  384. package/src/session/projectors.ts +136 -0
  385. package/src/session/prompt/build-switch.txt +5 -0
  386. package/src/session/prompt/builder.ts +135 -0
  387. package/src/session/prompt/default.txt +11 -0
  388. package/src/session/prompt/engine.ts +1072 -0
  389. package/src/session/prompt/gemma4.txt +1 -0
  390. package/src/session/prompt/max-steps.txt +16 -0
  391. package/src/session/prompt/orchestrator.ts +426 -0
  392. package/src/session/prompt/plan.txt +28 -0
  393. package/src/session/prompt/qwen.txt +19 -0
  394. package/src/session/prompt/resolver.ts +670 -0
  395. package/src/session/prompt/router.ts +197 -0
  396. package/src/session/prompt/state.ts +96 -0
  397. package/src/session/prompt/types.ts +115 -0
  398. package/src/session/prompt/utils.ts +15 -0
  399. package/src/session/prompt.ts +362 -0
  400. package/src/session/retry.ts +106 -0
  401. package/src/session/revert.ts +176 -0
  402. package/src/session/sanitizer.ts +125 -0
  403. package/src/session/schema.ts +38 -0
  404. package/src/session/session.sql.ts +106 -0
  405. package/src/session/status.ts +102 -0
  406. package/src/session/summary.ts +183 -0
  407. package/src/session/system.ts +79 -0
  408. package/src/session/todo.ts +166 -0
  409. package/src/session/worker.ts +382 -0
  410. package/src/shell/shell.ts +110 -0
  411. package/src/skill/discovery.ts +116 -0
  412. package/src/skill/index.ts +287 -0
  413. package/src/snapshot/index.ts +726 -0
  414. package/src/sql.d.ts +4 -0
  415. package/src/storage/db.bun.ts +8 -0
  416. package/src/storage/db.node.ts +8 -0
  417. package/src/storage/db.ts +174 -0
  418. package/src/storage/json-migration.ts +387 -0
  419. package/src/storage/schema.sql.ts +10 -0
  420. package/src/storage/schema.ts +4 -0
  421. package/src/storage/storage.ts +353 -0
  422. package/src/sync/README.md +179 -0
  423. package/src/sync/event.sql.ts +16 -0
  424. package/src/sync/index.ts +263 -0
  425. package/src/sync/schema.ts +14 -0
  426. package/src/tool/apply_patch.ts +281 -0
  427. package/src/tool/apply_patch.txt +1 -0
  428. package/src/tool/arbitration.txt +5 -0
  429. package/src/tool/bash.ts +494 -0
  430. package/src/tool/bash.txt +2 -0
  431. package/src/tool/batch.ts +183 -0
  432. package/src/tool/batch.txt +1 -0
  433. package/src/tool/codesearch.ts +132 -0
  434. package/src/tool/codesearch.txt +1 -0
  435. package/src/tool/edit.ts +734 -0
  436. package/src/tool/edit.txt +1 -0
  437. package/src/tool/external-directory.ts +46 -0
  438. package/src/tool/glob.ts +73 -0
  439. package/src/tool/glob.txt +2 -0
  440. package/src/tool/grep.ts +156 -0
  441. package/src/tool/grep.txt +2 -0
  442. package/src/tool/invalid.ts +20 -0
  443. package/src/tool/ls.ts +121 -0
  444. package/src/tool/ls.txt +1 -0
  445. package/src/tool/lsp.ts +97 -0
  446. package/src/tool/lsp.txt +1 -0
  447. package/src/tool/multiedit.ts +46 -0
  448. package/src/tool/multiedit.txt +1 -0
  449. package/src/tool/plan-enter.txt +14 -0
  450. package/src/tool/plan-exit.txt +13 -0
  451. package/src/tool/plan.ts +131 -0
  452. package/src/tool/question.ts +46 -0
  453. package/src/tool/question.txt +10 -0
  454. package/src/tool/read.ts +332 -0
  455. package/src/tool/read.txt +1 -0
  456. package/src/tool/registry.ts +288 -0
  457. package/src/tool/revert.ts +37 -0
  458. package/src/tool/schema.ts +17 -0
  459. package/src/tool/skill.ts +105 -0
  460. package/src/tool/task.ts +150 -0
  461. package/src/tool/task.txt +3 -0
  462. package/src/tool/task_complete.ts +21 -0
  463. package/src/tool/tool.ts +112 -0
  464. package/src/tool/truncate.ts +144 -0
  465. package/src/tool/truncation-dir.ts +4 -0
  466. package/src/tool/webfetch.ts +206 -0
  467. package/src/tool/webfetch.txt +1 -0
  468. package/src/tool/websearch.ts +150 -0
  469. package/src/tool/websearch.txt +1 -0
  470. package/src/tool/write.ts +101 -0
  471. package/src/tool/write.txt +1 -0
  472. package/src/util/abort.ts +35 -0
  473. package/src/util/ai-sdk.ts +59 -0
  474. package/src/util/archive.ts +17 -0
  475. package/src/util/color.ts +19 -0
  476. package/src/util/context.ts +25 -0
  477. package/src/util/data-url.ts +9 -0
  478. package/src/util/defer.ts +12 -0
  479. package/src/util/effect-http-client.ts +11 -0
  480. package/src/util/effect-zod.ts +98 -0
  481. package/src/util/error.ts +77 -0
  482. package/src/util/filesystem.ts +245 -0
  483. package/src/util/flock.ts +333 -0
  484. package/src/util/fn.ts +21 -0
  485. package/src/util/format.ts +20 -0
  486. package/src/util/glob.ts +34 -0
  487. package/src/util/hash.ts +7 -0
  488. package/src/util/iife.ts +3 -0
  489. package/src/util/keybind.ts +103 -0
  490. package/src/util/lazy.ts +23 -0
  491. package/src/util/locale.ts +81 -0
  492. package/src/util/lock.ts +98 -0
  493. package/src/util/log-parser.ts +114 -0
  494. package/src/util/log.ts +250 -0
  495. package/src/util/network.ts +23 -0
  496. package/src/util/process.ts +176 -0
  497. package/src/util/queue.ts +32 -0
  498. package/src/util/record.ts +3 -0
  499. package/src/util/rpc.ts +66 -0
  500. package/src/util/schema.ts +53 -0
  501. package/src/util/scrap.ts +10 -0
  502. package/src/util/session-analyzer.ts +331 -0
  503. package/src/util/session-telemetry.ts +91 -0
  504. package/src/util/signal.ts +12 -0
  505. package/src/util/timeout.ts +14 -0
  506. package/src/util/token.ts +7 -0
  507. package/src/util/tokenizer.ts +50 -0
  508. package/src/util/toon.ts +45 -0
  509. package/src/util/update-schema.ts +13 -0
  510. package/src/util/which.ts +14 -0
  511. package/src/util/wildcard.ts +59 -0
  512. package/src/worktree/index.ts +612 -0
  513. package/sst-env.d.ts +10 -0
  514. package/test/AGENTS.md +81 -0
  515. package/test/account/repo.test.ts +326 -0
  516. package/test/account/service.test.ts +393 -0
  517. package/test/acp/agent-interface.test.ts +51 -0
  518. package/test/acp/event-subscription.test.ts +685 -0
  519. package/test/agent/agent.test.ts +716 -0
  520. package/test/auth/auth.test.ts +58 -0
  521. package/test/bus/bus-effect.test.ts +164 -0
  522. package/test/bus/bus-integration.test.ts +87 -0
  523. package/test/bus/bus.test.ts +219 -0
  524. package/test/cli/account.test.ts +26 -0
  525. package/test/cli/cmd/tui/prompt-part.test.ts +47 -0
  526. package/test/cli/github-action.test.ts +198 -0
  527. package/test/cli/github-remote.test.ts +80 -0
  528. package/test/cli/plugin-auth-picker.test.ts +120 -0
  529. package/test/cli/tui/keybind-plugin.test.ts +90 -0
  530. package/test/cli/tui/plugin-add.test.ts +107 -0
  531. package/test/cli/tui/plugin-install.test.ts +89 -0
  532. package/test/cli/tui/plugin-lifecycle.test.ts +225 -0
  533. package/test/cli/tui/plugin-loader-entrypoint.test.ts +492 -0
  534. package/test/cli/tui/plugin-loader-pure.test.ts +72 -0
  535. package/test/cli/tui/plugin-loader.test.ts +752 -0
  536. package/test/cli/tui/plugin-toggle.test.ts +159 -0
  537. package/test/cli/tui/slot-replace.test.tsx +47 -0
  538. package/test/cli/tui/theme-store.test.ts +51 -0
  539. package/test/cli/tui/thread.test.ts +128 -0
  540. package/test/cli/tui/transcript.test.ts +426 -0
  541. package/test/config/agent-color.test.ts +71 -0
  542. package/test/config/config.test.ts +2337 -0
  543. package/test/config/fixtures/empty-frontmatter.md +4 -0
  544. package/test/config/fixtures/frontmatter.md +28 -0
  545. package/test/config/fixtures/markdown-header.md +11 -0
  546. package/test/config/fixtures/no-frontmatter.md +1 -0
  547. package/test/config/fixtures/weird-model-id.md +13 -0
  548. package/test/config/markdown.test.ts +228 -0
  549. package/test/config/tui.test.ts +800 -0
  550. package/test/control-plane/sse.test.ts +56 -0
  551. package/test/effect/cross-spawn-spawner.test.ts +412 -0
  552. package/test/effect/instance-state.test.ts +482 -0
  553. package/test/effect/run-service.test.ts +46 -0
  554. package/test/effect/runner.test.ts +523 -0
  555. package/test/fake/provider.ts +82 -0
  556. package/test/file/fsmonitor.test.ts +62 -0
  557. package/test/file/ignore.test.ts +10 -0
  558. package/test/file/index.test.ts +946 -0
  559. package/test/file/path-traversal.test.ts +198 -0
  560. package/test/file/ripgrep.test.ts +54 -0
  561. package/test/file/time.test.ts +445 -0
  562. package/test/file/watcher.test.ts +247 -0
  563. package/test/filesystem/filesystem.test.ts +319 -0
  564. package/test/fixture/db.ts +11 -0
  565. package/test/fixture/fixture.test.ts +26 -0
  566. package/test/fixture/fixture.ts +172 -0
  567. package/test/fixture/flock-worker.ts +72 -0
  568. package/test/fixture/lsp/fake-lsp-server.js +77 -0
  569. package/test/fixture/plug-worker.ts +93 -0
  570. package/test/fixture/plugin-meta-worker.ts +26 -0
  571. package/test/fixture/skills/agents-sdk/SKILL.md +152 -0
  572. package/test/fixture/skills/agents-sdk/references/callable.md +92 -0
  573. package/test/fixture/skills/cloudflare/SKILL.md +211 -0
  574. package/test/fixture/skills/index.json +6 -0
  575. package/test/fixture/tui-plugin.ts +328 -0
  576. package/test/fixture/tui-runtime.ts +27 -0
  577. package/test/format/format.test.ts +171 -0
  578. package/test/git/git.test.ts +128 -0
  579. package/test/ide/ide.test.ts +82 -0
  580. package/test/installation/installation.test.ts +152 -0
  581. package/test/keybind.test.ts +421 -0
  582. package/test/lib/effect.ts +53 -0
  583. package/test/lib/filesystem.ts +10 -0
  584. package/test/lib/llm-server.ts +794 -0
  585. package/test/lsp/client.test.ts +95 -0
  586. package/test/lsp/index.test.ts +133 -0
  587. package/test/lsp/launch.test.ts +22 -0
  588. package/test/lsp/lifecycle.test.ts +147 -0
  589. package/test/mcp/headers.test.ts +153 -0
  590. package/test/mcp/lifecycle.test.ts +750 -0
  591. package/test/mcp/oauth-auto-connect.test.ts +199 -0
  592. package/test/mcp/oauth-browser.test.ts +249 -0
  593. package/test/mcp/sc-approve-validator.test.ts +431 -0
  594. package/test/memory/abort-leak.test.ts +137 -0
  595. package/test/npm.test.ts +18 -0
  596. package/test/patch/patch.test.ts +348 -0
  597. package/test/permission/arity.test.ts +33 -0
  598. package/test/permission/next.test.ts +1123 -0
  599. package/test/permission-task.test.ts +323 -0
  600. package/test/plugin/auth-override.test.ts +74 -0
  601. package/test/plugin/codex.test.ts +123 -0
  602. package/test/plugin/github-copilot-models.test.ts +117 -0
  603. package/test/plugin/install-concurrency.test.ts +140 -0
  604. package/test/plugin/install.test.ts +570 -0
  605. package/test/plugin/loader-shared.test.ts +1136 -0
  606. package/test/plugin/meta.test.ts +137 -0
  607. package/test/plugin/shared.test.ts +88 -0
  608. package/test/plugin/trigger.test.ts +111 -0
  609. package/test/preload.ts +90 -0
  610. package/test/project/migrate-global.test.ts +140 -0
  611. package/test/project/project.test.ts +459 -0
  612. package/test/project/state.test.ts +115 -0
  613. package/test/project/vcs.test.ts +228 -0
  614. package/test/project/worktree-remove.test.ts +96 -0
  615. package/test/project/worktree.test.ts +173 -0
  616. package/test/provider/amazon-bedrock.test.ts +447 -0
  617. package/test/provider/copilot/convert-to-copilot-messages.test.ts +523 -0
  618. package/test/provider/copilot/copilot-chat-model.test.ts +592 -0
  619. package/test/provider/error.test.ts +49 -0
  620. package/test/provider/gitlab-duo.test.ts +412 -0
  621. package/test/provider/provider.test.ts +2494 -0
  622. package/test/provider/transform.test.ts +2944 -0
  623. package/test/pty/pty-output-isolation.test.ts +141 -0
  624. package/test/pty/pty-session.test.ts +92 -0
  625. package/test/pty/pty-shell.test.ts +59 -0
  626. package/test/question/question.test.ts +453 -0
  627. package/test/server/global-session-list.test.ts +89 -0
  628. package/test/server/project-init-git.test.ts +121 -0
  629. package/test/server/session-actions.test.ts +83 -0
  630. package/test/server/session-list.test.ts +98 -0
  631. package/test/server/session-messages.test.ts +159 -0
  632. package/test/server/session-select.test.ts +84 -0
  633. package/test/session/compaction.test.ts +683 -0
  634. package/test/session/continuity-handover.test.ts +620 -0
  635. package/test/session/deterministic-handover.test.ts +328 -0
  636. package/test/session/doom-protection.test.ts +247 -0
  637. package/test/session/hard-reset.test.ts +179 -0
  638. package/test/session/instruction.test.ts +286 -0
  639. package/test/session/llm/monitor.test.ts +53 -0
  640. package/test/session/llm-sanitizer.test.ts +90 -0
  641. package/test/session/llm-zones-e2e.test.ts +61 -0
  642. package/test/session/llm.test.ts +1308 -0
  643. package/test/session/mcpx-normalization.test.ts +86 -0
  644. package/test/session/mcpx-syntax-recovery.test.ts +28 -0
  645. package/test/session/message-v2.test.ts +957 -0
  646. package/test/session/messages-pagination.test.ts +885 -0
  647. package/test/session/processor-effect.test.ts +805 -0
  648. package/test/session/prompt/builder.test.ts +71 -0
  649. package/test/session/prompt/engine-loop.test.ts +80 -0
  650. package/test/session/prompt/orchestrator.test.ts +108 -0
  651. package/test/session/prompt/resolver.test.ts +211 -0
  652. package/test/session/prompt/router.test.ts +84 -0
  653. package/test/session/prompt/state.test.ts +57 -0
  654. package/test/session/prompt-effect.test.ts +1241 -0
  655. package/test/session/prompt.test.ts +522 -0
  656. package/test/session/refactor-system-zones.test.ts +241 -0
  657. package/test/session/retry.test.ts +232 -0
  658. package/test/session/revert-compact.test.ts +621 -0
  659. package/test/session/sanitizer.test.ts +61 -0
  660. package/test/session/session.test.ts +142 -0
  661. package/test/session/snapshot-tool-race.test.ts +242 -0
  662. package/test/session/structured-output-integration.test.ts +233 -0
  663. package/test/session/structured-output.test.ts +391 -0
  664. package/test/session/system.test.ts +59 -0
  665. package/test/session/telemetry.test.ts +35 -0
  666. package/test/shell/shell.test.ts +73 -0
  667. package/test/skill/discovery.test.ts +116 -0
  668. package/test/skill/skill.test.ts +392 -0
  669. package/test/snapshot/snapshot.test.ts +1404 -0
  670. package/test/storage/db.test.ts +14 -0
  671. package/test/storage/json-migration.test.ts +791 -0
  672. package/test/storage/storage.test.ts +295 -0
  673. package/test/sync/index.test.ts +191 -0
  674. package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
  675. package/test/tool/apply_patch.test.ts +567 -0
  676. package/test/tool/bash.test.ts +1099 -0
  677. package/test/tool/edit.test.ts +681 -0
  678. package/test/tool/external-directory.test.ts +198 -0
  679. package/test/tool/fixtures/large-image.png +0 -0
  680. package/test/tool/fixtures/models-api.json +65179 -0
  681. package/test/tool/grep.test.ts +111 -0
  682. package/test/tool/question.test.ts +126 -0
  683. package/test/tool/read.test.ts +468 -0
  684. package/test/tool/registry.test.ts +126 -0
  685. package/test/tool/skill.test.ts +167 -0
  686. package/test/tool/task.test.ts +49 -0
  687. package/test/tool/tool-define.test.ts +101 -0
  688. package/test/tool/truncation.test.ts +161 -0
  689. package/test/tool/webfetch.test.ts +101 -0
  690. package/test/tool/write.test.ts +354 -0
  691. package/test/util/data-url.test.ts +14 -0
  692. package/test/util/effect-zod.test.ts +61 -0
  693. package/test/util/error.test.ts +38 -0
  694. package/test/util/filesystem.test.ts +656 -0
  695. package/test/util/flock.test.ts +383 -0
  696. package/test/util/format.test.ts +59 -0
  697. package/test/util/glob.test.ts +164 -0
  698. package/test/util/iife.test.ts +36 -0
  699. package/test/util/lazy.test.ts +50 -0
  700. package/test/util/lock.test.ts +72 -0
  701. package/test/util/log-parser.test.ts +61 -0
  702. package/test/util/module.test.ts +59 -0
  703. package/test/util/process.test.ts +128 -0
  704. package/test/util/telemetry-integration.test.ts +104 -0
  705. package/test/util/timeout.test.ts +21 -0
  706. package/test/util/which.test.ts +100 -0
  707. package/test/util/wildcard.test.ts +90 -0
  708. package/test-regex.js +50 -0
  709. package/tsconfig.json +23 -0
  710. package/LICENSE +0 -21
  711. /package/{postinstall.mjs → script/postinstall.mjs} +0 -0
@@ -0,0 +1,176 @@
1
+ import { type ChildProcess } from "child_process"
2
+ import launch from "cross-spawn"
3
+ import { buffer } from "node:stream/consumers"
4
+ import { errorMessage } from "./error"
5
+
6
+ export namespace Process {
7
+ export type Stdio = "inherit" | "pipe" | "ignore"
8
+ export type Shell = boolean | string
9
+
10
+ export interface Options {
11
+ cwd?: string
12
+ env?: NodeJS.ProcessEnv | null
13
+ stdin?: Stdio
14
+ stdout?: Stdio
15
+ stderr?: Stdio
16
+ shell?: Shell
17
+ abort?: AbortSignal
18
+ kill?: NodeJS.Signals | number
19
+ timeout?: number
20
+ }
21
+
22
+ export interface RunOptions extends Omit<Options, "stdout" | "stderr"> {
23
+ nothrow?: boolean
24
+ }
25
+
26
+ export interface Result {
27
+ code: number
28
+ stdout: Buffer
29
+ stderr: Buffer
30
+ }
31
+
32
+ export interface TextResult extends Result {
33
+ text: string
34
+ }
35
+
36
+ export class RunFailedError extends Error {
37
+ readonly cmd: string[]
38
+ readonly code: number
39
+ readonly stdout: Buffer
40
+ readonly stderr: Buffer
41
+
42
+ constructor(cmd: string[], code: number, stdout: Buffer, stderr: Buffer) {
43
+ const text = stderr.toString().trim()
44
+ super(
45
+ text
46
+ ? `Command failed with code ${code}: ${cmd.join(" ")}\n${text}`
47
+ : `Command failed with code ${code}: ${cmd.join(" ")}`,
48
+ )
49
+ this.name = "ProcessRunFailedError"
50
+ this.cmd = [...cmd]
51
+ this.code = code
52
+ this.stdout = stdout
53
+ this.stderr = stderr
54
+ }
55
+ }
56
+
57
+ export type Child = ChildProcess & { exited: Promise<number> }
58
+
59
+ export function spawn(cmd: string[], opts: Options = {}): Child {
60
+ if (cmd.length === 0) throw new Error("Command is required")
61
+ opts.abort?.throwIfAborted()
62
+
63
+ const proc = launch(cmd[0], cmd.slice(1), {
64
+ cwd: opts.cwd,
65
+ shell: opts.shell,
66
+ env: opts.env === null ? {} : opts.env ? { ...process.env, ...opts.env } : undefined,
67
+ stdio: [opts.stdin ?? "ignore", opts.stdout ?? "ignore", opts.stderr ?? "ignore"],
68
+ windowsHide: process.platform === "win32",
69
+ })
70
+
71
+ let closed = false
72
+ let timer: ReturnType<typeof setTimeout> | undefined
73
+
74
+ const abort = () => {
75
+ if (closed) return
76
+ if (proc.exitCode !== null || proc.signalCode !== null) return
77
+ closed = true
78
+
79
+ proc.kill(opts.kill ?? "SIGTERM")
80
+
81
+ const ms = opts.timeout ?? 5_000
82
+ if (ms <= 0) return
83
+ timer = setTimeout(() => proc.kill("SIGKILL"), ms)
84
+ }
85
+
86
+ const exited = new Promise<number>((resolve, reject) => {
87
+ const done = () => {
88
+ opts.abort?.removeEventListener("abort", abort)
89
+ if (timer) clearTimeout(timer)
90
+ }
91
+
92
+ proc.once("exit", (code, signal) => {
93
+ done()
94
+ resolve(code ?? (signal ? 1 : 0))
95
+ })
96
+
97
+ proc.once("error", (error) => {
98
+ done()
99
+ reject(error)
100
+ })
101
+ })
102
+ void exited.catch(() => undefined)
103
+
104
+ if (opts.abort) {
105
+ opts.abort.addEventListener("abort", abort, { once: true })
106
+ if (opts.abort.aborted) abort()
107
+ }
108
+
109
+ const child = proc as Child
110
+ child.exited = exited
111
+ return child
112
+ }
113
+
114
+ export async function run(cmd: string[], opts: RunOptions = {}): Promise<Result> {
115
+ const proc = spawn(cmd, {
116
+ cwd: opts.cwd,
117
+ env: opts.env,
118
+ stdin: opts.stdin,
119
+ shell: opts.shell,
120
+ abort: opts.abort,
121
+ kill: opts.kill,
122
+ timeout: opts.timeout,
123
+ stdout: "pipe",
124
+ stderr: "pipe",
125
+ })
126
+
127
+ if (!proc.stdout || !proc.stderr) throw new Error("Process output not available")
128
+
129
+ const out = await Promise.all([proc.exited, buffer(proc.stdout), buffer(proc.stderr)])
130
+ .then(([code, stdout, stderr]) => ({
131
+ code,
132
+ stdout,
133
+ stderr,
134
+ }))
135
+ .catch((err: unknown) => {
136
+ if (!opts.nothrow) throw err
137
+ return {
138
+ code: 1,
139
+ stdout: Buffer.alloc(0),
140
+ stderr: Buffer.from(errorMessage(err)),
141
+ }
142
+ })
143
+ if (out.code === 0 || opts.nothrow) return out
144
+ throw new RunFailedError(cmd, out.code, out.stdout, out.stderr)
145
+ }
146
+
147
+ // Duplicated in `packages/sdk/js/src/process.ts` because the SDK cannot import
148
+ // `epochcli` without creating a cycle. Keep both copies in sync.
149
+ export async function stop(proc: ChildProcess) {
150
+ if (proc.exitCode !== null || proc.signalCode !== null) return
151
+
152
+ if (process.platform !== "win32" || !proc.pid) {
153
+ proc.kill()
154
+ return
155
+ }
156
+
157
+ const out = await run(["taskkill", "/pid", String(proc.pid), "/T", "/F"], {
158
+ nothrow: true,
159
+ })
160
+
161
+ if (out.code === 0) return
162
+ proc.kill()
163
+ }
164
+
165
+ export async function text(cmd: string[], opts: RunOptions = {}): Promise<TextResult> {
166
+ const out = await run(cmd, opts)
167
+ return {
168
+ ...out,
169
+ text: out.stdout.toString(),
170
+ }
171
+ }
172
+
173
+ export async function lines(cmd: string[], opts: RunOptions = {}): Promise<string[]> {
174
+ return (await text(cmd, opts)).text.split(/\r?\n/).filter(Boolean)
175
+ }
176
+ }
@@ -0,0 +1,32 @@
1
+ export class AsyncQueue<T> implements AsyncIterable<T> {
2
+ private queue: T[] = []
3
+ private resolvers: ((value: T) => void)[] = []
4
+
5
+ push(item: T) {
6
+ const resolve = this.resolvers.shift()
7
+ if (resolve) resolve(item)
8
+ else this.queue.push(item)
9
+ }
10
+
11
+ async next(): Promise<T> {
12
+ if (this.queue.length > 0) return this.queue.shift()!
13
+ return new Promise((resolve) => this.resolvers.push(resolve))
14
+ }
15
+
16
+ async *[Symbol.asyncIterator]() {
17
+ while (true) yield await this.next()
18
+ }
19
+ }
20
+
21
+ export async function work<T>(concurrency: number, items: T[], fn: (item: T) => Promise<void>) {
22
+ const pending = [...items]
23
+ await Promise.all(
24
+ Array.from({ length: concurrency }, async () => {
25
+ while (true) {
26
+ const item = pending.pop()
27
+ if (item === undefined) return
28
+ await fn(item)
29
+ }
30
+ }),
31
+ )
32
+ }
@@ -0,0 +1,3 @@
1
+ export function isRecord(value: unknown): value is Record<string, unknown> {
2
+ return !!value && typeof value === "object" && !Array.isArray(value)
3
+ }
@@ -0,0 +1,66 @@
1
+ export namespace Rpc {
2
+ type Definition = {
3
+ [method: string]: (input: any) => any
4
+ }
5
+
6
+ export function listen(rpc: Definition) {
7
+ onmessage = async (evt) => {
8
+ const parsed = JSON.parse(evt.data)
9
+ if (parsed.type === "rpc.request") {
10
+ const result = await rpc[parsed.method](parsed.input)
11
+ postMessage(JSON.stringify({ type: "rpc.result", result, id: parsed.id }))
12
+ }
13
+ }
14
+ }
15
+
16
+ export function emit(event: string, data: unknown) {
17
+ postMessage(JSON.stringify({ type: "rpc.event", event, data }))
18
+ }
19
+
20
+ export function client<T extends Definition>(target: {
21
+ postMessage: (data: string) => void | null
22
+ onmessage: ((this: Worker, ev: MessageEvent<any>) => any) | null
23
+ }) {
24
+ const pending = new Map<number, (result: any) => void>()
25
+ const listeners = new Map<string, Set<(data: any) => void>>()
26
+ let id = 0
27
+ target.onmessage = async (evt) => {
28
+ const parsed = JSON.parse(evt.data)
29
+ if (parsed.type === "rpc.result") {
30
+ const resolve = pending.get(parsed.id)
31
+ if (resolve) {
32
+ resolve(parsed.result)
33
+ pending.delete(parsed.id)
34
+ }
35
+ }
36
+ if (parsed.type === "rpc.event") {
37
+ const handlers = listeners.get(parsed.event)
38
+ if (handlers) {
39
+ for (const handler of handlers) {
40
+ handler(parsed.data)
41
+ }
42
+ }
43
+ }
44
+ }
45
+ return {
46
+ call<Method extends keyof T>(method: Method, input: Parameters<T[Method]>[0]): Promise<ReturnType<T[Method]>> {
47
+ const requestId = id++
48
+ return new Promise((resolve) => {
49
+ pending.set(requestId, resolve)
50
+ target.postMessage(JSON.stringify({ type: "rpc.request", method, input, id: requestId }))
51
+ })
52
+ },
53
+ on<Data>(event: string, handler: (data: Data) => void) {
54
+ let handlers = listeners.get(event)
55
+ if (!handlers) {
56
+ handlers = new Set()
57
+ listeners.set(event, handlers)
58
+ }
59
+ handlers.add(handler)
60
+ return () => {
61
+ handlers!.delete(handler)
62
+ }
63
+ },
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,53 @@
1
+ import { Schema } from "effect"
2
+
3
+ /**
4
+ * Attach static methods to a schema object. Designed to be used with `.pipe()`:
5
+ *
6
+ * @example
7
+ * export const Foo = fooSchema.pipe(
8
+ * withStatics((schema) => ({
9
+ * zero: schema.makeUnsafe(0),
10
+ * from: Schema.decodeUnknownOption(schema),
11
+ * }))
12
+ * )
13
+ */
14
+ export const withStatics =
15
+ <S extends object, M extends Record<string, unknown>>(methods: (schema: S) => M) =>
16
+ (schema: S): S & M =>
17
+ Object.assign(schema, methods(schema))
18
+
19
+ declare const NewtypeBrand: unique symbol
20
+ type NewtypeBrand<Tag extends string> = { readonly [NewtypeBrand]: Tag }
21
+
22
+ /**
23
+ * Nominal wrapper for scalar types. The class itself is a valid schema —
24
+ * pass it directly to `Schema.decode`, `Schema.decodeEffect`, etc.
25
+ *
26
+ * @example
27
+ * class QuestionID extends Newtype<QuestionID>()("QuestionID", Schema.String) {
28
+ * static make(id: string): QuestionID {
29
+ * return this.makeUnsafe(id)
30
+ * }
31
+ * }
32
+ *
33
+ * Schema.decodeEffect(QuestionID)(input)
34
+ */
35
+ export function Newtype<Self>() {
36
+ return <const Tag extends string, S extends Schema.Top>(tag: Tag, schema: S) => {
37
+ type Branded = NewtypeBrand<Tag>
38
+
39
+ abstract class Base {
40
+ declare readonly [NewtypeBrand]: Tag
41
+
42
+ static makeUnsafe(value: Schema.Schema.Type<S>): Self {
43
+ return value as unknown as Self
44
+ }
45
+ }
46
+
47
+ Object.setPrototypeOf(Base, schema)
48
+
49
+ return Base as unknown as (abstract new (_: never) => Branded) & {
50
+ readonly makeUnsafe: (value: Schema.Schema.Type<S>) => Self
51
+ } & Omit<Schema.Opaque<Self, S, {}>, "makeUnsafe">
52
+ }
53
+ }
@@ -0,0 +1,10 @@
1
+ export const foo: string = "42"
2
+ export const bar: number = 123
3
+
4
+ export function dummyFunction(): void {
5
+ console.log("This is a dummy function")
6
+ }
7
+
8
+ export function randomHelper(): boolean {
9
+ return Math.random() > 0.5
10
+ }
@@ -0,0 +1,331 @@
1
+ import { MessageV2 } from "../session/message-v2"
2
+ import * as fs from "fs/promises"
3
+ import * as path from "path"
4
+ import { SessionTelemetry } from "./session-telemetry"
5
+ import { TurnAggregator, type Turn, type ToolExecution } from "@epoch-ai/util/telemetry"
6
+
7
+ export namespace SessionAnalyzer {
8
+ export async function getTurns(sessionID: string): Promise<Turn[]> {
9
+ const telemetryPath = SessionTelemetry.getPath()
10
+ if (!telemetryPath) return []
11
+
12
+ try {
13
+ const content = await fs.readFile(telemetryPath, "utf-8")
14
+ const lines = content.split("\n").filter(Boolean)
15
+ const aggregator = new TurnAggregator()
16
+ const turns: Turn[] = []
17
+
18
+ for (const line of lines) {
19
+ try {
20
+ const event = JSON.parse(line)
21
+ if (event.mainEpochId !== sessionID && event.sessionID !== sessionID) continue
22
+ const turn = aggregator.processJSON(event)
23
+ if (turn) turns.push(turn)
24
+ } catch (e) {}
25
+ }
26
+
27
+ const lastTurn = aggregator.flush()
28
+ if (lastTurn) turns.push(lastTurn)
29
+
30
+ return turns
31
+ } catch (e) {
32
+ return []
33
+ }
34
+ }
35
+
36
+ export async function getGlobalTurns(): Promise<Turn[]> {
37
+ const telemetryPath = SessionTelemetry.getPath()
38
+ if (!telemetryPath) return []
39
+
40
+ try {
41
+ const content = await fs.readFile(telemetryPath, "utf-8")
42
+ const lines = content.split("\n").filter(Boolean)
43
+ const aggregator = new TurnAggregator()
44
+ const turns: Turn[] = []
45
+
46
+ for (const line of lines) {
47
+ try {
48
+ const event = JSON.parse(line)
49
+ const turn = aggregator.processJSON(event)
50
+ if (turn) turns.push(turn)
51
+ } catch (e) {}
52
+ }
53
+
54
+ const lastTurn = aggregator.flush()
55
+ if (lastTurn) turns.push(lastTurn)
56
+
57
+ return turns
58
+ } catch (e) {
59
+ return []
60
+ }
61
+ }
62
+
63
+ export async function exportHistoryToToon(workspaceRoot: string) {
64
+ const turns = await getGlobalTurns()
65
+ if (turns.length === 0) return
66
+
67
+ const historyDir = path.join(workspaceRoot, ".history")
68
+ try {
69
+ await fs.mkdir(historyDir, { recursive: true })
70
+ } catch (e) {}
71
+
72
+ // 1. Timeline
73
+ const timeline = generateActionTimeline(turns)
74
+ await fs
75
+ .writeFile(
76
+ path.join(historyDir, "timeline.toon"),
77
+ `global_timeline:\n${timeline
78
+ .split("\n")
79
+ .map((l) => " - " + JSON.stringify(l))
80
+ .join("\n")}`,
81
+ )
82
+ .catch(() => {})
83
+
84
+ // 2. Files
85
+ const files = new Set<string>()
86
+ for (const turn of turns) {
87
+ for (const tool of turn.tools) {
88
+ const input = tool.input as any
89
+
90
+ // Standard file tools
91
+ if (["edit", "write", "read", "replace", "read_file", "write_file", "view_file"].includes(tool.name)) {
92
+ if (input?.filePath) files.add(input.filePath)
93
+ if (input?.file_path) files.add(input.file_path)
94
+ }
95
+ // MCPX tools that might have a path in args
96
+ else if (tool.name.startsWith("mcpx [") && input?.args) {
97
+ const args = input.args as Record<string, any>
98
+ if (args?.file_path) files.add(args.file_path)
99
+ if (args?.path) files.add(args.path)
100
+ }
101
+ // Bash heuristics
102
+ else if (tool.name === "bash" && typeof input?.command === "string") {
103
+ const fileMatches = input.command.match(/[\w.\-\/]+\.(ts|js|json|md|txt|py|go|rs)/g)
104
+ if (fileMatches) fileMatches.forEach((m: string) => files.add(m))
105
+ }
106
+ }
107
+ }
108
+ await fs
109
+ .writeFile(
110
+ path.join(historyDir, "files.toon"),
111
+ `touched_files:\n${Array.from(files)
112
+ .map((f) => " - " + JSON.stringify(f))
113
+ .join("\n")}`,
114
+ )
115
+ .catch(() => {})
116
+
117
+ // 3. Errors & State Inconsistency
118
+ const errors: string[] = []
119
+ for (const turn of turns) {
120
+ for (const tool of turn.tools) {
121
+ if (tool.status === "failed") {
122
+ errors.push(`Turn ${turn.id} - ${tool.name}: ${tool.error || "Unknown error"}`)
123
+ }
124
+ }
125
+ }
126
+
127
+ // Proactive Inconsistency Check: Look for files modified without a successful commit turn
128
+ // (Simplified heuristic for the Global History Suite)
129
+ if (errors.length > 0) {
130
+ errors.unshift(
131
+ "[STATE_INCONSISTENCY_WARNING]: Multiple tool failures detected right before transition. Verify disk integrity.",
132
+ )
133
+ }
134
+
135
+ await fs
136
+ .writeFile(
137
+ path.join(historyDir, "errors.toon"),
138
+ `tool_errors:\n${errors.map((e) => " - " + JSON.stringify(e)).join("\n")}`,
139
+ )
140
+ .catch(() => {})
141
+
142
+ // 4. Longitudinal Intent
143
+ const continuityPath = path.join(workspaceRoot, ".epoch-continuity.toon")
144
+ try {
145
+ const continuityContent = await fs.readFile(continuityPath, "utf-8")
146
+ const intentMatch = continuityContent.match(/executive_intent:\n([\s\S]+?)\n technical_progress:/)
147
+ if (intentMatch) {
148
+ const intent = intentMatch[1]
149
+ const timestamp = new Date().toISOString()
150
+ const intentEntry = `\n- timestamp: ${timestamp}\n ${intent.trim().replace(/\n/g, "\n ")}\n`
151
+ await fs.appendFile(path.join(historyDir, "intent.toon"), intentEntry)
152
+ }
153
+ } catch (e) {}
154
+ }
155
+
156
+ export function generateActionTimeline(turns: Turn[]) {
157
+ const timeline: string[] = []
158
+
159
+ for (const turn of turns) {
160
+ if (turn.tools.length > 0) {
161
+ for (const tool of turn.tools) {
162
+ let detail = ""
163
+ if (tool.name === "bash" && tool.input?.command) {
164
+ detail = `command: '${tool.input.command}'`
165
+ } else if (tool.input) {
166
+ const inputStr = JSON.stringify(tool.input)
167
+ detail = `input: ${inputStr.length > 100 ? inputStr.slice(0, 100) + "..." : inputStr}`
168
+ }
169
+
170
+ let outputSummary = ""
171
+ if (tool.status === "failed") {
172
+ outputSummary = ` -> Error: ${tool.error || "Unknown error"}`
173
+ } else if (tool.output) {
174
+ const outStr = typeof tool.output === "string" ? tool.output : JSON.stringify(tool.output)
175
+ // Always include short outputs, or critical hints even in large outputs
176
+ if (outStr.length < 500) {
177
+ outputSummary = ` -> Output: ${outStr.replace(/\n/g, " ").trim()}`
178
+ } else if (outStr.includes("Please finish editing")) {
179
+ const hintMatch = outStr.match(/Please finish editing.*?\./)
180
+ outputSummary = ` -> Hint: ${hintMatch ? hintMatch[0] : "Requirement validation failed"}`
181
+ } else {
182
+ // Summarize large outputs instead of omitting them
183
+ const preview = outStr.replace(/\n/g, " ").trim().slice(0, 150)
184
+ outputSummary = ` -> Output: [Truncated from ${outStr.length} chars] "${preview}..."`
185
+ }
186
+ }
187
+
188
+ timeline.push(
189
+ `Turn ${turn.id}: Tool '${tool.name}' executed (${detail}) -> Result: ${tool.status}${outputSummary}`,
190
+ )
191
+ }
192
+ }
193
+ }
194
+
195
+ return timeline.join("\n")
196
+ }
197
+
198
+ export async function analyze(sessionID: string, chatHistory: MessageV2.WithParts[], workspaceRoot?: string) {
199
+ const turns = await getTurns(sessionID)
200
+
201
+ const summary = {
202
+ tpsList: [] as number[],
203
+ ttftMsList: [] as number[],
204
+ jsonRepairs: 0,
205
+ interventions: [] as string[],
206
+ mcpxFailures: [] as string[],
207
+ }
208
+
209
+ for (const turn of turns) {
210
+ // Collect metrics from lines in the turn (legacy or metadata)
211
+ for (const line of turn.lines) {
212
+ if (line.metadata?.event === "END_GENERATE" && line.metadata.metrics) {
213
+ try {
214
+ const metrics = JSON.parse(line.metadata.metrics)
215
+ if (metrics.tps) summary.tpsList.push(metrics.tps)
216
+ if (metrics.ttftMs) summary.ttftMsList.push(metrics.ttftMs)
217
+ if (metrics.json_repaired) summary.jsonRepairs++
218
+ } catch (e) {}
219
+ }
220
+ }
221
+
222
+ // Collect failures and interventions
223
+ summary.mcpxFailures.push(...turn.mcpxFailures)
224
+ summary.interventions.push(...turn.interventions)
225
+
226
+ // Also check tool statuses for failures
227
+ for (const tool of turn.tools) {
228
+ if (tool.status === "failed") {
229
+ summary.mcpxFailures.push(`${tool.name}: ${tool.error || "Unknown error"}`)
230
+ }
231
+ }
232
+ }
233
+
234
+ const actionTimeline = generateActionTimeline(turns)
235
+
236
+ const recentThoughts: string[] = []
237
+ const touchedFiles = new Set<string>()
238
+ let interruptedToolCall: { tool: string; raw: string } | undefined = undefined
239
+
240
+ // Use turns for touched files too
241
+ for (const turn of turns) {
242
+ for (const tool of turn.tools) {
243
+ const input = tool.input as any
244
+
245
+ if (["edit", "write", "read", "replace", "read_file", "write_file", "view_file"].includes(tool.name)) {
246
+ if (input?.filePath) touchedFiles.add(input.filePath)
247
+ if (input?.file_path) touchedFiles.add(input.file_path)
248
+ } else if (tool.name.startsWith("mcpx [") && input?.args) {
249
+ const args = input.args as Record<string, any>
250
+ if (args?.file_path) touchedFiles.add(args.file_path)
251
+ if (args?.path) touchedFiles.add(args.path)
252
+ } else if (tool.name === "bash" && typeof input?.command === "string") {
253
+ const fileMatches = input.command.match(/[\w.\-\/]+\.(ts|js|json|md|txt|py|go|rs)/g)
254
+ if (fileMatches) {
255
+ for (const m of fileMatches) touchedFiles.add(m)
256
+ }
257
+ }
258
+ }
259
+ }
260
+
261
+ const recentMessages = chatHistory.slice(-50)
262
+ const lastUserIndex = recentMessages.findLastIndex((m) => m.info.role === "user")
263
+
264
+ for (let i = 0; i < recentMessages.length; i++) {
265
+ const msg = recentMessages[i]
266
+ const isMostRecentTurn = i > lastUserIndex
267
+
268
+ for (const part of msg.parts) {
269
+ if (part.type === "reasoning" && part.text) {
270
+ if (isMostRecentTurn || part.text.length < 500) {
271
+ recentThoughts.push(part.text)
272
+ } else {
273
+ // Summarize older, large thinking blocks
274
+ const preview = part.text.slice(0, 150).replace(/\n/g, " ").trim()
275
+ const tail = part.text.slice(-150).replace(/\n/g, " ").trim()
276
+ recentThoughts.push(`[Older Thought Summary: ${part.text.length} chars] ${preview}... (omitted) ...${tail}`)
277
+ }
278
+ }
279
+
280
+ if (part.type === "tool" && "state" in part) {
281
+ // Check for interrupted tool calls in the most recent turn
282
+ if (isMostRecentTurn && (part.state.status === "pending" || part.state.status === "error") && "raw" in part.state && part.state.raw) {
283
+ interruptedToolCall = { tool: part.tool, raw: part.state.raw as string }
284
+ }
285
+
286
+ // Fallback to chat history for files if telemetry is sparse
287
+ const input = part.state.input as any
288
+ if (["edit", "write", "read", "replace", "read_file", "write_file", "view_file"].includes(part.tool)) {
289
+ const filePath = input?.filePath || input?.file_path
290
+ if (filePath) touchedFiles.add(filePath)
291
+ } else if (part.tool === "mcpx" && input?.args) {
292
+ const args = input.args as Record<string, any>
293
+ if (args?.file_path) touchedFiles.add(args.file_path)
294
+ if (args?.path) touchedFiles.add(args.path)
295
+ }
296
+ }
297
+ }
298
+ }
299
+
300
+ // GROUND TRUTH VERIFICATION: Check which files actually exist on disk to prevent artifact ghosting
301
+ const verifiedFiles: string[] = []
302
+ const missingFiles: string[] = []
303
+
304
+ if (workspaceRoot) {
305
+ const uniqueTouched = Array.from(touchedFiles)
306
+ await Promise.all(
307
+ uniqueTouched.map(async (file) => {
308
+ // Robust path resolution to handle both relative and absolute paths in the container
309
+ const normalizedFile = file.startsWith(workspaceRoot) ? file : path.join(workspaceRoot, file)
310
+ try {
311
+ await fs.stat(normalizedFile)
312
+ verifiedFiles.push(file)
313
+ } catch (e) {
314
+ missingFiles.push(file)
315
+ }
316
+ }),
317
+ )
318
+ }
319
+
320
+ return {
321
+ telemetry: summary,
322
+ actionTimeline,
323
+ thoughts: recentThoughts,
324
+ touchedFiles: Array.from(touchedFiles),
325
+ verifiedFiles: verifiedFiles.length > 0 ? verifiedFiles : undefined,
326
+ missingFiles: missingFiles.length > 0 ? missingFiles : undefined,
327
+ interruptedToolCall,
328
+ lastUserMessage: chatHistory.findLast((m) => m.info.role === "user"),
329
+ }
330
+ }
331
+ }