anymous 1.0.0

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 (415) hide show
  1. package/README.md +15 -0
  2. package/bin/anymous.cjs +45 -0
  3. package/package.json +155 -0
  4. package/src/account/account.ts +473 -0
  5. package/src/account/repo.ts +171 -0
  6. package/src/account/schema.ts +99 -0
  7. package/src/account/url.ts +8 -0
  8. package/src/acp/agent.ts +95 -0
  9. package/src/acp/config-option.ts +203 -0
  10. package/src/acp/content.ts +269 -0
  11. package/src/acp/directory.ts +212 -0
  12. package/src/acp/error.ts +97 -0
  13. package/src/acp/event.ts +342 -0
  14. package/src/acp/permission.ts +254 -0
  15. package/src/acp/profile.ts +42 -0
  16. package/src/acp/service.ts +1097 -0
  17. package/src/acp/session.ts +232 -0
  18. package/src/acp/tool.ts +364 -0
  19. package/src/acp/usage.ts +239 -0
  20. package/src/agent/agent.ts +581 -0
  21. package/src/agent/generate.txt +75 -0
  22. package/src/agent/prompt/compaction.txt +9 -0
  23. package/src/agent/prompt/debug-tools.txt +41 -0
  24. package/src/agent/prompt/exe-extractor.txt +37 -0
  25. package/src/agent/prompt/explore.txt +18 -0
  26. package/src/agent/prompt/memory-dump.txt +34 -0
  27. package/src/agent/prompt/reverser-automator.txt +24 -0
  28. package/src/agent/prompt/reverser-binary.txt +25 -0
  29. package/src/agent/prompt/reverser-dynamic.txt +29 -0
  30. package/src/agent/prompt/reverser-source.txt +22 -0
  31. package/src/agent/prompt/reverser-static.txt +28 -0
  32. package/src/agent/prompt/summary.txt +11 -0
  33. package/src/agent/prompt/title.txt +44 -0
  34. package/src/agent/subagent-permissions.ts +27 -0
  35. package/src/audio.d.ts +14 -0
  36. package/src/auth/index.ts +97 -0
  37. package/src/background/job.ts +37 -0
  38. package/src/bus/global.ts +22 -0
  39. package/src/cli/bootstrap.ts +11 -0
  40. package/src/cli/cmd/account.ts +264 -0
  41. package/src/cli/cmd/acp.ts +73 -0
  42. package/src/cli/cmd/agent.ts +259 -0
  43. package/src/cli/cmd/attach.ts +148 -0
  44. package/src/cli/cmd/cmd.ts +7 -0
  45. package/src/cli/cmd/db.ts +62 -0
  46. package/src/cli/cmd/debug/agent.handler.ts +193 -0
  47. package/src/cli/cmd/debug/agent.ts +27 -0
  48. package/src/cli/cmd/debug/config.ts +14 -0
  49. package/src/cli/cmd/debug/file.ts +73 -0
  50. package/src/cli/cmd/debug/index.ts +87 -0
  51. package/src/cli/cmd/debug/lsp.ts +50 -0
  52. package/src/cli/cmd/debug/ripgrep.ts +79 -0
  53. package/src/cli/cmd/debug/scrap.ts +16 -0
  54. package/src/cli/cmd/debug/skill.ts +15 -0
  55. package/src/cli/cmd/debug/snapshot.ts +50 -0
  56. package/src/cli/cmd/debug/startup.ts +11 -0
  57. package/src/cli/cmd/debug/v2.ts +42 -0
  58. package/src/cli/cmd/export.ts +292 -0
  59. package/src/cli/cmd/generate.ts +54 -0
  60. package/src/cli/cmd/github.handler.ts +1593 -0
  61. package/src/cli/cmd/github.shared.ts +30 -0
  62. package/src/cli/cmd/github.ts +42 -0
  63. package/src/cli/cmd/import.ts +230 -0
  64. package/src/cli/cmd/mcp.ts +840 -0
  65. package/src/cli/cmd/models.ts +66 -0
  66. package/src/cli/cmd/plug.ts +230 -0
  67. package/src/cli/cmd/pr.ts +115 -0
  68. package/src/cli/cmd/prompt-display.ts +1 -0
  69. package/src/cli/cmd/providers.ts +534 -0
  70. package/src/cli/cmd/run/demo.ts +1274 -0
  71. package/src/cli/cmd/run/entry.body.ts +205 -0
  72. package/src/cli/cmd/run/footer.command.tsx +1070 -0
  73. package/src/cli/cmd/run/footer.menu.tsx +351 -0
  74. package/src/cli/cmd/run/footer.permission.tsx +472 -0
  75. package/src/cli/cmd/run/footer.prompt.tsx +1315 -0
  76. package/src/cli/cmd/run/footer.question.tsx +573 -0
  77. package/src/cli/cmd/run/footer.subagent.tsx +175 -0
  78. package/src/cli/cmd/run/footer.ts +1129 -0
  79. package/src/cli/cmd/run/footer.view.tsx +945 -0
  80. package/src/cli/cmd/run/footer.width.ts +27 -0
  81. package/src/cli/cmd/run/permission.shared.ts +256 -0
  82. package/src/cli/cmd/run/prompt.editor.ts +157 -0
  83. package/src/cli/cmd/run/prompt.shared.ts +153 -0
  84. package/src/cli/cmd/run/question.shared.ts +340 -0
  85. package/src/cli/cmd/run/runtime.boot.ts +202 -0
  86. package/src/cli/cmd/run/runtime.lifecycle.ts +406 -0
  87. package/src/cli/cmd/run/runtime.queue.ts +349 -0
  88. package/src/cli/cmd/run/runtime.shared.ts +17 -0
  89. package/src/cli/cmd/run/runtime.stdin.ts +37 -0
  90. package/src/cli/cmd/run/runtime.ts +814 -0
  91. package/src/cli/cmd/run/scrollback.shared.ts +92 -0
  92. package/src/cli/cmd/run/scrollback.surface.ts +431 -0
  93. package/src/cli/cmd/run/scrollback.writer.tsx +352 -0
  94. package/src/cli/cmd/run/session-data.ts +1113 -0
  95. package/src/cli/cmd/run/session-replay.ts +374 -0
  96. package/src/cli/cmd/run/session.shared.ts +196 -0
  97. package/src/cli/cmd/run/splash.ts +280 -0
  98. package/src/cli/cmd/run/stream.transport.ts +1462 -0
  99. package/src/cli/cmd/run/stream.ts +175 -0
  100. package/src/cli/cmd/run/subagent-data.ts +876 -0
  101. package/src/cli/cmd/run/theme.ts +690 -0
  102. package/src/cli/cmd/run/tool.ts +1486 -0
  103. package/src/cli/cmd/run/trace.ts +94 -0
  104. package/src/cli/cmd/run/turn-summary.ts +47 -0
  105. package/src/cli/cmd/run/types.ts +350 -0
  106. package/src/cli/cmd/run/variant.shared.ts +216 -0
  107. package/src/cli/cmd/run.ts +1011 -0
  108. package/src/cli/cmd/serve.ts +24 -0
  109. package/src/cli/cmd/session.ts +147 -0
  110. package/src/cli/cmd/stats.ts +393 -0
  111. package/src/cli/cmd/tui.ts +309 -0
  112. package/src/cli/cmd/uninstall.ts +353 -0
  113. package/src/cli/cmd/upgrade.ts +74 -0
  114. package/src/cli/cmd/web.ts +84 -0
  115. package/src/cli/effect/prompt.ts +37 -0
  116. package/src/cli/effect-cmd.ts +96 -0
  117. package/src/cli/error.ts +130 -0
  118. package/src/cli/heap.ts +45 -0
  119. package/src/cli/logo.ts +1 -0
  120. package/src/cli/network.ts +80 -0
  121. package/src/cli/tui/layer.ts +8 -0
  122. package/src/cli/tui/validate-session.ts +29 -0
  123. package/src/cli/tui/worker.ts +80 -0
  124. package/src/cli/ui.ts +132 -0
  125. package/src/cli/upgrade.ts +53 -0
  126. package/src/command/index.ts +177 -0
  127. package/src/command/template/initialize.txt +66 -0
  128. package/src/command/template/review.txt +101 -0
  129. package/src/config/agent.ts +59 -0
  130. package/src/config/command.ts +39 -0
  131. package/src/config/config.ts +681 -0
  132. package/src/config/entry-name.ts +19 -0
  133. package/src/config/managed.ts +69 -0
  134. package/src/config/markdown.ts +36 -0
  135. package/src/config/parse.ts +79 -0
  136. package/src/config/paths.ts +45 -0
  137. package/src/config/plugin.ts +79 -0
  138. package/src/config/tui-cwd.ts +5 -0
  139. package/src/config/tui-host-attention.ts +21 -0
  140. package/src/config/tui-migrate.ts +132 -0
  141. package/src/config/tui.ts +276 -0
  142. package/src/config/variable.ts +91 -0
  143. package/src/control-plane/adapters/index.ts +41 -0
  144. package/src/control-plane/adapters/worktree.ts +96 -0
  145. package/src/control-plane/dev/README.md +19 -0
  146. package/src/control-plane/dev/debug-workspace-plugin.ts +73 -0
  147. package/src/control-plane/types.ts +59 -0
  148. package/src/control-plane/util.ts +39 -0
  149. package/src/control-plane/workspace-adapter-runtime.ts +51 -0
  150. package/src/control-plane/workspace-context.ts +26 -0
  151. package/src/control-plane/workspace.ts +964 -0
  152. package/src/effect/app-node-builder-v1.ts +12 -0
  153. package/src/effect/app-runtime.ts +135 -0
  154. package/src/effect/bootstrap-runtime.ts +19 -0
  155. package/src/effect/bridge.ts +84 -0
  156. package/src/effect/config-service.ts +67 -0
  157. package/src/effect/instance-ref.ts +11 -0
  158. package/src/effect/instance-registry.ts +12 -0
  159. package/src/effect/instance-state.ts +69 -0
  160. package/src/effect/promise.ts +17 -0
  161. package/src/effect/run-service.ts +47 -0
  162. package/src/effect/runner.ts +217 -0
  163. package/src/effect/runtime-flags.ts +78 -0
  164. package/src/env/index.ts +41 -0
  165. package/src/event-manifest.ts +3 -0
  166. package/src/event-v2-bridge.ts +71 -0
  167. package/src/format/formatter.ts +404 -0
  168. package/src/format/index.ts +203 -0
  169. package/src/git/index.ts +348 -0
  170. package/src/id/id.ts +80 -0
  171. package/src/ide/index.ts +54 -0
  172. package/src/image/image.ts +172 -0
  173. package/src/index.ts +142 -0
  174. package/src/installation/index.ts +336 -0
  175. package/src/lsp/client.ts +650 -0
  176. package/src/lsp/diagnostic.ts +29 -0
  177. package/src/lsp/language.ts +121 -0
  178. package/src/lsp/launch.ts +21 -0
  179. package/src/lsp/lsp.ts +507 -0
  180. package/src/lsp/server.ts +1983 -0
  181. package/src/markdown.d.ts +4 -0
  182. package/src/mcp/auth.ts +163 -0
  183. package/src/mcp/browser.ts +37 -0
  184. package/src/mcp/catalog.ts +170 -0
  185. package/src/mcp/index.ts +1004 -0
  186. package/src/mcp/oauth-callback.ts +194 -0
  187. package/src/mcp/oauth-provider.ts +259 -0
  188. package/src/node.ts +4 -0
  189. package/src/patch/index.ts +686 -0
  190. package/src/permission/arity.ts +163 -0
  191. package/src/permission/evaluate.ts +1 -0
  192. package/src/permission/index.ts +229 -0
  193. package/src/plugin/azure.ts +26 -0
  194. package/src/plugin/cloudflare.ts +76 -0
  195. package/src/plugin/digitalocean.ts +325 -0
  196. package/src/plugin/github-copilot/copilot.ts +414 -0
  197. package/src/plugin/github-copilot/models.ts +258 -0
  198. package/src/plugin/index.ts +314 -0
  199. package/src/plugin/install.ts +439 -0
  200. package/src/plugin/loader.ts +237 -0
  201. package/src/plugin/meta.ts +188 -0
  202. package/src/plugin/openai/README.md +31 -0
  203. package/src/plugin/openai/codex.ts +565 -0
  204. package/src/plugin/openai/ws-pool.ts +270 -0
  205. package/src/plugin/openai/ws.ts +381 -0
  206. package/src/plugin/pty-environment.ts +24 -0
  207. package/src/plugin/shared.ts +323 -0
  208. package/src/plugin/snowflake-cortex.ts +507 -0
  209. package/src/plugin/tui/internal.ts +10 -0
  210. package/src/plugin/tui/runtime.ts +1131 -0
  211. package/src/plugin/xai.ts +626 -0
  212. package/src/project/bootstrap-service.ts +9 -0
  213. package/src/project/bootstrap.ts +58 -0
  214. package/src/project/instance-context.ts +24 -0
  215. package/src/project/instance-runtime.ts +16 -0
  216. package/src/project/instance-store.ts +213 -0
  217. package/src/project/project.ts +483 -0
  218. package/src/project/vcs.ts +423 -0
  219. package/src/provider/auth.ts +229 -0
  220. package/src/provider/error.ts +188 -0
  221. package/src/provider/model-status.ts +8 -0
  222. package/src/provider/provider.ts +2006 -0
  223. package/src/provider/transform.ts +1832 -0
  224. package/src/question/index.ts +161 -0
  225. package/src/question/schema.ts +4 -0
  226. package/src/server/auth.ts +48 -0
  227. package/src/server/event.ts +10 -0
  228. package/src/server/global-lifecycle.ts +28 -0
  229. package/src/server/init-projectors.ts +3 -0
  230. package/src/server/mdns.ts +47 -0
  231. package/src/server/projectors.ts +1 -0
  232. package/src/server/proxy-util.ts +48 -0
  233. package/src/server/routes/instance/httpapi/AGENTS.md +39 -0
  234. package/src/server/routes/instance/httpapi/api.ts +97 -0
  235. package/src/server/routes/instance/httpapi/errors.ts +193 -0
  236. package/src/server/routes/instance/httpapi/groups/config.ts +65 -0
  237. package/src/server/routes/instance/httpapi/groups/control-plane.ts +35 -0
  238. package/src/server/routes/instance/httpapi/groups/control.ts +76 -0
  239. package/src/server/routes/instance/httpapi/groups/event.ts +29 -0
  240. package/src/server/routes/instance/httpapi/groups/experimental.ts +275 -0
  241. package/src/server/routes/instance/httpapi/groups/file.ts +185 -0
  242. package/src/server/routes/instance/httpapi/groups/global.ts +136 -0
  243. package/src/server/routes/instance/httpapi/groups/instance.ts +206 -0
  244. package/src/server/routes/instance/httpapi/groups/mcp.ts +156 -0
  245. package/src/server/routes/instance/httpapi/groups/metadata.ts +18 -0
  246. package/src/server/routes/instance/httpapi/groups/permission.ts +61 -0
  247. package/src/server/routes/instance/httpapi/groups/project-copy.ts +32 -0
  248. package/src/server/routes/instance/httpapi/groups/project.ts +93 -0
  249. package/src/server/routes/instance/httpapi/groups/provider.ts +101 -0
  250. package/src/server/routes/instance/httpapi/groups/pty.ts +172 -0
  251. package/src/server/routes/instance/httpapi/groups/query.ts +12 -0
  252. package/src/server/routes/instance/httpapi/groups/question.ts +74 -0
  253. package/src/server/routes/instance/httpapi/groups/session.ts +462 -0
  254. package/src/server/routes/instance/httpapi/groups/sync.ts +113 -0
  255. package/src/server/routes/instance/httpapi/groups/tui.ts +208 -0
  256. package/src/server/routes/instance/httpapi/groups/workspace.ts +141 -0
  257. package/src/server/routes/instance/httpapi/handlers/config.ts +34 -0
  258. package/src/server/routes/instance/httpapi/handlers/control-plane.ts +37 -0
  259. package/src/server/routes/instance/httpapi/handlers/control.ts +43 -0
  260. package/src/server/routes/instance/httpapi/handlers/event.ts +99 -0
  261. package/src/server/routes/instance/httpapi/handlers/experimental.ts +193 -0
  262. package/src/server/routes/instance/httpapi/handlers/file.ts +139 -0
  263. package/src/server/routes/instance/httpapi/handlers/global.ts +156 -0
  264. package/src/server/routes/instance/httpapi/handlers/instance.ts +110 -0
  265. package/src/server/routes/instance/httpapi/handlers/mcp.ts +111 -0
  266. package/src/server/routes/instance/httpapi/handlers/permission.ts +41 -0
  267. package/src/server/routes/instance/httpapi/handlers/project-copy.ts +83 -0
  268. package/src/server/routes/instance/httpapi/handlers/project.ts +63 -0
  269. package/src/server/routes/instance/httpapi/handlers/provider.ts +113 -0
  270. package/src/server/routes/instance/httpapi/handlers/pty.ts +273 -0
  271. package/src/server/routes/instance/httpapi/handlers/question.ts +54 -0
  272. package/src/server/routes/instance/httpapi/handlers/session-errors.ts +21 -0
  273. package/src/server/routes/instance/httpapi/handlers/session.ts +442 -0
  274. package/src/server/routes/instance/httpapi/handlers/sync.ts +89 -0
  275. package/src/server/routes/instance/httpapi/handlers/tui.ts +131 -0
  276. package/src/server/routes/instance/httpapi/handlers/workspace.ts +102 -0
  277. package/src/server/routes/instance/httpapi/lifecycle.ts +54 -0
  278. package/src/server/routes/instance/httpapi/middleware/authorization.ts +150 -0
  279. package/src/server/routes/instance/httpapi/middleware/compression.ts +64 -0
  280. package/src/server/routes/instance/httpapi/middleware/cors-vary.ts +29 -0
  281. package/src/server/routes/instance/httpapi/middleware/error.ts +43 -0
  282. package/src/server/routes/instance/httpapi/middleware/fence.ts +25 -0
  283. package/src/server/routes/instance/httpapi/middleware/instance-context.ts +43 -0
  284. package/src/server/routes/instance/httpapi/middleware/proxy.ts +108 -0
  285. package/src/server/routes/instance/httpapi/middleware/schema-error.ts +41 -0
  286. package/src/server/routes/instance/httpapi/middleware/workspace-routing.ts +250 -0
  287. package/src/server/routes/instance/httpapi/public.ts +537 -0
  288. package/src/server/routes/instance/httpapi/server.ts +325 -0
  289. package/src/server/routes/instance/httpapi/websocket-tracker.ts +60 -0
  290. package/src/server/server.ts +226 -0
  291. package/src/server/shared/fence.ts +60 -0
  292. package/src/server/shared/pty-ticket.ts +15 -0
  293. package/src/server/shared/public-ui.ts +12 -0
  294. package/src/server/shared/tui-control.ts +28 -0
  295. package/src/server/shared/ui.ts +108 -0
  296. package/src/server/shared/workspace-routing.ts +38 -0
  297. package/src/server/tui-event.ts +1 -0
  298. package/src/session/compaction.ts +562 -0
  299. package/src/session/instruction.ts +237 -0
  300. package/src/session/llm/AGENTS.md +90 -0
  301. package/src/session/llm/ai-sdk.ts +288 -0
  302. package/src/session/llm/native-request.ts +196 -0
  303. package/src/session/llm/native-runtime.ts +195 -0
  304. package/src/session/llm/request.ts +226 -0
  305. package/src/session/llm.ts +404 -0
  306. package/src/session/message-error.ts +14 -0
  307. package/src/session/message-v2.ts +734 -0
  308. package/src/session/message.ts +148 -0
  309. package/src/session/overflow.ts +34 -0
  310. package/src/session/processor.ts +718 -0
  311. package/src/session/prompt/anthropic.txt +105 -0
  312. package/src/session/prompt/beast.txt +147 -0
  313. package/src/session/prompt/build-switch.txt +5 -0
  314. package/src/session/prompt/codex.txt +79 -0
  315. package/src/session/prompt/copilot-gpt-5.txt +143 -0
  316. package/src/session/prompt/default.txt +95 -0
  317. package/src/session/prompt/gemini.txt +155 -0
  318. package/src/session/prompt/gpt.txt +107 -0
  319. package/src/session/prompt/kimi.txt +95 -0
  320. package/src/session/prompt/meta.txt +65 -0
  321. package/src/session/prompt/plan-mode.txt +70 -0
  322. package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
  323. package/src/session/prompt/plan.txt +26 -0
  324. package/src/session/prompt/trinity.txt +97 -0
  325. package/src/session/prompt.ts +1631 -0
  326. package/src/session/reminders.ts +92 -0
  327. package/src/session/retry.ts +201 -0
  328. package/src/session/revert.ts +146 -0
  329. package/src/session/run-state.ts +151 -0
  330. package/src/session/schema.ts +26 -0
  331. package/src/session/session.ts +1018 -0
  332. package/src/session/status.ts +56 -0
  333. package/src/session/summary.ts +160 -0
  334. package/src/session/system.ts +145 -0
  335. package/src/session/todo.ts +74 -0
  336. package/src/session/tools.ts +590 -0
  337. package/src/share/session.ts +58 -0
  338. package/src/share/share-next.ts +371 -0
  339. package/src/skill/discovery.ts +140 -0
  340. package/src/skill/index.ts +354 -0
  341. package/src/snapshot/index.ts +807 -0
  342. package/src/sql.d.ts +4 -0
  343. package/src/storage/schema.ts +5 -0
  344. package/src/storage/storage.ts +327 -0
  345. package/src/sync/README.md +179 -0
  346. package/src/sync/schema.ts +11 -0
  347. package/src/temporary.ts +31 -0
  348. package/src/tool/apply_patch.ts +313 -0
  349. package/src/tool/apply_patch.txt +33 -0
  350. package/src/tool/code-mode.ts +310 -0
  351. package/src/tool/edit.ts +737 -0
  352. package/src/tool/edit.txt +10 -0
  353. package/src/tool/external-directory.ts +49 -0
  354. package/src/tool/glob.ts +76 -0
  355. package/src/tool/glob.txt +6 -0
  356. package/src/tool/grep.ts +115 -0
  357. package/src/tool/grep.txt +8 -0
  358. package/src/tool/invalid.ts +21 -0
  359. package/src/tool/json-schema.ts +164 -0
  360. package/src/tool/lsp.ts +113 -0
  361. package/src/tool/lsp.txt +24 -0
  362. package/src/tool/mcp-websearch.ts +96 -0
  363. package/src/tool/plan-enter.txt +14 -0
  364. package/src/tool/plan-exit.txt +13 -0
  365. package/src/tool/plan.ts +79 -0
  366. package/src/tool/question.ts +44 -0
  367. package/src/tool/question.txt +10 -0
  368. package/src/tool/read.ts +386 -0
  369. package/src/tool/read.txt +14 -0
  370. package/src/tool/registry.ts +450 -0
  371. package/src/tool/schema.ts +14 -0
  372. package/src/tool/shell/id.ts +19 -0
  373. package/src/tool/shell/prompt.ts +293 -0
  374. package/src/tool/shell/shell.txt +21 -0
  375. package/src/tool/shell.ts +645 -0
  376. package/src/tool/skill.ts +70 -0
  377. package/src/tool/skill.txt +5 -0
  378. package/src/tool/task.ts +360 -0
  379. package/src/tool/task.txt +19 -0
  380. package/src/tool/todo.ts +46 -0
  381. package/src/tool/todowrite.txt +44 -0
  382. package/src/tool/tool.ts +183 -0
  383. package/src/tool/truncate.ts +156 -0
  384. package/src/tool/truncation-dir.ts +4 -0
  385. package/src/tool/webfetch.ts +192 -0
  386. package/src/tool/webfetch.txt +13 -0
  387. package/src/tool/websearch.ts +143 -0
  388. package/src/tool/websearch.txt +14 -0
  389. package/src/tool/write.ts +104 -0
  390. package/src/tool/write.txt +8 -0
  391. package/src/util/archive.ts +17 -0
  392. package/src/util/bom.ts +27 -0
  393. package/src/util/data-url.ts +9 -0
  394. package/src/util/defer.ts +10 -0
  395. package/src/util/effect-http-client.ts +11 -0
  396. package/src/util/error.ts +1 -0
  397. package/src/util/filesystem.ts +251 -0
  398. package/src/util/html.ts +8 -0
  399. package/src/util/iife.ts +3 -0
  400. package/src/util/lazy.ts +20 -0
  401. package/src/util/local-context.ts +25 -0
  402. package/src/util/locale.ts +2 -0
  403. package/src/util/media.ts +26 -0
  404. package/src/util/process.ts +177 -0
  405. package/src/util/proxy-env.ts +72 -0
  406. package/src/util/queue.ts +32 -0
  407. package/src/util/record.ts +1 -0
  408. package/src/util/repository.ts +232 -0
  409. package/src/util/rpc.ts +66 -0
  410. package/src/util/signal.ts +12 -0
  411. package/src/util/timeout.ts +13 -0
  412. package/src/util/token.ts +1 -0
  413. package/src/util/wildcard.ts +59 -0
  414. package/src/worktree/index.ts +623 -0
  415. package/tsconfig.json +16 -0
@@ -0,0 +1,562 @@
1
+ import { LayerNode } from "@opencode-ai/core/effect/layer-node"
2
+ import { SessionV1 } from "@opencode-ai/core/v1/session"
3
+ import { ConfigV1 } from "@opencode-ai/core/v1/config/config"
4
+ import { Session } from "./session"
5
+ import { SessionID, MessageID, PartID } from "./schema"
6
+ import { Provider } from "@/provider/provider"
7
+ import { MessageV2 } from "./message-v2"
8
+ import { Token } from "@/util/token"
9
+ import { SessionProcessor } from "./processor"
10
+ import { Agent } from "@/agent/agent"
11
+ import { Plugin } from "@/plugin"
12
+ import { Config } from "@/config/config"
13
+ import { NotFoundError } from "@/storage/storage"
14
+
15
+ import { Effect, Layer, Context } from "effect"
16
+ import { InstanceState } from "@/effect/instance-state"
17
+ import { isOverflow as overflow, usable } from "./overflow"
18
+ import { serviceUse } from "@opencode-ai/core/effect/service-use"
19
+ import { RuntimeFlags } from "@/effect/runtime-flags"
20
+ import { EventV2Bridge } from "@/event-v2-bridge"
21
+ import { ProviderV2 } from "@opencode-ai/core/provider"
22
+ import { ModelV2 } from "@opencode-ai/core/model"
23
+ import { buildPrompt } from "@opencode-ai/core/session/compaction"
24
+ import { SessionCompactionEvent } from "@opencode-ai/schema/session-compaction-event"
25
+
26
+ export const Event = SessionCompactionEvent
27
+
28
+ export const PRUNE_MINIMUM = 20_000
29
+ export const PRUNE_PROTECT = 40_000
30
+ const TOOL_OUTPUT_MAX_CHARS = 2_000
31
+ const PRUNE_PROTECTED_TOOLS = ["skill"]
32
+ const DEFAULT_TAIL_TURNS = 2
33
+ const MIN_PRESERVE_RECENT_TOKENS = 2_000
34
+ const MAX_PRESERVE_RECENT_TOKENS = 8_000
35
+ type Turn = {
36
+ start: number
37
+ end: number
38
+ id: MessageID
39
+ }
40
+
41
+ type Tail = {
42
+ start: number
43
+ id: MessageID
44
+ }
45
+
46
+ type CompletedCompaction = {
47
+ userIndex: number
48
+ assistantIndex: number
49
+ summary: string | undefined
50
+ }
51
+
52
+ function summaryText(message: SessionV1.WithParts) {
53
+ const text = message.parts
54
+ .filter((part): part is SessionV1.TextPart => part.type === "text")
55
+ .map((part) => part.text.trim())
56
+ .filter(Boolean)
57
+ .join("\n\n")
58
+ .trim()
59
+ return text || undefined
60
+ }
61
+
62
+ function completedCompactions(messages: SessionV1.WithParts[]) {
63
+ const users = new Map<MessageID, number>()
64
+ for (let i = 0; i < messages.length; i++) {
65
+ const msg = messages[i]
66
+ if (msg.info.role !== "user") continue
67
+ if (!msg.parts.some((part) => part.type === "compaction")) continue
68
+ users.set(msg.info.id, i)
69
+ }
70
+
71
+ return messages.flatMap((msg, assistantIndex): CompletedCompaction[] => {
72
+ if (msg.info.role !== "assistant") return []
73
+ if (!msg.info.summary || !msg.info.finish || msg.info.error) return []
74
+ const userIndex = users.get(msg.info.parentID)
75
+ if (userIndex === undefined) return []
76
+ return [{ userIndex, assistantIndex, summary: summaryText(msg) }]
77
+ })
78
+ }
79
+
80
+ function preserveRecentBudget(input: { cfg: ConfigV1.Info; model: Provider.Model }) {
81
+ return (
82
+ input.cfg.compaction?.preserve_recent_tokens ??
83
+ Math.min(MAX_PRESERVE_RECENT_TOKENS, Math.max(MIN_PRESERVE_RECENT_TOKENS, Math.floor(usable(input) * 0.25)))
84
+ )
85
+ }
86
+
87
+ function turns(messages: SessionV1.WithParts[]) {
88
+ const result: Turn[] = []
89
+ for (let i = 0; i < messages.length; i++) {
90
+ const msg = messages[i]
91
+ if (msg.info.role !== "user") continue
92
+ if (msg.parts.some((part) => part.type === "compaction")) continue
93
+ result.push({
94
+ start: i,
95
+ end: messages.length,
96
+ id: msg.info.id,
97
+ })
98
+ }
99
+ for (let i = 0; i < result.length - 1; i++) {
100
+ result[i].end = result[i + 1].start
101
+ }
102
+ return result
103
+ }
104
+
105
+ function splitTurn(input: {
106
+ messages: SessionV1.WithParts[]
107
+ turn: Turn
108
+ model: Provider.Model
109
+ budget: number
110
+ estimate: (input: { messages: SessionV1.WithParts[]; model: Provider.Model }) => Effect.Effect<number>
111
+ }) {
112
+ return Effect.gen(function* () {
113
+ if (input.budget <= 0) return undefined
114
+ if (input.turn.end - input.turn.start <= 1) return undefined
115
+ for (let start = input.turn.start + 1; start < input.turn.end; start++) {
116
+ const size = yield* input.estimate({
117
+ messages: input.messages.slice(start, input.turn.end),
118
+ model: input.model,
119
+ })
120
+ if (size > input.budget) continue
121
+ return {
122
+ start,
123
+ id: input.messages[start]!.info.id,
124
+ } satisfies Tail
125
+ }
126
+ return undefined
127
+ })
128
+ }
129
+
130
+ export interface Interface {
131
+ readonly isOverflow: (input: {
132
+ tokens: SessionV1.Assistant["tokens"]
133
+ model: Provider.Model
134
+ }) => Effect.Effect<boolean>
135
+ readonly prune: (input: { sessionID: SessionID }) => Effect.Effect<void>
136
+ readonly process: (input: {
137
+ parentID: MessageID
138
+ messages: SessionV1.WithParts[]
139
+ sessionID: SessionID
140
+ auto: boolean
141
+ overflow?: boolean
142
+ }) => Effect.Effect<"continue" | "stop">
143
+ readonly create: (input: {
144
+ sessionID: SessionID
145
+ agent: string
146
+ model: { providerID: ProviderV2.ID; modelID: ModelV2.ID }
147
+ auto: boolean
148
+ overflow?: boolean
149
+ }) => Effect.Effect<void>
150
+ }
151
+
152
+ export class Service extends Context.Service<Service, Interface>()("@opencode/SessionCompaction") {}
153
+
154
+ export const use = serviceUse(Service)
155
+
156
+ const layer = Layer.effect(
157
+ Service,
158
+ Effect.gen(function* () {
159
+ const config = yield* Config.Service
160
+ const session = yield* Session.Service
161
+ const agents = yield* Agent.Service
162
+ const plugin = yield* Plugin.Service
163
+ const processors = yield* SessionProcessor.Service
164
+ const provider = yield* Provider.Service
165
+ const events = yield* EventV2Bridge.Service
166
+ const flags = yield* RuntimeFlags.Service
167
+
168
+ const isOverflow = Effect.fn("SessionCompaction.isOverflow")(function* (input: {
169
+ tokens: SessionV1.Assistant["tokens"]
170
+ model: Provider.Model
171
+ }) {
172
+ return overflow({
173
+ cfg: yield* config.get(),
174
+ tokens: input.tokens,
175
+ model: input.model,
176
+ outputTokenMax: flags.outputTokenMax,
177
+ })
178
+ })
179
+
180
+ const estimate = Effect.fn("SessionCompaction.estimate")(function* (input: {
181
+ messages: SessionV1.WithParts[]
182
+ model: Provider.Model
183
+ }) {
184
+ const msgs = yield* MessageV2.toModelMessagesEffect(input.messages, input.model)
185
+ return Token.estimate(JSON.stringify(msgs))
186
+ })
187
+
188
+ const select = Effect.fn("SessionCompaction.select")(function* (input: {
189
+ messages: SessionV1.WithParts[]
190
+ cfg: ConfigV1.Info
191
+ model: Provider.Model
192
+ }) {
193
+ const limit = input.cfg.compaction?.tail_turns ?? DEFAULT_TAIL_TURNS
194
+ if (limit <= 0) return { head: input.messages, tail_start_id: undefined }
195
+ const budget = preserveRecentBudget({ cfg: input.cfg, model: input.model })
196
+ const all = turns(input.messages)
197
+ if (!all.length) return { head: input.messages, tail_start_id: undefined }
198
+ const recent = all.slice(-limit)
199
+ const sizes = yield* Effect.forEach(
200
+ recent,
201
+ (turn) =>
202
+ estimate({
203
+ messages: input.messages.slice(turn.start, turn.end),
204
+ model: input.model,
205
+ }),
206
+ { concurrency: 1 },
207
+ )
208
+
209
+ let total = 0
210
+ let keep: Tail | undefined
211
+ for (let i = recent.length - 1; i >= 0; i--) {
212
+ const turn = recent[i]!
213
+ const size = sizes[i]
214
+ if (total + size <= budget) {
215
+ total += size
216
+ keep = { start: turn.start, id: turn.id }
217
+ continue
218
+ }
219
+ const remaining = budget - total
220
+ const split = yield* splitTurn({
221
+ messages: input.messages,
222
+ turn,
223
+ model: input.model,
224
+ budget: remaining,
225
+ estimate,
226
+ })
227
+ if (split) keep = split
228
+ else if (!keep) {
229
+ yield* Effect.logInfo("tail fallback", { budget, size, total })
230
+ }
231
+ break
232
+ }
233
+
234
+ if (!keep || keep.start === 0) return { head: input.messages, tail_start_id: undefined }
235
+ return {
236
+ head: input.messages.slice(0, keep.start),
237
+ tail_start_id: keep.id,
238
+ }
239
+ })
240
+
241
+ // goes backwards through parts until there are PRUNE_PROTECT tokens worth of tool
242
+ // calls, then erases output of older tool calls to free context space
243
+ const prune = Effect.fn("SessionCompaction.prune")(function* (input: { sessionID: SessionID }) {
244
+ const cfg = yield* config.get()
245
+ if (!cfg.compaction?.prune) return
246
+ yield* Effect.logInfo("pruning")
247
+
248
+ const msgs = yield* session
249
+ .messages({ sessionID: input.sessionID })
250
+ .pipe(Effect.catchIf(NotFoundError.isInstance, () => Effect.succeed(undefined)))
251
+ if (!msgs) return
252
+
253
+ let total = 0
254
+ let pruned = 0
255
+ const toPrune: SessionV1.ToolPart[] = []
256
+ let turns = 0
257
+
258
+ loop: for (let msgIndex = msgs.length - 1; msgIndex >= 0; msgIndex--) {
259
+ const msg = msgs[msgIndex]
260
+ if (msg.info.role === "user") turns++
261
+ if (turns < 2) continue
262
+ if (msg.info.role === "assistant" && msg.info.summary) break loop
263
+ for (let partIndex = msg.parts.length - 1; partIndex >= 0; partIndex--) {
264
+ const part = msg.parts[partIndex]
265
+ if (part.type !== "tool") continue
266
+ if (part.state.status !== "completed") continue
267
+ if (PRUNE_PROTECTED_TOOLS.includes(part.tool)) continue
268
+ if (part.state.time.compacted) break loop
269
+ const estimate = Token.estimate(part.state.output)
270
+ total += estimate
271
+ if (total <= PRUNE_PROTECT) continue
272
+ pruned += estimate
273
+ toPrune.push(part)
274
+ }
275
+ }
276
+
277
+ yield* Effect.logInfo("found", { pruned, total })
278
+ if (pruned > PRUNE_MINIMUM) {
279
+ for (const part of toPrune) {
280
+ if (part.state.status === "completed") {
281
+ part.state.time.compacted = Date.now()
282
+ yield* session.updatePart(part)
283
+ }
284
+ }
285
+ yield* Effect.logInfo("pruned", { count: toPrune.length })
286
+ }
287
+ })
288
+
289
+ const processCompaction = Effect.fn("SessionCompaction.process")(function* (input: {
290
+ parentID: MessageID
291
+ messages: SessionV1.WithParts[]
292
+ sessionID: SessionID
293
+ auto: boolean
294
+ overflow?: boolean
295
+ }) {
296
+ const parent = input.messages.findLast((m) => m.info.id === input.parentID)
297
+ if (!parent || parent.info.role !== "user") {
298
+ throw new Error(`Compaction parent must be a user message: ${input.parentID}`)
299
+ }
300
+ const userMessage = parent.info
301
+ const compactionPart = parent.parts.find((part): part is SessionV1.CompactionPart => part.type === "compaction")
302
+
303
+ let messages = input.messages
304
+ let replay:
305
+ | {
306
+ info: SessionV1.User
307
+ parts: SessionV1.Part[]
308
+ }
309
+ | undefined
310
+ if (input.overflow) {
311
+ const idx = input.messages.findIndex((m) => m.info.id === input.parentID)
312
+ for (let i = idx - 1; i >= 0; i--) {
313
+ const msg = input.messages[i]
314
+ if (msg.info.role === "user" && !msg.parts.some((p) => p.type === "compaction")) {
315
+ replay = { info: msg.info, parts: msg.parts }
316
+ messages = input.messages.slice(0, i)
317
+ break
318
+ }
319
+ }
320
+ const hasContent =
321
+ replay && messages.some((m) => m.info.role === "user" && !m.parts.some((p) => p.type === "compaction"))
322
+ if (!hasContent) {
323
+ replay = undefined
324
+ messages = input.messages
325
+ }
326
+ }
327
+
328
+ const agent = yield* agents.get("compaction")
329
+ const model = agent.model
330
+ ? yield* provider.getModel(agent.model.providerID, agent.model.modelID).pipe(Effect.orDie)
331
+ : yield* provider.getModel(userMessage.model.providerID, userMessage.model.modelID).pipe(Effect.orDie)
332
+ const cfg = yield* config.get()
333
+ const history = compactionPart && messages.at(-1)?.info.id === input.parentID ? messages.slice(0, -1) : messages
334
+ const prior = completedCompactions(history)
335
+ const hidden = new Set(prior.flatMap((item) => [item.userIndex, item.assistantIndex]))
336
+ const previousSummary = prior.at(-1)?.summary
337
+ const selected = yield* select({
338
+ messages: history.filter((_, index) => !hidden.has(index)),
339
+ cfg,
340
+ model,
341
+ })
342
+ // Allow plugins to inject context or replace compaction prompt.
343
+ const compacting = yield* plugin.trigger(
344
+ "experimental.session.compacting",
345
+ { sessionID: input.sessionID },
346
+ { context: [], prompt: undefined },
347
+ )
348
+ const nextPrompt = compacting.prompt ?? buildPrompt({ previousSummary, context: compacting.context })
349
+ const msgs = structuredClone(selected.head)
350
+ yield* plugin.trigger("experimental.chat.messages.transform", {}, { messages: msgs })
351
+ const modelMessages = yield* MessageV2.toModelMessagesEffect(msgs, model, {
352
+ stripMedia: true,
353
+ toolOutputMaxChars: TOOL_OUTPUT_MAX_CHARS,
354
+ })
355
+ const ctx = yield* InstanceState.context
356
+ const msg: SessionV1.Assistant = {
357
+ id: MessageID.ascending(),
358
+ role: "assistant",
359
+ parentID: input.parentID,
360
+ sessionID: input.sessionID,
361
+ mode: "compaction",
362
+ agent: "compaction",
363
+ variant: userMessage.model.variant,
364
+ summary: true,
365
+ path: {
366
+ cwd: ctx.directory,
367
+ root: ctx.worktree,
368
+ },
369
+ cost: 0,
370
+ tokens: {
371
+ output: 0,
372
+ input: 0,
373
+ reasoning: 0,
374
+ cache: { read: 0, write: 0 },
375
+ },
376
+ modelID: model.id,
377
+ providerID: model.providerID,
378
+ time: {
379
+ created: Date.now(),
380
+ },
381
+ }
382
+ yield* session.updateMessage(msg)
383
+ const processor = yield* processors.create({
384
+ assistantMessage: msg,
385
+ sessionID: input.sessionID,
386
+ model,
387
+ })
388
+ const result = yield* processor.process({
389
+ user: userMessage,
390
+ agent,
391
+ sessionID: input.sessionID,
392
+ tools: {},
393
+ system: [],
394
+ messages: [
395
+ ...modelMessages,
396
+ {
397
+ role: "user",
398
+ content: [{ type: "text", text: nextPrompt }],
399
+ },
400
+ ],
401
+ model,
402
+ })
403
+
404
+ if (result === "compact") {
405
+ processor.message.error = new SessionV1.ContextOverflowError({
406
+ message: replay
407
+ ? "Conversation history too large to compact - exceeds model context limit"
408
+ : "Session too large to compact - context exceeds model limit even after stripping media",
409
+ }).toObject()
410
+ processor.message.finish = "error"
411
+ yield* session.updateMessage(processor.message)
412
+ return "stop"
413
+ }
414
+
415
+ if (compactionPart && selected.tail_start_id && compactionPart.tail_start_id !== selected.tail_start_id) {
416
+ yield* session.updatePart({
417
+ ...compactionPart,
418
+ tail_start_id: selected.tail_start_id,
419
+ })
420
+ }
421
+
422
+ if (result === "continue" && input.auto) {
423
+ if (replay) {
424
+ const original = replay.info
425
+ const replayMsg = yield* session.updateMessage({
426
+ id: MessageID.ascending(),
427
+ role: "user",
428
+ sessionID: input.sessionID,
429
+ time: { created: Date.now() },
430
+ agent: original.agent,
431
+ model: original.model,
432
+ format: original.format,
433
+ tools: original.tools,
434
+ system: original.system,
435
+ })
436
+ for (const part of replay.parts) {
437
+ if (part.type === "compaction") continue
438
+ const replayPart =
439
+ part.type === "file" && MessageV2.isMedia(part.mime)
440
+ ? { type: "text" as const, text: `[Attached ${part.mime}: ${part.filename ?? "file"}]` }
441
+ : part
442
+ yield* session.updatePart({
443
+ ...replayPart,
444
+ id: PartID.ascending(),
445
+ messageID: replayMsg.id,
446
+ sessionID: input.sessionID,
447
+ })
448
+ }
449
+ }
450
+
451
+ if (!replay) {
452
+ const info = yield* provider.getProvider(userMessage.model.providerID)
453
+ if (
454
+ (yield* plugin.trigger(
455
+ "experimental.compaction.autocontinue",
456
+ {
457
+ sessionID: input.sessionID,
458
+ agent: userMessage.agent,
459
+ model: yield* provider
460
+ .getModel(userMessage.model.providerID, userMessage.model.modelID)
461
+ .pipe(Effect.orDie),
462
+ provider: {
463
+ source: info.source,
464
+ info,
465
+ options: info.options,
466
+ },
467
+ message: userMessage,
468
+ overflow: input.overflow === true,
469
+ },
470
+ { enabled: true },
471
+ )).enabled
472
+ ) {
473
+ const continueMsg = yield* session.updateMessage({
474
+ id: MessageID.ascending(),
475
+ role: "user",
476
+ sessionID: input.sessionID,
477
+ time: { created: Date.now() },
478
+ agent: userMessage.agent,
479
+ model: userMessage.model,
480
+ })
481
+ const text =
482
+ (input.overflow
483
+ ? "The previous request exceeded the provider's size limit due to large media attachments. The conversation was compacted and media files were removed from context. If the user was asking about attached images or files, explain that the attachments were too large to process and suggest they try again with smaller or fewer files.\n\n"
484
+ : "") +
485
+ "Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed."
486
+ yield* session.updatePart({
487
+ id: PartID.ascending(),
488
+ messageID: continueMsg.id,
489
+ sessionID: input.sessionID,
490
+ type: "text",
491
+ // Internal marker for auto-compaction followups so provider plugins
492
+ // can distinguish them from manual post-compaction user prompts.
493
+ // This is not a stable plugin contract and may change or disappear.
494
+ metadata: { compaction_continue: true },
495
+ synthetic: true,
496
+ text,
497
+ time: {
498
+ start: Date.now(),
499
+ end: Date.now(),
500
+ },
501
+ })
502
+ }
503
+ }
504
+ }
505
+
506
+ if (processor.message.error) return "stop"
507
+ if (result === "continue") {
508
+ yield* events.publish(Event.Compacted, { sessionID: input.sessionID })
509
+ }
510
+ return result
511
+ })
512
+
513
+ const create = Effect.fn("SessionCompaction.create")(function* (input: {
514
+ sessionID: SessionID
515
+ agent: string
516
+ model: { providerID: ProviderV2.ID; modelID: ModelV2.ID }
517
+ auto: boolean
518
+ overflow?: boolean
519
+ }) {
520
+ const msg = yield* session.updateMessage({
521
+ id: MessageID.ascending(),
522
+ role: "user",
523
+ model: input.model,
524
+ sessionID: input.sessionID,
525
+ agent: input.agent,
526
+ time: { created: Date.now() },
527
+ })
528
+ yield* session.updatePart({
529
+ id: PartID.ascending(),
530
+ messageID: msg.id,
531
+ sessionID: msg.sessionID,
532
+ type: "compaction",
533
+ auto: input.auto,
534
+ overflow: input.overflow,
535
+ })
536
+ })
537
+
538
+ return Service.of({
539
+ isOverflow,
540
+ prune,
541
+ process: processCompaction,
542
+ create,
543
+ })
544
+ }),
545
+ )
546
+
547
+ export const node = LayerNode.make({
548
+ service: Service,
549
+ layer: layer,
550
+ deps: [
551
+ Config.node,
552
+ Session.node,
553
+ Agent.node,
554
+ Plugin.node,
555
+ SessionProcessor.node,
556
+ Provider.node,
557
+ EventV2Bridge.node,
558
+ RuntimeFlags.node,
559
+ ],
560
+ })
561
+
562
+ export * as SessionCompaction from "./compaction"