@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,328 @@
1
+ import fs from "fs/promises"
2
+ import path from "path"
3
+ import { zodToJsonSchema } from "zod-to-json-schema"
4
+ import { Config } from "../config/config"
5
+ import { Log } from "../util/log"
6
+
7
+ const log = Log.create({ service: "project-init" })
8
+
9
+ const AGENTS_MD_CONTENT = `# Epoch CLI Agent Guidelines
10
+
11
+ ## 1. Mandatory Workflows
12
+ - **\`mcpx\` (Unified MCP Interface)**: Use for ALL MCP interactions (spec, map, ground, github).
13
+ - **Adding Servers**: When asked to install or configure a new MCP server, you MUST follow the SOP defined in \`docs/MCP_config_guide.md\`.
14
+ - **Syntax**: Pass arguments via standard flags, \`key=value\` strings, or structured JSON.
15
+ - **Self-Discovery**: Use \`tool="--help"\` or \`args=["--help"]\` to inspect servers/tools.
16
+ - **\`spec\` (State Management)**: Maintain project state via \`mcpx\` server="spec".
17
+ - **Linear Progression**: \`sc_init\` -> \`write Specification.md\` -> \`sc_approve\` -> \`write Tasks.json\` -> \`sc_approve\` -> \`Build\`.
18
+ - **Arguments**: \`sc_init\` MANDATES the \`name\` parameter (e.g., \`flags: {"name": "my-feature"}\`). \`sc_plan\` and \`sc_approve\` take NO arguments. \`sc_todo_*\` requires \`--id\`.
19
+ - **\`map\` (Architectural Discovery)**: Use \`mcpx\` server="map" for navigation. Prefer \`pm_status\` and \`pm_query\` over manual \`ls\` or \`glob\`.
20
+
21
+ ## 2. Enforcement
22
+ - **Drafting Wall**: All template tags in \`Specification.md\` must be cleared and \`template_tags_present\` set to \`false\` before implementation.
23
+ - **Orientation**: Trust the provided context. If \`ORIENTATION_REQUIREMENTS: SATISFIED\` is present, do not repeat discovery tools.
24
+ - **YOLO Mode**: Proceed autonomously until \`task_complete\` is called.
25
+
26
+ ## 3. Subagent Guardrails
27
+ - **No State Mutation**: Subagents (e.g., \`@explore\`, \`@general\`) are STRICTLY FORBIDDEN from calling \`sc_init\` or \`sc_approve\`. Only the primary \`plan\` or \`build\` agent may mutate the global project lifecycle state.
28
+ - **Architectural Discovery**: Subagents MUST prioritize \`mcpx map\` tools (\`pm_query\` for context, \`pm_fetch_symbol\` for precise code extraction) to navigate the codebase efficiently. Avoid wide \`glob\` or \`read\` loops on large files.
29
+ `
30
+
31
+ const MCP_CONFIG_GUIDE_CONTENT = `# Guide: Setting Up MCP Servers with \`mcpx-rust\`
32
+
33
+ This guide explains how to configure Model Context Protocol (MCP) servers within this project using the \`mcpx-rust\` CLI utility. By using \`mcpx\`, we reduce prompt bloat by replacing massive JSON schemas with a single, discoverable CLI interface.
34
+
35
+ ## 1. Installation
36
+
37
+ \`mcpx-rust\` is the Rust-based binary used in this project to turn MCP servers into composable shell commands.
38
+
39
+ \`\`\`bash
40
+ # Via Cargo
41
+ cargo install mcpx-rust
42
+ \`\`\`
43
+
44
+ ## 2. Registering Servers
45
+
46
+ \`mcpx-rust\` stores its configuration in \`~/.config/mcpx/config.toml\`. You must edit this file manually to add or modify servers.
47
+
48
+ ### Manual Configuration
49
+ Add entries to the \`[mcp_servers]\` section in \`~/.config/mcpx/config.toml\`:
50
+
51
+ \`\`\`toml
52
+ [mcp_servers.map]
53
+ command = "project-map-cli-rust"
54
+ args = ["mcp"]
55
+
56
+ [mcp_servers.spec]
57
+ command = "deliver-cli"
58
+ args = ["mcp"]
59
+
60
+ [mcp_servers.github]
61
+ command = "npx"
62
+ args = ["-y", "@modelcontextprotocol/server-github"]
63
+ env = { GITHUB_TOKEN = "\${GITHUB_TOKEN}" }
64
+ \`\`\`
65
+
66
+ ## 3. \`epochcli\` / \`gemini-cli\` Integration
67
+
68
+ To enable \`mcpx\` integration, update your configuration file (e.g., \`.epochcli/epochcli.jsonc\` or \`.gemini/settings.json\`):
69
+
70
+ \`\`\`jsonc
71
+ {
72
+ "mcpx": {
73
+ "enabled": true,
74
+ "binaryPath": "mcpx-rust" // Optional: defaults to 'mcpx-rust'
75
+ },
76
+ "mcp": {} // Leave empty to disable standard schema-based MCP tools
77
+ }
78
+ \`\`\`
79
+
80
+ When enabled, the CLI will only expose a single \`mcpx\` tool to the LLM. The agent will discover capabilities dynamically by running \`mcpx <server> --help\`.
81
+
82
+ ## 4. Usage and Composition
83
+
84
+ Once configured, tools can be called using standard shell composition:
85
+
86
+ \`\`\`bash
87
+ # List all servers
88
+ mcpx-rust list
89
+
90
+ # List tools for a server
91
+ mcpx-rust github
92
+
93
+ # Inspect a specific tool's schema
94
+ mcpx-rust github search-repositories --help
95
+
96
+ # Call a tool and pipe to jq
97
+ mcpx-rust github search-repositories query=mcp --json | jq -r '.content[0].text'
98
+ \`\`\`
99
+
100
+ Note: \`mcpx-rust\` uses \`key=value\` syntax for positional arguments or standard \`--flag value\` syntax depending on the tool's implementation.
101
+
102
+ ## 5. Project Servers
103
+
104
+ The following project-specific servers are pre-configured. Agents should use the unified \`mcpx\` tool for all operations:
105
+
106
+ - **\`spec\`**: Management of specification-driven development.
107
+ - \`mcpx spec sc_status\`: View project health and next steps.
108
+ - \`mcpx spec sc_todo_start\`: Mark a task as active.
109
+ - **\`map\`**: Architectural mapping and symbol analysis.
110
+ - \`mcpx map pm_query\`: Search for symbols or get file context.
111
+ - \`mcpx map pm_plan\`: Analyze the architectural impact of a change.
112
+ - **\`ground\`**: Synthesis of behavioral rules and operational facts.
113
+ - \`mcpx ground gt_status\`: Check current project rules.
114
+ - \`mcpx ground gt_refresh\`: Force a refresh of the project constitution.
115
+
116
+ ## 6. Agent SOP: Adding a New Server
117
+
118
+ When an agent is instructed to add or install a new MCP server, it MUST follow this sequence to ensure the server is properly registered and discoverable:
119
+
120
+ 1. **Identify the Server**: Determine the correct command (e.g., \`npx -y package-name\`) or binary path for the requested MCP server.
121
+ 2. **Register the Server**: Update the configuration in \`~/.config/mcpx/config.toml\`.
122
+ - *Note*: Agents must use \`echo\` or \`cat <<EOF\` via \`run_shell_command\` to modify this file, as it lives outside the standard workspace directory.
123
+ 3. **Verify Installation**: Run \`mcpx-rust list\` and \`mcpx-rust <new_server> --help\` to ensure the routing engine recognizes the new server and the tool schema is accessible.
124
+ 4. **Update Project Knowledge**: Update \`AGENTS.md\` (or the relevant instruction file) with a brief summary of the new server's capabilities and its \`mcpx\` syntax so that future agent turns can utilize the new tools.
125
+ `
126
+
127
+ const MODEL_CONFIG_GUIDE_CONTENT = `# Model Configuration Guide
128
+
129
+ Epoch CLI utilizes a **Dual-Model Architecture** optimized for high-performance coding and reliable background supervision. This environment uses a unified proxy architecture (**llama-swap**) to manage model transitions efficiently.
130
+
131
+ ## 1. Unified Architecture (llama-swap)
132
+
133
+ Instead of managing separate URLs and ports, all models are served through a single transparent proxy on one port. This allows the system to dynamically swap models in VRAM as needed while maintaining a consistent client configuration.
134
+
135
+ * **Unified API Endpoint:** \`http://localhost:8085/v1\`
136
+ * **Protocol:** OpenAI Compatible
137
+ * **Authentication:** Shared API Key (e.g., \`2250\`)
138
+
139
+ ## 2. Configuration (\`epochcli.jsonc\`)
140
+
141
+ You can configure Epoch CLI to use either a single unified endpoint for both main and side roles, or a dual-model configuration that leverages the \`llama-swap\` proxy.
142
+
143
+ ### Option A: Single Endpoint Configuration (Recommended for High Context)
144
+
145
+ This setup uses one model for both roles. It is ideal for maximizing the context window (e.g., 64k) and eliminating the 15-20 second "cold start" delay associated with swapping models.
146
+
147
+ \`\`\`jsonc
148
+ {
149
+ "model": "local-unified/qwen-unified",
150
+ "side_model": "local-unified/qwen-unified",
151
+ "provider": {
152
+ "local-unified": {
153
+ "npm": "@ai-sdk/openai-compatible",
154
+ "name": "Local Unified (Qwen 64k)",
155
+ "options": {
156
+ "baseURL": "http://localhost:8085/v1",
157
+ "apiKey": "2250"
158
+ },
159
+ "models": {
160
+ "qwen-unified": {
161
+ "name": "Qwen Unified 64k",
162
+ "limit": { "context": 64000, "output": 4096 }
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ \`\`\`
169
+
170
+ ### Option B: Dual-Model Configuration (llama-swap)
171
+
172
+ This setup defines separate providers for main and side roles. The proxy handles routing based on the model ID. This is useful when you want a dedicated smaller model for clerk duties to save compute or when specific roles require different model capabilities.
173
+
174
+ \`\`\`jsonc
175
+ {
176
+ "model": "local-main/qwen3.6-35b-a3b-coding",
177
+ "side_model": "local-side/nemotron-3-nano",
178
+ "provider": {
179
+ "local-main": {
180
+ "npm": "@ai-sdk/openai-compatible",
181
+ "name": "Local Main (Coding)",
182
+ "options": {
183
+ "baseURL": "http://localhost:8085/v1",
184
+ "apiKey": "2250"
185
+ },
186
+ "models": {
187
+ "qwen3.6-35b-a3b-coding": {
188
+ "name": "Qwen 3.6 35B Coding",
189
+ "limit": { "context": 64000, "output": 4096 }
190
+ }
191
+ }
192
+ },
193
+ "local-side": {
194
+ "npm": "@ai-sdk/openai-compatible",
195
+ "name": "Local Side (Clerk)",
196
+ "options": {
197
+ "baseURL": "http://localhost:8085/v1",
198
+ "apiKey": "2250"
199
+ },
200
+ "models": {
201
+ "nemotron-3-nano": {
202
+ "name": "Nemotron 3 Nano",
203
+ "limit": { "context": 32000, "output": 2048 }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ }
209
+ \`\`\`
210
+
211
+ ### Switching Between Modes
212
+
213
+ To switch modes, simply update the \`model\`, \`side_model\`, and \`provider\` fields in your \`.epochcli/epochcli.jsonc\` file to match the desired configuration block. The CLI will automatically pick up the changes on the next execution.
214
+
215
+ ## 3. How Epoch CLI Identifies Models
216
+
217
+ Epoch CLI uses **keyword matching** on the Model ID string to apply specific architectural optimizations. You do not need to manually configure prompts or behaviors for different models as long as the ID is named correctly:
218
+
219
+ * **Qwen Optimized:** If the ID contains \`"qwen"\` (e.g., \`qwen3.6-35b-a3b-coding\`), the CLI automatically sets the temperature to \`0.55\` and Top-P to \`1.0\`.
220
+ * **Gemma Optimized:** If the ID contains \`"gemma-4"\`, the CLI enables reasoning token injection (\`<|think|>\`), specialized system prompts, and the Three-Stage Sanitizer to repair potential JSON errors.
221
+
222
+ ## 4. Operational Considerations
223
+
224
+ ### The "Cold Start" (Model Swapping)
225
+ The environment uses a **SWAP approach** to maximize VRAM for high-context models. Only one model is active in memory at a time.
226
+ * **Instant Response:** If you request the model that is already "hot" in memory.
227
+ * **Swap Delay:** If you request a model that is currently swapped out, the proxy will load it automatically. This adds a **15–20 second delay** to the first request.
228
+
229
+ ### Context Persistence & TTL
230
+ Models stay active in VRAM for **60 minutes** of inactivity before being automatically unloaded. This ensures subsequent requests within the same hour are nearly instantaneous.
231
+
232
+ ## 5. Monitoring & Maintenance
233
+
234
+ * **Dashboard:** You can monitor which model is currently active and view proxy status at \`http://localhost:8085/ui\`.
235
+ * **Restart Stack:** If you need to restart the entire dual-model stack, use the provided launch script:
236
+ \`\`\`bash
237
+ /home/llm/utils/launch/launch-dual.sh
238
+ \`\`\`
239
+ `
240
+
241
+ const DEFAULT_EPOCHCLI_JSONC = `{
242
+ "$schema": "./config.json",
243
+ "model": "local-unified/qwen-unified",
244
+ "side_model": "local-unified/qwen-unified",
245
+ "provider": {
246
+ "local-unified": {
247
+ "npm": "@ai-sdk/openai-compatible",
248
+ "name": "Local Unified (Qwen 64k)",
249
+ "options": {
250
+ "baseURL": "http://localhost:8085/v1",
251
+ "apiKey": "2250"
252
+ },
253
+ "models": {
254
+ "qwen-unified": {
255
+ "name": "Qwen Unified 64k",
256
+ "limit": {
257
+ "context": 64000,
258
+ "output": 4096
259
+ }
260
+ }
261
+ }
262
+ }
263
+ },
264
+ "permission": {
265
+ "edit": {
266
+ "packages/opencode/migration/*": "deny"
267
+ }
268
+ },
269
+ "mcpx": {
270
+ "enabled": true
271
+ }
272
+ }
273
+ `
274
+
275
+ export async function initProjectFiles(directory: string, worktree: string) {
276
+ try {
277
+ const epochcliDir = path.join(worktree, ".epochcli")
278
+
279
+ try {
280
+ await fs.access(epochcliDir)
281
+ return // Already initialized
282
+ } catch {
283
+ // Doesn't exist, proceed with initialization
284
+ }
285
+
286
+ log.info("Initializing new project files", { worktree })
287
+
288
+ // Create .epochcli directory
289
+ await fs.mkdir(epochcliDir, { recursive: true })
290
+
291
+ // Generate JSON Schema
292
+ const schema = zodToJsonSchema(Config.Info, {
293
+ name: "Config",
294
+ $refStrategy: "none",
295
+ })
296
+
297
+ // Write config.json (schema)
298
+ await fs.writeFile(
299
+ path.join(epochcliDir, "config.json"),
300
+ JSON.stringify(schema, null, 2)
301
+ )
302
+
303
+ // Write default epochcli.jsonc
304
+ await fs.writeFile(
305
+ path.join(epochcliDir, "epochcli.jsonc"),
306
+ DEFAULT_EPOCHCLI_JSONC
307
+ )
308
+
309
+ // Setup docs
310
+ const docsDir = path.join(epochcliDir, "docs")
311
+ await fs.mkdir(docsDir, { recursive: true })
312
+ await fs.writeFile(path.join(docsDir, "MCP_config_guide.md"), MCP_CONFIG_GUIDE_CONTENT)
313
+ await fs.writeFile(path.join(docsDir, "model_config.md"), MODEL_CONFIG_GUIDE_CONTENT)
314
+
315
+ // Setup AGENTS.md in the current directory if it doesn't exist
316
+ const agentsFile = path.join(directory, "AGENTS.md")
317
+ try {
318
+ await fs.access(agentsFile)
319
+ } catch {
320
+ await fs.writeFile(agentsFile, AGENTS_MD_CONTENT)
321
+ log.info("Created AGENTS.md", { path: agentsFile })
322
+ }
323
+
324
+ log.info("Project initialized successfully", { dir: epochcliDir })
325
+ } catch (error) {
326
+ log.error("Failed to initialize project files", { error })
327
+ }
328
+ }
@@ -0,0 +1,175 @@
1
+ import { GlobalBus } from "@/bus/global"
2
+ import { disposeInstance } from "@/effect/instance-registry"
3
+ import { Filesystem } from "@/util/filesystem"
4
+ import { iife } from "@/util/iife"
5
+ import { Log } from "@/util/log"
6
+ import { Context } from "../util/context"
7
+ import { Project } from "./project"
8
+ import { State } from "./state"
9
+
10
+ export interface InstanceContext {
11
+ directory: string
12
+ worktree: string
13
+ project: Project.Info
14
+ }
15
+
16
+ const context = Context.create<InstanceContext>("instance")
17
+ const cache = new Map<string, Promise<InstanceContext>>()
18
+
19
+ const disposal = {
20
+ all: undefined as Promise<void> | undefined,
21
+ }
22
+
23
+ function emit(directory: string) {
24
+ GlobalBus.emit("event", {
25
+ directory,
26
+ payload: {
27
+ type: "server.instance.disposed",
28
+ properties: {
29
+ directory,
30
+ },
31
+ },
32
+ })
33
+ }
34
+
35
+ function boot(input: { directory: string; init?: () => Promise<any>; project?: Project.Info; worktree?: string }) {
36
+ return iife(async () => {
37
+ const ctx =
38
+ input.project && input.worktree
39
+ ? {
40
+ directory: input.directory,
41
+ worktree: input.worktree,
42
+ project: input.project,
43
+ }
44
+ : await Project.fromDirectory(input.directory).then(({ project, sandbox }) => ({
45
+ directory: input.directory,
46
+ worktree: sandbox,
47
+ project,
48
+ }))
49
+ await context.provide(ctx, async () => {
50
+ await input.init?.()
51
+ })
52
+ return ctx
53
+ })
54
+ }
55
+
56
+ function track(directory: string, next: Promise<InstanceContext>) {
57
+ const task = next.catch((error) => {
58
+ if (cache.get(directory) === task) cache.delete(directory)
59
+ throw error
60
+ })
61
+ cache.set(directory, task)
62
+ return task
63
+ }
64
+
65
+ export const Instance = {
66
+ async provide<R>(input: { directory: string; init?: () => Promise<any>; fn: () => R }): Promise<R> {
67
+ const directory = Filesystem.resolve(input.directory)
68
+ let existing = cache.get(directory)
69
+ if (!existing) {
70
+ Log.Default.info("creating instance", { directory })
71
+ existing = track(
72
+ directory,
73
+ boot({
74
+ directory,
75
+ init: input.init,
76
+ }),
77
+ )
78
+ }
79
+ const ctx = await existing
80
+ return context.provide(ctx, async () => {
81
+ return input.fn()
82
+ })
83
+ },
84
+ get current() {
85
+ return context.use()
86
+ },
87
+ get directory() {
88
+ return context.use().directory
89
+ },
90
+ get worktree() {
91
+ return context.use().worktree
92
+ },
93
+ get project() {
94
+ return context.use().project
95
+ },
96
+ /**
97
+ * Check if a path is within the project boundary.
98
+ * Returns true if path is inside Instance.directory OR Instance.worktree.
99
+ * Paths within the worktree but outside the working directory should not trigger external_directory permission.
100
+ */
101
+ containsPath(filepath: string) {
102
+ if (Filesystem.contains(Instance.directory, filepath)) return true
103
+ // Non-git projects set worktree to "/" which would match ANY absolute path.
104
+ // Skip worktree check in this case to preserve external_directory permissions.
105
+ if (Instance.worktree === "/") return false
106
+ return Filesystem.contains(Instance.worktree, filepath)
107
+ },
108
+ /**
109
+ * Captures the current instance ALS context and returns a wrapper that
110
+ * restores it when called. Use this for callbacks that fire outside the
111
+ * instance async context (native addons, event emitters, timers, etc.).
112
+ */
113
+ bind<F extends (...args: any[]) => any>(fn: F): F {
114
+ const ctx = context.use()
115
+ return ((...args: any[]) => context.provide(ctx, () => fn(...args))) as F
116
+ },
117
+ /**
118
+ * Run a synchronous function within the given instance context ALS.
119
+ * Use this to bridge from Effect (where InstanceRef carries context)
120
+ * back to sync code that reads Instance.directory from ALS.
121
+ */
122
+ restore<R>(ctx: InstanceContext, fn: () => R): R {
123
+ return context.provide(ctx, fn)
124
+ },
125
+ state<S>(init: () => S, dispose?: (state: Awaited<S>) => Promise<void>): () => S {
126
+ return State.create(() => Instance.directory, init, dispose)
127
+ },
128
+ async reload(input: { directory: string; init?: () => Promise<any>; project?: Project.Info; worktree?: string }) {
129
+ const directory = Filesystem.resolve(input.directory)
130
+ Log.Default.info("reloading instance", { directory })
131
+ await Promise.all([State.dispose(directory), disposeInstance(directory)])
132
+ cache.delete(directory)
133
+ const next = track(directory, boot({ ...input, directory }))
134
+ emit(directory)
135
+ return await next
136
+ },
137
+ async dispose() {
138
+ const directory = Instance.directory
139
+ Log.Default.info("disposing instance", { directory })
140
+ await Promise.all([State.dispose(directory), disposeInstance(directory)])
141
+ cache.delete(directory)
142
+ emit(directory)
143
+ },
144
+ async disposeAll() {
145
+ if (disposal.all) return disposal.all
146
+
147
+ disposal.all = iife(async () => {
148
+ Log.Default.info("disposing all instances")
149
+ const entries = [...cache.entries()]
150
+ for (const [key, value] of entries) {
151
+ if (cache.get(key) !== value) continue
152
+
153
+ const ctx = await value.catch((error) => {
154
+ Log.Default.warn("instance dispose failed", { key, error })
155
+ return undefined
156
+ })
157
+
158
+ if (!ctx) {
159
+ if (cache.get(key) === value) cache.delete(key)
160
+ continue
161
+ }
162
+
163
+ if (cache.get(key) !== value) continue
164
+
165
+ await context.provide(ctx, async () => {
166
+ await Instance.dispose()
167
+ })
168
+ }
169
+ }).finally(() => {
170
+ disposal.all = undefined
171
+ })
172
+
173
+ return disposal.all
174
+ },
175
+ }
@@ -0,0 +1,16 @@
1
+ import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core"
2
+ import { Timestamps } from "../storage/schema.sql"
3
+ import type { ProjectID } from "./schema"
4
+
5
+ export const ProjectTable = sqliteTable("project", {
6
+ id: text().$type<ProjectID>().primaryKey(),
7
+ worktree: text().notNull(),
8
+ vcs: text(),
9
+ name: text(),
10
+ icon_url: text(),
11
+ icon_color: text(),
12
+ ...Timestamps,
13
+ time_initialized: integer(),
14
+ sandboxes: text({ mode: "json" }).notNull().$type<string[]>(),
15
+ commands: text({ mode: "json" }).$type<{ start?: string }>(),
16
+ })