@neurocode-ai/core 1.18.8

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 (490) hide show
  1. package/bin/neurocode +199 -0
  2. package/bunfig.toml +2 -0
  3. package/drizzle.config.ts +10 -0
  4. package/package.json +131 -0
  5. package/schema.json +2071 -0
  6. package/script/fix-node-pty.ts +28 -0
  7. package/script/migration.ts +196 -0
  8. package/src/account/sql.ts +39 -0
  9. package/src/account.ts +101 -0
  10. package/src/agent.ts +111 -0
  11. package/src/aisdk.ts +235 -0
  12. package/src/background-job.ts +365 -0
  13. package/src/catalog.ts +301 -0
  14. package/src/command.ts +64 -0
  15. package/src/config/agent.ts +25 -0
  16. package/src/config/attachments.ts +15 -0
  17. package/src/config/command.ts +12 -0
  18. package/src/config/compaction.ts +15 -0
  19. package/src/config/experimental.ts +18 -0
  20. package/src/config/formatter.ts +12 -0
  21. package/src/config/lsp.ts +18 -0
  22. package/src/config/markdown.ts +36 -0
  23. package/src/config/mcp.ts +48 -0
  24. package/src/config/plugin/agent.ts +179 -0
  25. package/src/config/plugin/command.ts +83 -0
  26. package/src/config/plugin/external.ts +91 -0
  27. package/src/config/plugin/provider.ts +113 -0
  28. package/src/config/plugin/reference.ts +70 -0
  29. package/src/config/plugin/skill.ts +50 -0
  30. package/src/config/plugin.ts +13 -0
  31. package/src/config/provider.ts +71 -0
  32. package/src/config/reference.ts +22 -0
  33. package/src/config/tool-output.ts +9 -0
  34. package/src/config/watcher.ts +7 -0
  35. package/src/config.ts +227 -0
  36. package/src/control-plane/move-session.ts +148 -0
  37. package/src/control-plane/workspace.sql.ts +20 -0
  38. package/src/credential/sql.ts +14 -0
  39. package/src/credential.ts +138 -0
  40. package/src/cross-spawn-spawner.ts +507 -0
  41. package/src/data-migration.sql.ts +6 -0
  42. package/src/database/database.ts +57 -0
  43. package/src/database/migration/20260127222353_familiar_lady_ursula.ts +107 -0
  44. package/src/database/migration/20260211171708_add_project_commands.ts +11 -0
  45. package/src/database/migration/20260213144116_wakeful_the_professor.ts +23 -0
  46. package/src/database/migration/20260225215848_workspace.ts +19 -0
  47. package/src/database/migration/20260227213759_add_session_workspace_id.ts +12 -0
  48. package/src/database/migration/20260228203230_blue_harpoon.ts +30 -0
  49. package/src/database/migration/20260303231226_add_workspace_fields.ts +15 -0
  50. package/src/database/migration/20260309230000_move_org_to_state.ts +15 -0
  51. package/src/database/migration/20260312043431_session_message_cursor.ts +16 -0
  52. package/src/database/migration/20260323234822_events.ts +26 -0
  53. package/src/database/migration/20260410174513_workspace-name.ts +29 -0
  54. package/src/database/migration/20260413175956_chief_energizer.ts +24 -0
  55. package/src/database/migration/20260423070820_add_icon_url_override.ts +14 -0
  56. package/src/database/migration/20260427172553_slow_nightmare.ts +30 -0
  57. package/src/database/migration/20260428004200_add_session_path.ts +11 -0
  58. package/src/database/migration/20260501142318_next_venus.ts +12 -0
  59. package/src/database/migration/20260504145000_add_sync_owner.ts +11 -0
  60. package/src/database/migration/20260507164347_add_workspace_time.ts +11 -0
  61. package/src/database/migration/20260510033149_session_usage.ts +56 -0
  62. package/src/database/migration/20260511000411_data_migration_state.ts +16 -0
  63. package/src/database/migration/20260511173437_session-metadata.ts +16 -0
  64. package/src/database/migration/20260601010001_normalize_storage_paths.ts +22 -0
  65. package/src/database/migration/20260601202201_amazing_prowler.ts +11 -0
  66. package/src/database/migration/20260602002951_lowly_union_jack.ts +24 -0
  67. package/src/database/migration/20260602182828_add_project_directories.ts +20 -0
  68. package/src/database/migration/20260603001617_session_message_projection_indexes.ts +19 -0
  69. package/src/database/migration/20260603040000_session_message_projection_order.ts +19 -0
  70. package/src/database/migration/20260603141458_session_input_inbox.ts +25 -0
  71. package/src/database/migration/20260603160727_jittery_ezekiel_stane.ts +20 -0
  72. package/src/database/migration/20260604172448_event_sourced_session_input.ts +47 -0
  73. package/src/database/migration/20260605003541_add_session_context_snapshot.ts +21 -0
  74. package/src/database/migration/20260605042240_add_context_epoch_agent.ts +11 -0
  75. package/src/database/migration/20260611035744_credential.ts +25 -0
  76. package/src/database/migration/20260611192811_lush_chimera.ts +25 -0
  77. package/src/database/migration/20260612174303_project_dir_strategy.ts +29 -0
  78. package/src/database/migration/20260622142730_simplify_session_context_epoch.ts +13 -0
  79. package/src/database/migration/20260622170816_reset_v2_session_state.ts +17 -0
  80. package/src/database/migration/20260622202450_simplify_session_input.ts +17 -0
  81. package/src/database/migration.gen.ts +44 -0
  82. package/src/database/migration.ts +81 -0
  83. package/src/database/path.ts +91 -0
  84. package/src/database/schema.gen.ts +274 -0
  85. package/src/database/schema.sql.ts +10 -0
  86. package/src/database/sqlite.bun.ts +183 -0
  87. package/src/database/sqlite.node.ts +178 -0
  88. package/src/database/sqlite.ts +8 -0
  89. package/src/effect/app-node-builder.ts +23 -0
  90. package/src/effect/app-node-platform.ts +18 -0
  91. package/src/effect/app-node.ts +14 -0
  92. package/src/effect/dfdf +1 -0
  93. package/src/effect/keyed-mutex.ts +45 -0
  94. package/src/effect/layer-node.ts +333 -0
  95. package/src/effect/memo-map.ts +3 -0
  96. package/src/effect/runtime.ts +21 -0
  97. package/src/effect/service-use.ts +43 -0
  98. package/src/event/sql.ts +25 -0
  99. package/src/event.ts +638 -0
  100. package/src/file-mutation.ts +207 -0
  101. package/src/file.ts +6 -0
  102. package/src/filesystem/fff.bun.ts +140 -0
  103. package/src/filesystem/fff.node.ts +138 -0
  104. package/src/filesystem/ignore.ts +67 -0
  105. package/src/filesystem/protected.ts +53 -0
  106. package/src/filesystem/search.ts +239 -0
  107. package/src/filesystem/watcher.ts +140 -0
  108. package/src/filesystem.ts +118 -0
  109. package/src/flag/flag.ts +78 -0
  110. package/src/fs-util.ts +274 -0
  111. package/src/git.ts +987 -0
  112. package/src/github-copilot/README.md +5 -0
  113. package/src/github-copilot/chat/convert-to-openai-compatible-chat-messages.ts +170 -0
  114. package/src/github-copilot/chat/get-response-metadata.ts +15 -0
  115. package/src/github-copilot/chat/map-openai-compatible-finish-reason.ts +19 -0
  116. package/src/github-copilot/chat/openai-compatible-api-types.ts +64 -0
  117. package/src/github-copilot/chat/openai-compatible-chat-language-model.ts +815 -0
  118. package/src/github-copilot/chat/openai-compatible-chat-options.ts +28 -0
  119. package/src/github-copilot/chat/openai-compatible-metadata-extractor.ts +44 -0
  120. package/src/github-copilot/chat/openai-compatible-prepare-tools.ts +83 -0
  121. package/src/github-copilot/copilot-provider.ts +100 -0
  122. package/src/github-copilot/openai-compatible-error.ts +27 -0
  123. package/src/github-copilot/responses/convert-to-openai-responses-input.ts +335 -0
  124. package/src/github-copilot/responses/map-openai-responses-finish-reason.ts +22 -0
  125. package/src/github-copilot/responses/openai-config.ts +18 -0
  126. package/src/github-copilot/responses/openai-error.ts +22 -0
  127. package/src/github-copilot/responses/openai-responses-api-types.ts +214 -0
  128. package/src/github-copilot/responses/openai-responses-language-model.ts +1770 -0
  129. package/src/github-copilot/responses/openai-responses-prepare-tools.ts +173 -0
  130. package/src/github-copilot/responses/openai-responses-settings.ts +1 -0
  131. package/src/github-copilot/responses/tool/code-interpreter.ts +87 -0
  132. package/src/github-copilot/responses/tool/file-search.ts +127 -0
  133. package/src/github-copilot/responses/tool/image-generation.ts +114 -0
  134. package/src/github-copilot/responses/tool/local-shell.ts +64 -0
  135. package/src/github-copilot/responses/tool/web-search-preview.ts +103 -0
  136. package/src/github-copilot/responses/tool/web-search.ts +102 -0
  137. package/src/global.ts +87 -0
  138. package/src/id/id.ts +47 -0
  139. package/src/image/photon.ts +94 -0
  140. package/src/image.ts +81 -0
  141. package/src/installation/version.ts +8 -0
  142. package/src/instruction-context.ts +101 -0
  143. package/src/integration/connection.ts +12 -0
  144. package/src/integration.ts +520 -0
  145. package/src/location-mutation.ts +162 -0
  146. package/src/location-service-map.ts +18 -0
  147. package/src/location-services.ts +115 -0
  148. package/src/location.ts +39 -0
  149. package/src/markdown.d.ts +4 -0
  150. package/src/model.ts +41 -0
  151. package/src/models-dev.ts +260 -0
  152. package/src/npm-config.ts +40 -0
  153. package/src/npm.ts +269 -0
  154. package/src/oauth/page.ts +276 -0
  155. package/src/observability/logging.ts +71 -0
  156. package/src/observability/otlp.ts +79 -0
  157. package/src/observability/shared.ts +1 -0
  158. package/src/observability.ts +24 -0
  159. package/src/patch.ts +197 -0
  160. package/src/permission/saved.ts +79 -0
  161. package/src/permission/sql.ts +20 -0
  162. package/src/permission.ts +310 -0
  163. package/src/plugin/agent.ts +206 -0
  164. package/src/plugin/command/initialize.txt +65 -0
  165. package/src/plugin/command/review.txt +100 -0
  166. package/src/plugin/command.ts +25 -0
  167. package/src/plugin/host.ts +219 -0
  168. package/src/plugin/internal.ts +153 -0
  169. package/src/plugin/layer-map.example.ts +94 -0
  170. package/src/plugin/models-dev.ts +183 -0
  171. package/src/plugin/promise.ts +93 -0
  172. package/src/plugin/provider/alibaba.ts +15 -0
  173. package/src/plugin/provider/amazon-bedrock.ts +126 -0
  174. package/src/plugin/provider/anthropic.ts +27 -0
  175. package/src/plugin/provider/azure.ts +82 -0
  176. package/src/plugin/provider/cerebras.ts +26 -0
  177. package/src/plugin/provider/cloudflare-ai-gateway.ts +81 -0
  178. package/src/plugin/provider/cloudflare-workers-ai.ts +81 -0
  179. package/src/plugin/provider/cohere.ts +15 -0
  180. package/src/plugin/provider/deepinfra.ts +15 -0
  181. package/src/plugin/provider/dynamic.ts +31 -0
  182. package/src/plugin/provider/gateway.ts +15 -0
  183. package/src/plugin/provider/github-copilot.ts +52 -0
  184. package/src/plugin/provider/gitlab.ts +65 -0
  185. package/src/plugin/provider/google-vertex.ts +173 -0
  186. package/src/plugin/provider/google.ts +15 -0
  187. package/src/plugin/provider/groq.ts +15 -0
  188. package/src/plugin/provider/kilo.ts +21 -0
  189. package/src/plugin/provider/llmgateway.ts +26 -0
  190. package/src/plugin/provider/mistral.ts +15 -0
  191. package/src/plugin/provider/nvidia.ts +22 -0
  192. package/src/plugin/provider/openai-compatible.ts +17 -0
  193. package/src/plugin/provider/openai.ts +292 -0
  194. package/src/plugin/provider/opencode.ts +311 -0
  195. package/src/plugin/provider/openrouter.ts +36 -0
  196. package/src/plugin/provider/perplexity.ts +15 -0
  197. package/src/plugin/provider/sap-ai-core.ts +46 -0
  198. package/src/plugin/provider/snowflake-cortex.ts +89 -0
  199. package/src/plugin/provider/togetherai.ts +15 -0
  200. package/src/plugin/provider/venice.ts +15 -0
  201. package/src/plugin/provider/vercel.ts +27 -0
  202. package/src/plugin/provider/xai.ts +22 -0
  203. package/src/plugin/provider/zenmux.ts +21 -0
  204. package/src/plugin/provider.ts +71 -0
  205. package/src/plugin/skill/customize-neurocode.md +452 -0
  206. package/src/plugin/skill.ts +31 -0
  207. package/src/plugin/variant.ts +39 -0
  208. package/src/plugin.ts +167 -0
  209. package/src/policy.ts +49 -0
  210. package/src/process.ts +261 -0
  211. package/src/project/copy-strategies.ts +35 -0
  212. package/src/project/copy.ts +292 -0
  213. package/src/project/directories.ts +158 -0
  214. package/src/project/schema.ts +16 -0
  215. package/src/project/sql.ts +35 -0
  216. package/src/project.ts +136 -0
  217. package/src/provider.ts +25 -0
  218. package/src/pty/protocol.ts +37 -0
  219. package/src/pty/pty.bun.ts +26 -0
  220. package/src/pty/pty.node.ts +29 -0
  221. package/src/pty/pty.ts +25 -0
  222. package/src/pty/schema.ts +1 -0
  223. package/src/pty/ticket.ts +56 -0
  224. package/src/pty.ts +318 -0
  225. package/src/public-event-manifest.ts +7 -0
  226. package/src/question.ts +153 -0
  227. package/src/reference/guidance.ts +69 -0
  228. package/src/reference.ts +125 -0
  229. package/src/repository-cache.ts +259 -0
  230. package/src/repository.ts +214 -0
  231. package/src/ripgrep/binary.ts +132 -0
  232. package/src/ripgrep.ts +281 -0
  233. package/src/schema.ts +79 -0
  234. package/src/session/compaction.ts +241 -0
  235. package/src/session/context-epoch.ts +174 -0
  236. package/src/session/error.ts +24 -0
  237. package/src/session/event.ts +2 -0
  238. package/src/session/execution/local.ts +46 -0
  239. package/src/session/execution.ts +34 -0
  240. package/src/session/history.ts +101 -0
  241. package/src/session/info.ts +50 -0
  242. package/src/session/input.ts +288 -0
  243. package/src/session/message-updater.ts +397 -0
  244. package/src/session/message.ts +2 -0
  245. package/src/session/projector.ts +458 -0
  246. package/src/session/prompt.ts +1 -0
  247. package/src/session/revert.ts +121 -0
  248. package/src/session/run-coordinator.ts +104 -0
  249. package/src/session/runner/index.ts +28 -0
  250. package/src/session/runner/llm.ts +432 -0
  251. package/src/session/runner/max-steps.ts +16 -0
  252. package/src/session/runner/model.ts +218 -0
  253. package/src/session/runner/publish-llm-event.ts +423 -0
  254. package/src/session/runner/to-llm-message.ts +171 -0
  255. package/src/session/schema.ts +9 -0
  256. package/src/session/sql.ts +176 -0
  257. package/src/session/store.ts +63 -0
  258. package/src/session/todo.ts +78 -0
  259. package/src/session.ts +486 -0
  260. package/src/share/sql.ts +13 -0
  261. package/src/shell.ts +226 -0
  262. package/src/skill/discovery.ts +213 -0
  263. package/src/skill/guidance.ts +76 -0
  264. package/src/skill.ts +132 -0
  265. package/src/snapshot.ts +266 -0
  266. package/src/state.ts +128 -0
  267. package/src/system-context/builtins.ts +50 -0
  268. package/src/system-context/index.ts +320 -0
  269. package/src/system-context/registry.ts +49 -0
  270. package/src/tool/AGENTS.md +59 -0
  271. package/src/tool/application-tools.ts +57 -0
  272. package/src/tool/apply-patch.ts +219 -0
  273. package/src/tool/bash.ts +207 -0
  274. package/src/tool/builtins.ts +48 -0
  275. package/src/tool/edit.ts +223 -0
  276. package/src/tool/glob.ts +105 -0
  277. package/src/tool/grep.ts +137 -0
  278. package/src/tool/http-body.ts +30 -0
  279. package/src/tool/question.ts +94 -0
  280. package/src/tool/read-filesystem.ts +366 -0
  281. package/src/tool/read.ts +117 -0
  282. package/src/tool/registry.ts +147 -0
  283. package/src/tool/skill.ts +109 -0
  284. package/src/tool/todowrite.ts +62 -0
  285. package/src/tool/tool.ts +162 -0
  286. package/src/tool/tools.ts +13 -0
  287. package/src/tool/webfetch.ts +218 -0
  288. package/src/tool/websearch.ts +260 -0
  289. package/src/tool/write.ts +101 -0
  290. package/src/tool-output-store.ts +211 -0
  291. package/src/util/array.ts +10 -0
  292. package/src/util/binary.ts +41 -0
  293. package/src/util/effect-flock.ts +284 -0
  294. package/src/util/encode.ts +51 -0
  295. package/src/util/error.ts +70 -0
  296. package/src/util/flock.ts +358 -0
  297. package/src/util/glob.ts +34 -0
  298. package/src/util/hash.ts +11 -0
  299. package/src/util/identifier.ts +1 -0
  300. package/src/util/iife.ts +3 -0
  301. package/src/util/lazy.ts +11 -0
  302. package/src/util/module.ts +10 -0
  303. package/src/util/path.ts +37 -0
  304. package/src/util/retry.ts +42 -0
  305. package/src/util/slug.ts +74 -0
  306. package/src/util/token.ts +5 -0
  307. package/src/util/which.ts +14 -0
  308. package/src/util/wildcard.ts +14 -0
  309. package/src/v1/config/agent.ts +89 -0
  310. package/src/v1/config/attachment.ts +25 -0
  311. package/src/v1/config/command.ts +13 -0
  312. package/src/v1/config/config.ts +192 -0
  313. package/src/v1/config/console-state.ts +16 -0
  314. package/src/v1/config/error.ts +39 -0
  315. package/src/v1/config/formatter.ts +13 -0
  316. package/src/v1/config/layout.ts +6 -0
  317. package/src/v1/config/lsp.ts +80 -0
  318. package/src/v1/config/mcp.ts +63 -0
  319. package/src/v1/config/migrate.ts +254 -0
  320. package/src/v1/config/permission.ts +50 -0
  321. package/src/v1/config/plugin.ts +9 -0
  322. package/src/v1/config/provider-options.ts +227 -0
  323. package/src/v1/config/provider.ts +121 -0
  324. package/src/v1/config/server.ts +19 -0
  325. package/src/v1/config/skills.ts +13 -0
  326. package/src/v1/permission.ts +33 -0
  327. package/src/v1/session.ts +68 -0
  328. package/src/v2-schema.ts +3 -0
  329. package/src/workspace.ts +6 -0
  330. package/sst-env.d.ts +10 -0
  331. package/test/agent.test.ts +131 -0
  332. package/test/application-tools.test.ts +287 -0
  333. package/test/background-job.test.ts +106 -0
  334. package/test/catalog.test.ts +353 -0
  335. package/test/command.test.ts +56 -0
  336. package/test/config/agent.test.ts +349 -0
  337. package/test/config/command.test.ts +83 -0
  338. package/test/config/config.test.ts +798 -0
  339. package/test/config/fixtures/plugin/directory-plugin.ts +13 -0
  340. package/test/config/plugin.test.ts +248 -0
  341. package/test/config/provider-options.test.ts +224 -0
  342. package/test/config/provider.test.ts +269 -0
  343. package/test/config/skill.test.ts +80 -0
  344. package/test/credential.test.ts +36 -0
  345. package/test/database-migration.test.ts +644 -0
  346. package/test/effect/cross-spawn-spawner.test.ts +426 -0
  347. package/test/effect/keyed-mutex.test.ts +73 -0
  348. package/test/effect/layer-node/layer-node-types.test.ts +143 -0
  349. package/test/effect/layer-node/layer-node.test.ts +261 -0
  350. package/test/effect/layer-node/node-build.test.ts +125 -0
  351. package/test/effect/observability.test.ts +109 -0
  352. package/test/event.test.ts +1124 -0
  353. package/test/file-mutation.test.ts +368 -0
  354. package/test/filesystem/filesystem.test.ts +387 -0
  355. package/test/filesystem/ignore.test.ts +10 -0
  356. package/test/filesystem/search.test.ts +44 -0
  357. package/test/filesystem/watcher.test.ts +266 -0
  358. package/test/fixture/effect-flock-worker.ts +60 -0
  359. package/test/fixture/flock-worker.ts +72 -0
  360. package/test/fixture/git.ts +49 -0
  361. package/test/fixture/location.ts +26 -0
  362. package/test/fixture/tmpdir.ts +25 -0
  363. package/test/fixtures/recordings/session-runner/openai-chat-streams-text.json +27 -0
  364. package/test/git.test.ts +164 -0
  365. package/test/github-copilot/convert-to-copilot-messages.test.ts +523 -0
  366. package/test/github-copilot/copilot-chat-model.test.ts +592 -0
  367. package/test/github-copilot/openai-responses-language-model.test.ts +206 -0
  368. package/test/global.test.ts +16 -0
  369. package/test/instruction-context.test.ts +323 -0
  370. package/test/integration.test.ts +349 -0
  371. package/test/legacy-event-schema.test.ts +16 -0
  372. package/test/lib/effect.ts +53 -0
  373. package/test/lib/tool.ts +20 -0
  374. package/test/location-filesystem.test.ts +69 -0
  375. package/test/location-layer.test.ts +226 -0
  376. package/test/location-mutation.test.ts +178 -0
  377. package/test/location.test.ts +42 -0
  378. package/test/model.test.ts +23 -0
  379. package/test/models.test.ts +290 -0
  380. package/test/move-session.test.ts +235 -0
  381. package/test/npm-config.test.ts +51 -0
  382. package/test/npm.test.ts +84 -0
  383. package/test/oauth-page.test.ts +15 -0
  384. package/test/patch.test.ts +68 -0
  385. package/test/permission.test.ts +315 -0
  386. package/test/plugin/command.test.ts +47 -0
  387. package/test/plugin/fixture.ts +52 -0
  388. package/test/plugin/fixtures/config-effect-plugin.ts +15 -0
  389. package/test/plugin/fixtures/config-promise-plugin.ts +13 -0
  390. package/test/plugin/fixtures/invalid-plugin.ts +1 -0
  391. package/test/plugin/fixtures/models-dev.json +14 -0
  392. package/test/plugin/fixtures/provider-factory.ts +9 -0
  393. package/test/plugin/host.ts +303 -0
  394. package/test/plugin/models-dev.test.ts +170 -0
  395. package/test/plugin/promise.test.ts +67 -0
  396. package/test/plugin/provider-alibaba.test.ts +92 -0
  397. package/test/plugin/provider-amazon-bedrock.test.ts +622 -0
  398. package/test/plugin/provider-anthropic.test.ts +94 -0
  399. package/test/plugin/provider-azure-cognitive-services.test.ts +199 -0
  400. package/test/plugin/provider-azure.test.ts +293 -0
  401. package/test/plugin/provider-cerebras.test.ts +136 -0
  402. package/test/plugin/provider-cloudflare-ai-gateway.test.ts +426 -0
  403. package/test/plugin/provider-cloudflare-workers-ai.test.ts +279 -0
  404. package/test/plugin/provider-cohere.test.ts +123 -0
  405. package/test/plugin/provider-deepinfra.test.ts +159 -0
  406. package/test/plugin/provider-dynamic.test.ts +184 -0
  407. package/test/plugin/provider-gateway.test.ts +115 -0
  408. package/test/plugin/provider-github-copilot.test.ts +278 -0
  409. package/test/plugin/provider-gitlab.test.ts +308 -0
  410. package/test/plugin/provider-google-vertex-anthropic.test.ts +264 -0
  411. package/test/plugin/provider-google-vertex.test.ts +387 -0
  412. package/test/plugin/provider-google.test.ts +80 -0
  413. package/test/plugin/provider-groq.test.ts +121 -0
  414. package/test/plugin/provider-kilo.test.ts +99 -0
  415. package/test/plugin/provider-llmgateway.test.ts +80 -0
  416. package/test/plugin/provider-mistral.test.ts +129 -0
  417. package/test/plugin/provider-nvidia.test.ts +97 -0
  418. package/test/plugin/provider-openai-compatible.test.ts +107 -0
  419. package/test/plugin/provider-openai.test.ts +176 -0
  420. package/test/plugin/provider-opencode.test.ts +423 -0
  421. package/test/plugin/provider-openrouter.test.ts +113 -0
  422. package/test/plugin/provider-perplexity.test.ts +122 -0
  423. package/test/plugin/provider-sap-ai-core.test.ts +159 -0
  424. package/test/plugin/provider-snowflake-cortex.test.ts +261 -0
  425. package/test/plugin/provider-togetherai.test.ts +129 -0
  426. package/test/plugin/provider-venice.test.ts +115 -0
  427. package/test/plugin/provider-vercel.test.ts +83 -0
  428. package/test/plugin/provider-xai.test.ts +125 -0
  429. package/test/plugin/provider-zenmux.test.ts +110 -0
  430. package/test/plugin/skill.test.ts +25 -0
  431. package/test/plugin/variant.test.ts +67 -0
  432. package/test/plugin.test.ts +71 -0
  433. package/test/policy.test.ts +85 -0
  434. package/test/preload.ts +5 -0
  435. package/test/process/process.test.ts +368 -0
  436. package/test/project-copy.test.ts +400 -0
  437. package/test/project-directories.test.ts +61 -0
  438. package/test/project.test.ts +221 -0
  439. package/test/provider-mistral.test.ts +282 -0
  440. package/test/provider-xai-responses.test.ts +32 -0
  441. package/test/pty/info-schema.test.ts +32 -0
  442. package/test/pty/protocol.test.ts +27 -0
  443. package/test/pty/pty-session.test.ts +240 -0
  444. package/test/pty/ticket.test.ts +62 -0
  445. package/test/question.test.ts +114 -0
  446. package/test/reference-guidance.test.ts +76 -0
  447. package/test/reference.test.ts +78 -0
  448. package/test/repository-cache.test.ts +153 -0
  449. package/test/repository.test.ts +71 -0
  450. package/test/ripgrep.test.ts +65 -0
  451. package/test/session-compaction.test.ts +27 -0
  452. package/test/session-create.test.ts +425 -0
  453. package/test/session-history.test.ts +165 -0
  454. package/test/session-projector.test.ts +533 -0
  455. package/test/session-prompt.test.ts +584 -0
  456. package/test/session-run-coordinator.test.ts +418 -0
  457. package/test/session-runner-message.test.ts +501 -0
  458. package/test/session-runner-model.test.ts +347 -0
  459. package/test/session-runner-recorded.test.ts +193 -0
  460. package/test/session-runner-tool-events.test.ts +136 -0
  461. package/test/session-runner-tool-registry.test.ts +452 -0
  462. package/test/session-runner.test.ts +3365 -0
  463. package/test/session-todo.test.ts +94 -0
  464. package/test/session-tool-progress.test.ts +158 -0
  465. package/test/shared-schema.test.ts +206 -0
  466. package/test/shell.test.ts +108 -0
  467. package/test/skill/guidance.test.ts +144 -0
  468. package/test/skill-discovery.test.ts +165 -0
  469. package/test/skill.test.ts +125 -0
  470. package/test/snapshot.test.ts +178 -0
  471. package/test/state.test.ts +115 -0
  472. package/test/system-context/builtins.test.ts +129 -0
  473. package/test/system-context/index.test.ts +307 -0
  474. package/test/system-context/registry.test.ts +114 -0
  475. package/test/tool-apply-patch.test.ts +436 -0
  476. package/test/tool-bash.test.ts +437 -0
  477. package/test/tool-edit.test.ts +434 -0
  478. package/test/tool-output-store.test.ts +247 -0
  479. package/test/tool-question.test.ts +162 -0
  480. package/test/tool-read-filesystem.test.ts +118 -0
  481. package/test/tool-read.test.ts +674 -0
  482. package/test/tool-skill.test.ts +149 -0
  483. package/test/tool-todowrite.test.ts +125 -0
  484. package/test/tool-webfetch.test.ts +281 -0
  485. package/test/tool-websearch.test.ts +316 -0
  486. package/test/tool-write.test.ts +305 -0
  487. package/test/util/effect-flock.test.ts +392 -0
  488. package/test/util/flock.test.ts +428 -0
  489. package/test/util/which.test.ts +100 -0
  490. package/tsconfig.json +7 -0
@@ -0,0 +1,266 @@
1
+ export * as Snapshot from "./snapshot"
2
+
3
+ import { makeLocationNode } from "./effect/app-node"
4
+ import path from "path"
5
+ import { Context, Effect, Layer, Schema } from "effect"
6
+ import { Config } from "./config"
7
+ import { File } from "./file"
8
+ import { FSUtil } from "./fs-util"
9
+ import { Git } from "./git"
10
+ import { Global } from "./global"
11
+ import { Location } from "./location"
12
+ import { AbsolutePath, RelativePath } from "./schema"
13
+ import { Hash } from "./util/hash"
14
+
15
+ export const ID = Schema.String.pipe(Schema.brand("Snapshot.ID"))
16
+ export type ID = typeof ID.Type
17
+
18
+ export class Error extends Schema.TaggedErrorClass<Error>()("Snapshot.Error", {
19
+ operation: Schema.Literals(["capture", "files", "diff", "preview", "restore"]),
20
+ message: Schema.String,
21
+ cause: Schema.optional(Schema.Defect()),
22
+ }) {}
23
+
24
+ export interface CompareInput {
25
+ readonly from: ID
26
+ readonly to: ID
27
+ }
28
+
29
+ export interface DiffInput extends CompareInput {
30
+ readonly context?: number
31
+ readonly paths?: readonly RelativePath[]
32
+ }
33
+
34
+ export interface RestoreInput {
35
+ /** Paths are relative to the project root. */
36
+ readonly files: ReadonlyMap<RelativePath, ID>
37
+ }
38
+
39
+ export interface PreviewInput extends RestoreInput {
40
+ readonly context?: number
41
+ }
42
+
43
+ export interface Interface {
44
+ /**
45
+ * Capture the current Location-scoped filesystem state as a content-addressed
46
+ * tree. Returns `undefined` when snapshots are disabled, unsupported, or the
47
+ * best-effort capture fails.
48
+ */
49
+ readonly capture: () => Effect.Effect<ID | undefined>
50
+
51
+ /**
52
+ * List project-relative paths changed between two captured trees without
53
+ * loading file contents or generating patches.
54
+ */
55
+ readonly files: (input: CompareInput) => Effect.Effect<readonly RelativePath[], Error>
56
+
57
+ /**
58
+ * Generate structured per-file diffs between two captured trees. `context`
59
+ * controls unchanged lines around each unified diff hunk.
60
+ */
61
+ readonly diff: (input: DiffInput) => Effect.Effect<readonly File.Diff[], Error>
62
+
63
+ /**
64
+ * Preview the filesystem result of a selective restore without modifying the
65
+ * worktree. Each project-relative path maps to the tree it would be restored
66
+ * from.
67
+ */
68
+ readonly preview: (input: PreviewInput) => Effect.Effect<readonly File.Diff[], Error>
69
+
70
+ /**
71
+ * Restore selected project-relative paths from their associated trees. A path
72
+ * absent from its selected tree is removed; paths outside the map are untouched.
73
+ */
74
+ readonly restore: (input: RestoreInput) => Effect.Effect<void, Error>
75
+
76
+ /**
77
+ * Replace the snapshot index with a captured tree and check out all its entries.
78
+ * Files absent from the tree remain untouched. Prefer selective `restore` when
79
+ * only known paths should change.
80
+ */
81
+ readonly checkout: (snapshot: ID) => Effect.Effect<void, Error>
82
+ }
83
+
84
+ export class Service extends Context.Service<Service, Interface>()("@neurocode/v2/Snapshot") {}
85
+
86
+ const layer = Layer.effect(
87
+ Service,
88
+ Effect.gen(function* () {
89
+ const config = yield* Config.Service
90
+ const fs = yield* FSUtil.Service
91
+ const git = yield* Git.Service
92
+ const global = yield* Global.Service
93
+ const location = yield* Location.Service
94
+ const source = yield* git.repo.discover(location.project.directory)
95
+ const worktree = source
96
+ ? AbsolutePath.make(yield* fs.realPath(source.worktree).pipe(Effect.orDie))
97
+ : location.project.directory
98
+ const gitDirectory = AbsolutePath.make(path.join(global.data, "snapshot", location.project.id, Hash.fast(worktree)))
99
+
100
+ const scope = Effect.fnUntraced(function* () {
101
+ const relative = path.relative(worktree, location.directory)
102
+ if (relative.startsWith("..") || path.isAbsolute(relative))
103
+ return yield* new Error({ operation: "capture", message: "Location is outside the project" })
104
+ return RelativePath.make(relative.replaceAll("\\", "/") || ".")
105
+ })
106
+
107
+ const repository = Effect.fnUntraced(function* () {
108
+ if (!source) return yield* new Error({ operation: "capture", message: "Project is not a Git repository" })
109
+ if (yield* fs.existsSafe(path.join(gitDirectory, "HEAD")))
110
+ return new Git.Repository({
111
+ worktree,
112
+ gitDirectory,
113
+ commonDirectory: gitDirectory,
114
+ })
115
+ return yield* git.repo
116
+ .create({
117
+ worktree,
118
+ gitDirectory,
119
+ seed: source,
120
+ })
121
+ .pipe(Effect.mapError((cause) => failure("capture", cause)))
122
+ })
123
+
124
+ const enabled = Effect.fnUntraced(function* () {
125
+ if (location.vcs?.type !== "git") return false
126
+ return Config.latest(yield* config.entries(), "snapshots") !== false
127
+ })
128
+
129
+ const capture = Effect.fn("Snapshot.capture")(function* () {
130
+ if (!(yield* enabled())) return undefined
131
+ return yield* Effect.gen(function* () {
132
+ const repo = yield* repository()
133
+ return ID.make(
134
+ yield* git.tree.capture({
135
+ repository: repo,
136
+ scopes: [yield* scope()],
137
+ ignores: source,
138
+ maximumUntrackedFileBytes: 2 * 1024 * 1024,
139
+ }),
140
+ )
141
+ }).pipe(
142
+ Effect.catch((cause) => Effect.logWarning("failed to capture snapshot", { cause }).pipe(Effect.as(undefined))),
143
+ )
144
+ })
145
+
146
+ const compare = Effect.fnUntraced(function* (operation: "files" | "diff", input: CompareInput) {
147
+ const repo = yield* repository().pipe(Effect.mapError((cause) => failure(operation, cause)))
148
+ return { repository: repo, from: Git.TreeID.make(input.from), to: Git.TreeID.make(input.to) }
149
+ })
150
+
151
+ const files = Effect.fn("Snapshot.files")(function* (input: CompareInput) {
152
+ const comparison = yield* compare("files", input)
153
+ const files = yield* git.tree.files(comparison).pipe(Effect.mapError((cause) => failure("files", cause)))
154
+ if (!source) return files
155
+ const ignored = yield* git.index
156
+ .ignored({ repository: source, paths: files })
157
+ .pipe(Effect.mapError((cause) => failure("files", cause)))
158
+ return files.filter((file) => !ignored.has(file))
159
+ })
160
+
161
+ const diff = Effect.fn("Snapshot.diff")(function* (input: DiffInput) {
162
+ const comparison = yield* compare("diff", input)
163
+ const files = yield* git.tree.files(comparison).pipe(Effect.mapError((cause) => failure("diff", cause)))
164
+ const ignored = source
165
+ ? yield* git.index
166
+ .ignored({ repository: source, paths: files })
167
+ .pipe(Effect.mapError((cause) => failure("diff", cause)))
168
+ : new Set<RelativePath>()
169
+ return yield* git.tree
170
+ .diff({
171
+ ...comparison,
172
+ context: input.context,
173
+ paths: (input.paths ?? files).filter((file) => !ignored.has(file)),
174
+ })
175
+ .pipe(Effect.mapError((cause) => failure("diff", cause)))
176
+ })
177
+
178
+ const plan = Effect.fnUntraced(function* (operation: "preview" | "restore", input: RestoreInput) {
179
+ const files = new Map<RelativePath, Git.TreeID>()
180
+ for (const [file, snapshot] of input.files) {
181
+ const absolute = path.resolve(worktree, file)
182
+ if (!FSUtil.contains(worktree, absolute))
183
+ return yield* new Error({ operation, message: `Path escapes the project: ${file}` })
184
+ files.set(file, Git.TreeID.make(snapshot))
185
+ }
186
+ return files
187
+ })
188
+
189
+ const preview = Effect.fn("Snapshot.preview")(function* (input: PreviewInput) {
190
+ if (!(yield* enabled())) return yield* new Error({ operation: "preview", message: "Snapshots are disabled" })
191
+ const repo = yield* repository().pipe(Effect.mapError((cause) => failure("preview", cause)))
192
+ const files = yield* plan("preview", input)
193
+ const current = yield* git.tree
194
+ .capture({
195
+ repository: repo,
196
+ scopes: Array.from(files.keys()),
197
+ ignores: source,
198
+ maximumUntrackedFileBytes: 2 * 1024 * 1024,
199
+ })
200
+ .pipe(Effect.mapError((cause) => failure("preview", cause)))
201
+ return yield* git.tree
202
+ .preview({
203
+ repository: repo,
204
+ current,
205
+ files,
206
+ context: input.context,
207
+ })
208
+ .pipe(Effect.mapError((cause) => failure("preview", cause)))
209
+ })
210
+
211
+ const restore = Effect.fn("Snapshot.restore")(function* (input: RestoreInput) {
212
+ if (!(yield* enabled())) return yield* new Error({ operation: "restore", message: "Snapshots are disabled" })
213
+ const repo = yield* repository().pipe(Effect.mapError((cause) => failure("restore", cause)))
214
+ yield* git.tree
215
+ .restore({ repository: repo, files: yield* plan("restore", input) })
216
+ .pipe(Effect.mapError((cause) => failure("restore", cause)))
217
+ })
218
+
219
+ const checkout = Effect.fn("Snapshot.checkout")(function* (snapshot: ID) {
220
+ const repo = yield* repository().pipe(Effect.mapError((cause) => failure("restore", cause)))
221
+ yield* git.tree
222
+ .checkout({ repository: repo, tree: Git.TreeID.make(snapshot) })
223
+ .pipe(Effect.mapError((cause) => failure("restore", cause)))
224
+ })
225
+
226
+ return Service.of({ capture, files, diff, preview, restore, checkout })
227
+ }),
228
+ )
229
+
230
+ export const locationLayer = layer.pipe(Layer.provideMerge(Config.locationLayer))
231
+
232
+ export const node = makeLocationNode({
233
+ service: Service,
234
+ layer,
235
+ deps: [Config.node, FSUtil.node, Git.node, Global.node, Location.node],
236
+ })
237
+
238
+ export const noopLayer = Layer.succeed(
239
+ Service,
240
+ Service.of({
241
+ capture: () => Effect.succeed(undefined),
242
+ files: () => Effect.succeed([]),
243
+ diff: () => Effect.succeed([]),
244
+ preview: () => Effect.succeed([]),
245
+ restore: () => Effect.void,
246
+ checkout: () => Effect.void,
247
+ }),
248
+ )
249
+
250
+ function failure(operation: Error["operation"], cause: unknown) {
251
+ if (cause instanceof Error && cause.operation === operation) return cause
252
+ return new Error({
253
+ operation,
254
+ message: cause instanceof globalThis.Error ? cause.message : String(cause),
255
+ cause,
256
+ })
257
+ }
258
+
259
+ /** Legacy persisted session diff shape. */
260
+ export type LegacyFileDiff = {
261
+ file?: string
262
+ patch?: string
263
+ additions: number
264
+ deletions: number
265
+ status?: "added" | "deleted" | "modified"
266
+ }
package/src/state.ts ADDED
@@ -0,0 +1,128 @@
1
+ export * as State from "./state"
2
+
3
+ import { Context, Effect, Scope, Semaphore } from "effect"
4
+
5
+ /**
6
+ * A replayable transform applied to a draft during reload.
7
+ *
8
+ * Domain drafts expose readable and writable state while preserving concise
9
+ * plugin/config code. Transforms may perform Effects before returning.
10
+ */
11
+ type TransformCallback<DraftApi> = (draft: DraftApi) => Effect.Effect<void> | void
12
+ export type MakeDraft<State, DraftApi> = (state: State) => DraftApi
13
+
14
+ export interface Registration {
15
+ readonly dispose: Effect.Effect<void>
16
+ }
17
+
18
+ export type Transform<DraftApi> = (
19
+ transform: TransformCallback<DraftApi>,
20
+ ) => Effect.Effect<Registration, never, Scope.Scope>
21
+
22
+ export type Reload = () => Effect.Effect<void>
23
+
24
+ export interface Transformable<DraftApi> {
25
+ readonly transform: Transform<DraftApi>
26
+ readonly reload: Reload
27
+ }
28
+
29
+ const CurrentBatch = Context.Reference<Set<Reload> | undefined>("@neurocode/State/CurrentBatch", {
30
+ defaultValue: () => undefined,
31
+ })
32
+
33
+ export function batch<A, E, R>(effect: Effect.Effect<A, E, R>) {
34
+ return Effect.gen(function* () {
35
+ const current = yield* CurrentBatch
36
+ if (current) return yield* effect
37
+ const reloads = new Set<Reload>()
38
+ const result = yield* effect.pipe(Effect.provideService(CurrentBatch, reloads))
39
+ yield* Effect.forEach(reloads, (reload) => reload(), { discard: true })
40
+ return result
41
+ })
42
+ }
43
+
44
+ export interface Options<State, DraftApi> {
45
+ /** Creates the base value for initial state and every scoped-transform reload. */
46
+ readonly initial: () => State
47
+ /** Wraps mutable state in a domain-specific draft API. */
48
+ readonly draft: MakeDraft<State, DraftApi>
49
+ /** Runs after all active transforms and before the rebuilt state becomes visible. */
50
+ readonly finalize?: (draft: DraftApi) => Effect.Effect<void>
51
+ }
52
+
53
+ export interface Interface<State, DraftApi> extends Transformable<DraftApi> {
54
+ readonly get: () => State
55
+ /**
56
+ * Registers and applies a scoped transform. Closing the owning Scope removes
57
+ * the transform and reloads the materialized state.
58
+ */
59
+ }
60
+
61
+ export function create<State, DraftApi>(options: Options<State, DraftApi>): Interface<State, DraftApi> {
62
+ let state = options.initial()
63
+ let transforms: { run: TransformCallback<DraftApi> }[] = []
64
+ const semaphore = Semaphore.makeUnsafe(1)
65
+
66
+ const commit = Effect.fn("State.commit")(function* (next: State) {
67
+ const api = options.draft(next)
68
+ if (options.finalize) yield* options.finalize(api)
69
+ state = next
70
+ })
71
+
72
+ const apply = (transform: TransformCallback<DraftApi>, draft: DraftApi) =>
73
+ Effect.suspend(() => {
74
+ const result = transform(draft)
75
+ return Effect.isEffect(result) ? Effect.asVoid(result).pipe(Effect.orDie) : Effect.void
76
+ })
77
+
78
+ const materialize = Effect.fnUntraced(function* () {
79
+ const next = options.initial()
80
+ const api = options.draft(next)
81
+ for (const transform of transforms) yield* apply(transform.run, api).pipe(Effect.withSpan("State.reload.update"))
82
+ yield* commit(next)
83
+ })
84
+
85
+ const reload = () => semaphore.withPermit(materialize())
86
+
87
+ const result: Interface<State, DraftApi> = {
88
+ get: () => state,
89
+ transform: Effect.fn("State.transform")(function* (update) {
90
+ const scope = yield* Scope.Scope
91
+ return yield* Effect.uninterruptible(
92
+ Effect.gen(function* () {
93
+ const transform = { run: update }
94
+ let active = true
95
+ const dispose = Effect.uninterruptible(
96
+ semaphore.withPermit(
97
+ Effect.suspend(() => {
98
+ if (!active) return Effect.void
99
+ active = false
100
+ transforms = transforms.filter((item) => item !== transform)
101
+ return Effect.gen(function* () {
102
+ const batch = yield* CurrentBatch
103
+ if (batch) {
104
+ batch.add(reload)
105
+ return
106
+ }
107
+ yield* materialize()
108
+ })
109
+ }),
110
+ ),
111
+ )
112
+ yield* semaphore.withPermit(
113
+ Effect.sync(() => {
114
+ transforms = [...transforms, transform]
115
+ }),
116
+ )
117
+ yield* Scope.addFinalizer(scope, dispose)
118
+ const batch = yield* CurrentBatch
119
+ if (batch) batch.add(reload)
120
+ else yield* reload()
121
+ return { dispose }
122
+ }),
123
+ )
124
+ }),
125
+ reload,
126
+ }
127
+ return result
128
+ }
@@ -0,0 +1,50 @@
1
+ export * as SystemContextBuiltIns from "./builtins"
2
+
3
+ import { makeLocationNode } from "../effect/app-node"
4
+ import { DateTime, Effect, Layer, Schema } from "effect"
5
+ import { Location } from "../location"
6
+ import { SystemContext } from "./index"
7
+ import { InstructionContext } from "../instruction-context"
8
+ import { SystemContextRegistry } from "./registry"
9
+ import { FSUtil } from "../fs-util"
10
+ import { Global } from "../global"
11
+
12
+ const builtIns = Layer.effectDiscard(
13
+ Effect.gen(function* () {
14
+ const location = yield* Location.Service
15
+ const registry = yield* SystemContextRegistry.Service
16
+ const environment = [
17
+ "<env>",
18
+ ` Working directory: ${location.directory}`,
19
+ ` Workspace root folder: ${location.project.directory}`,
20
+ ` Is directory a git repo: ${location.vcs?.type === "git" ? "yes" : "no"}`,
21
+ ` Platform: ${process.platform}`,
22
+ "</env>",
23
+ ].join("\n")
24
+ const context = SystemContext.combine([
25
+ SystemContext.make({
26
+ key: SystemContext.Key.make("core/environment"),
27
+ codec: Schema.toCodecJson(Schema.String),
28
+ load: Effect.succeed(environment),
29
+ baseline: (environment) =>
30
+ ["Here is some useful information about the environment you are running in:", environment].join("\n"),
31
+ update: (_previous, environment) => ["The environment you are running in is now:", environment].join("\n"),
32
+ }),
33
+ SystemContext.make({
34
+ key: SystemContext.Key.make("core/date"),
35
+ codec: Schema.toCodecJson(Schema.String),
36
+ load: DateTime.nowAsDate.pipe(Effect.map((date) => date.toDateString())),
37
+ baseline: (date) => `Today's date: ${date}`,
38
+ update: (_previous, date) => `Today's date is now: ${date}`,
39
+ }),
40
+ ])
41
+
42
+ yield* registry.register({ key: SystemContext.Key.make("core/builtins"), load: Effect.succeed(context) })
43
+ }),
44
+ )
45
+
46
+ export const node = makeLocationNode({
47
+ name: "system-context-builtins",
48
+ layer: builtIns,
49
+ deps: [Location.node, SystemContextRegistry.node, InstructionContext.node, FSUtil.node, Global.node],
50
+ })