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,104 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* embed-file-worker.ts — Detached worker: read file(s) and upsert into the
|
|
4
|
+
* embedding cache. Spawned fire-and-forget by the post-tool-use-embedding hook.
|
|
5
|
+
*
|
|
6
|
+
* Usage: bun run scripts/embed-file-worker.ts <path1> [path2 ...]
|
|
7
|
+
*
|
|
8
|
+
* Exits quickly — designed to run in the background with no blocking callers.
|
|
9
|
+
*
|
|
10
|
+
* AST chunking: TS/JS sources are split into top-level symbol chunks so each
|
|
11
|
+
* function/class/type gets its own embedding and retrieval can surface the
|
|
12
|
+
* exact symbol that matches a query. Unsupported languages fall back to a
|
|
13
|
+
* single whole-file embedding (same behaviour as before).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { readFileSync, existsSync, statSync } from "fs";
|
|
17
|
+
import { createHash } from "crypto";
|
|
18
|
+
import { clampToCwd } from "../servers/_cwd-clamp";
|
|
19
|
+
import { openContextDb } from "../servers/_embedding-cache";
|
|
20
|
+
import { embed, flushCorpusNow, upsertCorpus } from "../servers/_embedding-model";
|
|
21
|
+
import { chunkToRagString, splitFileIntoChunks } from "../servers/_ast-chunker";
|
|
22
|
+
|
|
23
|
+
if (process.env.ASHLR_CONTEXT_DB_DISABLE === "1") process.exit(0);
|
|
24
|
+
|
|
25
|
+
const MAX_FILE_BYTES = 100_000; // skip huge files
|
|
26
|
+
const cwd = process.env.PWD ?? process.cwd();
|
|
27
|
+
|
|
28
|
+
/** Stable 8-char project hash from absolute cwd. */
|
|
29
|
+
function projectHash(dir: string): string {
|
|
30
|
+
return createHash("sha256").update(dir).digest("hex").slice(0, 8);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const paths = process.argv.slice(2);
|
|
34
|
+
if (paths.length === 0) process.exit(0);
|
|
35
|
+
|
|
36
|
+
const ctxDb = openContextDb();
|
|
37
|
+
const pHash = projectHash(cwd);
|
|
38
|
+
|
|
39
|
+
async function processFile(relPath: string): Promise<void> {
|
|
40
|
+
// The hook payload is attacker-controllable via prompt-injected tool
|
|
41
|
+
// calls. Use the shared clampToCwd which canonicalizes via realpathSync
|
|
42
|
+
// on both sides — a raw string-level relative() check is defeated by
|
|
43
|
+
// symlinks (e.g. macOS /var → /private/var).
|
|
44
|
+
const clamp = clampToCwd(relPath, "embed-file-worker");
|
|
45
|
+
if (!clamp.ok) return;
|
|
46
|
+
const abs = clamp.abs;
|
|
47
|
+
if (!existsSync(abs)) return;
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const stat = statSync(abs);
|
|
51
|
+
if (!stat.isFile() || stat.size > MAX_FILE_BYTES) return;
|
|
52
|
+
|
|
53
|
+
const text = readFileSync(abs, "utf-8");
|
|
54
|
+
if (text.length < 20) return; // nothing useful to embed
|
|
55
|
+
|
|
56
|
+
upsertCorpus(text);
|
|
57
|
+
|
|
58
|
+
// Prefer per-symbol AST chunks so large files don't flatten into a single
|
|
59
|
+
// blurry embedding. Returns null for unsupported languages (fall through
|
|
60
|
+
// to the whole-file path below).
|
|
61
|
+
let chunks: Awaited<ReturnType<typeof splitFileIntoChunks>> = null;
|
|
62
|
+
try {
|
|
63
|
+
chunks = await splitFileIntoChunks(abs);
|
|
64
|
+
} catch {
|
|
65
|
+
chunks = null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (chunks && chunks.length > 0) {
|
|
69
|
+
for (const chunk of chunks) {
|
|
70
|
+
const rag = chunkToRagString(chunk);
|
|
71
|
+
if (rag.length < 20) continue;
|
|
72
|
+
const vec = await embed(rag);
|
|
73
|
+
ctxDb.upsertEmbedding({
|
|
74
|
+
projectHash: pHash,
|
|
75
|
+
sectionPath: `${abs}#${chunk.symbol}`,
|
|
76
|
+
sectionText: rag.slice(0, 2000),
|
|
77
|
+
embedding: vec,
|
|
78
|
+
embeddingDim: vec.length,
|
|
79
|
+
source: "code",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const vec = await embed(text.slice(0, 4000));
|
|
86
|
+
ctxDb.upsertEmbedding({
|
|
87
|
+
projectHash: pHash,
|
|
88
|
+
sectionPath: abs,
|
|
89
|
+
sectionText: text.slice(0, 1000),
|
|
90
|
+
embedding: vec,
|
|
91
|
+
embeddingDim: vec.length,
|
|
92
|
+
source: "code",
|
|
93
|
+
});
|
|
94
|
+
} catch {
|
|
95
|
+
/* best-effort — never crash the worker */
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Process all files, then drain pending IDF deltas before exit so the
|
|
100
|
+
// setImmediate scheduler doesn't lose them in the exit race.
|
|
101
|
+
await Promise.all(paths.map(processFile));
|
|
102
|
+
await flushCorpusNow();
|
|
103
|
+
ctxDb.close();
|
|
104
|
+
process.exit(0);
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* embed-tune.ts — Threshold tuner for the embedding cache.
|
|
4
|
+
*
|
|
5
|
+
* Reads ~/.ashlr/embed-calibration.jsonl (written by servers/_embed-calibration.ts
|
|
6
|
+
* on every grep call) and sweeps cosine similarity thresholds to find the
|
|
7
|
+
* value that maximises F1 (or a user-weighted F-beta variant).
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* bun run scripts/embed-tune.ts
|
|
11
|
+
* bun run scripts/embed-tune.ts --input ~/.ashlr/embed-calibration.jsonl
|
|
12
|
+
* bun run scripts/embed-tune.ts --weight precision=2 # penalise false-positives
|
|
13
|
+
* bun run scripts/embed-tune.ts --apply # write to ~/.ashlr/config.json
|
|
14
|
+
*
|
|
15
|
+
* Output (stdout):
|
|
16
|
+
* current threshold 0.68 → precision 0.72 recall 0.81
|
|
17
|
+
* recommended 0.71 → precision 0.78 recall 0.76 F1 0.77
|
|
18
|
+
* Set via ASHLR_EMBED_THRESHOLD=0.71 or use --apply to persist.
|
|
19
|
+
*
|
|
20
|
+
* With --apply, writes embedThreshold to ~/.ashlr/config.json and prints
|
|
21
|
+
* "restart Claude Code to apply".
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
25
|
+
import { homedir } from "os";
|
|
26
|
+
import { dirname, join } from "path";
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Types
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
export interface CalibrationEntry {
|
|
33
|
+
ts: string;
|
|
34
|
+
queryHashHex: string;
|
|
35
|
+
topSimilarity: number;
|
|
36
|
+
/** true = the cached result was used (hit); false = skipped (miss) */
|
|
37
|
+
hit: boolean;
|
|
38
|
+
contentLength: number;
|
|
39
|
+
threshold: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ThresholdStats {
|
|
43
|
+
threshold: number;
|
|
44
|
+
/** fraction of queries that would be served from cache */
|
|
45
|
+
recall: number;
|
|
46
|
+
/**
|
|
47
|
+
* of those served from cache, fraction that were genuinely "good" hits
|
|
48
|
+
* (defined as: original hit=true at any threshold, i.e. high-quality match).
|
|
49
|
+
* When all calibration data was recorded at the same threshold, we treat
|
|
50
|
+
* "hit=true" as ground-truth positive.
|
|
51
|
+
*/
|
|
52
|
+
precision: number;
|
|
53
|
+
/** F-beta score combining precision and recall */
|
|
54
|
+
fBeta: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface TuneResult {
|
|
58
|
+
currentThreshold: number;
|
|
59
|
+
currentStats: ThresholdStats;
|
|
60
|
+
recommendedThreshold: number;
|
|
61
|
+
recommendedStats: ThresholdStats;
|
|
62
|
+
allStats: ThresholdStats[];
|
|
63
|
+
betaWeight: number;
|
|
64
|
+
entryCount: number;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Paths
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
function defaultCalibPath(): string {
|
|
72
|
+
return join(process.env.HOME ?? homedir(), ".ashlr", "embed-calibration.jsonl");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function defaultConfigPath(): string {
|
|
76
|
+
return join(process.env.HOME ?? homedir(), ".ashlr", "config.json");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// I/O
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
export function loadCalibrationEntries(inputPath: string): CalibrationEntry[] {
|
|
84
|
+
if (!existsSync(inputPath)) return [];
|
|
85
|
+
const lines = readFileSync(inputPath, "utf-8").split("\n").filter((l) => l.trim());
|
|
86
|
+
const entries: CalibrationEntry[] = [];
|
|
87
|
+
for (const line of lines) {
|
|
88
|
+
try {
|
|
89
|
+
entries.push(JSON.parse(line) as CalibrationEntry);
|
|
90
|
+
} catch {
|
|
91
|
+
// Skip malformed lines.
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return entries;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Core sweep algorithm
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* For a given threshold, compute precision and recall.
|
|
103
|
+
*
|
|
104
|
+
* Ground truth:
|
|
105
|
+
* - "Positive" = the original calibration record had hit=true (the cached
|
|
106
|
+
* result was actually used). These are the genuinely useful retrievals.
|
|
107
|
+
* - At a swept threshold T, a query "would hit" iff topSimilarity >= T.
|
|
108
|
+
*
|
|
109
|
+
* Definitions:
|
|
110
|
+
* recall = |{would hit at T} ∩ {ground-truth positive}| / |{ground-truth positive}|
|
|
111
|
+
* i.e. fraction of real hits we'd serve from cache
|
|
112
|
+
* precision = |{would hit at T} ∩ {ground-truth positive}| / |{would hit at T}|
|
|
113
|
+
* i.e. fraction of cache hits that are genuine
|
|
114
|
+
*
|
|
115
|
+
* When |{would hit at T}| = 0, precision is defined as 1.0 (no false positives).
|
|
116
|
+
* When |{ground-truth positive}| = 0, recall is 0.
|
|
117
|
+
*/
|
|
118
|
+
export function computeStats(
|
|
119
|
+
entries: CalibrationEntry[],
|
|
120
|
+
threshold: number,
|
|
121
|
+
betaWeight: number,
|
|
122
|
+
): ThresholdStats {
|
|
123
|
+
const totalPositives = entries.filter((e) => e.hit).length;
|
|
124
|
+
const wouldHit = entries.filter((e) => e.topSimilarity >= threshold);
|
|
125
|
+
const truePositives = wouldHit.filter((e) => e.hit).length;
|
|
126
|
+
|
|
127
|
+
const precision = wouldHit.length === 0 ? 1.0 : truePositives / wouldHit.length;
|
|
128
|
+
const recall = totalPositives === 0 ? 0 : truePositives / totalPositives;
|
|
129
|
+
|
|
130
|
+
// F-beta: (1 + beta^2) * P * R / (beta^2 * P + R)
|
|
131
|
+
const beta2 = betaWeight * betaWeight;
|
|
132
|
+
const fBeta =
|
|
133
|
+
precision + recall === 0
|
|
134
|
+
? 0
|
|
135
|
+
: ((1 + beta2) * precision * recall) / (beta2 * precision + recall);
|
|
136
|
+
|
|
137
|
+
return { threshold, precision, recall, fBeta };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Sweep thresholds from 0.50 → 0.95 in 0.01 steps.
|
|
142
|
+
* Returns stats for every step, sorted ascending by threshold.
|
|
143
|
+
*/
|
|
144
|
+
export function sweepThresholds(
|
|
145
|
+
entries: CalibrationEntry[],
|
|
146
|
+
betaWeight: number,
|
|
147
|
+
): ThresholdStats[] {
|
|
148
|
+
const results: ThresholdStats[] = [];
|
|
149
|
+
for (let t = 50; t <= 95; t++) {
|
|
150
|
+
const threshold = t / 100;
|
|
151
|
+
results.push(computeStats(entries, threshold, betaWeight));
|
|
152
|
+
}
|
|
153
|
+
return results;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Main tuner logic
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
export function tune(
|
|
161
|
+
entries: CalibrationEntry[],
|
|
162
|
+
currentThreshold: number,
|
|
163
|
+
betaWeight: number,
|
|
164
|
+
): TuneResult {
|
|
165
|
+
const allStats = sweepThresholds(entries, betaWeight);
|
|
166
|
+
|
|
167
|
+
// Pick the threshold with the highest F-beta.
|
|
168
|
+
const best = allStats.reduce((a, b) => (b.fBeta > a.fBeta ? b : a));
|
|
169
|
+
|
|
170
|
+
// Stats at the current threshold (nearest 0.01 step).
|
|
171
|
+
const currentRounded = Math.round(currentThreshold * 100) / 100;
|
|
172
|
+
const currentStats =
|
|
173
|
+
allStats.find((s) => Math.abs(s.threshold - currentRounded) < 0.001) ??
|
|
174
|
+
computeStats(entries, currentThreshold, betaWeight);
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
currentThreshold,
|
|
178
|
+
currentStats,
|
|
179
|
+
recommendedThreshold: best.threshold,
|
|
180
|
+
recommendedStats: best,
|
|
181
|
+
allStats,
|
|
182
|
+
betaWeight,
|
|
183
|
+
entryCount: entries.length,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// Formatting
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
|
|
191
|
+
function fmt(n: number): string {
|
|
192
|
+
return n.toFixed(2);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function renderReport(result: TuneResult): string {
|
|
196
|
+
const lines: string[] = [];
|
|
197
|
+
|
|
198
|
+
lines.push("ashlr embed-tune report");
|
|
199
|
+
lines.push("─".repeat(50));
|
|
200
|
+
lines.push(` entries analysed : ${result.entryCount}`);
|
|
201
|
+
lines.push(` beta weight : ${result.betaWeight} (F${result.betaWeight} score)`);
|
|
202
|
+
lines.push("");
|
|
203
|
+
|
|
204
|
+
if (result.entryCount === 0) {
|
|
205
|
+
lines.push(" No calibration data found.");
|
|
206
|
+
lines.push(" Run some grep operations via ashlr to populate ~/.ashlr/embed-calibration.jsonl");
|
|
207
|
+
return lines.join("\n");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const c = result.currentStats;
|
|
211
|
+
const r = result.recommendedStats;
|
|
212
|
+
|
|
213
|
+
lines.push(
|
|
214
|
+
` current threshold ${fmt(result.currentThreshold)}` +
|
|
215
|
+
` → precision ${fmt(c.precision)} recall ${fmt(c.recall)} F${result.betaWeight} ${fmt(c.fBeta)}`,
|
|
216
|
+
);
|
|
217
|
+
lines.push(
|
|
218
|
+
` recommended ${fmt(r.threshold)}` +
|
|
219
|
+
` → precision ${fmt(r.precision)} recall ${fmt(r.recall)} F${result.betaWeight} ${fmt(r.fBeta)}`,
|
|
220
|
+
);
|
|
221
|
+
lines.push("");
|
|
222
|
+
|
|
223
|
+
const delta = r.threshold - result.currentThreshold;
|
|
224
|
+
if (Math.abs(delta) < 0.005) {
|
|
225
|
+
lines.push(" Current threshold is already optimal.");
|
|
226
|
+
} else {
|
|
227
|
+
lines.push(
|
|
228
|
+
` Set via: ASHLR_EMBED_THRESHOLD=${fmt(r.threshold)}`,
|
|
229
|
+
);
|
|
230
|
+
lines.push(` Or run with --apply to persist to ~/.ashlr/config.json`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return lines.join("\n");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// Config persistence (--apply)
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
|
|
240
|
+
export function applyThreshold(threshold: number, configPath: string): void {
|
|
241
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
242
|
+
let existing: Record<string, unknown> = {};
|
|
243
|
+
if (existsSync(configPath)) {
|
|
244
|
+
try {
|
|
245
|
+
existing = JSON.parse(readFileSync(configPath, "utf-8")) as Record<string, unknown>;
|
|
246
|
+
} catch {
|
|
247
|
+
existing = {};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
existing.embedThreshold = threshold;
|
|
251
|
+
writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// CLI entry point
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
|
|
258
|
+
function parseArgs(argv: string[]): {
|
|
259
|
+
input: string;
|
|
260
|
+
betaWeight: number;
|
|
261
|
+
apply: boolean;
|
|
262
|
+
configPath: string;
|
|
263
|
+
} {
|
|
264
|
+
let input = defaultCalibPath();
|
|
265
|
+
let betaWeight = 1.0;
|
|
266
|
+
let apply = false;
|
|
267
|
+
let configPath = defaultConfigPath();
|
|
268
|
+
|
|
269
|
+
for (let i = 0; i < argv.length; i++) {
|
|
270
|
+
const arg = argv[i];
|
|
271
|
+
if (arg === "--input" && argv[i + 1]) {
|
|
272
|
+
input = argv[++i];
|
|
273
|
+
} else if (arg === "--weight" && argv[i + 1]) {
|
|
274
|
+
// Accept formats: "precision=2" or "2" or "recall=0.5"
|
|
275
|
+
const raw = argv[++i];
|
|
276
|
+
const match = raw.match(/(?:precision|recall)?=?(\d+(?:\.\d+)?)/);
|
|
277
|
+
if (match) betaWeight = parseFloat(match[1]);
|
|
278
|
+
} else if (arg === "--apply") {
|
|
279
|
+
apply = true;
|
|
280
|
+
} else if (arg === "--config" && argv[i + 1]) {
|
|
281
|
+
configPath = argv[++i];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return { input, betaWeight, apply, configPath };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (import.meta.main) {
|
|
289
|
+
const { input, betaWeight, apply, configPath } = parseArgs(process.argv.slice(2));
|
|
290
|
+
|
|
291
|
+
const EMBED_HIT_THRESHOLD = (() => {
|
|
292
|
+
const raw = process.env.ASHLR_EMBED_THRESHOLD;
|
|
293
|
+
if (!raw) return 0.68;
|
|
294
|
+
const n = Number.parseFloat(raw);
|
|
295
|
+
return Number.isFinite(n) && n >= 0 && n <= 1 ? n : 0.68;
|
|
296
|
+
})();
|
|
297
|
+
|
|
298
|
+
const entries = loadCalibrationEntries(input);
|
|
299
|
+
const result = tune(entries, EMBED_HIT_THRESHOLD, betaWeight);
|
|
300
|
+
console.log(renderReport(result));
|
|
301
|
+
|
|
302
|
+
if (apply && entries.length > 0) {
|
|
303
|
+
const t = result.recommendedThreshold;
|
|
304
|
+
applyThreshold(t, configPath);
|
|
305
|
+
console.log(`\nWrote embedThreshold=${t} to ${configPath}`);
|
|
306
|
+
console.log("Restart Claude Code to apply.");
|
|
307
|
+
}
|
|
308
|
+
}
|