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,434 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* _ast-chunker.ts — Symbol-level AST chunking for genome indexing (v1.15 prep).
|
|
3
|
+
*
|
|
4
|
+
* Exports:
|
|
5
|
+
* splitFileIntoChunks — parse a source file and return top-level CodeChunks.
|
|
6
|
+
* chunkToRagString — render a CodeChunk as a retrieval-friendly string.
|
|
7
|
+
*
|
|
8
|
+
* MVP scope (v1.14 spike):
|
|
9
|
+
* - Top-level declarations only: function, class, type alias, interface,
|
|
10
|
+
* export const/let.
|
|
11
|
+
* - Per-class chunking is one chunk for the whole class body (per-method
|
|
12
|
+
* decomposition is a v1.15 expansion).
|
|
13
|
+
* - Nested functions inside class methods are NOT chunked separately.
|
|
14
|
+
* - Returns null for unsupported languages (same behaviour as parseFile).
|
|
15
|
+
*
|
|
16
|
+
* Not integrated with ashlr__grep or the genome build pipeline yet — pure
|
|
17
|
+
* export for prototype verification. Integration is v1.15.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { relative } from "path";
|
|
21
|
+
import type Parser from "web-tree-sitter";
|
|
22
|
+
import { parseFile } from "./_ast-helpers";
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Public types
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
export type ChunkKind =
|
|
29
|
+
| "function"
|
|
30
|
+
| "class"
|
|
31
|
+
| "type"
|
|
32
|
+
| "interface"
|
|
33
|
+
| "const"
|
|
34
|
+
| "enum"
|
|
35
|
+
| "module";
|
|
36
|
+
|
|
37
|
+
export interface CodeChunk {
|
|
38
|
+
symbol: string; // "upsertEmbedding"
|
|
39
|
+
kind: ChunkKind;
|
|
40
|
+
signature: string; // declaration header, body stripped
|
|
41
|
+
docstring: string | null; // leading JSDoc/TSDoc / line-comment block, or null
|
|
42
|
+
file: string; // relative to cwd
|
|
43
|
+
startLine: number; // 1-based
|
|
44
|
+
endLine: number;
|
|
45
|
+
startByte: number;
|
|
46
|
+
endByte: number;
|
|
47
|
+
/** For class chunks: one signature line per member (method bodies elided). */
|
|
48
|
+
members?: string[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Node types → ChunkKind mapping
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
/** Top-level declaration node types we chunk. */
|
|
56
|
+
const DECLARATION_KINDS: Record<string, ChunkKind> = {
|
|
57
|
+
function_declaration: "function",
|
|
58
|
+
class_declaration: "class",
|
|
59
|
+
abstract_class_declaration: "class",
|
|
60
|
+
type_alias_declaration: "type",
|
|
61
|
+
interface_declaration: "interface",
|
|
62
|
+
enum_declaration: "enum",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Public API
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parse `filePath` and return one CodeChunk per top-level declaration.
|
|
71
|
+
*
|
|
72
|
+
* Returns `null` for unsupported languages (mirrors parseFile behaviour).
|
|
73
|
+
* Returns an empty array for a parseable but empty file.
|
|
74
|
+
*/
|
|
75
|
+
export async function splitFileIntoChunks(
|
|
76
|
+
filePath: string,
|
|
77
|
+
): Promise<CodeChunk[] | null> {
|
|
78
|
+
const parsed = await parseFile(filePath);
|
|
79
|
+
if (!parsed) return null;
|
|
80
|
+
|
|
81
|
+
const { tree, source } = parsed;
|
|
82
|
+
const relPath = relative(process.cwd(), filePath);
|
|
83
|
+
const chunks: CodeChunk[] = [];
|
|
84
|
+
|
|
85
|
+
const root = tree.rootNode;
|
|
86
|
+
|
|
87
|
+
for (let i = 0; i < root.childCount; i++) {
|
|
88
|
+
const node = root.child(i)!;
|
|
89
|
+
const chunk = tryExtractChunk(node, source, relPath);
|
|
90
|
+
if (chunk) chunks.push(chunk);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return chunks;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Render a CodeChunk as a compact retrieval string.
|
|
98
|
+
*
|
|
99
|
+
* Format:
|
|
100
|
+
* # {file}:{startLine}-{endLine} · {kind} · {symbol}
|
|
101
|
+
* {docstring} ← omitted if null
|
|
102
|
+
* {signature}
|
|
103
|
+
*
|
|
104
|
+
* Full body is intentionally omitted; callers can expand on demand.
|
|
105
|
+
*/
|
|
106
|
+
export function chunkToRagString(chunk: CodeChunk): string {
|
|
107
|
+
const header = `# ${chunk.file}:${chunk.startLine}-${chunk.endLine} · ${chunk.kind} · ${chunk.symbol}`;
|
|
108
|
+
const parts: string[] = [header];
|
|
109
|
+
if (chunk.docstring) parts.push(chunk.docstring);
|
|
110
|
+
parts.push(chunk.signature);
|
|
111
|
+
return parts.join("\n");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// Internal helpers
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Attempt to build a CodeChunk from a single syntax node.
|
|
120
|
+
* Returns null if the node is not a top-level declaration we care about.
|
|
121
|
+
*/
|
|
122
|
+
function tryExtractChunk(
|
|
123
|
+
node: Parser.SyntaxNode,
|
|
124
|
+
source: string,
|
|
125
|
+
relPath: string,
|
|
126
|
+
): CodeChunk | null {
|
|
127
|
+
const type = node.type;
|
|
128
|
+
|
|
129
|
+
// Named declarations -------------------------------------------------------
|
|
130
|
+
const declKind = DECLARATION_KINDS[type];
|
|
131
|
+
if (declKind !== undefined) {
|
|
132
|
+
const symbol = extractName(node);
|
|
133
|
+
if (!symbol) return null;
|
|
134
|
+
return buildChunk(node, source, relPath, symbol, declKind);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// export_statement wrapping a declaration or variable statement ------------
|
|
138
|
+
if (type === "export_statement") {
|
|
139
|
+
return tryExtractFromExport(node, source, relPath);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Handle `export_statement` nodes. We recognise:
|
|
147
|
+
* export function foo() {}
|
|
148
|
+
* export class Foo {}
|
|
149
|
+
* export type Foo = …
|
|
150
|
+
* export interface Foo {}
|
|
151
|
+
* export const X = …
|
|
152
|
+
* export let X = …
|
|
153
|
+
*/
|
|
154
|
+
function tryExtractFromExport(
|
|
155
|
+
exportNode: Parser.SyntaxNode,
|
|
156
|
+
source: string,
|
|
157
|
+
relPath: string,
|
|
158
|
+
): CodeChunk | null {
|
|
159
|
+
// The exported declaration is always the last named child of export_statement.
|
|
160
|
+
const decl = exportNode.namedChildren.find(
|
|
161
|
+
(c) =>
|
|
162
|
+
DECLARATION_KINDS[c.type] !== undefined ||
|
|
163
|
+
c.type === "lexical_declaration" ||
|
|
164
|
+
c.type === "variable_declaration",
|
|
165
|
+
);
|
|
166
|
+
if (!decl) return null;
|
|
167
|
+
|
|
168
|
+
const declKind = DECLARATION_KINDS[decl.type];
|
|
169
|
+
if (declKind !== undefined) {
|
|
170
|
+
const symbol = extractName(decl);
|
|
171
|
+
if (!symbol) return null;
|
|
172
|
+
// Use the export node for byte/line extents so the export keyword is included.
|
|
173
|
+
return buildChunk(exportNode, source, relPath, symbol, declKind);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// lexical_declaration / variable_declaration → const/let X = …
|
|
177
|
+
if (
|
|
178
|
+
decl.type === "lexical_declaration" ||
|
|
179
|
+
decl.type === "variable_declaration"
|
|
180
|
+
) {
|
|
181
|
+
return tryExtractFromLexicalDecl(exportNode, decl, source, relPath);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Extract a "const" chunk from `export const X = …` or `export let X = …`.
|
|
189
|
+
* Only the first declarator is used as the chunk name; multi-declarator
|
|
190
|
+
* destructuring exports are skipped (uncommon in library code).
|
|
191
|
+
*/
|
|
192
|
+
function tryExtractFromLexicalDecl(
|
|
193
|
+
exportNode: Parser.SyntaxNode,
|
|
194
|
+
decl: Parser.SyntaxNode,
|
|
195
|
+
source: string,
|
|
196
|
+
relPath: string,
|
|
197
|
+
): CodeChunk | null {
|
|
198
|
+
const declarator = decl.namedChildren.find(
|
|
199
|
+
(c) => c.type === "variable_declarator",
|
|
200
|
+
);
|
|
201
|
+
if (!declarator) return null;
|
|
202
|
+
|
|
203
|
+
const nameNode = declarator.namedChildren.find(
|
|
204
|
+
(c) => c.type === "identifier",
|
|
205
|
+
);
|
|
206
|
+
if (!nameNode) return null;
|
|
207
|
+
|
|
208
|
+
const symbol = nameNode.text;
|
|
209
|
+
return buildChunk(exportNode, source, relPath, symbol, "const");
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Build a CodeChunk from a node + metadata.
|
|
214
|
+
*/
|
|
215
|
+
/** Collapse internal whitespace / newlines to single spaces. */
|
|
216
|
+
function collapseWs(s: string): string {
|
|
217
|
+
return s.replace(/\s+/g, " ").trim();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* For a class declaration, extract one signature line per member: method
|
|
222
|
+
* headers with the body elided as `{ … }`, plus field/property/abstract/index
|
|
223
|
+
* signatures (value initializers dropped to keep lines short). Returns [] when
|
|
224
|
+
* there is no class_body or no members. Lets the AST skeleton show a class's
|
|
225
|
+
* shape (its method signatures) instead of eliding the whole body.
|
|
226
|
+
*/
|
|
227
|
+
function extractClassMemberSignatures(
|
|
228
|
+
node: Parser.SyntaxNode,
|
|
229
|
+
source: string,
|
|
230
|
+
): string[] {
|
|
231
|
+
const classBody = findBodyNode(node, "class");
|
|
232
|
+
if (!classBody || classBody.type !== "class_body") return [];
|
|
233
|
+
|
|
234
|
+
const out: string[] = [];
|
|
235
|
+
for (const child of classBody.namedChildren) {
|
|
236
|
+
if (child.type === "comment") continue;
|
|
237
|
+
|
|
238
|
+
if (child.type === "method_definition") {
|
|
239
|
+
const body = child.namedChildren.find((c) => c.type === "statement_block");
|
|
240
|
+
const header = body
|
|
241
|
+
? source.slice(child.startIndex, body.startIndex)
|
|
242
|
+
: source.slice(child.startIndex, child.endIndex).split("\n")[0]!;
|
|
243
|
+
out.push(`${collapseWs(header)} { … }`);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (
|
|
248
|
+
child.type === "public_field_definition" ||
|
|
249
|
+
child.type === "property_signature" ||
|
|
250
|
+
child.type === "method_signature" ||
|
|
251
|
+
child.type === "abstract_method_signature" ||
|
|
252
|
+
child.type === "index_signature"
|
|
253
|
+
) {
|
|
254
|
+
let text = source.slice(child.startIndex, child.endIndex);
|
|
255
|
+
// Drop an assignment initializer (not `=>`, `==`, `<=`, `>=`, `!=`).
|
|
256
|
+
const eq = text.search(/(?<![=!<>])=(?![=>])/);
|
|
257
|
+
if (eq !== -1) text = text.slice(0, eq);
|
|
258
|
+
out.push(`${collapseWs(text).replace(/[;,]$/, "")};`);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
// static_block / other members: skipped.
|
|
262
|
+
}
|
|
263
|
+
return out;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function buildChunk(
|
|
267
|
+
node: Parser.SyntaxNode,
|
|
268
|
+
source: string,
|
|
269
|
+
relPath: string,
|
|
270
|
+
symbol: string,
|
|
271
|
+
kind: ChunkKind,
|
|
272
|
+
): CodeChunk {
|
|
273
|
+
const docstring = extractDocstring(node, source);
|
|
274
|
+
const signature = extractSignature(node, source, kind);
|
|
275
|
+
const members =
|
|
276
|
+
kind === "class" ? extractClassMemberSignatures(node, source) : undefined;
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
symbol,
|
|
280
|
+
kind,
|
|
281
|
+
signature,
|
|
282
|
+
docstring,
|
|
283
|
+
members,
|
|
284
|
+
file: relPath,
|
|
285
|
+
startLine: node.startPosition.row + 1, // tree-sitter rows are 0-based
|
|
286
|
+
endLine: node.endPosition.row + 1,
|
|
287
|
+
startByte: node.startIndex,
|
|
288
|
+
endByte: node.endIndex,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Return the name identifier text from a declaration node.
|
|
294
|
+
*
|
|
295
|
+
* Works for: function_declaration, class_declaration,
|
|
296
|
+
* type_alias_declaration, interface_declaration.
|
|
297
|
+
*/
|
|
298
|
+
function extractName(node: Parser.SyntaxNode): string | null {
|
|
299
|
+
// tree-sitter names the name child "name" for all four node types.
|
|
300
|
+
const nameNode = node.childForFieldName?.("name") ??
|
|
301
|
+
node.namedChildren.find(
|
|
302
|
+
(c) => c.type === "identifier" || c.type === "type_identifier",
|
|
303
|
+
);
|
|
304
|
+
return nameNode?.text ?? null;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Extract the declaration signature — the header line(s) with the body
|
|
309
|
+
* (statement_block / class_body / object_type / ...) stripped.
|
|
310
|
+
*
|
|
311
|
+
* Strategy: take the full node text, locate the opening `{` of the body
|
|
312
|
+
* (or `=` for type aliases), and trim everything from there onward.
|
|
313
|
+
* Falls back to the first source line of the node.
|
|
314
|
+
*/
|
|
315
|
+
function extractSignature(
|
|
316
|
+
node: Parser.SyntaxNode,
|
|
317
|
+
source: string,
|
|
318
|
+
kind: ChunkKind,
|
|
319
|
+
): string {
|
|
320
|
+
const nodeText = source.slice(node.startIndex, node.endIndex);
|
|
321
|
+
|
|
322
|
+
// For type aliases: `type Foo = Bar` — strip everything after `=`.
|
|
323
|
+
// We keep the `= TypeExpression` for readability but drop multiline bodies.
|
|
324
|
+
if (kind === "type") {
|
|
325
|
+
// Replace a multi-line type body with a single-line placeholder.
|
|
326
|
+
const firstLine = nodeText.split("\n")[0]!.trimEnd();
|
|
327
|
+
// If the full type fits on one line, return as-is (no trailing semicolon stripping).
|
|
328
|
+
if (!nodeText.includes("\n")) return nodeText.trim();
|
|
329
|
+
return firstLine + " …";
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// For everything else: find the opening brace of the body and truncate.
|
|
333
|
+
// We walk children to find the block/body node rather than doing naive
|
|
334
|
+
// string-scanning, which would break on `{` inside generics.
|
|
335
|
+
const bodyNode = findBodyNode(node, kind);
|
|
336
|
+
if (bodyNode) {
|
|
337
|
+
const headerEnd = bodyNode.startIndex - node.startIndex;
|
|
338
|
+
return nodeText.slice(0, headerEnd).trimEnd();
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Fallback: first line of the node text.
|
|
342
|
+
return nodeText.split("\n")[0]!.trimEnd();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Locate the "body" child node for a given declaration kind.
|
|
347
|
+
* Returns null if not found.
|
|
348
|
+
*/
|
|
349
|
+
function findBodyNode(
|
|
350
|
+
node: Parser.SyntaxNode,
|
|
351
|
+
kind: ChunkKind,
|
|
352
|
+
): Parser.SyntaxNode | null {
|
|
353
|
+
const bodyTypes = new Set([
|
|
354
|
+
"statement_block", // function body
|
|
355
|
+
"class_body", // class body
|
|
356
|
+
"object_type", // interface body in TS
|
|
357
|
+
"type_parameters", // not a body, skip — handled separately
|
|
358
|
+
]);
|
|
359
|
+
|
|
360
|
+
// For interfaces, tree-sitter uses `object_type` as the body.
|
|
361
|
+
// For classes, `class_body`. For functions, `statement_block`.
|
|
362
|
+
for (const child of node.namedChildren) {
|
|
363
|
+
if (bodyTypes.has(child.type) && child.type !== "type_parameters") {
|
|
364
|
+
return child;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// For export_statement wrapping, drill one level in.
|
|
369
|
+
if (node.type === "export_statement") {
|
|
370
|
+
for (const child of node.namedChildren) {
|
|
371
|
+
const inner = findBodyNode(child, kind);
|
|
372
|
+
if (inner) return inner;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Extract a JSDoc/TSDoc block or contiguous line-comment block that
|
|
381
|
+
* immediately precedes `node` in the source.
|
|
382
|
+
*
|
|
383
|
+
* Looks at the previous named siblings and collects contiguous `comment`
|
|
384
|
+
* nodes working backward (stopping at any non-comment node or a gap in lines).
|
|
385
|
+
*/
|
|
386
|
+
function extractDocstring(
|
|
387
|
+
node: Parser.SyntaxNode,
|
|
388
|
+
source: string,
|
|
389
|
+
): string | null {
|
|
390
|
+
const comments: string[] = [];
|
|
391
|
+
let prev = previousNamedSibling(node);
|
|
392
|
+
// Reference node for adjacency: starts as the declaration, then becomes
|
|
393
|
+
// the previously collected comment as we walk further back.
|
|
394
|
+
let reference: Parser.SyntaxNode = node;
|
|
395
|
+
|
|
396
|
+
// Collect contiguous comment nodes immediately before this declaration.
|
|
397
|
+
while (prev && prev.type === "comment") {
|
|
398
|
+
// Ensure the comment is adjacent (no blank line gap) to the reference below it.
|
|
399
|
+
if (!isAdjacentAbove(prev, reference, source)) break;
|
|
400
|
+
comments.unshift(source.slice(prev.startIndex, prev.endIndex));
|
|
401
|
+
reference = prev;
|
|
402
|
+
prev = previousNamedSibling(prev);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (comments.length === 0) return null;
|
|
406
|
+
return comments.join("\n");
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Walk `node.parent.namedChildren` to find the sibling immediately before node.
|
|
411
|
+
* SyntaxNode.previousNamedSibling exists in web-tree-sitter but the typing is
|
|
412
|
+
* sometimes absent in older @types stubs — access via cast to be safe.
|
|
413
|
+
*/
|
|
414
|
+
function previousNamedSibling(
|
|
415
|
+
node: Parser.SyntaxNode,
|
|
416
|
+
): Parser.SyntaxNode | null {
|
|
417
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
418
|
+
const prev = (node as any).previousNamedSibling;
|
|
419
|
+
return prev ?? null;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Returns true if `commentNode` ends on the line immediately before
|
|
424
|
+
* `declNode` starts (no blank lines between them).
|
|
425
|
+
*/
|
|
426
|
+
function isAdjacentAbove(
|
|
427
|
+
commentNode: Parser.SyntaxNode,
|
|
428
|
+
declNode: Parser.SyntaxNode,
|
|
429
|
+
_source: string,
|
|
430
|
+
): boolean {
|
|
431
|
+
const commentEndLine = commentNode.endPosition.row;
|
|
432
|
+
const declStartLine = declNode.startPosition.row;
|
|
433
|
+
return declStartLine - commentEndLine <= 1;
|
|
434
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* _ast-helpers.ts — Tree-sitter parse utilities for AST-aware editing (Track C, Sprint 1).
|
|
3
|
+
*
|
|
4
|
+
* Exports:
|
|
5
|
+
* parseFile — read + parse a source file, return tree/source/lang tuple.
|
|
6
|
+
* extractIdentifiers — walk a parsed tree, return all identifiers with kind.
|
|
7
|
+
* walkNodes — generic depth-first tree walker.
|
|
8
|
+
*
|
|
9
|
+
* Value vs type identifier distinction (TypeScript):
|
|
10
|
+
* tree-sitter-typescript uses two distinct node types for identifiers:
|
|
11
|
+
* - `identifier` — value-positioned names (variables, functions, classes in
|
|
12
|
+
* expressions, parameter names, etc.)
|
|
13
|
+
* - `type_identifier` — type-positioned names (type annotations, type aliases,
|
|
14
|
+
* interface names, generic params, etc.)
|
|
15
|
+
* `property_identifier` is also captured as "value" (object property names).
|
|
16
|
+
*
|
|
17
|
+
* Conservative heuristics sufficient for sprint-1. Sprint-2 adds scope-aware
|
|
18
|
+
* resolution (shadowing, closures, re-exports).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { readFile } from "fs/promises";
|
|
22
|
+
// web-tree-sitter@0.22.x: default export is Parser; Tree/SyntaxNode live in the
|
|
23
|
+
// Parser namespace. Import only types to avoid circular init.
|
|
24
|
+
import type Parser from "web-tree-sitter";
|
|
25
|
+
import { resolveLanguage, getParser, type Language, type WTSParser } from "./_ast-languages";
|
|
26
|
+
|
|
27
|
+
// Re-export Language for convenience.
|
|
28
|
+
export type { Language };
|
|
29
|
+
|
|
30
|
+
// Convenience aliases for the 0.22.x namespace types.
|
|
31
|
+
type Tree = Parser.Tree;
|
|
32
|
+
type SyntaxNode = Parser.SyntaxNode;
|
|
33
|
+
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
// Public types
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
export interface ParseResult {
|
|
39
|
+
tree: Tree;
|
|
40
|
+
source: string;
|
|
41
|
+
lang: Language;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface IdentifierRef {
|
|
45
|
+
/** The raw text of the identifier node. */
|
|
46
|
+
name: string;
|
|
47
|
+
/**
|
|
48
|
+
* `"value"` — identifier appears in a value/expression position.
|
|
49
|
+
* `"type"` — identifier appears in a type annotation or type-level position.
|
|
50
|
+
*/
|
|
51
|
+
kind: "value" | "type";
|
|
52
|
+
/**
|
|
53
|
+
* [startIndex, endIndex] byte offsets into the source string.
|
|
54
|
+
* Use `source.slice(range[0], range[1])` to recover the raw text.
|
|
55
|
+
*/
|
|
56
|
+
range: [number, number];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Node types that carry VALUE-position identifiers across languages
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
const VALUE_IDENTIFIER_TYPES = new Set([
|
|
64
|
+
"identifier",
|
|
65
|
+
"property_identifier",
|
|
66
|
+
"shorthand_property_identifier",
|
|
67
|
+
"shorthand_property_identifier_pattern",
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Node types that carry TYPE-position identifiers in TypeScript / TSX
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
const TYPE_IDENTIFIER_TYPES = new Set([
|
|
75
|
+
"type_identifier",
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// walkNodes — generic depth-first visitor
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
export type NodeVisitor = (node: SyntaxNode) => void;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Depth-first pre-order walk of the entire syntax tree.
|
|
86
|
+
* The visitor is called for every node (named and anonymous).
|
|
87
|
+
*/
|
|
88
|
+
export function walkNodes(tree: Tree, visitor: NodeVisitor): void {
|
|
89
|
+
walkNode(tree.rootNode, visitor);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Walk a subtree rooted at `node` (inclusive). Same pre-order semantics as
|
|
94
|
+
* {@link walkNodes}, but scoped — use this when you only want to visit
|
|
95
|
+
* descendants of a specific SyntaxNode (e.g., the body of a single import
|
|
96
|
+
* statement) instead of the whole tree.
|
|
97
|
+
*/
|
|
98
|
+
export function walkSubtree(node: SyntaxNode, visitor: NodeVisitor): void {
|
|
99
|
+
walkNode(node, visitor);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function walkNode(node: SyntaxNode, visitor: NodeVisitor): void {
|
|
103
|
+
visitor(node);
|
|
104
|
+
const children = node.children;
|
|
105
|
+
for (let i = 0; i < children.length; i++) {
|
|
106
|
+
walkNode(children[i]!, visitor);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// extractIdentifiers
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Walk the tree and collect all identifiers with their kind.
|
|
116
|
+
*
|
|
117
|
+
* Duplicate entries at the same byte range are dropped.
|
|
118
|
+
* A name may appear at multiple distinct ranges (each is a separate entry).
|
|
119
|
+
*/
|
|
120
|
+
export function extractIdentifiers(
|
|
121
|
+
tree: Tree,
|
|
122
|
+
_source: string
|
|
123
|
+
): IdentifierRef[] {
|
|
124
|
+
const results: IdentifierRef[] = [];
|
|
125
|
+
const seen = new Set<string>(); // key: `${startIndex}:${endIndex}`
|
|
126
|
+
|
|
127
|
+
walkNodes(tree, (node) => {
|
|
128
|
+
let kind: "value" | "type" | null = null;
|
|
129
|
+
|
|
130
|
+
if (VALUE_IDENTIFIER_TYPES.has(node.type)) {
|
|
131
|
+
kind = "value";
|
|
132
|
+
} else if (TYPE_IDENTIFIER_TYPES.has(node.type)) {
|
|
133
|
+
kind = "type";
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (kind === null) return;
|
|
137
|
+
|
|
138
|
+
const key = `${node.startIndex}:${node.endIndex}`;
|
|
139
|
+
if (seen.has(key)) return;
|
|
140
|
+
seen.add(key);
|
|
141
|
+
|
|
142
|
+
results.push({
|
|
143
|
+
name: node.text,
|
|
144
|
+
kind,
|
|
145
|
+
range: [node.startIndex, node.endIndex],
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return results;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// parseFile
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Read and parse a source file.
|
|
158
|
+
*
|
|
159
|
+
* Returns `null` if:
|
|
160
|
+
* - The file extension is unrecognised.
|
|
161
|
+
* - The language grammar is not yet wired (Python, Go, Rust in sprint-1).
|
|
162
|
+
*
|
|
163
|
+
* Throws on file-system errors (file not found, permission denied, etc.).
|
|
164
|
+
*/
|
|
165
|
+
export async function parseFile(filePath: string): Promise<ParseResult | null> {
|
|
166
|
+
const lang = resolveLanguage(filePath);
|
|
167
|
+
if (lang === null) return null;
|
|
168
|
+
|
|
169
|
+
// Attempt to get the parser — will throw for unwired languages.
|
|
170
|
+
let parser: WTSParser;
|
|
171
|
+
try {
|
|
172
|
+
parser = await getParser(lang);
|
|
173
|
+
} catch {
|
|
174
|
+
// Unwired language (sprint-2 deliverable): return null gracefully.
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const source = await readFile(filePath, "utf-8");
|
|
179
|
+
const tree = parser.parse(source);
|
|
180
|
+
if (!tree) return null;
|
|
181
|
+
|
|
182
|
+
return { tree, source, lang };
|
|
183
|
+
}
|