@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/vite-config.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure, conservative patcher for a Vite config: add the `@reticlehq/vite-plugin` import and drop
|
|
3
|
-
* `reticle` into the `plugins` array. Only handles the obvious, common shape — anything ambiguous
|
|
4
|
-
* bails to a `manual` result so we never half-edit a build config (a broken config is worse than a
|
|
5
|
-
* documented manual step).
|
|
6
|
-
*/
|
|
7
|
-
import { PatchKind } from './patch-kind.js';
|
|
8
|
-
export const VITE_IMPORT = "import { reticle } from '@reticlehq/vite-plugin';";
|
|
9
|
-
const RETICLE_MARKER = '@reticlehq/vite-plugin';
|
|
10
|
-
/**
|
|
11
|
-
* The `reticle(...)` call — the bridge port so the injected connect targets it.
|
|
12
|
-
*
|
|
13
|
-
* **`captureNetworkBodies` is OPT-IN.** It was written in by default, and the argument for that was
|
|
14
|
-
* a good one: without a body, a write that answers 2xx grades `unknown / outcome_unread`, because a
|
|
15
|
-
* 200 describes the transport and not the result. Measured on a real payments UI — a refund posted
|
|
16
|
-
* rupees into a paise field, the server answered 200 having refunded a hundredth of it, the page
|
|
17
|
-
* rendered the amount the user had typed, and every DOM-level check passed.
|
|
18
|
-
*
|
|
19
|
-
* That argument justifies the CAPABILITY. It does not justify the default, and the distinction is
|
|
20
|
-
* what #705 is about. A healthcare workspace proxying authenticated API traffic through Vite ran
|
|
21
|
-
* `init`, and on the first drive their login tokens and patient payloads were in the daemon's
|
|
22
|
-
* buffer. The old comment here conceded the exact gap — "the credential classes are redacted ... but
|
|
23
|
-
* an address or an email is not, and nothing here should decide that for someone silently" — and
|
|
24
|
-
* then decided it for them, because writing the line into their config IS deciding. `init` is run
|
|
25
|
-
* unattended by an agent; the person who knows the data is sensitive is not in the room.
|
|
26
|
-
*
|
|
27
|
-
* So the default is off and the ways in are all deliberate:
|
|
28
|
-
* - `reticle init --capture-bodies` writes the line, for someone who has decided
|
|
29
|
-
* - `VITE_RETICLE_CAPTURE_BODIES=1` turns it on for ONE dev-server run, no config edit
|
|
30
|
-
* - adding the option by hand, which is what the tools tell you to do
|
|
31
|
-
*
|
|
32
|
-
* Nothing goes quiet in exchange. Every tool that needs a body already says so when it is missing
|
|
33
|
-
* and names the option — see honesty/uncaptured-bodies.ts, honesty/verified.ts, predicate-eval.ts
|
|
34
|
-
* and reconcile-tools.ts — so the capability is discovered at the moment it is wanted, by the person
|
|
35
|
-
* who wanted it, instead of being switched on before anyone has asked.
|
|
36
|
-
*/
|
|
37
|
-
function reticlePluginCall(port, captureBodies) {
|
|
38
|
-
const options = [
|
|
39
|
-
...(port === undefined ? [] : [`port: ${String(port)}`]),
|
|
40
|
-
...(captureBodies ? ['captureNetworkBodies: true'] : []),
|
|
41
|
-
];
|
|
42
|
-
return 0 === options.length ? 'reticle()' : `reticle({ ${options.join(', ')} })`;
|
|
43
|
-
}
|
|
44
|
-
/** Matches the start of a `plugins: [` array literal. */
|
|
45
|
-
const PLUGINS_ARRAY = /plugins\s*:\s*\[/;
|
|
46
|
-
/** Matches an ES import statement (used to place our import after the last one). */
|
|
47
|
-
const IMPORT_LINE = /^import\s.+from\s+['"][^'"]+['"];?\s*$/gm;
|
|
48
|
-
/**
|
|
49
|
-
* The opening `{` of the exported config object — `defineConfig({`, or a bare `export default {`.
|
|
50
|
-
* Used only when there is no `plugins` array to extend: the object is right there, so adding the
|
|
51
|
-
* key is the same edit as extending the array, and bailing sent a user whose config merely set
|
|
52
|
-
* `server.port` to a manual paste for a change we can make correctly.
|
|
53
|
-
*
|
|
54
|
-
* A config built by a call (`defineConfig(buildOptions())`) has no literal to extend and still
|
|
55
|
-
* bails — the rule stays "only edit a shape we can see whole".
|
|
56
|
-
*/
|
|
57
|
-
const CONFIG_OBJECT = /(export\s+default\s+(?:defineConfig\s*\(\s*)?)\{/;
|
|
58
|
-
/** Alias kept so existing call sites read in Vite terms; the vocabulary is shared (see patch-kind). */
|
|
59
|
-
export const VitePatchKind = PatchKind;
|
|
60
|
-
const NO_PLUGINS_REASON = "couldn't find a `plugins: [...]` array to extend";
|
|
61
|
-
function insertImport(source) {
|
|
62
|
-
const matches = [...source.matchAll(IMPORT_LINE)];
|
|
63
|
-
const last = matches[matches.length - 1];
|
|
64
|
-
if (last?.index === undefined) {
|
|
65
|
-
return `${VITE_IMPORT}\n${source}`;
|
|
66
|
-
}
|
|
67
|
-
const end = last.index + last[0].length;
|
|
68
|
-
return `${source.slice(0, end)}\n${VITE_IMPORT}${source.slice(end)}`;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Insert right after the opening `[` of the plugins array, spaced the way the surrounding line is.
|
|
72
|
-
*
|
|
73
|
-
* A multi-line array puts a newline next, and `[reticle(), \n` leaves trailing whitespace — exactly
|
|
74
|
-
* what a formatter rewrites, turning a one-line install into a diff against the user's own style. A
|
|
75
|
-
* single-line array needs the space, or the result reads `[reticle(),react()]`.
|
|
76
|
-
*/
|
|
77
|
-
function insertPlugin(source, port, captureBodies) {
|
|
78
|
-
return source.replace(PLUGINS_ARRAY, (match, _g, offset) => {
|
|
79
|
-
const next = source[offset + match.length] ?? '';
|
|
80
|
-
const separator = '' === next || /\s/.test(next) ? '' : ' ';
|
|
81
|
-
return `${match}${reticlePluginCall(port, captureBodies)},${separator}`;
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Add a whole `plugins: [reticle()]` key to a config object that has none, matching the layout of
|
|
86
|
-
* the object it lands in: a multi-line object gets its own indented line, a one-liner stays inline.
|
|
87
|
-
*/
|
|
88
|
-
function insertPluginsKey(source, port, captureBodies) {
|
|
89
|
-
return source.replace(CONFIG_OBJECT, (_match, prefix, offset) => {
|
|
90
|
-
const rest = source.slice(offset + _match.length);
|
|
91
|
-
const multiline = /^\s*\n/.test(rest);
|
|
92
|
-
const indent = /^\s*\n(\s*)\S/.exec(rest)?.[1] ?? ' ';
|
|
93
|
-
const key = `plugins: [${reticlePluginCall(port, captureBodies)}],`;
|
|
94
|
-
return multiline ? `${prefix}{\n${indent}${key}` : `${prefix}{ ${key}`;
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
export function patchViteConfig(source, port, captureBodies = false) {
|
|
98
|
-
if (source.includes(RETICLE_MARKER)) {
|
|
99
|
-
return { kind: VitePatchKind.ALREADY };
|
|
100
|
-
}
|
|
101
|
-
if (PLUGINS_ARRAY.test(source)) {
|
|
102
|
-
return {
|
|
103
|
-
kind: VitePatchKind.APPLY,
|
|
104
|
-
code: insertImport(insertPlugin(source, port, captureBodies)),
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
if (CONFIG_OBJECT.test(source)) {
|
|
108
|
-
return {
|
|
109
|
-
kind: VitePatchKind.APPLY,
|
|
110
|
-
code: insertImport(insertPluginsKey(source, port, captureBodies)),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return { kind: VitePatchKind.MANUAL, reason: NO_PLUGINS_REASON };
|
|
114
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Quote one argument for a Windows command line. Pure, and deliberately NOT platform-gated.
|
|
3
|
-
*
|
|
4
|
-
* The rule used to live inside a `process.platform === WINDOWS` branch in node-io.ts, which meant
|
|
5
|
-
* the Windows path could not be exercised on a mac or in CI's Linux job — so it stayed wrong. A
|
|
6
|
-
* pure function is most of the fix: it can be asserted anywhere, and it is.
|
|
7
|
-
*
|
|
8
|
-
* ## What was wrong
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* /[\s"]/.test(arg) ? `"${arg.replace(/"/g, '\\"')}"` : arg
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* Two independent holes, both reachable from an ordinary directory path:
|
|
15
|
-
*
|
|
16
|
-
* 1. **Backslashes were not escaped.** `C:\Users\ada\My Projects\` became
|
|
17
|
-
* `"C:\Users\ada\My Projects\"`, whose trailing `\"` reads as an ESCAPED quote — the quoted
|
|
18
|
-
* region never closes and the rest of the line is re-parsed by cmd.exe. CodeQL flagged this one
|
|
19
|
-
* (`js/incomplete-sanitization`, high).
|
|
20
|
-
* 2. **The predicate only looked for whitespace and quotes.** An argument like `foo&whoami` has
|
|
21
|
-
* neither, so it was handed to cmd.exe completely unquoted. Correct backslash escaping does
|
|
22
|
-
* nothing for that; it needs the metacharacters in the trigger.
|
|
23
|
-
*
|
|
24
|
-
* ## The rule implemented here
|
|
25
|
-
*
|
|
26
|
-
* `CommandLineToArgvW`: a run of backslashes is literal unless it precedes a `"`, in which case the
|
|
27
|
-
* run is doubled and the quote escaped; a run at the very end sits before the closing quote we add,
|
|
28
|
-
* so it is doubled too. Correctly-terminated quotes also neutralise cmd.exe's metacharacters, which
|
|
29
|
-
* it does not interpret inside a quoted region.
|
|
30
|
-
*
|
|
31
|
-
* ## Known limit, stated rather than papered over
|
|
32
|
-
*
|
|
33
|
-
* `%VAR%` is expanded by cmd.exe even inside quotes, and no quoting prevents it — only avoiding
|
|
34
|
-
* `shell: true` does, which Windows needs so `pnpm.cmd`/`npx.cmd` resolve (see `shellOpt`). That is
|
|
35
|
-
* variable substitution, not command execution, and every caller here passes paths and package
|
|
36
|
-
* names rather than user prose.
|
|
37
|
-
*/
|
|
38
|
-
export declare function windowsShellArg(arg: string): string;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Quote one argument for a Windows command line. Pure, and deliberately NOT platform-gated.
|
|
3
|
-
*
|
|
4
|
-
* The rule used to live inside a `process.platform === WINDOWS` branch in node-io.ts, which meant
|
|
5
|
-
* the Windows path could not be exercised on a mac or in CI's Linux job — so it stayed wrong. A
|
|
6
|
-
* pure function is most of the fix: it can be asserted anywhere, and it is.
|
|
7
|
-
*
|
|
8
|
-
* ## What was wrong
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* /[\s"]/.test(arg) ? `"${arg.replace(/"/g, '\\"')}"` : arg
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* Two independent holes, both reachable from an ordinary directory path:
|
|
15
|
-
*
|
|
16
|
-
* 1. **Backslashes were not escaped.** `C:\Users\ada\My Projects\` became
|
|
17
|
-
* `"C:\Users\ada\My Projects\"`, whose trailing `\"` reads as an ESCAPED quote — the quoted
|
|
18
|
-
* region never closes and the rest of the line is re-parsed by cmd.exe. CodeQL flagged this one
|
|
19
|
-
* (`js/incomplete-sanitization`, high).
|
|
20
|
-
* 2. **The predicate only looked for whitespace and quotes.** An argument like `foo&whoami` has
|
|
21
|
-
* neither, so it was handed to cmd.exe completely unquoted. Correct backslash escaping does
|
|
22
|
-
* nothing for that; it needs the metacharacters in the trigger.
|
|
23
|
-
*
|
|
24
|
-
* ## The rule implemented here
|
|
25
|
-
*
|
|
26
|
-
* `CommandLineToArgvW`: a run of backslashes is literal unless it precedes a `"`, in which case the
|
|
27
|
-
* run is doubled and the quote escaped; a run at the very end sits before the closing quote we add,
|
|
28
|
-
* so it is doubled too. Correctly-terminated quotes also neutralise cmd.exe's metacharacters, which
|
|
29
|
-
* it does not interpret inside a quoted region.
|
|
30
|
-
*
|
|
31
|
-
* ## Known limit, stated rather than papered over
|
|
32
|
-
*
|
|
33
|
-
* `%VAR%` is expanded by cmd.exe even inside quotes, and no quoting prevents it — only avoiding
|
|
34
|
-
* `shell: true` does, which Windows needs so `pnpm.cmd`/`npx.cmd` resolve (see `shellOpt`). That is
|
|
35
|
-
* variable substitution, not command execution, and every caller here passes paths and package
|
|
36
|
-
* names rather than user prose.
|
|
37
|
-
*/
|
|
38
|
-
/**
|
|
39
|
-
* Characters that make cmd.exe do something other than pass the text along.
|
|
40
|
-
*
|
|
41
|
-
* Whitespace and `"` split or delimit; the rest are the shell's control operators. An argument
|
|
42
|
-
* containing any of them must be quoted, not just one containing a space.
|
|
43
|
-
*/
|
|
44
|
-
const NEEDS_QUOTING = /[\s"&|<>^()!%,;=]/;
|
|
45
|
-
export function windowsShellArg(arg) {
|
|
46
|
-
// An empty argument must still occupy a slot in argv. Unquoted it disappears entirely, silently
|
|
47
|
-
// shifting every argument after it by one.
|
|
48
|
-
if (0 === arg.length)
|
|
49
|
-
return '""';
|
|
50
|
-
if (!NEEDS_QUOTING.test(arg))
|
|
51
|
-
return arg;
|
|
52
|
-
let out = '"';
|
|
53
|
-
let backslashes = 0;
|
|
54
|
-
for (const ch of arg) {
|
|
55
|
-
if ('\\' === ch) {
|
|
56
|
-
backslashes += 1;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if ('"' === ch) {
|
|
60
|
-
// 2n+1 backslashes → n literal backslashes and an escaped quote.
|
|
61
|
-
out += '\\'.repeat(2 * backslashes + 1) + '"';
|
|
62
|
-
backslashes = 0;
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
out += '\\'.repeat(backslashes) + ch;
|
|
66
|
-
backslashes = 0;
|
|
67
|
-
}
|
|
68
|
-
// A trailing run sits immediately before the closing quote, so it must be doubled or it escapes it.
|
|
69
|
-
return `${out}${'\\'.repeat(2 * backslashes)}"`;
|
|
70
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { InitIo } from './run.js';
|
|
2
|
-
/**
|
|
3
|
-
* The file names that say what a directory IS, shared by everything that has to ask.
|
|
4
|
-
*
|
|
5
|
-
* They lived in run.ts and are read from here now because `findWorkspaceApps` moved and needs them —
|
|
6
|
-
* one definition, imported in both directions of the question ("is this an app?" and "which app?").
|
|
7
|
-
*/
|
|
8
|
-
export declare const PACKAGE_JSON = "package.json";
|
|
9
|
-
export declare const PNPM_WORKSPACE = "pnpm-workspace.yaml";
|
|
10
|
-
export declare const VITE_CONFIG_CANDIDATES: string[];
|
|
11
|
-
export declare const NEXT_CONFIG_CANDIDATES: string[];
|
|
12
|
-
interface WorkspaceSources {
|
|
13
|
-
/** Raw contents of pnpm-workspace.yaml, when present. */
|
|
14
|
-
pnpmWorkspace?: string;
|
|
15
|
-
/** The `workspaces` field of package.json — array form or the yarn/npm object form. */
|
|
16
|
-
pkgWorkspaces?: unknown;
|
|
17
|
-
/** Directory names at the repo root, used when nothing is declared. */
|
|
18
|
-
topLevelDirs?: readonly string[];
|
|
19
|
-
}
|
|
20
|
-
export declare function workspaceParents(sources: WorkspaceSources): string[];
|
|
21
|
-
/**
|
|
22
|
-
* App directories under a workspace root.
|
|
23
|
-
*
|
|
24
|
-
* Running `reticle init` at the repo root is what people actually do, and in a monorepo the app is a
|
|
25
|
-
* directory down — so init detected "no framework", printed a wall of manual HTML instructions, and
|
|
26
|
-
* would have installed the SDK into the ROOT package.json. It already walks UP for the lockfile, so
|
|
27
|
-
* it knows it is in a workspace; this is the matching walk DOWN.
|
|
28
|
-
*/
|
|
29
|
-
export declare function findWorkspaceApps(io: Pick<InitIo, 'exists' | 'readFile' | 'listDirs'>): string[];
|
|
30
|
-
export {};
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { DEV_SCRIPT_NAMES } from './dev-script.js';
|
|
2
|
-
/**
|
|
3
|
-
* The file names that say what a directory IS, shared by everything that has to ask.
|
|
4
|
-
*
|
|
5
|
-
* They lived in run.ts and are read from here now because `findWorkspaceApps` moved and needs them —
|
|
6
|
-
* one definition, imported in both directions of the question ("is this an app?" and "which app?").
|
|
7
|
-
*/
|
|
8
|
-
export const PACKAGE_JSON = 'package.json';
|
|
9
|
-
export const PNPM_WORKSPACE = 'pnpm-workspace.yaml';
|
|
10
|
-
export const VITE_CONFIG_CANDIDATES = [
|
|
11
|
-
'vite.config.ts',
|
|
12
|
-
'vite.config.js',
|
|
13
|
-
'vite.config.mjs',
|
|
14
|
-
'vite.config.mts',
|
|
15
|
-
];
|
|
16
|
-
export const NEXT_CONFIG_CANDIDATES = [
|
|
17
|
-
'next.config.mjs',
|
|
18
|
-
'next.config.js',
|
|
19
|
-
'next.config.ts',
|
|
20
|
-
'next.config.cjs',
|
|
21
|
-
];
|
|
22
|
-
/**
|
|
23
|
-
* Which directories to look in for the app, when `reticle init` runs at a monorepo root.
|
|
24
|
-
*
|
|
25
|
-
* This used to be the literal list `['apps', 'packages']`. Measured on a real repo with three Next
|
|
26
|
-
* apps at `web/`, `admin/` and `space/`, it found none — so the redirect never fired, init ran
|
|
27
|
-
* against the root, and it reported ✓ for writing `app/reticle-dev.tsx` into a directory Next never
|
|
28
|
-
* compiles. A ⚠ tells a human to act; a ✓ tells them it is handled.
|
|
29
|
-
*
|
|
30
|
-
* A workspace DECLARES its packages, so that declaration is used first and directory names are not
|
|
31
|
-
* guessed at all. Where nothing is declared, every top-level directory is a better candidate than two
|
|
32
|
-
* hardcoded ones — filtered by the usual non-source suspects, and still subject to the `looksLikeApp`
|
|
33
|
-
* check that follows, so a wrong guess here costs a `package.json` read.
|
|
34
|
-
*/
|
|
35
|
-
/** Directories that are never a workspace package, whatever the layout. */
|
|
36
|
-
const NEVER_A_PACKAGE = new Set(['node_modules', 'dist', 'build', 'out', 'coverage', 'target']);
|
|
37
|
-
/** `packages/*` -> `packages`; `web` -> `web`. The base directory a glob searches. */
|
|
38
|
-
function globBase(pattern) {
|
|
39
|
-
const base = pattern
|
|
40
|
-
.split('/')[0]
|
|
41
|
-
?.trim()
|
|
42
|
-
.replace(/^['"]|['"]$/g, '');
|
|
43
|
-
return base === undefined || '' === base || '.' === base || base.includes('*') ? undefined : base;
|
|
44
|
-
}
|
|
45
|
-
function fromPnpm(yaml) {
|
|
46
|
-
// A deliberately small reader rather than a YAML dependency: this file is a list of globs, and the
|
|
47
|
-
// only shape that matters is `- 'pattern'` under `packages:`. A malformed file yields nothing,
|
|
48
|
-
// which falls through to the top-level scan rather than failing the install.
|
|
49
|
-
const out = [];
|
|
50
|
-
let inPackages = false;
|
|
51
|
-
for (const line of yaml.split('\n')) {
|
|
52
|
-
if (/^packages\s*:/.test(line)) {
|
|
53
|
-
inPackages = true;
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (inPackages && /^\S/.test(line))
|
|
57
|
-
break;
|
|
58
|
-
const item = /^\s*-\s*(.+)$/.exec(line);
|
|
59
|
-
if (inPackages && item?.[1] !== undefined) {
|
|
60
|
-
const base = globBase(item[1]);
|
|
61
|
-
if (base !== undefined)
|
|
62
|
-
out.push(base);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return out;
|
|
66
|
-
}
|
|
67
|
-
function fromPkg(workspaces) {
|
|
68
|
-
const list = Array.isArray(workspaces)
|
|
69
|
-
? workspaces
|
|
70
|
-
: 'object' === typeof workspaces && workspaces !== null
|
|
71
|
-
? workspaces.packages
|
|
72
|
-
: undefined;
|
|
73
|
-
if (!Array.isArray(list))
|
|
74
|
-
return [];
|
|
75
|
-
return list
|
|
76
|
-
.filter((p) => 'string' === typeof p)
|
|
77
|
-
.map(globBase)
|
|
78
|
-
.filter((p) => p !== undefined);
|
|
79
|
-
}
|
|
80
|
-
export function workspaceParents(sources) {
|
|
81
|
-
const declared = [
|
|
82
|
-
...(sources.pnpmWorkspace === undefined ? [] : fromPnpm(sources.pnpmWorkspace)),
|
|
83
|
-
...fromPkg(sources.pkgWorkspaces),
|
|
84
|
-
];
|
|
85
|
-
const candidates = declared.length > 0
|
|
86
|
-
? declared
|
|
87
|
-
: (sources.topLevelDirs ?? []).filter((d) => !d.startsWith('.') && !NEVER_A_PACKAGE.has(d));
|
|
88
|
-
return [...new Set(candidates)];
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Which directories under this workspace are runnable apps.
|
|
92
|
-
*
|
|
93
|
-
* Moved here from run.ts, which was over the 1000-line cap and had carried a note saying it was at
|
|
94
|
-
* its cohesion limit. `library-path-boundary.test.ts` had already written down that this function
|
|
95
|
-
* "squats in init/ for historical reasons" — it is a general-purpose question about a repository's
|
|
96
|
-
* shape, next to `workspaceParents`, which answers the other half of it.
|
|
97
|
-
*/
|
|
98
|
-
/** Deps that mark a directory as a runnable web app even when it has no bundler config file. */
|
|
99
|
-
const APP_DEPS = ['next', 'vite'];
|
|
100
|
-
function hasDevScript(pkgRaw) {
|
|
101
|
-
try {
|
|
102
|
-
const parsed = JSON.parse(pkgRaw);
|
|
103
|
-
const scripts = 'object' === typeof parsed && parsed !== null
|
|
104
|
-
? parsed.scripts
|
|
105
|
-
: undefined;
|
|
106
|
-
if ('object' !== typeof scripts || null === scripts)
|
|
107
|
-
return false;
|
|
108
|
-
const named = scripts;
|
|
109
|
-
return DEV_SCRIPT_NAMES.some((n) => 'string' === typeof named[n] && '' !== named[n]);
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
// A manifest that will not parse says nothing either way, and this is a filter, not a verdict.
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
function looksLikeApp(dir, io) {
|
|
117
|
-
const pkgRaw = io.readFile(`${dir}/${PACKAGE_JSON}`);
|
|
118
|
-
if (null === pkgRaw)
|
|
119
|
-
return false;
|
|
120
|
-
const configs = [...VITE_CONFIG_CANDIDATES, ...NEXT_CONFIG_CANDIDATES];
|
|
121
|
-
if (configs.some((c) => io.exists(`${dir}/${c}`)))
|
|
122
|
-
return true;
|
|
123
|
-
// `next.config` is optional in Next, so the dependency list is the other half of the signal.
|
|
124
|
-
if (APP_DEPS.some((d) => pkgRaw.includes(`"${d}"`)))
|
|
125
|
-
return true;
|
|
126
|
-
// And the honest third: an app somebody can SERVE. Asking only for a bundler missed every app
|
|
127
|
-
// built on anything else — Remix, Astro, a plain node server — and in a monorepo missing it means
|
|
128
|
-
// init never redirects, wires the ROOT, and reports ✓ for files nothing compiles.
|
|
129
|
-
//
|
|
130
|
-
// A monorepo root has no dev script by design, and a package that can only be BUILT is not the app
|
|
131
|
-
// somebody is working in, so this stays a filter rather than matching every directory.
|
|
132
|
-
return hasDevScript(pkgRaw);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* App directories under a workspace root.
|
|
136
|
-
*
|
|
137
|
-
* Running `reticle init` at the repo root is what people actually do, and in a monorepo the app is a
|
|
138
|
-
* directory down — so init detected "no framework", printed a wall of manual HTML instructions, and
|
|
139
|
-
* would have installed the SDK into the ROOT package.json. It already walks UP for the lockfile, so
|
|
140
|
-
* it knows it is in a workspace; this is the matching walk DOWN.
|
|
141
|
-
*/
|
|
142
|
-
export function findWorkspaceApps(io) {
|
|
143
|
-
const found = [];
|
|
144
|
-
// A workspace DECLARES its packages; `['apps','packages']` was a guess that missed a real repo
|
|
145
|
-
// with three Next apps at web/, admin/ and space/ — and missing them meant init ran against the
|
|
146
|
-
// root and reported ✓ for a file Next never compiles. See workspace-apps.
|
|
147
|
-
const pkgRaw = io.readFile(PACKAGE_JSON);
|
|
148
|
-
let pkgWorkspaces;
|
|
149
|
-
try {
|
|
150
|
-
const parsed = null === pkgRaw ? undefined : JSON.parse(pkgRaw);
|
|
151
|
-
pkgWorkspaces =
|
|
152
|
-
'object' === typeof parsed && parsed !== null
|
|
153
|
-
? parsed.workspaces
|
|
154
|
-
: undefined;
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
pkgWorkspaces = undefined;
|
|
158
|
-
}
|
|
159
|
-
const parents = workspaceParents({
|
|
160
|
-
...(null === io.readFile(PNPM_WORKSPACE)
|
|
161
|
-
? {}
|
|
162
|
-
: { pnpmWorkspace: io.readFile(PNPM_WORKSPACE) ?? '' }),
|
|
163
|
-
...(pkgWorkspaces === undefined ? {} : { pkgWorkspaces }),
|
|
164
|
-
topLevelDirs: io.listDirs('.'),
|
|
165
|
-
});
|
|
166
|
-
// A declared parent can itself BE the app (`workspaces: ["web"]`), so check both the directory and
|
|
167
|
-
// its children rather than assuming one level of nesting.
|
|
168
|
-
for (const parent of parents) {
|
|
169
|
-
if (looksLikeApp(parent, io))
|
|
170
|
-
found.push(parent);
|
|
171
|
-
for (const name of io.listDirs(parent)) {
|
|
172
|
-
const dir = `${parent}/${name}`;
|
|
173
|
-
if (looksLikeApp(dir, io))
|
|
174
|
-
found.push(dir);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return [...new Set(found)];
|
|
178
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Record where this project lives, so a daemon started somewhere else can still find it.
|
|
3
|
-
*
|
|
4
|
-
* Called at the end of `init`, which is the one moment both halves are known for certain: the
|
|
5
|
-
* directory being initialised, and the projectId that was just written into its `.reticle.json`.
|
|
6
|
-
*
|
|
7
|
-
* Deliberately runs on EVERY init, not only the first. Most init runs report "already wired", and a
|
|
8
|
-
* re-run in a re-cloned or moved checkout is exactly when the remembered path has gone stale — so
|
|
9
|
-
* the run that would have been a no-op is the one that repairs the entry.
|
|
10
|
-
*
|
|
11
|
-
* Every failure is swallowed. This is a cache that makes a later resolution better; a read-only home
|
|
12
|
-
* directory, a full disk or a hand-mangled file must not turn a successful init into a failed one.
|
|
13
|
-
* The user's project is wired either way, and `init`'s report is the first thing a new user reads.
|
|
14
|
-
*/
|
|
15
|
-
/** The sync filesystem seam `init` already carries. Narrowed to what this needs. */
|
|
16
|
-
export interface RegistryIo {
|
|
17
|
-
readFile(path: string): string | null;
|
|
18
|
-
writeFile(path: string, content: string): void;
|
|
19
|
-
exists(path: string): boolean;
|
|
20
|
-
homeDir(): string;
|
|
21
|
-
}
|
|
22
|
-
/** The `projectId` a `.reticle.json` declares, or undefined when it declares none we can use. */
|
|
23
|
-
export declare function projectIdOf(configSource: string | null): string | undefined;
|
|
24
|
-
export declare function rememberProjectOnDisk(io: RegistryIo, projectId: string, directory: string, now: number): boolean;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { join } from 'node:path';
|
|
2
|
-
import { PROJECT_REGISTRY_FILE, ReticleDir, emptyProjectRegistry, parseProjectRegistry, rememberProject, } from '@reticlehq/core';
|
|
3
|
-
/** The `projectId` a `.reticle.json` declares, or undefined when it declares none we can use. */
|
|
4
|
-
export function projectIdOf(configSource) {
|
|
5
|
-
if (null === configSource || 0 === configSource.length)
|
|
6
|
-
return undefined;
|
|
7
|
-
try {
|
|
8
|
-
const parsed = JSON.parse(configSource);
|
|
9
|
-
if ('object' !== typeof parsed || null === parsed || Array.isArray(parsed))
|
|
10
|
-
return undefined;
|
|
11
|
-
const id = parsed['projectId'];
|
|
12
|
-
return 'string' === typeof id && id.length > 0 ? id : undefined;
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return undefined;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
export function rememberProjectOnDisk(io, projectId, directory, now) {
|
|
19
|
-
if (0 === projectId.length || 0 === directory.length)
|
|
20
|
-
return false;
|
|
21
|
-
try {
|
|
22
|
-
const path = join(io.homeDir(), ReticleDir.ROOT, PROJECT_REGISTRY_FILE);
|
|
23
|
-
const existing = io.exists(path) ? io.readFile(path) : null;
|
|
24
|
-
const registry = null === existing ? emptyProjectRegistry() : parseProjectRegistry(safeJson(existing));
|
|
25
|
-
const next = rememberProject(registry, projectId, directory, now);
|
|
26
|
-
io.writeFile(path, `${JSON.stringify(next, null, 2)}\n`);
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function safeJson(raw) {
|
|
34
|
-
try {
|
|
35
|
-
return JSON.parse(raw);
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
File without changes
|