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
package/docs/deploy.md ADDED
@@ -0,0 +1,325 @@
1
+ # Deploy Guide
2
+
3
+ This document covers end-to-end deployment of the ashlr site (Vercel) and API server (Railway), DNS configuration, smoke testing, rollback procedures, and expected costs.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Vercel — site deployment](#1-vercel--site-deployment)
10
+ 2. [Fly.io — API server deployment](#2-flyio--api-server-deployment)
11
+ 3. [DNS configuration](#3-dns-configuration)
12
+ 4. [Smoke test](#4-smoke-test)
13
+ 5. [Rollback procedures](#5-rollback-procedures)
14
+ 6. [Cost expectations](#6-cost-expectations)
15
+
16
+ ---
17
+
18
+ ## Signing up — email setup (SendGrid)
19
+
20
+ ashlr uses [SendGrid](https://sendgrid.com) to send magic-link sign-in emails from
21
+ `noreply@ashlr.ai`. Before users can self-serve sign up, a domain-verified
22
+ sender must be configured:
23
+
24
+ 1. Create a SendGrid account at https://sendgrid.com and add your sending domain
25
+ (e.g. `ashlr.ai`). Follow their
26
+ [domain verification guide](https://docs.sendgrid.com/ui/sending-email/sender-verification)
27
+ to add the required DNS records (SPF, DKIM, DMARC).
28
+ 2. Once the domain is verified, create an API key in the SendGrid dashboard
29
+ (Developers > API Keys). Scope it to "Sending access" only.
30
+ 3. Store the key as a Railway variable alongside your other server variables
31
+ (Project > ashlr-plugin-api > Variables, or via CLI):
32
+ ```
33
+ railway variables --service ashlr-plugin-api --set SENDGRID_API_KEY=SG...
34
+ ```
35
+ 4. Set the `FRONTEND_URL` variable to your site origin so magic-link URLs point
36
+ to the right place (default: `https://plugin.ashlr.ai`):
37
+ ```
38
+ railway variables --service ashlr-plugin-api --set FRONTEND_URL=https://plugin.ashlr.ai
39
+ ```
40
+
41
+ **Dev / test mode:** If `SENDGRID_API_KEY` is unset, or if `TESTING=1`, no email
42
+ is sent. The magic token is printed to stderr instead — safe for local
43
+ development and CI.
44
+
45
+ ---
46
+
47
+ ## Stripe webhook setup
48
+
49
+ After deploying the API server, register the billing webhook in the Stripe dashboard:
50
+
51
+ 1. Go to Stripe Dashboard > Developers > Webhooks > Add endpoint.
52
+ 2. Set the endpoint URL to `https://api.ashlr.ai/billing/webhook`.
53
+ 3. Select the following events to listen for:
54
+ - `checkout.session.completed`
55
+ - `customer.subscription.updated`
56
+ - `customer.subscription.deleted`
57
+ - `invoice.payment_failed`
58
+ 4. After saving, reveal the signing secret (`whsec_...`) and store it as a Railway variable:
59
+
60
+ ```sh
61
+ railway variables --service ashlr-plugin-api --set STRIPE_WEBHOOK_SECRET=whsec_...
62
+ railway variables --service ashlr-plugin-api --set STRIPE_SECRET_KEY=sk_live_...
63
+ ```
64
+
65
+ 5. Bootstrap Stripe products and prices (run once per environment):
66
+
67
+ ```sh
68
+ railway run --service ashlr-plugin-api -- bun run src/cli/stripe-setup.ts
69
+ ```
70
+
71
+ The setup script is idempotent — re-running it is safe.
72
+
73
+ ---
74
+
75
+ ## 1. Vercel — site deployment
76
+
77
+ The `site/` Next.js app is deployed to Vercel via `.github/workflows/deploy-site.yml`. Pushes to `main` that touch `site/**` trigger a production deploy. Pull requests get a preview URL posted as a comment.
78
+
79
+ ### Step 1 — Create the Vercel project
80
+
81
+ 1. Go to [vercel.com](https://vercel.com) and sign in.
82
+ 2. Click **Add New Project**, select your GitHub repo (`ashlrai/ashlr-plugin`).
83
+ 3. Set the **Root Directory** to `site`.
84
+ 4. Set the **Framework Preset** to `Next.js`.
85
+ 5. Leave build/output settings at defaults — the workflow runs `bun run build` itself.
86
+ 6. Click **Deploy** once to initialize the project (this first deploy can be ignored).
87
+
88
+ ### Step 2 — Grab the three required tokens
89
+
90
+ All three values are on the project settings page in Vercel.
91
+
92
+ | Secret | Where to find it |
93
+ |--------|-----------------|
94
+ | `VERCEL_TOKEN` | Account Settings > Tokens > Create (scope: Full Account) |
95
+ | `VERCEL_ORG_ID` | Project Settings > General > Team ID (shown at page top) |
96
+ | `VERCEL_PROJECT_ID` | Project Settings > General > Project ID |
97
+
98
+ ### Step 3 — Add secrets to GitHub
99
+
100
+ In the GitHub repo, go to **Settings > Secrets and variables > Actions**, then add:
101
+
102
+ - `VERCEL_TOKEN`
103
+ - `VERCEL_ORG_ID`
104
+ - `VERCEL_PROJECT_ID`
105
+
106
+ ### Step 4 — Verify
107
+
108
+ Push any change under `site/` to `main`. The **Deploy site to Vercel** workflow should appear under Actions, run `bun run build`, then deploy. The Vercel dashboard shows the new deployment within ~2 minutes.
109
+
110
+ For pull requests, the workflow posts a preview URL comment. No additional configuration needed.
111
+
112
+ ---
113
+
114
+ ## 2. Railway — API server deployment
115
+
116
+ The `server/` Hono/Bun app is deployed to Railway via `.github/workflows/deploy-server.yml`. Pushes to `main` that touch `server/**` run tests first, then deploy. Build is driven by `server/Dockerfile` (referenced from `server/railway.json`).
117
+
118
+ ### Step 1 — Install Railway CLI and log in
119
+
120
+ ```bash
121
+ brew install railway # macOS
122
+ # or: curl -fsSL https://railway.com/install.sh | sh
123
+ railway login
124
+ ```
125
+
126
+ ### Step 2 — Create the project (first time only)
127
+
128
+ ```bash
129
+ cd server
130
+ railway init --name ashlr-plugin-api
131
+ ```
132
+
133
+ This creates a Railway project in your default workspace. After init:
134
+
135
+ ```bash
136
+ # Add a service inside the project (named to match the workflow)
137
+ railway add --service ashlr-plugin-api
138
+
139
+ # Link this directory to the new project so `railway up` knows where to deploy
140
+ railway link
141
+ ```
142
+
143
+ Railway auto-detects the `Dockerfile` and `railway.json` in `server/`. The `healthcheckPath` is `/readyz` (matches `server/src/routes/health.ts`).
144
+
145
+ ### Step 3 — Set environment variables
146
+
147
+ The server needs ~20 variables — see [`docs/operations.md`](./operations.md) for the full list. Set them via either:
148
+
149
+ ```bash
150
+ # Per-key
151
+ railway variables --service ashlr-plugin-api --set ASHLR_MASTER_KEY=...
152
+
153
+ # Or paste a .env in the Railway dashboard:
154
+ # Project > ashlr-plugin-api > Variables > Raw editor
155
+ ```
156
+
157
+ The minimum to boot a healthy instance: `ASHLR_MASTER_KEY`, `NODE_ENV=production`, `FRONTEND_URL`, plus whichever feature secrets you need (Stripe / SendGrid / GitHub OAuth / xAI).
158
+
159
+ `PORT` is provided by Railway automatically — don't set it.
160
+
161
+ ### Step 4 — Get the deploy token
162
+
163
+ ```bash
164
+ # Project-scoped token (recommended): only deploys to this project, can't access others.
165
+ # Create one in the Railway dashboard:
166
+ # Account > Tokens > New Token > scope: Project: ashlr-plugin-api
167
+ ```
168
+
169
+ Copy the printed value. This is your `RAILWAY_TOKEN`.
170
+
171
+ ### Step 5 — Add the secret to GitHub
172
+
173
+ In GitHub repo > **Settings > Secrets and variables > Actions**, add:
174
+
175
+ - `RAILWAY_TOKEN`
176
+
177
+ ### Step 6 — Push and verify
178
+
179
+ Push any change under `server/` to `main`. The **Deploy server to Railway** workflow runs `bun test` first — if any test fails, the deploy is aborted. On success, `railway up --service ashlr-plugin-api --detach` builds and deploys remotely.
180
+
181
+ Verify with:
182
+
183
+ ```bash
184
+ curl https://api.ashlr.ai/
185
+ # Expected: {"ok":true,"service":"ashlr-server","phase":1}
186
+ ```
187
+
188
+ ---
189
+
190
+ ## 3. DNS configuration
191
+
192
+ ### plugin.ashlr.ai — Vercel
193
+
194
+ Add a CNAME record in your DNS provider:
195
+
196
+ ```
197
+ Type: CNAME
198
+ Name: plugin
199
+ Value: cname.vercel-dns.com
200
+ TTL: 3600
201
+ ```
202
+
203
+ Then in Vercel > Project Settings > Domains, add `plugin.ashlr.ai`. Vercel provisions a TLS certificate automatically via Let's Encrypt within ~2 minutes.
204
+
205
+ ### api.ashlr.ai — Railway
206
+
207
+ Railway provisions a default `<service>-production-<id>.up.railway.app` domain. Get it with:
208
+
209
+ ```bash
210
+ railway domain --service ashlr-plugin-api
211
+ ```
212
+
213
+ In the Railway dashboard → ashlr-plugin-api → Settings → Networking → **Custom Domain**, add `api.ashlr.ai`. Railway shows you the exact CNAME target to use; it usually looks like `<id>.up.railway.app`.
214
+
215
+ Add a CNAME record in your DNS provider:
216
+
217
+ ```
218
+ Type: CNAME
219
+ Name: api
220
+ Value: <target shown in Railway dashboard>
221
+ TTL: 3600
222
+ ```
223
+
224
+ Railway issues the TLS certificate automatically via Let's Encrypt within ~2 minutes.
225
+
226
+ ---
227
+
228
+ ## 4. Smoke test
229
+
230
+ After every deploy, run the smoke test script to verify both services are healthy:
231
+
232
+ ```bash
233
+ # Install endpoint only (no token required)
234
+ ./scripts/deploy-smoke.sh
235
+
236
+ # Full test including badge and stats endpoints
237
+ ASHLR_TOKEN=<provisioned_token> ./scripts/deploy-smoke.sh
238
+
239
+ # Override URLs for staging
240
+ SITE_URL=https://preview.plugin.ashlr.ai \
241
+ API_URL=https://staging-api.ashlr.ai \
242
+ ASHLR_TOKEN=<token> \
243
+ ./scripts/deploy-smoke.sh
244
+ ```
245
+
246
+ The script exits with code `0` on full pass, `1` if any check fails. It is safe to run repeatedly. Checks performed:
247
+
248
+ - `GET /` on site — 200
249
+ - `GET /robots.txt` — 200
250
+ - `GET /sitemap.xml` — 200
251
+ - `GET /` on API — `{ok: true}` JSON
252
+ - `POST /stats/sync` — 200 (authenticated)
253
+ - `GET /stats/aggregate` — user_id present (authenticated)
254
+ - `GET /u/:userId/badge.svg` — SVG content with metric text
255
+
256
+ To provision a token for testing:
257
+
258
+ ```bash
259
+ cd server && bun run issue-token
260
+ ```
261
+
262
+ ---
263
+
264
+ ## 5. Rollback procedures
265
+
266
+ ### Vercel rollback
267
+
268
+ The Vercel dashboard keeps every deployment permanently. To roll back:
269
+
270
+ 1. Go to the project > **Deployments**.
271
+ 2. Find the last known-good deployment.
272
+ 3. Click the three-dot menu > **Promote to Production**.
273
+
274
+ Takes effect within 30 seconds globally.
275
+
276
+ Alternatively, revert the offending commit and push — the workflow redeploys automatically.
277
+
278
+ ### Railway rollback
279
+
280
+ Railway keeps every previous deployment. Roll back instantly from the dashboard:
281
+
282
+ 1. Go to the project > **ashlr-plugin-api** > **Deployments**.
283
+ 2. Find the last known-good deployment.
284
+ 3. Click the three-dot menu > **Redeploy**.
285
+
286
+ Or via CLI:
287
+
288
+ ```bash
289
+ # List recent deployments
290
+ railway status --service ashlr-plugin-api
291
+
292
+ # Redeploy the most recent successful deployment (rollback if HEAD is broken)
293
+ railway redeploy --service ashlr-plugin-api
294
+ ```
295
+
296
+ Or revert the commit and push — the workflow redeploys the server automatically.
297
+
298
+ To monitor a rollback:
299
+
300
+ ```bash
301
+ railway logs --service ashlr-plugin-api
302
+ ```
303
+
304
+ ---
305
+
306
+ ## 6. Cost expectations
307
+
308
+ Cost figures below are derived from the Phase 1 architecture (Railway for compute, Neon serverless Postgres, Cloudflare R2/S3 for storage, Upstash Redis for rate limits).
309
+
310
+ | Component | 100 MAU | 1,000 MAU | 10,000 MAU |
311
+ |-----------|---------|-----------|------------|
312
+ | Vercel (site hosting) | Free tier | Free tier | ~$20/mo (Pro) |
313
+ | Railway compute (ashlr-plugin-api, sleeps when idle) | ~$5/mo | ~$10/mo | ~$30/mo |
314
+ | Postgres (Neon serverless) | ~$0.50/mo | ~$5/mo | ~$30/mo |
315
+ | S3 / R2 (stats backups, genome bodies) | ~$0.10/mo | ~$1/mo | ~$8/mo |
316
+ | Redis (Upstash, rate limits + cache) | $0 (free tier) | $20/mo (fixed) | $50/mo |
317
+ | Cloud LLM inference (Haiku, summarization) | ~$0.20/mo | ~$2/mo | ~$20/mo |
318
+ | Bandwidth + misc | ~$0.20/mo | ~$2/mo | ~$15/mo |
319
+ | **Total** | **~$4/mo** | **~$38/mo** | **~$173/mo** |
320
+
321
+ **At 1K MAU**, total infra is approximately **$38/month**. The MIT free tier carries no marginal cost per user for the open-source plugin itself; backend costs arise only from the Pro stats-sync and hosted badge features.
322
+
323
+ **At 10K MAU**, the architecture remains defensible. Beyond that, add Postgres read replicas and consider sharding by organization. See `docs/pro-backend-architecture.md` for the full cost model and scaling decision points.
324
+
325
+ **Fly.io specifics**: the `ashlr-api` app is configured with `auto_stop_machines = "stop"` and `min_machines_running = 0`. It scales to zero when idle, meaning zero compute cost at 0 requests. The first request cold-starts in ~500ms (Bun is fast). For production traffic, set `min_machines_running = 1` to eliminate cold starts at the cost of ~$3/mo for the always-on machine.
@@ -0,0 +1,113 @@
1
+ # ashlr email templates
2
+
3
+ React-email templates for all transactional emails sent by the ashlr backend.
4
+
5
+ ## Preview server
6
+
7
+ Start a local preview server on port 3333:
8
+
9
+ ```
10
+ bun run server/src/emails/preview.ts
11
+ ```
12
+
13
+ Then open http://localhost:3333 to browse all templates. Each template is rendered with realistic sample data. The preview server does not require `SENDGRID_API_KEY`.
14
+
15
+ Individual template URLs:
16
+
17
+ | Template | URL |
18
+ |---|---|
19
+ | magic-link | http://localhost:3333/preview/magic-link |
20
+ | welcome | http://localhost:3333/preview/welcome |
21
+ | payment-success | http://localhost:3333/preview/payment-success |
22
+ | payment-failed | http://localhost:3333/preview/payment-failed |
23
+ | subscription-canceled | http://localhost:3333/preview/subscription-canceled |
24
+ | daily-cap-reached | http://localhost:3333/preview/daily-cap-reached |
25
+
26
+ Or via the npm script alias:
27
+
28
+ ```
29
+ cd server && bun run email:preview
30
+ ```
31
+
32
+ ## Templates
33
+
34
+ ### magic-link
35
+
36
+ **Subject:** Your ashlr sign-in link
37
+ **Trigger:** `POST /auth/send`
38
+ **Props:** `{ email: string, link: string }`
39
+
40
+ Sign-in magic link. Greets the user by the local part of their email address, provides a prominent CTA button, includes the raw link in plain text below the button for accessibility, and notes the 15-minute expiration. Security notice at the bottom.
41
+
42
+ ### welcome
43
+
44
+ **Subject:** Welcome to ashlr · your first steps
45
+ **Trigger:** `checkout.session.completed` (sent alongside payment-success)
46
+ **Props:** `{ email: string }`
47
+
48
+ Onboarding email. Three numbered steps: run `/ashlr-tour`, set up `ASHLR_PRO_TOKEN`, open `/ashlr-dashboard`. Links to docs, GitHub, and pricing.
49
+
50
+ ### payment-success
51
+
52
+ **Subject:** ashlr Pro — you're in
53
+ **Trigger:** `checkout.session.completed`
54
+ **Props:** `{ email: string, amount: number, tier: string, renewsOn: string }`
55
+
56
+ Subscription confirmation. Receipt table with plan, amount charged (formatted as `$X.XX`), and renewal date. Links to dashboard and billing portal.
57
+
58
+ ### payment-failed
59
+
60
+ **Subject:** ashlr Pro — payment failed, we'll retry
61
+ **Trigger:** `invoice.payment_failed`
62
+ **Props:** `{ email: string, gracePeriodEnd: string }`
63
+
64
+ Payment failure notice. Explains the 7-day grace period, shows the exact date access expires if unresolved, provides a CTA to update the payment method in the Stripe billing portal.
65
+
66
+ ### subscription-canceled
67
+
68
+ **Subject:** ashlr Pro — your subscription has ended
69
+ **Trigger:** `customer.subscription.deleted`
70
+ **Props:** `{ email: string }`
71
+
72
+ Cancellation confirmation. Clearly states that local-first features (genome init, token savings, slash commands, full CLI) remain free forever. Lists the Pro-only features that have been disabled: genome sync across machines and cloud LLM summarization. CTA to resubscribe.
73
+
74
+ ### daily-cap-reached
75
+
76
+ **Subject:** ashlr Pro — daily LLM cap reached
77
+ **Trigger:** first `POST /llm/summarize` that returns 429 for a given user on a given UTC day
78
+ **Props:** `{ email: string }`
79
+
80
+ Throttled notification (once per user per day via `daily_cap_notifications` table). Shows the 1,000-call / $1.00 cap, the midnight UTC reset time, and a link to Enterprise pricing for higher limits. Local features are explicitly noted as unaffected.
81
+
82
+ ## Design system
83
+
84
+ | Token | Value |
85
+ |---|---|
86
+ | Paper (background) | `#F3EADB` |
87
+ | Ink (text) | `#121212` |
88
+ | Accent (CTA, links) | `#8B2E1A` |
89
+ | Muted (secondary text) | `#6B5B4E` |
90
+ | Border | `#D9CEBD` |
91
+
92
+ Fonts: Fraunces italic (headings, loaded via Google Fonts woff2), IBM Plex Sans (body). Web-safe fallbacks: Georgia, Helvetica, Arial.
93
+
94
+ Container: 600px centered, white background, 8px border-radius, parchment outer background. Mobile-responsive via `maxWidth: 600px`.
95
+
96
+ ## Sending integration
97
+
98
+ All sends go through `server/src/lib/email.ts`:
99
+
100
+ ```ts
101
+ await sendEmail("magic-link", { to: email, data: { email, link } });
102
+ ```
103
+
104
+ The function renders the React template to HTML + plain text, then calls SendGrid. If `SENDGRID_API_KEY` is unset or `TESTING=1`, it logs the rendered output to stderr instead.
105
+
106
+ ## Email client compatibility notes
107
+
108
+ - **Gmail**: strips `<style>` blocks in `<head>`. All styles are inline via react-email's built-in inline style props, so Gmail renders correctly.
109
+ - **Outlook (Windows)**: does not support border-radius, box-shadow, or `display: inline-block` on buttons reliably. The CTA button degrades to a plain rectangular block — still functional. The plain-text link below the button ensures access regardless.
110
+ - **Outlook (Windows)**: does not render SVG in `<img>` tags. The logo SVG is embedded inline (not via `<img src="...svg">`), which renders correctly in Gmail and Apple Mail. In Outlook on Windows the inline SVG is ignored; the `aria-label="ashlr"` on the SVG provides accessible fallback text.
111
+ - **Apple Mail**: full support for inline SVG, web fonts, and CSS. All templates render as designed.
112
+ - **Dark mode**: templates use a white card on parchment background. Email clients that invert colors in dark mode (Apple Mail, some Android clients) may adjust the outer background; the inner card remains readable due to explicit background-color declarations on all sections.
113
+ - **Plain-text fallback**: every template exports a `plainText()` function. The SendGrid send includes both `html` and `text` fields, so clients that strip HTML receive the plain-text version.
@@ -0,0 +1,103 @@
1
+ # Embedding Cache Threshold Tuning
2
+
3
+ The ashlr grep cache uses cosine similarity to decide whether a cached result
4
+ is close enough to the current query to be reused. The default threshold is
5
+ `0.68`. This document explains how to tune it for your actual usage patterns.
6
+
7
+ ## Background
8
+
9
+ Every grep routed through `ashlr__grep` logs a calibration record to
10
+ `~/.ashlr/embed-calibration.jsonl`:
11
+
12
+ ```jsonl
13
+ {"ts":"2026-04-25T10:00:00Z","queryHashHex":"a1b2c3d4","topSimilarity":0.82,"hit":true,"contentLength":1400,"threshold":0.68}
14
+ {"ts":"2026-04-25T10:00:01Z","queryHashHex":"e5f6a7b8","topSimilarity":0.61,"hit":false,"contentLength":0,"threshold":0.68}
15
+ ```
16
+
17
+ - `hit: true` — the cached result was served (cosine similarity >= threshold).
18
+ - `hit: false` — the cache was skipped; a fresh ripgrep ran instead.
19
+ - `topSimilarity` — the best cosine score found in the embedding index.
20
+
21
+ After a few hundred grep operations you have enough data to tune the threshold.
22
+
23
+ ## Running the tuner
24
+
25
+ ```sh
26
+ # Report only (no changes written):
27
+ bun run scripts/embed-tune.ts
28
+
29
+ # Custom input file:
30
+ bun run scripts/embed-tune.ts --input ~/.ashlr/embed-calibration.jsonl
31
+
32
+ # Weight precision 2× over recall (penalise false positives harder):
33
+ bun run scripts/embed-tune.ts --weight precision=2
34
+
35
+ # Write recommendation to ~/.ashlr/config.json:
36
+ bun run scripts/embed-tune.ts --apply
37
+ ```
38
+
39
+ Sample output:
40
+
41
+ ```
42
+ ashlr embed-tune report
43
+ ──────────────────────────────────────────────────
44
+ entries analysed : 312
45
+ beta weight : 1 (F1 score)
46
+
47
+ current threshold 0.68 → precision 0.74 recall 0.83 F1 0.78
48
+ recommended 0.71 → precision 0.81 recall 0.79 F1 0.80
49
+
50
+ Set via: ASHLR_EMBED_THRESHOLD=0.71
51
+ Or run with --apply to persist to ~/.ashlr/config.json
52
+ ```
53
+
54
+ ## How it works
55
+
56
+ The tuner sweeps thresholds from `0.50` to `0.95` in `0.01` steps. At each
57
+ step it computes:
58
+
59
+ | Metric | Definition |
60
+ |-----------|------------|
61
+ | precision | % of cache hits that were genuine (hit=true in calibration data) |
62
+ | recall | % of all genuine hits that would still be served from cache |
63
+ | F1 | harmonic mean of precision and recall |
64
+
65
+ The threshold that maximises F1 (or F-beta with `--weight`) is recommended.
66
+
67
+ ### Weighted F-beta
68
+
69
+ Pass `--weight precision=2` to use F2, which weights recall twice as much as
70
+ precision — useful if you want maximum cache utilisation and can tolerate some
71
+ irrelevant results. Pass `--weight precision=0.5` (i.e. F0.5) to prioritise
72
+ precision — useful if false positives cause visible quality regressions.
73
+
74
+ ## Applying the result
75
+
76
+ With `--apply`, the tuner writes `embedThreshold` to `~/.ashlr/config.json`:
77
+
78
+ ```json
79
+ {
80
+ "embedThreshold": 0.71
81
+ }
82
+ ```
83
+
84
+ Then prints: **"Restart Claude Code to apply."**
85
+
86
+ The MCP server reads this value on startup. The `ASHLR_EMBED_THRESHOLD`
87
+ environment variable takes precedence over `config.json` when both are set.
88
+
89
+ ## Minimum corpus size
90
+
91
+ The embedding cache is skipped entirely when the BM25 corpus has fewer than
92
+ 50 documents (`BM25_CORPUS_MIN`). Below this size, IDF weights are noisy and
93
+ cosine similarity scores are unreliable regardless of threshold. Let the corpus
94
+ grow before tuning.
95
+
96
+ ## When to re-tune
97
+
98
+ - After onboarding a new large project (corpus distribution shifts).
99
+ - If you change the embedding model (`ASHLR_EMBED_MODEL`).
100
+ - If you notice grep results that look stale or irrelevant.
101
+
102
+ A rule of thumb: re-tune after every ~500 grep operations, or whenever
103
+ `embed-calibration.jsonl` grows by more than 200 lines since the last run.
package/docs/genome.md ADDED
@@ -0,0 +1,120 @@
1
+ # Genome Auto-Refresh
2
+
3
+ The genome (`.ashlrcode/genome/`) is the RAG index that powers `ashlr__grep`. Without
4
+ updates it drifts from the codebase as you edit files — causing grep to silently fall
5
+ back to ripgrep, which is slower and larger.
6
+
7
+ The auto-refresh pipeline (v1.23 Track HH) keeps the genome current without
8
+ requiring manual intervention.
9
+
10
+ ---
11
+
12
+ ## How the refresh cycle works
13
+
14
+ ```
15
+ User edits file
16
+ │
17
+ ▼
18
+ PostToolUse hook: posttooluse-genome-refresh.ts
19
+ ├─ Extract file path from Edit/Write/MultiEdit/NotebookEdit payload
20
+ ├─ Append absolute path to ~/.ashlr/pending-genome-refresh.txt (deduped)
21
+ └─ Exit 0 immediately (never blocks)
22
+
23
+ │ (multiple edits accumulate, file is appended to)
24
+ │
25
+ ▼ (session ends)
26
+
27
+ SessionEnd hook: session-end-consolidate.ts
28
+ ├─ 1. genome-auto-consolidate.ts — merges proposals.jsonl
29
+ ├─ 2. genome-cloud-push.ts — pushes to team cloud (if configured)
30
+ ├─ 3. genome-refresh-worker.ts — incremental refresh ← NEW
31
+ └─ 4. telemetry-flush.ts — opt-in telemetry
32
+ ```
33
+
34
+ ### Debounce
35
+
36
+ The worker checks the mtime of `pending-genome-refresh.txt`. If it was written within
37
+ the last 2 seconds, processing is deferred (another edit may be in flight). This
38
+ prevents partial refreshes during rapid multi-file sessions. At session end the file is
39
+ always old enough to pass the debounce check.
40
+
41
+ ### Incremental vs. full
42
+
43
+ **Incremental (default):** For each pending file, `_genome-live.refreshGenomeAfterEdit`
44
+ is called. It:
45
+ - Finds genome sections that reference the file (by filename or path)
46
+ - Verbatim sections: patches literal content in-place
47
+ - Summarized sections: invalidates (deletes) them so the propose queue regenerates
48
+
49
+ No LLM calls. Cost is proportional to the number of sections referencing the file.
50
+
51
+ **Full rebuild (`--full`):** Re-runs `genome-init.ts --force --minimal` for each
52
+ affected genome root. Rebuilds from scratch. No LLM summarization unless Ollama is
53
+ running. Use explicitly for schema upgrades or large structural refactors.
54
+
55
+ ---
56
+
57
+ ## Stale detection
58
+
59
+ When `ashlr__grep` finds a genome but gets zero matching sections, it:
60
+ 1. Increments an in-session fallback counter
61
+ 2. Emits a `genome_stale_detected` telemetry event (pattern + fallback count)
62
+ 3. After **3 fallbacks in the same session**, surfaces a one-time nudge:
63
+
64
+ ```
65
+ [ashlr] genome may be stale (3 grep queries fell through to ripgrep).
66
+ Run `bun run scripts/genome-refresh-worker.ts` to refresh, or
67
+ `bun run scripts/genome-refresh-worker.ts --full` for a complete rebuild.
68
+ ```
69
+
70
+ This fires once per session so it doesn't spam repeated queries.
71
+
72
+ ---
73
+
74
+ ## File locations
75
+
76
+ | Path | Purpose |
77
+ |---|---|
78
+ | `~/.ashlr/pending-genome-refresh.txt` | Pending edit paths (one per line, deduped) |
79
+ | `hooks/posttooluse-genome-refresh.ts` | PostToolUse hook — records paths |
80
+ | `scripts/genome-refresh-worker.ts` | Worker — incremental refresh + `--full` mode |
81
+
82
+ ---
83
+
84
+ ## Manual refresh
85
+
86
+ ```bash
87
+ # Incremental: refresh only files edited since last refresh
88
+ bun run scripts/genome-refresh-worker.ts
89
+
90
+ # Dry run: see what would be refreshed
91
+ bun run scripts/genome-refresh-worker.ts --dry-run
92
+
93
+ # Full rebuild (no LLM unless Ollama is running)
94
+ bun run scripts/genome-refresh-worker.ts --full
95
+
96
+ # Full rebuild, dry run
97
+ bun run scripts/genome-refresh-worker.ts --full --dry-run
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Kill switch
103
+
104
+ Set `ASHLR_GENOME_AUTO=0` to disable all genome automation (refresh, proposals,
105
+ consolidation). The pending file will still accumulate but nothing processes it.
106
+
107
+ ---
108
+
109
+ ## Gotchas
110
+
111
+ - **Pending file is cumulative.** If you kill Claude mid-session, the pending file
112
+ persists across the next session start and is processed at the next session end.
113
+ - **Sections not referencing the file by name are not invalidated.** If your genome
114
+ section uses a generic title (e.g. "Overview") with no mention of the filename in
115
+ content/tags/summary, the refresh will miss it. Use descriptive section titles.
116
+ - **`--full` on large repos is slow.** It re-scans the entire project. Run it manually
117
+ only when structural reorganization makes incremental refresh insufficient.
118
+ - **No LLM in the auto path.** The incremental worker never calls an LLM. The only
119
+ LLM-touching path is `genome-init --summarize` (Ollama, opt-in), which is only
120
+ reachable via `--full`.