ashlr-plugin 1.36.4

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 (499) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +39 -0
  3. package/.claude-plugin/plugin.json +36 -0
  4. package/.codex/agents/README.md +9 -0
  5. package/.codex/agents/ashlr-explorer.md +36 -0
  6. package/.codex/agents/ashlr-worker.md +38 -0
  7. package/.codex-plugin/plugin.json +45 -0
  8. package/.mcp.json +14 -0
  9. package/LICENSE +21 -0
  10. package/README.md +311 -0
  11. package/agents/ashlr-code.md +69 -0
  12. package/agents/ashlr-explore.md +44 -0
  13. package/agents/ashlr-plan.md +54 -0
  14. package/bench/fixtures/notebook-large.ipynb +660 -0
  15. package/bench/fixtures/notebook-small.ipynb +39 -0
  16. package/bench/fixtures/tasklist-closed.json +62 -0
  17. package/bench/fixtures/tasklist-large-mixed.json +27 -0
  18. package/bench/fixtures/tasklist-sprint-open.json +79 -0
  19. package/bench/fixtures/websearch-bun-runtime.json +32 -0
  20. package/bench/fixtures/websearch-react-hooks-patterns.json +32 -0
  21. package/bench/fixtures/websearch-typescript-generics.json +38 -0
  22. package/bench/refs/node-sdk/.refrev +1 -0
  23. package/bench/refs/node-sdk/README.md +17 -0
  24. package/bench/refs/node-sdk/src/agent/agent.ts +163 -0
  25. package/bench/refs/node-sdk/src/agent/create-agent-ui-stream.ts +83 -0
  26. package/bench/refs/node-sdk/src/agent/tool-loop-agent.ts +238 -0
  27. package/bench/refs/node-sdk/src/embed/embed-many.ts +409 -0
  28. package/bench/refs/node-sdk/src/embed/embed-result.ts +50 -0
  29. package/bench/refs/node-sdk/src/embed/embed.ts +257 -0
  30. package/bench/refs/node-sdk/src/error/invalid-argument-error.ts +34 -0
  31. package/bench/refs/node-sdk/src/error/invalid-tool-input-error.ts +33 -0
  32. package/bench/refs/node-sdk/src/error/no-object-generated-error.ts +70 -0
  33. package/bench/refs/node-sdk/src/generate-image/generate-image-result.ts +42 -0
  34. package/bench/refs/node-sdk/src/generate-image/generate-image.ts +362 -0
  35. package/bench/refs/node-sdk/src/generate-object/generate-object-result.ts +67 -0
  36. package/bench/refs/node-sdk/src/generate-object/generate-object.ts +501 -0
  37. package/bench/refs/node-sdk/src/generate-object/inject-json-instruction.ts +30 -0
  38. package/bench/refs/node-sdk/src/generate-object/output-strategy.ts +415 -0
  39. package/bench/refs/node-sdk/src/generate-object/repair-text.ts +12 -0
  40. package/bench/refs/node-sdk/src/generate-object/stream-object.ts +960 -0
  41. package/bench/refs/node-sdk/src/generate-speech/generate-speech.ts +191 -0
  42. package/bench/refs/node-sdk/src/generate-text/generate-text.ts +1484 -0
  43. package/bench/refs/node-sdk/src/generate-text/stream-text.ts +2708 -0
  44. package/bench/refs/node-sdk/src/generate-text/tool-call.ts +59 -0
  45. package/bench/refs/node-sdk/src/generate-text/tool-result.ts +36 -0
  46. package/bench/refs/node-sdk/src/telemetry/create-telemetry-dispatcher.ts +146 -0
  47. package/bench/refs/node-sdk/src/telemetry/telemetry-registry.ts +15 -0
  48. package/bench/refs/node-sdk/src/telemetry/telemetry.ts +223 -0
  49. package/bench/refs/node-sdk/src/util/async-iterable-stream.ts +94 -0
  50. package/bench/refs/node-sdk/src/util/consume-stream.ts +31 -0
  51. package/bench/refs/node-sdk/src/util/create-stitchable-stream.ts +112 -0
  52. package/bench/refs/node-sdk/src/util/download/download.ts +74 -0
  53. package/bench/refs/node-sdk/src/util/error-handler.ts +1 -0
  54. package/bench/refs/node-sdk/src/util/fix-json.ts +401 -0
  55. package/bench/refs/node-sdk/src/util/merge-objects.ts +79 -0
  56. package/bench/refs/python-lib/.refrev +1 -0
  57. package/bench/refs/python-lib/README.md +18 -0
  58. package/bench/refs/python-lib/pandas/core/_numba/executor.py +249 -0
  59. package/bench/refs/python-lib/pandas/core/_numba/extensions.py +586 -0
  60. package/bench/refs/python-lib/pandas/core/_numba/kernels/mean_.py +198 -0
  61. package/bench/refs/python-lib/pandas/core/_numba/kernels/min_max_.py +178 -0
  62. package/bench/refs/python-lib/pandas/core/_numba/kernels/sum_.py +255 -0
  63. package/bench/refs/python-lib/pandas/core/_numba/kernels/var_.py +251 -0
  64. package/bench/refs/python-lib/pandas/core/accessor.py +520 -0
  65. package/bench/refs/python-lib/pandas/core/api.py +138 -0
  66. package/bench/refs/python-lib/pandas/core/array_algos/masked_accumulations.py +97 -0
  67. package/bench/refs/python-lib/pandas/core/array_algos/masked_reductions.py +252 -0
  68. package/bench/refs/python-lib/pandas/core/array_algos/putmask.py +150 -0
  69. package/bench/refs/python-lib/pandas/core/array_algos/quantile.py +232 -0
  70. package/bench/refs/python-lib/pandas/core/array_algos/replace.py +159 -0
  71. package/bench/refs/python-lib/pandas/core/array_algos/take.py +609 -0
  72. package/bench/refs/python-lib/pandas/core/arraylike.py +534 -0
  73. package/bench/refs/python-lib/pandas/core/arrays/_arrow_string_mixins.py +434 -0
  74. package/bench/refs/python-lib/pandas/core/arrays/_mixins.py +630 -0
  75. package/bench/refs/python-lib/pandas/core/arrays/_ranges.py +276 -0
  76. package/bench/refs/python-lib/pandas/core/arrays/_utils.py +77 -0
  77. package/bench/refs/python-lib/pandas/core/arrays/arrow/accessors.py +521 -0
  78. package/bench/refs/python-lib/pandas/core/arrays/arrow/extension_types.py +174 -0
  79. package/bench/refs/python-lib/pandas/core/arrays/boolean.py +454 -0
  80. package/bench/refs/python-lib/pandas/core/arrays/floating.py +192 -0
  81. package/bench/refs/python-lib/pandas/core/arrays/integer.py +296 -0
  82. package/bench/refs/python-lib/pandas/core/arrays/masked.py +2140 -0
  83. package/bench/refs/python-lib/pandas/core/arrays/numeric.py +305 -0
  84. package/bench/refs/python-lib/pandas/core/arrays/numpy_.py +701 -0
  85. package/bench/refs/python-lib/pandas/core/arrays/period.py +1586 -0
  86. package/bench/refs/python-lib/pandas/core/arrays/sparse/accessor.py +505 -0
  87. package/bench/refs/python-lib/pandas/core/arrays/sparse/scipy_sparse.py +208 -0
  88. package/bench/refs/rust-project/.refrev +1 -0
  89. package/bench/refs/rust-project/README.md +17 -0
  90. package/bench/refs/rust-project/tokio/src/doc/os.rs +68 -0
  91. package/bench/refs/rust-project/tokio/src/fs/dir_builder.rs +129 -0
  92. package/bench/refs/rust-project/tokio/src/fs/file.rs +1113 -0
  93. package/bench/refs/rust-project/tokio/src/fs/mocks.rs +176 -0
  94. package/bench/refs/rust-project/tokio/src/fs/mod.rs +324 -0
  95. package/bench/refs/rust-project/tokio/src/fs/open_options.rs +856 -0
  96. package/bench/refs/rust-project/tokio/src/fs/read.rs +80 -0
  97. package/bench/refs/rust-project/tokio/src/fs/read_dir.rs +357 -0
  98. package/bench/refs/rust-project/tokio/src/fs/write.rs +99 -0
  99. package/bench/refs/rust-project/tokio/src/future/maybe_done.rs +123 -0
  100. package/bench/refs/rust-project/tokio/src/future/try_join.rs +82 -0
  101. package/bench/refs/rust-project/tokio/src/io/async_buf_read.rs +117 -0
  102. package/bench/refs/rust-project/tokio/src/io/async_read.rs +133 -0
  103. package/bench/refs/rust-project/tokio/src/io/async_seek.rs +96 -0
  104. package/bench/refs/rust-project/tokio/src/io/async_write.rs +402 -0
  105. package/bench/refs/rust-project/tokio/src/io/blocking.rs +339 -0
  106. package/bench/refs/rust-project/tokio/src/io/interest.rs +345 -0
  107. package/bench/refs/rust-project/tokio/src/io/join.rs +130 -0
  108. package/bench/refs/rust-project/tokio/src/io/mod.rs +308 -0
  109. package/bench/refs/rust-project/tokio/src/io/poll_evented.rs +319 -0
  110. package/bench/refs/rust-project/tokio/src/io/read_buf.rs +344 -0
  111. package/bench/refs/rust-project/tokio/src/io/ready.rs +322 -0
  112. package/bench/refs/rust-project/tokio/src/io/split.rs +166 -0
  113. package/bench/refs/rust-project/tokio/src/io/stderr.rs +148 -0
  114. package/bench/refs/rust-project/tokio/src/io/stdin.rs +98 -0
  115. package/bench/refs/rust-project/tokio/src/io/stdio_common.rs +222 -0
  116. package/bench/refs/rust-project/tokio/src/io/stdout.rs +197 -0
  117. package/bench/refs/rust-project/tokio/src/io/util/buf_reader.rs +311 -0
  118. package/bench/refs/rust-project/tokio/src/io/util/buf_stream.rs +207 -0
  119. package/bench/refs/rust-project/tokio/src/io/util/buf_writer.rs +310 -0
  120. package/bench/refs/rust-project/tokio/src/io/util/chain.rs +144 -0
  121. package/commands/_spawn-patterns.json +32 -0
  122. package/commands/ashlr-allow.md +21 -0
  123. package/commands/ashlr-benchmark.md +53 -0
  124. package/commands/ashlr-brief.md +97 -0
  125. package/commands/ashlr-budget.md +76 -0
  126. package/commands/ashlr-compact.md +54 -0
  127. package/commands/ashlr-dashboard.md +37 -0
  128. package/commands/ashlr-doctor.md +56 -0
  129. package/commands/ashlr-eco-mode.md +92 -0
  130. package/commands/ashlr-genome-init.md +24 -0
  131. package/commands/ashlr-genome-keygen.md +36 -0
  132. package/commands/ashlr-genome-loop.md +118 -0
  133. package/commands/ashlr-genome-push.md +36 -0
  134. package/commands/ashlr-genome-rewrap.md +48 -0
  135. package/commands/ashlr-genome-team-init.md +67 -0
  136. package/commands/ashlr-handoff.md +23 -0
  137. package/commands/ashlr-help.md +86 -0
  138. package/commands/ashlr-hook-timings.md +30 -0
  139. package/commands/ashlr-leaderboard.md +50 -0
  140. package/commands/ashlr-ollama-setup.md +39 -0
  141. package/commands/ashlr-orchestrate-status.md +72 -0
  142. package/commands/ashlr-orchestrate.md +83 -0
  143. package/commands/ashlr-parallelize.md +63 -0
  144. package/commands/ashlr-report-crash.md +33 -0
  145. package/commands/ashlr-resume.md +72 -0
  146. package/commands/ashlr-savings.md +24 -0
  147. package/commands/ashlr-settings.md +50 -0
  148. package/commands/ashlr-spawn.md +61 -0
  149. package/commands/ashlr-start.md +60 -0
  150. package/commands/ashlr-status.md +64 -0
  151. package/commands/ashlr-team-invite.md +47 -0
  152. package/commands/ashlr-tier.md +122 -0
  153. package/commands/ashlr-tour.md +60 -0
  154. package/commands/ashlr-update.md +155 -0
  155. package/commands/ashlr-upgrade.md +96 -0
  156. package/commands/goal.md +58 -0
  157. package/commands/loop.md +40 -0
  158. package/docs/CNAME +1 -0
  159. package/docs/PRO_TIER.md +104 -0
  160. package/docs/README.md +21 -0
  161. package/docs/architecture.md +415 -0
  162. package/docs/ashlr-pipe.md +161 -0
  163. package/docs/assets/logo.svg +19 -0
  164. package/docs/assets/og.png +0 -0
  165. package/docs/assets/og.svg +41 -0
  166. package/docs/benchmarks-v2.json +355 -0
  167. package/docs/benchmarks.json +102 -0
  168. package/docs/benchmarks.md +211 -0
  169. package/docs/billing.md +185 -0
  170. package/docs/cloud-genome.md +155 -0
  171. package/docs/competitive-wozcode.md +92 -0
  172. package/docs/deploy.md +325 -0
  173. package/docs/email-templates.md +113 -0
  174. package/docs/embed-tuning.md +103 -0
  175. package/docs/genome.md +120 -0
  176. package/docs/github-oauth-onboarding.md +127 -0
  177. package/docs/hero-video-script.md +129 -0
  178. package/docs/index.html +2262 -0
  179. package/docs/install-prompt.md +78 -0
  180. package/docs/install-windows.md +132 -0
  181. package/docs/install.ps1 +171 -0
  182. package/docs/install.sh +146 -0
  183. package/docs/launch/README.md +114 -0
  184. package/docs/launch/hn.md +49 -0
  185. package/docs/launch/reddit.md +45 -0
  186. package/docs/launch/x.md +65 -0
  187. package/docs/launch-post.md +112 -0
  188. package/docs/legal.md +78 -0
  189. package/docs/llm-providers.md +99 -0
  190. package/docs/multi-host-mcp.md +217 -0
  191. package/docs/multi-turn-architecture.md +108 -0
  192. package/docs/operations/deployment.md +108 -0
  193. package/docs/operations/error-monitoring.md +70 -0
  194. package/docs/operations/weekly-digest.md +70 -0
  195. package/docs/operations.md +494 -0
  196. package/docs/platform-support.md +133 -0
  197. package/docs/policy-packs.md +188 -0
  198. package/docs/press-kit/fact-sheet.md +78 -0
  199. package/docs/press-kit/founder-bio.md +3 -0
  200. package/docs/press-kit/logo.svg +33 -0
  201. package/docs/press-kit/screenshots.md +146 -0
  202. package/docs/pricing.md +251 -0
  203. package/docs/pro-backend-architecture.md +523 -0
  204. package/docs/producthunt.md +52 -0
  205. package/docs/router-migration.md +110 -0
  206. package/docs/session-log-schema.md +68 -0
  207. package/docs/social.md +95 -0
  208. package/docs/team-genome.md +528 -0
  209. package/docs/telemetry.md +194 -0
  210. package/docs/test-isolation.md +100 -0
  211. package/docs/upgrade.md +159 -0
  212. package/hooks/_hook-errors.ts +87 -0
  213. package/hooks/_hook-perf-emit.ts +113 -0
  214. package/hooks/_hook-timing-ledger.ts +1133 -0
  215. package/hooks/_nudge-throttle.ts +127 -0
  216. package/hooks/_recent-blocks.ts +127 -0
  217. package/hooks/audit-upload.ts +86 -0
  218. package/hooks/codex-hooks.json +171 -0
  219. package/hooks/commit-attribution.ts +179 -0
  220. package/hooks/edit-batching-nudge.ts +154 -0
  221. package/hooks/genome-scribe-hook.ts +219 -0
  222. package/hooks/hooks.json +294 -0
  223. package/hooks/orient-nudge-hook.ts +242 -0
  224. package/hooks/policy-enforce.ts +214 -0
  225. package/hooks/post-tool-use-embedding.ts +93 -0
  226. package/hooks/post-tool-use-genome.sh +37 -0
  227. package/hooks/post-tool-use-genome.ts +69 -0
  228. package/hooks/posttooluse-correlate.ts +122 -0
  229. package/hooks/posttooluse-dedupe-output.ts +241 -0
  230. package/hooks/posttooluse-genome-refresh.ts +223 -0
  231. package/hooks/posttooluse-native-nudge.ts +205 -0
  232. package/hooks/posttooluse-stale-result.ts +277 -0
  233. package/hooks/pretooluse-bash.ts +63 -0
  234. package/hooks/pretooluse-budget-guard.ts +318 -0
  235. package/hooks/pretooluse-common.ts +985 -0
  236. package/hooks/pretooluse-eco-router.ts +196 -0
  237. package/hooks/pretooluse-edit.sh +93 -0
  238. package/hooks/pretooluse-edit.ts +197 -0
  239. package/hooks/pretooluse-glob.ts +70 -0
  240. package/hooks/pretooluse-grep.sh +85 -0
  241. package/hooks/pretooluse-grep.ts +96 -0
  242. package/hooks/pretooluse-notebookedit.ts +121 -0
  243. package/hooks/pretooluse-read.sh +118 -0
  244. package/hooks/pretooluse-read.ts +118 -0
  245. package/hooks/pretooluse-task.ts +130 -0
  246. package/hooks/pretooluse-webfetch.ts +66 -0
  247. package/hooks/pretooluse-websearch.ts +85 -0
  248. package/hooks/pretooluse-write.ts +128 -0
  249. package/hooks/pulse-emit.ts +197 -0
  250. package/hooks/session-end-consolidate.sh +35 -0
  251. package/hooks/session-end-consolidate.ts +188 -0
  252. package/hooks/session-end-stats-gc.ts +80 -0
  253. package/hooks/session-log-append.sh +94 -0
  254. package/hooks/session-log-append.ts +116 -0
  255. package/hooks/session-start.ts +993 -0
  256. package/hooks/sessionend-hook-health-nudge.ts +451 -0
  257. package/hooks/sessionend-savings-nudge.ts +318 -0
  258. package/hooks/sessionend-status-line-nudge.ts +296 -0
  259. package/hooks/sessionstart-brief.ts +140 -0
  260. package/hooks/sessionstart-cost-refactor.ts +95 -0
  261. package/hooks/sessionstart-efficient.ts +110 -0
  262. package/hooks/sessionstart-genome-author.ts +93 -0
  263. package/hooks/sessionstart-lean-tools.ts +98 -0
  264. package/hooks/sessionstart-search.ts +97 -0
  265. package/hooks/stop-accounting.ts +152 -0
  266. package/hooks/subagent-stop-rollup.ts +162 -0
  267. package/hooks/userpromptsubmit-brief-trigger.ts +156 -0
  268. package/package.json +56 -0
  269. package/ports/README.md +108 -0
  270. package/ports/cursor/mcp.json +11 -0
  271. package/ports/goose/recipe.yaml +26 -0
  272. package/scripts/ashlr-mcp.ts +40 -0
  273. package/scripts/auto-update.ts +177 -0
  274. package/scripts/baseline-scan.ts +831 -0
  275. package/scripts/bench-orchestrate.ts +377 -0
  276. package/scripts/benchmark-refs.ts +292 -0
  277. package/scripts/bootstrap.mjs +100 -0
  278. package/scripts/brief-eval.ts +234 -0
  279. package/scripts/bump-version.ts +82 -0
  280. package/scripts/bun-resolve.d.mts +11 -0
  281. package/scripts/bun-resolve.mjs +59 -0
  282. package/scripts/calibrate-grep.ts +467 -0
  283. package/scripts/capture-grep-workload.ts +260 -0
  284. package/scripts/check-tier.ts +61 -0
  285. package/scripts/check-version-sync.ts +97 -0
  286. package/scripts/cli-orchestrate-status.ts +386 -0
  287. package/scripts/cli-orchestrate.ts +303 -0
  288. package/scripts/cli.ts +478 -0
  289. package/scripts/cloud-smoke-test.ts +313 -0
  290. package/scripts/coach-report.ts +373 -0
  291. package/scripts/context-db-migrate.ts +137 -0
  292. package/scripts/context-status.ts +43 -0
  293. package/scripts/demo-run.ts +255 -0
  294. package/scripts/deploy-smoke.sh +140 -0
  295. package/scripts/doctor.ts +992 -0
  296. package/scripts/embed-file-worker.ts +104 -0
  297. package/scripts/embed-tune.ts +308 -0
  298. package/scripts/errors-report.ts +428 -0
  299. package/scripts/find-test-leak.ts +69 -0
  300. package/scripts/generate-badge.ts +357 -0
  301. package/scripts/genome-auto-consolidate.ts +533 -0
  302. package/scripts/genome-auto-propose.ts +578 -0
  303. package/scripts/genome-cloud-pull.ts +363 -0
  304. package/scripts/genome-cloud-push.ts +382 -0
  305. package/scripts/genome-cloud-sync.ts +587 -0
  306. package/scripts/genome-commit-watcher.ts +295 -0
  307. package/scripts/genome-init.ts +986 -0
  308. package/scripts/genome-key.ts +233 -0
  309. package/scripts/genome-keygen.ts +168 -0
  310. package/scripts/genome-link.ts +59 -0
  311. package/scripts/genome-refresh-worker.ts +364 -0
  312. package/scripts/genome-rewrap.ts +90 -0
  313. package/scripts/genome-synthesizer.ts +679 -0
  314. package/scripts/genome-team-init.ts +312 -0
  315. package/scripts/handoff-pack.ts +438 -0
  316. package/scripts/hook-bootstrap.mjs +75 -0
  317. package/scripts/hook-timing-reader.ts +371 -0
  318. package/scripts/hook-timings-report.ts +554 -0
  319. package/scripts/install-genome-hooks.ts +196 -0
  320. package/scripts/install-onnx-model.ts +154 -0
  321. package/scripts/install-permissions.ts +276 -0
  322. package/scripts/install-status-line.ts +150 -0
  323. package/scripts/mcp-entrypoint.sh +78 -0
  324. package/scripts/mcp-entrypoint.ts +130 -0
  325. package/scripts/mdx-angle-bracket-lint.ts +152 -0
  326. package/scripts/measure-cold-start.ts +126 -0
  327. package/scripts/migrate-stats-to-sqlite.ts +86 -0
  328. package/scripts/ollama-setup.ts +498 -0
  329. package/scripts/onboarding-wizard.ts +1691 -0
  330. package/scripts/orchestrate-emit-telemetry.ts +177 -0
  331. package/scripts/orchestrate-expand.ts +517 -0
  332. package/scripts/orchestrate-run.ts +744 -0
  333. package/scripts/print-legend.ts +50 -0
  334. package/scripts/product-metadata.ts +38 -0
  335. package/scripts/prune-old-memories.ts +208 -0
  336. package/scripts/publish.sh +88 -0
  337. package/scripts/read-calibration.ts +122 -0
  338. package/scripts/report-crash.ts +226 -0
  339. package/scripts/run-benchmark.ts +750 -0
  340. package/scripts/run-root-tests.ts +28 -0
  341. package/scripts/savings-dashboard.ts +1258 -0
  342. package/scripts/savings-report-extras.ts +447 -0
  343. package/scripts/savings-status-line.ts +873 -0
  344. package/scripts/session-event-emit.ts +266 -0
  345. package/scripts/session-greet.ts +686 -0
  346. package/scripts/session-log-report.ts +551 -0
  347. package/scripts/session-resume.ts +614 -0
  348. package/scripts/set-hook-mode.ts +83 -0
  349. package/scripts/smoke-cross-platform.ts +117 -0
  350. package/scripts/smoke-realtime.ts +257 -0
  351. package/scripts/smoke-tools.ts +21 -0
  352. package/scripts/stats-cloud-pull.ts +213 -0
  353. package/scripts/stats-cloud-sync.ts +261 -0
  354. package/scripts/telemetry-flush.ts +160 -0
  355. package/scripts/telemetry-status.ts +266 -0
  356. package/scripts/timing-budget.ts +35 -0
  357. package/scripts/ui-animation.ts +120 -0
  358. package/scripts/ui.ts +431 -0
  359. package/scripts/upgrade-flow.ts +775 -0
  360. package/scripts/weekly-digest.ts +394 -0
  361. package/servers/_accounting.ts +78 -0
  362. package/servers/_ask-router.ts +84 -0
  363. package/servers/_ast-chunker.ts +434 -0
  364. package/servers/_ast-helpers.ts +183 -0
  365. package/servers/_ast-languages.ts +153 -0
  366. package/servers/_ast-refactor/_shared.ts +221 -0
  367. package/servers/_ast-refactor/cross-file-rename.ts +560 -0
  368. package/servers/_ast-refactor/extract-function.ts +357 -0
  369. package/servers/_ast-refactor/file-local-rename.ts +172 -0
  370. package/servers/_ast-refactor.ts +41 -0
  371. package/servers/_ast-skeleton.ts +107 -0
  372. package/servers/_bash-summarizers-registry.ts +1096 -0
  373. package/servers/_crash-dump.ts +210 -0
  374. package/servers/_cwd-clamp.ts +342 -0
  375. package/servers/_edit-log.ts +28 -0
  376. package/servers/_edit-match.ts +236 -0
  377. package/servers/_edit-validate.ts +196 -0
  378. package/servers/_embed-calibration.ts +123 -0
  379. package/servers/_embedding-cache.ts +401 -0
  380. package/servers/_embedding-model.ts +329 -0
  381. package/servers/_events.ts +113 -0
  382. package/servers/_genome-cache.ts +154 -0
  383. package/servers/_genome-commits.ts +172 -0
  384. package/servers/_genome-crypto-v2.ts +242 -0
  385. package/servers/_genome-crypto.ts +259 -0
  386. package/servers/_genome-discoveries.ts +140 -0
  387. package/servers/_genome-embed-populator.ts +216 -0
  388. package/servers/_genome-freshness.ts +134 -0
  389. package/servers/_genome-issues.ts +171 -0
  390. package/servers/_genome-live.ts +263 -0
  391. package/servers/_genome-prs.ts +188 -0
  392. package/servers/_genome-search.ts +479 -0
  393. package/servers/_genome-sync.ts +297 -0
  394. package/servers/_history-tracker.ts +279 -0
  395. package/servers/_http-helpers.ts +151 -0
  396. package/servers/_identity-hash.ts +151 -0
  397. package/servers/_llm-providers/anthropic.ts +132 -0
  398. package/servers/_llm-providers/cloud.ts +195 -0
  399. package/servers/_llm-providers/index.ts +350 -0
  400. package/servers/_llm-providers/local.ts +127 -0
  401. package/servers/_llm-providers/onnx.ts +393 -0
  402. package/servers/_llm-providers/types.ts +27 -0
  403. package/servers/_manifest-v2.ts +447 -0
  404. package/servers/_mcp-host.ts +93 -0
  405. package/servers/_nudge-events.ts +451 -0
  406. package/servers/_orchestrate-executor.ts +316 -0
  407. package/servers/_prefetch.ts +435 -0
  408. package/servers/_pricing.ts +256 -0
  409. package/servers/_pro.ts +381 -0
  410. package/servers/_read-cache.ts +44 -0
  411. package/servers/_router-handlers.ts +46 -0
  412. package/servers/_router.ts +55 -0
  413. package/servers/_run-with-timeout.ts +173 -0
  414. package/servers/_savings-render.ts +214 -0
  415. package/servers/_stats-sqlite.ts +640 -0
  416. package/servers/_stats.ts +1183 -0
  417. package/servers/_status-line-cells.ts +469 -0
  418. package/servers/_streaks.ts +162 -0
  419. package/servers/_summarize.ts +208 -0
  420. package/servers/_task-graph-render.ts +217 -0
  421. package/servers/_task-graph.ts +545 -0
  422. package/servers/_telemetry.ts +719 -0
  423. package/servers/_test-parsers.ts +530 -0
  424. package/servers/_test-watch.ts +626 -0
  425. package/servers/_text-helpers.ts +37 -0
  426. package/servers/_token-measure.ts +160 -0
  427. package/servers/_tool-base.ts +248 -0
  428. package/servers/_weekly-digest.ts +391 -0
  429. package/servers/ask-server-handlers.ts +49 -0
  430. package/servers/ask-server.ts +174 -0
  431. package/servers/bash-server-handlers.ts +138 -0
  432. package/servers/bash-server.ts +1136 -0
  433. package/servers/bench.ts +186 -0
  434. package/servers/diff-semantic-server-handlers.ts +39 -0
  435. package/servers/diff-semantic-server.ts +566 -0
  436. package/servers/diff-server-handlers.ts +317 -0
  437. package/servers/diff-server.ts +20 -0
  438. package/servers/edit-server-handlers.ts +31 -0
  439. package/servers/edit-server.ts +209 -0
  440. package/servers/edit-structural-server-handlers.ts +322 -0
  441. package/servers/efficiency-server-handlers.ts +161 -0
  442. package/servers/efficiency-server.ts +1135 -0
  443. package/servers/flush-server-handlers.ts +21 -0
  444. package/servers/flush-server.ts +19 -0
  445. package/servers/genome-server-handlers.ts +118 -0
  446. package/servers/genome-server.ts +397 -0
  447. package/servers/github-server-handlers.ts +187 -0
  448. package/servers/github-server.ts +856 -0
  449. package/servers/glob-server-handlers.ts +233 -0
  450. package/servers/glob-server.ts +20 -0
  451. package/servers/grep-server-handlers.ts +61 -0
  452. package/servers/grep-server.ts +564 -0
  453. package/servers/http-server-handlers.ts +36 -0
  454. package/servers/http-server.ts +149 -0
  455. package/servers/logs-server-handlers.ts +42 -0
  456. package/servers/logs-server.ts +359 -0
  457. package/servers/ls-server-handlers.ts +166 -0
  458. package/servers/ls-server.ts +20 -0
  459. package/servers/multi-edit-server-handlers.ts +51 -0
  460. package/servers/multi-edit-server.ts +422 -0
  461. package/servers/notebook-edit-server-handlers.ts +34 -0
  462. package/servers/notebook-edit-server.ts +181 -0
  463. package/servers/orient-server-handlers.ts +52 -0
  464. package/servers/orient-server.ts +436 -0
  465. package/servers/pipe-server-handlers.ts +68 -0
  466. package/servers/pipe-server.ts +300 -0
  467. package/servers/read-server-handlers.ts +42 -0
  468. package/servers/read-server.ts +206 -0
  469. package/servers/rename-file-server-handlers.ts +67 -0
  470. package/servers/rename-file-server.ts +699 -0
  471. package/servers/savings-server-handlers.ts +27 -0
  472. package/servers/savings-server.ts +54 -0
  473. package/servers/search-replace-regex-server-handlers.ts +96 -0
  474. package/servers/search-replace-regex-server.ts +751 -0
  475. package/servers/sql-server-handlers.ts +58 -0
  476. package/servers/sql-server.ts +505 -0
  477. package/servers/task-server-handlers.ts +358 -0
  478. package/servers/task-server.ts +24 -0
  479. package/servers/test-server-handlers.ts +351 -0
  480. package/servers/test-server.ts +20 -0
  481. package/servers/tree-server-handlers.ts +503 -0
  482. package/servers/tree-server.ts +20 -0
  483. package/servers/webfetch-server-handlers.ts +166 -0
  484. package/servers/webfetch-server.ts +20 -0
  485. package/servers/websearch-server-handlers.ts +215 -0
  486. package/servers/websearch-server.ts +19 -0
  487. package/servers/write-server-handlers.ts +27 -0
  488. package/servers/write-server.ts +97 -0
  489. package/skills/ashlr-brief/SKILL.md +80 -0
  490. package/skills/ashlr-codex-doctor/SKILL.md +21 -0
  491. package/skills/ashlr-codex-efficient-tools/SKILL.md +17 -0
  492. package/skills/ashlr-codex-genome-refresh/SKILL.md +20 -0
  493. package/skills/ashlr-codex-parallel-explore/SKILL.md +20 -0
  494. package/skills/ashlr-codex-savings/SKILL.md +17 -0
  495. package/skills/ashlr-cost-refactor/SKILL.md +50 -0
  496. package/skills/ashlr-efficient/SKILL.md +64 -0
  497. package/skills/ashlr-genome-author/SKILL.md +43 -0
  498. package/skills/ashlr-lean-tools/SKILL.md +43 -0
  499. package/skills/ashlr-search/SKILL.md +46 -0
@@ -0,0 +1,21 @@
1
+ /**
2
+ * flush-server-handlers — registers ashlr__flush into the shared tool registry.
3
+ */
4
+
5
+ import { registerTool, type ToolCallContext, type ToolResult } from "./_tool-base";
6
+ import { flushPending } from "./flush-server";
7
+
8
+ registerTool({
9
+ name: "ashlr__flush",
10
+ description:
11
+ "Flush all queued ashlr__edit writes to disk immediately and return a " +
12
+ "summary of what was committed. Use when you need to read a file you just " +
13
+ "edited, or at the end of a multi-edit sequence.",
14
+ inputSchema: { type: "object", properties: {} },
15
+ handler: async (_args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
16
+ const summary = await flushPending();
17
+ return {
18
+ content: [{ type: "text", text: summary || "[ashlr__flush] nothing to flush" }],
19
+ };
20
+ },
21
+ });
@@ -0,0 +1,19 @@
1
+ /**
2
+ * flush-server — ashlr__flush tool implementation.
3
+ *
4
+ * Pure reporting tool: drains the edit log and returns a compact summary of
5
+ * edits applied since the last flush (or session start).
6
+ */
7
+
8
+ import { drainEdits } from "./_edit-log";
9
+
10
+ /** Summarize edits applied since the last flush (or session start). */
11
+ export async function flushPending(): Promise<string> {
12
+ const batch = drainEdits();
13
+ if (batch.length === 0) return "";
14
+ const lines = [`[ashlr__flush] ${batch.length} edit(s) applied this batch:`];
15
+ for (const e of batch) {
16
+ lines.push(` ok ${e.relPath} (${e.hunksApplied} hunk${e.hunksApplied === 1 ? "" : "s"})`);
17
+ }
18
+ return lines.join("\n");
19
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * genome-server-handlers — registers ashlr__genome_propose / _consolidate /
3
+ * _status on the shared registry.
4
+ */
5
+
6
+ import { registerTool, toErrorResult, type ToolCallContext, type ToolResult } from "./_tool-base";
7
+ import {
8
+ handlePropose,
9
+ handleConsolidate,
10
+ handleStatus,
11
+ type ProposeArgs,
12
+ type ConsolidateArgs,
13
+ type StatusArgs,
14
+ } from "./genome-server";
15
+
16
+ const ERR_PREFIX = "ashlr-genome error";
17
+
18
+ registerTool({
19
+ name: "ashlr__genome_propose",
20
+ description:
21
+ "Queue a proposed update to a named genome section. Fire-and-forget: the " +
22
+ "proposal is appended to the pending queue and will be merged into the genome " +
23
+ "on the next ashlr__genome_consolidate call. Use this to record project " +
24
+ "decisions, new strategies, architectural discoveries, or lessons learned so " +
25
+ "they persist across sessions.",
26
+ inputSchema: {
27
+ type: "object",
28
+ properties: {
29
+ section: {
30
+ type: "string",
31
+ description:
32
+ "Section path relative to .ashlrcode/genome, e.g. 'knowledge/decisions.md' or 'strategies/active.md'",
33
+ },
34
+ content: {
35
+ type: "string",
36
+ description:
37
+ "Proposed content (full section replace OR appended block; see 'operation')",
38
+ },
39
+ operation: {
40
+ type: "string",
41
+ enum: ["append", "update", "create"],
42
+ description: "How to apply the content (default: append)",
43
+ },
44
+ rationale: {
45
+ type: "string",
46
+ description: "Why this change — 1-3 sentences",
47
+ },
48
+ cwd: {
49
+ type: "string",
50
+ description: "Override working directory (default: process.cwd())",
51
+ },
52
+ },
53
+ required: ["section", "content", "rationale"],
54
+ },
55
+ handler: async (args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
56
+ try {
57
+ const text = await handlePropose(args as unknown as ProposeArgs);
58
+ return { content: [{ type: "text", text }] };
59
+ } catch (err) {
60
+ return toErrorResult(ERR_PREFIX, err);
61
+ }
62
+ },
63
+ });
64
+
65
+ registerTool({
66
+ name: "ashlr__genome_consolidate",
67
+ description:
68
+ "Merge pending proposals into the genome. Without `model` (and without " +
69
+ "$ASHLR_LLM_URL) runs a deterministic sequential-apply; with an " +
70
+ "OpenAI-compatible endpoint it uses the LLM to merge conflicting proposals " +
71
+ "for the same section.",
72
+ inputSchema: {
73
+ type: "object",
74
+ properties: {
75
+ model: {
76
+ type: "string",
77
+ description:
78
+ "Optional OpenAI-compatible base URL (e.g. http://localhost:1234/v1). Pass 'none' to force offline sequential-apply. If omitted, falls back to $ASHLR_LLM_URL or sequential-apply.",
79
+ },
80
+ cwd: {
81
+ type: "string",
82
+ description: "Override working directory",
83
+ },
84
+ },
85
+ },
86
+ handler: async (args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
87
+ try {
88
+ const text = await handleConsolidate(args as unknown as ConsolidateArgs);
89
+ return { content: [{ type: "text", text }] };
90
+ } catch (err) {
91
+ return toErrorResult(ERR_PREFIX, err);
92
+ }
93
+ },
94
+ });
95
+
96
+ registerTool({
97
+ name: "ashlr__genome_status",
98
+ description:
99
+ "Show pending proposals and recent mutations for the current genome. Compact " +
100
+ "report suitable for inline context.",
101
+ inputSchema: {
102
+ type: "object",
103
+ properties: {
104
+ cwd: {
105
+ type: "string",
106
+ description: "Override working directory",
107
+ },
108
+ },
109
+ },
110
+ handler: async (args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
111
+ try {
112
+ const text = await handleStatus(args as unknown as StatusArgs);
113
+ return { content: [{ type: "text", text }] };
114
+ } catch (err) {
115
+ return toErrorResult(ERR_PREFIX, err);
116
+ }
117
+ },
118
+ });
@@ -0,0 +1,397 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * ashlr-genome MCP server.
4
+ *
5
+ * The active genome scribe loop — exposes three tools that let an agent
6
+ * propose, consolidate, and inspect evolutionary updates to the project
7
+ * genome stored under `.ashlrcode/genome/`.
8
+ *
9
+ * ashlr__genome_propose — queue a proposed update to a section
10
+ * ashlr__genome_consolidate — merge pending proposals into the genome
11
+ * (optionally via an OpenAI-compatible LLM)
12
+ * ashlr__genome_status — compact report of pending + recent mutations
13
+ *
14
+ * All heavy lifting (pending queue, mutation log, merge semantics) lives in
15
+ * @ashlr/core-efficiency's `scribe.ts`. This server is a thin MCP adapter.
16
+ */
17
+
18
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
19
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
20
+ import {
21
+ CallToolRequestSchema,
22
+ ListToolsRequestSchema,
23
+ } from "@modelcontextprotocol/sdk/types.js";
24
+ import {
25
+ consolidateProposals,
26
+ genomeExists,
27
+ loadManifest,
28
+ loadMutations,
29
+ loadPendingProposals,
30
+ proposeUpdate,
31
+ } from "@ashlr/core-efficiency/genome";
32
+ import type {
33
+ GenomeProposal,
34
+ MutationRecord,
35
+ } from "@ashlr/core-efficiency/genome";
36
+ import type {
37
+ LLMSummarizer,
38
+ ProviderRequest,
39
+ StreamEvent,
40
+ } from "@ashlr/core-efficiency";
41
+
42
+ // ---------------------------------------------------------------------------
43
+ // LLM shim — OpenAI-compatible chat.completions streaming
44
+ // ---------------------------------------------------------------------------
45
+
46
+ /**
47
+ * Build a minimal LLMSummarizer that hits an OpenAI-compatible endpoint.
48
+ *
49
+ * Precedence:
50
+ * 1. explicit `modelUrl` arg (per-call override)
51
+ * 2. $ASHLR_LLM_URL / $ASHLR_LLM_KEY
52
+ * 3. local LM Studio at http://localhost:1234/v1 (no key required)
53
+ *
54
+ * Returns null if no endpoint is configured AND no override given — the
55
+ * scribe falls back to sequential-apply merging in that case.
56
+ */
57
+ export function buildLLMShim(modelUrl?: string): LLMSummarizer | undefined {
58
+ const base =
59
+ modelUrl ??
60
+ process.env.ASHLR_LLM_URL ??
61
+ "http://localhost:1234/v1";
62
+ const key = process.env.ASHLR_LLM_KEY ?? "";
63
+ const model = process.env.ASHLR_LLM_MODEL ?? "local";
64
+
65
+ const endpoint = base.replace(/\/+$/, "") + "/chat/completions";
66
+
67
+ return {
68
+ async *stream(req: ProviderRequest): AsyncGenerator<StreamEvent> {
69
+ // Collapse the core-efficiency message shape into OpenAI format.
70
+ const messages = [
71
+ { role: "system", content: req.systemPrompt },
72
+ ...req.messages.map((m) => ({
73
+ role: m.role === "tool" ? "user" : m.role,
74
+ content:
75
+ typeof m.content === "string"
76
+ ? m.content
77
+ : m.content
78
+ .map((b) =>
79
+ b.type === "text"
80
+ ? b.text
81
+ : b.type === "thinking"
82
+ ? ""
83
+ : "",
84
+ )
85
+ .join(""),
86
+ })),
87
+ ];
88
+
89
+ let res: Response;
90
+ try {
91
+ res = await fetch(endpoint, {
92
+ method: "POST",
93
+ headers: {
94
+ "Content-Type": "application/json",
95
+ ...(key ? { Authorization: `Bearer ${key}` } : {}),
96
+ },
97
+ body: JSON.stringify({
98
+ model,
99
+ messages,
100
+ stream: true,
101
+ max_tokens: req.maxTokens ?? 2048,
102
+ }),
103
+ });
104
+ } catch (err) {
105
+ // Network error — yield nothing so scribe falls through to sequential.
106
+ yield { type: "message_end", stopReason: "end_turn" };
107
+ return;
108
+ }
109
+
110
+ if (!res.ok || !res.body) {
111
+ yield { type: "message_end", stopReason: "end_turn" };
112
+ return;
113
+ }
114
+
115
+ const reader = res.body.getReader();
116
+ const decoder = new TextDecoder();
117
+ // Cap per-frame payload at 1 MB — OpenAI chat.completion deltas are
118
+ // kilobytes at most, so anything larger is a misbehaving upstream.
119
+ // Reject rather than parse so we bound memory on hostile input.
120
+ const MAX_SSE_FRAME_BYTES = 1024 * 1024;
121
+ let buf = "";
122
+ while (true) {
123
+ const { done, value } = await reader.read();
124
+ if (done) break;
125
+ buf += decoder.decode(value, { stream: true });
126
+ // OpenAI SSE: "data: {...}\n\n"
127
+ let idx: number;
128
+ while ((idx = buf.indexOf("\n")) >= 0) {
129
+ const line = buf.slice(0, idx).trim();
130
+ buf = buf.slice(idx + 1);
131
+ if (!line.startsWith("data:")) continue;
132
+ const payload = line.slice(5).trim();
133
+ if (payload === "[DONE]") continue;
134
+ if (payload.length > MAX_SSE_FRAME_BYTES) {
135
+ // Drop the frame, don't throw — stream may still recover.
136
+ continue;
137
+ }
138
+ try {
139
+ const j = JSON.parse(payload);
140
+ const delta = j?.choices?.[0]?.delta?.content;
141
+ if (typeof delta === "string" && delta.length > 0) {
142
+ yield { type: "text_delta", text: delta };
143
+ }
144
+ } catch {
145
+ /* skip malformed frame */
146
+ }
147
+ }
148
+ }
149
+ yield { type: "message_end", stopReason: "end_turn" };
150
+ },
151
+ };
152
+ }
153
+
154
+ // ---------------------------------------------------------------------------
155
+ // Tool arg types
156
+ // ---------------------------------------------------------------------------
157
+
158
+ export interface ProposeArgs {
159
+ section: string;
160
+ content: string;
161
+ operation?: "append" | "update" | "create";
162
+ rationale: string;
163
+ cwd?: string;
164
+ }
165
+
166
+ export interface ConsolidateArgs {
167
+ model?: string;
168
+ cwd?: string;
169
+ }
170
+
171
+ export interface StatusArgs {
172
+ cwd?: string;
173
+ }
174
+
175
+ // ---------------------------------------------------------------------------
176
+ // Tool implementations
177
+ // ---------------------------------------------------------------------------
178
+
179
+ async function resolveCwd(explicit?: string): Promise<string> {
180
+ return explicit ?? process.cwd();
181
+ }
182
+
183
+ async function currentGeneration(cwd: string): Promise<number> {
184
+ const m = await loadManifest(cwd);
185
+ return m?.generation?.number ?? 1;
186
+ }
187
+
188
+ export async function handlePropose(args: ProposeArgs): Promise<string> {
189
+ const cwd = await resolveCwd(args.cwd);
190
+ if (!genomeExists(cwd)) {
191
+ return "ashlr__genome_propose error: no genome found at .ashlrcode/genome — run /ashlr-genome-init first.";
192
+ }
193
+ if (typeof args.section !== "string" || args.section.length === 0) {
194
+ return "ashlr__genome_propose error: 'section' is required";
195
+ }
196
+ if (typeof args.content !== "string" || args.content.length === 0) {
197
+ return "ashlr__genome_propose error: 'content' is required";
198
+ }
199
+ if (typeof args.rationale !== "string" || args.rationale.length === 0) {
200
+ return "ashlr__genome_propose error: 'rationale' is required";
201
+ }
202
+ const operation = args.operation ?? "append";
203
+ if (!["append", "update", "create"].includes(operation)) {
204
+ return `ashlr__genome_propose error: invalid operation '${operation}' (expected append|update|create)`;
205
+ }
206
+ const generation = await currentGeneration(cwd);
207
+ const id = await proposeUpdate(cwd, {
208
+ section: args.section,
209
+ content: args.content,
210
+ operation,
211
+ rationale: args.rationale,
212
+ agentId: "ashlr:code",
213
+ generation,
214
+ });
215
+ return `proposal ${id} queued · section ${args.section} · op ${operation} · gen ${generation}`;
216
+ }
217
+
218
+ export async function handleConsolidate(args: ConsolidateArgs): Promise<string> {
219
+ const cwd = await resolveCwd(args.cwd);
220
+ if (!genomeExists(cwd)) {
221
+ return "ashlr__genome_consolidate error: no genome found at .ashlrcode/genome";
222
+ }
223
+ const pending = await loadPendingProposals(cwd);
224
+ if (pending.length === 0) {
225
+ return "ashlr__genome_consolidate · no pending proposals";
226
+ }
227
+ // Only construct the LLM shim if caller explicitly requested one OR env is
228
+ // configured. When args.model is the literal string "none", skip the shim
229
+ // and fall through to sequential-apply.
230
+ let router: LLMSummarizer | undefined;
231
+ if (args.model === "none") {
232
+ router = undefined;
233
+ } else if (args.model || process.env.ASHLR_LLM_URL || process.env.ASHLR_LLM_KEY) {
234
+ router = buildLLMShim(args.model);
235
+ } else {
236
+ // No configured endpoint — sequential-apply keeps this deterministic and
237
+ // offline. Users opt into LLM merging by passing `model` or setting env.
238
+ router = undefined;
239
+ }
240
+ const result = await consolidateProposals(cwd, router);
241
+ return `consolidated · applied ${result.applied} · skipped ${result.skipped} · from ${pending.length} pending`;
242
+ }
243
+
244
+ export function renderStatus(
245
+ pending: GenomeProposal[],
246
+ mutations: MutationRecord[],
247
+ currentGen: number,
248
+ ): string {
249
+ const genMutations = mutations.filter((m) => m.generation === currentGen);
250
+ const lines: string[] = [];
251
+ lines.push(
252
+ `genome · ${pending.length} pending proposal${pending.length === 1 ? "" : "s"} · ${genMutations.length} mutation${genMutations.length === 1 ? "" : "s"} this gen`,
253
+ );
254
+ if (pending.length > 0) {
255
+ lines.push(" pending:");
256
+ for (const p of pending) {
257
+ const snippet = (p.rationale ?? "").replace(/\s+/g, " ").slice(0, 80);
258
+ lines.push(` ${p.id}: ${p.section} · ${p.operation} · "${snippet}"`);
259
+ }
260
+ }
261
+ if (mutations.length > 0) {
262
+ lines.push(" recent mutations:");
263
+ const recent = mutations.slice(-5);
264
+ for (const m of recent) {
265
+ const when = m.timestamp.slice(0, 16).replace("T", " ");
266
+ lines.push(` - ${when} · ${m.section} · by ${m.agentId}`);
267
+ }
268
+ }
269
+ return lines.join("\n");
270
+ }
271
+
272
+ export async function handleStatus(args: StatusArgs): Promise<string> {
273
+ const cwd = await resolveCwd(args.cwd);
274
+ if (!genomeExists(cwd)) {
275
+ return "ashlr__genome_status · no genome found at .ashlrcode/genome";
276
+ }
277
+ const [pending, mutations, gen] = await Promise.all([
278
+ loadPendingProposals(cwd),
279
+ loadMutations(cwd),
280
+ currentGeneration(cwd),
281
+ ]);
282
+ return renderStatus(pending, mutations, gen);
283
+ }
284
+
285
+ // ---------------------------------------------------------------------------
286
+ // MCP server wiring
287
+ // ---------------------------------------------------------------------------
288
+
289
+ const server = new Server(
290
+ { name: "ashlr-genome", version: "0.1.0" },
291
+ { capabilities: { tools: {} } },
292
+ );
293
+
294
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
295
+ tools: [
296
+ {
297
+ name: "ashlr__genome_propose",
298
+ description:
299
+ "Queue a proposed update to a named genome section. Fire-and-forget: the proposal is appended to the pending queue and will be merged into the genome on the next ashlr__genome_consolidate call. Use this to record project decisions, new strategies, architectural discoveries, or lessons learned so they persist across sessions.",
300
+ inputSchema: {
301
+ type: "object",
302
+ properties: {
303
+ section: {
304
+ type: "string",
305
+ description:
306
+ "Section path relative to .ashlrcode/genome, e.g. 'knowledge/decisions.md' or 'strategies/active.md'",
307
+ },
308
+ content: {
309
+ type: "string",
310
+ description:
311
+ "Proposed content (full section replace OR appended block; see 'operation')",
312
+ },
313
+ operation: {
314
+ type: "string",
315
+ enum: ["append", "update", "create"],
316
+ description: "How to apply the content (default: append)",
317
+ },
318
+ rationale: {
319
+ type: "string",
320
+ description: "Why this change — 1-3 sentences",
321
+ },
322
+ cwd: {
323
+ type: "string",
324
+ description: "Override working directory (default: process.cwd())",
325
+ },
326
+ },
327
+ required: ["section", "content", "rationale"],
328
+ },
329
+ },
330
+ {
331
+ name: "ashlr__genome_consolidate",
332
+ description:
333
+ "Merge pending proposals into the genome. Without `model` (and without $ASHLR_LLM_URL) runs a deterministic sequential-apply; with an OpenAI-compatible endpoint it uses the LLM to merge conflicting proposals for the same section.",
334
+ inputSchema: {
335
+ type: "object",
336
+ properties: {
337
+ model: {
338
+ type: "string",
339
+ description:
340
+ "Optional OpenAI-compatible base URL (e.g. http://localhost:1234/v1). Pass 'none' to force offline sequential-apply. If omitted, falls back to $ASHLR_LLM_URL or sequential-apply.",
341
+ },
342
+ cwd: {
343
+ type: "string",
344
+ description: "Override working directory",
345
+ },
346
+ },
347
+ },
348
+ },
349
+ {
350
+ name: "ashlr__genome_status",
351
+ description:
352
+ "Show pending proposals and recent mutations for the current genome. Compact report suitable for inline context.",
353
+ inputSchema: {
354
+ type: "object",
355
+ properties: {
356
+ cwd: {
357
+ type: "string",
358
+ description: "Override working directory",
359
+ },
360
+ },
361
+ },
362
+ },
363
+ ],
364
+ }));
365
+
366
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
367
+ const { name, arguments: args } = req.params;
368
+ try {
369
+ if (name === "ashlr__genome_propose") {
370
+ const text = await handlePropose(args as unknown as ProposeArgs);
371
+ return { content: [{ type: "text", text }] };
372
+ }
373
+ if (name === "ashlr__genome_consolidate") {
374
+ const text = await handleConsolidate(args as unknown as ConsolidateArgs);
375
+ return { content: [{ type: "text", text }] };
376
+ }
377
+ if (name === "ashlr__genome_status") {
378
+ const text = await handleStatus(args as unknown as StatusArgs);
379
+ return { content: [{ type: "text", text }] };
380
+ }
381
+ return {
382
+ content: [{ type: "text", text: `Unknown tool: ${name}` }],
383
+ isError: true,
384
+ };
385
+ } catch (err) {
386
+ const message = err instanceof Error ? err.message : String(err);
387
+ return {
388
+ content: [{ type: "text", text: `ashlr-genome error: ${message}` }],
389
+ isError: true,
390
+ };
391
+ }
392
+ });
393
+
394
+ if (import.meta.main) {
395
+ const transport = new StdioServerTransport();
396
+ await server.connect(transport);
397
+ }