@penpair/core 0.2.0 → 0.3.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.
Files changed (125) hide show
  1. package/dist/adapters.js +58 -11
  2. package/dist/approvals.js +143 -29
  3. package/dist/atomic-output.js +9 -4
  4. package/dist/audit-rules.js +345 -79
  5. package/dist/backup-note.js +29 -8
  6. package/dist/baseline-coverage.js +169 -35
  7. package/dist/baselines-config.js +119 -29
  8. package/dist/baselines.js +280 -57
  9. package/dist/cli-arguments.js +18 -6
  10. package/dist/cli-main.js +1645 -392
  11. package/dist/client.d.ts +5 -2
  12. package/dist/client.js +127 -28
  13. package/dist/command-result.js +341 -52
  14. package/dist/coordination.js +91 -29
  15. package/dist/credentials.js +57 -13
  16. package/dist/deep-check.js +56 -12
  17. package/dist/design-spec.js +189 -49
  18. package/dist/endpoint.js +102 -34
  19. package/dist/export.js +86 -18
  20. package/dist/file-archive.js +33 -7
  21. package/dist/file-guard.js +29 -11
  22. package/dist/formats.js +215 -14
  23. package/dist/index.d.ts +8 -7
  24. package/dist/index.js +8 -7
  25. package/dist/inspection.d.ts +1 -1
  26. package/dist/inspection.js +378 -65
  27. package/dist/instance/config-schema.js +400 -41
  28. package/dist/instance/config.js +101 -30
  29. package/dist/instance/connect.js +151 -44
  30. package/dist/instance/connection.d.ts +26 -5
  31. package/dist/instance/connection.js +194 -21
  32. package/dist/instance/gitignore.js +5 -2
  33. package/dist/instance/init.js +32 -7
  34. package/dist/instance/runner.js +32 -10
  35. package/dist/instance/setup.js +46 -13
  36. package/dist/instance/tty.js +26 -8
  37. package/dist/journal.d.ts +10 -0
  38. package/dist/journal.js +212 -49
  39. package/dist/kit-smoke.js +82 -20
  40. package/dist/kit-source.js +10 -40
  41. package/dist/kit.js +102 -34
  42. package/dist/layout-policy.d.ts +2 -0
  43. package/dist/layout-policy.js +86 -0
  44. package/dist/layout.d.ts +7 -1
  45. package/dist/layout.js +27 -70
  46. package/dist/live-smoke.js +13 -4
  47. package/dist/local-profile.js +2 -1
  48. package/dist/mcp-server.js +360 -47
  49. package/dist/native-api.js +47 -11
  50. package/dist/onboard.js +33 -7
  51. package/dist/operation.d.ts +2 -2
  52. package/dist/operation.js +279 -69
  53. package/dist/page-session.d.ts +23 -0
  54. package/dist/page-session.js +142 -0
  55. package/dist/png.js +18 -3
  56. package/dist/portable-tokens.js +254 -57
  57. package/dist/probe.d.ts +1 -1
  58. package/dist/probe.js +48 -11
  59. package/dist/project-input.js +24 -10
  60. package/dist/project-snippets.js +18 -6
  61. package/dist/project-status.js +133 -24
  62. package/dist/registry.js +217 -60
  63. package/dist/run-file.js +129 -30
  64. package/dist/shots.js +108 -26
  65. package/dist/skill-check-entry.d.ts +17 -0
  66. package/dist/skill-check-entry.js +89 -0
  67. package/dist/skill-check-instructions.d.ts +7 -0
  68. package/dist/skill-check-instructions.js +39 -0
  69. package/dist/skill-check.d.ts +15 -0
  70. package/dist/skill-check.js +36 -0
  71. package/dist/skill-file.d.ts +2 -0
  72. package/dist/skill-file.js +31 -0
  73. package/dist/skill-instructions.d.ts +4 -0
  74. package/dist/skill-instructions.js +97 -22
  75. package/dist/skill-metadata.d.ts +8 -0
  76. package/dist/skill-metadata.js +52 -0
  77. package/dist/skill-routing.d.ts +2 -0
  78. package/dist/skill-routing.js +36 -0
  79. package/dist/skills.js +131 -41
  80. package/dist/snippet.js +27 -7
  81. package/dist/snippets/read.js +8 -2
  82. package/dist/structure-snapshot.d.ts +12 -0
  83. package/dist/structure-snapshot.js +439 -85
  84. package/dist/token-edit.js +219 -64
  85. package/dist/token-projection.d.ts +56 -0
  86. package/dist/token-projection.js +286 -0
  87. package/dist/tokens-diff.js +125 -32
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/package.json +3 -2
  91. package/skills/design-judgment/SKILL.md +1 -1
  92. package/skills/design-judgment/agents/openai.yaml +6 -0
  93. package/skills/penpair-design/SKILL.md +14 -1
  94. package/skills/penpair-design/agents/openai.yaml +6 -0
  95. package/skills/penpair-design/references/penpot-plugin-gotchas.md +2 -2
  96. package/skills/penpair-design/references/project-facts.md +2 -0
  97. package/skills/penpair-handoff/SKILL.md +14 -1
  98. package/skills/penpair-handoff/agents/openai.yaml +6 -0
  99. package/skills/penpair-handoff/references/comparison-companion.md +16 -0
  100. package/skills/penpair-handoff/references/handoff-flow.md +2 -0
  101. package/skills/penpair-recipes/SKILL.md +13 -1
  102. package/skills/penpair-recipes/agents/openai.yaml +6 -0
  103. package/skills/penpair-recipes/assets/visual-checkpoint.md +48 -0
  104. package/skills/penpair-recipes/references/visual-checkpoint.md +37 -0
  105. package/skills/penpair-setup/SKILL.md +9 -3
  106. package/skills/penpair-setup/agents/openai.yaml +6 -0
  107. package/skills/penpair-verify/SKILL.md +49 -0
  108. package/skills/penpair-verify/agents/openai.yaml +6 -0
  109. package/skills/penpair-verify/references/browser-evidence.md +33 -0
  110. package/dist/cli.d.ts +0 -2
  111. package/dist/cli.js +0 -3
  112. package/dist/docker/lifecycle.d.ts +0 -96
  113. package/dist/docker/lifecycle.js +0 -273
  114. package/dist/docker/secrets.d.ts +0 -11
  115. package/dist/docker/secrets.js +0 -38
  116. package/dist/docker/template.d.ts +0 -8
  117. package/dist/docker/template.js +0 -158
  118. package/dist/docker-profile.d.ts +0 -114
  119. package/dist/docker-profile.js +0 -18
  120. package/dist/instance/lifecycle.d.ts +0 -129
  121. package/dist/instance/lifecycle.js +0 -336
  122. package/dist/instance/secrets.d.ts +0 -11
  123. package/dist/instance/secrets.js +0 -38
  124. package/dist/instance/template.d.ts +0 -8
  125. package/dist/instance/template.js +0 -158
@@ -0,0 +1,16 @@
1
+ # Frontend comparison companion
2
+
3
+ Recommend `@penpair/reflection-check` when a task moves from a design into frontend implementation and visual verification. It connects approved design cases to a real project browser provider; that provider handles route, theme, state, fixtures, fonts, screenshot capture and comparison.
4
+
5
+ 1. Inspect the project's installed command/core versions and `adapters` configuration. Offer the companion at the same reviewed version, using the project's package manager and dependency location. Merge its config entry while preserving other adapters. Do not install a second command package.
6
+ 2. Follow the [companion setup guide](https://github.com/niklas-westman/penpair/blob/main/docs/adapters.md#check-the-frontend-against-the-design). The project needs a pinned file, approved baseline provenance and explicit viewport/theme/state/fixture/font cases. Existing human approval cannot be invented or carried over to changed artifacts.
7
+ 3. Prepare an explicit case-to-setup mapping and a trusted project module exporting `async runCase(test)`. The module must perform actual browser setup, readback, capture and comparison using the project's tools. A stub or copied input labels cannot establish browser verification.
8
+ 4. Run `penpair reflection plan --map FILE`, then `penpair reflection check --map FILE --provider FILE` once ready. Inspect the images and report pending cases, measured drift and unknowns. Preserve the baseline bytes.
9
+ 5. Report separate readiness stages: installed, registered, references approved, cases mapped, provider configured, browser verified and owner reviewed. Missing stages are explicit pending work. Never describe installing the adapter as supplying a browser or a complete frontend integration.
10
+
11
+ The package reference defines the current provider evidence contract. For a
12
+ design-only task, defer implementation setup until that work is in scope. Use
13
+ `penpair-verify` when installed for the real browser comparison and repair loop.
14
+ The final comparison verdict still requires owner review.
15
+
16
+ The command package ships a real-browser starter at `node_modules/@penpair/web/examples/reflection-browser/`. Supply project-owned setup and independent state hooks; read its README for font, scroll/sticky, pointer and crop requirements. Keep browsers pinned in the adopting project.
@@ -1,5 +1,7 @@
1
1
  # Evidence and review
2
2
 
3
+ For frontend checks, first follow [the recommended comparison companion](comparison-companion.md). Report adapter installation separately from complete browser/provider evidence.
4
+
3
5
  Use `spec --page PAGE --frame ID` for live evidence or `spec --from INSPECTION --map MAP --out FILE` for an offline handoff. `spec check` regenerates against the supplied inspection/map and detects manual edits or changed provenance. Offline success establishes freshness against those inputs, not the current live file or an unchanged PNG.
4
6
 
5
7
  A schema-1 map declares exact `libraryId`, `componentId`, identifier `codeComponent`, literal scalar `props` and `textProps` pointing at exact descendant text node IDs. Familiar names and equal scalar values are insufficient for automatic semantic mapping. Missing references remain unknown. A single captured viewport/state cannot establish responsive behavior, application transitions, focus order, keyboard support or accessible roles.
@@ -1,16 +1,28 @@
1
1
  ---
2
2
  name: penpair-recipes
3
- description: Build or update a Penpot page through reviewed penpair recipes, active tokens and an idempotent script, then verify the resulting objects and export.
3
+ description: Build a Penpot screen or create loading, empty or error variants from an approved frame using the existing library and tokens. Use for design construction and state variants in Penpot; frontend implementation belongs to penpair-handoff.
4
4
  ---
5
5
 
6
6
  # Page recipes
7
7
 
8
8
  Use the existing project library and declared tokens as inputs. Work within the owner's authorized design scope; retain unresolved choices for review.
9
9
 
10
+
11
+ Before building a page, record a short composition decision: the primary user task, one chosen existing reference, visual hierarchy and useful context, responsive behavior and focus order. Build one small representative frame first; critique its hierarchy, density and missing context before expanding themes/states/devices. This is a design decision and critique, not owner approval.
12
+
13
+ For a substantial state variant or screen family, read
14
+ [visual-checkpoint.md](references/visual-checkpoint.md) and create a project-owned
15
+ evidence record. Carry the approved image/inspection, preserved regions and
16
+ intentional deviations into the plan. Keep expansion pending until the first
17
+ candidate has actual comparison evidence and its blocking findings are resolved.
18
+ Do not infer critique from a passing mechanical audit.
19
+
10
20
  1. **Target.** Read the project's design facts and `penpair doctor --json`. Confirm the pinned file and exact page/frame IDs. Done when the connected target matches the authorized target and required APIs are observed.
11
21
  2. **Vocabulary.** Inspect the actual token catalog, theme selection and existing components. Select explicit token names/types and component IDs. Done when every recipe input resolves or is listed as an explicit missing dependency. Equal computed values alone establish candidate matches.
12
22
  3. **Preview.** Read [build-flow.md](references/build-flow.md) for file declarations, helper order and partial-root ownership. Prepare an idempotent operation with positive independent readback. Run inspection first. Done when source preconditions and the exact changed objects are reviewable.
13
23
  4. **Build.** Apply within the existing authorization, set values/fonts before bindings and await helper flush. On uncertainty, retain the run ID and inspect actual state before explicit recovery. Done when independent geometry, text and binding evidence matches the intended output.
14
24
  5. **Judge.** Export until stable, inspect the image twice, and audit the complete relevant scope. Done when visual findings and unknowns are reported separately from mechanical verification. Name frames with the project's page/state/device convention.
15
25
 
26
+ When frontend implementation follows, recommend the comparison companion described in the [adapter guide](https://github.com/niklas-westman/penpair/blob/main/docs/adapters.md#check-the-frontend-against-the-design) and the installed handoff skill. Retain intended viewport/theme/state/fixture information so the project can map approved designs to actual browser cases. A rendered design is not yet a verified implementation.
27
+
16
28
  Report **Changed**, **Validated**, **Risks**, with exact object/artifact IDs and any owner decisions still needed. The kit smoke test is scratch work requiring its own authorized target. Native library expansion stays gated on demonstrated instance-override preservation.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "Penpair Recipes"
3
+ short_description: "Build screens and approved-design variants"
4
+ default_prompt: "Use $penpair-recipes to create a state variant from the approved Penpot frame and critique one representative candidate."
5
+ policy:
6
+ allow_implicit_invocation: true
@@ -0,0 +1,48 @@
1
+ # Visual evidence checkpoint
2
+
3
+ Copy into the project's review folder and replace every pending field with actual
4
+ evidence or a reason it remains unknown. This is an unfilled template, not proof
5
+ of an inspection, comparison or approval.
6
+
7
+ - Work / case ID: pending
8
+ - Mode: design variant / frontend comparison (select one)
9
+ - Current status: pending
10
+ - Next action and responsible person/agent: pending
11
+
12
+ ## Source and intended change
13
+
14
+ - Authorized scope and user task: pending
15
+ - Source image path and complete inspection path: pending
16
+ - File / page / frame IDs and captured revision: pending
17
+ - Approval record / exact approved case and reference hash, or missing approval: pending
18
+ - Source image actually inspected; observed hierarchy/density: pending
19
+ - Existing component identities and relevant token evidence: pending
20
+
21
+ | Region | Preserve or change | Evidence / reason for deviation |
22
+ | --- | --- | --- |
23
+ | pending | pending | pending |
24
+
25
+ ## Representative result
26
+
27
+ - Candidate frame / implementation route: pending
28
+ - Viewport, theme, state, fixture and expected fonts: pending
29
+ - Stable candidate image and independent readback: pending
30
+ - Source/candidate comparison view and regions inspected: pending
31
+ - Provider/setup/version and observed browser state (frontend only): pending
32
+ - Comparison result / drift / screenshot hash (frontend only): pending
33
+ - Mechanical audits and their limits: pending
34
+
35
+ | Location | User impact | Observed evidence | Fix / explicit decision | Rerun case and result |
36
+ | --- | --- | --- | --- | --- |
37
+ | pending | pending | pending | pending | pending |
38
+
39
+ ## Decision and continuation
40
+
41
+ - [ ] Source and candidate evidence exist and were inspected.
42
+ - [ ] Preserved regions and intentional deviations were compared.
43
+ - [ ] Blocking findings are resolved; remaining unknowns are explicit.
44
+ - Expansion readiness: pending (with reason)
45
+ - Behavior/accessibility checks: not assessed
46
+ - Owner approval: pending; record exact words/artifact only if actually supplied
47
+ - Attempts / tooling effort / revised approach if blocked: pending
48
+ - Next case or action, with exact artifact paths: pending
@@ -0,0 +1,37 @@
1
+ # Comparative evidence checkpoint
2
+
3
+ For a new screen family or a substantial variant of an approved design, copy the
4
+ [checkpoint template](../assets/visual-checkpoint.md) into the project's review
5
+ folder before building. Use the project's existing report format if it retains
6
+ the same evidence. The copy is project-owned; never keep completed records inside
7
+ an installed skill folder, where `skills install --force` may refresh templates.
8
+
9
+ Record one representative case first. Link the actual approved image and complete
10
+ inspection with file/page/frame identity, revision, approval/case identity and
11
+ relevant component/token evidence. State which regions keep their layout,
12
+ hierarchy, density, type scale and native instances, and which intentionally
13
+ change. A sentence naming a reference does not establish that its image was seen.
14
+ If the task has no approved reference, record that limitation and the chosen
15
+ design direction; do not manufacture provenance or turn a draft into a baseline.
16
+
17
+ Before expanding devices/themes/states, export the candidate until stable, look
18
+ at source and candidate and record the consequential findings. Use a side-by-side
19
+ view at comparable scale; compare preserved regions separately from intentionally
20
+ changed content. Whole-page pixel equality is inappropriate for different data
21
+ states. A clean token/overflow audit and a generated screenshot do not establish
22
+ visual critique. Recomposition is allowed within the task's scope when its reason
23
+ and deviations are explicit; owner acceptance stays separate.
24
+
25
+ Expansion is ready only when the representative candidate has real source and
26
+ candidate evidence, a recorded critique and resolved blocking findings. Missing
27
+ images, unobserved instance behavior or failed readback remain pending. If
28
+ repeated failures or substantial tooling work prevent this result, report the
29
+ current evidence, effort and revised approach before adding a renderer or a larger
30
+ case matrix. Preserve source/library objects and stop ambiguous write retries.
31
+
32
+ For frontend work, carry the case record through handoff and browser comparison:
33
+ retain the route, viewport, theme, state, fixture, fonts, setup/provider identity,
34
+ baseline hash, observed screenshot and rerun result. Use `penpair-verify` when
35
+ installed. Design-to-design critique does not satisfy frontend verification, and
36
+ browser comparison does not approve a new design. Another agent should be able to
37
+ continue from the record's next action without guessing which artifact was judged.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: penpair-setup
3
- description: Set up penpair in a project and connect it to a Penpot, on the web (the default) or in Docker on this computer. Use when a project has no penpair.config.json, when `penpair doctor` reports a failure, when the user asks to install, start, connect, repair or move their Penpot connection, or when an agent is told "set up penpair". Do not use for editing a Penpot file (penpair-design) or deciding how a screen looks (design-judgment).
3
+ description: Install Penpair or connect and repair a project's Penpot setup, including a failing doctor check, suspended plugin or missing configuration. Use for connection and setup work; use penpair-design to edit designs and design-judgment to choose their composition.
4
4
  metadata:
5
5
  version: "0.1.0"
6
6
  scope: setup and connection
@@ -14,11 +14,15 @@ Two ways to run Penpot, one way to connect. **Web** (design.penpot.app, or a tea
14
14
 
15
15
  ## The key never passes through you
16
16
 
17
+ For an existing installation, use its local command and reviewed version
18
+ (`pnpm exec penpair` in pnpm projects) in place of the first-use `npx` examples
19
+ below. Preserve its chosen command package and current profile.
20
+
17
21
  The MCP key is the person's password to their Penpot. Keep it out of chat, logs, commands and commits. The person pastes it themselves into a prompt that hides it (`penpair connect`), or pipes it from their clipboard (`pbpaste | npx @penpair/web connect`). Your shell cannot answer a hidden prompt, so hand that one step to the person with the exact words below.
18
22
 
19
23
  ## Steps
20
24
 
21
- 1. **Look.** If `penpair.config.json` exists, run `npx @penpair/web doctor --json` and read its versioned envelope: `data.ok`, then `data.checks`. Done when you can name the first failing check, or say all pass. If all pass, stop here and say so.
25
+ 1. **Look.** If `penpair.config.json` exists, run `npx @penpair/web doctor --json` and read its versioned envelope: `data.ok`, then `data.checks`. Done when you can name the first failing check, or say all pass. If all pass, skip connection repair and check the companion recommendations in step 7 before reporting setup complete.
22
26
  2. **Choose where Penpot runs.** Recommend web. Choose Docker when the person asks for offline work, data that stays on this computer, or a disposable instance. Ask once, in one sentence, and take the answer. Done when the choice is stated. The decision table and what is checked: [references/web-or-docker.md](references/web-or-docker.md).
23
27
  3. **Initialise.**
24
28
  - Web: `npx @penpair/web init --external https://design.penpot.app --gitignore` (a team's own Penpot: its address instead).
@@ -39,7 +43,9 @@ The MCP key is the person's password to their Penpot. Keep it out of chat, logs,
39
43
  | editor and plugin: not connected or suspended | The tab is asleep or the plugin is not connected. Do step 4.4 again; keep the tab in front. |
40
44
  | key file: git would commit it | Add `.env.local` to `.gitignore`; `penpair connect` does it. |
41
45
 
42
- 6. **Install the rules.** Run `npx @penpair/web skills install`, add the printed rows to the project's agent guide, then fill in `.skills/penpair-design/references/project-facts.md` with the person (the Penpot file, token sets, naming, who approves). Done when that file has no `<...>` placeholders left.
46
+ 6. **Install the rules.** Use the installed local command when available (`pnpm exec penpair` in pnpm projects). Preview `penpair skills install --agents AGENTS.md --dry-run`, then apply the reviewed update to the selected instruction file. Preserve project customizations and fill in the installed `penpair-design/references/project-facts.md` (file pin, token sets, naming, who approves); use the destination printed by the installer. Run `penpair skills check --json` for Codex discovery/routing diagnostics, selecting `--only` for intentional partial installs. A passing file check does not prove a session loaded or correctly applied a skill. Done when required project facts and diagnostics are ready, or their missing evidence is reported explicitly.
47
+
48
+ 7. **Recommend companions for the task.** Read the [adapter guide](https://github.com/niklas-westman/penpair/blob/main/docs/adapters.md). A library adapter brings the project's chosen component-library tokens and recipes into the workflow. When frontend implementation/comparison is in scope, recommend `@penpair/reflection-check`, installed at the same version as the command/core and merged into the existing `adapters` list. State the remaining requirements: approved baselines, explicit case mappings and a real browser provider. Record those as pending until configured and exercised; connection-ready does not mean comparison-ready. Design-only projects can defer comparison setup.
43
49
 
44
50
  ## Moving between web and Docker
45
51
 
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "Penpair Setup"
3
+ short_description: "Connect or repair a Penpot project"
4
+ default_prompt: "Use $penpair-setup to diagnose this project's Penpot connection and report the remaining setup steps."
5
+ policy:
6
+ allow_implicit_invocation: true
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: penpair-verify
3
+ description: Verify a frontend against an approved Penpot design using Penpair Reflection Check. Use to check visual parity, investigate design mismatches or recheck an implementation after fixes with real browser screenshots and observed application state.
4
+ ---
5
+
6
+ # Frontend verification
7
+
8
+ Compare the real implementation with the exact approved design case. Use the
9
+ project's configured browser provider and component library. A captured design,
10
+ an installed adapter and a passing build each establish different facts.
11
+
12
+ Continue the project's existing comparative checkpoint, or create a project-owned
13
+ case report outside installed skill folders. Retain source/candidate identities,
14
+ preserved and changed regions, actual image paths, observed setup, consequential
15
+ findings and the next action. If `penpair-recipes` is installed, its
16
+ `references/visual-checkpoint.md` and template supply the common format.
17
+
18
+ 1. **Establish readiness.** Inspect the installed command and adapter versions,
19
+ the project's existing verification scripts, approved reference and explicit
20
+ case mapping. Use the local command (`pnpm exec penpair` in pnpm projects).
21
+ Report installed, registered, references approved, cases mapped, provider
22
+ configured, browser verified and owner reviewed separately. Keep unavailable
23
+ stages pending; do not invent approval or replace an unimplemented setup.
24
+ 2. **Plan the case.** Run `penpair reflection plan --map FILE`. Confirm the
25
+ reference identity/hash and intended route, viewport, theme, state, fixture and
26
+ fonts. Start with one representative case before expanding the matrix. For
27
+ browser evidence requirements, read [browser-evidence.md](references/browser-evidence.md).
28
+ 3. **Run the real browser.** Start or reuse the authorized local application and
29
+ run `penpair reflection check --map FILE --provider FILE`. The project module
30
+ must activate and independently observe the requested application state.
31
+ Exit 0 means complete evidence within thresholds; 2 means measured drift;
32
+ 3 means incomplete evidence. An execution error establishes no comparison.
33
+ 4. **Inspect and repair.** Look at the approved image and actual browser image;
34
+ inspect a diff image when the checker produces one. Record consequential
35
+ findings as location, impact, evidence, proposed fix and rerun case. Fix
36
+ implementation mismatches within scope, then recapture affected cases. Do
37
+ not overwrite approved references, change case intent or loosen thresholds
38
+ merely to pass. A design change goes back through design review and approval.
39
+ 5. **Checkpoint and report.** If repeated failures or substantial tooling work
40
+ prevent a representative visual result, report the evidence and revised
41
+ approach before expanding tools or cases. Retain case IDs, image paths,
42
+ findings and the next action so another agent can continue. Report **Changed**,
43
+ **Validated**, **Risks**, separating comparison, visual critique, accessibility
44
+ checks and owner approval. A low pixel ratio does not establish any of the last
45
+ three.
46
+
47
+ For a new implementation or missing component mapping, use `penpair-handoff` when
48
+ installed. For Penpot changes, use `penpair-design` when installed and retain the
49
+ project's write protocol. Reading a skill never authorizes an extra live write.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "Penpair Verify"
3
+ short_description: "Compare browser UI with approved designs"
4
+ default_prompt: "Use $penpair-verify to compare this running frontend with its approved design, inspect the images and recheck scoped fixes."
5
+ policy:
6
+ allow_implicit_invocation: true
@@ -0,0 +1,33 @@
1
+ # Real browser evidence
2
+
3
+ The optional `@penpair/reflection-check` adapter connects approved design cases to
4
+ a trusted project module exporting `async runCase(test)`. Match its version to
5
+ the installed command/core and preserve existing adapter entries. Read the
6
+ [adapter guide](https://github.com/niklas-westman/penpair/blob/main/docs/adapters.md#check-the-frontend-against-the-design)
7
+ for installation and the current provider contract.
8
+
9
+ The command package ships `examples/reflection-browser/`: for a web installation,
10
+ start at `node_modules/@penpair/web/examples/reflection-browser/README.md`. The
11
+ starter supplies browser capture and pixel comparison plumbing. Project hooks
12
+ still own the actual route, state setup, fixture, theme observation, capture root
13
+ and expected fonts. The standalone Reflection application is optional; a pinned
14
+ browser dependency and working provider are still required in the project.
15
+
16
+ Before claiming a comparison, retain the case ID, approved reference/hash, setup
17
+ name, provider identity/version and actual browser observation. Check viewport,
18
+ theme, state, fixture, loaded fonts, PNG dimensions and scale. Missing state
19
+ hooks, placeholder routes or echoed test inputs leave verification pending.
20
+ Inspect pointer/hover, scroll/sticky behavior, occlusion and capture-root bounds
21
+ when they can explain a mismatch. Do not hide them by changing the reference.
22
+
23
+ Use the project's existing verification command or pass its explicit mapping and
24
+ provider to the installed `penpair reflection` command. Providers execute trusted
25
+ project code, not sandboxed data. Preserve approved baseline bytes before and
26
+ after running them. Browser state and screenshots must be independently observed;
27
+ an adapter accepts an evidence contract but cannot attest that a provider is
28
+ honest.
29
+
30
+ Keep the result and screenshots in a project-owned report. Distinguish measured
31
+ drift, a visual finding, behavior/accessibility checks and owner acceptance.
32
+ Design-to-design state variants need a source/candidate critique, not an
33
+ implementation parity score against intentionally different content.
package/dist/cli.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
package/dist/cli.js DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- import { runCli } from "./cli-main.js";
3
- process.exitCode = await runCli(process.argv.slice(2));
@@ -1,96 +0,0 @@
1
- import { type InstanceConfig } from "../instance/config.js";
2
- import { type Check, type DoctorCheck, type DoctorOptions } from "../instance/connection.js";
3
- import type { Runner } from "../instance/runner.js";
4
- export interface Context {
5
- root: string;
6
- config: InstanceConfig;
7
- runner: Runner;
8
- log?: (message: string) => void;
9
- sleep?: (milliseconds: number) => Promise<void>;
10
- fetch?: typeof fetch;
11
- now?: () => Date;
12
- }
13
- /** `docker compose` arguments for this instance: its own project name, compose file and secrets. */
14
- export declare function composeArgs(c: Context, ...rest: string[]): string[];
15
- /** The frontend answers a few seconds before the backend does (502 until then); /readyz is 200 only when the backend is ready. */
16
- export declare const readyUrl: (config: InstanceConfig) => string;
17
- export declare function waitForHttp(c: Context, url: string, timeoutMs?: number, stepMs?: number): Promise<boolean>;
18
- export declare function up(c: Context): Promise<{
19
- url: string;
20
- ready: boolean;
21
- }>;
22
- /** Stops and removes the containers. Volumes are never removed: the design data stays. */
23
- export declare function down(c: Context): Promise<void>;
24
- export interface ServiceState {
25
- service: string;
26
- state: string;
27
- health: string;
28
- }
29
- export declare function parseComposePs(output: string): ServiceState[];
30
- export declare function status(c: Context): Promise<{
31
- services: ServiceState[];
32
- frontendReachable: boolean;
33
- backendReady: boolean;
34
- url: string;
35
- }>;
36
- export interface Counts {
37
- files: number;
38
- profiles: number;
39
- teams: number;
40
- storageObjects: number;
41
- fileRevisions: {
42
- id: string;
43
- name: string;
44
- revn: number;
45
- }[];
46
- }
47
- export interface BackupManifest {
48
- instance: string;
49
- penpotVersion: string;
50
- createdAt: string;
51
- label?: string;
52
- files: {
53
- db: {
54
- name: string;
55
- sha256: string;
56
- bytes: number;
57
- };
58
- assets: {
59
- name: string;
60
- sha256: string;
61
- bytes: number;
62
- };
63
- };
64
- counts: Counts;
65
- note: string;
66
- }
67
- /**
68
- * A backup of the whole instance: a Postgres dump and a tarball of the asset volume, with checksums and the counts
69
- * that `backup verify` later checks a restore against. It holds account data (password hashes): never commit it.
70
- */
71
- export declare function backup(c: Context, label?: string): Promise<{
72
- directory: string;
73
- manifest: BackupManifest;
74
- }>;
75
- /** Proves a backup can be restored without touching the instance: restores the dump into a throwaway Postgres and compares. */
76
- export declare function verifyBackup(c: Context, directory: string): Promise<{
77
- ok: boolean;
78
- checks: Check[];
79
- }>;
80
- export interface RestoreOptions {
81
- /** Restoring replaces the instance's data; it only runs when this is true. */
82
- yes: boolean;
83
- /** Skip the safety backup of the current data. */
84
- skipSafetyBackup?: boolean;
85
- }
86
- /**
87
- * Replaces the instance's database and assets with a backup. A backup of the current data is taken first unless told
88
- * not to, the checksums are checked before anything is touched, and the counts are compared afterwards.
89
- */
90
- export declare function restore(c: Context, directory: string, options: RestoreOptions): Promise<{
91
- ok: boolean;
92
- checks: Check[];
93
- safetyBackup?: string;
94
- }>;
95
- /** What is up, what is not, and what to do about it. */
96
- export declare function doctor(c: Context, options?: DoctorOptions): Promise<DoctorCheck[]>;