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,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* edit-structural-server-handlers — registers ashlr__edit_structural on the
|
|
3
|
+
* shared registry (Track C v1.14).
|
|
4
|
+
*
|
|
5
|
+
* v1.14 adds:
|
|
6
|
+
* - operation: "rename" (default, file-local) | "rename-cross-file" | "extract-function"
|
|
7
|
+
* - rename-cross-file: rootDir + optional include/exclude globs, applies edits
|
|
8
|
+
* atomically across all matching files.
|
|
9
|
+
* - extract-function: byte-range extract with outer-scope param detection (MVP).
|
|
10
|
+
*
|
|
11
|
+
* Input (operation: "rename", default for back-compat):
|
|
12
|
+
* - path (required) — absolute or cwd-relative file path
|
|
13
|
+
* - name (required) — identifier name to rename
|
|
14
|
+
* - newName (required) — target name
|
|
15
|
+
* - kind? — "value" (default) | "type"
|
|
16
|
+
* - dryRun? — if true, return the planned edits without writing
|
|
17
|
+
* - force? — bypass shadowing + collision guards
|
|
18
|
+
*
|
|
19
|
+
* Input (operation: "rename-cross-file"):
|
|
20
|
+
* - rootDir (required) — cwd-clamped root directory to search
|
|
21
|
+
* - name (required) — identifier name to rename
|
|
22
|
+
* - newName (required) — target name
|
|
23
|
+
* - kind? — "value" (default) | "type"
|
|
24
|
+
* - include? — glob patterns (default: **\/*.{ts,tsx,js,jsx})
|
|
25
|
+
* - exclude? — glob patterns to exclude
|
|
26
|
+
* - dryRun? — if true, plan but don't write
|
|
27
|
+
*
|
|
28
|
+
* Input (operation: "extract-function"):
|
|
29
|
+
* - path (required) — source file path
|
|
30
|
+
* - newName (required) — name for the extracted function
|
|
31
|
+
* - start (required) — byte offset start of range to extract
|
|
32
|
+
* - end (required) — byte offset end of range to extract
|
|
33
|
+
* - dryRun? — if true, return edits without writing
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import { writeFile } from "fs/promises";
|
|
37
|
+
import {
|
|
38
|
+
registerTool,
|
|
39
|
+
toErrorResult,
|
|
40
|
+
type ToolCallContext,
|
|
41
|
+
type ToolResult,
|
|
42
|
+
} from "./_tool-base";
|
|
43
|
+
import { clampToCwd } from "./_cwd-clamp";
|
|
44
|
+
import {
|
|
45
|
+
applyRangeEdits,
|
|
46
|
+
applyCrossFileRenameEdits,
|
|
47
|
+
planRenameInFile,
|
|
48
|
+
planCrossFileRename,
|
|
49
|
+
planExtractFunction,
|
|
50
|
+
type RefactorKind,
|
|
51
|
+
} from "./_ast-refactor";
|
|
52
|
+
import { parseFile } from "./_ast-helpers";
|
|
53
|
+
import { recordSaving } from "./_stats";
|
|
54
|
+
|
|
55
|
+
interface StructuralArgs {
|
|
56
|
+
operation?: unknown;
|
|
57
|
+
path?: unknown;
|
|
58
|
+
rootDir?: unknown;
|
|
59
|
+
name?: unknown;
|
|
60
|
+
newName?: unknown;
|
|
61
|
+
kind?: unknown;
|
|
62
|
+
dryRun?: unknown;
|
|
63
|
+
force?: unknown;
|
|
64
|
+
include?: unknown;
|
|
65
|
+
exclude?: unknown;
|
|
66
|
+
anchorFile?: unknown;
|
|
67
|
+
maxFiles?: unknown;
|
|
68
|
+
start?: unknown;
|
|
69
|
+
end?: unknown;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
registerTool({
|
|
73
|
+
name: "ashlr__edit_structural",
|
|
74
|
+
description:
|
|
75
|
+
"Rename a symbol with AST awareness (one file or N files). Use instead of native " +
|
|
76
|
+
"Edit when renaming variables/functions/types — avoids accidental matches in " +
|
|
77
|
+
"strings/comments. Compresses by returning only a rename summary; typical savings " +
|
|
78
|
+
"80–95%. operation='rename': file-local. operation='rename-cross-file': across " +
|
|
79
|
+
"rootDir. operation='extract-function': extract byte-range to new function. " +
|
|
80
|
+
"Supports .ts/.tsx/.js/.jsx. dryRun=true previews. Use ashlr__edit for literal edits.",
|
|
81
|
+
inputSchema: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
operation: {
|
|
85
|
+
type: "string",
|
|
86
|
+
enum: ["rename", "rename-cross-file", "extract-function"],
|
|
87
|
+
description: "Operation to perform (default: 'rename' for back-compat)",
|
|
88
|
+
},
|
|
89
|
+
path: { type: "string", description: "Absolute or cwd-relative file path (rename, extract-function)" },
|
|
90
|
+
rootDir: { type: "string", description: "Root directory to search (rename-cross-file)" },
|
|
91
|
+
name: { type: "string", description: "Current identifier name to rename (rename, rename-cross-file)" },
|
|
92
|
+
newName: { type: "string", description: "Target identifier / new function name" },
|
|
93
|
+
kind: {
|
|
94
|
+
type: "string",
|
|
95
|
+
enum: ["value", "type"],
|
|
96
|
+
description: "'value' (default) | 'type' — for rename operations",
|
|
97
|
+
},
|
|
98
|
+
dryRun: {
|
|
99
|
+
type: "boolean",
|
|
100
|
+
description: "If true, return the planned edits without writing (default false)",
|
|
101
|
+
},
|
|
102
|
+
force: {
|
|
103
|
+
type: "boolean",
|
|
104
|
+
description: "Bypass shadowing + collision guards for rename (default false)",
|
|
105
|
+
},
|
|
106
|
+
include: {
|
|
107
|
+
type: "array",
|
|
108
|
+
items: { type: "string" },
|
|
109
|
+
description: "Glob patterns to include (rename-cross-file, default: **/*.{ts,tsx,js,jsx})",
|
|
110
|
+
},
|
|
111
|
+
exclude: {
|
|
112
|
+
type: "array",
|
|
113
|
+
items: { type: "string" },
|
|
114
|
+
description: "Glob patterns to exclude (rename-cross-file)",
|
|
115
|
+
},
|
|
116
|
+
anchorFile: {
|
|
117
|
+
type: "string",
|
|
118
|
+
description: "Absolute path of the file that declares + exports the symbol (rename-cross-file). When set, only files that import the symbol from this file are renamed — unrelated local same-named identifiers are left alone.",
|
|
119
|
+
},
|
|
120
|
+
maxFiles: {
|
|
121
|
+
type: "number",
|
|
122
|
+
description: "Hard cap on candidate files for cross-file rename (default 200). Beyond this the rename is truncated and a warning is emitted.",
|
|
123
|
+
},
|
|
124
|
+
start: { type: "number", description: "Byte offset start of range to extract (extract-function)" },
|
|
125
|
+
end: { type: "number", description: "Byte offset end of range to extract (extract-function)" },
|
|
126
|
+
},
|
|
127
|
+
required: ["newName"],
|
|
128
|
+
},
|
|
129
|
+
handler: async (args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
|
|
130
|
+
const a = args as StructuralArgs;
|
|
131
|
+
const operation = typeof a.operation === "string" ? a.operation : "rename";
|
|
132
|
+
const dryRun = a.dryRun === true;
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
if (operation === "rename-cross-file") {
|
|
136
|
+
return await handleCrossFileRename(a, dryRun);
|
|
137
|
+
} else if (operation === "extract-function") {
|
|
138
|
+
return await handleExtractFunction(a, dryRun);
|
|
139
|
+
} else {
|
|
140
|
+
return await handleFileLocalRename(a, dryRun);
|
|
141
|
+
}
|
|
142
|
+
} catch (err) {
|
|
143
|
+
return toErrorResult("ashlr__edit_structural error", err);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// Operation handlers
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
async function handleFileLocalRename(a: StructuralArgs, dryRun: boolean): Promise<ToolResult> {
|
|
153
|
+
const path = typeof a.path === "string" ? a.path : "";
|
|
154
|
+
const name = typeof a.name === "string" ? a.name : "";
|
|
155
|
+
const newName = typeof a.newName === "string" ? a.newName : "";
|
|
156
|
+
const kind: RefactorKind = a.kind === "type" ? "type" : "value";
|
|
157
|
+
const force = a.force === true;
|
|
158
|
+
|
|
159
|
+
if (!path) return errText("ashlr__edit_structural: 'path' is required");
|
|
160
|
+
if (!name) return errText("ashlr__edit_structural: 'name' is required");
|
|
161
|
+
if (!newName) return errText("ashlr__edit_structural: 'newName' is required");
|
|
162
|
+
|
|
163
|
+
const clamp = clampToCwd(path, "ashlr__edit_structural");
|
|
164
|
+
if (!clamp.ok) return errText(clamp.message);
|
|
165
|
+
|
|
166
|
+
const result = await planRenameInFile(clamp.abs, name, newName, { kind, force });
|
|
167
|
+
if (!result.ok) {
|
|
168
|
+
return errText(`ashlr__edit_structural: ${result.reason}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const header =
|
|
172
|
+
`[ashlr__edit_structural] rename ${kind} '${name}' → '${newName}' in ${path}\n` +
|
|
173
|
+
` ${result.references} occurrence${result.references === 1 ? "" : "s"} updated` +
|
|
174
|
+
(result.warnings.length > 0 ? `\n warnings: ${result.warnings.join("; ")}` : "");
|
|
175
|
+
|
|
176
|
+
if (dryRun) {
|
|
177
|
+
const lines = [header, " (dry run — file not written)", " planned edits:"];
|
|
178
|
+
for (const e of result.edits) {
|
|
179
|
+
lines.push(` [${e.start}, ${e.end}] → '${e.replacement}'`);
|
|
180
|
+
}
|
|
181
|
+
return okText(lines.join("\n"));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const sourceBefore = result.source;
|
|
185
|
+
const sourceAfter = applyRangeEdits(sourceBefore, result.edits);
|
|
186
|
+
if (sourceBefore === sourceAfter) {
|
|
187
|
+
return okText(header + "\n (no-op — source unchanged after rewrite)");
|
|
188
|
+
}
|
|
189
|
+
await writeFile(clamp.abs, sourceAfter, "utf-8");
|
|
190
|
+
|
|
191
|
+
const rawBytes = Buffer.byteLength(sourceBefore, "utf-8");
|
|
192
|
+
const compactBytes = Buffer.byteLength(header, "utf-8");
|
|
193
|
+
await recordSaving(rawBytes, compactBytes, "ashlr__edit_structural");
|
|
194
|
+
|
|
195
|
+
return okText(header);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function handleCrossFileRename(a: StructuralArgs, dryRun: boolean): Promise<ToolResult> {
|
|
199
|
+
const rootDir = typeof a.rootDir === "string" ? a.rootDir : "";
|
|
200
|
+
const name = typeof a.name === "string" ? a.name : "";
|
|
201
|
+
const newName = typeof a.newName === "string" ? a.newName : "";
|
|
202
|
+
const kind: RefactorKind = a.kind === "type" ? "type" : "value";
|
|
203
|
+
const include = Array.isArray(a.include) ? (a.include as string[]) : undefined;
|
|
204
|
+
const exclude = Array.isArray(a.exclude) ? (a.exclude as string[]) : undefined;
|
|
205
|
+
const anchorFileRaw = typeof a.anchorFile === "string" ? a.anchorFile : undefined;
|
|
206
|
+
const maxFiles = typeof a.maxFiles === "number" ? a.maxFiles : undefined;
|
|
207
|
+
|
|
208
|
+
if (!rootDir) return errText("ashlr__edit_structural (rename-cross-file): 'rootDir' is required");
|
|
209
|
+
if (!name) return errText("ashlr__edit_structural (rename-cross-file): 'name' is required");
|
|
210
|
+
if (!newName) return errText("ashlr__edit_structural (rename-cross-file): 'newName' is required");
|
|
211
|
+
|
|
212
|
+
const clamp = clampToCwd(rootDir, "ashlr__edit_structural");
|
|
213
|
+
if (!clamp.ok) return errText(clamp.message);
|
|
214
|
+
|
|
215
|
+
let anchorFile: string | undefined;
|
|
216
|
+
if (anchorFileRaw) {
|
|
217
|
+
const aClamp = clampToCwd(anchorFileRaw, "ashlr__edit_structural");
|
|
218
|
+
if (!aClamp.ok) return errText(aClamp.message);
|
|
219
|
+
anchorFile = aClamp.abs;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const result = await planCrossFileRename(clamp.abs, name, newName, {
|
|
223
|
+
kind,
|
|
224
|
+
include,
|
|
225
|
+
exclude,
|
|
226
|
+
anchorFile,
|
|
227
|
+
maxFiles,
|
|
228
|
+
});
|
|
229
|
+
if (!result.ok) {
|
|
230
|
+
return errText(`ashlr__edit_structural (rename-cross-file): ${result.reason}`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const totalRefs = result.fileEdits.reduce((s, f) => s + f.references, 0);
|
|
234
|
+
const header =
|
|
235
|
+
`[ashlr__edit_structural] cross-file rename '${name}' → '${newName}'` +
|
|
236
|
+
(anchorFile ? ` (scoped to importers of ${anchorFile})` : "") + "\n" +
|
|
237
|
+
` ${result.fileEdits.length} file${result.fileEdits.length === 1 ? "" : "s"}, ${totalRefs} occurrence${totalRefs === 1 ? "" : "s"} updated` +
|
|
238
|
+
(result.skipped ? `, ${result.skipped} candidate${result.skipped === 1 ? "" : "s"} skipped` : "") +
|
|
239
|
+
(result.warnings.length > 0 ? `\n warnings:\n${result.warnings.map((w) => ` ${w}`).join("\n")}` : "");
|
|
240
|
+
|
|
241
|
+
if (dryRun) {
|
|
242
|
+
// List every planned edit so the caller can review before committing.
|
|
243
|
+
const lines = [header, " (dry run — files not written)", " planned edits:"];
|
|
244
|
+
for (const fe of result.fileEdits) {
|
|
245
|
+
lines.push(` ${fe.path} — ${fe.edits.length} edit${fe.edits.length === 1 ? "" : "s"}`);
|
|
246
|
+
for (const e of fe.edits) {
|
|
247
|
+
lines.push(` [${e.start}, ${e.end}] → '${e.replacement}'`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return okText(lines.join("\n"));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const written = await applyCrossFileRenameEdits(result.fileEdits);
|
|
254
|
+
const summary = header + `\n ${written} file${written === 1 ? "" : "s"} written`;
|
|
255
|
+
|
|
256
|
+
const totalRawBytes = result.fileEdits.reduce((s, f) => s + Buffer.byteLength(f.source, "utf-8"), 0);
|
|
257
|
+
await recordSaving(totalRawBytes, Buffer.byteLength(summary, "utf-8"), "ashlr__edit_structural");
|
|
258
|
+
|
|
259
|
+
return okText(summary);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function handleExtractFunction(a: StructuralArgs, dryRun: boolean): Promise<ToolResult> {
|
|
263
|
+
const path = typeof a.path === "string" ? a.path : "";
|
|
264
|
+
const newName = typeof a.newName === "string" ? a.newName : "";
|
|
265
|
+
const start = typeof a.start === "number" ? a.start : -1;
|
|
266
|
+
const end = typeof a.end === "number" ? a.end : -1;
|
|
267
|
+
|
|
268
|
+
if (!path) return errText("ashlr__edit_structural (extract-function): 'path' is required");
|
|
269
|
+
if (!newName) return errText("ashlr__edit_structural (extract-function): 'newName' is required");
|
|
270
|
+
if (start < 0) return errText("ashlr__edit_structural (extract-function): 'start' is required");
|
|
271
|
+
if (end < 0) return errText("ashlr__edit_structural (extract-function): 'end' is required");
|
|
272
|
+
|
|
273
|
+
const clamp = clampToCwd(path, "ashlr__edit_structural");
|
|
274
|
+
if (!clamp.ok) return errText(clamp.message);
|
|
275
|
+
|
|
276
|
+
const parsed = await parseFile(clamp.abs);
|
|
277
|
+
if (!parsed) {
|
|
278
|
+
return errText("ashlr__edit_structural (extract-function): unsupported language or grammar not wired");
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const result = planExtractFunction(parsed, { newFunctionName: newName, start, end });
|
|
282
|
+
if (!result.ok) {
|
|
283
|
+
return errText(`ashlr__edit_structural (extract-function): ${result.reason}`);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const warnings = result.warnings ?? [];
|
|
287
|
+
const header =
|
|
288
|
+
`[ashlr__edit_structural] extract-function '${newName}' from ${path} [${start}–${end}]` +
|
|
289
|
+
(warnings.length > 0 ? `\n warnings:\n${warnings.map((w) => ` ${w}`).join("\n")}` : "");
|
|
290
|
+
|
|
291
|
+
if (dryRun) {
|
|
292
|
+
const lines = [header, " (dry run — file not written)", " planned edits:"];
|
|
293
|
+
for (const e of result.edits!) {
|
|
294
|
+
// Truncate long replacements for readability
|
|
295
|
+
const repl = e.replacement.length > 120
|
|
296
|
+
? e.replacement.slice(0, 117) + "..."
|
|
297
|
+
: e.replacement;
|
|
298
|
+
lines.push(` [${e.start}, ${e.end}] → ${JSON.stringify(repl)}`);
|
|
299
|
+
}
|
|
300
|
+
return okText(lines.join("\n"));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const sourceAfter = applyRangeEdits(result.source!, result.edits!);
|
|
304
|
+
await writeFile(clamp.abs, sourceAfter, "utf-8");
|
|
305
|
+
|
|
306
|
+
const rawBytes = Buffer.byteLength(result.source!, "utf-8");
|
|
307
|
+
await recordSaving(rawBytes, Buffer.byteLength(header, "utf-8"), "ashlr__edit_structural");
|
|
308
|
+
|
|
309
|
+
return okText(header + "\n written");
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ---------------------------------------------------------------------------
|
|
313
|
+
// Helpers
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
|
|
316
|
+
function okText(text: string): ToolResult {
|
|
317
|
+
return { content: [{ type: "text", text }] };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function errText(text: string): ToolResult {
|
|
321
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
322
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* efficiency-server-handlers — side-effect module.
|
|
3
|
+
*
|
|
4
|
+
* Importing this file registers the five efficiency-server tools (ashlr__read,
|
|
5
|
+
* ashlr__grep, ashlr__edit, ashlr__flush, ashlr__savings) into the shared
|
|
6
|
+
* registry (_tool-base.ts). Logic still lives in efficiency-server.ts during
|
|
7
|
+
* the v1.12 → v1.13 migration window; this module is a thin adapter so the
|
|
8
|
+
* same tools can be dispatched through the router process.
|
|
9
|
+
*
|
|
10
|
+
* The standalone entry point (efficiency-server.ts) keeps its own Server /
|
|
11
|
+
* setRequestHandler wiring for stale plugin.json entries. Once every
|
|
12
|
+
* migrated-tool plugin.json entry is collapsed into a single router entry,
|
|
13
|
+
* the standalone wiring can be deleted.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { registerTool, type ToolCallContext, type ToolResult } from "./_tool-base";
|
|
17
|
+
import {
|
|
18
|
+
ashlrRead,
|
|
19
|
+
ashlrGrep,
|
|
20
|
+
ashlrEdit,
|
|
21
|
+
flushPending,
|
|
22
|
+
renderSavings,
|
|
23
|
+
type EditArgs,
|
|
24
|
+
} from "./efficiency-server";
|
|
25
|
+
import { readStats, readCurrentSession } from "./_stats";
|
|
26
|
+
import {
|
|
27
|
+
buildTopProjects,
|
|
28
|
+
readCalibrationState,
|
|
29
|
+
type ExtraContext,
|
|
30
|
+
} from "../scripts/savings-report-extras";
|
|
31
|
+
import { readNudgeSummary } from "./_nudge-events";
|
|
32
|
+
import { isProSync } from "./_pro";
|
|
33
|
+
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// ashlr__read
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
registerTool({
|
|
39
|
+
name: "ashlr__read",
|
|
40
|
+
description:
|
|
41
|
+
"Read a file with automatic snipCompact truncation for results > 2KB. " +
|
|
42
|
+
"Preserves head + tail, elides middle. Lower-token alternative to the " +
|
|
43
|
+
"built-in Read tool.",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
path: { type: "string", description: "Absolute or cwd-relative file path" },
|
|
48
|
+
bypassSummary: {
|
|
49
|
+
type: "boolean",
|
|
50
|
+
description: "Skip LLM summarization, return snipCompact-truncated content (default: false)",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
required: ["path"],
|
|
54
|
+
},
|
|
55
|
+
handler: async (args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
|
|
56
|
+
const text = await ashlrRead({
|
|
57
|
+
path: String(args.path ?? ""),
|
|
58
|
+
bypassSummary: args.bypassSummary === true,
|
|
59
|
+
});
|
|
60
|
+
return { content: [{ type: "text", text }] };
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// ashlr__grep
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
registerTool({
|
|
69
|
+
name: "ashlr__grep",
|
|
70
|
+
description:
|
|
71
|
+
"Search for a pattern. When a .ashlrcode/genome/ directory exists, uses " +
|
|
72
|
+
"genome-aware retrieval to return only the most relevant sections. Falls " +
|
|
73
|
+
"back to ripgrep otherwise.",
|
|
74
|
+
inputSchema: {
|
|
75
|
+
type: "object",
|
|
76
|
+
properties: {
|
|
77
|
+
pattern: { type: "string", description: "Query or regex" },
|
|
78
|
+
cwd: { type: "string", description: "Working directory (default: process.cwd())" },
|
|
79
|
+
bypassSummary: {
|
|
80
|
+
type: "boolean",
|
|
81
|
+
description: "Skip LLM summarization, return rg output as-is (default: false)",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
required: ["pattern"],
|
|
85
|
+
},
|
|
86
|
+
handler: async (args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
|
|
87
|
+
const text = await ashlrGrep({
|
|
88
|
+
pattern: String(args.pattern ?? ""),
|
|
89
|
+
cwd: typeof args.cwd === "string" ? args.cwd : undefined,
|
|
90
|
+
bypassSummary: args.bypassSummary === true,
|
|
91
|
+
});
|
|
92
|
+
return { content: [{ type: "text", text }] };
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// ashlr__edit
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
registerTool({
|
|
101
|
+
name: "ashlr__edit",
|
|
102
|
+
description:
|
|
103
|
+
"Apply a search/replace edit in-place and return only a diff summary. In " +
|
|
104
|
+
"strict mode (default), requires exactly one match for safety. Set " +
|
|
105
|
+
"strict:false to replace all occurrences.",
|
|
106
|
+
inputSchema: {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: {
|
|
109
|
+
path: { type: "string", description: "Absolute or cwd-relative file path" },
|
|
110
|
+
search: { type: "string", description: "Exact text to find" },
|
|
111
|
+
replace: { type: "string", description: "Replacement text" },
|
|
112
|
+
strict: { type: "boolean", description: "Require exactly one match (default: true)" },
|
|
113
|
+
},
|
|
114
|
+
required: ["path", "search", "replace"],
|
|
115
|
+
},
|
|
116
|
+
handler: async (args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
|
|
117
|
+
const res = await ashlrEdit(args as unknown as EditArgs);
|
|
118
|
+
return { content: [{ type: "text", text: res.text }] };
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// ashlr__flush
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
registerTool({
|
|
127
|
+
name: "ashlr__flush",
|
|
128
|
+
description:
|
|
129
|
+
"Flush all queued ashlr__edit writes to disk immediately and return a " +
|
|
130
|
+
"summary of what was committed. Use when you need to read a file you just " +
|
|
131
|
+
"edited, or at the end of a multi-edit sequence.",
|
|
132
|
+
inputSchema: { type: "object", properties: {} },
|
|
133
|
+
handler: async (_args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
|
|
134
|
+
const summary = await flushPending();
|
|
135
|
+
return {
|
|
136
|
+
content: [{ type: "text", text: summary || "[ashlr__flush] nothing to flush" }],
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// ashlr__savings
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
|
|
145
|
+
registerTool({
|
|
146
|
+
name: "ashlr__savings",
|
|
147
|
+
description: "Return estimated tokens saved in the current session and lifetime totals.",
|
|
148
|
+
inputSchema: { type: "object", properties: {} },
|
|
149
|
+
handler: async (_args: Record<string, unknown>, _ctx: ToolCallContext): Promise<ToolResult> => {
|
|
150
|
+
const stats = await readStats();
|
|
151
|
+
const session = await readCurrentSession();
|
|
152
|
+
const topProjects = buildTopProjects();
|
|
153
|
+
const { ratio: calibrationRatio, present: calibrationPresent } = readCalibrationState();
|
|
154
|
+
const nudgeSummary = await readNudgeSummary();
|
|
155
|
+
const proUser = isProSync();
|
|
156
|
+
const extra: ExtraContext = { topProjects, calibrationRatio, calibrationPresent, nudgeSummary, proUser };
|
|
157
|
+
return {
|
|
158
|
+
content: [{ type: "text", text: renderSavings(session, stats.lifetime, extra) }],
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
});
|