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,68 @@
1
+ # Session log schema
2
+
3
+ The ashlr session log is a JSONL file at `~/.ashlr/session-log.jsonl`. One
4
+ JSON object per line, one line per tool invocation, append-only, size-
5
+ capped at 10 MB with a cascading backup (`.jsonl.1` → `.jsonl.2`). The
6
+ format is designed to be stable across agents (Codex, Claude Code, Cursor,
7
+ Goose and any future consumer) so downstream tooling can parse it without
8
+ special-casing per-agent quirks.
9
+
10
+ ## Line format
11
+
12
+ Each line is a single JSON object with the following fields:
13
+
14
+ ```json
15
+ {
16
+ "ts": "2026-04-18T22:14:03.127Z",
17
+ "agent": "codex-cli",
18
+ "event": "tool_call",
19
+ "tool": "ashlr__read",
20
+ "cwd": "/Users/me/code/project",
21
+ "session": "sess_abc123",
22
+ "input_size": 240,
23
+ "output_size": 8210
24
+ }
25
+ ```
26
+
27
+ | Field | Type | Notes |
28
+ |----------------|---------|-------|
29
+ | `ts` | string | ISO 8601 UTC timestamp with millisecond precision |
30
+ | `agent` | string | Agent name, such as `"codex-cli"`, `"claude-code"`, `"cursor"`, `"goose"`, or `"generic"` |
31
+ | `event` | string | One of `tool_call`, `tool_fallback`, `tool_error`, `tool_escalate` |
32
+ | `tool` | string | MCP tool name (e.g. `ashlr__read`), or `"unknown"` when the hook can't parse it |
33
+ | `cwd` | string | Absolute path of the agent's working directory at the time of the call |
34
+ | `session` | string | Host session ID when available, or a hashed PPID fallback starting with `h` |
35
+ | `input_size` | number | Byte size of the tool's input payload (JSON-stringified when not already bytes) |
36
+ | `output_size` | number | Byte size of the tool's output payload |
37
+
38
+ ### Event vocabulary
39
+
40
+ - `tool_call` — the default. Tool ran to completion.
41
+ - `tool_fallback` — tool took the fallback path (e.g. genome empty, fell through to raw ripgrep; summarizer unavailable, fell through to head+tail bytes).
42
+ - `tool_error` — tool threw or returned non-zero.
43
+ - `tool_escalate` — tool returned a bypassSummary-style hint that the caller should retry with more context.
44
+
45
+ Consumers that don't know an `event` value should treat it as `tool_call`.
46
+
47
+ ## Rotation
48
+
49
+ - Active file: `~/.ashlr/session-log.jsonl`.
50
+ - Once the active file crosses 10 MB, the next write:
51
+ 1. Renames `.jsonl.1` → `.jsonl.2` if a prior rotation exists (cascade keeps one generation of backup).
52
+ 2. Renames the active file → `.jsonl.1`.
53
+ 3. Starts a fresh active file.
54
+ - Maximum on-disk footprint is therefore ~20 MB (active ≤ 10 MB + one 10 MB backup). `.jsonl.2` is overwritten on the next rotation.
55
+
56
+ ## Reading the log
57
+
58
+ - `bun run scripts/session-log-report.ts` produces a human-readable report covering the active file + any rotated backups.
59
+ - `/ashlr-usage` wraps that report as a Claude Code skill.
60
+ - `ashlr-plugin stats --json` (new in v1.11.0) prints the stats ledger at `~/.ashlr/stats.json` as JSON on stdout — the session log is the raw feed, stats.json is the aggregated view.
61
+
62
+ ## Schema stability
63
+
64
+ This is schema version **1**. Breaking changes add a `schema_version` field at the top of the file (not per-line) and bump the number. Non-breaking additions (new `event` values, new optional fields) don't change the version. Consumers should tolerate unknown fields silently.
65
+
66
+ ## Disabling
67
+
68
+ Set `ASHLR_SESSION_LOG=0` at shell startup to suppress the log entirely. The tools still work; they just don't record.
package/docs/social.md ADDED
@@ -0,0 +1,95 @@
1
+ # Social copy — current ashlr positioning
2
+
3
+ ---
4
+
5
+ ## Twitter (3 variants, 280 char each)
6
+
7
+ **Variant A — lead with the number**
8
+ ```
9
+ −57% token savings on real codebases, measured and reproducible.
10
+
11
+ ashlr is an open-source Codex and Claude Code plugin: 40 MCP tools that replace native Read/Grep/Edit/Bash workflows with compressed alternatives.
12
+
13
+ curl -fsSL https://plugin.ashlr.ai/install.sh | bash
14
+
15
+ Full post: [LINK]
16
+ ```
17
+ (253 chars)
18
+
19
+ **Variant B — lead with the cost angle**
20
+ ```
21
+ Codex and Claude Code token bills add up. ashlr cuts them by 57% on average — open source, MIT, no account.
22
+
23
+ 40 MCP tools. Measured benchmark. Install in 30 seconds.
24
+
25
+ curl -fsSL https://plugin.ashlr.ai/install.sh | bash
26
+
27
+ [LINK]
28
+ ```
29
+ (214 chars)
30
+
31
+ **Variant C — lead with the specific example**
32
+ ```
33
+ Reading a 10,846-byte file in Claude Code costs 2,709 tokens natively.
34
+ ashlr__read returns the same file for 406 tokens. That's an 85% drop.
35
+
36
+ 40 tools. Reproducible benchmark. MIT free.
37
+
38
+ plugin.ashlr.ai
39
+ ```
40
+ (208 chars)
41
+
42
+ ---
43
+
44
+ ## LinkedIn (~1,200 chars)
45
+
46
+ ```
47
+ I shipped the Codex-native ashlr release today — an open-source token-efficiency layer for Codex and Claude Code.
48
+
49
+ The background: Claude Code's native Read, Grep, and Edit tools transmit full file contents and full match output to the model on every call. On a real codebase this adds up fast. A single grep for a common pattern can cost 85,000 tokens of output the model skims and discards. A 15KB file opened to change three lines sends all 15KB.
50
+
51
+ ashlr replaces those tools with compressed alternatives. ashlr__read returns a head+tail snip. ashlr__grep routes through a genome-aware retrieval index. ashlr__edit returns a diff summary instead of echoing the before+after.
52
+
53
+ The numbers from the reproducible multi-repo benchmark:
54
+
55
+ - TypeScript (`vercel/ai`): −62%
56
+ - Python (`pandas`): −65%
57
+ - Rust (`tokio`): −44%
58
+ - Cross-language mean: −57%
59
+
60
+ The plugin is MIT-licensed. The free tier ships 40 MCP tools, 34 Claude Code slash commands, Codex workflow skills, per-session token accounting, and a reproducible benchmark against your own codebase. No account required; telemetry is off by default. Pro adds cloud genome sync and a hosted LLM summarizer for developers who don't want to run Ollama locally.
61
+
62
+ Install: curl -fsSL https://plugin.ashlr.ai/install.sh | bash
63
+
64
+ Full write-up with methodology and the three bugs that surprised me: [LINK]
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Hacker News
70
+
71
+ **Title:**
72
+ ```
73
+ Ashlr – open-source Codex and Claude Code plugin, −57% token savings measured on real codebases
74
+ ```
75
+
76
+ **First comment (from the author):**
77
+
78
+ ```
79
+ Author here.
80
+
81
+ The motivation is straightforward: Claude Code's native Read/Grep/Edit tools ship full payloads — entire file contents, complete grep output — into model context on every call. On a codebase of any real size this wastes a meaningful fraction of every context window.
82
+
83
+ ashlr replaces those three tools with MCP server alternatives that return compressed views: head+tail snip for reads, truncated/genome-aware retrieval for grep, diff summary for edit. The model gets enough context to do the work; the rest doesn't go over the wire.
84
+
85
+ The −57% number is from a reproducible benchmark in scripts/run-benchmark.ts across TypeScript, Python, and Rust reference repos. The full methodology is in docs/benchmarks.md and docs/benchmarks-v2.json. The benchmark is honest about cases where ashlr is worse than native — small edits are guarded in real use because the diff-summary overhead can exceed the edit payload. Medium and large edits compress substantially.
86
+
87
+ A few things worth noting for HN:
88
+
89
+ - The free tier is complete. 40 MCP tools, 34 Claude Code slash commands, Codex workflow skills, MIT license, no account required, telemetry off by default, no feature gates. Pro adds hosted infrastructure (cloud genome sync, hosted LLM summarizer). Nothing in free degrades to push upgrades.
90
+ - Codex packaging is in `.codex-plugin/` and `.mcp.json`; Cursor and Goose ports are in `ports/`. MCP tools run under any compatible host. Claude-only extras remain status line, slash commands, auto redirects, and OAuth bootstrap.
91
+ - Two tests are skipped: a no-genome grep flake that's an environment-leak in the full parallel suite (passes in isolation) and a benchmark ratio assertion with the same root cause. Both documented in-line.
92
+ - The $-interpolation bug in v0.9.2 is worth reading about if you do any string replace work: JavaScript's String.replace(string, string) interprets $& and $` in the replacement. It corrupted multi-edits silently for a while.
93
+
94
+ Happy to answer questions about the genome format, the stats accounting architecture, or the benchmark methodology.
95
+ ```
@@ -0,0 +1,528 @@
1
+ # Team Genome: Sharing a Genome Across a Development Team
2
+
3
+ A single `.ashlrcode/genome/` directory can be committed to your repository and
4
+ shared by every developer on the team. This guide explains how it works, when to
5
+ use it, and how to keep it healthy as the codebase evolves.
6
+
7
+ ---
8
+
9
+ ## What a shared genome does
10
+
11
+ The genome is a pre-summarized retrieval index of your codebase. When the
12
+ ashlr-efficiency server receives a `grep` or `read` call, it first checks whether
13
+ the genome has a relevant section and returns that instead of scanning raw files.
14
+ This cuts token usage by 40-80% on well-indexed repos.
15
+
16
+ When you commit the genome to the repository:
17
+
18
+ - Every developer gets the same index on `git clone` or `git pull`.
19
+ - `ashlr__grep` returns consistent answers regardless of whose machine runs it.
20
+ - Token savings are deterministic per project — the genome ships with cost
21
+ estimates in `manifest.json` that the savings accounting uses.
22
+ - New contributors start saving tokens immediately, without running
23
+ `ashlr-genome-init` themselves.
24
+
25
+ A committed genome also serves as a living architectural digest: reviewers can
26
+ read `sections/*.md` to understand how subsystems fit together before touching
27
+ code.
28
+
29
+ ---
30
+
31
+ ## Repository layout
32
+
33
+ After initialization the genome lives entirely inside `.ashlrcode/`:
34
+
35
+ ```
36
+ .ashlrcode/
37
+ genome/
38
+ manifest.json # index metadata, section checksums, cost estimates
39
+ sections/
40
+ architecture.md
41
+ api-surface.md
42
+ data-models.md
43
+ ... # one file per logical section
44
+ genome-ignore # optional exclusion list (see below)
45
+ ```
46
+
47
+ `proposals.jsonl` is written locally by the scribe hook during a session. It is
48
+ not shared.
49
+
50
+ ---
51
+
52
+ ## Git workflow
53
+
54
+ ### Initial commit
55
+
56
+ After running `/ashlr-genome-init` (or `ashlr__genome_propose` + consolidate) on
57
+ the base branch:
58
+
59
+ ```bash
60
+ git add .ashlrcode/genome/
61
+ git commit -m "chore: add ashlr genome index"
62
+ ```
63
+
64
+ Add this to your project `.gitignore`:
65
+
66
+ ```gitignore
67
+ # ashlr genome — commit the genome itself, ignore local proposals
68
+ .ashlrcode/proposals.jsonl
69
+ .ashlrcode/genome/proposals.jsonl
70
+ ```
71
+
72
+ The `sections/` directory and `manifest.json` should be tracked. They are plain
73
+ markdown and JSON — readable in any diff tool, no binary blobs.
74
+
75
+ ### Keeping it up to date
76
+
77
+ The genome does not auto-update itself in CI. Designate one developer per sprint
78
+ (or add a `make genome-sync` target) to regenerate it when the codebase drifts:
79
+
80
+ ```makefile
81
+ # Makefile
82
+ genome-sync:
83
+ git pull --rebase
84
+ bun run $(ASHLR_PLUGIN_ROOT)/scripts/genome-auto-consolidate.ts
85
+ git add .ashlrcode/genome/
86
+ git commit -m "chore: refresh ashlr genome" || true
87
+ git push
88
+ ```
89
+
90
+ The consolidation script reads accumulated proposals and merges them into
91
+ `sections/*.md`. Run it on a clean working tree so the diff is easy to review.
92
+
93
+ A practical cadence: run `make genome-sync` after any large refactor, and at
94
+ least once per two-week sprint. The genome degrades gracefully — stale sections
95
+ return slightly less precise results but never break tool calls.
96
+
97
+ ---
98
+
99
+ ## Conflict resolution
100
+
101
+ ### How conflicts arise
102
+
103
+ `hooks/genome-scribe-hook.ts` appends to `proposals.jsonl` after each session.
104
+ `scripts/genome-auto-consolidate.ts` applies those proposals to `sections/*.md`
105
+ at session end. Both operations are local-only.
106
+
107
+ If two developers run consolidation on diverged branches and both commit updated
108
+ sections, a standard merge conflict appears in `sections/<name>.md`.
109
+
110
+ ### Resolution strategy
111
+
112
+ Genome sections are prose documents. The last consolidator's version wins — there
113
+ is no semantic merge logic. Resolve conflicts by accepting one side or
114
+ hand-editing to combine the relevant changes, then re-commit.
115
+
116
+ Recommended approach:
117
+
118
+ 1. Pull the remote genome into your branch before consolidating locally.
119
+ 2. Run `genome-auto-consolidate.ts`.
120
+ 3. Commit and push.
121
+
122
+ ```bash
123
+ git pull --rebase origin main
124
+ bun run /path/to/ashlr-plugin/scripts/genome-auto-consolidate.ts
125
+ git add .ashlrcode/genome/
126
+ git commit -m "chore: merge genome"
127
+ git push
128
+ ```
129
+
130
+ If you encounter a conflict during `git pull`:
131
+
132
+ ```bash
133
+ # Accept the remote version (safe default — theirs was already reviewed)
134
+ git checkout --theirs .ashlrcode/genome/sections/architecture.md
135
+ git add .ashlrcode/genome/sections/architecture.md
136
+
137
+ # Then consolidate your local proposals on top
138
+ bun run /path/to/ashlr-plugin/scripts/genome-auto-consolidate.ts
139
+ ```
140
+
141
+ Conflicts in `manifest.json` should always be resolved by regenerating the file
142
+ via consolidation — do not hand-edit checksums.
143
+
144
+ ---
145
+
146
+ ## genome-ignore: excluding files from the index
147
+
148
+ Create `.ashlrcode/genome-ignore` at the repository root. One glob pattern per
149
+ line. The scribe hook skips any source file whose path matches a listed pattern.
150
+
151
+ Example `.ashlrcode/genome-ignore`:
152
+
153
+ ```
154
+ # Never include secrets or credentials
155
+ .env
156
+ .env.*
157
+ secrets/**
158
+ config/credentials.*
159
+ **/*.pem
160
+ **/*.key
161
+
162
+ # Generated files add noise
163
+ dist/**
164
+ build/**
165
+ coverage/**
166
+ *.min.js
167
+ ```
168
+
169
+ Patterns follow the same syntax as `.gitignore`. The ignore file itself should be
170
+ committed so every developer's scribe respects the same exclusions.
171
+
172
+ ---
173
+
174
+ ## When not to share a genome
175
+
176
+ **Small throwaway repositories.** If the project will be deleted or archived
177
+ within a few weeks, the overhead of maintaining a genome is not worth it. Skip
178
+ the commit — developers can generate a local genome on demand.
179
+
180
+ **Secrets risk.** The genome embeds excerpts from source files. Any file that
181
+ contains secrets — API keys, passwords, private keys — must be excluded via
182
+ `genome-ignore` before running the first propose. If a secret is accidentally
183
+ indexed, rotate the secret immediately, remove the section from `sections/`,
184
+ and force-push or use `git filter-repo` to scrub the history.
185
+
186
+ Rule of thumb: if a file would be dangerous to share in a public pull request,
187
+ add it to `genome-ignore` before running `/ashlr-genome-init`.
188
+
189
+ **High-churn monorepos.** If hundreds of files change every day, the genome will
190
+ be stale by the time it lands on other machines. Prefer per-package genomes
191
+ scoped to stable subdirectories, or run `genome-sync` in CI on a nightly schedule
192
+ rather than per-commit.
193
+
194
+ ---
195
+
196
+ ## Bootstrapping a new team member
197
+
198
+ No extra steps are needed beyond the standard clone:
199
+
200
+ ```bash
201
+ git clone https://github.com/your-org/your-repo
202
+ cd your-repo
203
+ bun install # if ashlr-plugin is a dev dependency
204
+ ```
205
+
206
+ The plugin auto-detects `.ashlrcode/genome/` in the current working directory on
207
+ startup. If the genome exists, it is used immediately — no initialization
208
+ required.
209
+
210
+ If the new developer's session generates proposals that improve on the committed
211
+ genome, they can run `genome-auto-consolidate.ts` locally and open a PR with the
212
+ updated sections.
213
+
214
+ ---
215
+
216
+ ## Size considerations
217
+
218
+ A typical genome for a 50,000-line codebase is 200-500 KB. Sections are Markdown
219
+ and compress well in git's object store.
220
+
221
+ Recommended upper bound: **5 MB total** for the `sections/` directory. Beyond
222
+ that, `git clone` and `git pull` times degrade noticeably on slow connections, and
223
+ the retrieval index itself becomes slower to scan.
224
+
225
+ If the genome approaches 5 MB:
226
+
227
+ - Audit `sections/` for redundant or overly verbose entries.
228
+ - Tighten `genome-ignore` to exclude large generated directories.
229
+ - Consider splitting the repo into smaller packages, each with its own genome.
230
+
231
+ Check current size:
232
+
233
+ ```bash
234
+ du -sh .ashlrcode/genome/sections/
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Example: full team workflow end-to-end
240
+
241
+ ```bash
242
+ # Tech lead initializes the genome on main
243
+ cd /path/to/your-repo
244
+ # (in Claude Code with ashlr active)
245
+ # /ashlr-genome-init
246
+ git add .ashlrcode/genome/
247
+ git commit -m "chore: add ashlr genome index"
248
+ git push
249
+
250
+ # Developer clones repo — genome is immediately active
251
+ git clone https://github.com/your-org/your-repo
252
+ cd your-repo
253
+ # ashlr__grep and ashlr__read now use the genome automatically
254
+
255
+ # After a sprint of changes, refresh the genome
256
+ make genome-sync
257
+ # opens a PR with updated sections/*.md
258
+ ```
259
+
260
+ ---
261
+
262
+ ## See also
263
+
264
+ - `docs/architecture.md` — system architecture overview used as a source for the
265
+ genome's architecture section.
266
+ - `/ashlr-genome-init` skill — interactive setup wizard that runs propose +
267
+ consolidate and writes the initial genome.
268
+
269
+ ---
270
+
271
+ ## Backend-hosted genome sync (Pro team tier)
272
+
273
+ Teams on the `team` plan can host the authoritative genome on the ashlr backend
274
+ instead of (or alongside) the git-committed copy. Every developer pulls the
275
+ latest sections at session start and pushes their edits back automatically.
276
+
277
+ ### How to opt in
278
+
279
+ 1. Obtain a `ASHLR_PRO_TOKEN` for your org (set in the team billing dashboard).
280
+ 2. Create a hosted genome:
281
+ ```bash
282
+ curl -X POST https://api.ashlr.ai/genome/init \
283
+ -H "Authorization: Bearer $ASHLR_PRO_TOKEN" \
284
+ -H "Content-Type: application/json" \
285
+ -d '{"orgId":"your-org","repoUrl":"https://github.com/your-org/repo"}'
286
+ # → {"genomeId":"...","cloneToken":"gclone_..."}
287
+ ```
288
+ 3. Export the genome ID in every developer's shell profile or `.env`:
289
+ ```bash
290
+ export ASHLR_TEAM_GENOME_ID=<genomeId>
291
+ export ASHLR_PRO_TOKEN=<token>
292
+ ```
293
+
294
+ From that point on, `session-start.ts` pulls updates automatically and
295
+ `_genome-live.ts` pushes section changes after each `ashlr__edit`.
296
+
297
+ ### Sync flow
298
+
299
+ ```
300
+ Session start
301
+ └─ GET /genome/:id/pull?since=<localSeq>
302
+ └─ returns sections modified since last pull
303
+ └─ writes each section to .ashlrcode/genome/sections/<name>.md
304
+ └─ persists new serverSeqNum to ~/.ashlr/genome-seq.json
305
+
306
+ After ashlr__edit on a genome section
307
+ └─ POST /genome/:id/push { sections:[{path,content,vclock}], clientId }
308
+ └─ server merges vclocks, detects conflicts
309
+ └─ responds { applied:[paths], conflicts:[paths] }
310
+ ```
311
+
312
+ ### Vector-clock merge algorithm
313
+
314
+ Each section carries a vector clock `{ [clientId]: count }`.
315
+
316
+ ```
317
+ mergeVClocks(a, b) → component-wise max of every key in a ∪ b
318
+
319
+ compareVClocks(incoming, stored):
320
+ if incoming[k] >= stored[k] for all k → "dominates" (safe update)
321
+ if stored[k] > incoming[k] for any k
322
+ and incoming[k] < stored[k] for any k → "concurrent" (conflict)
323
+ if stored[k] > incoming[k] for all k → "dominated" (stale push)
324
+ ```
325
+
326
+ Push semantics by relation:
327
+ - **dominates** — section updated, any prior conflict cleared.
328
+ - **concurrent** — both variants stored; conflict surfaced via `GET /conflicts`.
329
+ - **dominated** — incoming is stale; stored value kept, conflict recorded so
330
+ neither version is lost.
331
+
332
+ ### Conflict example
333
+
334
+ Developer A and B both edit `sections/auth.md` from the same base:
335
+
336
+ | Event | Client | vclock stored | vclock incoming | Result |
337
+ |-------|--------|---------------|-----------------|--------|
338
+ | Push A | `ca` | `{}` | `{ca:1}` | applied, stored = `{ca:1}` |
339
+ | Push B | `cb` | `{ca:1}` | `{cb:1}` | concurrent — conflict recorded |
340
+
341
+ B's push has `cb:1` (new to server) but is missing `ca:1` (server has it). Neither
342
+ dominates. Both variants are stored and `GET /genome/:id/conflicts` returns them
343
+ with an `authorHint` so the team can choose the winner via
344
+ `POST /genome/:id/resolve`.
345
+
346
+ ### Conflict resolution
347
+
348
+ ```bash
349
+ # List conflicts
350
+ curl https://api.ashlr.ai/genome/$GENOME_ID/conflicts \
351
+ -H "Authorization: Bearer $ASHLR_PRO_TOKEN"
352
+
353
+ # Resolve — pick the winning content
354
+ curl -X POST https://api.ashlr.ai/genome/$GENOME_ID/resolve \
355
+ -H "Authorization: Bearer $ASHLR_PRO_TOKEN" \
356
+ -H "Content-Type: application/json" \
357
+ -d '{"path":"sections/auth.md","winning":{"content":"...","vclock":{"ca":1,"cb":1}}}'
358
+ ```
359
+
360
+ The `/ashlr-genome-conflicts` skill shows unresolved conflicts with a short diff
361
+ view inside Claude Code. A full CLI resolver is planned for v2.
362
+
363
+ ### Private vs shared genome trade-offs
364
+
365
+ | | Git-committed genome | Backend-hosted genome |
366
+ |--|----------------------|-----------------------|
367
+ | Conflict resolution | Manual merge / PR | CRDT auto-merge |
368
+ | Latency to teammates | Next `git pull` | Next session start (~instant) |
369
+ | Offline support | Full | Pull/push silently skipped |
370
+ | Visibility | Full git history | Push audit log only |
371
+ | Setup complexity | None | Requires `ASHLR_TEAM_GENOME_ID` |
372
+
373
+ For small teams with short PR cycles, the git-committed genome is usually
374
+ sufficient. The hosted sync shines when multiple developers are in active Claude
375
+ Code sessions simultaneously on the same repo.
376
+
377
+ ### Security
378
+
379
+ - All requests are authenticated with a bearer token (`ASHLR_PRO_TOKEN`).
380
+ - Section paths are sanitized server-side: `..`, absolute paths, and `//`
381
+ patterns are rejected with HTTP 400.
382
+ - Content is capped at 1 MB per section.
383
+ - Push calls are rate-limited to 10 sections per minute per client.
384
+ - Every push is written to an audit log (`genome_push_log`) for Phase 4 audit
385
+ trail integration.
386
+ - **Client-side AES-256-GCM encryption is available.** When a team key is
387
+ present at `~/.ashlr/team-keys/<genomeId>.key`, section content is encrypted
388
+ before upload and decrypted after pull. The server stores only ciphertext and
389
+ cannot read section content. See the encryption section below.
390
+
391
+ ---
392
+
393
+ ## Client-side encryption (v1)
394
+
395
+ ### Threat model
396
+
397
+ | Threat | Mitigation |
398
+ |--------|-----------|
399
+ | Server operator reads section content | Ciphertext only on server; key never leaves client machines |
400
+ | Network observer | TLS + client-side encryption (defence-in-depth) |
401
+ | Compromised Redis / S3 / Postgres | Only ciphertext stored; useless without the key |
402
+ | User leaves team | Rotate the key; ex-member cannot decrypt new sections |
403
+ | Tampered ciphertext | AES-256-GCM auth tag — decryption throws on any modification |
404
+
405
+ Vector clock (vclock) metadata is transmitted in plaintext so the server can
406
+ perform conflict detection without decrypting content.
407
+
408
+ ### Algorithm
409
+
410
+ - **AES-256-GCM** with a 256-bit key and a 96-bit (12-byte) random nonce per section push.
411
+ - The 128-bit GCM authentication tag is verified on every decrypt — any tampering throws.
412
+ - Wire format (base64url): `[ version(1 byte) | nonce(12 bytes) | authTag(16 bytes) | ciphertext ]`
413
+
414
+ ### Key setup
415
+
416
+ Generate a team key once and save it locally:
417
+
418
+ ```bash
419
+ bun run scripts/genome-key.ts generate <genomeId>
420
+ # Key saved to ~/.ashlr/team-keys/<genomeId>.key (mode 0600)
421
+ ```
422
+
423
+ Share it with each team member over a secure channel (Signal, 1Password, etc.):
424
+
425
+ ```bash
426
+ # On machine with key:
427
+ bun run scripts/genome-key.ts export <genomeId>
428
+ # Prints base32-encoded key after confirmation prompt
429
+
430
+ # On each team member's machine:
431
+ bun run scripts/genome-key.ts import <genomeId> <BASE32_KEY>
432
+ ```
433
+
434
+ Once the key file exists at `~/.ashlr/team-keys/<genomeId>.key`, every push is
435
+ automatically encrypted and every pull automatically decrypted. No other
436
+ configuration is needed.
437
+
438
+ ### Key file location and permissions
439
+
440
+ ```
441
+ ~/.ashlr/team-keys/<genomeId>.key — 32 raw bytes, mode 0600 (owner read/write only)
442
+ ```
443
+
444
+ The file is never logged, never included in git, and never transmitted to the
445
+ server. It lives only on developer machines.
446
+
447
+ ### Key rotation
448
+
449
+ When a team member leaves or a key may be compromised, rotate the key. This
450
+ re-encrypts all sections on the server with a new key:
451
+
452
+ ```bash
453
+ bun run scripts/genome-key.ts rotate <genomeId>
454
+ ```
455
+
456
+ The rotate command:
457
+ 1. Pulls all sections from the remote.
458
+ 2. Decrypts each with the current key.
459
+ 3. Generates a new 32-byte key.
460
+ 4. Re-encrypts all sections with the new key and pushes them.
461
+ 5. Saves the new key file locally.
462
+
463
+ After rotation, distribute the new key to all remaining team members:
464
+
465
+ ```bash
466
+ bun run scripts/genome-key.ts export <genomeId>
467
+ ```
468
+
469
+ Members who do not receive the new key will see a warning on pull and their
470
+ local copy of those sections will not be updated until they import the new key.
471
+
472
+ ### Enforcing encryption org-wide
473
+
474
+ Org admins can mark a genome as requiring encryption. Pushes from clients
475
+ without a key (plaintext content) will be rejected with HTTP 422:
476
+
477
+ ```bash
478
+ curl -X PATCH https://api.ashlr.ai/genome/$GENOME_ID/settings \
479
+ -H "Authorization: Bearer $ASHLR_PRO_TOKEN" \
480
+ -H "Content-Type: application/json" \
481
+ -d '{"encryption_required": true}'
482
+ ```
483
+
484
+ ### Backward compatibility
485
+
486
+ The server stores a `content_encrypted` boolean per section. Existing plaintext
487
+ sections remain readable by old clients without keys. Mixed teams (some members
488
+ with keys, some without) are supported — members without a key simply cannot
489
+ read encrypted sections. `encryption_required=true` enforces a clean cutover.
490
+
491
+ ### Migration from plaintext to encrypted
492
+
493
+ For an existing team genome that has been syncing in plaintext:
494
+
495
+ 1. Generate and distribute a key to all team members (see Key setup above).
496
+ 2. Run `bun run scripts/genome-key.ts rotate <genomeId>` — this re-encrypts
497
+ all existing plaintext sections on the server.
498
+ 3. Optionally set `encryption_required: true` to prevent future plaintext pushes.
499
+
500
+ ---
501
+
502
+ ## Multi-user encryption model (v2, not yet shipped)
503
+
504
+ The v1 model uses a single shared symmetric key. This is simple but requires
505
+ out-of-band key distribution and a full rotate when any member leaves.
506
+
507
+ The v2 model uses asymmetric key wrapping (X25519 / HKDF):
508
+
509
+ 1. **Each member** generates an X25519 keypair. The public key is registered
510
+ with the genome on the server.
511
+ 2. **The genome** has one symmetric data-encryption key (DEK), the same
512
+ AES-256-GCM key used in v1.
513
+ 3. **Key envelopes**: the DEK is encrypted once per member using that member's
514
+ X25519 public key (via ECDH + HKDF). The server stores the envelope set:
515
+ `{ memberId → encrypt(memberPublicKey, DEK) }`.
516
+ 4. **Adding a member**: admin fetches the DEK (decrypts with their own
517
+ envelope), re-wraps it to the new member's public key, pushes a new
518
+ envelope. No re-encryption of section content needed.
519
+ 5. **Removing a member**: admin removes the member's envelope and rotates the
520
+ DEK (same as v1 rotate, but the new DEK is then wrapped for all remaining
521
+ members). The removed member's envelope is gone; they cannot decrypt the
522
+ new DEK.
523
+ 6. **Decryption on pull**: client fetches its envelope, decrypts the DEK, then
524
+ decrypts sections exactly as in v1.
525
+
526
+ Migration from v1 to v2 is non-breaking: the section wire format and
527
+ `serializeBlob` encoding are unchanged. Only key delivery changes.
528
+