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.
- package/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +39 -0
- package/.claude-plugin/plugin.json +36 -0
- package/.codex/agents/README.md +9 -0
- package/.codex/agents/ashlr-explorer.md +36 -0
- package/.codex/agents/ashlr-worker.md +38 -0
- package/.codex-plugin/plugin.json +45 -0
- package/.mcp.json +14 -0
- package/LICENSE +21 -0
- package/README.md +311 -0
- package/agents/ashlr-code.md +69 -0
- package/agents/ashlr-explore.md +44 -0
- package/agents/ashlr-plan.md +54 -0
- package/bench/fixtures/notebook-large.ipynb +660 -0
- package/bench/fixtures/notebook-small.ipynb +39 -0
- package/bench/fixtures/tasklist-closed.json +62 -0
- package/bench/fixtures/tasklist-large-mixed.json +27 -0
- package/bench/fixtures/tasklist-sprint-open.json +79 -0
- package/bench/fixtures/websearch-bun-runtime.json +32 -0
- package/bench/fixtures/websearch-react-hooks-patterns.json +32 -0
- package/bench/fixtures/websearch-typescript-generics.json +38 -0
- package/bench/refs/node-sdk/.refrev +1 -0
- package/bench/refs/node-sdk/README.md +17 -0
- package/bench/refs/node-sdk/src/agent/agent.ts +163 -0
- package/bench/refs/node-sdk/src/agent/create-agent-ui-stream.ts +83 -0
- package/bench/refs/node-sdk/src/agent/tool-loop-agent.ts +238 -0
- package/bench/refs/node-sdk/src/embed/embed-many.ts +409 -0
- package/bench/refs/node-sdk/src/embed/embed-result.ts +50 -0
- package/bench/refs/node-sdk/src/embed/embed.ts +257 -0
- package/bench/refs/node-sdk/src/error/invalid-argument-error.ts +34 -0
- package/bench/refs/node-sdk/src/error/invalid-tool-input-error.ts +33 -0
- package/bench/refs/node-sdk/src/error/no-object-generated-error.ts +70 -0
- package/bench/refs/node-sdk/src/generate-image/generate-image-result.ts +42 -0
- package/bench/refs/node-sdk/src/generate-image/generate-image.ts +362 -0
- package/bench/refs/node-sdk/src/generate-object/generate-object-result.ts +67 -0
- package/bench/refs/node-sdk/src/generate-object/generate-object.ts +501 -0
- package/bench/refs/node-sdk/src/generate-object/inject-json-instruction.ts +30 -0
- package/bench/refs/node-sdk/src/generate-object/output-strategy.ts +415 -0
- package/bench/refs/node-sdk/src/generate-object/repair-text.ts +12 -0
- package/bench/refs/node-sdk/src/generate-object/stream-object.ts +960 -0
- package/bench/refs/node-sdk/src/generate-speech/generate-speech.ts +191 -0
- package/bench/refs/node-sdk/src/generate-text/generate-text.ts +1484 -0
- package/bench/refs/node-sdk/src/generate-text/stream-text.ts +2708 -0
- package/bench/refs/node-sdk/src/generate-text/tool-call.ts +59 -0
- package/bench/refs/node-sdk/src/generate-text/tool-result.ts +36 -0
- package/bench/refs/node-sdk/src/telemetry/create-telemetry-dispatcher.ts +146 -0
- package/bench/refs/node-sdk/src/telemetry/telemetry-registry.ts +15 -0
- package/bench/refs/node-sdk/src/telemetry/telemetry.ts +223 -0
- package/bench/refs/node-sdk/src/util/async-iterable-stream.ts +94 -0
- package/bench/refs/node-sdk/src/util/consume-stream.ts +31 -0
- package/bench/refs/node-sdk/src/util/create-stitchable-stream.ts +112 -0
- package/bench/refs/node-sdk/src/util/download/download.ts +74 -0
- package/bench/refs/node-sdk/src/util/error-handler.ts +1 -0
- package/bench/refs/node-sdk/src/util/fix-json.ts +401 -0
- package/bench/refs/node-sdk/src/util/merge-objects.ts +79 -0
- package/bench/refs/python-lib/.refrev +1 -0
- package/bench/refs/python-lib/README.md +18 -0
- package/bench/refs/python-lib/pandas/core/_numba/executor.py +249 -0
- package/bench/refs/python-lib/pandas/core/_numba/extensions.py +586 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/mean_.py +198 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/min_max_.py +178 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/sum_.py +255 -0
- package/bench/refs/python-lib/pandas/core/_numba/kernels/var_.py +251 -0
- package/bench/refs/python-lib/pandas/core/accessor.py +520 -0
- package/bench/refs/python-lib/pandas/core/api.py +138 -0
- package/bench/refs/python-lib/pandas/core/array_algos/masked_accumulations.py +97 -0
- package/bench/refs/python-lib/pandas/core/array_algos/masked_reductions.py +252 -0
- package/bench/refs/python-lib/pandas/core/array_algos/putmask.py +150 -0
- package/bench/refs/python-lib/pandas/core/array_algos/quantile.py +232 -0
- package/bench/refs/python-lib/pandas/core/array_algos/replace.py +159 -0
- package/bench/refs/python-lib/pandas/core/array_algos/take.py +609 -0
- package/bench/refs/python-lib/pandas/core/arraylike.py +534 -0
- package/bench/refs/python-lib/pandas/core/arrays/_arrow_string_mixins.py +434 -0
- package/bench/refs/python-lib/pandas/core/arrays/_mixins.py +630 -0
- package/bench/refs/python-lib/pandas/core/arrays/_ranges.py +276 -0
- package/bench/refs/python-lib/pandas/core/arrays/_utils.py +77 -0
- package/bench/refs/python-lib/pandas/core/arrays/arrow/accessors.py +521 -0
- package/bench/refs/python-lib/pandas/core/arrays/arrow/extension_types.py +174 -0
- package/bench/refs/python-lib/pandas/core/arrays/boolean.py +454 -0
- package/bench/refs/python-lib/pandas/core/arrays/floating.py +192 -0
- package/bench/refs/python-lib/pandas/core/arrays/integer.py +296 -0
- package/bench/refs/python-lib/pandas/core/arrays/masked.py +2140 -0
- package/bench/refs/python-lib/pandas/core/arrays/numeric.py +305 -0
- package/bench/refs/python-lib/pandas/core/arrays/numpy_.py +701 -0
- package/bench/refs/python-lib/pandas/core/arrays/period.py +1586 -0
- package/bench/refs/python-lib/pandas/core/arrays/sparse/accessor.py +505 -0
- package/bench/refs/python-lib/pandas/core/arrays/sparse/scipy_sparse.py +208 -0
- package/bench/refs/rust-project/.refrev +1 -0
- package/bench/refs/rust-project/README.md +17 -0
- package/bench/refs/rust-project/tokio/src/doc/os.rs +68 -0
- package/bench/refs/rust-project/tokio/src/fs/dir_builder.rs +129 -0
- package/bench/refs/rust-project/tokio/src/fs/file.rs +1113 -0
- package/bench/refs/rust-project/tokio/src/fs/mocks.rs +176 -0
- package/bench/refs/rust-project/tokio/src/fs/mod.rs +324 -0
- package/bench/refs/rust-project/tokio/src/fs/open_options.rs +856 -0
- package/bench/refs/rust-project/tokio/src/fs/read.rs +80 -0
- package/bench/refs/rust-project/tokio/src/fs/read_dir.rs +357 -0
- package/bench/refs/rust-project/tokio/src/fs/write.rs +99 -0
- package/bench/refs/rust-project/tokio/src/future/maybe_done.rs +123 -0
- package/bench/refs/rust-project/tokio/src/future/try_join.rs +82 -0
- package/bench/refs/rust-project/tokio/src/io/async_buf_read.rs +117 -0
- package/bench/refs/rust-project/tokio/src/io/async_read.rs +133 -0
- package/bench/refs/rust-project/tokio/src/io/async_seek.rs +96 -0
- package/bench/refs/rust-project/tokio/src/io/async_write.rs +402 -0
- package/bench/refs/rust-project/tokio/src/io/blocking.rs +339 -0
- package/bench/refs/rust-project/tokio/src/io/interest.rs +345 -0
- package/bench/refs/rust-project/tokio/src/io/join.rs +130 -0
- package/bench/refs/rust-project/tokio/src/io/mod.rs +308 -0
- package/bench/refs/rust-project/tokio/src/io/poll_evented.rs +319 -0
- package/bench/refs/rust-project/tokio/src/io/read_buf.rs +344 -0
- package/bench/refs/rust-project/tokio/src/io/ready.rs +322 -0
- package/bench/refs/rust-project/tokio/src/io/split.rs +166 -0
- package/bench/refs/rust-project/tokio/src/io/stderr.rs +148 -0
- package/bench/refs/rust-project/tokio/src/io/stdin.rs +98 -0
- package/bench/refs/rust-project/tokio/src/io/stdio_common.rs +222 -0
- package/bench/refs/rust-project/tokio/src/io/stdout.rs +197 -0
- package/bench/refs/rust-project/tokio/src/io/util/buf_reader.rs +311 -0
- package/bench/refs/rust-project/tokio/src/io/util/buf_stream.rs +207 -0
- package/bench/refs/rust-project/tokio/src/io/util/buf_writer.rs +310 -0
- package/bench/refs/rust-project/tokio/src/io/util/chain.rs +144 -0
- package/commands/_spawn-patterns.json +32 -0
- package/commands/ashlr-allow.md +21 -0
- package/commands/ashlr-benchmark.md +53 -0
- package/commands/ashlr-brief.md +97 -0
- package/commands/ashlr-budget.md +76 -0
- package/commands/ashlr-compact.md +54 -0
- package/commands/ashlr-dashboard.md +37 -0
- package/commands/ashlr-doctor.md +56 -0
- package/commands/ashlr-eco-mode.md +92 -0
- package/commands/ashlr-genome-init.md +24 -0
- package/commands/ashlr-genome-keygen.md +36 -0
- package/commands/ashlr-genome-loop.md +118 -0
- package/commands/ashlr-genome-push.md +36 -0
- package/commands/ashlr-genome-rewrap.md +48 -0
- package/commands/ashlr-genome-team-init.md +67 -0
- package/commands/ashlr-handoff.md +23 -0
- package/commands/ashlr-help.md +86 -0
- package/commands/ashlr-hook-timings.md +30 -0
- package/commands/ashlr-leaderboard.md +50 -0
- package/commands/ashlr-ollama-setup.md +39 -0
- package/commands/ashlr-orchestrate-status.md +72 -0
- package/commands/ashlr-orchestrate.md +83 -0
- package/commands/ashlr-parallelize.md +63 -0
- package/commands/ashlr-report-crash.md +33 -0
- package/commands/ashlr-resume.md +72 -0
- package/commands/ashlr-savings.md +24 -0
- package/commands/ashlr-settings.md +50 -0
- package/commands/ashlr-spawn.md +61 -0
- package/commands/ashlr-start.md +60 -0
- package/commands/ashlr-status.md +64 -0
- package/commands/ashlr-team-invite.md +47 -0
- package/commands/ashlr-tier.md +122 -0
- package/commands/ashlr-tour.md +60 -0
- package/commands/ashlr-update.md +155 -0
- package/commands/ashlr-upgrade.md +96 -0
- package/commands/goal.md +58 -0
- package/commands/loop.md +40 -0
- package/docs/CNAME +1 -0
- package/docs/PRO_TIER.md +104 -0
- package/docs/README.md +21 -0
- package/docs/architecture.md +415 -0
- package/docs/ashlr-pipe.md +161 -0
- package/docs/assets/logo.svg +19 -0
- package/docs/assets/og.png +0 -0
- package/docs/assets/og.svg +41 -0
- package/docs/benchmarks-v2.json +355 -0
- package/docs/benchmarks.json +102 -0
- package/docs/benchmarks.md +211 -0
- package/docs/billing.md +185 -0
- package/docs/cloud-genome.md +155 -0
- package/docs/competitive-wozcode.md +92 -0
- package/docs/deploy.md +325 -0
- package/docs/email-templates.md +113 -0
- package/docs/embed-tuning.md +103 -0
- package/docs/genome.md +120 -0
- package/docs/github-oauth-onboarding.md +127 -0
- package/docs/hero-video-script.md +129 -0
- package/docs/index.html +2262 -0
- package/docs/install-prompt.md +78 -0
- package/docs/install-windows.md +132 -0
- package/docs/install.ps1 +171 -0
- package/docs/install.sh +146 -0
- package/docs/launch/README.md +114 -0
- package/docs/launch/hn.md +49 -0
- package/docs/launch/reddit.md +45 -0
- package/docs/launch/x.md +65 -0
- package/docs/launch-post.md +112 -0
- package/docs/legal.md +78 -0
- package/docs/llm-providers.md +99 -0
- package/docs/multi-host-mcp.md +217 -0
- package/docs/multi-turn-architecture.md +108 -0
- package/docs/operations/deployment.md +108 -0
- package/docs/operations/error-monitoring.md +70 -0
- package/docs/operations/weekly-digest.md +70 -0
- package/docs/operations.md +494 -0
- package/docs/platform-support.md +133 -0
- package/docs/policy-packs.md +188 -0
- package/docs/press-kit/fact-sheet.md +78 -0
- package/docs/press-kit/founder-bio.md +3 -0
- package/docs/press-kit/logo.svg +33 -0
- package/docs/press-kit/screenshots.md +146 -0
- package/docs/pricing.md +251 -0
- package/docs/pro-backend-architecture.md +523 -0
- package/docs/producthunt.md +52 -0
- package/docs/router-migration.md +110 -0
- package/docs/session-log-schema.md +68 -0
- package/docs/social.md +95 -0
- package/docs/team-genome.md +528 -0
- package/docs/telemetry.md +194 -0
- package/docs/test-isolation.md +100 -0
- package/docs/upgrade.md +159 -0
- package/hooks/_hook-errors.ts +87 -0
- package/hooks/_hook-perf-emit.ts +113 -0
- package/hooks/_hook-timing-ledger.ts +1133 -0
- package/hooks/_nudge-throttle.ts +127 -0
- package/hooks/_recent-blocks.ts +127 -0
- package/hooks/audit-upload.ts +86 -0
- package/hooks/codex-hooks.json +171 -0
- package/hooks/commit-attribution.ts +179 -0
- package/hooks/edit-batching-nudge.ts +154 -0
- package/hooks/genome-scribe-hook.ts +219 -0
- package/hooks/hooks.json +294 -0
- package/hooks/orient-nudge-hook.ts +242 -0
- package/hooks/policy-enforce.ts +214 -0
- package/hooks/post-tool-use-embedding.ts +93 -0
- package/hooks/post-tool-use-genome.sh +37 -0
- package/hooks/post-tool-use-genome.ts +69 -0
- package/hooks/posttooluse-correlate.ts +122 -0
- package/hooks/posttooluse-dedupe-output.ts +241 -0
- package/hooks/posttooluse-genome-refresh.ts +223 -0
- package/hooks/posttooluse-native-nudge.ts +205 -0
- package/hooks/posttooluse-stale-result.ts +277 -0
- package/hooks/pretooluse-bash.ts +63 -0
- package/hooks/pretooluse-budget-guard.ts +318 -0
- package/hooks/pretooluse-common.ts +985 -0
- package/hooks/pretooluse-eco-router.ts +196 -0
- package/hooks/pretooluse-edit.sh +93 -0
- package/hooks/pretooluse-edit.ts +197 -0
- package/hooks/pretooluse-glob.ts +70 -0
- package/hooks/pretooluse-grep.sh +85 -0
- package/hooks/pretooluse-grep.ts +96 -0
- package/hooks/pretooluse-notebookedit.ts +121 -0
- package/hooks/pretooluse-read.sh +118 -0
- package/hooks/pretooluse-read.ts +118 -0
- package/hooks/pretooluse-task.ts +130 -0
- package/hooks/pretooluse-webfetch.ts +66 -0
- package/hooks/pretooluse-websearch.ts +85 -0
- package/hooks/pretooluse-write.ts +128 -0
- package/hooks/pulse-emit.ts +197 -0
- package/hooks/session-end-consolidate.sh +35 -0
- package/hooks/session-end-consolidate.ts +188 -0
- package/hooks/session-end-stats-gc.ts +80 -0
- package/hooks/session-log-append.sh +94 -0
- package/hooks/session-log-append.ts +116 -0
- package/hooks/session-start.ts +993 -0
- package/hooks/sessionend-hook-health-nudge.ts +451 -0
- package/hooks/sessionend-savings-nudge.ts +318 -0
- package/hooks/sessionend-status-line-nudge.ts +296 -0
- package/hooks/sessionstart-brief.ts +140 -0
- package/hooks/sessionstart-cost-refactor.ts +95 -0
- package/hooks/sessionstart-efficient.ts +110 -0
- package/hooks/sessionstart-genome-author.ts +93 -0
- package/hooks/sessionstart-lean-tools.ts +98 -0
- package/hooks/sessionstart-search.ts +97 -0
- package/hooks/stop-accounting.ts +152 -0
- package/hooks/subagent-stop-rollup.ts +162 -0
- package/hooks/userpromptsubmit-brief-trigger.ts +156 -0
- package/package.json +56 -0
- package/ports/README.md +108 -0
- package/ports/cursor/mcp.json +11 -0
- package/ports/goose/recipe.yaml +26 -0
- package/scripts/ashlr-mcp.ts +40 -0
- package/scripts/auto-update.ts +177 -0
- package/scripts/baseline-scan.ts +831 -0
- package/scripts/bench-orchestrate.ts +377 -0
- package/scripts/benchmark-refs.ts +292 -0
- package/scripts/bootstrap.mjs +100 -0
- package/scripts/brief-eval.ts +234 -0
- package/scripts/bump-version.ts +82 -0
- package/scripts/bun-resolve.d.mts +11 -0
- package/scripts/bun-resolve.mjs +59 -0
- package/scripts/calibrate-grep.ts +467 -0
- package/scripts/capture-grep-workload.ts +260 -0
- package/scripts/check-tier.ts +61 -0
- package/scripts/check-version-sync.ts +97 -0
- package/scripts/cli-orchestrate-status.ts +386 -0
- package/scripts/cli-orchestrate.ts +303 -0
- package/scripts/cli.ts +478 -0
- package/scripts/cloud-smoke-test.ts +313 -0
- package/scripts/coach-report.ts +373 -0
- package/scripts/context-db-migrate.ts +137 -0
- package/scripts/context-status.ts +43 -0
- package/scripts/demo-run.ts +255 -0
- package/scripts/deploy-smoke.sh +140 -0
- package/scripts/doctor.ts +992 -0
- package/scripts/embed-file-worker.ts +104 -0
- package/scripts/embed-tune.ts +308 -0
- package/scripts/errors-report.ts +428 -0
- package/scripts/find-test-leak.ts +69 -0
- package/scripts/generate-badge.ts +357 -0
- package/scripts/genome-auto-consolidate.ts +533 -0
- package/scripts/genome-auto-propose.ts +578 -0
- package/scripts/genome-cloud-pull.ts +363 -0
- package/scripts/genome-cloud-push.ts +382 -0
- package/scripts/genome-cloud-sync.ts +587 -0
- package/scripts/genome-commit-watcher.ts +295 -0
- package/scripts/genome-init.ts +986 -0
- package/scripts/genome-key.ts +233 -0
- package/scripts/genome-keygen.ts +168 -0
- package/scripts/genome-link.ts +59 -0
- package/scripts/genome-refresh-worker.ts +364 -0
- package/scripts/genome-rewrap.ts +90 -0
- package/scripts/genome-synthesizer.ts +679 -0
- package/scripts/genome-team-init.ts +312 -0
- package/scripts/handoff-pack.ts +438 -0
- package/scripts/hook-bootstrap.mjs +75 -0
- package/scripts/hook-timing-reader.ts +371 -0
- package/scripts/hook-timings-report.ts +554 -0
- package/scripts/install-genome-hooks.ts +196 -0
- package/scripts/install-onnx-model.ts +154 -0
- package/scripts/install-permissions.ts +276 -0
- package/scripts/install-status-line.ts +150 -0
- package/scripts/mcp-entrypoint.sh +78 -0
- package/scripts/mcp-entrypoint.ts +130 -0
- package/scripts/mdx-angle-bracket-lint.ts +152 -0
- package/scripts/measure-cold-start.ts +126 -0
- package/scripts/migrate-stats-to-sqlite.ts +86 -0
- package/scripts/ollama-setup.ts +498 -0
- package/scripts/onboarding-wizard.ts +1691 -0
- package/scripts/orchestrate-emit-telemetry.ts +177 -0
- package/scripts/orchestrate-expand.ts +517 -0
- package/scripts/orchestrate-run.ts +744 -0
- package/scripts/print-legend.ts +50 -0
- package/scripts/product-metadata.ts +38 -0
- package/scripts/prune-old-memories.ts +208 -0
- package/scripts/publish.sh +88 -0
- package/scripts/read-calibration.ts +122 -0
- package/scripts/report-crash.ts +226 -0
- package/scripts/run-benchmark.ts +750 -0
- package/scripts/run-root-tests.ts +28 -0
- package/scripts/savings-dashboard.ts +1258 -0
- package/scripts/savings-report-extras.ts +447 -0
- package/scripts/savings-status-line.ts +873 -0
- package/scripts/session-event-emit.ts +266 -0
- package/scripts/session-greet.ts +686 -0
- package/scripts/session-log-report.ts +551 -0
- package/scripts/session-resume.ts +614 -0
- package/scripts/set-hook-mode.ts +83 -0
- package/scripts/smoke-cross-platform.ts +117 -0
- package/scripts/smoke-realtime.ts +257 -0
- package/scripts/smoke-tools.ts +21 -0
- package/scripts/stats-cloud-pull.ts +213 -0
- package/scripts/stats-cloud-sync.ts +261 -0
- package/scripts/telemetry-flush.ts +160 -0
- package/scripts/telemetry-status.ts +266 -0
- package/scripts/timing-budget.ts +35 -0
- package/scripts/ui-animation.ts +120 -0
- package/scripts/ui.ts +431 -0
- package/scripts/upgrade-flow.ts +775 -0
- package/scripts/weekly-digest.ts +394 -0
- package/servers/_accounting.ts +78 -0
- package/servers/_ask-router.ts +84 -0
- package/servers/_ast-chunker.ts +434 -0
- package/servers/_ast-helpers.ts +183 -0
- package/servers/_ast-languages.ts +153 -0
- package/servers/_ast-refactor/_shared.ts +221 -0
- package/servers/_ast-refactor/cross-file-rename.ts +560 -0
- package/servers/_ast-refactor/extract-function.ts +357 -0
- package/servers/_ast-refactor/file-local-rename.ts +172 -0
- package/servers/_ast-refactor.ts +41 -0
- package/servers/_ast-skeleton.ts +107 -0
- package/servers/_bash-summarizers-registry.ts +1096 -0
- package/servers/_crash-dump.ts +210 -0
- package/servers/_cwd-clamp.ts +342 -0
- package/servers/_edit-log.ts +28 -0
- package/servers/_edit-match.ts +236 -0
- package/servers/_edit-validate.ts +196 -0
- package/servers/_embed-calibration.ts +123 -0
- package/servers/_embedding-cache.ts +401 -0
- package/servers/_embedding-model.ts +329 -0
- package/servers/_events.ts +113 -0
- package/servers/_genome-cache.ts +154 -0
- package/servers/_genome-commits.ts +172 -0
- package/servers/_genome-crypto-v2.ts +242 -0
- package/servers/_genome-crypto.ts +259 -0
- package/servers/_genome-discoveries.ts +140 -0
- package/servers/_genome-embed-populator.ts +216 -0
- package/servers/_genome-freshness.ts +134 -0
- package/servers/_genome-issues.ts +171 -0
- package/servers/_genome-live.ts +263 -0
- package/servers/_genome-prs.ts +188 -0
- package/servers/_genome-search.ts +479 -0
- package/servers/_genome-sync.ts +297 -0
- package/servers/_history-tracker.ts +279 -0
- package/servers/_http-helpers.ts +151 -0
- package/servers/_identity-hash.ts +151 -0
- package/servers/_llm-providers/anthropic.ts +132 -0
- package/servers/_llm-providers/cloud.ts +195 -0
- package/servers/_llm-providers/index.ts +350 -0
- package/servers/_llm-providers/local.ts +127 -0
- package/servers/_llm-providers/onnx.ts +393 -0
- package/servers/_llm-providers/types.ts +27 -0
- package/servers/_manifest-v2.ts +447 -0
- package/servers/_mcp-host.ts +93 -0
- package/servers/_nudge-events.ts +451 -0
- package/servers/_orchestrate-executor.ts +316 -0
- package/servers/_prefetch.ts +435 -0
- package/servers/_pricing.ts +256 -0
- package/servers/_pro.ts +381 -0
- package/servers/_read-cache.ts +44 -0
- package/servers/_router-handlers.ts +46 -0
- package/servers/_router.ts +55 -0
- package/servers/_run-with-timeout.ts +173 -0
- package/servers/_savings-render.ts +214 -0
- package/servers/_stats-sqlite.ts +640 -0
- package/servers/_stats.ts +1183 -0
- package/servers/_status-line-cells.ts +469 -0
- package/servers/_streaks.ts +162 -0
- package/servers/_summarize.ts +208 -0
- package/servers/_task-graph-render.ts +217 -0
- package/servers/_task-graph.ts +545 -0
- package/servers/_telemetry.ts +719 -0
- package/servers/_test-parsers.ts +530 -0
- package/servers/_test-watch.ts +626 -0
- package/servers/_text-helpers.ts +37 -0
- package/servers/_token-measure.ts +160 -0
- package/servers/_tool-base.ts +248 -0
- package/servers/_weekly-digest.ts +391 -0
- package/servers/ask-server-handlers.ts +49 -0
- package/servers/ask-server.ts +174 -0
- package/servers/bash-server-handlers.ts +138 -0
- package/servers/bash-server.ts +1136 -0
- package/servers/bench.ts +186 -0
- package/servers/diff-semantic-server-handlers.ts +39 -0
- package/servers/diff-semantic-server.ts +566 -0
- package/servers/diff-server-handlers.ts +317 -0
- package/servers/diff-server.ts +20 -0
- package/servers/edit-server-handlers.ts +31 -0
- package/servers/edit-server.ts +209 -0
- package/servers/edit-structural-server-handlers.ts +322 -0
- package/servers/efficiency-server-handlers.ts +161 -0
- package/servers/efficiency-server.ts +1135 -0
- package/servers/flush-server-handlers.ts +21 -0
- package/servers/flush-server.ts +19 -0
- package/servers/genome-server-handlers.ts +118 -0
- package/servers/genome-server.ts +397 -0
- package/servers/github-server-handlers.ts +187 -0
- package/servers/github-server.ts +856 -0
- package/servers/glob-server-handlers.ts +233 -0
- package/servers/glob-server.ts +20 -0
- package/servers/grep-server-handlers.ts +61 -0
- package/servers/grep-server.ts +564 -0
- package/servers/http-server-handlers.ts +36 -0
- package/servers/http-server.ts +149 -0
- package/servers/logs-server-handlers.ts +42 -0
- package/servers/logs-server.ts +359 -0
- package/servers/ls-server-handlers.ts +166 -0
- package/servers/ls-server.ts +20 -0
- package/servers/multi-edit-server-handlers.ts +51 -0
- package/servers/multi-edit-server.ts +422 -0
- package/servers/notebook-edit-server-handlers.ts +34 -0
- package/servers/notebook-edit-server.ts +181 -0
- package/servers/orient-server-handlers.ts +52 -0
- package/servers/orient-server.ts +436 -0
- package/servers/pipe-server-handlers.ts +68 -0
- package/servers/pipe-server.ts +300 -0
- package/servers/read-server-handlers.ts +42 -0
- package/servers/read-server.ts +206 -0
- package/servers/rename-file-server-handlers.ts +67 -0
- package/servers/rename-file-server.ts +699 -0
- package/servers/savings-server-handlers.ts +27 -0
- package/servers/savings-server.ts +54 -0
- package/servers/search-replace-regex-server-handlers.ts +96 -0
- package/servers/search-replace-regex-server.ts +751 -0
- package/servers/sql-server-handlers.ts +58 -0
- package/servers/sql-server.ts +505 -0
- package/servers/task-server-handlers.ts +358 -0
- package/servers/task-server.ts +24 -0
- package/servers/test-server-handlers.ts +351 -0
- package/servers/test-server.ts +20 -0
- package/servers/tree-server-handlers.ts +503 -0
- package/servers/tree-server.ts +20 -0
- package/servers/webfetch-server-handlers.ts +166 -0
- package/servers/webfetch-server.ts +20 -0
- package/servers/websearch-server-handlers.ts +215 -0
- package/servers/websearch-server.ts +19 -0
- package/servers/write-server-handlers.ts +27 -0
- package/servers/write-server.ts +97 -0
- package/skills/ashlr-brief/SKILL.md +80 -0
- package/skills/ashlr-codex-doctor/SKILL.md +21 -0
- package/skills/ashlr-codex-efficient-tools/SKILL.md +17 -0
- package/skills/ashlr-codex-genome-refresh/SKILL.md +20 -0
- package/skills/ashlr-codex-parallel-explore/SKILL.md +20 -0
- package/skills/ashlr-codex-savings/SKILL.md +17 -0
- package/skills/ashlr-cost-refactor/SKILL.md +50 -0
- package/skills/ashlr-efficient/SKILL.md +64 -0
- package/skills/ashlr-genome-author/SKILL.md +43 -0
- package/skills/ashlr-lean-tools/SKILL.md +43 -0
- 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
|
+
|