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,58 @@
1
+ ---
2
+ name: goal
3
+ description: Create a goal, decompose it into milestones, and advance the next one as a sandboxed proposal-only run.
4
+ argument-hint: '"<objective>" [--project <repo>] [--allow-cloud] [--plan-only] [--direct]'
5
+ ---
6
+
7
+ Registers an objective with the ashlr fleet, plans it into milestones, and runs
8
+ the next one sandboxed — filing a **PENDING** inbox proposal. Nothing is applied
9
+ until you review and accept via `ashlr inbox`.
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ /goal "<objective>" [--project <repo>] [--allow-cloud] [--plan-only] [--direct]
15
+ ```
16
+
17
+ Flags:
18
+
19
+ - `--project <repo>` — target repo path (required with `--direct`; optional otherwise)
20
+ - `--allow-cloud` — permit cloud-tier backends for the sandboxed run
21
+ - `--plan-only` — stop after milestone planning; do not advance yet
22
+ - `--direct` — skip milestone decomposition; run the objective verbatim as a
23
+ single sandboxed frontier-engine run (same dispatch path as the daemon).
24
+ Requires `--project`.
25
+
26
+ ## Steps
27
+
28
+ ### If `$ARGUMENTS` is empty
29
+
30
+ Print the following and stop:
31
+
32
+ ```
33
+ Usage: ashlr goal "<objective>" [--project <repo>] [--allow-cloud] [--plan-only] [--direct]
34
+
35
+ Create a goal, plan it into milestones, and advance the next one as a
36
+ sandboxed, PROPOSAL-ONLY run (review it via `ashlr inbox`). Routed across
37
+ the polyglot backend roster by capability + trust tier.
38
+
39
+ --direct Skip milestone decomposition. Run the objective verbatim as a
40
+ SINGLE sandboxed proposal-only frontier-engine run (same path as
41
+ the daemon's non-builtin dispatch). Requires --project.
42
+ Ideal for concrete tasks that need no Design->Implement->Test split.
43
+ ```
44
+
45
+ ### Otherwise
46
+
47
+ Run the following Bash command and relay its output verbatim:
48
+
49
+ ```bash
50
+ ashlr goal $ARGUMENTS
51
+ ```
52
+
53
+ After the command completes, if a proposal ID appears in the output, relay it
54
+ and add exactly one reminder line:
55
+
56
+ > Review the proposal with `ashlr inbox` — nothing was applied to the working tree.
57
+
58
+ No preamble, no trailing summary beyond the above reminder.
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: loop
3
+ description: Run the goal-aware fleet conductor over every enrolled repo — one tick (default) or continuous.
4
+ argument-hint: "[--watch] [--dry-run]"
5
+ ---
6
+
7
+ Runs the ashlr fleet conductor over every enrolled repo: discovers work, routes
8
+ each item across the polyglot backend roster by trust tier, runs it sandboxed,
9
+ and files **PENDING** inbox proposals. Default is one tick (safe — will not hang
10
+ the terminal). Nothing is applied until you review via `ashlr inbox`.
11
+
12
+ The conductor is **goal-aware**: active goals are prioritised over the general
13
+ backlog. The kill-switch (`~/.ashlr/KILL`) and daily budget are respected;
14
+ auto-merge and intelligence posture are read from your config at runtime.
15
+
16
+ ## Usage
17
+
18
+ ```
19
+ /loop [--watch] [--dry-run]
20
+ ```
21
+
22
+ Flags:
23
+
24
+ - `--watch` — run the continuous loop (Ctrl-C to stop). Default: one tick.
25
+ - `--dry-run` — simulate work discovery and routing without spawning any engine runs.
26
+
27
+ ## Steps
28
+
29
+ Run the following Bash command and relay its output verbatim:
30
+
31
+ ```bash
32
+ ashlr loop $ARGUMENTS
33
+ ```
34
+
35
+ After the command completes, relay the final summary line from the output and
36
+ add exactly one reminder line:
37
+
38
+ > Any proposals filed await review in `ashlr inbox` — nothing was applied.
39
+
40
+ No preamble, no trailing summary beyond the above reminder.
package/docs/CNAME ADDED
@@ -0,0 +1 @@
1
+ plugin.ashlr.ai
@@ -0,0 +1,104 @@
1
+ # ashlr Pro — Your Team Learns Together
2
+
3
+ _Version: v1.31.0 · Updated: 2026-05-08_
4
+
5
+ ---
6
+
7
+ ## The core idea
8
+
9
+ Free ashlr builds a genome that lives on your machine. Every session starts
10
+ from context you've already derived — but it's yours alone. The moment a team
11
+ forms, everyone re-derives the same codebase patterns from scratch.
12
+
13
+ Pro solves this. The genome becomes a shared, encrypted, versioned layer every
14
+ teammate retrieves from. One engineer's grep hit — a tricky auth flow, an
15
+ undocumented API edge case — becomes context for everyone who touches that code
16
+ next. New engineers onboard into accumulated knowledge, not silence.
17
+
18
+ ---
19
+
20
+ ## Pro ($12/mo or $120/yr) — individual cloud
21
+
22
+ - **Cross-machine sync** — savings ledger, streak counter, and `/ashlr-dashboard`
23
+ follow you across machines automatically.
24
+ - **Cloud LLM summarizer** — `ashlr__read` and genome summarization run on
25
+ hosted Haiku. No local Ollama or GPU required.
26
+ - **Hosted embedding retrieval** — `ashlr__grep` uses a cloud pgvector index
27
+ refreshed on every push. Materially better recall on repos with > 5,000 files.
28
+ - **Weekly digest** — a personal summary of learnings, top tools, and streak
29
+ milestones via `/ashlr-resume`.
30
+ - **7-day free trial on first checkout** — no charge until the trial ends,
31
+ cancel any time.
32
+
33
+ Run `/ashlr-upgrade` from any Claude Code session to start.
34
+
35
+ ---
36
+
37
+ ## Pro Team ($24/user/mo, min 3 seats · or $20/user/mo annual)
38
+
39
+ Everything in Pro, plus:
40
+
41
+ - **Shared encrypted team genome** — E2E AES-256-GCM encrypted. Every
42
+ section synced via vclock conflict detection. Divergent edits surface in
43
+ `/ashlr-genome-conflicts` for human resolution. No plaintext leaves the
44
+ client.
45
+ - **Org-wide savings dashboard** — aggregate savings, tool adoption, and
46
+ streak rankings across all team members. Deduped per-repo.
47
+ - **Weekly team digest** — top genome sections hit, new discoveries, savings
48
+ milestones across the team. Delivered via `/ashlr-resume` and optional email.
49
+ - **Policy packs** — centrally managed allow/deny lists for `ashlr__bash`,
50
+ `ashlr__sql`, and destructive ops, pushed to every seat via the hook
51
+ infrastructure. (Shipping — contact sales for early access.)
52
+ - **SSO + SCIM** — WorkOS integration for orgs that require it.
53
+ - **Audit log** — every non-read MCP tool call with commit linkage. SOC 2
54
+ evidence export on request.
55
+
56
+ Run `/ashlr-upgrade --tier team` to start.
57
+
58
+ ---
59
+
60
+ ## What's never paywalled
61
+
62
+ Every MCP tool (all 45), every skill (all 31), the genome format, the local
63
+ scribe loop, per-session savings accounting, the benchmark harness, local
64
+ Ollama semantic search — all MIT, forever. Pro adds cloud infrastructure; it
65
+ does not remove or degrade anything in the free tier.
66
+
67
+ ---
68
+
69
+ ## Pricing summary
70
+
71
+ | Tier | Price | For |
72
+ |------|-------|-----|
73
+ | **Free** | $0, MIT forever | Every developer. Local-first. Full tool suite. Public-repo cloud genome. |
74
+ | **Pro** | $12/mo or $120/yr | One developer wanting cloud sync, hosted LLM, cross-machine dashboard. |
75
+ | **Pro Team** | $24/user/mo (min 3) or $20/user/mo annual | Engineering teams. Shared genome, org dashboard, policy packs, SSO. |
76
+ | **Enterprise** | Contact sales | On-prem, private inference, dedicated SLA, custom genome spec. |
77
+
78
+ **Downgrade path:** graceful. When a license lapses, the plugin routes to
79
+ free-tier fallbacks silently — no nag screens, no broken features. The genome
80
+ stays local. Cloud sync pauses.
81
+
82
+ ---
83
+
84
+ ## Technical architecture
85
+
86
+ **No fork.** One codebase. Pro features activate when `~/.ashlr/license.json`
87
+ validates against the Pro license server (signed JWT, 24h cache, works offline
88
+ for 30 days once cached).
89
+
90
+ **Retrieval fallback chain (Pro → free, never breaks):**
91
+ ```
92
+ hosted pgvector → local Ollama → TF-IDF
93
+ ```
94
+
95
+ **Genome sync** — `_genome-sync.ts` client, inactive without
96
+ `ASHLR_TEAM_GENOME_ID`. Uses the existing `proposeUpdate` /
97
+ `consolidateProposals` path; on consolidation it publishes a delta encrypted
98
+ with the team key to the Postgres-backed sync hub.
99
+
100
+ **Stats sync** — `ashlr-pro-telemetry` hook POSTs deltas of the per-session
101
+ ledger to a lightweight ingest endpoint. Opt-in, per-user toggleable, zero PII.
102
+
103
+ For architecture details see `docs/team-genome.md` and
104
+ `docs/github-oauth-onboarding.md`.
package/docs/README.md ADDED
@@ -0,0 +1,21 @@
1
+ > **Internal reference only.** Canonical public docs: [plugin.ashlr.ai/docs](https://plugin.ashlr.ai/docs) (source: `site/content/docs/`).
2
+
3
+ This directory contains internal architecture notes, runbooks, and operational docs for contributors and maintainers. It is not the public documentation site.
4
+
5
+ ## Files in this directory
6
+
7
+ | File | Purpose |
8
+ |---|---|
9
+ | `architecture.md` | Full system architecture reference for contributors |
10
+ | `benchmarks.md` | Benchmark methodology and raw data |
11
+ | `benchmarks.json` | Single-repo benchmark snapshot (ashlr-plugin source) |
12
+ | `benchmarks-v2.json` | Cross-language benchmark (TS + Python + Rust) |
13
+ | `telemetry.md` | Telemetry privacy contract — what is and isn't sent |
14
+ | `pricing.md` | Internal pricing model and tier definitions |
15
+ | `cloud-genome.md` | Cloud genome sync deep-dive |
16
+ | `multi-host-mcp.md` | Multi-host MCP setup (Cline, Claude Desktop, Codex CLI) |
17
+ | `operations.md` | Operations runbook |
18
+ | `deploy.md` | Deployment guide |
19
+ | `platform-support.md` | Windows / macOS / Linux platform matrix |
20
+
21
+ For public user-facing documentation, see `site/content/docs/` or visit [plugin.ashlr.ai/docs](https://plugin.ashlr.ai/docs).
@@ -0,0 +1,415 @@
1
+ # ashlr-plugin Architecture
2
+
3
+ Reference for contributors. Covers system shape, data flows, and conventions. All file references are relative to the plugin root unless otherwise noted.
4
+
5
+ > **Platform support:** ashlr-plugin runs on Windows, macOS, and Linux. All Claude Code hooks are TypeScript files invoked via `bun run`. There are no bash-only code paths in the hot loop. The legacy `.sh` files in `hooks/` remain for reference but `hooks/hooks.json` points exclusively at the `.ts` siblings. See [install-windows.md](install-windows.md) for Windows-specific notes.
6
+
7
+ ---
8
+
9
+ ## 1. Overview
10
+
11
+ ashlr-plugin is a multi-host plugin for Codex and Claude Code that wraps file, search, edit, and shell workflows with lower-token alternatives and adds a lightweight observability layer over tool usage and cost.
12
+
13
+ Two value propositions:
14
+
15
+ **Token efficiency.** `ashlr__read`, `ashlr__grep`, and `ashlr__edit` replace the built-in `Read`, `Grep`, and `Edit` tools. Large file reads are snip-compacted or LLM-summarized; grep calls route through a per-project genome index (RAG) when one exists, cutting tokens by ~84% on warm queries; edits send only diffs, not full file contents.
16
+
17
+ **Observability.** Every tool call is accounted in `~/.ashlr/stats.json` (per-session + lifetime counters) and appended to `~/.ashlr/session-log.jsonl`. Claude Code surfaces savings in the status line; Codex surfaces them through MCP tools, CLI commands, and skills. The genome scribe loop extracts architectural knowledge from tool results into `.ashlrcode/genome/`, which feeds back into future grep routing.
18
+
19
+ The Claude Code wiring entry point is `.claude-plugin/plugin.json`. The Codex wiring entry point is `.codex-plugin/plugin.json` with `.mcp.json` and `hooks/codex-hooks.json`.
20
+
21
+ ---
22
+
23
+ ## 2. MCP Server Map
24
+
25
+ Source of truth: `.claude-plugin/plugin.json:mcpServers`. As of v1.13, **a single `ashlr` router entry** replaces the previous 16 per-server entries. The router at `servers/_router.ts` dispatches all 40 tools via a shared `registerTool` / `getTool` registry. `plugin.json` has one `mcpServers` entry:
26
+
27
+ ```json
28
+ "ashlr": {
29
+ "command": "bun",
30
+ "args": ["${CLAUDE_PLUGIN_ROOT}/scripts/bootstrap.mjs", "servers/_router.ts"]
31
+ }
32
+ ```
33
+
34
+ The node bootstrap (`scripts/bootstrap.mjs`) ensures Bun is available before handing off to the bun-native entrypoint (`scripts/mcp-entrypoint.ts`). The entrypoint replaces the legacy bash wrapper so the plugin runs on Windows without Git Bash. It handles first-run `bun install`, stale-sibling version cache cleanup, and `CLAUDE_SESSION_ID` forwarding. The dedicated `ashlr-mcp` bin launches the same router path for Codex and other MCP hosts without invoking the stats CLI.
35
+
36
+ `ASHLR_ROUTER_DISABLE=1` is retained as a kill switch for one release cycle (reverts to legacy per-server mode).
37
+
38
+ ### Tool registry (all 40 tools)
39
+
40
+ | Tool | Origin server module | Replaces (native) |
41
+ |---|---|---|
42
+ | `ashlr__read` | `servers/efficiency-server.ts` | `Read` |
43
+ | `ashlr__grep` | `servers/efficiency-server.ts` | `Grep` |
44
+ | `ashlr__edit` | `servers/efficiency-server.ts` | `Edit` (baseline is `search+replace` bytes as of v1.18 Trust Pass) |
45
+ | `ashlr__edit_structural` | `servers/edit-structural-server.ts` | — (v2 as of v1.18: Unicode identifiers, cross-file rename with `anchorFile`/`maxFiles`/shadowing guard/dryRun, extract-function with return-value detection) |
46
+ | `ashlr__multi_edit` | `servers/multi-edit-server.ts` | — |
47
+ | `ashlr__savings` | `servers/efficiency-server.ts` | — |
48
+ | `ashlr__flush` | `servers/efficiency-server.ts` | — |
49
+ | `ashlr__bash` | `servers/bash-server.ts` | `Bash` (v1.18: process-group SIGKILL on timeout, pluggable summarizer registry) |
50
+ | `ashlr__bash_start` / `_stop` / `_tail` / `_list` | `servers/bash-server.ts` | — (long-running control plane) |
51
+ | `ashlr__diff` | `servers/diff-server.ts` | — |
52
+ | `ashlr__diff_semantic` | `servers/diff-semantic-server.ts` | — |
53
+ | `ashlr__sql` | `servers/sql-server.ts` | — |
54
+ | `ashlr__tree` | `servers/tree-server.ts` | — |
55
+ | `ashlr__http` | `servers/http-server.ts` | `WebFetch` |
56
+ | `ashlr__logs` | `servers/logs-server.ts` | — |
57
+ | `ashlr__genome_propose` / `_consolidate` / `_status` | `servers/genome-server.ts` | — |
58
+ | `ashlr__orient` | `servers/orient-server.ts` | — |
59
+ | `ashlr__issue` / `ashlr__pr` | `servers/github-server.ts` | — (wraps `gh` CLI) |
60
+ | `ashlr__pr_comment` / `ashlr__pr_approve` | `servers/github-server.ts` | — (v1.18 PR write ops; `pr:"current"` via `gh pr view`, self-approval guard, `ASHLR_REQUIRE_GH_CONFIRM=1`) |
61
+ | `ashlr__issue_create` / `ashlr__issue_close` | `servers/github-server.ts` | — (v1.18 issue write ops; no destructive ops) |
62
+ | `ashlr__glob` | `servers/glob-server.ts` | `Glob` |
63
+ | `ashlr__ls` | `servers/ls-server.ts` | — |
64
+ | `ashlr__webfetch` | `servers/webfetch-server.ts` | `WebFetch` (summarizes at 4 KB as of v1.18) |
65
+ | `ashlr__ask` | `servers/ask-server.ts` | — |
66
+ | `ashlr__test` | `servers/test-server.ts` | — (bun/vitest/jest/pytest/go test parser; v1.18: async spawn + `bun.lock` text detection) |
67
+
68
+ The router pattern: each server module calls `registerTool(name, handler)` at import time. The router's `CallToolRequestSchema` handler calls `getTool(name)(params)` — no per-server process spawning, one stdin/stdout pair.
69
+
70
+ ### Shared infrastructure modules
71
+
72
+ - **`servers/_pricing.ts`** (v1.18) — single source of truth for $/MTok across the plugin. Consumed by `efficiency-server.ts`, `scripts/savings-dashboard.ts`, `scripts/savings-status-line.ts`, and `session-greet.ts`. Prior to v1.18 each surface hardcoded its own rate, producing three different dollar values for the same token count. `ASHLR_PRICING_MODEL` env var selects the model (default `sonnet-4.5` at $3/MTok input; `opus-4`, `haiku-4.5` also supported).
73
+ - **`servers/_bash-summarizers-registry.ts`** (v1.18) — pluggable registry of structured summarizers for `ashlr__bash` output. Keyed by command prefix, each entry returns a compact summary for matched output (`git log`, `git diff`, `git show`, unified test-runner output across jest/vitest/pytest/bun/mocha/npm/yarn/pnpm, `tsc`, package installs across the four major JS package managers). `bash-server.ts::tryStructuredSummary` falls back to `findSummarizer(command)` after the hardcoded branches, so new summarizers register without per-command edits.
74
+ - **`rawTotal` in stats** (v1.18) — new column in both `_stats.ts` (JSON) and `_stats-sqlite.ts` backends. Lets the dashboard display `saved / rawTotal` as a percentage. Backward-compat: missing values treat as 0. See section 3.
75
+
76
+ ---
77
+
78
+ ## 2a. GitHub OAuth + Cloud Genome Pipeline
79
+
80
+ As of v1.13, sign-in with GitHub triggers an auto-genome build for any public repo the user picks. The pipeline links the CLI, backend, and `ashlr__grep` retrieval path.
81
+
82
+ ```
83
+ User runs /ashlr-upgrade
84
+ │
85
+ ▼
86
+ scripts/upgrade-flow.ts ──► "Sign in with GitHub" picker
87
+ │ (magic-link preserved as fallback)
88
+ ▼
89
+ browser: plugin.ashlr.ai/auth/github
90
+ │ GitHub consent: read:user user:email public_repo
91
+ ▼
92
+ server: /auth/github/callback
93
+ │ AES-256-GCM encrypt token → users.github_access_token_encrypted
94
+ │ write pending_auth_tokens by session_id
95
+ ▼
96
+ CLI polls /auth/status?session=<sid> ──► receives token
97
+ │
98
+ ▼
99
+ browser: /repo-picker
100
+ │ POST /genome/build → fire-and-forget buildGenomeFromGitHub()
101
+ │ git clone --depth 1 + genome-init --minimal
102
+ │ per-section AES-GCM encrypt → upsertSection
103
+ ▼
104
+ hooks/session-start.ts
105
+ │ scripts/genome-cloud-pull.ts
106
+ │ parse cwd git remote → canonicalize repo URL
107
+ │ GET /genome/personal/find?repo_url=<canon>
108
+ │ download sections → ~/.ashlr/genomes/<projectHash>/
109
+ │ write .ashlr-cloud-genome marker
110
+ ▼
111
+ ashlr__grep
112
+ ├─ local .ashlrcode/genome/ (wins if present)
113
+ ├─ ~/.ashlr/genomes/<hash>/ (cloud fallback via findParentGenome)
114
+ └─ ripgrep full-tree (last resort)
115
+ ```
116
+
117
+ Full walkthrough: [docs/github-oauth-onboarding.md](github-oauth-onboarding.md)
118
+ Pipeline architecture: [docs/cloud-genome.md](cloud-genome.md)
119
+
120
+ ---
121
+
122
+ ## 3. Stats Data Flow
123
+
124
+ ### Per-session bucket shape
125
+
126
+ `~/.ashlr/stats.json` holds a `sessions` map keyed by `CLAUDE_SESSION_ID` (or a PPID-derived fallback when the env var is absent). Each bucket:
127
+
128
+ ```
129
+ sessions: {
130
+ "<session-id>": {
131
+ calls: number, // tool invocations attributed to this session
132
+ tokensSaved: number,
133
+ costSaved: number,
134
+ startedAt: ISO-string,
135
+ byTool: { [toolName]: { calls, tokensSaved, costSaved } },
136
+ projects: { [cwd]: { calls, tokensSaved } },
137
+ }
138
+ }
139
+ ```
140
+
141
+ Lifetime totals live in `stats.lifetime` alongside the map and are never dropped.
142
+
143
+ ### Write path
144
+
145
+ ```
146
+ MCP tool handler (e.g. ashlr__read)
147
+ └─ recordSaving(tokens, cost, tool, cwd) servers/_stats.ts:recordSaving
148
+ └─ withSerializedWrite(fn) in-process Promise mutex (writeQueue chain)
149
+ └─ acquireLock() ~/.ashlr/stats.lock (O_EXCL, 200ms spin)
150
+ └─ readStats() JSON.parse(readFileSync)
151
+ └─ mutate bucket
152
+ └─ writeStatsAtomic()
153
+ └─ writeFile(tmpPath)
154
+ └─ fsync(fd) (via Bun's native fd)
155
+ └─ rename(tmp → stats.json)
156
+ └─ releaseLock()
157
+ ```
158
+
159
+ Two serialization layers — the in-process mutex (a chained Promise) prevents concurrent async calls within one server process from racing; the filesystem lock extends that to the 12 servers and hooks that can run simultaneously. The rename is atomic at the OS level, so readers never see a partial write.
160
+
161
+ ### schemaVersion and migration
162
+
163
+ `stats.json` carries `"schemaVersion": 2`. On load, `_stats.ts:readStats` checks the version and migrates forward if needed (v1 had a single global `session` field; v2 moves that to the per-session map). The migration is additive and non-destructive — old lifetime counters are preserved.
164
+
165
+ ---
166
+
167
+ ## 4. Hook Graph
168
+
169
+ Hooks are declared in `hooks/hooks.json` and executed by the Claude Code harness. The file references below show where each hook lives.
170
+
171
+ ```
172
+ Session opens
173
+ │
174
+ ▼
175
+ SessionStart ──► hooks/session-start.ts
176
+ │ • Runs baseline scanner (project orientation)
177
+ │ • Calls initSessionBucket() in _stats.ts
178
+ │ • Emits session greeting to stderr
179
+ │
180
+ ▼ (for each tool call)
181
+ PreToolUse (matcher: "Read") ──► hooks/pretooluse-read.ts
182
+ PreToolUse (matcher: "Grep") ──► hooks/pretooluse-grep.ts
183
+ PreToolUse (matcher: "Edit") ──► hooks/pretooluse-edit.ts
184
+ │ (as of v1.18: emits permissionDecision: "deny" with actionable
185
+ │ "call mcp__plugin_ashlr_ashlr__ashlr__* instead" message when
186
+ │ ASHLR_HOOK_MODE=redirect, which is the default. Safety nets:
187
+ │ paths outside cwd (realpath-canonicalized for macOS /tmp →
188
+ │ /private/tmp), paths inside CLAUDE_PLUGIN_ROOT, bypassSummary:true
189
+ │ are never redirected. Escape hatch: ASHLR_HOOK_MODE=nudge or
190
+ │ hookMode:"nudge" in ~/.ashlr/config.json.)
191
+ ▼
192
+ [ tool executes ]
193
+ │
194
+ ▼
195
+ PostToolUse (matcher: Write|Edit|MultiEdit|Bash|mcp__plugin_ashlr_ashlr__ashlr__*)
196
+ ├──► hooks/genome-scribe-hook.ts (genome auto-propose; matcher expanded
197
+ │ in v1.18 to cover MultiEdit,
198
+ │ ashlr__multi_edit, ashlr__edit_structural)
199
+ └──► hooks/session-log-append.ts (JSONL append)
200
+ │
201
+ ▼
202
+ SessionEnd
203
+ ├──► hooks/session-end-consolidate.ts (genome consolidation; v1.17+ fires
204
+ │ scripts/genome-cloud-push.ts afterwards
205
+ │ when .cloud-id present)
206
+ └──► hooks/session-end-stats-gc.ts (drop session bucket, append summary to log)
207
+ ```
208
+
209
+ PreToolUse hooks are matcher-filtered — Claude Code only fires them for the named tool. PostToolUse has a pipe-separated matcher covering both native tools and the ashlr MCP variants (canonical prefix `mcp__plugin_ashlr_ashlr__ashlr__*` as of v1.13 router consolidation; all matchers in `hooks/hooks.json` renamed to this form in v1.18 after legacy `mcp__ashlr-efficiency__*` / `mcp__ashlr-multi-edit__*` stopped matching post-router-migration).
210
+
211
+ ---
212
+
213
+ ## 5. Genome Lifecycle
214
+
215
+ The genome is a per-project knowledge base stored under `.ashlrcode/genome/`. It powers genome-aware `ashlr__grep` routing and surfaces architectural context during sessions.
216
+
217
+ **Init** — `scripts/genome-init.ts` (invoked by the `/ashlr-genome-init` skill). Creates the scaffold via `@ashlr/core-efficiency/genome:initGenome`, then writes three knowledge files: `knowledge/architecture.md` (baseline scanner output), `knowledge/conventions.md` (detected from config files), and `knowledge/decisions.md` (ADR-0000 placeholder).
218
+
219
+ **Propose (edit-triggered)** — `hooks/post-tool-use-genome.sh` fires on every Write/Edit/MultiEdit/Bash call. It pipes the PostToolUse payload to `scripts/genome-auto-propose.ts`, which:
220
+ 1. Skips trivial tools via a whitelist.
221
+ 2. Regex-matches architecture/decision signals in the result text.
222
+ 3. Deduplicates by SHA-256 of the first 500 chars against a persisted set at `~/.ashlr/genome-proposals-seen.json` (capped at 10K entries).
223
+ 4. Walks up from `cwd` to find `.ashlrcode/genome/`.
224
+ 5. Appends a JSONL record to `proposals.jsonl` with the current generation number.
225
+
226
+ **Consolidate (session-end or threshold)** — `hooks/session-end-consolidate.sh` runs at SessionEnd. It also fires mid-session when the proposal count crosses a threshold. Consolidation calls `ashlr__genome_consolidate` (via `servers/genome-server.ts`), which delegates to `@ashlr/core-efficiency/scribe.ts` to merge pending proposals into the genome files. If a local LLM is reachable it summarizes the diffs; otherwise it does a line-level merge. Progress is logged to `~/.ashlr/genome-consolidation.log`.
227
+
228
+ ---
229
+
230
+ ## 6. Status Line Rendering
231
+
232
+ Claude Code calls the `statusLine.command` from `plugin.json` periodically and renders the first stdout line in its UI bar.
233
+
234
+ Pipeline:
235
+
236
+ ```
237
+ stats.json
238
+ └─ readCurrentSession(sessionId) servers/_stats.ts
239
+ └─ buildStatusLine() scripts/savings-status-line.ts
240
+ ├─ formatTokens(saved) → "1.2K", "450K", "2.1M"
241
+ ├─ readDailyHistory() → last-N-day savings array
242
+ ├─ renderSparkline(history) scripts/ui-animation.ts:renderSparkline
243
+ │ └─ 16-rung Unicode bars (ASCII fallback for non-Unicode terminals)
244
+ ├─ renderGradient(sparkline) scripts/ui-animation.ts:renderGradient
245
+ │ └─ truecolor sweep (single brand color fallback)
246
+ ├─ renderHeartbeat(pulse) scripts/ui-animation.ts
247
+ └─ applyColor(line) scripts/savings-status-line.ts
248
+ ```
249
+
250
+ **Capability detection.** `scripts/savings-status-line.ts` reads terminal capability flags before rendering. Unicode glyphs are suppressed when the terminal can't display them. Color is suppressed when `NO_COLOR` is set or when the terminal reports no color support. Animation is suppressed when `ASHLR_STATUS_ANIMATE=0`.
251
+
252
+ **Width budget.** The output target is 80 characters. `visibleWidth()` in `scripts/ui-animation.ts:visibleWidth` strips ANSI escapes and counts code points to measure rendered width, independent of color sequences. The status line truncates segments to stay within budget.
253
+
254
+ **Context-pressure widget.** A micro-widget `ctx: NN%` is inserted between the sparkline and the `session +N` segment when Claude Code pipes a session-state JSON payload on stdin. The widget is hidden entirely when the payload is absent or contains no usable fields — it never guesses. Color tiers (truecolor only):
255
+
256
+ | Range | Color |
257
+ |--------|---------------------|
258
+ | 0–60% | dim brand-green |
259
+ | 60–80% | yellow (`#d4a72c`) |
260
+ | 80–95% | orange (`#d9793a`) |
261
+ | 95%+ | red + bold (`#e15b5b`) |
262
+
263
+ Payload fields tried (in priority order):
264
+ 1. `context_used_tokens` + `context_limit_tokens` (explicit used/limit pair — most precise)
265
+ 2. All other fields (`input_tokens`, `context_tokens`, `total_tokens`, `total_tokens_used`, `sessionTokens`) require a paired limit field to compute a percentage; without one the widget is hidden.
266
+
267
+ The stdin reader in `import.meta.main` has a hard 50ms deadline and never blocks the terminal. The widget counts toward the 80-char visible-width budget. Drop-order under tight budget: tip is dropped first, then the context widget; the brand + session + lifetime core is never truncated mid-word.
268
+
269
+ **Settings toggles** (under `ashlr` key in `~/.claude/settings.json`):
270
+ - `statusLine` — master on/off switch (default: true)
271
+ - `statusLineSession` — show "session +N" segment
272
+ - `statusLineLifetime` — show "lifetime +N" segment
273
+ - `statusLineTips` — rotate a helpful tip at the tail
274
+
275
+ ---
276
+
277
+ ## 7. Session Log
278
+
279
+ `~/.ashlr/session-log.jsonl` is an append-only JSONL file. Each line is a flat JSON record.
280
+
281
+ **Append path** — `hooks/session-log-append.sh` fires PostToolUse. It uses `bun` to parse the hook payload and emit a structured record; falls back to a minimal bash-built record if bun is unavailable. Self-rotates at 10 MB to `session-log.jsonl.1`.
282
+
283
+ **Record schema:**
284
+ ```json
285
+ { "ts": "ISO-8601", "agent": "claude-code", "event": "tool_call",
286
+ "tool": "ashlr__read", "cwd": "/abs/path", "session": "sess-id",
287
+ "input_size": 42, "output_size": 310 }
288
+ ```
289
+
290
+ **Session-end summary** — `hooks/session-end-stats-gc.ts` appends one final record per session with `event: "session_end"` carrying `calls`, `tokens_saved`, and `started_at` from the bucket being dropped.
291
+
292
+ **Planned events** — `tool_fallback` (LLM summarization fell back to snip-compact) and `tool_escalate` (agent escalated from haiku to sonnet) are reserved event types.
293
+
294
+ **Aggregator** — `scripts/session-log-report.ts` reads the log (+ rotated `.1`) and produces a plain-text report covering top tools by call count, per-project breakdowns, 24h vs lifetime comparison, and recent session summaries. Exposed via the `/ashlr-usage` skill.
295
+
296
+ ---
297
+
298
+ ## 8. Summarization
299
+
300
+ Source: `servers/_summarize.ts`.
301
+
302
+ **When it fires.** Each tool that handles large output (read, grep, edit, bash, sql, diff) checks if the raw result exceeds ~2KB. If so it calls `summarize(content, toolName)`.
303
+
304
+ **Local-first.** Default endpoint is `http://localhost:1234/v1` (LM Studio). Override via `ASHLR_LLM_URL` + `ASHLR_LLM_KEY` for cloud. Cloud only fires when explicitly set; the plugin has no account requirement and telemetry is off by default.
305
+
306
+ **Cache.** SHA-256 of the input is used as cache key. Cache files live at `~/.ashlr/summary-cache/<hash>.txt` with a 1-hour TTL. A cache hit costs zero tokens.
307
+
308
+ **Fallback.** If the LLM endpoint is unreachable or times out (5s), `summarize` falls back to snipCompact truncation and appends `[LLM unreachable, fell back to truncation]` so the agent can see what happened. `bypassSummary: true` on any tool call skips LLM and snip-compacts directly.
309
+
310
+ **Per-tool prompts.** `_summarize.ts:TOOL_PROMPTS` maps tool names to system prompts tuned for each output type: file contents preserve imports and signatures; bash preserves errors and final result lines; SQL preserves first/last rows and counts. Reading from the end of the file gives the full prompt set.
311
+
312
+ ---
313
+
314
+ ## 9. Adding a New MCP Tool
315
+
316
+ With the consolidated router, adding a tool no longer requires a new `mcpServers` entry in `plugin.json`.
317
+
318
+ 1. **Create or extend a server module** (e.g. `servers/foo-server.ts`):
319
+ - Import `registerTool` from `servers/_router.ts`.
320
+ - Call `registerTool("ashlr__foo", async (params) => { ... })` at module top level.
321
+ - Call `await recordSaving(tokensEstimate, costEstimate, "ashlr__foo", cwd)` after each successful call.
322
+ - Wrap handler body in `try/catch`; return `{ content: [...], isError: true }` on error.
323
+
324
+ 2. **Import the module in `servers/_router.ts`** so `registerTool` runs at startup.
325
+
326
+ 3. **Write tests in `__tests__/foo-server.test.ts`**. Use `mkdtemp` for an isolated `HOME` so no test touches `~/.ashlr`. Spawn the real server process and speak JSON-RPC over stdio (see `__tests__/efficiency-server.test.ts` for the `rpc()` helper pattern).
327
+
328
+ 4. **Add to `CHANGELOG.md`** under the current version block.
329
+
330
+ 5. **Update this document** — add a row to the tool registry table in section 2.
331
+
332
+ No `plugin.json` change is needed. The entrypoint script handles `bun install` automatically.
333
+
334
+ ---
335
+
336
+ ## 10. Testing Model
337
+
338
+ Test runner: `bun test`. All test files live in `__tests__/`.
339
+
340
+ **Isolation.** Every test suite that touches the filesystem creates a `mkdtemp` temp dir and passes it as `HOME` (or equivalent) to the code under test. No test reads or writes the real `~/.ashlr`. See `__tests__/session-log-report.test.ts:beforeEach` for the canonical pattern.
341
+
342
+ **Integration tests.** `__tests__/efficiency-server.test.ts` spawns the real MCP server process and sends JSON-RPC requests over stdio. This catches wiring bugs that unit tests miss. The `rpc(reqs, env)` helper in that file is reusable for other server tests.
343
+
344
+ **Fixture conventions.** Synthetic log/stats data is built inline as arrays of typed records, not from files on disk. This keeps tests hermetic and readable without fixture file management.
345
+
346
+ **Special test groups:**
347
+ - `__tests__/integration/` — multi-server or end-to-end scenarios.
348
+ - `__tests__/quality/` — snapshot/regression tests for rendered output (savings report, status line).
349
+
350
+ **Running:**
351
+ ```
352
+ bun test # all tests
353
+ bun test __tests__/foo.test.ts # single file
354
+ ```
355
+
356
+ Tests that require a live database are skipped automatically when `$TEST_DATABASE_URL` is absent.
357
+
358
+ ---
359
+
360
+ ## 11. Release Flow
361
+
362
+ Script: `scripts/publish.sh`. Accepts `--dry-run`.
363
+
364
+ Steps:
365
+ 1. Checks `gh auth status`.
366
+ 2. Creates the `ashlr-plugin` GitHub repo (public) if it doesn't exist, then pushes `main`.
367
+ 3. Optionally creates and pushes `@ashlr/core-efficiency` if the sibling repo exists locally.
368
+ 4. Enables GitHub Pages from `/docs` (POST then PUT — idempotent).
369
+
370
+ Version bumping is manual: edit `plugin.json:version` and `CHANGELOG.md` before running the script. There is no automated semver bump. The `scripts/mcp-entrypoint.ts` reads the version from `plugin.json` to identify stale sibling cache dirs and clean them up.
371
+
372
+ ---
373
+
374
+ ## 12. Design Principles
375
+
376
+ These are the non-obvious decisions baked into the codebase.
377
+
378
+ **Local-first LLM, opt-in telemetry.** The summarization helper calls `localhost:1234` by default. No summarization payload leaves the machine unless the user explicitly sets `ASHLR_LLM_URL`; telemetry is off by default and has to be enabled separately.
379
+
380
+ **Atomic stats writes.** A two-layer write protocol (in-process Promise chain + `O_EXCL` lockfile + `rename`) ensures that N concurrent MCP servers and hooks never corrupt `stats.json`. Any approach that just does `JSON.parse` → mutate → `writeFile` will lose updates under load. The lockfile spin is capped at 200ms; if it can't acquire, it skips the write rather than blocking the tool call.
381
+
382
+ **Per-session accounting.** The old `stats.json` had a single global `session` field. With multiple Claude Code terminals open, every server clobbered each other's counter. v2 uses `CLAUDE_SESSION_ID` as a bucket key. The TypeScript MCP entrypoint mirrors this value to `ASHLR_SESSION_ID` before launching the router.
383
+
384
+ **Width-stable status line.** The status line must not reflow the UI on every refresh. `visibleWidth()` strips ANSI escapes before measuring. Segments are truncated (not wrapped) to stay within 80 chars. The sparkline always occupies the same number of columns regardless of savings magnitude.
385
+
386
+ **Genome is fire-and-forget.** The auto-propose hook, the consolidation hook, and the genome server are all written to never throw and never block the agent. A genome write failure is invisible to the user. This is intentional — genome is an optimization layer, not a correctness requirement.
387
+
388
+ **GC at session end.** Per-session buckets are dropped from `stats.json` when the session closes (`hooks/session-end-stats-gc.ts`). Lifetime counters are never dropped. This bounds `stats.json` size without losing the numbers that matter.
389
+
390
+ ---
391
+
392
+ ## Supported Platforms
393
+
394
+ ashlr-plugin is tested in CI on three operating systems via a matrix strategy in `.github/workflows/ci.yml`. The `typecheck`, `test`, and `smoke` jobs all run on every OS on every push.
395
+
396
+ | Platform | Runner | Status |
397
+ |---|---|---|
398
+ | Linux | `ubuntu-latest` (Ubuntu 22.04) | Full support |
399
+ | macOS | `macos-latest` (macOS 14 Sonoma) | Full support |
400
+ | Windows | `windows-latest` (Windows Server 2022) | Full support — see caveats below |
401
+
402
+ ### Caveats
403
+
404
+ **ripgrep install.** The install step is platform-specific: `apt-get` on Linux, `brew` on macOS, `winget` (falling back to `choco`) on Windows. The plugin itself does not bundle ripgrep; it must be on `PATH`.
405
+
406
+ **File permissions.** Three tests are skipped on Windows with `test.skipIf(process.platform === "win32")` because Windows does not honour POSIX `chmod` mode bits:
407
+ - `genome-crypto.test.ts` — key file mode 0600 check
408
+ - `genome-init.test.ts` — unreadable dir (chmod 000) fallback
409
+ - `doctor.test.ts` — non-executable hook warnings / chmod +x fix
410
+
411
+ **bash-server.** The `ashlr-bash` MCP server spawns `sh -c` commands. On Windows this requires Git Bash or WSL in the user's `PATH`. The server tests are Linux/macOS only in practice; Windows users who need `ashlr__bash` should install Git for Windows. On POSIX, v1.18 spawns with `detached: true` and kills the process group (`-pid`) on timeout so forked grandchildren (`npm install`, `cargo build`) don't leak past the timeout. Policy-enforce cache path uses `os.tmpdir()` (v1.18) so the hook works on Windows.
412
+
413
+ **CRLF line endings.** The checkout step sets `core.autocrlf false` in all matrix jobs to prevent git from converting LF to CRLF on Windows, which would break hash-based cache keys and diff expectations.
414
+
415
+ **Integration tests.** The `integration` job runs on Linux only. These tests spawn the backend server process; the server is deployed on Linux in production, so Linux e2e parity is sufficient. See `docs/platform-support.md` for the full matrix of what runs where.