@reticlehq/init 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/LICENSE +105 -0
- package/NOTICE +5 -0
- package/README.md +29 -0
- package/dist/agent-rules.d.ts +116 -0
- package/dist/agent-rules.js +279 -0
- package/dist/app-choice.d.ts +29 -0
- package/dist/app-choice.js +39 -0
- package/dist/astro-host.d.ts +21 -0
- package/dist/astro-host.js +27 -0
- package/dist/astro-patch.d.ts +33 -0
- package/dist/astro-patch.js +103 -0
- package/dist/brace-scan.d.ts +24 -0
- package/dist/brace-scan.js +46 -0
- package/dist/capabilities.d.ts +40 -0
- package/dist/capabilities.js +167 -0
- package/dist/closing-hint.d.ts +35 -0
- package/dist/closing-hint.js +122 -0
- package/dist/codex-toml.d.ts +10 -0
- package/dist/codex-toml.js +144 -0
- package/dist/connect-steps.d.ts +55 -0
- package/dist/connect-steps.js +92 -0
- package/dist/cra.d.ts +82 -0
- package/dist/cra.js +183 -0
- package/dist/csp-check.d.ts +49 -0
- package/dist/csp-check.js +168 -0
- package/dist/csp-doctor.d.ts +32 -0
- package/dist/csp-doctor.js +62 -0
- package/dist/desktop-doctor.d.ts +46 -0
- package/dist/desktop-doctor.js +201 -0
- package/dist/detect.d.ts +225 -0
- package/dist/detect.js +334 -0
- package/dist/dev-script.d.ts +51 -0
- package/dist/dev-script.js +66 -0
- package/dist/dev-server-ports.d.ts +20 -0
- package/dist/dev-server-ports.js +45 -0
- package/dist/electron-patch.d.ts +11 -0
- package/dist/electron-patch.js +70 -0
- package/dist/electron-vite-patch.d.ts +12 -0
- package/dist/electron-vite-patch.js +100 -0
- package/dist/existing-config.d.ts +31 -0
- package/dist/existing-config.js +63 -0
- package/dist/format-generated.d.ts +18 -0
- package/dist/format-generated.js +48 -0
- package/dist/framework-adapter.d.ts +60 -0
- package/dist/framework-adapter.js +138 -0
- package/dist/host.d.ts +41 -0
- package/dist/host.js +21 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +25 -0
- package/dist/init-failure.d.ts +19 -0
- package/dist/init-failure.js +18 -0
- package/dist/init-opt-out.d.ts +17 -0
- package/dist/init-opt-out.js +30 -0
- package/dist/install-hint.d.ts +9 -0
- package/dist/install-hint.js +41 -0
- package/dist/install-retries.d.ts +22 -0
- package/dist/install-retries.js +65 -0
- package/dist/install-source-config.d.ts +18 -0
- package/dist/install-source-config.js +34 -0
- package/dist/lockfiles.d.ts +14 -0
- package/dist/lockfiles.js +49 -0
- package/dist/mcp-clients.d.ts +94 -0
- package/dist/mcp-clients.js +327 -0
- package/dist/mcp-registered.d.ts +12 -0
- package/dist/mcp-registered.js +14 -0
- package/dist/mcp.d.ts +89 -0
- package/dist/mcp.js +129 -0
- package/dist/next-patch.d.ts +49 -0
- package/dist/next-patch.js +237 -0
- package/dist/node-io.d.ts +22 -0
- package/dist/node-io.js +150 -0
- package/dist/non-js-project.d.ts +44 -0
- package/dist/non-js-project.js +137 -0
- package/dist/nuxt-patch.d.ts +18 -0
- package/dist/nuxt-patch.js +33 -0
- package/dist/patch-kind.d.ts +20 -0
- package/dist/patch-kind.js +10 -0
- package/dist/plan-electron-vite.d.ts +16 -0
- package/dist/plan-electron-vite.js +72 -0
- package/dist/plan-framework.d.ts +122 -0
- package/dist/plan-framework.js +773 -0
- package/dist/plan.d.ts +312 -0
- package/dist/plan.js +650 -0
- package/dist/platform.d.ts +16 -0
- package/dist/platform.js +16 -0
- package/dist/preflight.d.ts +30 -0
- package/dist/preflight.js +52 -0
- package/dist/project-id.d.ts +12 -0
- package/dist/project-id.js +25 -0
- package/dist/refresh-rules.d.ts +40 -0
- package/dist/refresh-rules.js +51 -0
- package/dist/remember-project.d.ts +24 -0
- package/dist/remember-project.js +40 -0
- package/dist/run.d.ts +122 -0
- package/dist/run.js +762 -0
- package/dist/slash-command.d.ts +27 -0
- package/dist/slash-command.js +132 -0
- package/dist/snippets.d.ts +267 -0
- package/dist/snippets.js +898 -0
- package/dist/tanstack-start.d.ts +18 -0
- package/dist/tanstack-start.js +57 -0
- package/dist/version.d.ts +18 -0
- package/dist/version.js +23 -0
- package/dist/vite-config.d.ts +18 -0
- package/dist/vite-config.js +111 -0
- package/dist/vite-owning-config.d.ts +25 -0
- package/dist/vite-owning-config.js +219 -0
- package/dist/windows-quote.d.ts +38 -0
- package/dist/windows-quote.js +70 -0
- package/dist/workspace-apps.d.ts +40 -0
- package/dist/workspace-apps.js +188 -0
- package/dist/workspace-redirect.d.ts +22 -0
- package/dist/workspace-redirect.js +97 -0
- package/package.json +53 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/reticle` slash command — the entry point the docs have been promising and nothing created.
|
|
3
|
+
*
|
|
4
|
+
* SKILL.md tells the user "Type `/reticle` anytime to verify the app" in three places, and `init`
|
|
5
|
+
* never wrote the file that makes it exist. So the one obvious way in was a command that silently did
|
|
6
|
+
* nothing in every tool. Claude Code and Cursor both read custom commands from a markdown file per
|
|
7
|
+
* command; the body is the prompt the agent receives.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately SCOPED to one flow. A user installing Reticle has an existing app with many flows, and
|
|
10
|
+
* an agent told to "verify the app" will try to instrument all of them — slow, noisy, and nothing to
|
|
11
|
+
* see for minutes. One flow, driven where the human can watch it, is the whole difference between a
|
|
12
|
+
* two-minute first impression and an afternoon.
|
|
13
|
+
*/
|
|
14
|
+
/** Claude Code reads project commands from `.claude/commands/<name>.md`. */
|
|
15
|
+
export declare const CLAUDE_COMMAND_PATH = ".claude/commands/reticle.md";
|
|
16
|
+
/** Cursor reads them from `.cursor/commands/<name>.md`. */
|
|
17
|
+
export declare const CURSOR_COMMAND_PATH = ".cursor/commands/reticle.md";
|
|
18
|
+
/**
|
|
19
|
+
* The frontmatter line that marks a command file as OURS.
|
|
20
|
+
*
|
|
21
|
+
* A stale command has to be refreshable — a file frozen at whatever release created it can never be
|
|
22
|
+
* improved for anyone who already ran init — but the path is one a human may have claimed for their
|
|
23
|
+
* own `/reticle`, and overwriting that would be destroying somebody's work. This line is how the two
|
|
24
|
+
* are told apart.
|
|
25
|
+
*/
|
|
26
|
+
export declare const SLASH_COMMAND_SIGNATURE = "description: Verify this app in the browser with Reticle";
|
|
27
|
+
export declare const SLASH_COMMAND_BODY = "---\ndescription: Verify this app in the browser with Reticle \u2014 drive one real flow and report what happened.\n---\n\nVerify this running app with Reticle. Drive it; do not read the code and guess.\n\n## Step 0 \u2014 is anything connected?\n\nCall `reticle_sessions` first.\n\n**A session is listed?** Go to \"Pick ONE flow\".\n\n**No session?** Setup is not finished, and stopping to ask the user to run something is not an\nanswer. Every step below is yours to do without them. Work these in order, and say which one you are\non, one line each:\n\n0. **Is Reticle even wired into this project?** `cat .reticle.json`. If it is not there, this\n project was never set up: run `npx @reticlehq/server@latest init`,\n fix every `\u26A0` and `\u2139` it prints, and carry on. Do not ask first, and do not ask which\n framework or port \u2014 both come out of the repo you are sitting in.\n\n1. **Is anything serving the app at all?** If a dev server is already listening, use it and go to\n step 2 \u2014 the cause is then almost always that the SDK never loaded in the page, not a missing\n server, so do not tell the user to start one they are already running. If nothing is listening:\n\n**A dev server already running when `reticle init` ran does not have Reticle in its bundle.** It read the build config at boot; `init` edited it afterwards. It serves the old bundle and no session appears. In order:\n\n1. **A dev server was already running?** Restart it, then hard-reload the tab. \"Something is listening\" does not mean the right bundle is served.\n2. **Nothing was running?** Start it in the BACKGROUND and say so in one line. `reticle_sessions` gives you this project's own dev command in `next_action`; use that, never compose one. Started after `init`, it needs no restart.\n\nStopping to ask is how a verification turn ends with nothing verified.\n\nFour guards, none optional:\n\n1. **Never run two at once.** One dev server on the app's port. Restarting a stale one means stopping it first, not starting a second alongside it.\n2. **Never guess the command.** It comes from `package.json` scripts. No recognisable dev script means say so and stop, not invent one.\n3. **Never kill anything you did not start**, and never a daemon or a port holder. The one exception is the restart above, and say in one line that you did it.\n4. **The permission prompt belongs to your host.** Never bypass, suppress or auto-approve it, and take a refusal as the answer.\n\n2. **Is a page open on it?** Do not ask the user to open a browser \u2014 open it:\n\n ```bash\n npx @reticlehq/server open <the url the dev server is serving>\n ```\n\n That reuses an already-connected tab or opens a new one, and waits for the page to register. On a\n machine with no browser to open, take a tab Reticle owns instead:\n `reticle_run({ tool: \"reticle_lease\", args: { action: \"acquire\", url: \"<the same url>\" } })`.\n\nThen, once something is serving the app and a page is on it:\n\n3. **Is the SDK actually in the app?** Read the app's entry file (`src/main.tsx`, `app/layout.tsx`,\n `src/app.vue`, whatever this project uses). You are looking for an `import` from\n `@reticlehq/react` or `@reticlehq/browser` and a `connect()` call, or the Reticle plugin in\n `vite.config.*`, or `withReticle` in `next.config.*`. **If it is not there, that is the bug.**\n Wire it in \u2014 see the framework snippets at https://docs.reticle.sh/instrumentation \u2014 then restart\n the dev server and re-check.\n4. **Is the connect guarded on `hostname === 'localhost'`?** If so, remove that guard. It is false on\n any non-localhost dev host, and `window` does not exist during SSR, so the guard silently prevents\n the connect and logs nothing. Use the framework's dev flag instead (`import.meta.env.DEV`,\n `process.env.NODE_ENV !== 'production'`, `import.meta.dev`).\n5. **Is the dev server serving that entry?** Look in `reticle_console`, or in the page you opened in\n step 2, for a line starting `[Reticle]`. That line, or its absence, tells you which side is at\n fault. Reticle itself never starts a dev server \u2014 starting it is your job, under the guards above.\n6. **Do both sides agree on the port?** Run `npx @reticlehq/server doctor` and compare the daemon\n port against the port the page dials.\n\nIf you are still stuck after all of those, file it: `reticle_feedback` with kind `gap`, saying what you\nchecked and what you saw. Then tell the user exactly which step is blocked. Do not report the install\nas finished.\n\n## Pick ONE flow\n\nNot the whole app. Pick the single most important flow you can complete in a handful of steps \u2014 the\none a user would do first (sign in, search, add to cart, submit the form). If the user named a flow or\njust changed some code, use that one instead.\n\nState which flow you picked in one line before you start.\n\n## Drive it where the human can see\n\n1. `reticle_snapshot` \u2014 read the accessibility tree and locate the elements the flow needs. Elements\n are addressable by role and name; you do **not** need `data-testid` to drive them.\n2. Walk the flow with `reticle_act_and_wait`, one step at a time. Narrate each step first \u2014 the human\n is watching the page, and the HUD shows what you say.\n3. After each step, check the effect with `reticle_assert` \u2014 not just that the click dispatched, but\n that the thing it was supposed to do actually happened.\n4. Finish with `reticle_console` and `reticle_network` to catch errors the DOM does not show.\n\n**Only `reticle_act_and_wait` and `reticle_assert` produce a verdict.** A run that ends on a\nsnapshot has proved nothing, however many tools it used.\n\n## Report\n\n- What you drove, step by step, and what each step actually produced.\n- Anything broken, with the `file:line` Reticle gave you.\n- If a step could not be verified, say so plainly. \"Unknown\" is a real answer; a green verdict you\n cannot back is not.\n\nDo not weaken or skip an assertion to make the run pass \u2014 that is a finding, not a fix.\n\n## If the user handed you a license key\n\nAppend `RETICLE_LICENSE_KEY=<key>` to the project's `.env` (create it if absent), make sure `.env`\nis in `.gitignore`, and confirm with `npx @reticlehq/server license`. The CLI folds a project-local\n`.env` in on every invocation, so nothing else changes. Never echo the key back, and never put it in\na commit, a comment, or a feedback report.\n\n## Two things afterwards\n\n- **Anything about Reticle itself that was wrong, missing, confusing, or expensive?** Send it with\n `reticle_feedback` now, before your context is gone. That report is the only signal that decides\n what gets fixed. Bugs in the app under test are Reticle working; those go in your answer to the user.\n- **If the verification actually succeeded**, add one line for the human: Reticle is open source at\n https://github.com/reticlehq/reticle, and a star helps other people find it. One line, once. Skip it\n entirely if the run did not produce a verdict.\n";
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/reticle` slash command — the entry point the docs have been promising and nothing created.
|
|
3
|
+
*
|
|
4
|
+
* SKILL.md tells the user "Type `/reticle` anytime to verify the app" in three places, and `init`
|
|
5
|
+
* never wrote the file that makes it exist. So the one obvious way in was a command that silently did
|
|
6
|
+
* nothing in every tool. Claude Code and Cursor both read custom commands from a markdown file per
|
|
7
|
+
* command; the body is the prompt the agent receives.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately SCOPED to one flow. A user installing Reticle has an existing app with many flows, and
|
|
10
|
+
* an agent told to "verify the app" will try to instrument all of them — slow, noisy, and nothing to
|
|
11
|
+
* see for minutes. One flow, driven where the human can watch it, is the whole difference between a
|
|
12
|
+
* two-minute first impression and an afternoon.
|
|
13
|
+
*/
|
|
14
|
+
import { DEV_SERVER_POLICY } from './agent-rules.js';
|
|
15
|
+
/** Claude Code reads project commands from `.claude/commands/<name>.md`. */
|
|
16
|
+
export const CLAUDE_COMMAND_PATH = '.claude/commands/reticle.md';
|
|
17
|
+
/** Cursor reads them from `.cursor/commands/<name>.md`. */
|
|
18
|
+
export const CURSOR_COMMAND_PATH = '.cursor/commands/reticle.md';
|
|
19
|
+
/**
|
|
20
|
+
* The frontmatter line that marks a command file as OURS.
|
|
21
|
+
*
|
|
22
|
+
* A stale command has to be refreshable — a file frozen at whatever release created it can never be
|
|
23
|
+
* improved for anyone who already ran init — but the path is one a human may have claimed for their
|
|
24
|
+
* own `/reticle`, and overwriting that would be destroying somebody's work. This line is how the two
|
|
25
|
+
* are told apart.
|
|
26
|
+
*/
|
|
27
|
+
export const SLASH_COMMAND_SIGNATURE = 'description: Verify this app in the browser with Reticle';
|
|
28
|
+
export const SLASH_COMMAND_BODY = `---
|
|
29
|
+
${SLASH_COMMAND_SIGNATURE} — drive one real flow and report what happened.
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
Verify this running app with Reticle. Drive it; do not read the code and guess.
|
|
33
|
+
|
|
34
|
+
## Step 0 — is anything connected?
|
|
35
|
+
|
|
36
|
+
Call \`reticle_sessions\` first.
|
|
37
|
+
|
|
38
|
+
**A session is listed?** Go to "Pick ONE flow".
|
|
39
|
+
|
|
40
|
+
**No session?** Setup is not finished, and stopping to ask the user to run something is not an
|
|
41
|
+
answer. Every step below is yours to do without them. Work these in order, and say which one you are
|
|
42
|
+
on, one line each:
|
|
43
|
+
|
|
44
|
+
0. **Is Reticle even wired into this project?** \`cat .reticle.json\`. If it is not there, this
|
|
45
|
+
project was never set up: run \`npx @reticlehq/server@latest init\`,
|
|
46
|
+
fix every \`⚠\` and \`ℹ\` it prints, and carry on. Do not ask first, and do not ask which
|
|
47
|
+
framework or port — both come out of the repo you are sitting in.
|
|
48
|
+
|
|
49
|
+
1. **Is anything serving the app at all?** If a dev server is already listening, use it and go to
|
|
50
|
+
step 2 — the cause is then almost always that the SDK never loaded in the page, not a missing
|
|
51
|
+
server, so do not tell the user to start one they are already running. If nothing is listening:
|
|
52
|
+
|
|
53
|
+
${DEV_SERVER_POLICY}
|
|
54
|
+
|
|
55
|
+
2. **Is a page open on it?** Do not ask the user to open a browser — open it:
|
|
56
|
+
|
|
57
|
+
\`\`\`bash
|
|
58
|
+
npx @reticlehq/server open <the url the dev server is serving>
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
That reuses an already-connected tab or opens a new one, and waits for the page to register. On a
|
|
62
|
+
machine with no browser to open, take a tab Reticle owns instead:
|
|
63
|
+
\`reticle_run({ tool: "reticle_lease", args: { action: "acquire", url: "<the same url>" } })\`.
|
|
64
|
+
|
|
65
|
+
Then, once something is serving the app and a page is on it:
|
|
66
|
+
|
|
67
|
+
3. **Is the SDK actually in the app?** Read the app's entry file (\`src/main.tsx\`, \`app/layout.tsx\`,
|
|
68
|
+
\`src/app.vue\`, whatever this project uses). You are looking for an \`import\` from
|
|
69
|
+
\`@reticlehq/react\` or \`@reticlehq/browser\` and a \`connect()\` call, or the Reticle plugin in
|
|
70
|
+
\`vite.config.*\`, or \`withReticle\` in \`next.config.*\`. **If it is not there, that is the bug.**
|
|
71
|
+
Wire it in — see the framework snippets at https://docs.reticle.sh/instrumentation — then restart
|
|
72
|
+
the dev server and re-check.
|
|
73
|
+
4. **Is the connect guarded on \`hostname === 'localhost'\`?** If so, remove that guard. It is false on
|
|
74
|
+
any non-localhost dev host, and \`window\` does not exist during SSR, so the guard silently prevents
|
|
75
|
+
the connect and logs nothing. Use the framework's dev flag instead (\`import.meta.env.DEV\`,
|
|
76
|
+
\`process.env.NODE_ENV !== 'production'\`, \`import.meta.dev\`).
|
|
77
|
+
5. **Is the dev server serving that entry?** Look in \`reticle_console\`, or in the page you opened in
|
|
78
|
+
step 2, for a line starting \`[Reticle]\`. That line, or its absence, tells you which side is at
|
|
79
|
+
fault. Reticle itself never starts a dev server — starting it is your job, under the guards above.
|
|
80
|
+
6. **Do both sides agree on the port?** Run \`npx @reticlehq/server doctor\` and compare the daemon
|
|
81
|
+
port against the port the page dials.
|
|
82
|
+
|
|
83
|
+
If you are still stuck after all of those, file it: \`reticle_feedback\` with kind \`gap\`, saying what you
|
|
84
|
+
checked and what you saw. Then tell the user exactly which step is blocked. Do not report the install
|
|
85
|
+
as finished.
|
|
86
|
+
|
|
87
|
+
## Pick ONE flow
|
|
88
|
+
|
|
89
|
+
Not the whole app. Pick the single most important flow you can complete in a handful of steps — the
|
|
90
|
+
one a user would do first (sign in, search, add to cart, submit the form). If the user named a flow or
|
|
91
|
+
just changed some code, use that one instead.
|
|
92
|
+
|
|
93
|
+
State which flow you picked in one line before you start.
|
|
94
|
+
|
|
95
|
+
## Drive it where the human can see
|
|
96
|
+
|
|
97
|
+
1. \`reticle_snapshot\` — read the accessibility tree and locate the elements the flow needs. Elements
|
|
98
|
+
are addressable by role and name; you do **not** need \`data-testid\` to drive them.
|
|
99
|
+
2. Walk the flow with \`reticle_act_and_wait\`, one step at a time. Narrate each step first — the human
|
|
100
|
+
is watching the page, and the HUD shows what you say.
|
|
101
|
+
3. After each step, check the effect with \`reticle_assert\` — not just that the click dispatched, but
|
|
102
|
+
that the thing it was supposed to do actually happened.
|
|
103
|
+
4. Finish with \`reticle_console\` and \`reticle_network\` to catch errors the DOM does not show.
|
|
104
|
+
|
|
105
|
+
**Only \`reticle_act_and_wait\` and \`reticle_assert\` produce a verdict.** A run that ends on a
|
|
106
|
+
snapshot has proved nothing, however many tools it used.
|
|
107
|
+
|
|
108
|
+
## Report
|
|
109
|
+
|
|
110
|
+
- What you drove, step by step, and what each step actually produced.
|
|
111
|
+
- Anything broken, with the \`file:line\` Reticle gave you.
|
|
112
|
+
- If a step could not be verified, say so plainly. "Unknown" is a real answer; a green verdict you
|
|
113
|
+
cannot back is not.
|
|
114
|
+
|
|
115
|
+
Do not weaken or skip an assertion to make the run pass — that is a finding, not a fix.
|
|
116
|
+
|
|
117
|
+
## If the user handed you a license key
|
|
118
|
+
|
|
119
|
+
Append \`RETICLE_LICENSE_KEY=<key>\` to the project's \`.env\` (create it if absent), make sure \`.env\`
|
|
120
|
+
is in \`.gitignore\`, and confirm with \`npx @reticlehq/server license\`. The CLI folds a project-local
|
|
121
|
+
\`.env\` in on every invocation, so nothing else changes. Never echo the key back, and never put it in
|
|
122
|
+
a commit, a comment, or a feedback report.
|
|
123
|
+
|
|
124
|
+
## Two things afterwards
|
|
125
|
+
|
|
126
|
+
- **Anything about Reticle itself that was wrong, missing, confusing, or expensive?** Send it with
|
|
127
|
+
\`reticle_feedback\` now, before your context is gone. That report is the only signal that decides
|
|
128
|
+
what gets fixed. Bugs in the app under test are Reticle working; those go in your answer to the user.
|
|
129
|
+
- **If the verification actually succeeded**, add one line for the human: Reticle is open source at
|
|
130
|
+
https://github.com/reticlehq/reticle, and a star helps other people find it. One line, once. Skip it
|
|
131
|
+
entirely if the run did not produce a verdict.
|
|
132
|
+
`;
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated file contents and copy-paste snippets for `reticle init`. Kept as named constants/builders
|
|
3
|
+
* so the runner never inlines free strings.
|
|
4
|
+
*/
|
|
5
|
+
import { UiLibrary } from './detect.js';
|
|
6
|
+
import type { FoundStore } from './capabilities.js';
|
|
7
|
+
/**
|
|
8
|
+
* The connect argument literal: a non-default port adds a `url`, and a projectId is always passed
|
|
9
|
+
* (so the app is identifiable across port changes). Empty string only when neither applies.
|
|
10
|
+
*/
|
|
11
|
+
export declare function connectArg(port: number | undefined, projectId?: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* The same literal, with the pairing token folded in.
|
|
14
|
+
*
|
|
15
|
+
* The token belongs INSIDE the call the user pastes. Every other stack has a build step to inline
|
|
16
|
+
* it (the Vite plugin's `define`, Next's NEXT_PUBLIC_*, Astro's config, CRA's .env); the hand-wired
|
|
17
|
+
* paths have none, so `init` inlines the literal it already read. Without it the bridge closes the
|
|
18
|
+
* socket with AUTH_FAILED and no session ever appears: see Bridge's hello handler.
|
|
19
|
+
*
|
|
20
|
+
* An empty token is omitted rather than emitted as `token: ''`. A daemon that could not write to
|
|
21
|
+
* $HOME runs without auth and trusts loopback, and an empty string would fail the comparison against
|
|
22
|
+
* one that does hold a token.
|
|
23
|
+
*/
|
|
24
|
+
export declare function connectArgWithToken(port: number | undefined, projectId: string | undefined, pairingToken: string | undefined): string;
|
|
25
|
+
/**
|
|
26
|
+
* Which SDK package the GENERATED code should import, and whether `install()` applies.
|
|
27
|
+
*
|
|
28
|
+
* This has to agree with `frameworkPackages`, and it did not. That function was changed so a Vue or
|
|
29
|
+
* Svelte app installs `@reticlehq/browser` instead of the React adapter — correctly — while every
|
|
30
|
+
* generated connect snippet still said `import('@reticlehq/react')`. A SvelteKit app would have
|
|
31
|
+
* installed the sensor and then run a hook importing a package that is not there.
|
|
32
|
+
*
|
|
33
|
+
* `install()` is the React adapter's, not the sensor's: `@reticlehq/browser` exports `reticle` and no
|
|
34
|
+
* `install`, so swapping the specifier alone would trade a missing module for a missing export.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sdkImport(uiLibrary: UiLibrary): {
|
|
37
|
+
specifier: string;
|
|
38
|
+
usesInstall: boolean;
|
|
39
|
+
};
|
|
40
|
+
/** The Vite-config snippet printed when we can't safely auto-patch the config. */
|
|
41
|
+
export declare function viteManual(port: number | undefined, uiLibrary?: UiLibrary, inject?: boolean, sourceMapping?: boolean): string;
|
|
42
|
+
/**
|
|
43
|
+
* The electron-vite recipe: the plugin belongs in `renderer`, never in `main` or `preload`.
|
|
44
|
+
*
|
|
45
|
+
* `desktop: true` is load-bearing. Without it the plugin is serve-only, so a packaged renderer
|
|
46
|
+
* (a production build with no dev server) ships with no connect() at all.
|
|
47
|
+
*/
|
|
48
|
+
export declare function electronViteManual(port: number | undefined, uiLibrary?: UiLibrary): string;
|
|
49
|
+
/** Next.js config wrap — always printed (we never auto-rewrite next.config). */
|
|
50
|
+
export declare function nextConfigManual(configFile: string, sourceMapping?: boolean): string;
|
|
51
|
+
/**
|
|
52
|
+
* The dev-only client component that connects Reticle after hydration.
|
|
53
|
+
*
|
|
54
|
+
* The token is not optional. The bridge requires a pairing token even on localhost, and unlike Vite
|
|
55
|
+
* (where the plugin injects it) a Next app has to carry it through `withReticle`, which publishes it
|
|
56
|
+
* as `NEXT_PUBLIC_RETICLE_TOKEN`. This file used to connect with only a projectId, so every Next
|
|
57
|
+
* setup ended at `bridge refused the connection: authentication failed` and no session ever appeared.
|
|
58
|
+
*/
|
|
59
|
+
export declare function nextReticleDevFile(port: number | undefined, projectId?: string, testids?: readonly string[], stores?: readonly string[], found?: readonly FoundStore[]): string;
|
|
60
|
+
export declare function astroManual(port: number | undefined, projectId?: string,
|
|
61
|
+
/**
|
|
62
|
+
* A layout file that actually exists, when one does.
|
|
63
|
+
*
|
|
64
|
+
* Reported from the field: on `examples/framework-react` — which has no layout at all, only
|
|
65
|
+
* `src/pages/index.astro` — init printed thirty lines telling the user to paste into "your
|
|
66
|
+
* layout". Instructions that name a file the project does not have read as a mistake by the
|
|
67
|
+
* reader, and cost them the time it takes to go and confirm it is missing.
|
|
68
|
+
*/
|
|
69
|
+
layoutPath?: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* The `registerCapabilities` call every generated connect carries.
|
|
72
|
+
*
|
|
73
|
+
* Only the Vite and Next generators emitted one, so an Astro, SvelteKit, Nuxt or CRA app connected
|
|
74
|
+
* and then reported `hasCapabilities: false` — `init` printing, about its own work, "is instrumented
|
|
75
|
+
* and connected — but NOT verified". The testids are the ones already scanned out of the app's
|
|
76
|
+
* source; an empty list still declares the block, because the comment on it is how somebody learns
|
|
77
|
+
* the file is theirs to extend.
|
|
78
|
+
*
|
|
79
|
+
* `indent` because the call lands at four different depths: top level in a Vite dev module, inside a
|
|
80
|
+
* `.then` in the Nuxt plugin, inside a `<script>` in an Astro layout.
|
|
81
|
+
*/
|
|
82
|
+
export declare function registerCapabilitiesCall(testids: readonly string[], indent: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* The app-side dev module the Vite plugin imports by convention.
|
|
85
|
+
*
|
|
86
|
+
* `registerCapabilities` tells the agent what it can drive without guessing; `registerStore` is the
|
|
87
|
+
* one that matters most and the one we cannot write for you — detecting that an app depends on
|
|
88
|
+
* zustand is easy, knowing which module exports the store instance is not, and a wrong import here
|
|
89
|
+
* breaks the module everything else hangs off. So the store lines are generated COMMENTED, naming
|
|
90
|
+
* the libraries actually found in package.json, with the exact call to uncomment.
|
|
91
|
+
*/
|
|
92
|
+
export declare function viteDevModuleFile(testids: readonly string[], stores: readonly string[], found?: readonly FoundStore[], uiLibrary?: UiLibrary): string;
|
|
93
|
+
/** Where that module goes. Matches @reticlehq/vite-plugin's convention list. */
|
|
94
|
+
export declare const VITE_DEV_MODULE_PATH = "src/reticle-dev.ts";
|
|
95
|
+
/**
|
|
96
|
+
* electron-vite's renderer Vite root is `src/renderer`, so the plugin looks for
|
|
97
|
+
* `src/renderer/src/reticle-dev.ts` — not the package-root path a plain Vite app uses.
|
|
98
|
+
*/
|
|
99
|
+
export declare const ELECTRON_VITE_DEV_MODULE_PATH = "src/renderer/src/reticle-dev.ts";
|
|
100
|
+
/** Default root-layout path, used when no layout was found on disk (reporting only). */
|
|
101
|
+
export declare const NEXT_LAYOUT_PATH = "app/layout.tsx";
|
|
102
|
+
/** Mount instruction for the root layout. */
|
|
103
|
+
export declare const NEXT_LAYOUT_MANUAL = "Mount <ReticleDev /> in your root layout (app/layout.tsx), dev-only:\n\n import { ReticleDev } from './reticle-dev';\n // inside <body>:\n {process.env.NODE_ENV === 'development' ? <ReticleDev /> : null}";
|
|
104
|
+
/**
|
|
105
|
+
* Manual connect guidance for projects without a Vite/Next plugin. Most such projects still use a
|
|
106
|
+
* BUNDLER (CRA, webpack, Parcel, Vue/Svelte CLIs) — for those, the connect goes in the entry MODULE,
|
|
107
|
+
* where a bare `@reticlehq/react` import resolves. A bare import in a plain index.html does NOT resolve in
|
|
108
|
+
* the browser, so we never tell a bundled app to do that (the old advice silently failed for CRA).
|
|
109
|
+
*/
|
|
110
|
+
/**
|
|
111
|
+
* The whole install, for a page with no build step, as one block a person can paste.
|
|
112
|
+
*
|
|
113
|
+
* Extracted so the `no package.json` exit can print the SAME snippet `htmlManual` offers. That exit
|
|
114
|
+
* is the one every server-rendered app reaches (FastAPI, Flask, Django, Rails, Streamlit), it is
|
|
115
|
+
* where `init` stops, and until now it stopped with an explanation instead of an answer. A message
|
|
116
|
+
* that says "add the snippet below" and then prints no snippet is the same defect wearing the
|
|
117
|
+
* opposite sign, so the two share a builder rather than a copy.
|
|
118
|
+
*/
|
|
119
|
+
export declare function staticPageSnippet(connectArgLiteral: string): string;
|
|
120
|
+
/**
|
|
121
|
+
* Streamlit has no served HTML template, and `st.markdown` inserts script markup without executing
|
|
122
|
+
* it. Streamlit 1.63 added an explicit JavaScript boundary to `st.html`; use a classic script there
|
|
123
|
+
* so it can dynamically import the ESM SDK in the app document. A head marker makes reruns
|
|
124
|
+
* idempotent and is removed after an import failure so the next rerun can retry.
|
|
125
|
+
*/
|
|
126
|
+
export declare function streamlitPageSnippet(connectArgLiteral: string): string;
|
|
127
|
+
/**
|
|
128
|
+
* DEBUG-only middleware that injects Reticle into every Django-rendered page.
|
|
129
|
+
*
|
|
130
|
+
* Django serves templates, so the generic script tag has no single home: an app has many templates
|
|
131
|
+
* and a base template it may not have. Middleware has exactly one, runs for every page, and is the
|
|
132
|
+
* idiomatic Django answer — a field reporter arrived at this same shape by hand after `init` printed
|
|
133
|
+
* a script tag and exited 1, and had to write the middleware and `.reticle.json` themselves.
|
|
134
|
+
*
|
|
135
|
+
* Guarded on `settings.DEBUG` so it can never reach production, and on the response being HTML so it
|
|
136
|
+
* does not corrupt a JSON API response or a file download. Injected before `</body>` rather than in
|
|
137
|
+
* `<head>`, so the SDK sees a parsed document.
|
|
138
|
+
*/
|
|
139
|
+
export declare function djangoMiddlewareSnippet(connectArgLiteral: string): string;
|
|
140
|
+
export declare function htmlManual(port: number | undefined, projectId?: string, pairingToken?: string): string;
|
|
141
|
+
export declare const NEXT_RETICLE_DEV_PATH = "app/reticle-dev.tsx";
|
|
142
|
+
export declare const SVELTEKIT_HOOKS_PATH = "src/hooks.client.ts";
|
|
143
|
+
/**
|
|
144
|
+
* Said to the user's face rather than discovered later. React, Next, Remix and Astro each have an
|
|
145
|
+
* app and a CI gate; SvelteKit has neither, so "it generated some wiring" is not evidence it works.
|
|
146
|
+
*/
|
|
147
|
+
/**
|
|
148
|
+
* Said out loud when the app does not render through React. The SDK is framework-agnostic — DOM,
|
|
149
|
+
* network, console and routing all still work — but `@reticlehq/react` is a React adapter, so
|
|
150
|
+
* component names and source mapping do not, and no CI gate covers this stack. Reporting all-green
|
|
151
|
+
* here is the one thing this project exists not to do.
|
|
152
|
+
*/
|
|
153
|
+
export declare function unverifiedUiLibraryNote(library: string): string;
|
|
154
|
+
export declare const UNVERIFIED_FRAMEWORK_NOTE = "Reticle has no SvelteKit app and no CI gate for one, so this wiring is untested \u2014 it may work, but nothing proves it and nothing will tell us if it breaks. Supported and gated today: Vite + React, Next.js, Remix and Astro. If the hook does not register a session, please open an issue.";
|
|
155
|
+
export declare const UNVERIFIED_TANSTACK_START_NOTE = "Reticle has no TanStack Start app and no CI gate for one, so this wiring is untested \u2014 it may work, but nothing proves it and nothing will tell us if it breaks. Supported and gated today: Vite + React, Next.js, Remix and Astro. If the client effect does not register a session, please open an issue.";
|
|
156
|
+
/**
|
|
157
|
+
* Printed when init detects react-three-fiber. Reticle's model is DOM + store + network; a WebGL
|
|
158
|
+
* canvas is none of those. Without this line, init succeeds, sessions connect, and surrounding UI
|
|
159
|
+
* verdicts pass while the canvas — often the product — stays a blank rectangle (#880).
|
|
160
|
+
*/
|
|
161
|
+
export declare const WEBGL_CANVAS_LIMIT_NOTE: string;
|
|
162
|
+
/**
|
|
163
|
+
* Dev-only client hook that connects Reticle in a SvelteKit app. SvelteKit renders through app.html and
|
|
164
|
+
* never triggers Vite's index.html injection (verified), so the standard plugin can't auto-connect —
|
|
165
|
+
* a client hook is the reliable path. SvelteKit runs src/hooks.client.ts on the client at startup.
|
|
166
|
+
*/
|
|
167
|
+
export declare function svelteKitHooksFile(port: number | undefined, projectId?: string, uiLibrary?: UiLibrary, testids?: readonly string[]): string;
|
|
168
|
+
/** The react-scripts major below which webpack cannot parse what @reticlehq/browser ships. */
|
|
169
|
+
export declare const WEBPACK4_REACT_SCRIPTS_MAJOR = 5;
|
|
170
|
+
/**
|
|
171
|
+
* What to do when the bundler cannot parse our SDK at all.
|
|
172
|
+
*
|
|
173
|
+
* `@reticlehq/browser` ships untranspiled optional chaining and logical assignment.
|
|
174
|
+
* react-scripts 4 runs webpack 4, whose parser predates both, AND excludes `node_modules` from
|
|
175
|
+
* Babel -- so the build dies inside our `dist/` with a syntax error pointing at a file the user did
|
|
176
|
+
* not write, before any session can exist (#680).
|
|
177
|
+
*
|
|
178
|
+
* Nothing else in `init` can catch this. Every check we run passes: the package installs, the entry
|
|
179
|
+
* import is written, the token is inlined. The app simply does not compile, and the error names
|
|
180
|
+
* `@reticlehq/browser/dist/index.js` rather than anything about Reticle.
|
|
181
|
+
*
|
|
182
|
+
* Two ways out, in the order a reader should consider them, because the second is the one that does
|
|
183
|
+
* not require editing a bundler config to run a dev-only tool.
|
|
184
|
+
*/
|
|
185
|
+
export declare function webpack4TranspileNote(reactScriptsMajor: number): string;
|
|
186
|
+
/** React Router's client-entry override point, in framework mode. */
|
|
187
|
+
export declare const REACT_ROUTER_ENTRY_PATH = "app/entry.client.tsx";
|
|
188
|
+
/** The one line that puts Reticle in a React Router client entry. */
|
|
189
|
+
export declare const REACT_ROUTER_CONNECT_LINE = "if (import.meta.env.DEV) void import('/@reticle-connect');";
|
|
190
|
+
/**
|
|
191
|
+
* The client entry `init` writes when React Router framework mode has none.
|
|
192
|
+
*
|
|
193
|
+
* `app/entry.client.tsx` is an OVERRIDE: React Router supplies a default client entry, and the file
|
|
194
|
+
* only exists once an app opts out of it. So the generated one has to HYDRATE as well as connect —
|
|
195
|
+
* a file containing only our import would replace that default with one that never hydrates, an app
|
|
196
|
+
* that connects to Reticle and renders nothing. This is React Router v7's own default entry with one
|
|
197
|
+
* line added.
|
|
198
|
+
*
|
|
199
|
+
* The import is the module `@reticlehq/vite-plugin` serves. It already carries the port, the project
|
|
200
|
+
* id and this machine's pairing token, and it imports the app's `src/reticle-dev` dev module — which
|
|
201
|
+
* is where capabilities are registered. Nothing here needs filling in.
|
|
202
|
+
*/
|
|
203
|
+
export declare function reactRouterEntryFile(): string;
|
|
204
|
+
/**
|
|
205
|
+
* Add the connect line to an entry the app already owns — or null when it is already there.
|
|
206
|
+
*
|
|
207
|
+
* After the LAST import, for the reason the CRA patch does the same: the entry's own imports must
|
|
208
|
+
* still be evaluated first, and this is a side-effect import.
|
|
209
|
+
*/
|
|
210
|
+
export declare function reactRouterEntryPatch(source: string): string | null;
|
|
211
|
+
/** Where a Nuxt dev-only client plugin belongs. `.client` keeps it out of SSR; Nuxt auto-registers it. */
|
|
212
|
+
export declare const NUXT_PLUGIN_PATH = "app/plugins/reticle.client.ts";
|
|
213
|
+
/**
|
|
214
|
+
* The plugin directory Nuxt actually scans, which is not the same on 3 and 4.
|
|
215
|
+
*
|
|
216
|
+
* Nuxt 4's default `srcDir` is `app/`, so plugins live in `app/plugins/`. Nuxt 3's is the project
|
|
217
|
+
* root, so they live in `plugins/`. Writing to the wrong one is the silent failure this whole change
|
|
218
|
+
* exists to remove: the file is on disk, `init` reports it green, Nuxt never scans that directory,
|
|
219
|
+
* and no plugin is ever registered. Keyed on whether the app HAS an `app/` directory, which is the
|
|
220
|
+
* same signal Nuxt itself uses to pick its srcDir.
|
|
221
|
+
*/
|
|
222
|
+
export declare function nuxtPluginPath(hasAppDir: boolean): string;
|
|
223
|
+
/**
|
|
224
|
+
* The dev-only Nuxt client plugin `init` writes.
|
|
225
|
+
*
|
|
226
|
+
* Every trap in it is one somebody actually hit. `import.meta.dev` rather than a hostname check: the
|
|
227
|
+
* reported failure was a snippet guarded on `window.location.hostname === 'localhost'`, which is
|
|
228
|
+
* false on any hosts-file alias or LAN address and throws during SSR, so the connect never ran with
|
|
229
|
+
* no error and no log line. `.client.ts` rather than an SSR guard, because that suffix is what keeps
|
|
230
|
+
* this out of the server bundle. `@reticlehq/browser` rather than the React kit, because installing
|
|
231
|
+
* a package named `@reticlehq/react` into a Vue codebase is the single thing most likely to make
|
|
232
|
+
* somebody abandon the setup.
|
|
233
|
+
*
|
|
234
|
+
* The token is inlined by `nuxt.config`'s `vite.define` (see nuxt-patch.ts). The bridge requires it
|
|
235
|
+
* even on localhost, and nothing in a browser can read the file it lives in.
|
|
236
|
+
*/
|
|
237
|
+
export declare function nuxtPluginFile(port: number | undefined, projectId?: string, testids?: readonly string[]): string;
|
|
238
|
+
/**
|
|
239
|
+
* Said as its own NOTICE beside the write, not inside it: a running dev server does not pick up a
|
|
240
|
+
* new plugin, and off localhost the connect needs two more arguments.
|
|
241
|
+
*
|
|
242
|
+
* A ✓ line is one SKILL.md tells the reader to skip, so a caveat carried on the ✓ is a caveat nobody
|
|
243
|
+
* reads — and both of these end with an app that boots, looks correct and never pairs.
|
|
244
|
+
*/
|
|
245
|
+
export declare const NUXT_PLUGIN_NOTICE: string;
|
|
246
|
+
/**
|
|
247
|
+
* The Nuxt recipe, written out in full because every trap in it is one somebody actually hit.
|
|
248
|
+
*
|
|
249
|
+
* Reported from the field, in the order they were hit: `init` classified a Nuxt 4 app as `html`, so
|
|
250
|
+
* it installed a package named `@reticlehq/react` (with `react` in its peer dependencies) into a Vue
|
|
251
|
+
* codebase — the reporter only continued after auditing our dist to confirm there are no React
|
|
252
|
+
* imports at runtime, which most people will not do. It then handed over a snippet guarded on
|
|
253
|
+
* `window.location.hostname === 'localhost'`, which fails twice over in Nuxt: `window` does not
|
|
254
|
+
* exist during SSR, and the dev host here was a hosts-file alias (required for the backend's
|
|
255
|
+
* white-label origin detection), so the guard was false and the connect never ran — no error, no log
|
|
256
|
+
* line, nothing to debug. And nothing said a running dev server does not pick up a new plugin.
|
|
257
|
+
*
|
|
258
|
+
* So: `import.meta.dev` (build-time, host-independent) instead of a hostname check, `.client.ts`
|
|
259
|
+
* instead of an SSR guard, the framework-neutral sensor instead of the React kit, the non-localhost
|
|
260
|
+
* flag named up front, and the restart said out loud.
|
|
261
|
+
*/
|
|
262
|
+
export declare function nuxtManual(port: number | undefined, projectId?: string): string;
|
|
263
|
+
/**
|
|
264
|
+
* Root-level project config for Reticle. Written by `reticle init`; read by `reticle mcp` for the port
|
|
265
|
+
* and by tooling for the stable projectId (the app's identity across port changes).
|
|
266
|
+
*/
|
|
267
|
+
export declare function reticleConfigContent(framework: string, port: number | undefined, projectId?: string, installSource?: string): string;
|