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,50 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* print-legend.ts
|
|
4
|
+
*
|
|
5
|
+
* Emits a plain-text ASCII legend for every element in the ashlr status line.
|
|
6
|
+
* Invoked by the /ashlr-legend skill. No I/O dependencies beyond stdout.
|
|
7
|
+
*
|
|
8
|
+
* Output is designed for a monospace terminal, <=60 visible chars per line
|
|
9
|
+
* for the structured rows (the description wraps with a hanging indent).
|
|
10
|
+
* Box-drawing characters (U+256x) are used for the header/footer frame;
|
|
11
|
+
* they render as plain hyphens in terminals that strip Unicode.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const LEGEND = `\u256d\u2500\u2500\u2500\u2500 ashlr status-line legend \u2500\u2500\u2500\u2500\u256e
|
|
15
|
+
|
|
16
|
+
ashlr \u00b7 brand label + activity dot.
|
|
17
|
+
Dim when idle; pulses during a saving event.
|
|
18
|
+
|
|
19
|
+
\u00b7 \u2014 separator glyph between segments (middle dot).
|
|
20
|
+
|
|
21
|
+
\u2840\u2844\u2847\u28FF \u2014 heartbeat glyph between "ashlr" and the sparkline.
|
|
22
|
+
Braille wave when active (last 4s); dim dot
|
|
23
|
+
when idle.
|
|
24
|
+
|
|
25
|
+
7d \u2581\u2582\u2583\u2585\u2587\u2588\u2587 \u2014 7-day sparkline. Each cell = one day of savings,
|
|
26
|
+
tallest cell = busiest day (scaled to full
|
|
27
|
+
block). "7d" label shown when terminal >100
|
|
28
|
+
cols; dropped on narrow windows.
|
|
29
|
+
|
|
30
|
+
ctx:NN% \u2014 context-window pressure (how full your Claude
|
|
31
|
+
Code context is). Color tiers:
|
|
32
|
+
green 0-60% \u2022 yellow 60-80%
|
|
33
|
+
orange 80-95% \u2022 red+bold 95%+
|
|
34
|
+
|
|
35
|
+
session +N \u2014 tokens saved in THIS terminal since the
|
|
36
|
+
session started.
|
|
37
|
+
|
|
38
|
+
lifetime +M \u2014 tokens saved across every session, ever.
|
|
39
|
+
|
|
40
|
+
tip:\u2026 \u2014 rotating daily hint (one tip per day, cycles
|
|
41
|
+
through the built-in tip list). Toggle off:
|
|
42
|
+
/ashlr-settings set statusLineTips false
|
|
43
|
+
|
|
44
|
+
\u2570\u2500 run /ashlr-savings for totals \u00b7 /ashlr-tour to see it in action \u2500\u256f`;
|
|
45
|
+
|
|
46
|
+
if (import.meta.main) {
|
|
47
|
+
process.stdout.write(LEGEND + "\n");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { LEGEND };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { readdir } from "fs/promises";
|
|
2
|
+
import { dirname, join, resolve } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
|
|
5
|
+
import { listTools } from "../servers/_tool-base";
|
|
6
|
+
import "../servers/_router-handlers";
|
|
7
|
+
|
|
8
|
+
export interface PublicProductCounts {
|
|
9
|
+
mcpTools: number;
|
|
10
|
+
slashCommands: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const PUBLIC_PRODUCT_COUNTS = {
|
|
14
|
+
mcpTools: 40,
|
|
15
|
+
slashCommands: 34,
|
|
16
|
+
} as const satisfies PublicProductCounts;
|
|
17
|
+
|
|
18
|
+
export const PUBLIC_PRODUCT_TELEMETRY = "off by default; explicit opt-in only";
|
|
19
|
+
|
|
20
|
+
export function repoRoot(): string {
|
|
21
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function registeredMcpToolCount(): number {
|
|
25
|
+
return new Set(listTools().map((tool) => tool.name)).size;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function slashCommandCount(root = repoRoot()): Promise<number> {
|
|
29
|
+
const entries = await readdir(join(root, "commands"));
|
|
30
|
+
return entries.filter((name) => /^ashlr-.+\.md$/.test(name)).length;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function publicProductCounts(root = repoRoot()): Promise<PublicProductCounts> {
|
|
34
|
+
return {
|
|
35
|
+
mcpTools: registeredMcpToolCount(),
|
|
36
|
+
slashCommands: await slashCommandCount(root),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* prune-old-memories.ts — surface auto-memory entries (under
|
|
4
|
+
* `<claude-projects-dir>/memory/`) that are stale candidates for deletion.
|
|
5
|
+
*
|
|
6
|
+
* Read-only by default — prints a candidate report and exits 0. Pass
|
|
7
|
+
* `--apply` to actually delete the flagged files.
|
|
8
|
+
*
|
|
9
|
+
* Heuristics for "candidate":
|
|
10
|
+
* 1. File has not been modified in > N days (default: 30; --days=N to override)
|
|
11
|
+
* 2. There is a NEWER entry whose name starts with the same project_v<major>
|
|
12
|
+
* prefix (e.g. project_v1.13_*.md is superseded by project_v1.14_*.md)
|
|
13
|
+
* 3. Or the entry's title contains an explicit "(superseded ...)" marker
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* bun run scripts/prune-old-memories.ts # report only
|
|
17
|
+
* bun run scripts/prune-old-memories.ts --days=60 # 60-day cutoff
|
|
18
|
+
* bun run scripts/prune-old-memories.ts --dir=/path/to/memory # explicit dir
|
|
19
|
+
* bun run scripts/prune-old-memories.ts --apply # actually delete
|
|
20
|
+
*
|
|
21
|
+
* Files removed are also removed from MEMORY.md if a single-line link to them
|
|
22
|
+
* is found (`- [.*](filename.md) — ...`).
|
|
23
|
+
*
|
|
24
|
+
* This is a hygiene tool — never run automatically. Operator-driven.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { existsSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
28
|
+
import { homedir } from "os";
|
|
29
|
+
import { basename, dirname, join } from "path";
|
|
30
|
+
|
|
31
|
+
interface PruneCandidate {
|
|
32
|
+
path: string;
|
|
33
|
+
name: string;
|
|
34
|
+
ageDays: number;
|
|
35
|
+
reason: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function parseArgs(argv: string[]): { dir?: string; days: number; apply: boolean } {
|
|
39
|
+
const out = { days: 30, apply: false } as { dir?: string; days: number; apply: boolean };
|
|
40
|
+
for (const a of argv) {
|
|
41
|
+
if (a === "--apply") out.apply = true;
|
|
42
|
+
else if (a.startsWith("--days=")) out.days = parseInt(a.slice("--days=".length), 10) || 30;
|
|
43
|
+
else if (a.startsWith("--dir=")) out.dir = a.slice("--dir=".length);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Find the default Claude Code project memory directory for this CWD. */
|
|
49
|
+
function defaultMemoryDir(): string | null {
|
|
50
|
+
const home = process.env.HOME ?? homedir();
|
|
51
|
+
const cwd = process.cwd();
|
|
52
|
+
// Convention: <home>/.claude/projects/<encoded-cwd>/memory/
|
|
53
|
+
// The encoding replaces / with -, e.g. /Users/masonwyatt/foo → -Users-masonwyatt-foo
|
|
54
|
+
const encoded = "-" + cwd.replace(/^\//, "").replace(/\//g, "-");
|
|
55
|
+
const dir = join(home, ".claude", "projects", encoded, "memory");
|
|
56
|
+
if (existsSync(dir)) return dir;
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function listMemoryFiles(dir: string): string[] {
|
|
61
|
+
return readdirSync(dir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Extract the version-major prefix from a project memory filename. e.g. "project_v123_..." → "v123" */
|
|
65
|
+
function versionPrefix(name: string): string | null {
|
|
66
|
+
const m = name.match(/^project_v(\d+(?:[a-z\d_]*)?)/i);
|
|
67
|
+
return m ? `v${m[1]!.split("_")[0]!}` : null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Compare two project memory entries by version prefix (semver-ish). */
|
|
71
|
+
function compareVersions(a: string, b: string): number {
|
|
72
|
+
// Strip non-digit suffix and compare numerically
|
|
73
|
+
const an = parseInt(a.replace(/[^\d]/g, ""), 10);
|
|
74
|
+
const bn = parseInt(b.replace(/[^\d]/g, ""), 10);
|
|
75
|
+
return an - bn;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function findCandidates(dir: string, days: number): PruneCandidate[] {
|
|
79
|
+
const files = listMemoryFiles(dir);
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
const cutoff = now - days * 24 * 60 * 60 * 1000;
|
|
82
|
+
|
|
83
|
+
// Group by major-version prefix
|
|
84
|
+
const byPrefix = new Map<string, Array<{ file: string; mtime: number }>>();
|
|
85
|
+
for (const file of files) {
|
|
86
|
+
const full = join(dir, file);
|
|
87
|
+
const mtime = statSync(full).mtimeMs;
|
|
88
|
+
const prefix = versionPrefix(file);
|
|
89
|
+
if (!prefix) continue;
|
|
90
|
+
if (!byPrefix.has(prefix)) byPrefix.set(prefix, []);
|
|
91
|
+
byPrefix.get(prefix)!.push({ file, mtime });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// For each prefix group, find the newest version. Older same-prefix files are candidates.
|
|
95
|
+
const candidates: PruneCandidate[] = [];
|
|
96
|
+
// Sort prefixes by version number; older versions whose newer-version sibling exists are candidates.
|
|
97
|
+
const prefixes = [...byPrefix.keys()].sort(compareVersions);
|
|
98
|
+
for (let i = 0; i < prefixes.length - 1; i++) {
|
|
99
|
+
const olderPrefix = prefixes[i]!;
|
|
100
|
+
const newerPrefix = prefixes[i + 1]!;
|
|
101
|
+
const olderEntries = byPrefix.get(olderPrefix) ?? [];
|
|
102
|
+
for (const { file, mtime } of olderEntries) {
|
|
103
|
+
if (mtime > cutoff) continue;
|
|
104
|
+
const ageDays = Math.round((now - mtime) / (24 * 60 * 60 * 1000));
|
|
105
|
+
candidates.push({
|
|
106
|
+
path: join(dir, file),
|
|
107
|
+
name: file,
|
|
108
|
+
ageDays,
|
|
109
|
+
reason: `superseded by ${newerPrefix}_*.md (older than ${days}d cutoff)`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Also flag any file with an explicit "(superseded" marker in its body
|
|
115
|
+
for (const file of files) {
|
|
116
|
+
const full = join(dir, file);
|
|
117
|
+
const mtime = statSync(full).mtimeMs;
|
|
118
|
+
if (mtime > cutoff) continue;
|
|
119
|
+
let content = "";
|
|
120
|
+
try { content = readFileSync(full, "utf-8"); } catch { continue; }
|
|
121
|
+
if (/\(superseded by/i.test(content) && !candidates.some((c) => c.path === full)) {
|
|
122
|
+
const ageDays = Math.round((now - mtime) / (24 * 60 * 60 * 1000));
|
|
123
|
+
candidates.push({
|
|
124
|
+
path: full,
|
|
125
|
+
name: file,
|
|
126
|
+
ageDays,
|
|
127
|
+
reason: `body contains "(superseded by ...)" marker`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return candidates;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function pruneFromIndex(memoryDir: string, removedNames: string[]): number {
|
|
136
|
+
const indexPath = join(memoryDir, "MEMORY.md");
|
|
137
|
+
if (!existsSync(indexPath)) return 0;
|
|
138
|
+
const lines = readFileSync(indexPath, "utf-8").split("\n");
|
|
139
|
+
const removedSet = new Set(removedNames);
|
|
140
|
+
const kept: string[] = [];
|
|
141
|
+
let pruned = 0;
|
|
142
|
+
for (const line of lines) {
|
|
143
|
+
const m = line.match(/\(([^)]+\.md)\)/);
|
|
144
|
+
if (m && removedSet.has(basename(m[1]!))) {
|
|
145
|
+
pruned++;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
kept.push(line);
|
|
149
|
+
}
|
|
150
|
+
if (pruned > 0) {
|
|
151
|
+
writeFileSync(indexPath, kept.join("\n"));
|
|
152
|
+
}
|
|
153
|
+
return pruned;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function main(): Promise<void> {
|
|
157
|
+
const args = parseArgs(process.argv.slice(2));
|
|
158
|
+
const dir = args.dir ?? defaultMemoryDir();
|
|
159
|
+
if (!dir || !existsSync(dir)) {
|
|
160
|
+
process.stderr.write(
|
|
161
|
+
`prune-old-memories: no memory dir found.\n` +
|
|
162
|
+
`Try: bun run scripts/prune-old-memories.ts --dir=<path>\n` +
|
|
163
|
+
`Default location: ~/.claude/projects/<encoded-cwd>/memory/\n`,
|
|
164
|
+
);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const candidates = findCandidates(dir, args.days);
|
|
169
|
+
|
|
170
|
+
if (candidates.length === 0) {
|
|
171
|
+
process.stdout.write(`prune-old-memories: no candidates older than ${args.days} days found in ${dir}\n`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
process.stdout.write(`prune-old-memories: ${candidates.length} candidate(s) older than ${args.days} days in:\n`);
|
|
176
|
+
process.stdout.write(` ${dir}\n\n`);
|
|
177
|
+
for (const c of candidates) {
|
|
178
|
+
process.stdout.write(` • ${c.name} (${c.ageDays}d old)\n`);
|
|
179
|
+
process.stdout.write(` reason: ${c.reason}\n`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!args.apply) {
|
|
183
|
+
process.stdout.write(`\nDry run — no files removed. Re-run with --apply to delete + remove from MEMORY.md.\n`);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Apply mode
|
|
188
|
+
let removed = 0;
|
|
189
|
+
const removedNames: string[] = [];
|
|
190
|
+
for (const c of candidates) {
|
|
191
|
+
try {
|
|
192
|
+
unlinkSync(c.path);
|
|
193
|
+
removed++;
|
|
194
|
+
removedNames.push(c.name);
|
|
195
|
+
} catch (e) {
|
|
196
|
+
process.stderr.write(` ✗ failed to delete ${c.name}: ${(e as Error).message}\n`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const indexPruned = pruneFromIndex(dir, removedNames);
|
|
200
|
+
process.stdout.write(`\nremoved ${removed} memory file(s); pruned ${indexPruned} MEMORY.md entry(ies).\n`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (import.meta.main) {
|
|
204
|
+
void main();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Re-export for testing
|
|
208
|
+
export { findCandidates, defaultMemoryDir, parseArgs, versionPrefix };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Publish ashlr-plugin to GitHub (public) and enable Pages for the /docs site.
|
|
3
|
+
# Also publishes @ashlr/core-efficiency if the sibling repo exists locally and
|
|
4
|
+
# hasn't been pushed yet. Safe to re-run — each step is a no-op if already done.
|
|
5
|
+
#
|
|
6
|
+
# Requires: gh CLI authed (gh auth status).
|
|
7
|
+
# Usage: ./scripts/publish.sh [--dry-run]
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
DRY_RUN=0
|
|
12
|
+
[ "${1:-}" = "--dry-run" ] && DRY_RUN=1
|
|
13
|
+
|
|
14
|
+
cyan() { printf "\033[36m%s\033[0m\n" "$*"; }
|
|
15
|
+
green() { printf "\033[32m%s\033[0m\n" "$*"; }
|
|
16
|
+
yellow() { printf "\033[33m%s\033[0m\n" "$*"; }
|
|
17
|
+
red() { printf "\033[31m%s\033[0m\n" "$*"; }
|
|
18
|
+
|
|
19
|
+
run() {
|
|
20
|
+
cyan "\$ $*"
|
|
21
|
+
if [ "$DRY_RUN" -eq 0 ]; then eval "$@"; fi
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if ! command -v gh >/dev/null; then
|
|
25
|
+
red "gh CLI not installed. https://cli.github.com"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
gh auth status >/dev/null 2>&1 || { red "gh not authed. Run: gh auth login"; exit 1; }
|
|
30
|
+
USER=$(gh api user --jq .login)
|
|
31
|
+
green "Authed as: $USER"
|
|
32
|
+
echo
|
|
33
|
+
|
|
34
|
+
STACK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
35
|
+
CORE_DIR="$(cd "$STACK_DIR/../ashlr-core-efficiency" 2>/dev/null && pwd || true)"
|
|
36
|
+
|
|
37
|
+
# --- 0. Pre-flight: verify the public manifests agree on the version ---
|
|
38
|
+
yellow "→ Checking version manifest sync…"
|
|
39
|
+
if ! (cd "$STACK_DIR" && bun run version:check); then
|
|
40
|
+
red "Version manifests are out of sync. Run: bun run version:bump <new-version>"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
echo
|
|
44
|
+
|
|
45
|
+
# --- 1. Publish @ashlr/core-efficiency (public) ---
|
|
46
|
+
if [ -n "$CORE_DIR" ] && [ -d "$CORE_DIR/.git" ]; then
|
|
47
|
+
cd "$CORE_DIR"
|
|
48
|
+
if ! git remote get-url origin >/dev/null 2>&1; then
|
|
49
|
+
yellow "→ ashlr-core-efficiency has no remote. Creating…"
|
|
50
|
+
run "gh repo create $USER/ashlr-core-efficiency --public --source . --description 'Token-efficiency primitives for Claude Code: genome, compression, provider-aware budgeting.' --push"
|
|
51
|
+
else
|
|
52
|
+
green "✓ ashlr-core-efficiency already has remote: $(git remote get-url origin)"
|
|
53
|
+
run "git push -u origin main 2>/dev/null || git push"
|
|
54
|
+
fi
|
|
55
|
+
else
|
|
56
|
+
yellow "⚠ skipping ashlr-core-efficiency — sibling repo not found at $STACK_DIR/../ashlr-core-efficiency"
|
|
57
|
+
fi
|
|
58
|
+
echo
|
|
59
|
+
|
|
60
|
+
# --- 2. Publish ashlr-plugin ---
|
|
61
|
+
cd "$STACK_DIR"
|
|
62
|
+
if ! git remote get-url origin >/dev/null 2>&1; then
|
|
63
|
+
yellow "→ ashlr-plugin has no remote. Creating…"
|
|
64
|
+
run "gh repo create $USER/ashlr-plugin --public --source . --description 'Open-source Claude Code plugin — token-efficient Read/Grep/Edit via @ashlr/core-efficiency. MIT.' --push"
|
|
65
|
+
else
|
|
66
|
+
green "✓ ashlr-plugin already has remote: $(git remote get-url origin)"
|
|
67
|
+
run "git push -u origin main 2>/dev/null || git push"
|
|
68
|
+
fi
|
|
69
|
+
echo
|
|
70
|
+
|
|
71
|
+
# --- 3. Enable GitHub Pages from /docs ---
|
|
72
|
+
yellow "→ Enabling GitHub Pages from /docs folder…"
|
|
73
|
+
PAGES_JSON=$(cat <<EOF
|
|
74
|
+
{"source":{"branch":"main","path":"/docs"}}
|
|
75
|
+
EOF
|
|
76
|
+
)
|
|
77
|
+
run "gh api -X POST /repos/$USER/ashlr-plugin/pages --input - <<< '$PAGES_JSON' 2>/dev/null || gh api -X PUT /repos/$USER/ashlr-plugin/pages --input - <<< '$PAGES_JSON' 2>/dev/null || echo '(pages may already be enabled)'"
|
|
78
|
+
echo
|
|
79
|
+
|
|
80
|
+
# --- 4. Report final URLs ---
|
|
81
|
+
green "Done."
|
|
82
|
+
echo " Plugin repo: https://github.com/$USER/ashlr-plugin"
|
|
83
|
+
echo " Landing page: https://plugin.ashlr.ai/"
|
|
84
|
+
echo " Core library repo: https://github.com/$USER/ashlr-core-efficiency"
|
|
85
|
+
echo
|
|
86
|
+
yellow "Install inside Claude Code:"
|
|
87
|
+
echo " /plugin marketplace add $USER/ashlr-plugin"
|
|
88
|
+
echo " /plugin install ashlr@ashlr-marketplace"
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* read-calibration — loads the empirical grep multiplier from
|
|
3
|
+
* ~/.ashlr/calibration.json (written by scripts/calibrate-grep.ts).
|
|
4
|
+
*
|
|
5
|
+
* Exports `getCalibrationMultiplier()` which efficiency-server.ts calls when
|
|
6
|
+
* computing the "tokens saved" credit for genome-routed greps.
|
|
7
|
+
*
|
|
8
|
+
* Caching: the result is memoized for the process lifetime. The calibration
|
|
9
|
+
* file is written rarely (only when the user explicitly runs calibrate-grep),
|
|
10
|
+
* so re-reading on every tool call is wasteful.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { existsSync, readFileSync } from "fs";
|
|
14
|
+
import { homedir } from "os";
|
|
15
|
+
import { join } from "path";
|
|
16
|
+
|
|
17
|
+
// Use process.env.HOME when set so test subprocesses on Windows can override
|
|
18
|
+
// the home directory (os.homedir() on Windows reads USERPROFILE, not HOME).
|
|
19
|
+
export const CALIBRATION_PATH = join(
|
|
20
|
+
process.env.HOME ?? homedir(),
|
|
21
|
+
".ashlr",
|
|
22
|
+
"calibration.json",
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
/** Default when no calibration has been run — conservative guess. */
|
|
26
|
+
export const DEFAULT_MULTIPLIER = 4;
|
|
27
|
+
|
|
28
|
+
export interface CalibrationFile {
|
|
29
|
+
updatedAt: string;
|
|
30
|
+
samples: CalibrationSample[];
|
|
31
|
+
meanRatio: number;
|
|
32
|
+
p50: number;
|
|
33
|
+
p90: number;
|
|
34
|
+
/** Mean ratio across only pattern-matched genome retrievals (excludes core-fallback + synthetic). */
|
|
35
|
+
measuredMean?: number;
|
|
36
|
+
/** Mean ratio across synthetic-only samples (no genome hit). */
|
|
37
|
+
syntheticMean?: number;
|
|
38
|
+
/** Number of samples that used a real pattern-matched genome retrieval. */
|
|
39
|
+
measuredCount?: number;
|
|
40
|
+
/** Mean ratio across core-fallback samples (genome present but pattern scored 0; constant-core output). */
|
|
41
|
+
coreFallbackMean?: number;
|
|
42
|
+
/** Number of samples that hit the core-fallback path. */
|
|
43
|
+
coreFallbackCount?: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface CalibrationSample {
|
|
47
|
+
cwd: string;
|
|
48
|
+
pattern: string;
|
|
49
|
+
rawBytes: number;
|
|
50
|
+
compressedBytes: number;
|
|
51
|
+
ratio: number;
|
|
52
|
+
/**
|
|
53
|
+
* "measured" — pattern scored > 0 against genome sections; compressedBytes is the real retrieval output.
|
|
54
|
+
* "core-fallback" — pattern scored 0; compressedBytes is the constant core-section output (north-star + milestone).
|
|
55
|
+
* Reflects real ashlr__grep behavior for non-matching queries, but the ratio is dominated by the constant
|
|
56
|
+
* numerator, not pattern-specific compression.
|
|
57
|
+
* "synthetic" — no genome present at all; compressedBytes = rawBytes / 4 (estimate, ratio always 4.0).
|
|
58
|
+
*/
|
|
59
|
+
quality: "measured" | "core-fallback" | "synthetic";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// In-process cache so we pay the file read exactly once per MCP server
|
|
63
|
+
// lifetime. Set to `null` to force a re-read (tests can clear this).
|
|
64
|
+
let _cached: number | null = null;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns the empirical mean ratio from ~/.ashlr/calibration.json, or
|
|
68
|
+
* DEFAULT_MULTIPLIER if the file is absent or malformed.
|
|
69
|
+
*
|
|
70
|
+
* The returned value is the multiplier applied to the genome-compressed output
|
|
71
|
+
* size to estimate what full ripgrep output would have cost.
|
|
72
|
+
*/
|
|
73
|
+
export function getCalibrationMultiplier(
|
|
74
|
+
calibrationPath: string = CALIBRATION_PATH,
|
|
75
|
+
): number {
|
|
76
|
+
// Return memoized value if already loaded (and using default path).
|
|
77
|
+
if (_cached !== null && calibrationPath === CALIBRATION_PATH) {
|
|
78
|
+
return _cached;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
if (!existsSync(calibrationPath)) {
|
|
83
|
+
_cached = DEFAULT_MULTIPLIER;
|
|
84
|
+
return DEFAULT_MULTIPLIER;
|
|
85
|
+
}
|
|
86
|
+
const raw = readFileSync(calibrationPath, "utf-8");
|
|
87
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
88
|
+
if (
|
|
89
|
+
typeof parsed !== "object" ||
|
|
90
|
+
parsed === null ||
|
|
91
|
+
typeof (parsed as Record<string, unknown>).meanRatio !== "number" ||
|
|
92
|
+
!Number.isFinite((parsed as Record<string, unknown>).meanRatio as number) ||
|
|
93
|
+
((parsed as Record<string, unknown>).meanRatio as number) <= 0
|
|
94
|
+
) {
|
|
95
|
+
_cached = DEFAULT_MULTIPLIER;
|
|
96
|
+
return DEFAULT_MULTIPLIER;
|
|
97
|
+
}
|
|
98
|
+
const file = parsed as CalibrationFile;
|
|
99
|
+
// Preference order:
|
|
100
|
+
// 1. measuredMean — pattern-matched genome retrievals (best signal)
|
|
101
|
+
// 2. coreFallbackMean — real ashlr__grep output for non-matching queries
|
|
102
|
+
// (still a measurement, just of the constant-core path)
|
|
103
|
+
// 3. meanRatio — overall, may be diluted by synthetic 4× estimates
|
|
104
|
+
const isUsable = (n: unknown): n is number =>
|
|
105
|
+
typeof n === "number" && Number.isFinite(n) && (n as number) > 0;
|
|
106
|
+
const ratio = isUsable(file.measuredMean) && (file.measuredCount ?? 0) > 0
|
|
107
|
+
? file.measuredMean
|
|
108
|
+
: isUsable(file.coreFallbackMean) && (file.coreFallbackCount ?? 0) > 0
|
|
109
|
+
? file.coreFallbackMean
|
|
110
|
+
: file.meanRatio;
|
|
111
|
+
if (calibrationPath === CALIBRATION_PATH) _cached = ratio;
|
|
112
|
+
return ratio;
|
|
113
|
+
} catch {
|
|
114
|
+
if (calibrationPath === CALIBRATION_PATH) _cached = DEFAULT_MULTIPLIER;
|
|
115
|
+
return DEFAULT_MULTIPLIER;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Clear the in-process cache (useful in tests). */
|
|
120
|
+
export function clearCalibrationCache(): void {
|
|
121
|
+
_cached = null;
|
|
122
|
+
}
|