oh-my-opencode 4.14.0 → 4.14.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/.agents/skills/codex-qa/references/isolation.md +1 -1
- package/README.md +1 -1
- package/dist/cli/doctor/framework/types.d.ts +2 -0
- package/dist/cli/index.js +149 -1426
- package/dist/cli-node/index.js +149 -1426
- package/dist/index.js +4255 -714
- package/dist/plugin/native-skills.d.ts +9 -0
- package/dist/plugin/system-transform.d.ts +1 -1
- package/dist/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/dist/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/dist/skills/lcx-doctor/SKILL.md +48 -13
- package/dist/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/dist/skills/lcx-report-bug/SKILL.md +44 -13
- package/dist/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/dist/skills/visual-qa/SKILL.md +5 -5
- package/dist/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/dist/skills/visual-qa/scripts/cli.test.ts +7 -2
- package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +10 -2
- package/dist/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/dist/tools/delegate-task/skill-resolver.d.ts +1 -0
- package/dist/tools/delegate-task/types.d.ts +2 -0
- package/dist/tools/skill/types.d.ts +1 -0
- package/package.json +26 -13
- package/packages/git-bash-mcp/dist/cli.js +2 -0
- package/packages/lsp-daemon/dist/cli.js +15 -4
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +1 -0
- package/packages/lsp-daemon/dist/ensure-daemon.js +9 -3
- package/packages/lsp-daemon/dist/index.js +15 -4
- package/packages/lsp-daemon/dist/paths.d.ts +1 -0
- package/packages/lsp-daemon/dist/paths.js +6 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +4 -7
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +123 -10
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +123 -10
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +126 -9
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +141 -0
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +90 -25
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.d.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +56 -0
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +2 -5
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +65 -0
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +6 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +8 -106
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -17
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +17 -5
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +63 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +80 -50
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +4 -12
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +7 -33
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +4 -12
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/sample-quality-gate.json +7 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +3 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-doc.test.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +7 -6
- package/packages/omo-codex/plugin/package-lock.json +16 -56
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +48 -13
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +44 -13
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +17 -5
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +63 -1
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +80 -50
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +4 -4
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +5 -5
- package/packages/omo-codex/plugin/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/packages/omo-codex/plugin/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +38 -2
- package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +12 -11
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +99 -1
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +62 -8
- package/packages/omo-codex/plugin/test/node-install-surface.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +102 -0
- package/packages/omo-codex/plugin/test/teammode-safety-fixture.mjs +41 -1
- package/packages/omo-codex/plugin/test/teammode-safety.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +6 -0
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +28 -0
- package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +43 -3
- package/packages/omo-codex/scripts/install-delegated-command.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +103 -28
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +21 -2
- package/packages/omo-codex/scripts/install-local.test.mjs +0 -1
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/lcx-doctor/SKILL.md +48 -13
- package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +44 -13
- package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/visual-qa/SKILL.md +5 -5
- package/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/packages/shared-skills/skills/visual-qa/scripts/cli.test.ts +7 -2
- package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +10 -2
- package/packages/shared-skills/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/dist/cli/sparkshell-appserver-websocket.d.ts +0 -4
- package/dist/cli/sparkshell-appserver.d.ts +0 -16
- package/dist/cli/sparkshell-condense.d.ts +0 -10
- package/dist/cli/sparkshell-parse.d.ts +0 -24
- package/dist/cli/sparkshell-session-context.d.ts +0 -20
- package/dist/cli/sparkshell-spark.d.ts +0 -23
- package/dist/cli/sparkshell.d.ts +0 -33
- package/dist/shared/sparkshell-awareness.d.ts +0 -5
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +0 -106
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +0 -355
|
@@ -33,28 +33,59 @@ Create or prepare a GitHub issue or PR that includes:
|
|
|
33
33
|
|
|
34
34
|
1. Read the user's bug report and identify the affected surface: LazyCodex installer, Codex plugin, skill, hook, MCP, CLI alias, GitHub marketplace sync, or web/docs.
|
|
35
35
|
2. Invoke `$omo:debugging` for the investigation. If Codex exposes only unqualified skill names in the current session, invoke `$debugging` and state that it is the OMO debugging skill.
|
|
36
|
-
3. Materialize the latest LazyCodex and upstream Codex sources under
|
|
36
|
+
3. Materialize the latest LazyCodex and upstream Codex sources under `LAZYCODEX_SOURCE_ROOT="${LAZYCODEX_SOURCE_ROOT:-${TMPDIR:-/tmp}/lazycodex-sources}"` before deciding ownership. Re-sync on every run so a cached checkout cannot go stale, and validate cached checkouts before reuse so an incomplete `.git` directory cannot produce wrong routing and dead line references:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
+
LAZYCODEX_SOURCE_ROOT="${LAZYCODEX_SOURCE_ROOT:-${TMPDIR:-/tmp}/lazycodex-sources}"
|
|
40
|
+
mkdir -p "$LAZYCODEX_SOURCE_ROOT"
|
|
41
|
+
|
|
42
|
+
valid_source_checkout() {
|
|
43
|
+
DEST="$1"
|
|
44
|
+
git -C "$DEST" rev-parse --is-inside-work-tree >/dev/null 2>&1 &&
|
|
45
|
+
git -C "$DEST" config --get remote.origin.url >/dev/null 2>&1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
recover_corrupt_source_checkout() {
|
|
49
|
+
DEST="$1"
|
|
50
|
+
if [ -e "$DEST" ] && ! valid_source_checkout "$DEST"; then
|
|
51
|
+
QUARANTINED="$DEST.corrupt.$(date +%Y%m%d%H%M%S)"
|
|
52
|
+
mv "$DEST" "$QUARANTINED"
|
|
53
|
+
echo "Moved corrupt source cache $DEST to $QUARANTINED" >&2
|
|
54
|
+
fi
|
|
55
|
+
}
|
|
56
|
+
|
|
39
57
|
sync_latest_source() {
|
|
40
58
|
REPO="$1"; DEST="$2"
|
|
41
|
-
|
|
59
|
+
recover_corrupt_source_checkout "$DEST"
|
|
60
|
+
if [ ! -d "$DEST" ]; then
|
|
42
61
|
gh repo clone "$REPO" "$DEST" -- --depth=1 \
|
|
43
62
|
|| git clone --depth=1 "https://github.com/$REPO" "$DEST"
|
|
44
63
|
fi
|
|
64
|
+
if ! valid_source_checkout "$DEST"; then
|
|
65
|
+
echo "Source cache $DEST is not a usable git checkout after clone" >&2
|
|
66
|
+
return 1
|
|
67
|
+
fi
|
|
68
|
+
git -C "$DEST" remote set-url origin "https://github.com/$REPO.git" >/dev/null 2>&1 || true
|
|
45
69
|
DEFAULT_BRANCH="$(git -C "$DEST" remote show origin | sed -n '/HEAD branch/s/.*: //p')"
|
|
70
|
+
if [ -z "$DEFAULT_BRANCH" ]; then
|
|
71
|
+
DEFAULT_BRANCH="$(git -C "$DEST" symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's#^origin/##')"
|
|
72
|
+
fi
|
|
73
|
+
if [ -z "$DEFAULT_BRANCH" ]; then
|
|
74
|
+
echo "Could not determine default branch for $REPO in $DEST" >&2
|
|
75
|
+
return 1
|
|
76
|
+
fi
|
|
46
77
|
git -C "$DEST" fetch --depth=1 origin "$DEFAULT_BRANCH"
|
|
47
78
|
git -C "$DEST" checkout -B "$DEFAULT_BRANCH" FETCH_HEAD
|
|
48
79
|
}
|
|
49
|
-
sync_latest_source code-yeongyu/lazycodex /
|
|
50
|
-
sync_latest_source openai/codex /
|
|
80
|
+
sync_latest_source code-yeongyu/lazycodex "$LAZYCODEX_SOURCE_ROOT/lazycodex-source"
|
|
81
|
+
sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/openai-codex-source"
|
|
51
82
|
```
|
|
52
83
|
4. Follow the debugging skill far enough to gather runtime evidence:
|
|
53
84
|
- form at least three plausible hypotheses
|
|
54
85
|
- run the smallest reproduction that exercises the real surface
|
|
55
86
|
- confirm the root cause by observing the failing state
|
|
56
87
|
- identify the minimal fix path or maintainer action
|
|
57
|
-
5. Compare runtime evidence with both
|
|
88
|
+
5. Compare runtime evidence with both `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/openai-codex-source` before choosing the target repo. Cite exact files, commands, logs, or source paths that support the routing decision.
|
|
58
89
|
6. Choose the target repo:
|
|
59
90
|
- Use `code-yeongyu/lazycodex` when the bug is in LazyCodex integration, distribution, bundled plugin code, skills, hooks, MCP wiring, installer behavior, aliases, marketplace sync, docs, or any behavior that disappears in clean upstream Codex.
|
|
60
91
|
- Use `openai/codex` when the bug reproduces in clean upstream Codex without LazyCodex, or the failing behavior comes from Codex CLI core, plugin API contracts, sandboxing, approvals, config loading, or built-in tool behavior.
|
|
@@ -110,8 +141,8 @@ Write the issue body in English and keep it direct:
|
|
|
110
141
|
## Repository Decision
|
|
111
142
|
- Target repository:
|
|
112
143
|
- Why this belongs there:
|
|
113
|
-
- LazyCodex evidence (runtime +
|
|
114
|
-
- Upstream Codex source evidence from
|
|
144
|
+
- LazyCodex evidence (runtime + `$LAZYCODEX_SOURCE_ROOT/lazycodex-source`):
|
|
145
|
+
- Upstream Codex source evidence from `$LAZYCODEX_SOURCE_ROOT/openai-codex-source`:
|
|
115
146
|
|
|
116
147
|
## Reproduction
|
|
117
148
|
1. [Exact command or UI action]
|
|
@@ -154,8 +185,8 @@ Use this only when a PR is the right artifact, which is only ever for `openai/co
|
|
|
154
185
|
## Repository Decision
|
|
155
186
|
- Target repository:
|
|
156
187
|
- Why this belongs there:
|
|
157
|
-
- LazyCodex evidence (runtime +
|
|
158
|
-
- Upstream Codex source evidence from
|
|
188
|
+
- LazyCodex evidence (runtime + `$LAZYCODEX_SOURCE_ROOT/lazycodex-source`):
|
|
189
|
+
- Upstream Codex source evidence from `$LAZYCODEX_SOURCE_ROOT/openai-codex-source`:
|
|
159
190
|
|
|
160
191
|
## Root Cause
|
|
161
192
|
[Confirmed cause. Cite runtime evidence and source paths.]
|
|
@@ -178,7 +209,7 @@ Tag: lazycodex-generated
|
|
|
178
209
|
Prefer `gh`:
|
|
179
210
|
|
|
180
211
|
```bash
|
|
181
|
-
ISSUE_BODY="
|
|
212
|
+
ISSUE_BODY="${TMPDIR:-/tmp}/lcx-report-bug-$(date +%Y%m%d-%H%M%S).md"
|
|
182
213
|
$EDITOR "$ISSUE_BODY"
|
|
183
214
|
gh issue create --repo "$TARGET_REPO" --title "<clear title>" "${LABEL_ARGS[@]}" --body-file "$ISSUE_BODY"
|
|
184
215
|
```
|
|
@@ -188,7 +219,7 @@ If `$EDITOR` is not usable, write the file with the available file-editing tool,
|
|
|
188
219
|
For an existing issue:
|
|
189
220
|
|
|
190
221
|
```bash
|
|
191
|
-
COMMENT_BODY="
|
|
222
|
+
COMMENT_BODY="${TMPDIR:-/tmp}/lcx-report-bug-comment-$(date +%Y%m%d-%H%M%S).md"
|
|
192
223
|
gh issue comment "<issue-number>" --repo "$TARGET_REPO" --body-file "$COMMENT_BODY"
|
|
193
224
|
if [ "${#LABEL_ARGS[@]}" -gt 0 ]; then
|
|
194
225
|
gh issue edit "<issue-number>" --repo "$TARGET_REPO" --add-label lazycodex-generated
|
|
@@ -198,7 +229,7 @@ fi
|
|
|
198
229
|
For a PR from a branch pushed to a fork — `openai/codex` only, never `code-yeongyu/lazycodex`:
|
|
199
230
|
|
|
200
231
|
```bash
|
|
201
|
-
PR_BODY="
|
|
232
|
+
PR_BODY="${TMPDIR:-/tmp}/lcx-report-bug-pr-$(date +%Y%m%d-%H%M%S).md"
|
|
202
233
|
gh pr create --repo openai/codex --title "<clear title>" "${LABEL_ARGS[@]}" --body-file "$PR_BODY"
|
|
203
234
|
```
|
|
204
235
|
|
|
@@ -232,6 +263,6 @@ Do not file:
|
|
|
232
263
|
- a vague issue without reproduction steps
|
|
233
264
|
- an issue that claims a root cause not supported by runtime evidence
|
|
234
265
|
- a duplicate when commenting on an existing issue is enough
|
|
235
|
-
- an issue without checking the latest
|
|
266
|
+
- an issue without checking the latest `$LAZYCODEX_SOURCE_ROOT/lazycodex-source` and `$LAZYCODEX_SOURCE_ROOT/openai-codex-source` checkouts
|
|
236
267
|
- a LazyCodex issue when the bug is proven to reproduce in clean upstream Codex
|
|
237
268
|
- a fix PR without a concrete branch, implemented fix, and verification result
|
|
@@ -8,4 +8,4 @@ interface:
|
|
|
8
8
|
- "omo-codex bug"
|
|
9
9
|
- "openai codex bug"
|
|
10
10
|
- "codex upstream issue"
|
|
11
|
-
default_prompt: "Use $lcx-report-bug to investigate this LazyCodex or Codex bug, compare LazyCodex evidence with
|
|
11
|
+
default_prompt: "Use $lcx-report-bug to investigate this LazyCodex or Codex bug, compare LazyCodex evidence with sources under LAZYCODEX_SOURCE_ROOT or ${TMPDIR:-/tmp}/lazycodex-sources, choose the correct GitHub repo, and file an issue (or, for openai/codex only, a PR — never a PR on code-yeongyu/lazycodex) with reproduction, root cause, fix guidance, and the lazycodex-generated label and footer."
|
|
@@ -13,7 +13,7 @@ Verify a rendered UI against intent using objective script evidence plus two par
|
|
|
13
13
|
- Use when output must match a mock, a baseline, or a stated design intent; when you suspect a regression; when CJK (Korean/Japanese/Chinese) text may clip, misalign, or wrap awkwardly; when a claimed design system might actually be a flat image; when a terminal layout may overflow or its borders may break.
|
|
14
14
|
- Skip when there is no rendered surface (pure backend or library logic with no visual or terminal output). For broad post-implementation review use review-work; this skill is the visual specialist.
|
|
15
15
|
|
|
16
|
-
In the commands below, `$SKILL_DIR` is this skill's own directory (the folder containing this SKILL.md). The bundled
|
|
16
|
+
In the commands below, `$SKILL_DIR` is this skill's own directory (the folder containing this SKILL.md). The bundled Node evidence CLI lives at `scripts/visual-qa.mjs` inside it; the TypeScript source in `scripts/cli.ts` is for development.
|
|
17
17
|
|
|
18
18
|
## Step 1 - Detect the surface
|
|
19
19
|
|
|
@@ -44,11 +44,11 @@ Every gate runs on captures produced AFTER the last edit to the rendered source.
|
|
|
44
44
|
### Web
|
|
45
45
|
|
|
46
46
|
1. Capture a REFERENCE image: the user's mock/target, generated page snapshot, Figma export, source-site capture, or known-good baseline. Save as PNG. If the user provided overview text or annotations, save them next to the image and treat them as part of the reference packet.
|
|
47
|
-
2. Capture the ACTUAL rendered screenshot at the same viewport size. In Codex, when `browser:control-in-app-browser` is available and the page does not need an authenticated user browser session, use that Browser plugin first for navigation, page state inspection, and screenshots. If it is unavailable or lacks the needed capture action, use the project's configured browser tooling (the playwright, agent-browser, or dev-browser skill). Save as PNG. If none is configured or available, install [agent-browser](https://github.com/vercel-labs/agent-browser) (`
|
|
47
|
+
2. Capture the ACTUAL rendered screenshot at the same viewport size. In Codex, when `browser:control-in-app-browser` is available and the page does not need an authenticated user browser session, use that Browser plugin first for navigation, page state inspection, and screenshots. If it is unavailable or lacks the needed capture action, use the project's configured browser tooling (the playwright, agent-browser, or dev-browser skill). Save as PNG. If none is configured or available, install [agent-browser](https://github.com/vercel-labs/agent-browser) (`npm install -g agent-browser && agent-browser install`) and capture with it — see `$SKILL_DIR/references/agent-browser-setup.md` for the full setup, including how to shoot a fixed-viewport screenshot.
|
|
48
48
|
3. Run the diff and keep the JSON:
|
|
49
49
|
|
|
50
50
|
```
|
|
51
|
-
|
|
51
|
+
node "$SKILL_DIR/scripts/visual-qa.mjs" image-diff <reference.png> <actual.png>
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
Key fields: `dimensionsMatch`, `diffRatio` (0..1), `similarityScore` (0..100), `alphaChannelIntact`, `hotspots[]` (grid regions ranked by `diffRatio`).
|
|
@@ -82,7 +82,7 @@ metadata with cleanup receipt.
|
|
|
82
82
|
3. Run the check with the REAL terminal width and keep the JSON:
|
|
83
83
|
|
|
84
84
|
```
|
|
85
|
-
|
|
85
|
+
node "$SKILL_DIR/scripts/visual-qa.mjs" tui-check capture.txt --cols <N>
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
Key fields: `maxWidth`, `overflowLines[]`, `borderMisaligned`, `wideCharColumns[]`, `hasAnsi`.
|
|
@@ -245,7 +245,7 @@ Run this step IN ADDITION to Steps 1-4 when the original user task has a concret
|
|
|
245
245
|
1. Pixel-perfect design-compare subagent (visual oracle). Dispatch a focused, read-only design-compare reviewer (recommend `gpt-5.5` with medium reasoning). It must crop/zoom BOTH the reference (target / Figma export / source-site screenshot / generated page snapshot) and the ACTUAL screenshot into matching regions and read them **pixel-by-pixel** - header, nav, each card, spacing, type ramp, color tokens - not at a glance. It must also compare the overview text or annotations against the rendered content and DOM text. Anchor every claim with the bundled tool:
|
|
246
246
|
|
|
247
247
|
```
|
|
248
|
-
|
|
248
|
+
node "$SKILL_DIR/scripts/visual-qa.mjs" image-diff <reference.png> <actual.png>
|
|
249
249
|
```
|
|
250
250
|
|
|
251
251
|
It judges whether layout geometry, spacing, design tokens (color, type, radius, shadow), and the design itself are identical to the target, region by region. Anything off by more than rounding is a finding.
|
|
@@ -11,11 +11,12 @@ Repo: https://github.com/vercel-labs/agent-browser
|
|
|
11
11
|
## Install
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
|
|
14
|
+
npm install -g agent-browser && agent-browser install
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
`
|
|
18
|
-
managed browser it drives.
|
|
17
|
+
`npm install -g agent-browser` installs the CLI globally; `agent-browser install` downloads the
|
|
18
|
+
managed browser it drives. If Bun is already available, `bun add -g agent-browser && agent-browser install`
|
|
19
|
+
is equivalent, but npm is the default because LazyCodex/Codex installations do not require Bun.
|
|
19
20
|
|
|
20
21
|
Confirm it is ready and discover the current flags:
|
|
21
22
|
|
|
@@ -36,7 +37,7 @@ agent-browser screenshot actual.png # add --full for full-page, --screensho
|
|
|
36
37
|
Then feed the PNG into the diff exactly as in Step 2:
|
|
37
38
|
|
|
38
39
|
```
|
|
39
|
-
|
|
40
|
+
node "$SKILL_DIR/scripts/visual-qa.mjs" image-diff <reference.png> actual.png
|
|
40
41
|
```
|
|
41
42
|
|
|
42
43
|
Match the viewport numbers to whatever the reference/mock was captured at; mismatched
|
|
@@ -55,15 +55,20 @@ describe("run dispatch", () => {
|
|
|
55
55
|
})
|
|
56
56
|
|
|
57
57
|
describe("cli entry", () => {
|
|
58
|
-
test("#given the
|
|
58
|
+
test("#given the Node bundle is spawned for image-diff without Bun on PATH #when it runs #then it prints JSON and exits zero", () => {
|
|
59
59
|
// given
|
|
60
60
|
const dir = tempDir()
|
|
61
61
|
const reference = join(dir, "reference.png")
|
|
62
62
|
const actual = join(dir, "actual.png")
|
|
63
63
|
writeFileSync(reference, encodeRgbaPng(2, 2, solidRgba(2, 2, [0, 0, 0, 255])))
|
|
64
64
|
writeFileSync(actual, encodeRgbaPng(2, 2, solidRgba(2, 2, [255, 255, 255, 255])))
|
|
65
|
+
const nodePath = Bun.which("node")
|
|
66
|
+
if (nodePath === null) throw new Error("node not found on PATH")
|
|
65
67
|
// when
|
|
66
|
-
const proc = Bun.spawnSync(
|
|
68
|
+
const proc = Bun.spawnSync({
|
|
69
|
+
cmd: [nodePath, join(import.meta.dir, "visual-qa.mjs"), "image-diff", reference, actual],
|
|
70
|
+
env: { ...process.env, PATH: "/usr/bin:/bin" },
|
|
71
|
+
})
|
|
67
72
|
// then
|
|
68
73
|
expect(proc.exitCode).toBe(0)
|
|
69
74
|
const parsed: Record<string, unknown> = JSON.parse(proc.stdout.toString())
|
|
@@ -98,7 +98,7 @@ describe("visual-qa skill prompt contract", () => {
|
|
|
98
98
|
const web = sectionBetween(fixture.text, "### Web", "### TUI")
|
|
99
99
|
|
|
100
100
|
expect(web, fixture.label).toContain("agent-browser")
|
|
101
|
-
expect(fixture.text, fixture.label).toContain("
|
|
101
|
+
expect(fixture.text, fixture.label).toContain("npm install -g agent-browser")
|
|
102
102
|
expect(fixture.text, fixture.label).toContain("https://github.com/vercel-labs/agent-browser")
|
|
103
103
|
expect(fixture.text, fixture.label).toContain("references/agent-browser-setup.md")
|
|
104
104
|
}
|
|
@@ -108,12 +108,20 @@ describe("visual-qa skill prompt contract", () => {
|
|
|
108
108
|
expect(existsSync(referencesPath)).toBe(true)
|
|
109
109
|
const doc = readFileSync(referencesPath, "utf8")
|
|
110
110
|
|
|
111
|
-
expect(doc).toContain("
|
|
111
|
+
expect(doc).toContain("npm install -g agent-browser")
|
|
112
112
|
expect(doc).toContain("agent-browser install")
|
|
113
113
|
expect(doc).toContain("https://github.com/vercel-labs/agent-browser")
|
|
114
114
|
expect(doc).toContain("agent-browser --help")
|
|
115
115
|
})
|
|
116
116
|
|
|
117
|
+
test("#given the visual QA evidence commands #when documented #then they use the Node bundle, not a Bun-only TypeScript launcher", () => {
|
|
118
|
+
for (const fixture of fixtures()) {
|
|
119
|
+
expect(fixture.text, fixture.label).toContain('node "$SKILL_DIR/scripts/visual-qa.mjs" image-diff')
|
|
120
|
+
expect(fixture.text, fixture.label).toContain('node "$SKILL_DIR/scripts/visual-qa.mjs" tui-check')
|
|
121
|
+
expect(fixture.text, fixture.label).not.toContain('bun "$SKILL_DIR/scripts/cli.ts"')
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
117
125
|
test("#given a concrete visual target #when in reference-fidelity mode #then dual pixel + code-fidelity verification loops until both pass", () => {
|
|
118
126
|
for (const fixture of fixtures()) {
|
|
119
127
|
const cloneMode = sectionBetween(fixture.text, "## Step 5", "## Reference evidence is not the verdict")
|