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,140 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * sessionstart-brief.ts — SessionStart hook that injects the active
4
+ * ashlr-brief level's ruleset into the session's additionalContext.
5
+ *
6
+ * Reads, in order of precedence:
7
+ * 1. <repo-root>/.ashlr/brief.json — project-level (Pro-enforced)
8
+ * 2. ~/.ashlr/brief.json — user-level
9
+ *
10
+ * Active levels: "lite" | "standard" | "concise"
11
+ * Inactive level: "off" (or missing file) — emits no additionalContext.
12
+ *
13
+ * Hook contract (SessionStart):
14
+ * stdout → { hookSpecificOutput: { hookEventName: "SessionStart",
15
+ * additionalContext?: string } }
16
+ *
17
+ * Design rules:
18
+ * - Never throw — passes through silently on any error.
19
+ * - The additionalContext is short (<500 bytes) so it doesn't bloat
20
+ * every session that has brief enabled.
21
+ * - Always exits 0.
22
+ */
23
+
24
+ import { existsSync, readFileSync } from "fs";
25
+ import { homedir } from "os";
26
+ import { join } from "path";
27
+
28
+ import { noteHookError } from "./_hook-errors";
29
+
30
+ interface BriefConfig {
31
+ level?: "off" | "lite" | "standard" | "concise";
32
+ source?: "user" | "project";
33
+ setAt?: string;
34
+ writtenBy?: string;
35
+ }
36
+
37
+ interface HookOutput {
38
+ hookSpecificOutput: {
39
+ hookEventName: "SessionStart";
40
+ additionalContext?: string;
41
+ };
42
+ }
43
+
44
+ function safeReadJson(path: string): BriefConfig | null {
45
+ if (!existsSync(path)) return null;
46
+ try {
47
+ return JSON.parse(readFileSync(path, "utf-8")) as BriefConfig;
48
+ } catch (e) {
49
+ noteHookError("sessionstart-brief", `parse:${path}`, e);
50
+ return null;
51
+ }
52
+ }
53
+
54
+ /** Find the repo root by walking up from cwd looking for .git or package.json. */
55
+ function findRepoRoot(start: string): string | null {
56
+ let cur = start;
57
+ for (let i = 0; i < 10; i++) {
58
+ if (existsSync(join(cur, ".git")) || existsSync(join(cur, "package.json"))) return cur;
59
+ const parent = join(cur, "..");
60
+ if (parent === cur) return null;
61
+ cur = parent;
62
+ }
63
+ return null;
64
+ }
65
+
66
+ function home(): string {
67
+ return process.env.HOME ?? homedir();
68
+ }
69
+
70
+ /** Resolve the active level: project file wins over user file when present. */
71
+ export function resolveActiveLevel(opts?: { homeDir?: string; cwd?: string }): {
72
+ level: "off" | "lite" | "standard" | "concise";
73
+ source: "user" | "project" | "none";
74
+ } {
75
+ const h = opts?.homeDir ?? home();
76
+ const cwd = opts?.cwd ?? process.cwd();
77
+
78
+ // 1. Project file (when in a repo)
79
+ const repoRoot = findRepoRoot(cwd);
80
+ if (repoRoot) {
81
+ const projectCfg = safeReadJson(join(repoRoot, ".ashlr", "brief.json"));
82
+ if (projectCfg && projectCfg.level && projectCfg.level !== "off") {
83
+ return { level: projectCfg.level, source: "project" };
84
+ }
85
+ }
86
+
87
+ // 2. User file
88
+ const userCfg = safeReadJson(join(h, ".ashlr", "brief.json"));
89
+ if (userCfg && userCfg.level && userCfg.level !== "off") {
90
+ return { level: userCfg.level, source: "user" };
91
+ }
92
+
93
+ // 3. Eco-mode fallback — when ASHLR_ECO=1 and no explicit brief level, default
94
+ // to "standard". This is the integration point with /ashlr-eco-mode.
95
+ if (process.env["ASHLR_ECO"] === "1" && (!userCfg || userCfg.level == null || userCfg.level === "off")) {
96
+ return { level: "standard", source: "user" };
97
+ }
98
+
99
+ return { level: "off", source: "none" };
100
+ }
101
+
102
+ const RULESETS: Record<"lite" | "standard" | "concise", string> = {
103
+ lite:
104
+ `[ashlr-brief: lite] Trim filler from prose. Drop "just", "really", "basically", "actually", "simply", "in order to" (use "to"), "due to the fact that" (use "because"). Drop self-narration ("Let me look at...", "I'll now..."). Keep: full grammar, articles, complete sentences, all explanations the user asked for, code blocks, error messages, destructive-action confirmations.`,
105
+ standard:
106
+ `[ashlr-brief: standard] Drop filler AND padding. Cut transition phrases ("Now that we have X, let's...", "As you can see"), restating-the-question preambles, and "Here's what I did:" lists when the diff already shows it. Replace verbose constructions with short ones. Keep: complete sentences, articles, code blocks untouched, errors verbatim, destructive-action confirmations in full grammar.`,
107
+ concise:
108
+ `[ashlr-brief: concise] Drop filler, padding, and most articles. Sentence fragments OK when meaning is clear. Arrow notation for causality ("X → Y"). Common abbreviations OK in prose only (db, auth, cfg, req, res, fn, ctx). NEVER abbreviate identifiers, file paths, function names, or render error messages compressed. Keep: code blocks untouched, destructive-action confirmations in full grammar, security findings in full grammar, multi-step migrations in full grammar.`,
109
+ };
110
+
111
+ const COMMON_RULES =
112
+ `Auto-clarity exceptions (always restore full grammar): destructive actions (rm -rf, git reset --hard, force-push, DROP TABLE, deleting branches), security findings (credentials, secrets, vulnerabilities), multi-step migrations, error messages and stack traces, code blocks and diffs, file:line citations.`;
113
+
114
+ export function buildAdditionalContext(level: "off" | "lite" | "standard" | "concise", source: "user" | "project" | "none"): string {
115
+ if (level === "off") return "";
116
+ const ruleset = RULESETS[level];
117
+ const sourceLabel = source === "project" ? "project-level (.ashlr/brief.json)" : "user-level (~/.ashlr/brief.json)";
118
+ return `${ruleset}\n\n${COMMON_RULES}\n\nActive source: ${sourceLabel}. Toggle via /ashlr-brief off.`;
119
+ }
120
+
121
+ async function main(): Promise<void> {
122
+ try {
123
+ const { level, source } = resolveActiveLevel();
124
+ const out: HookOutput = {
125
+ hookSpecificOutput: {
126
+ hookEventName: "SessionStart",
127
+ ...(level !== "off" ? { additionalContext: buildAdditionalContext(level, source) } : {}),
128
+ },
129
+ };
130
+ process.stdout.write(JSON.stringify(out));
131
+ } catch (e) {
132
+ noteHookError("sessionstart-brief", "main", e);
133
+ // Pass-through on any error.
134
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart" } }));
135
+ }
136
+ }
137
+
138
+ if (import.meta.main) {
139
+ void main();
140
+ }
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * sessionstart-cost-refactor.ts — SessionStart hook for the ashlr-cost-refactor skill.
4
+ *
5
+ * Injects the ashlr-cost-refactor ruleset as additionalContext when
6
+ * ~/.ashlr/cost-refactor.json { "enabled": true } (or project-level .ashlr/cost-refactor.json).
7
+ *
8
+ * Contract: never throws, always exits 0.
9
+ */
10
+
11
+ import { existsSync, readFileSync } from "fs";
12
+ import { homedir } from "os";
13
+ import { join } from "path";
14
+
15
+ import { noteHookError } from "./_hook-errors";
16
+
17
+ interface SkillConfig {
18
+ enabled?: boolean;
19
+ }
20
+
21
+ interface HookOutput {
22
+ hookSpecificOutput: {
23
+ hookEventName: "SessionStart";
24
+ additionalContext?: string;
25
+ };
26
+ }
27
+
28
+ const SKILL_KEY = "cost-refactor";
29
+
30
+ const RULESET = `[ashlr-cost-refactor] Token-efficient refactoring discipline active.
31
+ 1. Diff first: run ashlr__diff or ashlr__diff_semantic before editing anything.
32
+ 2. Use ashlr__edit_structural for symbol/file renames (finds all refs in one pass).
33
+ 3. Find all refs with ashlr__grep, then apply all changes to each file in a single ashlr__multi_edit call.
34
+ 4. No re-reads between edits in a sequence — ashlr__edit/multi_edit diffs confirm each change.
35
+ 5. Verify with ashlr__bash (typecheck/tests), not Read.
36
+ 6. One ashlr__genome_propose at the end summarizing the full refactor.`;
37
+
38
+ function safeReadJson(path: string): SkillConfig | null {
39
+ if (!existsSync(path)) return null;
40
+ try {
41
+ return JSON.parse(readFileSync(path, "utf-8")) as SkillConfig;
42
+ } catch (e) {
43
+ noteHookError(`sessionstart-${SKILL_KEY}`, `parse:${path}`, e);
44
+ return null;
45
+ }
46
+ }
47
+
48
+ function findRepoRoot(start: string): string | null {
49
+ let cur = start;
50
+ for (let i = 0; i < 10; i++) {
51
+ if (existsSync(join(cur, ".git")) || existsSync(join(cur, "package.json"))) return cur;
52
+ const parent = join(cur, "..");
53
+ if (parent === cur) return null;
54
+ cur = parent;
55
+ }
56
+ return null;
57
+ }
58
+
59
+ export function isEnabled(opts?: { homeDir?: string; cwd?: string }): boolean {
60
+ const h = opts?.homeDir ?? (process.env.HOME ?? homedir());
61
+ const cwd = opts?.cwd ?? process.cwd();
62
+
63
+ const repoRoot = findRepoRoot(cwd);
64
+ if (repoRoot) {
65
+ const cfg = safeReadJson(join(repoRoot, ".ashlr", `${SKILL_KEY}.json`));
66
+ if (cfg !== null) return cfg.enabled === true;
67
+ }
68
+
69
+ const userCfg = safeReadJson(join(h, ".ashlr", `${SKILL_KEY}.json`));
70
+ return userCfg?.enabled === true;
71
+ }
72
+
73
+ export function buildAdditionalContext(): string {
74
+ return RULESET;
75
+ }
76
+
77
+ async function main(): Promise<void> {
78
+ try {
79
+ const enabled = isEnabled();
80
+ const out: HookOutput = {
81
+ hookSpecificOutput: {
82
+ hookEventName: "SessionStart",
83
+ ...(enabled ? { additionalContext: buildAdditionalContext() } : {}),
84
+ },
85
+ };
86
+ process.stdout.write(JSON.stringify(out));
87
+ } catch (e) {
88
+ noteHookError(`sessionstart-${SKILL_KEY}`, "main", e);
89
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart" } }));
90
+ }
91
+ }
92
+
93
+ if (import.meta.main) {
94
+ void main();
95
+ }
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * sessionstart-efficient.ts — SessionStart hook for the ashlr-efficient output style.
4
+ *
5
+ * Injects the ashlr-efficient ruleset as additionalContext when
6
+ * ~/.ashlr/efficient.json { "enabled": true } (or project-level .ashlr/efficient.json).
7
+ *
8
+ * When BOTH ashlr-brief and ashlr-efficient are active, emits a merged block
9
+ * noting that both rulesets apply.
10
+ *
11
+ * Contract: never throws, always exits 0.
12
+ */
13
+
14
+ import { existsSync, readFileSync } from "fs";
15
+ import { homedir } from "os";
16
+ import { join } from "path";
17
+
18
+ import { noteHookError } from "./_hook-errors";
19
+ import { resolveActiveLevel } from "./sessionstart-brief";
20
+
21
+ interface SkillConfig {
22
+ enabled?: boolean;
23
+ }
24
+
25
+ interface BriefConfig {
26
+ level?: string;
27
+ }
28
+
29
+ interface HookOutput {
30
+ hookSpecificOutput: {
31
+ hookEventName: "SessionStart";
32
+ additionalContext?: string;
33
+ };
34
+ }
35
+
36
+ const SKILL_KEY = "efficient";
37
+
38
+ const EFFICIENT_RULESET = `[ashlr-efficient] Output structure rules active.
39
+ 1. Inverted pyramid: lead with the answer, then context/explanation.
40
+ 2. Inline code for all identifiers, paths, CLI commands, and config keys.
41
+ 3. Tables for 3+ item comparisons (not bulleted prose lists).
42
+ 4. No transitional filler: drop "Now that we have X", "As mentioned above", "Moving on to", "Let's now", "With that in mind".
43
+ 5. file:line citations instead of quoted blocks (quote only when exact text is load-bearing).`;
44
+
45
+ const COMBINED_RULESET = `[ashlr-brief + ashlr-efficient] Both output-shaping rulesets are active simultaneously.
46
+ ashlr-brief: reduces prose volume (drops filler words, padding, restating-the-question preambles).
47
+ ashlr-efficient: reshapes structure (answer-first, inline code for identifiers, tables for 3+ comparisons, no transitional filler, file:line citations).
48
+ Auto-clarity exceptions (both suspended): destructive actions, security findings, error messages/stack traces, multi-step migrations, code blocks/diffs.`;
49
+
50
+ function safeReadJson<T>(path: string): T | null {
51
+ if (!existsSync(path)) return null;
52
+ try {
53
+ return JSON.parse(readFileSync(path, "utf-8")) as T;
54
+ } catch (e) {
55
+ noteHookError(`sessionstart-${SKILL_KEY}`, `parse:${path}`, e);
56
+ return null;
57
+ }
58
+ }
59
+
60
+ function findRepoRoot(start: string): string | null {
61
+ let cur = start;
62
+ for (let i = 0; i < 10; i++) {
63
+ if (existsSync(join(cur, ".git")) || existsSync(join(cur, "package.json"))) return cur;
64
+ const parent = join(cur, "..");
65
+ if (parent === cur) return null;
66
+ cur = parent;
67
+ }
68
+ return null;
69
+ }
70
+
71
+ export function isEnabled(opts?: { homeDir?: string; cwd?: string }): boolean {
72
+ const h = opts?.homeDir ?? (process.env.HOME ?? homedir());
73
+ const cwd = opts?.cwd ?? process.cwd();
74
+
75
+ const repoRoot = findRepoRoot(cwd);
76
+ if (repoRoot) {
77
+ const cfg = safeReadJson<SkillConfig>(join(repoRoot, ".ashlr", `${SKILL_KEY}.json`));
78
+ if (cfg !== null) return cfg.enabled === true;
79
+ }
80
+
81
+ const userCfg = safeReadJson<SkillConfig>(join(h, ".ashlr", `${SKILL_KEY}.json`));
82
+ return userCfg?.enabled === true;
83
+ }
84
+
85
+ /** Returns the context string. Detects if ashlr-brief is also active and merges. */
86
+ export function buildAdditionalContext(opts?: { homeDir?: string; cwd?: string }): string {
87
+ const { level } = resolveActiveLevel(opts);
88
+ const briefActive = level !== "off";
89
+ return briefActive ? COMBINED_RULESET : EFFICIENT_RULESET;
90
+ }
91
+
92
+ async function main(): Promise<void> {
93
+ try {
94
+ const enabled = isEnabled();
95
+ const out: HookOutput = {
96
+ hookSpecificOutput: {
97
+ hookEventName: "SessionStart",
98
+ ...(enabled ? { additionalContext: buildAdditionalContext() } : {}),
99
+ },
100
+ };
101
+ process.stdout.write(JSON.stringify(out));
102
+ } catch (e) {
103
+ noteHookError(`sessionstart-${SKILL_KEY}`, "main", e);
104
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart" } }));
105
+ }
106
+ }
107
+
108
+ if (import.meta.main) {
109
+ void main();
110
+ }
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * sessionstart-genome-author.ts — SessionStart hook for the ashlr-genome-author skill.
4
+ *
5
+ * Injects the ashlr-genome-author ruleset as additionalContext when
6
+ * ~/.ashlr/genome-author.json { "enabled": true } (or project-level .ashlr/genome-author.json).
7
+ *
8
+ * Contract: never throws, always exits 0.
9
+ */
10
+
11
+ import { existsSync, readFileSync } from "fs";
12
+ import { homedir } from "os";
13
+ import { join } from "path";
14
+
15
+ import { noteHookError } from "./_hook-errors";
16
+
17
+ interface SkillConfig {
18
+ enabled?: boolean;
19
+ }
20
+
21
+ interface HookOutput {
22
+ hookSpecificOutput: {
23
+ hookEventName: "SessionStart";
24
+ additionalContext?: string;
25
+ };
26
+ }
27
+
28
+ const SKILL_KEY = "genome-author";
29
+
30
+ const RULESET = `[ashlr-genome-author] Genome proposal discipline active.
31
+ Call ashlr__genome_propose AFTER: new module added, schema change, auth/security change, routing change, or architectural decision.
32
+ Summary format: 2–5 sentences, past tense, ending with affected file paths.
33
+ Do NOT propose for: routine edits, typo fixes, test updates, mid-refactor (wait until stable), or more than once per logical change.
34
+ Use existing manifest section names where possible; introduce new names only for genuinely new architectural concepts.`;
35
+
36
+ function safeReadJson(path: string): SkillConfig | null {
37
+ if (!existsSync(path)) return null;
38
+ try {
39
+ return JSON.parse(readFileSync(path, "utf-8")) as SkillConfig;
40
+ } catch (e) {
41
+ noteHookError(`sessionstart-${SKILL_KEY}`, `parse:${path}`, e);
42
+ return null;
43
+ }
44
+ }
45
+
46
+ function findRepoRoot(start: string): string | null {
47
+ let cur = start;
48
+ for (let i = 0; i < 10; i++) {
49
+ if (existsSync(join(cur, ".git")) || existsSync(join(cur, "package.json"))) return cur;
50
+ const parent = join(cur, "..");
51
+ if (parent === cur) return null;
52
+ cur = parent;
53
+ }
54
+ return null;
55
+ }
56
+
57
+ export function isEnabled(opts?: { homeDir?: string; cwd?: string }): boolean {
58
+ const h = opts?.homeDir ?? (process.env.HOME ?? homedir());
59
+ const cwd = opts?.cwd ?? process.cwd();
60
+
61
+ const repoRoot = findRepoRoot(cwd);
62
+ if (repoRoot) {
63
+ const cfg = safeReadJson(join(repoRoot, ".ashlr", `${SKILL_KEY}.json`));
64
+ if (cfg !== null) return cfg.enabled === true;
65
+ }
66
+
67
+ const userCfg = safeReadJson(join(h, ".ashlr", `${SKILL_KEY}.json`));
68
+ return userCfg?.enabled === true;
69
+ }
70
+
71
+ export function buildAdditionalContext(): string {
72
+ return RULESET;
73
+ }
74
+
75
+ async function main(): Promise<void> {
76
+ try {
77
+ const enabled = isEnabled();
78
+ const out: HookOutput = {
79
+ hookSpecificOutput: {
80
+ hookEventName: "SessionStart",
81
+ ...(enabled ? { additionalContext: buildAdditionalContext() } : {}),
82
+ },
83
+ };
84
+ process.stdout.write(JSON.stringify(out));
85
+ } catch (e) {
86
+ noteHookError(`sessionstart-${SKILL_KEY}`, "main", e);
87
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart" } }));
88
+ }
89
+ }
90
+
91
+ if (import.meta.main) {
92
+ void main();
93
+ }
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * sessionstart-lean-tools.ts — SessionStart hook for the ashlr-lean-tools skill.
4
+ *
5
+ * Injects the ashlr-lean-tools ruleset as additionalContext when
6
+ * ~/.ashlr/lean-tools.json { "enabled": true } (or project-level .ashlr/lean-tools.json).
7
+ *
8
+ * Contract: never throws, always exits 0.
9
+ */
10
+
11
+ import { existsSync, readFileSync } from "fs";
12
+ import { homedir } from "os";
13
+ import { join } from "path";
14
+
15
+ import { noteHookError } from "./_hook-errors";
16
+
17
+ interface SkillConfig {
18
+ enabled?: boolean;
19
+ }
20
+
21
+ interface HookOutput {
22
+ hookSpecificOutput: {
23
+ hookEventName: "SessionStart";
24
+ additionalContext?: string;
25
+ };
26
+ }
27
+
28
+ const SKILL_KEY = "lean-tools";
29
+
30
+ const RULESET = `[ashlr-lean-tools] Highest-impact token-saving habits active.
31
+ 1. Read-once: do not re-read a file already in context (it hasn't changed).
32
+ 2. Batch edits: use ashlr__multi_edit for 2+ edits to the same file.
33
+ 3. Orient before searching: run ashlr__orient once per task before any grep/glob.
34
+ 4. Skip verification reads: ashlr__edit and ashlr__write return a diff — do not re-read to confirm.
35
+ 5. Grep-before-read: run ashlr__grep first; open the file only if you need more than what grep returned.
36
+ 6. Shift to concise output when session spend is high (>5,000 tool-output tokens): file:line citations over quoted blocks, skip preamble.
37
+ 7. Use ashlr__bash over native Bash for verbose commands (test runners, git log, find).`;
38
+
39
+ function safeReadJson(path: string): SkillConfig | null {
40
+ if (!existsSync(path)) return null;
41
+ try {
42
+ return JSON.parse(readFileSync(path, "utf-8")) as SkillConfig;
43
+ } catch (e) {
44
+ noteHookError(`sessionstart-${SKILL_KEY}`, `parse:${path}`, e);
45
+ return null;
46
+ }
47
+ }
48
+
49
+ function findRepoRoot(start: string): string | null {
50
+ let cur = start;
51
+ for (let i = 0; i < 10; i++) {
52
+ if (existsSync(join(cur, ".git")) || existsSync(join(cur, "package.json"))) return cur;
53
+ const parent = join(cur, "..");
54
+ if (parent === cur) return null;
55
+ cur = parent;
56
+ }
57
+ return null;
58
+ }
59
+
60
+ export function isEnabled(opts?: { homeDir?: string; cwd?: string }): boolean {
61
+ const h = opts?.homeDir ?? (process.env.HOME ?? homedir());
62
+ const cwd = opts?.cwd ?? process.cwd();
63
+
64
+ // Project-level wins.
65
+ const repoRoot = findRepoRoot(cwd);
66
+ if (repoRoot) {
67
+ const cfg = safeReadJson(join(repoRoot, ".ashlr", `${SKILL_KEY}.json`));
68
+ if (cfg !== null) return cfg.enabled === true;
69
+ }
70
+
71
+ // User-level.
72
+ const userCfg = safeReadJson(join(h, ".ashlr", `${SKILL_KEY}.json`));
73
+ return userCfg?.enabled === true;
74
+ }
75
+
76
+ export function buildAdditionalContext(): string {
77
+ return RULESET;
78
+ }
79
+
80
+ async function main(): Promise<void> {
81
+ try {
82
+ const enabled = isEnabled();
83
+ const out: HookOutput = {
84
+ hookSpecificOutput: {
85
+ hookEventName: "SessionStart",
86
+ ...(enabled ? { additionalContext: buildAdditionalContext() } : {}),
87
+ },
88
+ };
89
+ process.stdout.write(JSON.stringify(out));
90
+ } catch (e) {
91
+ noteHookError(`sessionstart-${SKILL_KEY}`, "main", e);
92
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart" } }));
93
+ }
94
+ }
95
+
96
+ if (import.meta.main) {
97
+ void main();
98
+ }
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * sessionstart-search.ts — SessionStart hook for the ashlr-search skill.
4
+ *
5
+ * Injects the ashlr-search ruleset as additionalContext when
6
+ * ~/.ashlr/search.json { "enabled": true } (or project-level .ashlr/search.json).
7
+ *
8
+ * Contract: never throws, always exits 0.
9
+ */
10
+
11
+ import { existsSync, readFileSync } from "fs";
12
+ import { homedir } from "os";
13
+ import { join } from "path";
14
+
15
+ import { noteHookError } from "./_hook-errors";
16
+
17
+ interface SkillConfig {
18
+ enabled?: boolean;
19
+ }
20
+
21
+ interface HookOutput {
22
+ hookSpecificOutput: {
23
+ hookEventName: "SessionStart";
24
+ additionalContext?: string;
25
+ };
26
+ }
27
+
28
+ const SKILL_KEY = "search";
29
+
30
+ const RULESET = `[ashlr-search] Genome-aware search habits active.
31
+ 1. Run ashlr__orient once per task before any grep or glob.
32
+ 2. Use ashlr__grep instead of native Grep — genome-aware, 70–90% lower token cost.
33
+ 3. Use ashlr__glob instead of native Glob.
34
+ 4. Compose multi-term queries with | alternation (one call beats three).
35
+ 5. Trust genome section summaries — do NOT open the referenced file unless you need exact line content for an edit.
36
+ 6. Do not re-search patterns already in context.`;
37
+
38
+ function safeReadJson(path: string): SkillConfig | null {
39
+ if (!existsSync(path)) return null;
40
+ try {
41
+ return JSON.parse(readFileSync(path, "utf-8")) as SkillConfig;
42
+ } catch (e) {
43
+ noteHookError(`sessionstart-${SKILL_KEY}`, `parse:${path}`, e);
44
+ return null;
45
+ }
46
+ }
47
+
48
+ function findRepoRoot(start: string): string | null {
49
+ let cur = start;
50
+ for (let i = 0; i < 10; i++) {
51
+ if (existsSync(join(cur, ".git")) || existsSync(join(cur, "package.json"))) return cur;
52
+ const parent = join(cur, "..");
53
+ if (parent === cur) return null;
54
+ cur = parent;
55
+ }
56
+ return null;
57
+ }
58
+
59
+ export function isEnabled(opts?: { homeDir?: string; cwd?: string }): boolean {
60
+ const h = opts?.homeDir ?? (process.env.HOME ?? homedir());
61
+ const cwd = opts?.cwd ?? process.cwd();
62
+
63
+ // Project-level wins.
64
+ const repoRoot = findRepoRoot(cwd);
65
+ if (repoRoot) {
66
+ const cfg = safeReadJson(join(repoRoot, ".ashlr", `${SKILL_KEY}.json`));
67
+ if (cfg !== null) return cfg.enabled === true;
68
+ }
69
+
70
+ // User-level.
71
+ const userCfg = safeReadJson(join(h, ".ashlr", `${SKILL_KEY}.json`));
72
+ return userCfg?.enabled === true;
73
+ }
74
+
75
+ export function buildAdditionalContext(): string {
76
+ return RULESET;
77
+ }
78
+
79
+ async function main(): Promise<void> {
80
+ try {
81
+ const enabled = isEnabled();
82
+ const out: HookOutput = {
83
+ hookSpecificOutput: {
84
+ hookEventName: "SessionStart",
85
+ ...(enabled ? { additionalContext: buildAdditionalContext() } : {}),
86
+ },
87
+ };
88
+ process.stdout.write(JSON.stringify(out));
89
+ } catch (e) {
90
+ noteHookError(`sessionstart-${SKILL_KEY}`, "main", e);
91
+ process.stdout.write(JSON.stringify({ hookSpecificOutput: { hookEventName: "SessionStart" } }));
92
+ }
93
+ }
94
+
95
+ if (import.meta.main) {
96
+ void main();
97
+ }