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
package/docs/deploy.md
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Deploy Guide
|
|
2
|
+
|
|
3
|
+
This document covers end-to-end deployment of the ashlr site (Vercel) and API server (Railway), DNS configuration, smoke testing, rollback procedures, and expected costs.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Vercel — site deployment](#1-vercel--site-deployment)
|
|
10
|
+
2. [Fly.io — API server deployment](#2-flyio--api-server-deployment)
|
|
11
|
+
3. [DNS configuration](#3-dns-configuration)
|
|
12
|
+
4. [Smoke test](#4-smoke-test)
|
|
13
|
+
5. [Rollback procedures](#5-rollback-procedures)
|
|
14
|
+
6. [Cost expectations](#6-cost-expectations)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Signing up — email setup (SendGrid)
|
|
19
|
+
|
|
20
|
+
ashlr uses [SendGrid](https://sendgrid.com) to send magic-link sign-in emails from
|
|
21
|
+
`noreply@ashlr.ai`. Before users can self-serve sign up, a domain-verified
|
|
22
|
+
sender must be configured:
|
|
23
|
+
|
|
24
|
+
1. Create a SendGrid account at https://sendgrid.com and add your sending domain
|
|
25
|
+
(e.g. `ashlr.ai`). Follow their
|
|
26
|
+
[domain verification guide](https://docs.sendgrid.com/ui/sending-email/sender-verification)
|
|
27
|
+
to add the required DNS records (SPF, DKIM, DMARC).
|
|
28
|
+
2. Once the domain is verified, create an API key in the SendGrid dashboard
|
|
29
|
+
(Developers > API Keys). Scope it to "Sending access" only.
|
|
30
|
+
3. Store the key as a Railway variable alongside your other server variables
|
|
31
|
+
(Project > ashlr-plugin-api > Variables, or via CLI):
|
|
32
|
+
```
|
|
33
|
+
railway variables --service ashlr-plugin-api --set SENDGRID_API_KEY=SG...
|
|
34
|
+
```
|
|
35
|
+
4. Set the `FRONTEND_URL` variable to your site origin so magic-link URLs point
|
|
36
|
+
to the right place (default: `https://plugin.ashlr.ai`):
|
|
37
|
+
```
|
|
38
|
+
railway variables --service ashlr-plugin-api --set FRONTEND_URL=https://plugin.ashlr.ai
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Dev / test mode:** If `SENDGRID_API_KEY` is unset, or if `TESTING=1`, no email
|
|
42
|
+
is sent. The magic token is printed to stderr instead — safe for local
|
|
43
|
+
development and CI.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Stripe webhook setup
|
|
48
|
+
|
|
49
|
+
After deploying the API server, register the billing webhook in the Stripe dashboard:
|
|
50
|
+
|
|
51
|
+
1. Go to Stripe Dashboard > Developers > Webhooks > Add endpoint.
|
|
52
|
+
2. Set the endpoint URL to `https://api.ashlr.ai/billing/webhook`.
|
|
53
|
+
3. Select the following events to listen for:
|
|
54
|
+
- `checkout.session.completed`
|
|
55
|
+
- `customer.subscription.updated`
|
|
56
|
+
- `customer.subscription.deleted`
|
|
57
|
+
- `invoice.payment_failed`
|
|
58
|
+
4. After saving, reveal the signing secret (`whsec_...`) and store it as a Railway variable:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
railway variables --service ashlr-plugin-api --set STRIPE_WEBHOOK_SECRET=whsec_...
|
|
62
|
+
railway variables --service ashlr-plugin-api --set STRIPE_SECRET_KEY=sk_live_...
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
5. Bootstrap Stripe products and prices (run once per environment):
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
railway run --service ashlr-plugin-api -- bun run src/cli/stripe-setup.ts
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The setup script is idempotent — re-running it is safe.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 1. Vercel — site deployment
|
|
76
|
+
|
|
77
|
+
The `site/` Next.js app is deployed to Vercel via `.github/workflows/deploy-site.yml`. Pushes to `main` that touch `site/**` trigger a production deploy. Pull requests get a preview URL posted as a comment.
|
|
78
|
+
|
|
79
|
+
### Step 1 — Create the Vercel project
|
|
80
|
+
|
|
81
|
+
1. Go to [vercel.com](https://vercel.com) and sign in.
|
|
82
|
+
2. Click **Add New Project**, select your GitHub repo (`ashlrai/ashlr-plugin`).
|
|
83
|
+
3. Set the **Root Directory** to `site`.
|
|
84
|
+
4. Set the **Framework Preset** to `Next.js`.
|
|
85
|
+
5. Leave build/output settings at defaults — the workflow runs `bun run build` itself.
|
|
86
|
+
6. Click **Deploy** once to initialize the project (this first deploy can be ignored).
|
|
87
|
+
|
|
88
|
+
### Step 2 — Grab the three required tokens
|
|
89
|
+
|
|
90
|
+
All three values are on the project settings page in Vercel.
|
|
91
|
+
|
|
92
|
+
| Secret | Where to find it |
|
|
93
|
+
|--------|-----------------|
|
|
94
|
+
| `VERCEL_TOKEN` | Account Settings > Tokens > Create (scope: Full Account) |
|
|
95
|
+
| `VERCEL_ORG_ID` | Project Settings > General > Team ID (shown at page top) |
|
|
96
|
+
| `VERCEL_PROJECT_ID` | Project Settings > General > Project ID |
|
|
97
|
+
|
|
98
|
+
### Step 3 — Add secrets to GitHub
|
|
99
|
+
|
|
100
|
+
In the GitHub repo, go to **Settings > Secrets and variables > Actions**, then add:
|
|
101
|
+
|
|
102
|
+
- `VERCEL_TOKEN`
|
|
103
|
+
- `VERCEL_ORG_ID`
|
|
104
|
+
- `VERCEL_PROJECT_ID`
|
|
105
|
+
|
|
106
|
+
### Step 4 — Verify
|
|
107
|
+
|
|
108
|
+
Push any change under `site/` to `main`. The **Deploy site to Vercel** workflow should appear under Actions, run `bun run build`, then deploy. The Vercel dashboard shows the new deployment within ~2 minutes.
|
|
109
|
+
|
|
110
|
+
For pull requests, the workflow posts a preview URL comment. No additional configuration needed.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 2. Railway — API server deployment
|
|
115
|
+
|
|
116
|
+
The `server/` Hono/Bun app is deployed to Railway via `.github/workflows/deploy-server.yml`. Pushes to `main` that touch `server/**` run tests first, then deploy. Build is driven by `server/Dockerfile` (referenced from `server/railway.json`).
|
|
117
|
+
|
|
118
|
+
### Step 1 — Install Railway CLI and log in
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
brew install railway # macOS
|
|
122
|
+
# or: curl -fsSL https://railway.com/install.sh | sh
|
|
123
|
+
railway login
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Step 2 — Create the project (first time only)
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
cd server
|
|
130
|
+
railway init --name ashlr-plugin-api
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
This creates a Railway project in your default workspace. After init:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Add a service inside the project (named to match the workflow)
|
|
137
|
+
railway add --service ashlr-plugin-api
|
|
138
|
+
|
|
139
|
+
# Link this directory to the new project so `railway up` knows where to deploy
|
|
140
|
+
railway link
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Railway auto-detects the `Dockerfile` and `railway.json` in `server/`. The `healthcheckPath` is `/readyz` (matches `server/src/routes/health.ts`).
|
|
144
|
+
|
|
145
|
+
### Step 3 — Set environment variables
|
|
146
|
+
|
|
147
|
+
The server needs ~20 variables — see [`docs/operations.md`](./operations.md) for the full list. Set them via either:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Per-key
|
|
151
|
+
railway variables --service ashlr-plugin-api --set ASHLR_MASTER_KEY=...
|
|
152
|
+
|
|
153
|
+
# Or paste a .env in the Railway dashboard:
|
|
154
|
+
# Project > ashlr-plugin-api > Variables > Raw editor
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The minimum to boot a healthy instance: `ASHLR_MASTER_KEY`, `NODE_ENV=production`, `FRONTEND_URL`, plus whichever feature secrets you need (Stripe / SendGrid / GitHub OAuth / xAI).
|
|
158
|
+
|
|
159
|
+
`PORT` is provided by Railway automatically — don't set it.
|
|
160
|
+
|
|
161
|
+
### Step 4 — Get the deploy token
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Project-scoped token (recommended): only deploys to this project, can't access others.
|
|
165
|
+
# Create one in the Railway dashboard:
|
|
166
|
+
# Account > Tokens > New Token > scope: Project: ashlr-plugin-api
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Copy the printed value. This is your `RAILWAY_TOKEN`.
|
|
170
|
+
|
|
171
|
+
### Step 5 — Add the secret to GitHub
|
|
172
|
+
|
|
173
|
+
In GitHub repo > **Settings > Secrets and variables > Actions**, add:
|
|
174
|
+
|
|
175
|
+
- `RAILWAY_TOKEN`
|
|
176
|
+
|
|
177
|
+
### Step 6 — Push and verify
|
|
178
|
+
|
|
179
|
+
Push any change under `server/` to `main`. The **Deploy server to Railway** workflow runs `bun test` first — if any test fails, the deploy is aborted. On success, `railway up --service ashlr-plugin-api --detach` builds and deploys remotely.
|
|
180
|
+
|
|
181
|
+
Verify with:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
curl https://api.ashlr.ai/
|
|
185
|
+
# Expected: {"ok":true,"service":"ashlr-server","phase":1}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 3. DNS configuration
|
|
191
|
+
|
|
192
|
+
### plugin.ashlr.ai — Vercel
|
|
193
|
+
|
|
194
|
+
Add a CNAME record in your DNS provider:
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
Type: CNAME
|
|
198
|
+
Name: plugin
|
|
199
|
+
Value: cname.vercel-dns.com
|
|
200
|
+
TTL: 3600
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Then in Vercel > Project Settings > Domains, add `plugin.ashlr.ai`. Vercel provisions a TLS certificate automatically via Let's Encrypt within ~2 minutes.
|
|
204
|
+
|
|
205
|
+
### api.ashlr.ai — Railway
|
|
206
|
+
|
|
207
|
+
Railway provisions a default `<service>-production-<id>.up.railway.app` domain. Get it with:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
railway domain --service ashlr-plugin-api
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
In the Railway dashboard → ashlr-plugin-api → Settings → Networking → **Custom Domain**, add `api.ashlr.ai`. Railway shows you the exact CNAME target to use; it usually looks like `<id>.up.railway.app`.
|
|
214
|
+
|
|
215
|
+
Add a CNAME record in your DNS provider:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
Type: CNAME
|
|
219
|
+
Name: api
|
|
220
|
+
Value: <target shown in Railway dashboard>
|
|
221
|
+
TTL: 3600
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Railway issues the TLS certificate automatically via Let's Encrypt within ~2 minutes.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 4. Smoke test
|
|
229
|
+
|
|
230
|
+
After every deploy, run the smoke test script to verify both services are healthy:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Install endpoint only (no token required)
|
|
234
|
+
./scripts/deploy-smoke.sh
|
|
235
|
+
|
|
236
|
+
# Full test including badge and stats endpoints
|
|
237
|
+
ASHLR_TOKEN=<provisioned_token> ./scripts/deploy-smoke.sh
|
|
238
|
+
|
|
239
|
+
# Override URLs for staging
|
|
240
|
+
SITE_URL=https://preview.plugin.ashlr.ai \
|
|
241
|
+
API_URL=https://staging-api.ashlr.ai \
|
|
242
|
+
ASHLR_TOKEN=<token> \
|
|
243
|
+
./scripts/deploy-smoke.sh
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The script exits with code `0` on full pass, `1` if any check fails. It is safe to run repeatedly. Checks performed:
|
|
247
|
+
|
|
248
|
+
- `GET /` on site — 200
|
|
249
|
+
- `GET /robots.txt` — 200
|
|
250
|
+
- `GET /sitemap.xml` — 200
|
|
251
|
+
- `GET /` on API — `{ok: true}` JSON
|
|
252
|
+
- `POST /stats/sync` — 200 (authenticated)
|
|
253
|
+
- `GET /stats/aggregate` — user_id present (authenticated)
|
|
254
|
+
- `GET /u/:userId/badge.svg` — SVG content with metric text
|
|
255
|
+
|
|
256
|
+
To provision a token for testing:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
cd server && bun run issue-token
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## 5. Rollback procedures
|
|
265
|
+
|
|
266
|
+
### Vercel rollback
|
|
267
|
+
|
|
268
|
+
The Vercel dashboard keeps every deployment permanently. To roll back:
|
|
269
|
+
|
|
270
|
+
1. Go to the project > **Deployments**.
|
|
271
|
+
2. Find the last known-good deployment.
|
|
272
|
+
3. Click the three-dot menu > **Promote to Production**.
|
|
273
|
+
|
|
274
|
+
Takes effect within 30 seconds globally.
|
|
275
|
+
|
|
276
|
+
Alternatively, revert the offending commit and push — the workflow redeploys automatically.
|
|
277
|
+
|
|
278
|
+
### Railway rollback
|
|
279
|
+
|
|
280
|
+
Railway keeps every previous deployment. Roll back instantly from the dashboard:
|
|
281
|
+
|
|
282
|
+
1. Go to the project > **ashlr-plugin-api** > **Deployments**.
|
|
283
|
+
2. Find the last known-good deployment.
|
|
284
|
+
3. Click the three-dot menu > **Redeploy**.
|
|
285
|
+
|
|
286
|
+
Or via CLI:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# List recent deployments
|
|
290
|
+
railway status --service ashlr-plugin-api
|
|
291
|
+
|
|
292
|
+
# Redeploy the most recent successful deployment (rollback if HEAD is broken)
|
|
293
|
+
railway redeploy --service ashlr-plugin-api
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Or revert the commit and push — the workflow redeploys the server automatically.
|
|
297
|
+
|
|
298
|
+
To monitor a rollback:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
railway logs --service ashlr-plugin-api
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 6. Cost expectations
|
|
307
|
+
|
|
308
|
+
Cost figures below are derived from the Phase 1 architecture (Railway for compute, Neon serverless Postgres, Cloudflare R2/S3 for storage, Upstash Redis for rate limits).
|
|
309
|
+
|
|
310
|
+
| Component | 100 MAU | 1,000 MAU | 10,000 MAU |
|
|
311
|
+
|-----------|---------|-----------|------------|
|
|
312
|
+
| Vercel (site hosting) | Free tier | Free tier | ~$20/mo (Pro) |
|
|
313
|
+
| Railway compute (ashlr-plugin-api, sleeps when idle) | ~$5/mo | ~$10/mo | ~$30/mo |
|
|
314
|
+
| Postgres (Neon serverless) | ~$0.50/mo | ~$5/mo | ~$30/mo |
|
|
315
|
+
| S3 / R2 (stats backups, genome bodies) | ~$0.10/mo | ~$1/mo | ~$8/mo |
|
|
316
|
+
| Redis (Upstash, rate limits + cache) | $0 (free tier) | $20/mo (fixed) | $50/mo |
|
|
317
|
+
| Cloud LLM inference (Haiku, summarization) | ~$0.20/mo | ~$2/mo | ~$20/mo |
|
|
318
|
+
| Bandwidth + misc | ~$0.20/mo | ~$2/mo | ~$15/mo |
|
|
319
|
+
| **Total** | **~$4/mo** | **~$38/mo** | **~$173/mo** |
|
|
320
|
+
|
|
321
|
+
**At 1K MAU**, total infra is approximately **$38/month**. The MIT free tier carries no marginal cost per user for the open-source plugin itself; backend costs arise only from the Pro stats-sync and hosted badge features.
|
|
322
|
+
|
|
323
|
+
**At 10K MAU**, the architecture remains defensible. Beyond that, add Postgres read replicas and consider sharding by organization. See `docs/pro-backend-architecture.md` for the full cost model and scaling decision points.
|
|
324
|
+
|
|
325
|
+
**Fly.io specifics**: the `ashlr-api` app is configured with `auto_stop_machines = "stop"` and `min_machines_running = 0`. It scales to zero when idle, meaning zero compute cost at 0 requests. The first request cold-starts in ~500ms (Bun is fast). For production traffic, set `min_machines_running = 1` to eliminate cold starts at the cost of ~$3/mo for the always-on machine.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# ashlr email templates
|
|
2
|
+
|
|
3
|
+
React-email templates for all transactional emails sent by the ashlr backend.
|
|
4
|
+
|
|
5
|
+
## Preview server
|
|
6
|
+
|
|
7
|
+
Start a local preview server on port 3333:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
bun run server/src/emails/preview.ts
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then open http://localhost:3333 to browse all templates. Each template is rendered with realistic sample data. The preview server does not require `SENDGRID_API_KEY`.
|
|
14
|
+
|
|
15
|
+
Individual template URLs:
|
|
16
|
+
|
|
17
|
+
| Template | URL |
|
|
18
|
+
|---|---|
|
|
19
|
+
| magic-link | http://localhost:3333/preview/magic-link |
|
|
20
|
+
| welcome | http://localhost:3333/preview/welcome |
|
|
21
|
+
| payment-success | http://localhost:3333/preview/payment-success |
|
|
22
|
+
| payment-failed | http://localhost:3333/preview/payment-failed |
|
|
23
|
+
| subscription-canceled | http://localhost:3333/preview/subscription-canceled |
|
|
24
|
+
| daily-cap-reached | http://localhost:3333/preview/daily-cap-reached |
|
|
25
|
+
|
|
26
|
+
Or via the npm script alias:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
cd server && bun run email:preview
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Templates
|
|
33
|
+
|
|
34
|
+
### magic-link
|
|
35
|
+
|
|
36
|
+
**Subject:** Your ashlr sign-in link
|
|
37
|
+
**Trigger:** `POST /auth/send`
|
|
38
|
+
**Props:** `{ email: string, link: string }`
|
|
39
|
+
|
|
40
|
+
Sign-in magic link. Greets the user by the local part of their email address, provides a prominent CTA button, includes the raw link in plain text below the button for accessibility, and notes the 15-minute expiration. Security notice at the bottom.
|
|
41
|
+
|
|
42
|
+
### welcome
|
|
43
|
+
|
|
44
|
+
**Subject:** Welcome to ashlr · your first steps
|
|
45
|
+
**Trigger:** `checkout.session.completed` (sent alongside payment-success)
|
|
46
|
+
**Props:** `{ email: string }`
|
|
47
|
+
|
|
48
|
+
Onboarding email. Three numbered steps: run `/ashlr-tour`, set up `ASHLR_PRO_TOKEN`, open `/ashlr-dashboard`. Links to docs, GitHub, and pricing.
|
|
49
|
+
|
|
50
|
+
### payment-success
|
|
51
|
+
|
|
52
|
+
**Subject:** ashlr Pro — you're in
|
|
53
|
+
**Trigger:** `checkout.session.completed`
|
|
54
|
+
**Props:** `{ email: string, amount: number, tier: string, renewsOn: string }`
|
|
55
|
+
|
|
56
|
+
Subscription confirmation. Receipt table with plan, amount charged (formatted as `$X.XX`), and renewal date. Links to dashboard and billing portal.
|
|
57
|
+
|
|
58
|
+
### payment-failed
|
|
59
|
+
|
|
60
|
+
**Subject:** ashlr Pro — payment failed, we'll retry
|
|
61
|
+
**Trigger:** `invoice.payment_failed`
|
|
62
|
+
**Props:** `{ email: string, gracePeriodEnd: string }`
|
|
63
|
+
|
|
64
|
+
Payment failure notice. Explains the 7-day grace period, shows the exact date access expires if unresolved, provides a CTA to update the payment method in the Stripe billing portal.
|
|
65
|
+
|
|
66
|
+
### subscription-canceled
|
|
67
|
+
|
|
68
|
+
**Subject:** ashlr Pro — your subscription has ended
|
|
69
|
+
**Trigger:** `customer.subscription.deleted`
|
|
70
|
+
**Props:** `{ email: string }`
|
|
71
|
+
|
|
72
|
+
Cancellation confirmation. Clearly states that local-first features (genome init, token savings, slash commands, full CLI) remain free forever. Lists the Pro-only features that have been disabled: genome sync across machines and cloud LLM summarization. CTA to resubscribe.
|
|
73
|
+
|
|
74
|
+
### daily-cap-reached
|
|
75
|
+
|
|
76
|
+
**Subject:** ashlr Pro — daily LLM cap reached
|
|
77
|
+
**Trigger:** first `POST /llm/summarize` that returns 429 for a given user on a given UTC day
|
|
78
|
+
**Props:** `{ email: string }`
|
|
79
|
+
|
|
80
|
+
Throttled notification (once per user per day via `daily_cap_notifications` table). Shows the 1,000-call / $1.00 cap, the midnight UTC reset time, and a link to Enterprise pricing for higher limits. Local features are explicitly noted as unaffected.
|
|
81
|
+
|
|
82
|
+
## Design system
|
|
83
|
+
|
|
84
|
+
| Token | Value |
|
|
85
|
+
|---|---|
|
|
86
|
+
| Paper (background) | `#F3EADB` |
|
|
87
|
+
| Ink (text) | `#121212` |
|
|
88
|
+
| Accent (CTA, links) | `#8B2E1A` |
|
|
89
|
+
| Muted (secondary text) | `#6B5B4E` |
|
|
90
|
+
| Border | `#D9CEBD` |
|
|
91
|
+
|
|
92
|
+
Fonts: Fraunces italic (headings, loaded via Google Fonts woff2), IBM Plex Sans (body). Web-safe fallbacks: Georgia, Helvetica, Arial.
|
|
93
|
+
|
|
94
|
+
Container: 600px centered, white background, 8px border-radius, parchment outer background. Mobile-responsive via `maxWidth: 600px`.
|
|
95
|
+
|
|
96
|
+
## Sending integration
|
|
97
|
+
|
|
98
|
+
All sends go through `server/src/lib/email.ts`:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
await sendEmail("magic-link", { to: email, data: { email, link } });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The function renders the React template to HTML + plain text, then calls SendGrid. If `SENDGRID_API_KEY` is unset or `TESTING=1`, it logs the rendered output to stderr instead.
|
|
105
|
+
|
|
106
|
+
## Email client compatibility notes
|
|
107
|
+
|
|
108
|
+
- **Gmail**: strips `<style>` blocks in `<head>`. All styles are inline via react-email's built-in inline style props, so Gmail renders correctly.
|
|
109
|
+
- **Outlook (Windows)**: does not support border-radius, box-shadow, or `display: inline-block` on buttons reliably. The CTA button degrades to a plain rectangular block — still functional. The plain-text link below the button ensures access regardless.
|
|
110
|
+
- **Outlook (Windows)**: does not render SVG in `<img>` tags. The logo SVG is embedded inline (not via `<img src="...svg">`), which renders correctly in Gmail and Apple Mail. In Outlook on Windows the inline SVG is ignored; the `aria-label="ashlr"` on the SVG provides accessible fallback text.
|
|
111
|
+
- **Apple Mail**: full support for inline SVG, web fonts, and CSS. All templates render as designed.
|
|
112
|
+
- **Dark mode**: templates use a white card on parchment background. Email clients that invert colors in dark mode (Apple Mail, some Android clients) may adjust the outer background; the inner card remains readable due to explicit background-color declarations on all sections.
|
|
113
|
+
- **Plain-text fallback**: every template exports a `plainText()` function. The SendGrid send includes both `html` and `text` fields, so clients that strip HTML receive the plain-text version.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Embedding Cache Threshold Tuning
|
|
2
|
+
|
|
3
|
+
The ashlr grep cache uses cosine similarity to decide whether a cached result
|
|
4
|
+
is close enough to the current query to be reused. The default threshold is
|
|
5
|
+
`0.68`. This document explains how to tune it for your actual usage patterns.
|
|
6
|
+
|
|
7
|
+
## Background
|
|
8
|
+
|
|
9
|
+
Every grep routed through `ashlr__grep` logs a calibration record to
|
|
10
|
+
`~/.ashlr/embed-calibration.jsonl`:
|
|
11
|
+
|
|
12
|
+
```jsonl
|
|
13
|
+
{"ts":"2026-04-25T10:00:00Z","queryHashHex":"a1b2c3d4","topSimilarity":0.82,"hit":true,"contentLength":1400,"threshold":0.68}
|
|
14
|
+
{"ts":"2026-04-25T10:00:01Z","queryHashHex":"e5f6a7b8","topSimilarity":0.61,"hit":false,"contentLength":0,"threshold":0.68}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- `hit: true` — the cached result was served (cosine similarity >= threshold).
|
|
18
|
+
- `hit: false` — the cache was skipped; a fresh ripgrep ran instead.
|
|
19
|
+
- `topSimilarity` — the best cosine score found in the embedding index.
|
|
20
|
+
|
|
21
|
+
After a few hundred grep operations you have enough data to tune the threshold.
|
|
22
|
+
|
|
23
|
+
## Running the tuner
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
# Report only (no changes written):
|
|
27
|
+
bun run scripts/embed-tune.ts
|
|
28
|
+
|
|
29
|
+
# Custom input file:
|
|
30
|
+
bun run scripts/embed-tune.ts --input ~/.ashlr/embed-calibration.jsonl
|
|
31
|
+
|
|
32
|
+
# Weight precision 2× over recall (penalise false positives harder):
|
|
33
|
+
bun run scripts/embed-tune.ts --weight precision=2
|
|
34
|
+
|
|
35
|
+
# Write recommendation to ~/.ashlr/config.json:
|
|
36
|
+
bun run scripts/embed-tune.ts --apply
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Sample output:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
ashlr embed-tune report
|
|
43
|
+
──────────────────────────────────────────────────
|
|
44
|
+
entries analysed : 312
|
|
45
|
+
beta weight : 1 (F1 score)
|
|
46
|
+
|
|
47
|
+
current threshold 0.68 → precision 0.74 recall 0.83 F1 0.78
|
|
48
|
+
recommended 0.71 → precision 0.81 recall 0.79 F1 0.80
|
|
49
|
+
|
|
50
|
+
Set via: ASHLR_EMBED_THRESHOLD=0.71
|
|
51
|
+
Or run with --apply to persist to ~/.ashlr/config.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## How it works
|
|
55
|
+
|
|
56
|
+
The tuner sweeps thresholds from `0.50` to `0.95` in `0.01` steps. At each
|
|
57
|
+
step it computes:
|
|
58
|
+
|
|
59
|
+
| Metric | Definition |
|
|
60
|
+
|-----------|------------|
|
|
61
|
+
| precision | % of cache hits that were genuine (hit=true in calibration data) |
|
|
62
|
+
| recall | % of all genuine hits that would still be served from cache |
|
|
63
|
+
| F1 | harmonic mean of precision and recall |
|
|
64
|
+
|
|
65
|
+
The threshold that maximises F1 (or F-beta with `--weight`) is recommended.
|
|
66
|
+
|
|
67
|
+
### Weighted F-beta
|
|
68
|
+
|
|
69
|
+
Pass `--weight precision=2` to use F2, which weights recall twice as much as
|
|
70
|
+
precision — useful if you want maximum cache utilisation and can tolerate some
|
|
71
|
+
irrelevant results. Pass `--weight precision=0.5` (i.e. F0.5) to prioritise
|
|
72
|
+
precision — useful if false positives cause visible quality regressions.
|
|
73
|
+
|
|
74
|
+
## Applying the result
|
|
75
|
+
|
|
76
|
+
With `--apply`, the tuner writes `embedThreshold` to `~/.ashlr/config.json`:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"embedThreshold": 0.71
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then prints: **"Restart Claude Code to apply."**
|
|
85
|
+
|
|
86
|
+
The MCP server reads this value on startup. The `ASHLR_EMBED_THRESHOLD`
|
|
87
|
+
environment variable takes precedence over `config.json` when both are set.
|
|
88
|
+
|
|
89
|
+
## Minimum corpus size
|
|
90
|
+
|
|
91
|
+
The embedding cache is skipped entirely when the BM25 corpus has fewer than
|
|
92
|
+
50 documents (`BM25_CORPUS_MIN`). Below this size, IDF weights are noisy and
|
|
93
|
+
cosine similarity scores are unreliable regardless of threshold. Let the corpus
|
|
94
|
+
grow before tuning.
|
|
95
|
+
|
|
96
|
+
## When to re-tune
|
|
97
|
+
|
|
98
|
+
- After onboarding a new large project (corpus distribution shifts).
|
|
99
|
+
- If you change the embedding model (`ASHLR_EMBED_MODEL`).
|
|
100
|
+
- If you notice grep results that look stale or irrelevant.
|
|
101
|
+
|
|
102
|
+
A rule of thumb: re-tune after every ~500 grep operations, or whenever
|
|
103
|
+
`embed-calibration.jsonl` grows by more than 200 lines since the last run.
|
package/docs/genome.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Genome Auto-Refresh
|
|
2
|
+
|
|
3
|
+
The genome (`.ashlrcode/genome/`) is the RAG index that powers `ashlr__grep`. Without
|
|
4
|
+
updates it drifts from the codebase as you edit files — causing grep to silently fall
|
|
5
|
+
back to ripgrep, which is slower and larger.
|
|
6
|
+
|
|
7
|
+
The auto-refresh pipeline (v1.23 Track HH) keeps the genome current without
|
|
8
|
+
requiring manual intervention.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## How the refresh cycle works
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
User edits file
|
|
16
|
+
│
|
|
17
|
+
▼
|
|
18
|
+
PostToolUse hook: posttooluse-genome-refresh.ts
|
|
19
|
+
├─ Extract file path from Edit/Write/MultiEdit/NotebookEdit payload
|
|
20
|
+
├─ Append absolute path to ~/.ashlr/pending-genome-refresh.txt (deduped)
|
|
21
|
+
└─ Exit 0 immediately (never blocks)
|
|
22
|
+
|
|
23
|
+
│ (multiple edits accumulate, file is appended to)
|
|
24
|
+
│
|
|
25
|
+
▼ (session ends)
|
|
26
|
+
|
|
27
|
+
SessionEnd hook: session-end-consolidate.ts
|
|
28
|
+
├─ 1. genome-auto-consolidate.ts — merges proposals.jsonl
|
|
29
|
+
├─ 2. genome-cloud-push.ts — pushes to team cloud (if configured)
|
|
30
|
+
├─ 3. genome-refresh-worker.ts — incremental refresh ← NEW
|
|
31
|
+
└─ 4. telemetry-flush.ts — opt-in telemetry
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Debounce
|
|
35
|
+
|
|
36
|
+
The worker checks the mtime of `pending-genome-refresh.txt`. If it was written within
|
|
37
|
+
the last 2 seconds, processing is deferred (another edit may be in flight). This
|
|
38
|
+
prevents partial refreshes during rapid multi-file sessions. At session end the file is
|
|
39
|
+
always old enough to pass the debounce check.
|
|
40
|
+
|
|
41
|
+
### Incremental vs. full
|
|
42
|
+
|
|
43
|
+
**Incremental (default):** For each pending file, `_genome-live.refreshGenomeAfterEdit`
|
|
44
|
+
is called. It:
|
|
45
|
+
- Finds genome sections that reference the file (by filename or path)
|
|
46
|
+
- Verbatim sections: patches literal content in-place
|
|
47
|
+
- Summarized sections: invalidates (deletes) them so the propose queue regenerates
|
|
48
|
+
|
|
49
|
+
No LLM calls. Cost is proportional to the number of sections referencing the file.
|
|
50
|
+
|
|
51
|
+
**Full rebuild (`--full`):** Re-runs `genome-init.ts --force --minimal` for each
|
|
52
|
+
affected genome root. Rebuilds from scratch. No LLM summarization unless Ollama is
|
|
53
|
+
running. Use explicitly for schema upgrades or large structural refactors.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Stale detection
|
|
58
|
+
|
|
59
|
+
When `ashlr__grep` finds a genome but gets zero matching sections, it:
|
|
60
|
+
1. Increments an in-session fallback counter
|
|
61
|
+
2. Emits a `genome_stale_detected` telemetry event (pattern + fallback count)
|
|
62
|
+
3. After **3 fallbacks in the same session**, surfaces a one-time nudge:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
[ashlr] genome may be stale (3 grep queries fell through to ripgrep).
|
|
66
|
+
Run `bun run scripts/genome-refresh-worker.ts` to refresh, or
|
|
67
|
+
`bun run scripts/genome-refresh-worker.ts --full` for a complete rebuild.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
This fires once per session so it doesn't spam repeated queries.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## File locations
|
|
75
|
+
|
|
76
|
+
| Path | Purpose |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `~/.ashlr/pending-genome-refresh.txt` | Pending edit paths (one per line, deduped) |
|
|
79
|
+
| `hooks/posttooluse-genome-refresh.ts` | PostToolUse hook — records paths |
|
|
80
|
+
| `scripts/genome-refresh-worker.ts` | Worker — incremental refresh + `--full` mode |
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Manual refresh
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Incremental: refresh only files edited since last refresh
|
|
88
|
+
bun run scripts/genome-refresh-worker.ts
|
|
89
|
+
|
|
90
|
+
# Dry run: see what would be refreshed
|
|
91
|
+
bun run scripts/genome-refresh-worker.ts --dry-run
|
|
92
|
+
|
|
93
|
+
# Full rebuild (no LLM unless Ollama is running)
|
|
94
|
+
bun run scripts/genome-refresh-worker.ts --full
|
|
95
|
+
|
|
96
|
+
# Full rebuild, dry run
|
|
97
|
+
bun run scripts/genome-refresh-worker.ts --full --dry-run
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Kill switch
|
|
103
|
+
|
|
104
|
+
Set `ASHLR_GENOME_AUTO=0` to disable all genome automation (refresh, proposals,
|
|
105
|
+
consolidation). The pending file will still accumulate but nothing processes it.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Gotchas
|
|
110
|
+
|
|
111
|
+
- **Pending file is cumulative.** If you kill Claude mid-session, the pending file
|
|
112
|
+
persists across the next session start and is processed at the next session end.
|
|
113
|
+
- **Sections not referencing the file by name are not invalidated.** If your genome
|
|
114
|
+
section uses a generic title (e.g. "Overview") with no mention of the filename in
|
|
115
|
+
content/tags/summary, the refresh will miss it. Use descriptive section titles.
|
|
116
|
+
- **`--full` on large repos is slow.** It re-scans the entire project. Run it manually
|
|
117
|
+
only when structural reorganization makes incremental refresh insufficient.
|
|
118
|
+
- **No LLM in the auto path.** The incremental worker never calls an LLM. The only
|
|
119
|
+
LLM-touching path is `genome-init --summarize` (Ollama, opt-in), which is only
|
|
120
|
+
reachable via `--full`.
|