@penpair/web 0.4.1 → 0.5.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/README.md +30 -0
- package/docs/copy-between-pages.md +195 -45
- package/docs/design-releases.md +27 -4
- package/docs/mcp.md +61 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -56,6 +56,36 @@ Then choose a scratch page and agree on a small design task. The workflow is: in
|
|
|
56
56
|
|
|
57
57
|
The installed skills cover **setup → design → recipes → handoff → verification**, with `design-judgment` for visual hierarchy. Ask the assistant to name the skill it uses. For frontend work, `penpair-handoff` carries design evidence into implementation; `penpair-verify` guides browser comparison, image review, fixes and recapture. [Check skill discovery and behavior](https://github.com/niklas-westman/penpair/blob/main/docs/skill-validation.md).
|
|
58
58
|
|
|
59
|
+
## Where the command and tools live
|
|
60
|
+
|
|
61
|
+
Install one command package in your application project. Both expose the same
|
|
62
|
+
`penpair` command; the core library is installed as a dependency.
|
|
63
|
+
|
|
64
|
+
| Surface | Where it comes from | How you discover it |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| Hosted/team Penpot CLI | `@penpair/web` | `pnpm exec penpair --help` |
|
|
67
|
+
| CLI with local Penpot containers | `@penpair/docker` | The same command, plus instance lifecycle commands |
|
|
68
|
+
| Engine and shipped agent skills | `@penpair/core` | Library exports and `penpair skills`; core has no executable |
|
|
69
|
+
| Penpair MCP tools | Your installed command, started as a stdio server | Register the executable with `mcp --root /absolute/path/to/project` in your assistant |
|
|
70
|
+
| Your assistant's browser/computer controls | The assistant host, separately from Penpair | Host configuration; installing Penpair does not add these controls |
|
|
71
|
+
|
|
72
|
+
For example, register `/absolute/path/to/project/node_modules/.bin/penpair` with
|
|
73
|
+
arguments `["mcp", "--root", "/absolute/path/to/project"]`. That exposes typed
|
|
74
|
+
inspection, status, doctor, spec and export tools for the pinned project. It does
|
|
75
|
+
not expose every CLI command or arbitrary browser control. See the
|
|
76
|
+
[tool inventory and client configuration](https://github.com/niklas-westman/penpair/blob/main/docs/mcp.md).
|
|
77
|
+
|
|
78
|
+
Explicit `--allow-writes` additionally exposes registered operations and the
|
|
79
|
+
experimental `design_release_copy` tool. Both preview by default; applying a
|
|
80
|
+
native copy also requires a loopback browser debugging port and existing browser
|
|
81
|
+
clipboard read/write capability. Penpair does not grant those permissions. The equivalent CLI
|
|
82
|
+
starts with `penpair design-release copy --source-page PAGE --frame BOARD_ID
|
|
83
|
+
--release 1.2.0`. Copying creates native boards and transfer evidence; it does not
|
|
84
|
+
approve a full design release. Read the
|
|
85
|
+
[native copy guide](https://github.com/niklas-westman/penpair/blob/main/docs/copy-between-pages.md)
|
|
86
|
+
before applying it. `penpair wake` remains CLI-only.
|
|
87
|
+
For Claude and other hosts, read the [CLI/MCP prerequisites and current qualification](https://github.com/niklas-westman/penpair/blob/main/docs/copy-between-pages.md#using-from-claude-or-other-hosts); the native-UI test driver is not shipped as a fallback.
|
|
88
|
+
|
|
59
89
|
## Add your companions
|
|
60
90
|
|
|
61
91
|
| Package | Add it when | What it contributes |
|
|
@@ -1,54 +1,204 @@
|
|
|
1
|
-
# Copy boards between pages
|
|
1
|
+
# Copy native boards between pages
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
the Penpot
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
for its additional fidelity requirements.
|
|
3
|
+
`penpair design-release copy` is an experimental native-editor transfer within
|
|
4
|
+
the project's pinned Penpot file. It copies selected boards to
|
|
5
|
+
`release/<version>`, leaves their originals in place and independently captures
|
|
6
|
+
source and destination evidence. It uses the browser's native clipboard rather
|
|
7
|
+
than trying to move a plugin shape proxy between pages.
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
This is a page-copy operation, not a complete design-release assembly or owner
|
|
10
|
+
approval. It produces a private transfer receipt, not a fabricated
|
|
11
|
+
`release.json`. The stricter [design release verification](design-releases.md)
|
|
12
|
+
requirements still apply before a full release can be finalized.
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
## Prerequisites and preview
|
|
15
|
+
|
|
16
|
+
Use the reviewed project installation, with a valid configuration, an
|
|
17
|
+
owner-confirmed file pin and a connected responsive Penpot plugin. Choose one
|
|
18
|
+
source page and 1–100 distinct board IDs from that page. IDs must identify boards,
|
|
19
|
+
not arbitrary shapes; selecting a board together with its descendant board is
|
|
20
|
+
refused. Boards nested in sections can be selected by their IDs.
|
|
21
|
+
The PoC bounds each observed page to 20,000 nodes and the native clipboard
|
|
22
|
+
payload to 16 MiB; exceeding either limit stops the transfer.
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
# Replace these board IDs and page name with observed source identities.
|
|
26
|
+
penpair design-release copy --source-page "Screens" \
|
|
27
|
+
--frame SOURCE_BOARD_ID --frame ANOTHER_BOARD_ID --release 1.2.0
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Preview resolves the source and destination, inventories existing content and
|
|
31
|
+
reports the planned selection. It does not create a page, alter selection or
|
|
32
|
+
use the clipboard. The destination is always `release/1.2.0` in the same pinned
|
|
33
|
+
file; this command does not copy between files or deployments.
|
|
34
|
+
|
|
35
|
+
A unique existing destination can be reused without replacing its content.
|
|
36
|
+
Missing destinations are created on apply. Ambiguous page names, finalized
|
|
37
|
+
release ownership and conflicting ownership markers are refused. New copies
|
|
38
|
+
are arranged separately from existing destination content; existing frames are
|
|
39
|
+
not moved or normalized.
|
|
40
|
+
|
|
41
|
+
## Apply through the native editor
|
|
42
|
+
|
|
43
|
+
Review the preview and authorize the actual transfer before applying:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
penpair design-release copy --source-page "Screens" \
|
|
47
|
+
--frame SOURCE_BOARD_ID --frame ANOTHER_BOARD_ID --release 1.2.0 \
|
|
48
|
+
--debug-port 9222 --apply
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The browser must already expose a loopback debugging port. See
|
|
52
|
+
[browser setup and recovery](browser-sessions.md) for an isolated-profile example.
|
|
53
|
+
Clipboard APIs also require a secure browser context, normally HTTPS or local
|
|
54
|
+
loopback HTTP. See the browser vendor's [clipboard access guidance](https://web.dev/articles/async-clipboard).
|
|
55
|
+
Penpair adds no browser dependency or browser download and does not start a
|
|
56
|
+
managed session. It verifies the browser origin and pinned file; configured local
|
|
57
|
+
instances may use the equivalent `localhost`/`127.0.0.1` HTTP origin on the same
|
|
58
|
+
port. Hosted deployments require the exact configured origin.
|
|
59
|
+
|
|
60
|
+
The bundled transport also requires the browser's existing clipboard read/write
|
|
61
|
+
capability for that editor. Penpair does not grant clipboard permissions. If the
|
|
62
|
+
capability is unavailable, denied or waiting for a browser prompt, the operation
|
|
63
|
+
fails closed before paste. Complete any intended browser permission decision
|
|
64
|
+
separately; a debugging connection alone does not establish clipboard access.
|
|
65
|
+
|
|
66
|
+
Applying changes page and board selection, foregrounds the editor and dispatches
|
|
67
|
+
native Copy/Paste. The Penpot canvas must have focus, with no text field,
|
|
68
|
+
content-editable region, plugin iframe or dialog focused. Penpair refuses unsafe
|
|
69
|
+
focus instead of sending shortcuts into another control. This replaces the
|
|
70
|
+
system clipboard contents; previous clipboard contents are not automatically
|
|
71
|
+
restored. Avoid using the clipboard or changing editor focus during the transfer.
|
|
72
|
+
A local clipboard lease excludes cooperating Penpair sessions, not unrelated
|
|
73
|
+
applications or manual actions.
|
|
74
|
+
|
|
75
|
+
Before dispatching Copy, the transport clears the clipboard to a unique sentinel.
|
|
76
|
+
It then waits for an actual native Penpot JSON/verbose-Transit payload matching
|
|
77
|
+
the pinned file and selected board UUIDs. Validation and SHA-256 calculation run
|
|
78
|
+
inside the browser; the bundled transport does not return, log or persist raw
|
|
79
|
+
clipboard contents. Immediately before Paste it revalidates the payload digest.
|
|
80
|
+
Missing, stale, unrelated or changed clipboard data prevents paste rather than
|
|
81
|
+
reusing whatever was previously on the clipboard. Clearing the clipboard can
|
|
82
|
+
therefore replace its contents even when the transfer subsequently stops.
|
|
83
|
+
|
|
84
|
+
The command captures source inspections and stable exports, prepares the
|
|
85
|
+
same-file destination, fences one native paste attempt, identifies the new
|
|
86
|
+
boards and arranges only those copies. Independent readback checks the copied
|
|
87
|
+
boards and the unchanged originals. It records structural findings and decoded
|
|
88
|
+
pixel comparisons. Review the saved source/target exports visually as part of
|
|
89
|
+
acceptance; a technical result does not supply human approval.
|
|
90
|
+
|
|
91
|
+
## Results and recovery
|
|
92
|
+
|
|
93
|
+
The result includes a `runId`, source/target board pairs, `nativeVerified`,
|
|
94
|
+
`pixelsMatch`, problems and a receipt path:
|
|
15
95
|
|
|
16
96
|
```text
|
|
17
|
-
|
|
97
|
+
.penpair/native-copy/<run-id>/receipt.json
|
|
18
98
|
```
|
|
19
99
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
100
|
+
The receipt and its referenced inspections/exports are private operation evidence.
|
|
101
|
+
A successful fully verified transfer reports `status: "copied"`; missing native
|
|
102
|
+
proof or a pixel mismatch can leave `status: "incomplete"` and exit 3 even when
|
|
103
|
+
boards already exist in the destination. Read the findings before doing anything
|
|
104
|
+
else. Existing verification limits remain strict: component overrides, masks,
|
|
105
|
+
paths, mixed text styles and other unobserved native fields cannot be accepted
|
|
106
|
+
merely because exported pixels match.
|
|
107
|
+
|
|
108
|
+
Do not rerun a fresh apply to recover a lost response. Inspect the journal and
|
|
109
|
+
destination independently, then use the original inputs and run ID:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
penpair runs RUN_ID
|
|
113
|
+
penpair design-release copy --source-page "Screens" \
|
|
114
|
+
--frame SOURCE_BOARD_ID --frame ANOTHER_BOARD_ID --release 1.2.0 \
|
|
115
|
+
--debug-port 9222 --resume RUN_ID --apply
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Resume reconciles the observed destination against the original transfer. A
|
|
119
|
+
paste-attempt fence prevents blind replay after an uncertain paste. Changed
|
|
120
|
+
inputs, changed originals or an ambiguous destination require explicit
|
|
121
|
+
reconciliation; neither resume nor browser activation promises rollback.
|
|
122
|
+
|
|
123
|
+
The transfer receipt is not the receipt-list schema consumed by
|
|
124
|
+
`design-release verify --receipts`. Do not rename it to `release.json` or pass it
|
|
125
|
+
as an approved release. Full release plans, maps, source evidence, native-copy
|
|
126
|
+
mapping and exact owner reviews remain separate requirements. Compatibility
|
|
127
|
+
between copy-created page ownership and the full assembly workflow must be
|
|
128
|
+
validated before treating a copied page as an assembled release.
|
|
129
|
+
|
|
130
|
+
## MCP discovery
|
|
131
|
+
|
|
132
|
+
The typed `design_release_copy` tool appears only when the project's Penpair
|
|
133
|
+
stdio server starts with `--allow-writes`. Its inputs are `sourcePage`,
|
|
134
|
+
`frameIds`, `releaseVersion`, optional `debugPort`, `apply` and `resume`. Preview
|
|
135
|
+
is the default; apply requires `debugPort`, and resume requires apply. The tool
|
|
136
|
+
returns the same operation result and keeps the same target/recovery safeguards.
|
|
137
|
+
It does not expose raw page code. See [MCP tools](mcp.md).
|
|
138
|
+
|
|
139
|
+
## Using from Claude or other hosts
|
|
140
|
+
|
|
141
|
+
The standard copy route is host-neutral: an assistant can invoke the installed
|
|
142
|
+
CLI or call the typed Penpair MCP tool. It requires the configured project,
|
|
143
|
+
owner-confirmed file pin and responsive plugin connection described above. Apply
|
|
144
|
+
also requires a debugging-enabled browser on the same computer as the Penpair
|
|
145
|
+
process, the explicit debugging port and existing clipboard read/write access.
|
|
146
|
+
These are the same prerequisites in Claude, Codex and other CLI/MCP-capable hosts.
|
|
147
|
+
|
|
148
|
+
Claude does not need an additional computer-control integration for the standard
|
|
149
|
+
CDP route. Register the reviewed Penpair executable with `--allow-writes` to expose
|
|
150
|
+
`design_release_copy`, or use the CLI directly. Preview first; tool visibility
|
|
151
|
+
alone neither applies the copy nor grants browser permissions. See the
|
|
152
|
+
[Claude registration example](mcp.md#client-registration).
|
|
153
|
+
|
|
154
|
+
The native-UI keyboard driver used in the trial below was an injected test
|
|
155
|
+
driver, not a public CLI/MCP fallback supplied to Claude or other hosts. That
|
|
156
|
+
trial establishes the core-service proof described below; qualification of the
|
|
157
|
+
bundled CDP clipboard path against Penpot remains pending. Installing Penpair or
|
|
158
|
+
adding host computer controls does not turn that pending qualification into a
|
|
159
|
+
passing result.
|
|
160
|
+
|
|
161
|
+
## Evidence and API boundary
|
|
162
|
+
|
|
163
|
+
The hardened bundled CDP transport has not passed end-to-end browser
|
|
164
|
+
qualification. In a disposable unauthenticated Brave fixture, it stopped while
|
|
165
|
+
awaiting clipboard read access and dispatched no paste. Earlier shortcut-only
|
|
166
|
+
fixture results do not establish that the current payload-validation path works
|
|
167
|
+
end to end. A separate native-UI experiment also does not qualify the bundled
|
|
168
|
+
CDP transport or provide a public CLI fallback.
|
|
169
|
+
|
|
170
|
+
An owner-authorized hosted Penpot trial on 25 October 2026 copied two synthetic
|
|
171
|
+
240 × 160 boards with simple rectangle/ellipse children into a disposable release
|
|
172
|
+
page. It used an injected native-UI keyboard driver through the same core copy
|
|
173
|
+
service because that existing browser profile had no debugging port. The actual
|
|
174
|
+
JSON/verbose-Transit clipboard payload was checked locally against the pinned
|
|
175
|
+
file, selected board identities and digest before one paste; arranging the new
|
|
176
|
+
copies was a separate idempotent step. Independent inspection/native-fidelity
|
|
177
|
+
comparison and decoded RGBA pixel hashes passed for both boards, with four mapped
|
|
178
|
+
nodes. Source and copied stable PNG exports were visually inspected.
|
|
179
|
+
|
|
180
|
+
The original trial run then completed explicit resume with `status: "copied"`,
|
|
181
|
+
`nativeVerified: true`, `pixelsMatch: true` and no problems. The copies were
|
|
182
|
+
arranged, the original source hashes remained unchanged, the receipt was saved
|
|
183
|
+
and the journal reached `verified`. Revision drift had safely interrupted the
|
|
184
|
+
first final capture; bounded read-only recapture and reconciliation completed
|
|
185
|
+
verification without another Copy or Paste dispatch.
|
|
186
|
+
|
|
187
|
+
This establishes the limited native-UI/core-service proof of concept. End-to-end
|
|
188
|
+
Penpot qualification of the bundled CDP clipboard transport remains pending;
|
|
189
|
+
the native-UI result does not establish that qualification or record owner
|
|
190
|
+
approval. Unsupported content remains incomplete. Full release assembly adoption
|
|
191
|
+
is not implemented by this transfer proof of concept.
|
|
192
|
+
|
|
193
|
+
The direct plugin API limitation remains: a disposable two-page trial on local
|
|
194
|
+
Penpot 2.18.3 tested a board with one rectangle child. `clone()` remained on the
|
|
195
|
+
source page, and cross-page `appendChild`/`insertChild` attempts failed with
|
|
196
|
+
`Cannot modify a page that is not currently active`. Independent readback found
|
|
197
|
+
the originals unchanged and no destination children. The native clipboard route
|
|
198
|
+
avoids that unsupported operation; it does not make cross-page reparenting safe.
|
|
28
199
|
|
|
29
200
|
The [upstream shape implementation](https://github.com/penpot/penpot/blob/develop/frontend/src/app/plugins/shape.cljs)
|
|
30
|
-
checks
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
validation and history, without a file-change submission method.
|
|
35
|
-
|
|
36
|
-
## File-change route
|
|
37
|
-
|
|
38
|
-
Penpair's connection calls the editor's MCP tools; it has no authenticated
|
|
39
|
-
Penpot backend file-change client or supported plugin method for submitting raw
|
|
40
|
-
file changes. Internal `$page` metadata does not provide that capability.
|
|
41
|
-
Changing a proxy's internals, reconstructing a board from its visible properties,
|
|
42
|
-
or patching backend file objects would not establish preserved component
|
|
43
|
-
overrides, token bindings, references, undo behavior or revision coordination.
|
|
44
|
-
|
|
45
|
-
There is therefore no safe file-change route in the current implementation.
|
|
46
|
-
Automatic cross-page copying stops at this boundary. A future supported transfer
|
|
47
|
-
API or separately validated native editor integration would need exact source
|
|
48
|
-
selection, a dry run, journaled recovery, independent fidelity readback and stable
|
|
49
|
-
exports before shipping a copy command. Moving must remain explicit.
|
|
50
|
-
|
|
51
|
-
For large pages, scope a writer's layout observation with repeatable
|
|
52
|
-
`--layout-root <shape-id>` and, when needed, `--layout-max-nodes <n>`; see
|
|
53
|
-
[layout settling](layout-settling.md). Reducing the observation scope does not
|
|
54
|
-
add a cross-page copy capability.
|
|
201
|
+
checks active-page ownership. The [Board API](https://doc.plugins.penpot.app/interfaces/Board)
|
|
202
|
+
provides cloning and reparenting, but no cross-page transfer operation. Penpair
|
|
203
|
+
does not patch proxy internals, reconstruct the design from screenshots or
|
|
204
|
+
submit unauthenticated raw backend file changes as a fallback.
|
package/docs/design-releases.md
CHANGED
|
@@ -7,6 +7,27 @@ design cases and immutable evidence so a later implementation agent can identify
|
|
|
7
7
|
what was reviewed. This is a design release, separate from publishing Penpair's
|
|
8
8
|
npm packages or accepting a frontend implementation.
|
|
9
9
|
|
|
10
|
+
## Copy boards to a release page
|
|
11
|
+
|
|
12
|
+
For an experimental same-file page transfer, preview the observed source boards:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
penpair design-release copy --source-page "Screens" \
|
|
16
|
+
--frame SOURCE_BOARD_ID --release 1.2.0
|
|
17
|
+
# After reviewing and authorizing the transfer:
|
|
18
|
+
penpair design-release copy --source-page "Screens" \
|
|
19
|
+
--frame SOURCE_BOARD_ID --release 1.2.0 --debug-port 9222 --apply
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This uses native editor copy/paste into `release/1.2.0`, preserving originals and
|
|
23
|
+
existing destination content, and writes private evidence under
|
|
24
|
+
`.penpair/native-copy/<run-id>/`. It can report incomplete native fidelity after
|
|
25
|
+
copying; read the findings and inspect the exports. The transfer receipt is not
|
|
26
|
+
a release manifest, the `verify --receipts` input schema or owner approval.
|
|
27
|
+
Copy-created page ownership does not by itself establish compatibility with the
|
|
28
|
+
full assembly flow below. See [native copy and recovery](copy-between-pages.md)
|
|
29
|
+
for prerequisites, clipboard effects, explicit resume and current proof limits.
|
|
30
|
+
|
|
10
31
|
## Local commands
|
|
11
32
|
|
|
12
33
|
Create the plan from actual source inspection, using your own product SemVer.
|
|
@@ -60,10 +81,12 @@ is not approval of the child graph. See [linked detail maps](integration-maps.md
|
|
|
60
81
|
Keep the release page in the same pinned Penpot file, named `release/<version>`.
|
|
61
82
|
Assembly creates the owned overview/map sections and reports `awaiting-copy`.
|
|
62
83
|
Copy source design frames natively using a reviewed, guided copy/paste operation
|
|
63
|
-
by a person or an authorized AI using existing browser tools.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
84
|
+
by a person or an authorized AI using existing browser tools. The experimental
|
|
85
|
+
`design-release copy` path separately automates native clipboard transfer; its
|
|
86
|
+
receipt is not automatically a full release's mapping or approval. Assembly
|
|
87
|
+
does not perform an unsupported cross-page clone. The
|
|
88
|
+
[native copy guide](copy-between-pages.md) records both that API boundary and the
|
|
89
|
+
new transport's verification limits.
|
|
67
90
|
Preserve visual fidelity, native components, token bindings, text and layout;
|
|
68
91
|
do not recreate frames from screenshots or normalize their dimensions. A source
|
|
69
92
|
using auto height must retain it. Floating-point geometry noise is not a reason
|
package/docs/mcp.md
CHANGED
|
@@ -6,9 +6,48 @@ penpair mcp --root /absolute/path/to/project
|
|
|
6
6
|
|
|
7
7
|
Use the project's reviewed local executable. Startup requires an absolute root, valid project config and owner-confirmed file pin. The server keeps that target for its lifetime and refuses a changed target until restart/review. Each call gets request-scoped root state; it never calls `process.chdir`. Even basic reads use strict same-execution file guards. Environment/project `.env.local` endpoint resolution remains available; unrelated global Codex/Claude endpoint fallback is disabled. Keep credentials in the private connection flow, outside client configuration examples.
|
|
8
8
|
|
|
9
|
-
Default
|
|
9
|
+
Default tool names are `pages`, `tree`, `audit`, `inspect`, `tokens_dump`, `run_status`, `baselines_status`, `project_status`, `doctor`, `design_spec` and `export`. These cover bounded live inspection, offline run/baseline evidence, diagnostics, derived specs and stable export to a path inside the project. Export creates/replaces a local file and has a write annotation. There is no raw-code tool or unrestricted command forwarding. Each typed input is validated independently of the client schema. No Penpot write tool is advertised by default.
|
|
10
10
|
|
|
11
|
-
Explicit `--allow-writes` additionally advertises `run_registered`.
|
|
11
|
+
Explicit `--allow-writes` additionally advertises `run_registered` and `design_release_copy`. The first runs registered operations; the second provides the typed native-copy workflow described below. `run_registered` accepts a registered operation name and scalar parameters, defaults to inspection, and requires explicit `apply:true` for design writes. Explicit `resume` requires apply and the original journal; file/instance guards, local/shared advisory lease, same-execution preconditions, checkpoints supported by the underlying command, and independent readback remain in the same services. Registered modules execute trusted project code, including imports; they must keep stdout for MCP and log through the command context. This is not an execution sandbox. Adapter-specific commands remain available through the CLI; the neutral server does not guess library-specific tool schemas.
|
|
12
|
+
|
|
13
|
+
## Native release-page copy
|
|
14
|
+
|
|
15
|
+
Start the reviewed project executable with write tools enabled only when those
|
|
16
|
+
operations are authorized:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
penpair mcp --root /absolute/path/to/project --allow-writes
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The `design_release_copy` tool previews by default. Example input, with observed
|
|
23
|
+
source board IDs substituted:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"sourcePage": "Screens",
|
|
28
|
+
"frameIds": ["SOURCE_BOARD_ID", "ANOTHER_BOARD_ID"],
|
|
29
|
+
"releaseVersion": "1.2.0",
|
|
30
|
+
"apply": false
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Explicit `apply: true` also requires `debugPort` (1–65535) for an already enabled
|
|
35
|
+
loopback browser debugging endpoint and existing clipboard read/write capability.
|
|
36
|
+
Penpair does not grant browser permissions; denied or unavailable access stops
|
|
37
|
+
before paste. `resume` requires apply and the original run ID/inputs. Copy uses the pinned file, preserves originals, and creates or appends
|
|
38
|
+
to `release/1.2.0`; it changes browser focus and selection and replaces the system
|
|
39
|
+
clipboard. The bundled transport clears stale data before Copy, validates the
|
|
40
|
+
native payload against the pinned file and selected boards inside the browser,
|
|
41
|
+
and rechecks its digest before Paste. Raw clipboard data is not returned, logged
|
|
42
|
+
or persisted by that transport. An uncertain paste is reconciled rather than
|
|
43
|
+
automatically replayed.
|
|
44
|
+
An incomplete native/pixel result is not a completed transfer or release
|
|
45
|
+
approval. See [native copy, evidence and recovery](copy-between-pages.md).
|
|
46
|
+
|
|
47
|
+
This tool is absent from the default server. There is no MCP `wake` tool: explicit
|
|
48
|
+
browser activation remains the CLI `penpair wake` command. Native browser/computer
|
|
49
|
+
controls supplied by an assistant host are separate tools and are not installed
|
|
50
|
+
or exposed by Penpair's server.
|
|
12
51
|
|
|
13
52
|
Requests return the version-1 CLI envelope as text plus structured content. Default cooperative deadline: 60 seconds; SDK cancellation propagates into the service. Arbitrary trusted code can ignore cancellation. A 256 KiB response cap returns an explicit incomplete envelope rather than apparently successful truncated data; uncertain writes retain their uncertain outcome/run ID. Use narrower inspection or CLI artifact output for larger evidence. Stdio has no HTTP listener or background polling.
|
|
14
53
|
|
|
@@ -22,8 +61,9 @@ Every advertised tool explicitly declares boolean `readOnlyHint`, `destructiveHi
|
|
|
22
61
|
| `pages`, `tree`, `audit`, `inspect`, `tokens_dump`, `project_status`, `doctor`, `design_spec` (may contact Penpot or its deployment) | true | false | true | true |
|
|
23
62
|
| `export` (creates or replaces a local image from live Penpot) | false | true | false | true |
|
|
24
63
|
| `run_registered` (opt-in trusted code, potentially mutating) | false | true | false | true |
|
|
64
|
+
| `design_release_copy` (opt-in native clipboard transfer) | false | false | false | true |
|
|
25
65
|
|
|
26
|
-
`export` can overwrite an existing artifact, so its destructive hint is true. It captures the current design, so callers must not assume repeated calls preserve the earlier image. `run_registered` retains conservative hints even when a particular invocation only previews: its metadata must cover the registered code's possible effects. `archive` is an internal registered operation invoked through `run_registered`, not a separately advertised MCP tool.
|
|
66
|
+
`export` can overwrite an existing artifact, so its destructive hint is true. It captures the current design, so callers must not assume repeated calls preserve the earlier image. `run_registered` retains conservative hints even when a particular invocation only previews: its metadata must cover the registered code's possible effects. `design_release_copy` preserves source boards and existing destination content, but is still mutating and non-idempotent: it can create native copies, change selection/focus and replace the clipboard. Its preview does not change that tool-wide annotation. `archive` is an internal registered operation invoked through `run_registered`, not a separately advertised MCP tool.
|
|
27
67
|
|
|
28
68
|
## Code execution boundaries
|
|
29
69
|
|
|
@@ -46,6 +86,24 @@ Claude Code supports project `.mcp.json` entries under `mcpServers`; see [offici
|
|
|
46
86
|
}
|
|
47
87
|
```
|
|
48
88
|
|
|
89
|
+
For authorized native-copy work, change that Claude entry's `args` to:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
["mcp", "--root", "/absolute/path/to/project", "--allow-writes"]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Restart or reconnect the server to discover `design_release_copy`. This enables
|
|
96
|
+
tool visibility; it does not apply a copy or grant browser permissions. The tool
|
|
97
|
+
must be present in the installed Penpair version's tool list. Registering only
|
|
98
|
+
Penpot's upstream MCP server does not expose Penpair's project tools.
|
|
99
|
+
The tool
|
|
100
|
+
still previews by default. Apply requires `apply: true`, `debugPort`, the pinned
|
|
101
|
+
project/plugin connection and existing clipboard read/write access in the
|
|
102
|
+
browser on the Penpair process's computer. The standard CDP route needs no
|
|
103
|
+
additional Claude computer-control integration. The injected native-UI driver
|
|
104
|
+
used in the core-service trial is not a public fallback; bundled CDP/Penpot
|
|
105
|
+
qualification remains pending. See [host prerequisites and qualification](copy-between-pages.md#using-from-claude-or-other-hosts).
|
|
106
|
+
|
|
49
107
|
Codex uses project `.codex/config.toml` for trusted projects, with a server table; see [official Codex MCP configuration](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
|
|
50
108
|
|
|
51
109
|
```toml
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@penpair/web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "The penpair command for Penpot on the web (design.penpot.app or your team's own): guided setup, a safe write protocol, skills for AI agents. Includes everything in @penpair/core.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@penpair/core": "0.
|
|
51
|
+
"@penpair/core": "0.5.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "tsc -p tsconfig.json",
|