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,467 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* ashlr grep calibration harness.
|
|
4
|
+
*
|
|
5
|
+
* Measures the empirical ratio between raw ripgrep output size and the genome-
|
|
6
|
+
* compressed size returned by ashlr__grep. Writes results to
|
|
7
|
+
* ~/.ashlr/calibration.json so efficiency-server.ts can replace its
|
|
8
|
+
* hardcoded 4× multiplier with a data-driven value.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* bun run scripts/calibrate-grep.ts
|
|
12
|
+
* bun run scripts/calibrate-grep.ts --workload /path/to/workload.jsonl
|
|
13
|
+
* bun run scripts/calibrate-grep.ts --out /path/to/calibration.json
|
|
14
|
+
*
|
|
15
|
+
* Workload format (~/.ashlr/calibration-workload.jsonl):
|
|
16
|
+
* { "cwd": "/path/to/project", "pattern": "someSymbol" }
|
|
17
|
+
* { "cwd": "/path/to/other", "pattern": "anotherPattern" }
|
|
18
|
+
*
|
|
19
|
+
* If no workload file is found, a bundled synthetic fixture is used instead
|
|
20
|
+
* (runs rg against the ashlr-plugin source tree itself).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { spawnSync } from "child_process";
|
|
24
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
25
|
+
import { homedir } from "os";
|
|
26
|
+
import { dirname, join, resolve } from "path";
|
|
27
|
+
|
|
28
|
+
import { type CalibrationFile, type CalibrationSample } from "./read-calibration";
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Types
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
interface Workload {
|
|
35
|
+
cwd: string;
|
|
36
|
+
pattern: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Helpers
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
function resolveRg(): string {
|
|
44
|
+
// Mirror the same resolution logic as efficiency-server.ts so we run the
|
|
45
|
+
// same binary.
|
|
46
|
+
return (
|
|
47
|
+
(typeof (globalThis as { Bun?: { which(b: string): string | null } }).Bun !== "undefined"
|
|
48
|
+
? (globalThis as { Bun: { which(b: string): string | null } }).Bun.which("rg")
|
|
49
|
+
: null) ??
|
|
50
|
+
["/opt/homebrew/bin/rg", "/usr/local/bin/rg", "/usr/bin/rg"].find((p) => {
|
|
51
|
+
try {
|
|
52
|
+
require("fs").accessSync(p);
|
|
53
|
+
return true;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}) ??
|
|
58
|
+
"rg"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Run `rg --json <pattern> <cwd>` and return the raw stdout bytes.
|
|
64
|
+
* Returns null if rg is unavailable or the call times out.
|
|
65
|
+
*/
|
|
66
|
+
function rgRawBytes(pattern: string, cwd: string): number | null {
|
|
67
|
+
try {
|
|
68
|
+
// `--` stops rg flag parsing so a workload with a pattern starting with
|
|
69
|
+
// `-` or `--` can't smuggle in flags like --invert-match or -uuu.
|
|
70
|
+
const res = spawnSync(resolveRg(), ["--json", "-n", "--", pattern, cwd], {
|
|
71
|
+
encoding: "buffer",
|
|
72
|
+
timeout: 10_000,
|
|
73
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
74
|
+
});
|
|
75
|
+
// status 0 = matches found, status 1 = no matches — both are valid.
|
|
76
|
+
if (res.status !== 0 && res.status !== 1) return null;
|
|
77
|
+
const buf = res.stdout as Buffer | null;
|
|
78
|
+
return buf ? buf.length : 0;
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Try to load genome helpers and retrieve compressed output size.
|
|
86
|
+
* Returns null when the genome is absent or the import fails.
|
|
87
|
+
*
|
|
88
|
+
* Root-cause fix (v1.29): the genome is a project-knowledge store (vision,
|
|
89
|
+
* strategies, milestones). Its TF-IDF scorer filters out any section with
|
|
90
|
+
* score === 0. Code-level patterns like "recordSaving" or "spawnSync" never
|
|
91
|
+
* appear in section tags/titles/summaries, so retrieveSectionsV2 returns [] for
|
|
92
|
+
* every synthetic workload pattern — causing the caller to fall through to the
|
|
93
|
+
* syntheticSampleNoGenome() 4× estimate.
|
|
94
|
+
*
|
|
95
|
+
* Fix: when retrieveSectionsV2 returns 0 sections (pattern has no genome match),
|
|
96
|
+
* retry with an empty query to get the *core* genome sections (north-star,
|
|
97
|
+
* current milestone, active strategies). These are what the real ashlr__grep
|
|
98
|
+
* tool returns for any query that scores zero sections — they represent the
|
|
99
|
+
* actual compressed output the tool would emit, giving a real measurement
|
|
100
|
+
* rather than the synthetic rawBytes/4 fallback.
|
|
101
|
+
*
|
|
102
|
+
* We try the @ashlr/core-efficiency import dynamically so the script still
|
|
103
|
+
* runs (in synthetic-fixture mode) on machines where the module is absent.
|
|
104
|
+
*/
|
|
105
|
+
async function genomeCompressedBytes(
|
|
106
|
+
pattern: string,
|
|
107
|
+
cwd: string,
|
|
108
|
+
): Promise<{ bytes: number; wasCoreFallback: boolean } | null> {
|
|
109
|
+
try {
|
|
110
|
+
// Dynamic imports so a missing genome doesn't throw at module load time.
|
|
111
|
+
const { genomeExists, retrieveSectionsV2, retrieveSections, formatGenomeForPrompt } =
|
|
112
|
+
await import("@ashlr/core-efficiency");
|
|
113
|
+
const { findParentGenome } = await import("./genome-link");
|
|
114
|
+
|
|
115
|
+
let genomeRoot: string | null = null;
|
|
116
|
+
if (genomeExists(cwd)) {
|
|
117
|
+
genomeRoot = cwd;
|
|
118
|
+
} else {
|
|
119
|
+
const parent = findParentGenome(cwd);
|
|
120
|
+
if (parent) genomeRoot = parent;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!genomeRoot) return null;
|
|
124
|
+
|
|
125
|
+
// First: try pattern-matched retrieval (semantic + TF-IDF).
|
|
126
|
+
let sections = await retrieveSectionsV2(genomeRoot, pattern, 4000);
|
|
127
|
+
let wasCoreFallback = false;
|
|
128
|
+
|
|
129
|
+
if (sections.length === 0) {
|
|
130
|
+
// Pattern scored 0 against all genome sections (expected for code-symbol
|
|
131
|
+
// patterns against a project-knowledge genome). Fall back to core sections
|
|
132
|
+
// (empty-query path in retrieveSections) — these are the actual bytes the
|
|
133
|
+
// real grep tool returns for unmatched queries. This gives a real ratio
|
|
134
|
+
// measurement rather than the synthetic rawBytes/4 estimate.
|
|
135
|
+
sections = await retrieveSections(genomeRoot, "", 4000);
|
|
136
|
+
wasCoreFallback = true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (sections.length === 0) return null;
|
|
140
|
+
const formatted = formatGenomeForPrompt(sections);
|
|
141
|
+
return { bytes: formatted.length, wasCoreFallback };
|
|
142
|
+
} catch {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
// Synthetic fixture (used when no real workload is available)
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Build a synthetic workload that runs rg against the ashlr-plugin source
|
|
153
|
+
* tree. These patterns are representative of typical agent queries.
|
|
154
|
+
*/
|
|
155
|
+
function syntheticWorkload(): Workload[] {
|
|
156
|
+
// Use __dirname-equivalent: the directory of this script.
|
|
157
|
+
const pluginRoot = resolve(dirname(new URL(import.meta.url).pathname), "..");
|
|
158
|
+
return [
|
|
159
|
+
{ cwd: pluginRoot, pattern: "recordSaving" },
|
|
160
|
+
{ cwd: pluginRoot, pattern: "retrieveSectionsV2" },
|
|
161
|
+
{ cwd: pluginRoot, pattern: "genomeExists" },
|
|
162
|
+
{ cwd: pluginRoot, pattern: "spawnSync" },
|
|
163
|
+
{ cwd: pluginRoot, pattern: "estimateTokens" },
|
|
164
|
+
{ cwd: pluginRoot, pattern: "tokensSaved" },
|
|
165
|
+
{ cwd: pluginRoot, pattern: "formatBaseline" },
|
|
166
|
+
{ cwd: pluginRoot, pattern: "snipCompact" },
|
|
167
|
+
];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Build a synthetic workload using only rg raw sizes (no genome required).
|
|
172
|
+
* Used when genome isn't available — we still measure rg output sizes so the
|
|
173
|
+
* calibration data is available for future use once a genome is created.
|
|
174
|
+
*
|
|
175
|
+
* In this mode we compute ratio = rawBytes / (rawBytes / 4) = 4.0 as a
|
|
176
|
+
* passthrough. The sample is flagged quality="synthetic" so callers can
|
|
177
|
+
* detect and warn about the bogus estimate.
|
|
178
|
+
*/
|
|
179
|
+
function syntheticSampleNoGenome(w: Workload, rawBytes: number): CalibrationSample {
|
|
180
|
+
// Without a genome we can't compress, so we estimate compressed = raw/4.
|
|
181
|
+
// quality="synthetic" lets the report warn about low-quality samples.
|
|
182
|
+
const compressedBytes = Math.max(1, Math.round(rawBytes / 4));
|
|
183
|
+
return {
|
|
184
|
+
cwd: w.cwd,
|
|
185
|
+
pattern: w.pattern,
|
|
186
|
+
rawBytes,
|
|
187
|
+
compressedBytes,
|
|
188
|
+
ratio: rawBytes / compressedBytes,
|
|
189
|
+
quality: "synthetic",
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Stats helpers
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
|
|
197
|
+
function percentile(sorted: number[], p: number): number {
|
|
198
|
+
if (sorted.length === 0) return 0;
|
|
199
|
+
const idx = Math.min(
|
|
200
|
+
sorted.length - 1,
|
|
201
|
+
Math.floor((p / 100) * sorted.length),
|
|
202
|
+
);
|
|
203
|
+
return sorted[idx]!;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function mean(values: number[]): number {
|
|
207
|
+
if (values.length === 0) return 0;
|
|
208
|
+
return values.reduce((s, v) => s + v, 0) / values.length;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// Report rendering
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
|
|
215
|
+
function renderReport(
|
|
216
|
+
samples: CalibrationSample[],
|
|
217
|
+
meanRatio: number,
|
|
218
|
+
p50: number,
|
|
219
|
+
p90: number,
|
|
220
|
+
outPath: string,
|
|
221
|
+
measuredMean?: number,
|
|
222
|
+
syntheticMean?: number,
|
|
223
|
+
measuredCount?: number,
|
|
224
|
+
coreFallbackMean?: number,
|
|
225
|
+
coreFallbackCount?: number,
|
|
226
|
+
): string {
|
|
227
|
+
const lines: string[] = [];
|
|
228
|
+
lines.push("ashlr grep calibration report");
|
|
229
|
+
lines.push("═".repeat(50));
|
|
230
|
+
lines.push("");
|
|
231
|
+
|
|
232
|
+
if (samples.length === 0) {
|
|
233
|
+
lines.push("No samples collected. Check that rg is installed and patterns match files.");
|
|
234
|
+
return lines.join("\n");
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Per-sample table
|
|
238
|
+
lines.push("samples:");
|
|
239
|
+
const hdr = " pattern".padEnd(30) + "raw bytes".padEnd(12) + "compressed".padEnd(13) + "ratio".padEnd(9) + "quality";
|
|
240
|
+
lines.push(hdr);
|
|
241
|
+
lines.push(" " + "─".repeat(72));
|
|
242
|
+
for (const s of samples) {
|
|
243
|
+
const pat = s.pattern.slice(0, 26).padEnd(28);
|
|
244
|
+
const raw = s.rawBytes.toLocaleString().padEnd(10);
|
|
245
|
+
const comp = s.compressedBytes.toLocaleString().padEnd(11);
|
|
246
|
+
const ratio = (s.ratio.toFixed(2) + "×").padEnd(7);
|
|
247
|
+
const quality = s.quality ?? "synthetic";
|
|
248
|
+
lines.push(` ${pat} ${raw} ${comp} ${ratio} ${quality}`);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Counts: prefer caller-supplied; otherwise derive from samples to stay
|
|
252
|
+
// consistent with the per-sample quality flags.
|
|
253
|
+
const cfCount = coreFallbackCount ?? samples.filter((s) => s.quality === "core-fallback").length;
|
|
254
|
+
const synCount =
|
|
255
|
+
samples.length - (measuredCount ?? samples.filter((s) => s.quality === "measured").length) - cfCount;
|
|
256
|
+
const syntheticPct = ((synCount / samples.length) * 100).toFixed(0);
|
|
257
|
+
|
|
258
|
+
lines.push("");
|
|
259
|
+
lines.push("aggregate:");
|
|
260
|
+
lines.push(` samples ${samples.length}`);
|
|
261
|
+
if ((measuredCount ?? 0) > 0) {
|
|
262
|
+
lines.push(` measured ${measuredCount ?? 0} (pattern-matched genome retrieval)`);
|
|
263
|
+
}
|
|
264
|
+
if (cfCount > 0) {
|
|
265
|
+
lines.push(` core-fallback ${cfCount} (no pattern match — constant core-section output)`);
|
|
266
|
+
}
|
|
267
|
+
if (synCount > 0) {
|
|
268
|
+
lines.push(` synthetic ${synCount} (${syntheticPct}% — 4× estimate, no genome present)`);
|
|
269
|
+
}
|
|
270
|
+
if ((measuredCount ?? 0) > 0 && measuredMean !== undefined) {
|
|
271
|
+
lines.push(` measuredMean ${measuredMean.toFixed(2)}× ← used by efficiency-server`);
|
|
272
|
+
}
|
|
273
|
+
if (cfCount > 0 && coreFallbackMean !== undefined) {
|
|
274
|
+
lines.push(` coreFbMean ${coreFallbackMean.toFixed(2)}×`);
|
|
275
|
+
}
|
|
276
|
+
if (synCount > 0 && syntheticMean !== undefined) {
|
|
277
|
+
lines.push(` syntheticMean ${syntheticMean.toFixed(2)}×`);
|
|
278
|
+
}
|
|
279
|
+
lines.push(` overallMean ${meanRatio.toFixed(2)}×`);
|
|
280
|
+
lines.push(` p50 ${p50.toFixed(2)}×`);
|
|
281
|
+
lines.push(` p90 ${p90.toFixed(2)}×`);
|
|
282
|
+
|
|
283
|
+
if (synCount > 0 && synCount > (samples.length / 2)) {
|
|
284
|
+
lines.push("");
|
|
285
|
+
lines.push(
|
|
286
|
+
` WARNING: ${syntheticPct}% of samples are synthetic (no genome match). ` +
|
|
287
|
+
`Run /ashlr-genome-init to index this project's code for real measurements.`,
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
if (cfCount > 0 && (measuredCount ?? 0) === 0) {
|
|
291
|
+
lines.push("");
|
|
292
|
+
lines.push(
|
|
293
|
+
` NOTE: every genome-engaged sample fell to core-fallback. The mean ratio ` +
|
|
294
|
+
`reflects ashlr__grep behavior on non-matching queries, not pattern-specific ` +
|
|
295
|
+
`compression. Refresh the genome to improve pattern match rates.`,
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
lines.push("");
|
|
300
|
+
lines.push(`written → ${outPath}`);
|
|
301
|
+
lines.push("");
|
|
302
|
+
lines.push(
|
|
303
|
+
`To activate: efficiency-server will read this file automatically on next start.`,
|
|
304
|
+
);
|
|
305
|
+
return lines.join("\n");
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// ---------------------------------------------------------------------------
|
|
309
|
+
// CLI argument parsing
|
|
310
|
+
// ---------------------------------------------------------------------------
|
|
311
|
+
|
|
312
|
+
interface CliArgs {
|
|
313
|
+
workloadPath?: string;
|
|
314
|
+
outPath: string;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function parseArgs(argv: string[]): CliArgs {
|
|
318
|
+
let workloadPath: string | undefined;
|
|
319
|
+
let outPath = join(homedir(), ".ashlr", "calibration.json");
|
|
320
|
+
for (let i = 0; i < argv.length; i++) {
|
|
321
|
+
const a = argv[i];
|
|
322
|
+
if ((a === "--workload" || a === "-w") && argv[i + 1]) {
|
|
323
|
+
workloadPath = argv[++i];
|
|
324
|
+
} else if ((a === "--out" || a === "-o") && argv[i + 1]) {
|
|
325
|
+
outPath = argv[++i];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return { workloadPath, outPath };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ---------------------------------------------------------------------------
|
|
332
|
+
// Main
|
|
333
|
+
// ---------------------------------------------------------------------------
|
|
334
|
+
|
|
335
|
+
export async function runCalibration(opts: {
|
|
336
|
+
workloadPath?: string;
|
|
337
|
+
outPath?: string;
|
|
338
|
+
}): Promise<CalibrationFile> {
|
|
339
|
+
const outPath = opts.outPath ?? join(homedir(), ".ashlr", "calibration.json");
|
|
340
|
+
|
|
341
|
+
// 1. Load workload
|
|
342
|
+
let workloads: Workload[];
|
|
343
|
+
const defaultWorkloadPath = join(homedir(), ".ashlr", "calibration-workload.jsonl");
|
|
344
|
+
|
|
345
|
+
const resolvedWorkloadPath = opts.workloadPath ?? (existsSync(defaultWorkloadPath) ? defaultWorkloadPath : null);
|
|
346
|
+
if (resolvedWorkloadPath && existsSync(resolvedWorkloadPath)) {
|
|
347
|
+
const raw = readFileSync(resolvedWorkloadPath, "utf-8");
|
|
348
|
+
workloads = raw
|
|
349
|
+
.split("\n")
|
|
350
|
+
.map((l) => l.trim())
|
|
351
|
+
.filter((l) => l.length > 0)
|
|
352
|
+
.map((l) => JSON.parse(l) as Workload);
|
|
353
|
+
process.stdout.write(`Loaded ${workloads.length} workload(s) from ${resolvedWorkloadPath}\n`);
|
|
354
|
+
} else {
|
|
355
|
+
workloads = syntheticWorkload();
|
|
356
|
+
process.stdout.write(`No workload file found — using ${workloads.length} synthetic fixture(s)\n`);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// 2. Run each workload
|
|
360
|
+
const samples: CalibrationSample[] = [];
|
|
361
|
+
process.stdout.write(`\nRunning calibration against ${workloads.length} pattern(s)...\n`);
|
|
362
|
+
|
|
363
|
+
for (const w of workloads) {
|
|
364
|
+
const cwdAbs = resolve(w.cwd);
|
|
365
|
+
process.stdout.write(` rg ${JSON.stringify(w.pattern)} in ${cwdAbs} ... `);
|
|
366
|
+
|
|
367
|
+
const rawBytes = rgRawBytes(w.pattern, cwdAbs);
|
|
368
|
+
if (rawBytes === null) {
|
|
369
|
+
process.stdout.write("rg unavailable, skipped\n");
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
if (rawBytes === 0) {
|
|
373
|
+
process.stdout.write("no matches, skipped\n");
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Try genome path first
|
|
378
|
+
const genomeResult = await genomeCompressedBytes(w.pattern, cwdAbs);
|
|
379
|
+
if (genomeResult !== null && genomeResult.bytes > 0) {
|
|
380
|
+
const { bytes: compressedBytes, wasCoreFallback } = genomeResult;
|
|
381
|
+
const ratio = rawBytes / compressedBytes;
|
|
382
|
+
const qualityNote = wasCoreFallback ? " (core-fallback)" : "";
|
|
383
|
+
samples.push({
|
|
384
|
+
cwd: cwdAbs,
|
|
385
|
+
pattern: w.pattern,
|
|
386
|
+
rawBytes,
|
|
387
|
+
compressedBytes,
|
|
388
|
+
ratio,
|
|
389
|
+
quality: wasCoreFallback ? "core-fallback" : "measured",
|
|
390
|
+
});
|
|
391
|
+
process.stdout.write(
|
|
392
|
+
`raw=${rawBytes} compressed=${compressedBytes} ratio=${ratio.toFixed(2)}×${qualityNote}\n`,
|
|
393
|
+
);
|
|
394
|
+
} else {
|
|
395
|
+
// No genome — use synthetic estimate so we still have a data point
|
|
396
|
+
const s = syntheticSampleNoGenome(w, rawBytes);
|
|
397
|
+
samples.push(s);
|
|
398
|
+
process.stdout.write(`raw=${rawBytes} (no genome, estimated ratio=${s.ratio.toFixed(2)}×)\n`);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// 3. Compute stats — split measured / core-fallback / synthetic. "measured"
|
|
403
|
+
// is reserved for pattern-matched genome retrievals; core-fallback samples
|
|
404
|
+
// reflect real ashlr__grep behavior for non-matching queries but their
|
|
405
|
+
// ratio is dominated by a constant numerator, so we surface them
|
|
406
|
+
// separately rather than letting them inflate `measuredMean`.
|
|
407
|
+
const measuredSamples = samples.filter((s) => s.quality === "measured");
|
|
408
|
+
const coreFallbackSamples = samples.filter((s) => s.quality === "core-fallback");
|
|
409
|
+
const syntheticSamples = samples.filter((s) => s.quality === "synthetic");
|
|
410
|
+
|
|
411
|
+
const allRatios = samples.map((s) => s.ratio).sort((a, b) => a - b);
|
|
412
|
+
const measuredRatios = measuredSamples.map((s) => s.ratio);
|
|
413
|
+
const coreFallbackRatios = coreFallbackSamples.map((s) => s.ratio);
|
|
414
|
+
const syntheticRatios = syntheticSamples.map((s) => s.ratio);
|
|
415
|
+
|
|
416
|
+
const meanRatio = mean(allRatios);
|
|
417
|
+
const measuredMean = measuredRatios.length > 0 ? mean(measuredRatios) : undefined;
|
|
418
|
+
const coreFallbackMean = coreFallbackRatios.length > 0 ? mean(coreFallbackRatios) : undefined;
|
|
419
|
+
const syntheticMean = syntheticRatios.length > 0 ? mean(syntheticRatios) : undefined;
|
|
420
|
+
const p50 = percentile(allRatios, 50);
|
|
421
|
+
const p90 = percentile(allRatios, 90);
|
|
422
|
+
|
|
423
|
+
// 4. Write calibration.json
|
|
424
|
+
const result: CalibrationFile = {
|
|
425
|
+
updatedAt: new Date().toISOString(),
|
|
426
|
+
samples,
|
|
427
|
+
meanRatio: samples.length > 0 ? meanRatio : 4,
|
|
428
|
+
p50: samples.length > 0 ? p50 : 4,
|
|
429
|
+
p90: samples.length > 0 ? p90 : 4,
|
|
430
|
+
measuredMean,
|
|
431
|
+
syntheticMean,
|
|
432
|
+
measuredCount: measuredSamples.length,
|
|
433
|
+
coreFallbackMean,
|
|
434
|
+
coreFallbackCount: coreFallbackSamples.length,
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
438
|
+
writeFileSync(outPath, JSON.stringify(result, null, 2));
|
|
439
|
+
|
|
440
|
+
// 5. Print report
|
|
441
|
+
process.stdout.write(
|
|
442
|
+
"\n" +
|
|
443
|
+
renderReport(
|
|
444
|
+
samples,
|
|
445
|
+
result.meanRatio,
|
|
446
|
+
result.p50,
|
|
447
|
+
result.p90,
|
|
448
|
+
outPath,
|
|
449
|
+
measuredMean,
|
|
450
|
+
syntheticMean,
|
|
451
|
+
measuredSamples.length,
|
|
452
|
+
coreFallbackMean,
|
|
453
|
+
coreFallbackSamples.length,
|
|
454
|
+
) +
|
|
455
|
+
"\n",
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Exported for tests
|
|
462
|
+
export { percentile, mean, renderReport, syntheticWorkload, syntheticSampleNoGenome };
|
|
463
|
+
|
|
464
|
+
if (import.meta.main) {
|
|
465
|
+
const args = parseArgs(process.argv.slice(2));
|
|
466
|
+
await runCalibration({ workloadPath: args.workloadPath, outPath: args.outPath });
|
|
467
|
+
}
|