@reticlehq/server 2.13.0 → 2.14.0
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/SKILL.md +8 -18
- package/bin/reticle.js +3 -0
- package/dist/bridge/auth-failure-reason.js +12 -1
- package/dist/bridge/bridge-security.d.ts +8 -0
- package/dist/bridge/bridge-security.js +6 -1
- package/dist/bridge/bridge.d.ts +3 -0
- package/dist/bridge/bridge.js +23 -1
- package/dist/bridge/bridge.test-harness.d.ts +10 -1
- package/dist/bridge/bridge.test-harness.js +7 -1
- package/dist/bridge/pairing-token.d.ts +17 -0
- package/dist/bridge/pairing-token.js +26 -0
- package/dist/bridge/token-auth.d.ts +7 -0
- package/dist/bridge/token-auth.js +7 -1
- package/dist/capsule/capsule-store.d.ts +4 -4
- package/dist/capsule/capsule.d.ts +1 -1
- package/dist/capsule/capsule.js +3 -3
- package/dist/capsule/causal-summary.d.ts +21 -1
- package/dist/capsule/causal-summary.js +8 -6
- package/dist/capsule/divergence.d.ts +1 -1
- package/dist/capsule/divergence.js +26 -10
- package/dist/chromium-launch-options.d.ts +2 -1
- package/dist/cli/adhoc-verdict.d.ts +58 -0
- package/dist/cli/adhoc-verdict.js +115 -0
- package/dist/cli/chromium-hint.d.ts +18 -4
- package/dist/cli/chromium-hint.js +54 -6
- package/dist/cli/cli-doctor.js +1 -2
- package/dist/cli/cli-flow-commands.d.ts +16 -2
- package/dist/cli/cli-flow-commands.js +28 -9
- package/dist/cli/cli-parse-feedback.js +1 -1
- package/dist/cli/cli-parse.d.ts +2 -1
- package/dist/cli/cli-parse.js +38 -0
- package/dist/cli/cli-port.d.ts +5 -13
- package/dist/cli/cli-port.js +5 -38
- package/dist/cli/cli-update-commands.js +4 -4
- package/dist/cli/cli-verify.d.ts +24 -7
- package/dist/cli/cli-verify.js +87 -13
- package/dist/cli/cloud-keystore.d.ts +2 -1
- package/dist/cli/cloud-login.d.ts +2 -1
- package/dist/cli/cloud-session.d.ts +2 -1
- package/dist/cli/cloud-session.js +1 -1
- package/dist/cli/daemon-start-options.d.ts +2 -1
- package/dist/cli/device-flow.d.ts +2 -2
- package/dist/cli/doctor-daemon-line.d.ts +2 -1
- package/dist/cli/doctor-project-line.d.ts +2 -1
- package/dist/cli/doctor-rows.d.ts +2 -1
- package/dist/cli/drive-attach.d.ts +4 -3
- package/dist/cli/gate-hook-message.d.ts +2 -1
- package/dist/cli/status-next-action.js +10 -11
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +21 -9
- package/dist/cloud/account-state.d.ts +20 -0
- package/dist/cloud/account-state.js +65 -0
- package/dist/cloud/cloud-sync.d.ts +46 -3
- package/dist/cloud/cloud-sync.js +116 -0
- package/dist/cloud/sync-cycle.d.ts +5 -4
- package/dist/cloud/sync-cycle.js +1 -1
- package/dist/cloud/sync-daemon.d.ts +3 -19
- package/dist/cloud/sync-daemon.js +2 -2
- package/dist/crawl/crawl-tools.js +1 -1
- package/dist/crawl/crawl.d.ts +5 -5
- package/dist/crawl/crawl.js +138 -4
- package/dist/daemon/daemon-resilience.d.ts +3 -2
- package/dist/daemon/daemon-resilience.js +43 -4
- package/dist/daemon/daemon-resolve.d.ts +0 -9
- package/dist/daemon/daemon-resolve.js +2 -2
- package/dist/daemon/dev-servers.d.ts +1 -1
- package/dist/daemon/dev-servers.js +1 -1
- package/dist/daemon/loopback-alias.d.ts +2 -1
- package/dist/daemon/startup-failure.d.ts +11 -0
- package/dist/daemon/startup-failure.js +46 -0
- package/dist/events/contradictions.d.ts +10 -16
- package/dist/events/contradictions.js +149 -17
- package/dist/events/declared.d.ts +13 -1
- package/dist/events/declared.js +59 -3
- package/dist/events/echo-mismatch.js +75 -6
- package/dist/events/lineage.d.ts +52 -0
- package/dist/events/lineage.js +122 -0
- package/dist/events/net-evidence.d.ts +21 -0
- package/dist/events/net-evidence.js +81 -0
- package/dist/events/predicate-console.d.ts +13 -0
- package/dist/events/predicate-console.js +138 -0
- package/dist/events/predicate-element.d.ts +13 -0
- package/dist/events/predicate-element.js +214 -0
- package/dist/events/predicate-eval.d.ts +15 -3
- package/dist/events/predicate-eval.js +128 -110
- package/dist/events/predicate-parse.js +34 -1
- package/dist/events/predicate-request-body.d.ts +50 -0
- package/dist/events/predicate-request-body.js +120 -0
- package/dist/events/predicate-route.d.ts +21 -1
- package/dist/events/predicate-route.js +149 -21
- package/dist/events/predicate-schema.d.ts +8 -1
- package/dist/events/predicate-schema.js +34 -0
- package/dist/events/predicate.d.ts +2 -0
- package/dist/events/predicate.js +52 -159
- package/dist/events/split-text-miss.d.ts +6 -4
- package/dist/events/split-text-miss.js +12 -5
- package/dist/flows/affected-tools.js +22 -9
- package/dist/flows/annotate.d.ts +2 -1
- package/dist/flows/annotate.js +19 -1
- package/dist/flows/coverage.d.ts +2 -2
- package/dist/flows/flake.d.ts +3 -3
- package/dist/flows/flow-expect-grammar.d.ts +33 -0
- package/dist/flows/flow-expect-grammar.js +155 -0
- package/dist/flows/flow-replay-run.d.ts +1 -1
- package/dist/flows/flow-replay-run.js +28 -15
- package/dist/flows/flow-replay.d.ts +10 -0
- package/dist/flows/flow-replay.js +57 -22
- package/dist/flows/flow-secret-field.d.ts +14 -0
- package/dist/flows/flow-secret-field.js +22 -0
- package/dist/flows/flow-step-runners.d.ts +1 -0
- package/dist/flows/flow-step-runners.js +91 -34
- package/dist/flows/flow-success.js +22 -0
- package/dist/flows/flow-tools.js +27 -8
- package/dist/flows/flow-upload-resolve.d.ts +23 -0
- package/dist/flows/flow-upload-resolve.js +46 -0
- package/dist/flows/flows.d.ts +15 -0
- package/dist/flows/flows.js +17 -14
- package/dist/flows/git-changed.d.ts +23 -4
- package/dist/flows/git-changed.js +32 -6
- package/dist/flows/heal-run.js +2 -2
- package/dist/flows/predicate-to-expect.d.ts +3 -2
- package/dist/flows/predicate-to-expect.js +11 -5
- package/dist/flows/recording-backtrack.d.ts +24 -0
- package/dist/flows/recording-backtrack.js +73 -0
- package/dist/flows/recordings.d.ts +6 -0
- package/dist/flows/replay-halt.d.ts +26 -0
- package/dist/flows/replay-halt.js +30 -0
- package/dist/flows/replay.d.ts +0 -8
- package/dist/flows/replay.js +15 -3
- package/dist/flows/suite-flakes.d.ts +2 -1
- package/dist/flows/verify-change-tools.js +16 -4
- package/dist/honesty/already-true.d.ts +14 -0
- package/dist/honesty/already-true.js +47 -4
- package/dist/honesty/blind-spots.d.ts +3 -1
- package/dist/honesty/blind-spots.js +24 -1
- package/dist/honesty/body-capture-remedy.d.ts +42 -0
- package/dist/honesty/body-capture-remedy.js +95 -0
- package/dist/honesty/feature-capture.d.ts +3 -2
- package/dist/honesty/feature-capture.js +1 -1
- package/dist/honesty/gap-ledger.d.ts +1 -1
- package/dist/honesty/gap-ledger.js +1 -1
- package/dist/honesty/instrumentation-gaps.d.ts +8 -1
- package/dist/honesty/instrumentation-gaps.js +12 -2
- package/dist/honesty/observability.d.ts +4 -3
- package/dist/honesty/tool-hit-rate.d.ts +3 -2
- package/dist/honesty/uncaptured-bodies.d.ts +3 -1
- package/dist/honesty/uncaptured-bodies.js +6 -2
- package/dist/honesty/unsettled.d.ts +9 -0
- package/dist/honesty/unsettled.js +45 -0
- package/dist/honesty/verified.d.ts +32 -1
- package/dist/honesty/verified.js +37 -10
- package/dist/impact/impact-store.d.ts +5 -14
- package/dist/impact/impact-store.js +49 -6
- package/dist/index.js +1 -1
- package/dist/input/network-detail.d.ts +26 -1
- package/dist/input/network-detail.js +44 -12
- package/dist/input/network-mock-tools.js +24 -17
- package/dist/input/real-input.js +1 -1
- package/dist/input/viewport-tools.js +25 -13
- package/dist/intent/inline-intent.d.ts +0 -10
- package/dist/intent/inline-intent.js +1 -1
- package/dist/intent/intent-shard-store.d.ts +3 -2
- package/dist/intent/intent-shard-store.js +1 -1
- package/dist/intent/intent-shard.d.ts +14 -14
- package/dist/intent/intent-shard.js +4 -4
- package/dist/intent/intent-store.d.ts +1 -1
- package/dist/intent/intent-store.js +1 -1
- package/dist/intent/intent-subject.d.ts +2 -1
- package/dist/intent/open-intents.d.ts +3 -2
- package/dist/license/license.d.ts +4 -4
- package/dist/license/license.js +1 -1
- package/dist/mcp/attach-memory.d.ts +2 -1
- package/dist/mcp/client-identity.d.ts +2 -1
- package/dist/mcp/mcp-outage.d.ts +1 -1
- package/dist/mcp/mcp-outage.js +1 -1
- package/dist/mcp/mcp-proxy.d.ts +3 -1
- package/dist/mcp/mcp-proxy.js +32 -7
- package/dist/mcp/mcp.js +3 -1
- package/dist/mcp/proxy-handshake.d.ts +2 -1
- package/dist/mcp/proxy-idle-exit.d.ts +45 -0
- package/dist/mcp/proxy-idle-exit.js +94 -0
- package/dist/mcp/server-instructions.d.ts +2 -1
- package/dist/memory/project-memory.d.ts +2 -3
- package/dist/memory/project-memory.js +1 -1
- package/dist/oracles/propose-consequences.js +5 -5
- package/dist/oracles/self-instrument.d.ts +2 -2
- package/dist/oracles/self-instrument.js +1 -1
- package/dist/platform.d.ts +3 -5
- package/dist/platform.js +3 -5
- package/dist/pool/browser-pool.d.ts +92 -0
- package/dist/pool/browser-pool.js +119 -5
- package/dist/pool/playwright-launcher.js +29 -2
- package/dist/pool/storage-seed.d.ts +23 -0
- package/dist/pool/storage-seed.js +198 -0
- package/dist/project/artifact-root.d.ts +2 -1
- package/dist/project/memory-fs.d.ts +2 -1
- package/dist/project/reticle-dir.js +1 -1
- package/dist/project/session-root.d.ts +8 -0
- package/dist/project/session-root.js +9 -2
- package/dist/runs/reticle-runner.d.ts +14 -1
- package/dist/runs/reticle-runner.js +39 -2
- package/dist/session/attachment-history.d.ts +2 -1
- package/dist/session/fake-session.d.ts +37 -0
- package/dist/session/fake-session.js +81 -0
- package/dist/session/lease-visibility.d.ts +2 -1
- package/dist/session/live-control-tools.js +6 -0
- package/dist/session/no-session-diagnosis.d.ts +17 -1
- package/dist/session/no-session-diagnosis.js +32 -6
- package/dist/session/no-session-next-action.d.ts +14 -0
- package/dist/session/no-session-next-action.js +18 -0
- package/dist/session/no-session-watch.js +46 -3
- package/dist/session/registered-projects.d.ts +54 -0
- package/dist/session/registered-projects.js +73 -0
- package/dist/session/review-store.d.ts +2 -1
- package/dist/session/session-health.d.ts +62 -1
- package/dist/session/session-health.js +82 -2
- package/dist/session/session-manager.d.ts +11 -1
- package/dist/session/session-manager.js +18 -3
- package/dist/session/session-replaced.d.ts +24 -0
- package/dist/session/session-replaced.js +29 -0
- package/dist/session/session-successor.js +20 -4
- package/dist/session/session.d.ts +13 -5
- package/dist/session/session.js +31 -23
- package/dist/setup/agent-configs.d.ts +3 -2
- package/dist/setup/agent-writer.d.ts +3 -2
- package/dist/setup/approval-migration.d.ts +2 -1
- package/dist/setup/approval-migration.js +1 -1
- package/dist/setup/auto-approve.d.ts +11 -19
- package/dist/setup/auto-approve.js +15 -12
- package/dist/{init → setup}/confirm.js +1 -1
- package/dist/setup/desktop-shape.d.ts +3 -2
- package/dist/setup/dev-server-wait.d.ts +8 -0
- package/dist/setup/dev-server-wait.js +3 -1
- package/dist/setup/drive-agent.d.ts +2 -3
- package/dist/setup/drive-agent.js +1 -1
- package/dist/setup/drive-plan.d.ts +3 -2
- package/dist/setup/ensure-daemon.d.ts +2 -1
- package/dist/setup/existing-app.d.ts +12 -0
- package/dist/setup/existing-app.js +13 -0
- package/dist/setup/init-host.d.ts +11 -0
- package/dist/setup/init-host.js +26 -0
- package/dist/setup/init-runtime.d.ts +4 -10
- package/dist/setup/init-runtime.js +23 -16
- package/dist/setup/license-key.d.ts +2 -1
- package/dist/setup/listeners.d.ts +2 -1
- package/dist/setup/loopback-probe-urls.d.ts +18 -0
- package/dist/setup/loopback-probe-urls.js +52 -0
- package/dist/setup/node-effects.d.ts +3 -0
- package/dist/setup/node-effects.js +26 -11
- package/dist/setup/page-probe.d.ts +5 -0
- package/dist/setup/relaunch.d.ts +2 -1
- package/dist/setup/run-setup.d.ts +5 -1
- package/dist/setup/run-setup.js +155 -48
- package/dist/setup/setup-command.d.ts +3 -2
- package/dist/setup/setup-command.js +8 -0
- package/dist/setup/setup-options.d.ts +5 -3
- package/dist/setup/setup-options.js +3 -2
- package/dist/setup/wait-progress.d.ts +28 -0
- package/dist/setup/wait-progress.js +43 -0
- package/dist/telemetry/app-instrumented.d.ts +2 -1
- package/dist/telemetry/app-instrumented.js +1 -1
- package/dist/telemetry/automation-hint.d.ts +1 -1
- package/dist/telemetry/automation-hint.js +1 -1
- package/dist/telemetry/cli-telemetry.js +1 -1
- package/dist/telemetry/connect-failure.d.ts +1 -1
- package/dist/telemetry/connect-failure.js +1 -1
- package/dist/telemetry/crash-cause.d.ts +3 -2
- package/dist/telemetry/crash-cause.js +1 -1
- package/dist/telemetry/daemon-telemetry.d.ts +3 -2
- package/dist/telemetry/daemon-telemetry.js +1 -1
- package/dist/telemetry/error-class.d.ts +3 -2
- package/dist/telemetry/error-class.js +1 -1
- package/dist/telemetry/feedback-cli.js +1 -1
- package/dist/telemetry/feedback-context.d.ts +3 -2
- package/dist/telemetry/feedback-context.js +5 -4
- package/dist/telemetry/feedback-local.d.ts +3 -2
- package/dist/telemetry/feedback.d.ts +4 -3
- package/dist/telemetry/feedback.js +1 -1
- package/dist/telemetry/git-facts.d.ts +2 -2
- package/dist/telemetry/git-facts.js +1 -1
- package/dist/telemetry/identify.d.ts +1 -1
- package/dist/telemetry/identify.js +1 -1
- package/dist/telemetry/init-telemetry.d.ts +2 -14
- package/dist/telemetry/init-telemetry.js +4 -13
- package/dist/telemetry/install-source.d.ts +7 -13
- package/dist/telemetry/install-source.js +7 -29
- package/dist/telemetry/license-activation.d.ts +3 -2
- package/dist/telemetry/license-activation.js +1 -1
- package/dist/telemetry/machine-snapshot.d.ts +1 -1
- package/dist/telemetry/mcp-connection.js +1 -1
- package/dist/telemetry/project-profile.d.ts +0 -14
- package/dist/telemetry/project-profile.js +1 -1
- package/dist/telemetry/proxy-telemetry.js +1 -1
- package/dist/telemetry/session-metrics.d.ts +1 -1
- package/dist/telemetry/session-metrics.js +1 -1
- package/dist/telemetry/telemetry.d.ts +1 -17
- package/dist/telemetry/telemetry.js +4 -4
- package/dist/telemetry/tool-refused.d.ts +1 -1
- package/dist/telemetry/tool-refused.js +1 -1
- package/dist/tools/act-observation.d.ts +3 -2
- package/dist/tools/act-preflight.js +8 -3
- package/dist/tools/act-target.d.ts +4 -0
- package/dist/tools/act-target.js +14 -5
- package/dist/tools/act-tools.d.ts +0 -2
- package/dist/tools/act-tools.js +45 -15
- package/dist/tools/assert-source.d.ts +30 -0
- package/dist/tools/assert-source.js +21 -0
- package/dist/tools/assert-verdict.d.ts +1 -1
- package/dist/tools/assert-verdict.js +14 -4
- package/dist/tools/browser-tools.js +28 -8
- package/dist/tools/complete-snapshot.d.ts +3 -2
- package/dist/tools/dynamic-tools.js +8 -0
- package/dist/tools/error-recovery.d.ts +10 -0
- package/dist/tools/error-recovery.js +23 -0
- package/dist/tools/feedback-tools.js +1 -1
- package/dist/tools/invoke-tool.js +2 -0
- package/dist/tools/lease-tools.d.ts +48 -20
- package/dist/tools/lease-tools.js +311 -76
- package/dist/tools/lineage-tools.d.ts +14 -0
- package/dist/tools/lineage-tools.js +64 -0
- package/dist/tools/merge-tools.js +1 -3
- package/dist/tools/navigate-arrival.d.ts +45 -1
- package/dist/tools/navigate-arrival.js +39 -6
- package/dist/tools/navigate-result.d.ts +8 -1
- package/dist/tools/navigate-result.js +14 -4
- package/dist/tools/numeric-bounds.d.ts +0 -11
- package/dist/tools/numeric-bounds.js +4 -4
- package/dist/tools/observe-tools.js +22 -26
- package/dist/tools/observed-nothing.d.ts +9 -0
- package/dist/tools/observed-nothing.js +2 -1
- package/dist/tools/read-tools.js +12 -17
- package/dist/tools/real-input-attempt.d.ts +14 -6
- package/dist/tools/real-input-attempt.js +75 -18
- package/dist/tools/reconcile-tools.js +2 -1
- package/dist/tools/reload-result.d.ts +6 -1
- package/dist/tools/reload-result.js +7 -2
- package/dist/tools/resolve-target.d.ts +7 -1
- package/dist/tools/resolve-target.js +72 -9
- package/dist/tools/settle-in-flight.d.ts +1 -1
- package/dist/tools/settle-in-flight.js +9 -2
- package/dist/tools/snapshot-delta.d.ts +24 -1
- package/dist/tools/snapshot-delta.js +66 -7
- package/dist/tools/tool-names.d.ts +1 -0
- package/dist/tools/tool-names.js +1 -0
- package/dist/tools/tool-surface.js +20 -2
- package/dist/tools/tools.js +120 -11
- package/dist/tools/verify-next-baton.d.ts +2 -1
- package/dist/update/sdk-sync.d.ts +1 -1
- package/dist/update/sdk-sync.js +1 -1
- package/dist/update/updater.js +1 -1
- package/dist/version/sdk-fix.d.ts +2 -1
- package/dist/version/version-skew.d.ts +0 -8
- package/dist/version/version-skew.js +1 -1
- package/docs/README.md +8 -6
- package/docs/actions.mdx +1 -1
- package/docs/agent-cheatsheet.md +4 -2
- package/docs/architecture.md +1 -1
- package/docs/cli/mcp.mdx +3 -1
- package/docs/cli/watch.mdx +1 -1
- package/docs/cli.mdx +1 -1
- package/docs/desktop.mdx +1 -1
- package/docs/docs.json +8 -3
- package/docs/faq.mdx +9 -0
- package/docs/first-drive.md +136 -0
- package/docs/frameworks.mdx +29 -7
- package/docs/gate-plan.md +2 -2
- package/docs/gates.md +19 -11
- package/docs/getting-started.md +7 -1
- package/docs/http-transport.md +164 -0
- package/docs/index.mdx +5 -3
- package/docs/install-manual.mdx +1 -1
- package/docs/packages/tauri.mdx +1 -1
- package/docs/packages.mdx +15 -3
- package/docs/platform-integration.md +1 -1
- package/docs/predicates.mdx +2 -0
- package/docs/system-map.md +2 -2
- package/docs/telemetry-contract.md +4 -4
- package/docs/telemetry-events.mdx +1 -1
- package/docs/telemetry.md +3 -3
- package/docs/tools-navigate.mdx +14 -6
- package/docs/usage.md +4 -4
- package/package.json +7 -4
- package/dist/init/agent-rules.d.ts +0 -116
- package/dist/init/agent-rules.js +0 -279
- package/dist/init/app-choice.d.ts +0 -20
- package/dist/init/app-choice.js +0 -25
- package/dist/init/astro-host.d.ts +0 -21
- package/dist/init/astro-host.js +0 -27
- package/dist/init/astro-patch.d.ts +0 -33
- package/dist/init/astro-patch.js +0 -300
- package/dist/init/capabilities.d.ts +0 -40
- package/dist/init/capabilities.js +0 -150
- package/dist/init/closing-hint.d.ts +0 -36
- package/dist/init/closing-hint.js +0 -120
- package/dist/init/connect-steps.d.ts +0 -2
- package/dist/init/connect-steps.js +0 -50
- package/dist/init/cra.d.ts +0 -79
- package/dist/init/cra.js +0 -178
- package/dist/init/csp-check.d.ts +0 -38
- package/dist/init/csp-check.js +0 -107
- package/dist/init/csp-doctor.d.ts +0 -32
- package/dist/init/csp-doctor.js +0 -54
- package/dist/init/desktop-doctor.d.ts +0 -41
- package/dist/init/desktop-doctor.js +0 -198
- package/dist/init/detect.d.ts +0 -96
- package/dist/init/detect.js +0 -209
- package/dist/init/dev-script.d.ts +0 -50
- package/dist/init/dev-script.js +0 -66
- package/dist/init/format-generated.d.ts +0 -18
- package/dist/init/format-generated.js +0 -39
- package/dist/init/install-hint.d.ts +0 -9
- package/dist/init/install-hint.js +0 -29
- package/dist/init/mcp-clients.d.ts +0 -89
- package/dist/init/mcp-clients.js +0 -299
- package/dist/init/mcp-registered.d.ts +0 -12
- package/dist/init/mcp-registered.js +0 -14
- package/dist/init/mcp.d.ts +0 -89
- package/dist/init/mcp.js +0 -129
- package/dist/init/next-patch.d.ts +0 -39
- package/dist/init/next-patch.js +0 -196
- package/dist/init/node-io.d.ts +0 -7
- package/dist/init/node-io.js +0 -117
- package/dist/init/non-js-project.d.ts +0 -27
- package/dist/init/non-js-project.js +0 -84
- package/dist/init/patch-kind.d.ts +0 -20
- package/dist/init/patch-kind.js +0 -10
- package/dist/init/plan-framework.d.ts +0 -64
- package/dist/init/plan-framework.js +0 -565
- package/dist/init/plan.d.ts +0 -242
- package/dist/init/plan.js +0 -703
- package/dist/init/preflight.d.ts +0 -28
- package/dist/init/preflight.js +0 -38
- package/dist/init/project-id.d.ts +0 -12
- package/dist/init/project-id.js +0 -25
- package/dist/init/refresh-rules.d.ts +0 -39
- package/dist/init/refresh-rules.js +0 -51
- package/dist/init/run.d.ts +0 -117
- package/dist/init/run.js +0 -806
- package/dist/init/slash-command.d.ts +0 -27
- package/dist/init/slash-command.js +0 -132
- package/dist/init/snippets.d.ts +0 -134
- package/dist/init/snippets.js +0 -572
- package/dist/init/vite-config.d.ts +0 -18
- package/dist/init/vite-config.js +0 -114
- package/dist/init/windows-quote.d.ts +0 -38
- package/dist/init/windows-quote.js +0 -70
- package/dist/init/workspace-apps.d.ts +0 -30
- package/dist/init/workspace-apps.js +0 -178
- package/dist/project/remember-project.d.ts +0 -24
- package/dist/project/remember-project.js +0 -40
- /package/dist/{init → setup}/confirm.d.ts +0 -0
package/dist/init/mcp.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Global (user-scope) MCP registration for `reticle init`. The bridge + MCP server is a single
|
|
3
|
-
* process that serves every project, so it is registered ONCE at user scope — not per-project via
|
|
4
|
-
* a checked-in `.mcp.json`. We shell out to the official `claude mcp add -s user` CLI rather than
|
|
5
|
-
* hand-editing `~/.claude.json` (a large stateful file). When the `claude` CLI is absent we print a
|
|
6
|
-
* manual instruction instead.
|
|
7
|
-
*
|
|
8
|
-
* The registration is intentionally PORTLESS — `npx @reticlehq/server mcp`, never `--port N`. A single
|
|
9
|
-
* global entry serves every project, so baking a port into it would pin every project to one port
|
|
10
|
-
* and defeat per-project isolation. Instead `reticle mcp` resolves the port at runtime from the
|
|
11
|
-
* project's `.reticle.json` in its CWD (see cli-port.ts). The port belongs to the project, not the
|
|
12
|
-
* global agent config.
|
|
13
|
-
*/
|
|
14
|
-
import { RETICLE_NPM_PACKAGE } from '../version/server-version.js';
|
|
15
|
-
// The name is a wire identity and lives in the contract; re-exported here so the registration writers
|
|
16
|
-
// below (and their tests) keep reading it from the module that USES it.
|
|
17
|
-
export { MCP_SERVER_NAME } from '@reticlehq/core';
|
|
18
|
-
import { MCP_SERVER_NAME } from '@reticlehq/core';
|
|
19
|
-
/**
|
|
20
|
-
* The registered command is STILL bare `npx` on every platform, deliberately.
|
|
21
|
-
*
|
|
22
|
-
* Windows is most of Reticle's users and, when this was written, had no CI. There is Windows CI
|
|
23
|
-
* now, so the `cmd /c` fallback is testable. Defaulting the majority platform to that launch
|
|
24
|
-
* command is still the riskier change: `.cmd` has spawn caveats in some hosts, and a registration
|
|
25
|
-
* that works on the machines we can test can still fail in the hosts we cannot. So the fallback
|
|
26
|
-
* stays documented rather than defaulted.
|
|
27
|
-
*
|
|
28
|
-
* What DID change is when it is printed. `mcpManual` used to run only when the `claude` CLI was
|
|
29
|
-
* absent. The reported Windows install had `claude mcp add` succeed, so the one paragraph that
|
|
30
|
-
* would have unblocked zero tools never appeared. `mcpWindowsNote` is that paragraph, and init
|
|
31
|
-
* prints it on every Windows run — including the ones that look like a clean registration.
|
|
32
|
-
*/
|
|
33
|
-
export const NPX = 'npx';
|
|
34
|
-
// The `reticle` bin lives in the server package, so `npx <pkg> mcp` runs the bridge without the
|
|
35
|
-
// retired `core` umbrella. Sourced from the single derived identity so it can never drift.
|
|
36
|
-
const RETICLE_PACKAGE = RETICLE_NPM_PACKAGE;
|
|
37
|
-
const MCP_SUBCOMMAND = 'mcp';
|
|
38
|
-
const CLAUDE_CLI = 'claude';
|
|
39
|
-
/** Windows `cmd /c` — the spawn that PowerShell's execution policy does not gate. */
|
|
40
|
-
const WINDOWS_SHELL = 'cmd';
|
|
41
|
-
const WINDOWS_SHELL_C = '/c';
|
|
42
|
-
/**
|
|
43
|
-
* Args after `npx` that launch the bridge: `@reticlehq/server mcp`. Portless — the port comes from
|
|
44
|
-
* the project's `.reticle.json` at runtime, so one global entry works for every project.
|
|
45
|
-
*
|
|
46
|
-
* DELIBERATELY UNPINNED, and the trade is worth stating. `reticle init` pins the SDK to the CLI's
|
|
47
|
-
* exact version, so on release day the app can be on the new one while npx serves a cached older
|
|
48
|
-
* build — a real skew, reported from the field. Pinning this entry would remove that window.
|
|
49
|
-
*
|
|
50
|
-
* It would also freeze the agent's MCP server at whatever version was installed the day `init` ran,
|
|
51
|
-
* for as long as that entry survives — and `reticle update` upgrades the CLI, not a global agent
|
|
52
|
-
* config. Reticle's biggest measured problem is fixes not reaching people (2.4.0 reached zero users
|
|
53
|
-
* before its nudge existed), and a permanent pin makes that worse for every install, to close a
|
|
54
|
-
* window that lasts until the next npx cache miss.
|
|
55
|
-
*
|
|
56
|
-
* So it stays unpinned, and the skew is handled where it actually shows up: the contract fingerprint
|
|
57
|
-
* makes a real mismatch loud on the next tool result (see version-skew), and a stale entry of our own
|
|
58
|
-
* shape is now repaired on re-run rather than reported "already registered" (see mcp-clients.ts).
|
|
59
|
-
*/
|
|
60
|
-
export function npxServerArgs() {
|
|
61
|
-
return [RETICLE_PACKAGE, MCP_SUBCOMMAND];
|
|
62
|
-
}
|
|
63
|
-
/** The npm scope every Reticle package shares — the marker of a registration we are entitled to fix. */
|
|
64
|
-
const RETICLE_SCOPE = '@reticlehq/';
|
|
65
|
-
/**
|
|
66
|
-
* Is this existing registration one WE are responsible for?
|
|
67
|
-
*
|
|
68
|
-
* Deliberately the SCOPE and not the server package. An entry naming any `@reticlehq/*` package is
|
|
69
|
-
* ours to repair — including one naming the WRONG package, which is the case this widened for:
|
|
70
|
-
* `args: ["@reticlehq/core","mcp"]` was reported from the field, where `core` has no `mcp` bin, so
|
|
71
|
-
* the client showed the server errored with zero tools while `init` reported it already wired and
|
|
72
|
-
* left it alone on every re-run. Every `reticle_*` tool was blocked until a human edited that file.
|
|
73
|
-
*
|
|
74
|
-
* An entry that names no Reticle package at all — a local build, a wrapper script — is still someone
|
|
75
|
-
* else's deliberate choice and is left exactly as it is.
|
|
76
|
-
*
|
|
77
|
-
* @param tokens every string in the entry's command + args, in any of the client shapes.
|
|
78
|
-
*/
|
|
79
|
-
export function isReticleRegistration(tokens) {
|
|
80
|
-
return tokens.includes(NPX) && tokens.some((t) => t.includes(RETICLE_SCOPE));
|
|
81
|
-
}
|
|
82
|
-
/** The full `npx …` invocation — the tail after `claude mcp add … --`. */
|
|
83
|
-
function serverInvocation() {
|
|
84
|
-
return [NPX, ...npxServerArgs()];
|
|
85
|
-
}
|
|
86
|
-
/** `claude mcp add reticle -s user -- npx @reticlehq/server mcp` — registers globally for all projects (portless). */
|
|
87
|
-
export function claudeAddCommand() {
|
|
88
|
-
const tail = serverInvocation();
|
|
89
|
-
const args = [MCP_SUBCOMMAND, 'add', MCP_SERVER_NAME, '-s', 'user', '--', ...tail];
|
|
90
|
-
return { command: CLAUDE_CLI, args, display: `${CLAUDE_CLI} ${args.join(' ')}` };
|
|
91
|
-
}
|
|
92
|
-
/** Probe args that tell us whether an `reticle` server already exists in any scope (exit 0 = exists). */
|
|
93
|
-
export function claudeExistsProbe() {
|
|
94
|
-
// NO `-s`: `claude mcp get` takes no options at all, so passing one exits 1 with "unknown option
|
|
95
|
-
// '-s'" — the probe answered "not registered" on EVERY machine, init then ran `claude mcp add`,
|
|
96
|
-
// which exits 1 with "already exists", and a re-run reported `[⚠] step failed` plus a manual
|
|
97
|
-
// command that fails the same way. A false positive from a project-scoped entry costs one skipped
|
|
98
|
-
// registration; the flag cost every re-run a failed step.
|
|
99
|
-
return { command: CLAUDE_CLI, args: [MCP_SUBCOMMAND, 'get', MCP_SERVER_NAME] };
|
|
100
|
-
}
|
|
101
|
-
/** Probe args for whether the `claude` CLI is installed at all. */
|
|
102
|
-
export function claudeAvailableProbe() {
|
|
103
|
-
return { command: CLAUDE_CLI, args: ['--version'] };
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* The Windows `cmd /c npx` registration. Printed on every Windows init, not only when the `claude`
|
|
107
|
-
* CLI is missing — a successful `claude mcp add` of bare `npx` is exactly the failure that reported
|
|
108
|
-
* as a clean install with zero tools.
|
|
109
|
-
*/
|
|
110
|
-
export function mcpWindowsNote() {
|
|
111
|
-
return `On Windows, if the agent cannot start Reticle because npx is blocked ("running scripts is disabled
|
|
112
|
-
on this system" — a PowerShell execution policy), register it through cmd instead, which that policy
|
|
113
|
-
does not gate:
|
|
114
|
-
|
|
115
|
-
"${MCP_SERVER_NAME}": { "command": "${WINDOWS_SHELL}", "args": ${JSON.stringify([WINDOWS_SHELL_C, NPX, ...serverInvocation().slice(1)])} }`;
|
|
116
|
-
}
|
|
117
|
-
/** Printed when the `claude` CLI isn't available — register Reticle globally once, by hand. */
|
|
118
|
-
export function mcpManual() {
|
|
119
|
-
const tail = serverInvocation().join(' ');
|
|
120
|
-
return `Register the Reticle MCP server ONCE, globally (so every project gets it):
|
|
121
|
-
|
|
122
|
-
${CLAUDE_CLI} ${MCP_SUBCOMMAND} add ${MCP_SERVER_NAME} -s user -- ${tail}
|
|
123
|
-
|
|
124
|
-
Or, for another agent, add this to its global MCP config (e.g. Cursor's ~/.cursor/mcp.json):
|
|
125
|
-
|
|
126
|
-
"${MCP_SERVER_NAME}": { "command": "${NPX}", "args": ${JSON.stringify(serverInvocation().slice(1))} }
|
|
127
|
-
|
|
128
|
-
${mcpWindowsNote()}`;
|
|
129
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure, conservative patchers for the two files a Next app needed edited BY HAND: `next.config.*`
|
|
3
|
-
* (wrap the export in `withReticle`) and `app/layout.tsx` (mount `<ReticleDev />`). Same contract as
|
|
4
|
-
* the Vite patcher — recognise the obvious shape, bail to `manual` on anything ambiguous, never
|
|
5
|
-
* half-edit. Leaving these manual is why Next connected 0% of the time: both edits are silent when
|
|
6
|
-
* skipped, and one of them is JSX.
|
|
7
|
-
*/
|
|
8
|
-
import { type SourcePatch } from './patch-kind.js';
|
|
9
|
-
/** Where the generated connect component goes, and how the mount file should import it. */
|
|
10
|
-
interface ReticleDevLocation {
|
|
11
|
-
/** Project-relative path to write. */
|
|
12
|
-
path: string;
|
|
13
|
-
/** What the mount file (`app/layout.*` or `pages/_app.*`) should import. */
|
|
14
|
-
importSpecifier: string;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Decide where the connect component lives, from the file that will mount it.
|
|
18
|
-
*
|
|
19
|
-
* Two things this gets wrong if hardcoded, both of which broke real apps:
|
|
20
|
-
*
|
|
21
|
-
* - **Pages Router routes on presence.** EVERY file under `pages/` is a route, so a component
|
|
22
|
-
* dropped there has no default export: `/reticle-dev` 500s and `next build` fails. It has to go
|
|
23
|
-
* somewhere that is not a route directory. App Router routes on FILENAME (`page`/`layout`/
|
|
24
|
-
* `route`), so an extra file beside the layout is inert and can stay there.
|
|
25
|
-
* - **The extension is not cosmetic.** A `.tsx` file in a JavaScript project makes Next auto-install
|
|
26
|
-
* TypeScript on the next `next dev` — and on Next 13 that takes its require-hook down with it, so
|
|
27
|
-
* the dev server never starts. The install then looks like it broke the app, because it did.
|
|
28
|
-
*/
|
|
29
|
-
export declare function reticleDevLocation(mountPath: string, typescript: boolean): ReticleDevLocation;
|
|
30
|
-
export declare function patchNextConfig(source: string): SourcePatch;
|
|
31
|
-
/**
|
|
32
|
-
* Pages Router has no root layout to mount into — `app/layout.tsx` does not exist — so the connect
|
|
33
|
-
* rides in `pages/_app` instead, wrapped in a fragment alongside the page. Without this, `init`
|
|
34
|
-
* wrote `app/reticle-dev.tsx` into a directory the app does not have and nothing ever connected,
|
|
35
|
-
* with no error to say so.
|
|
36
|
-
*/
|
|
37
|
-
export declare function patchPagesApp(source: string, importSpecifier?: string): SourcePatch;
|
|
38
|
-
export declare function patchRootLayout(source: string): SourcePatch;
|
|
39
|
-
export {};
|
package/dist/init/next-patch.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure, conservative patchers for the two files a Next app needed edited BY HAND: `next.config.*`
|
|
3
|
-
* (wrap the export in `withReticle`) and `app/layout.tsx` (mount `<ReticleDev />`). Same contract as
|
|
4
|
-
* the Vite patcher — recognise the obvious shape, bail to `manual` on anything ambiguous, never
|
|
5
|
-
* half-edit. Leaving these manual is why Next connected 0% of the time: both edits are silent when
|
|
6
|
-
* skipped, and one of them is JSX.
|
|
7
|
-
*/
|
|
8
|
-
import { PatchKind } from './patch-kind.js';
|
|
9
|
-
const RETICLE_NEXT_PACKAGE = '@reticlehq/next';
|
|
10
|
-
const NEXT_CONFIG_IMPORT = `import { withReticle } from '${RETICLE_NEXT_PACKAGE}';`;
|
|
11
|
-
const NEXT_CONFIG_REQUIRE = `const { withReticle } = require('${RETICLE_NEXT_PACKAGE}');`;
|
|
12
|
-
const RETICLE_DEV_COMPONENT = 'ReticleDev';
|
|
13
|
-
const RETICLE_DEV_BASENAME = 'reticle-dev';
|
|
14
|
-
/** Default import specifier: the component sits beside the file importing it (App Router). */
|
|
15
|
-
const RETICLE_DEV_SIBLING = `./${RETICLE_DEV_BASENAME}`;
|
|
16
|
-
const reticleDevImport = (specifier) => `import { ${RETICLE_DEV_COMPONENT} } from '${specifier}';`;
|
|
17
|
-
const RETICLE_DEV_IMPORT = reticleDevImport(RETICLE_DEV_SIBLING);
|
|
18
|
-
/**
|
|
19
|
-
* Decide where the connect component lives, from the file that will mount it.
|
|
20
|
-
*
|
|
21
|
-
* Two things this gets wrong if hardcoded, both of which broke real apps:
|
|
22
|
-
*
|
|
23
|
-
* - **Pages Router routes on presence.** EVERY file under `pages/` is a route, so a component
|
|
24
|
-
* dropped there has no default export: `/reticle-dev` 500s and `next build` fails. It has to go
|
|
25
|
-
* somewhere that is not a route directory. App Router routes on FILENAME (`page`/`layout`/
|
|
26
|
-
* `route`), so an extra file beside the layout is inert and can stay there.
|
|
27
|
-
* - **The extension is not cosmetic.** A `.tsx` file in a JavaScript project makes Next auto-install
|
|
28
|
-
* TypeScript on the next `next dev` — and on Next 13 that takes its require-hook down with it, so
|
|
29
|
-
* the dev server never starts. The install then looks like it broke the app, because it did.
|
|
30
|
-
*/
|
|
31
|
-
export function reticleDevLocation(mountPath, typescript) {
|
|
32
|
-
const ext = typescript ? '.tsx' : '.jsx';
|
|
33
|
-
const slash = mountPath.lastIndexOf('/');
|
|
34
|
-
const dir = -1 === slash ? '' : mountPath.slice(0, slash);
|
|
35
|
-
const isPagesRouter = /(^|\/)pages$/.test(dir);
|
|
36
|
-
if (!isPagesRouter) {
|
|
37
|
-
return {
|
|
38
|
-
path: `${'' === dir ? '' : `${dir}/`}${RETICLE_DEV_BASENAME}${ext}`,
|
|
39
|
-
importSpecifier: RETICLE_DEV_SIBLING,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
// Siblings of `pages/`, so `src/pages/_app.js` → `src/components/…` and `pages/_app.js` → `components/…`.
|
|
43
|
-
const parent = dir.slice(0, Math.max(0, dir.length - 'pages'.length));
|
|
44
|
-
return {
|
|
45
|
-
path: `${parent}components/${RETICLE_DEV_BASENAME}${ext}`,
|
|
46
|
-
importSpecifier: `../components/${RETICLE_DEV_BASENAME}`,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/** The dev-guarded mount. Production strips it — `process.env.NODE_ENV` is inlined at build time. */
|
|
50
|
-
const RETICLE_DEV_MOUNT = `{process.env.NODE_ENV === 'development' ? <${RETICLE_DEV_COMPONENT} /> : null}`;
|
|
51
|
-
/**
|
|
52
|
-
* `export default ` / `module.exports = ` at the START of a line — the head of the assignment, not
|
|
53
|
-
* the whole statement. Where the exported expression ENDS is decided by `expressionEnd` below.
|
|
54
|
-
*
|
|
55
|
-
* These used to be `/…([\s\S]+?);?\s*$/`, which reads as "the expression, lazily". It is not: with
|
|
56
|
-
* no `m` flag the `$` is end-of-FILE and the trailing `;?\s*` is satisfiable only there, so the
|
|
57
|
-
* capture always ran to the last non-blank character of the file. Every config whose export was not
|
|
58
|
-
* the final statement got everything after it swallowed into the wrap. On a config exporting
|
|
59
|
-
* conditionally that produced an unbalanced paren — a syntax error, so `next dev` exited 1 while
|
|
60
|
-
* `init` reported the step as ✓ and the only symptom was "dev server never served".
|
|
61
|
-
*/
|
|
62
|
-
const ESM_DEFAULT_HEAD = /^[ \t]*export[ \t]+default[ \t]+/gm;
|
|
63
|
-
const CJS_EXPORT_HEAD = /^[ \t]*module\.exports[ \t]*=[ \t]*/gm;
|
|
64
|
-
/** The opening `<body ...>` tag, whose first child is where the mount goes. */
|
|
65
|
-
const BODY_OPEN_TAG = /<body(\s[^>]*)?>/g;
|
|
66
|
-
const NO_EXPORT_REASON = "couldn't find an `export default` or `module.exports` to wrap";
|
|
67
|
-
const NO_BODY_REASON = "couldn't find a single <body> tag to mount <ReticleDev /> inside";
|
|
68
|
-
/** Bracket pairs that keep an expression open. A `;` at depth 0 is what ends it. */
|
|
69
|
-
const OPENERS = '([{';
|
|
70
|
-
const CLOSERS = ')]}';
|
|
71
|
-
const LINE_COMMENT = '//';
|
|
72
|
-
const BLOCK_COMMENT_OPEN = '/*';
|
|
73
|
-
const BLOCK_COMMENT_CLOSE = '*/';
|
|
74
|
-
const QUOTES = '\'"`';
|
|
75
|
-
/**
|
|
76
|
-
* Index just past the exported expression that starts at `from` — the `;` that closes it, or end of
|
|
77
|
-
* file. Tracks bracket depth so a multi-line object or a nested call ends in the right place, and
|
|
78
|
-
* skips strings and comments so a `;` or a brace inside one cannot end it early.
|
|
79
|
-
*
|
|
80
|
-
* Deliberately a scanner and not a parser: `next.config.*` is arbitrary JS and this file's contract
|
|
81
|
-
* is to recognise the obvious shape or bail. It only has to be right about where ONE expression
|
|
82
|
-
* stops, and wrong is caught by the caller bailing to manual, never by a half-edit.
|
|
83
|
-
*/
|
|
84
|
-
function expressionEnd(source, from) {
|
|
85
|
-
let depth = 0;
|
|
86
|
-
for (let i = from; i < source.length; i++) {
|
|
87
|
-
const ch = source[i] ?? '';
|
|
88
|
-
const pair = source.slice(i, i + 2);
|
|
89
|
-
if (pair === LINE_COMMENT) {
|
|
90
|
-
const nl = source.indexOf('\n', i);
|
|
91
|
-
if (-1 === nl)
|
|
92
|
-
return source.length;
|
|
93
|
-
i = nl;
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
if (pair === BLOCK_COMMENT_OPEN) {
|
|
97
|
-
const close = source.indexOf(BLOCK_COMMENT_CLOSE, i + 2);
|
|
98
|
-
i = -1 === close ? source.length : close + 1;
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
if (QUOTES.includes(ch)) {
|
|
102
|
-
for (i++; i < source.length; i++) {
|
|
103
|
-
if ('\\' === source[i])
|
|
104
|
-
i++;
|
|
105
|
-
else if (source[i] === ch)
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (OPENERS.includes(ch))
|
|
111
|
-
depth++;
|
|
112
|
-
else if (CLOSERS.includes(ch)) {
|
|
113
|
-
// A closer at depth 0 belongs to an enclosing block, so the expression ended before it.
|
|
114
|
-
if (0 === depth)
|
|
115
|
-
return i;
|
|
116
|
-
depth--;
|
|
117
|
-
}
|
|
118
|
-
else if (';' === ch && 0 === depth)
|
|
119
|
-
return i;
|
|
120
|
-
}
|
|
121
|
-
return source.length;
|
|
122
|
-
}
|
|
123
|
-
/** Every top-level export assignment in the file, in source order. */
|
|
124
|
-
function exportSites(source, head) {
|
|
125
|
-
const sites = [];
|
|
126
|
-
for (const match of source.matchAll(head)) {
|
|
127
|
-
if (match.index === undefined)
|
|
128
|
-
continue;
|
|
129
|
-
const start = match.index + match[0].length;
|
|
130
|
-
sites.push({ start, end: expressionEnd(source, start) });
|
|
131
|
-
}
|
|
132
|
-
return sites;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Wrap every listed expression in `withReticle(...)`, leaving every other byte of the file alone.
|
|
136
|
-
*
|
|
137
|
-
* All of them, not just the first: a config can export CONDITIONALLY — Sentry-wrapped in one branch,
|
|
138
|
-
* plain in the other — and which branch runs is an environment variable's business, not ours.
|
|
139
|
-
* Wrapping each assignment is correct whichever one executes, and it is what turns that shape from a
|
|
140
|
-
* manual step (an app that boots and never connects) into a working install.
|
|
141
|
-
*
|
|
142
|
-
* Applied back-to-front so each splice leaves the earlier offsets valid.
|
|
143
|
-
*/
|
|
144
|
-
function wrapAll(source, sites) {
|
|
145
|
-
let out = source;
|
|
146
|
-
for (const site of [...sites].sort((a, b) => b.start - a.start)) {
|
|
147
|
-
out = `${out.slice(0, site.start)}withReticle(${out.slice(site.start, site.end)})${out.slice(site.end)}`;
|
|
148
|
-
}
|
|
149
|
-
return out;
|
|
150
|
-
}
|
|
151
|
-
export function patchNextConfig(source) {
|
|
152
|
-
if (source.includes(RETICLE_NEXT_PACKAGE))
|
|
153
|
-
return { kind: PatchKind.ALREADY };
|
|
154
|
-
const esm = exportSites(source, ESM_DEFAULT_HEAD);
|
|
155
|
-
if (esm.length > 0) {
|
|
156
|
-
return { kind: PatchKind.APPLY, code: `${NEXT_CONFIG_IMPORT}\n${wrapAll(source, esm)}` };
|
|
157
|
-
}
|
|
158
|
-
const cjs = exportSites(source, CJS_EXPORT_HEAD);
|
|
159
|
-
if (cjs.length > 0) {
|
|
160
|
-
return { kind: PatchKind.APPLY, code: `${NEXT_CONFIG_REQUIRE}\n${wrapAll(source, cjs)}` };
|
|
161
|
-
}
|
|
162
|
-
return { kind: PatchKind.MANUAL, reason: NO_EXPORT_REASON };
|
|
163
|
-
}
|
|
164
|
-
/** `<Component {...pageProps} />` — the one element every `pages/_app` renders. */
|
|
165
|
-
const PAGES_APP_COMPONENT = /<Component\b[^>]*\/>/g;
|
|
166
|
-
const NO_PAGES_COMPONENT_REASON = "couldn't find a single <Component {...pageProps} /> to wrap in pages/_app";
|
|
167
|
-
/**
|
|
168
|
-
* Pages Router has no root layout to mount into — `app/layout.tsx` does not exist — so the connect
|
|
169
|
-
* rides in `pages/_app` instead, wrapped in a fragment alongside the page. Without this, `init`
|
|
170
|
-
* wrote `app/reticle-dev.tsx` into a directory the app does not have and nothing ever connected,
|
|
171
|
-
* with no error to say so.
|
|
172
|
-
*/
|
|
173
|
-
export function patchPagesApp(source, importSpecifier = RETICLE_DEV_SIBLING) {
|
|
174
|
-
if (source.includes(RETICLE_DEV_COMPONENT))
|
|
175
|
-
return { kind: PatchKind.ALREADY };
|
|
176
|
-
const matches = [...source.matchAll(PAGES_APP_COMPONENT)];
|
|
177
|
-
const match = 1 === matches.length ? matches[0] : undefined;
|
|
178
|
-
if (match?.index === undefined)
|
|
179
|
-
return { kind: PatchKind.MANUAL, reason: NO_PAGES_COMPONENT_REASON };
|
|
180
|
-
const wrapped = `<>${RETICLE_DEV_MOUNT}${match[0]}</>`;
|
|
181
|
-
const code = source.slice(0, match.index) + wrapped + source.slice(match.index + match[0].length);
|
|
182
|
-
return { kind: PatchKind.APPLY, code: `${reticleDevImport(importSpecifier)}\n${code}` };
|
|
183
|
-
}
|
|
184
|
-
export function patchRootLayout(source) {
|
|
185
|
-
if (source.includes(RETICLE_DEV_COMPONENT))
|
|
186
|
-
return { kind: PatchKind.ALREADY };
|
|
187
|
-
const tags = [...source.matchAll(BODY_OPEN_TAG)];
|
|
188
|
-
// Exactly one <body> or we cannot tell which one actually renders — and mounting into the wrong
|
|
189
|
-
// one is the same silent no-connect as not mounting at all.
|
|
190
|
-
const tag = 1 === tags.length ? tags[0] : undefined;
|
|
191
|
-
if (tag?.index === undefined)
|
|
192
|
-
return { kind: PatchKind.MANUAL, reason: NO_BODY_REASON };
|
|
193
|
-
const insertAt = tag.index + tag[0].length;
|
|
194
|
-
const mounted = `${source.slice(0, insertAt)}${RETICLE_DEV_MOUNT}${source.slice(insertAt)}`;
|
|
195
|
-
return { kind: PatchKind.APPLY, code: `${RETICLE_DEV_IMPORT}\n${mounted}` };
|
|
196
|
-
}
|
package/dist/init/node-io.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The real (Node filesystem) implementation of `InitIo`. Kept separate from the pure runner so
|
|
3
|
-
* `runInit` stays testable with an in-memory IO. Prints to stdout — `init` is a one-shot CLI
|
|
4
|
-
* command, not the MCP stdio transport.
|
|
5
|
-
*/
|
|
6
|
-
import type { InitIo } from './run.js';
|
|
7
|
-
export declare function buildNodeIo(cwd: string): InitIo;
|
package/dist/init/node-io.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The real (Node filesystem) implementation of `InitIo`. Kept separate from the pure runner so
|
|
3
|
-
* `runInit` stays testable with an in-memory IO. Prints to stdout — `init` is a one-shot CLI
|
|
4
|
-
* command, not the MCP stdio transport.
|
|
5
|
-
*/
|
|
6
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, accessSync, constants, } from 'node:fs';
|
|
7
|
-
import { NodePlatform } from '../platform.js';
|
|
8
|
-
import { join, dirname, isAbsolute } from 'node:path';
|
|
9
|
-
import { homedir } from 'node:os';
|
|
10
|
-
import { spawnSync } from 'node:child_process';
|
|
11
|
-
import { windowsShellArg } from './windows-quote.js';
|
|
12
|
-
/**
|
|
13
|
-
* `shell: true` ONLY where it earns its keep.
|
|
14
|
-
*
|
|
15
|
-
* It exists so package-manager shims (`pnpm.cmd`, `npx.cmd`) resolve on Windows. On POSIX it buys
|
|
16
|
-
* nothing and costs correctness: under a shell, arguments are re-parsed, so a path containing a
|
|
17
|
-
* space — `/Users/ada/My Projects/app` — silently becomes two arguments and registration fails with
|
|
18
|
-
* no error anyone can read.
|
|
19
|
-
*/
|
|
20
|
-
function shellOpt() {
|
|
21
|
-
return NodePlatform.WINDOWS === process.platform ? { shell: true } : {};
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Under a shell, quote what the shell would otherwise split or interpret. Windows only, where
|
|
25
|
-
* `shell: true` is required (see shellOpt). The rule itself lives in windows-quote.ts as a pure
|
|
26
|
-
* function so it can be tested on every platform — keeping it inside this branch is why it was
|
|
27
|
-
* wrong for as long as it was.
|
|
28
|
-
*/
|
|
29
|
-
function shellSafe(args) {
|
|
30
|
-
if (process.platform !== NodePlatform.WINDOWS)
|
|
31
|
-
return [...args];
|
|
32
|
-
return args.map(windowsShellArg);
|
|
33
|
-
}
|
|
34
|
-
export function buildNodeIo(cwd) {
|
|
35
|
-
// Project-relative by default; absolute paths (e.g. ~/.cursor/mcp.json) pass through unchanged.
|
|
36
|
-
const abs = (rel) => (isAbsolute(rel) ? rel : join(cwd, rel));
|
|
37
|
-
return {
|
|
38
|
-
readFile(rel) {
|
|
39
|
-
const path = abs(rel);
|
|
40
|
-
if (!existsSync(path))
|
|
41
|
-
return null;
|
|
42
|
-
return readFileSync(path, 'utf8');
|
|
43
|
-
},
|
|
44
|
-
writeFile(rel, content) {
|
|
45
|
-
const path = abs(rel);
|
|
46
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
47
|
-
writeFileSync(path, content, 'utf8');
|
|
48
|
-
},
|
|
49
|
-
exists(rel) {
|
|
50
|
-
return existsSync(abs(rel));
|
|
51
|
-
},
|
|
52
|
-
homeDir() {
|
|
53
|
-
return homedir();
|
|
54
|
-
},
|
|
55
|
-
cwd() {
|
|
56
|
-
return cwd;
|
|
57
|
-
},
|
|
58
|
-
rootFiles() {
|
|
59
|
-
return readdirSync(cwd).filter((name) => {
|
|
60
|
-
try {
|
|
61
|
-
return statSync(join(cwd, name)).isFile();
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
},
|
|
68
|
-
listDirs(rel) {
|
|
69
|
-
const path = abs(rel);
|
|
70
|
-
if (!existsSync(path))
|
|
71
|
-
return [];
|
|
72
|
-
try {
|
|
73
|
-
return readdirSync(path).filter((name) => statSync(join(path, name)).isDirectory());
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
return [];
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
listFiles(rel) {
|
|
80
|
-
const path = abs(rel);
|
|
81
|
-
if (!existsSync(path))
|
|
82
|
-
return [];
|
|
83
|
-
try {
|
|
84
|
-
return readdirSync(path).filter((name) => !statSync(join(path, name)).isDirectory());
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
return [];
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
scoped(rel) {
|
|
91
|
-
return buildNodeIo(abs(rel));
|
|
92
|
-
},
|
|
93
|
-
exec(command, args) {
|
|
94
|
-
// Inherit stdio so the install's own progress is visible to the user.
|
|
95
|
-
const result = spawnSync(command, shellSafe(args), { cwd, stdio: 'inherit', ...shellOpt() });
|
|
96
|
-
return 0 === result.status;
|
|
97
|
-
},
|
|
98
|
-
/** One access check, rather than discovering it as an EACCES stack four phases later. */
|
|
99
|
-
canWrite() {
|
|
100
|
-
try {
|
|
101
|
-
accessSync(cwd, constants.W_OK);
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
probe(command, args) {
|
|
109
|
-
// Quiet yes/no check (CLI availability, existing registration). Never throws.
|
|
110
|
-
const result = spawnSync(command, shellSafe(args), { cwd, stdio: 'ignore', ...shellOpt() });
|
|
111
|
-
return 0 === result.status;
|
|
112
|
-
},
|
|
113
|
-
print(line) {
|
|
114
|
-
process.stdout.write(`${line}\n`);
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Telling a Python (or Ruby, or Go, or PHP) developer why Reticle cannot wire their app.
|
|
3
|
-
*
|
|
4
|
-
* `reticle init` answered "No package.json found here, and no app directory beneath it either",
|
|
5
|
-
* which reads as *you are in the wrong directory* — so an agent on a Streamlit app went looking for
|
|
6
|
-
* a directory that does not exist, then went looking for a standalone browser bundle to inject by
|
|
7
|
-
* hand, and only worked out the real answer several steps later.
|
|
8
|
-
*
|
|
9
|
-
* The real answer is not about directories at all: Reticle's SDK has to be imported by the app's own
|
|
10
|
-
* JS build, and a server-rendered Python app has no JS build to import it from. That is a property
|
|
11
|
-
* of the project, it is knowable from one look at the filesystem, and saying it plainly costs the
|
|
12
|
-
* reader nothing while the directory message costs them the whole investigation.
|
|
13
|
-
*
|
|
14
|
-
* Deliberately a hint, not a refusal: a Django or Rails app with a `frontend/` package.json is a
|
|
15
|
-
* perfectly ordinary Reticle install, and this only ever speaks when there is no package.json to be
|
|
16
|
-
* found anywhere.
|
|
17
|
-
*/
|
|
18
|
-
/** The ecosystem this directory looks like, or undefined when nothing says. */
|
|
19
|
-
export declare function detectNonJsEcosystem(exists: (file: string) => boolean): string | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* What `init` should say when there is no package.json.
|
|
22
|
-
*
|
|
23
|
-
* Two genuinely different situations behind one old sentence: a JS developer standing in the wrong
|
|
24
|
-
* directory, and a developer whose project is not JavaScript at all. The first needs a path; the
|
|
25
|
-
* second needs to know that no path exists and why.
|
|
26
|
-
*/
|
|
27
|
-
export declare function noPackageJsonMessage(exists: (file: string) => boolean): string;
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Telling a Python (or Ruby, or Go, or PHP) developer why Reticle cannot wire their app.
|
|
3
|
-
*
|
|
4
|
-
* `reticle init` answered "No package.json found here, and no app directory beneath it either",
|
|
5
|
-
* which reads as *you are in the wrong directory* — so an agent on a Streamlit app went looking for
|
|
6
|
-
* a directory that does not exist, then went looking for a standalone browser bundle to inject by
|
|
7
|
-
* hand, and only worked out the real answer several steps later.
|
|
8
|
-
*
|
|
9
|
-
* The real answer is not about directories at all: Reticle's SDK has to be imported by the app's own
|
|
10
|
-
* JS build, and a server-rendered Python app has no JS build to import it from. That is a property
|
|
11
|
-
* of the project, it is knowable from one look at the filesystem, and saying it plainly costs the
|
|
12
|
-
* reader nothing while the directory message costs them the whole investigation.
|
|
13
|
-
*
|
|
14
|
-
* Deliberately a hint, not a refusal: a Django or Rails app with a `frontend/` package.json is a
|
|
15
|
-
* perfectly ordinary Reticle install, and this only ever speaks when there is no package.json to be
|
|
16
|
-
* found anywhere.
|
|
17
|
-
*/
|
|
18
|
-
/** Marker files that identify an ecosystem, and what to call it. */
|
|
19
|
-
const ECOSYSTEM_MARKERS = [
|
|
20
|
-
['requirements.txt', 'Python'],
|
|
21
|
-
['pyproject.toml', 'Python'],
|
|
22
|
-
['Pipfile', 'Python'],
|
|
23
|
-
['setup.py', 'Python'],
|
|
24
|
-
['manage.py', 'Python (Django)'],
|
|
25
|
-
['Gemfile', 'Ruby'],
|
|
26
|
-
['go.mod', 'Go'],
|
|
27
|
-
['composer.json', 'PHP'],
|
|
28
|
-
['Cargo.toml', 'Rust'],
|
|
29
|
-
['pom.xml', 'Java'],
|
|
30
|
-
['build.gradle', 'Java'],
|
|
31
|
-
['mix.exs', 'Elixir'],
|
|
32
|
-
// Not like the others. Every ecosystem above can grow a JS front end that Reticle instruments
|
|
33
|
-
// perfectly well, so their message ends with a lead. Flutter web paints into a canvas, and there
|
|
34
|
-
// is no DOM behind it at any path, so the honest answer is a named refusal.
|
|
35
|
-
['pubspec.yaml', 'Flutter'],
|
|
36
|
-
];
|
|
37
|
-
/** The one ecosystem where no directory, front end or flag could ever help. */
|
|
38
|
-
const FLUTTER = 'Flutter';
|
|
39
|
-
/** The ecosystem this directory looks like, or undefined when nothing says. */
|
|
40
|
-
export function detectNonJsEcosystem(exists) {
|
|
41
|
-
for (const [marker, name] of ECOSYSTEM_MARKERS) {
|
|
42
|
-
if (exists(marker))
|
|
43
|
-
return name;
|
|
44
|
-
}
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* What `init` should say when there is no package.json.
|
|
49
|
-
*
|
|
50
|
-
* Two genuinely different situations behind one old sentence: a JS developer standing in the wrong
|
|
51
|
-
* directory, and a developer whose project is not JavaScript at all. The first needs a path; the
|
|
52
|
-
* second needs to know that no path exists and why.
|
|
53
|
-
*/
|
|
54
|
-
export function noPackageJsonMessage(exists) {
|
|
55
|
-
const ecosystem = detectNonJsEcosystem(exists);
|
|
56
|
-
if (ecosystem === undefined) {
|
|
57
|
-
return ('No package.json found here, and no app directory beneath it either. Run `reticle init` from ' +
|
|
58
|
-
"your app's directory, or from a repo root that contains it.");
|
|
59
|
-
}
|
|
60
|
-
if (ecosystem === FLUTTER) {
|
|
61
|
-
// An agent on a Flutter workspace asked us to "support Flutter, or clearly identify it as
|
|
62
|
-
// unsupported during init". The second is the truthful one, and saying it by name in one line
|
|
63
|
-
// is the difference between an agent that stops and an agent that spends an hour looking for
|
|
64
|
-
// the package.json we told it was missing.
|
|
65
|
-
return ('This is a Flutter project. Reticle cannot instrument it, and no directory or flag will ' +
|
|
66
|
-
'change that: Reticle reads the DOM of a running page, and Flutter web paints its entire UI ' +
|
|
67
|
-
'into a single canvas element with no DOM behind it. Nothing here is missing or misconfigured. ' +
|
|
68
|
-
'If this repo also contains an ordinary web app with its own package.json, run `reticle init` ' +
|
|
69
|
-
'inside that directory instead.');
|
|
70
|
-
}
|
|
71
|
-
return (`This looks like a ${ecosystem} project, and there is no package.json here or in any app ` +
|
|
72
|
-
'directory beneath it. That is not a blocker: Reticle needs its SDK loaded by the page, not ' +
|
|
73
|
-
'built by npm, and a page with no build step can load it from a URL. ' +
|
|
74
|
-
// The old message ended at "there is no directory you could run this from that would change
|
|
75
|
-
// that", which read as a refusal and was acted on as one — agents went looking for a bundler,
|
|
76
|
-
// or for a standalone build to inject by hand, or gave up and used a different tool. The
|
|
77
|
-
// capability was there the whole time; only the sentence was missing. Proven end to end on a
|
|
78
|
-
// page served by `python3 -m http.server` before this line was written.
|
|
79
|
-
'Add the script-tag snippet below to a template you only serve in development, then reload the ' +
|
|
80
|
-
'page. ' +
|
|
81
|
-
'If this project ALSO has a JS front end (a `frontend/`, `client/` or `assets/` directory with ' +
|
|
82
|
-
'its own package.json), running `reticle init` there instead gives you source mapping and ' +
|
|
83
|
-
'framework state as well: point at it with `--app <dir>`.');
|
|
84
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The outcome vocabulary shared by every conservative source patcher in `init` (Vite config, Next
|
|
3
|
-
* config, Next root layout). One enum so a new patcher cannot invent a fourth status the reporter
|
|
4
|
-
* has no symbol for.
|
|
5
|
-
*/
|
|
6
|
-
export declare const PatchKind: {
|
|
7
|
-
readonly APPLY: "apply";
|
|
8
|
-
readonly ALREADY: "already";
|
|
9
|
-
readonly MANUAL: "manual";
|
|
10
|
-
};
|
|
11
|
-
export type PatchKind = (typeof PatchKind)[keyof typeof PatchKind];
|
|
12
|
-
export type SourcePatch = {
|
|
13
|
-
kind: typeof PatchKind.APPLY;
|
|
14
|
-
code: string;
|
|
15
|
-
} | {
|
|
16
|
-
kind: typeof PatchKind.ALREADY;
|
|
17
|
-
} | {
|
|
18
|
-
kind: typeof PatchKind.MANUAL;
|
|
19
|
-
reason: string;
|
|
20
|
-
};
|
package/dist/init/patch-kind.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The outcome vocabulary shared by every conservative source patcher in `init` (Vite config, Next
|
|
3
|
-
* config, Next root layout). One enum so a new patcher cannot invent a fourth status the reporter
|
|
4
|
-
* has no symbol for.
|
|
5
|
-
*/
|
|
6
|
-
export const PatchKind = {
|
|
7
|
-
APPLY: 'apply',
|
|
8
|
-
ALREADY: 'already',
|
|
9
|
-
MANUAL: 'manual',
|
|
10
|
-
};
|