@reticlehq/server 3.10.0 → 3.10.1
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/dist/command/setup/init/init-runtime.js +37 -2
- package/docs/cli/init.mdx +2 -2
- package/docs/deploy-checks.md +1 -1
- package/docs/skill.md +1 -1
- package/docs/troubleshooting.mdx +29 -0
- package/package.json +8 -11
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
-
import { InitConfirmation, OnboardingPhase, OnboardingStop, RETICLE_DEFAULT_PORT, } from '@reticlehq/core';
|
|
10
|
+
import { InitConfirmation, InitStop, OnboardingPhase, OnboardingStop, RETICLE_DEFAULT_PORT, } from '@reticlehq/core';
|
|
11
11
|
import { COMMUNITY_HINT, FEEDBACK_HINT, Framework, InitFailure, } from '@reticlehq/init';
|
|
12
12
|
import { confirmInstall, nodeConfirmDeps } from '../terminal/confirm.js';
|
|
13
13
|
import { writeLicenseKey } from '../license-key.js';
|
|
@@ -85,6 +85,11 @@ function printRelaunch(parsed, io, cwd) {
|
|
|
85
85
|
}).message);
|
|
86
86
|
io.print('');
|
|
87
87
|
}
|
|
88
|
+
/** The dev-server stops caused by the machine, not the app: the files init wrote are right. */
|
|
89
|
+
const WIRED_WHEN_STOPPED_AT = new Set([
|
|
90
|
+
InitStop.PORT_BUSY,
|
|
91
|
+
InitStop.SPLIT_LOOPBACK,
|
|
92
|
+
]);
|
|
88
93
|
export async function continueAfterInit(parsed, result, io, cwd,
|
|
89
94
|
/** init's ending once the connection is proved: coverage and the agent prompt. See `FirstFlowPort`. */
|
|
90
95
|
firstFlow, agentsBlock) {
|
|
@@ -256,6 +261,14 @@ firstFlow, agentsBlock) {
|
|
|
256
261
|
: { pendingViteConfig: context.pendingViteConfig }),
|
|
257
262
|
}, (line) => io.print(line))
|
|
258
263
|
.then(async (outcome) => {
|
|
264
|
+
// The files are written before the app starts. When the app could not be reached for a reason
|
|
265
|
+
// of the machine, not of the app (its port was taken, or it answered on one loopback address
|
|
266
|
+
// and not the other), the project is wired and not confirmed yet: not a failed install.
|
|
267
|
+
// A dev server that exits, hangs or does not exist, and a failure to connect, still fail.
|
|
268
|
+
const wiredNotStarted = !outcome.ok &&
|
|
269
|
+
outcome.reachedPhase === SetupPhase.DEV_SERVER &&
|
|
270
|
+
undefined !== outcome.stop &&
|
|
271
|
+
WIRED_WHEN_STOPPED_AT.has(outcome.stop);
|
|
259
272
|
if (result.outcome !== undefined) {
|
|
260
273
|
const init = {
|
|
261
274
|
...result.outcome,
|
|
@@ -265,6 +278,14 @@ firstFlow, agentsBlock) {
|
|
|
265
278
|
delete init.reason;
|
|
266
279
|
init.confirmation = InitConfirmation.CONNECTED;
|
|
267
280
|
}
|
|
281
|
+
else if (wiredNotStarted) {
|
|
282
|
+
init.ok = true;
|
|
283
|
+
delete init.reason;
|
|
284
|
+
init.confirmation = InitConfirmation.DEV_SERVER_NOT_STARTED;
|
|
285
|
+
if (outcome.stop !== undefined) {
|
|
286
|
+
init.stop = outcome.stop;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
268
289
|
else {
|
|
269
290
|
// A failed startup does not establish whether a daemon or instrumented page exists.
|
|
270
291
|
// Keep the watcher's no_daemon/no_session/no_page classifications for observed facts.
|
|
@@ -281,7 +302,11 @@ firstFlow, agentsBlock) {
|
|
|
281
302
|
}
|
|
282
303
|
// One object, so an agent reads a result instead of interpreting a report.
|
|
283
304
|
if (true === parsed.json) {
|
|
284
|
-
|
|
305
|
+
const answer = wiredNotStarted ? { ...outcome, ok: true, confirmed: false } : outcome;
|
|
306
|
+
process.stdout.write(`${JSON.stringify(answer, null, 2)}\n`);
|
|
307
|
+
if (wiredNotStarted) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
285
310
|
if (!outcome.ok) {
|
|
286
311
|
stop();
|
|
287
312
|
}
|
|
@@ -334,6 +359,16 @@ firstFlow, agentsBlock) {
|
|
|
334
359
|
io.print(COMMUNITY_HINT);
|
|
335
360
|
return;
|
|
336
361
|
}
|
|
362
|
+
if (wiredNotStarted) {
|
|
363
|
+
io.print('✓ Reticle is wired into this app. Its dev server did not start, so the connection is not ' +
|
|
364
|
+
'confirmed yet. To confirm it:');
|
|
365
|
+
for (const [i, step] of outcome.fallback.entries()) {
|
|
366
|
+
io.print(` ${String(i + 1)}. ${step}`);
|
|
367
|
+
}
|
|
368
|
+
io.print(` ${String(outcome.fallback.length + 1)}. Run \`reticle status\`: it lists the app when it connects.`);
|
|
369
|
+
ask();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
337
372
|
// A run that produced no verdict did not succeed, and the exit code is the one place a caller
|
|
338
373
|
// reads that without parsing anything.
|
|
339
374
|
io.print('⚠ setup did not finish. To carry on from here:');
|
package/docs/cli/init.mdx
CHANGED
|
@@ -122,8 +122,8 @@ In the two captures above, the punctuation that separates the two halves of the
|
|
|
122
122
|
|
|
123
123
|
| Code | Meaning |
|
|
124
124
|
| --- | --- |
|
|
125
|
-
| `0` | The app connected. Steps marked `⚠` still need a hand, and do not change the code |
|
|
126
|
-
| `1` |
|
|
125
|
+
| `0` | The app connected. Or the files are written and the machine kept the dev server from starting (its port was taken, or it answered on one loopback address only): init prints the steps to confirm the connection (`--json` answers `"confirmed": false`). Steps marked `⚠` still need a hand, and do not change the code |
|
|
126
|
+
| `1` | The dev server exited, hung or does not exist, a running app did not connect, init failed, an unknown flag was passed, or several apps were found and none was chosen |
|
|
127
127
|
|
|
128
128
|
An unknown flag is rejected by name: `reticle init --bogus` prints `unknown argument '--bogus'`, then the short usage (`reticle --help`), and exits `1`.
|
|
129
129
|
|
package/docs/deploy-checks.md
CHANGED
|
@@ -70,7 +70,7 @@ jobs:
|
|
|
70
70
|
runs-on: ubuntu-latest
|
|
71
71
|
steps:
|
|
72
72
|
- uses: actions/checkout@v4
|
|
73
|
-
- uses: reticlehq/reticle/action@v3.10.
|
|
73
|
+
- uses: reticlehq/reticle/action@v3.10.1
|
|
74
74
|
with:
|
|
75
75
|
api-key: ${{ secrets.RETICLE_API_KEY }}
|
|
76
76
|
# Only for a Vercel preview behind Deployment Protection.
|
package/docs/skill.md
CHANGED
|
@@ -3,7 +3,7 @@ name: reticle-docs
|
|
|
3
3
|
description: Install, instrument and verify this running web app from the inside (DOM, network, routing, console and framework state) instead of screenshots or guessing. Drives one real flow end to end and returns a verdict with the file:line to fix. Use when the user asks to set up or install Reticle, when a user-facing change needs proving before you call it done, when a test passes but the UI is broken, or when the user types /reticle.
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
|
-
version: 3.10.
|
|
6
|
+
version: 3.10.1
|
|
7
7
|
homepage: https://docs.reticle.sh
|
|
8
8
|
repository: https://github.com/reticlehq/reticle
|
|
9
9
|
internal: true
|
package/docs/troubleshooting.mdx
CHANGED
|
@@ -11,6 +11,35 @@ Reticle is a verification layer that runs a dev-only SDK inside your running web
|
|
|
11
11
|
|
|
12
12
|
Most of these were hit while writing these docs. The diagnostics quoted are real output.
|
|
13
13
|
|
|
14
|
+
## Quick fixes
|
|
15
|
+
|
|
16
|
+
| What you see | Why | Fix |
|
|
17
|
+
| --- | --- | --- |
|
|
18
|
+
| Agent says the `reticle_*` tools do not exist | It read its tool list before Reticle was installed | Restart the agent once. Mid-conversation: `reticle init --relaunch` prints the resume command |
|
|
19
|
+
| "no browser session connected" | The dev server was already running when `init` edited the build config, so it serves a bundle without the SDK | Restart the dev server and hard-reload the tab |
|
|
20
|
+
| Browser console: `[Reticle] this page could not open a websocket to …` | The app and Reticle disagree on the port | `RETICLE_PORT=4400 npm run dev` (Vite plugin), `reticle({ port: 4400 })` in `vite.config`, or `reticle.connect({ url: 'ws://localhost:4400/reticle' })` by hand |
|
|
21
|
+
| `init` stops with "Several apps found" | A monorepo | Rerun with the `reticle init --app <dir>` line it printed |
|
|
22
|
+
| Codex does not see the tools | The `codex` command was not on PATH, so the installer could not run `codex mcp add` | `codex mcp add reticle -- npx @reticlehq/server mcp`, or add the block from [Manual install](/install-manual#codex-cli) to `~/.codex/config.toml` |
|
|
23
|
+
| `reticle: command not found` | npm's global bin is not on your PATH | `export PATH="$(npm prefix -g)/bin:$PATH"`, or use `npx @reticlehq/server …` |
|
|
24
|
+
| Anything else | | `reticle doctor` checks the browser, the background service and the port in one go, and names the fix |
|
|
25
|
+
|
|
26
|
+
Still stuck? `reticle feedback "what happened"` reaches us directly and prints exactly what it sends. Or ask in [Discord](https://discord.gg/BwAbzv9ZRz).
|
|
27
|
+
|
|
28
|
+
<details>
|
|
29
|
+
<summary><b>Installing with an AI agent? The rules it should follow</b></summary>
|
|
30
|
+
|
|
31
|
+
<br />
|
|
32
|
+
|
|
33
|
+
The full agent guide is [SKILL.md](https://github.com/reticlehq/reticle/blob/main/SKILL.md). These are the rules that matter most during install:
|
|
34
|
+
|
|
35
|
+
- `init` changes the user's files. Run it only when the user asked to set up Reticle, or agreed when you offered. Run it in the app's folder. Use `reticle init --json`, so you read one object instead of parsing text. Add `--app <dir>` in a monorepo, and `--env KEY=VALUE` for anything the app needs to start.
|
|
36
|
+
- If the dev server was already running when `init` ran, restart it and reload the tab. Until you do, the app serves a bundle without the SDK.
|
|
37
|
+
- Run `reticle connect` only if the user asked for the dashboard. A person must approve the sign-in in a browser.
|
|
38
|
+
- If the `reticle_*` tools are not in your client, ask the user to run the installer and restart the client. Then stop. If the tools were registered while you were running, `reticle init --relaunch` prints the command that resumes this conversation with them loaded.
|
|
39
|
+
- A session listed means the SDK reached the page. Setup is finished when the first run returns a verdict.
|
|
40
|
+
- `unknown` is not a pass. Report it as "cannot tell", with the reason Reticle gives.
|
|
41
|
+
- Stuck? Run `reticle doctor` and report what it says. To report a problem with Reticle, run `reticle feedback --agent --kind bug "…"`.
|
|
42
|
+
|
|
14
43
|
## Start here
|
|
15
44
|
|
|
16
45
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reticlehq/server",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.1",
|
|
4
4
|
"mcpName": "io.github.reticlehq/reticle",
|
|
5
5
|
"description": "Reticle CLI, bridge and MCP server: a coding agent drives your running web app from the inside and gets a verdict with evidence, for change verification, access control, accessibility, performance and SEO checks.",
|
|
6
6
|
"type": "module",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"@modelcontextprotocol/sdk": "^1.32.2",
|
|
24
24
|
"ws": "^8.22.1",
|
|
25
25
|
"zod": "^4.6.6",
|
|
26
|
-
"@reticlehq/browser": "3.10.
|
|
27
|
-
"@reticlehq/init": "3.10.
|
|
28
|
-
"
|
|
29
|
-
"@reticlehq/engine": "3.10.
|
|
30
|
-
"
|
|
26
|
+
"@reticlehq/browser": "3.10.1",
|
|
27
|
+
"@reticlehq/init": "3.10.1",
|
|
28
|
+
"open-verification": "1.1.0",
|
|
29
|
+
"@reticlehq/engine": "3.10.1",
|
|
30
|
+
"@reticlehq/core": "3.10.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/pngjs": "^6.0.5",
|
|
@@ -65,11 +65,8 @@
|
|
|
65
65
|
"cli"
|
|
66
66
|
],
|
|
67
67
|
"reticle": {
|
|
68
|
-
"changelog": "3.10.
|
|
69
|
-
"breakingChanges": [
|
|
70
|
-
"The commands kill, login, link, project, whoami, push, regression, share, issues and memory are removed. Each prints the command that replaces it and exits 1. See MIGRATION.md.",
|
|
71
|
-
"The MCP tools reticle_explore and reticle_replay left the tool surface. Use reticle_look { action: \"page\", mode: \"interactive\" } and reticle_record { action: \"replay\" }."
|
|
72
|
-
]
|
|
68
|
+
"changelog": "3.10.1 fixes reticle init on a busy machine. When the dev server could not start because its port was taken, or the app answered on one loopback address only, init reported a failed install although the project was wired. Now it says Reticle is wired, prints the steps to confirm the connection, and exits 0.",
|
|
69
|
+
"breakingChanges": []
|
|
73
70
|
},
|
|
74
71
|
"publishConfig": {
|
|
75
72
|
"access": "public"
|