Commit graph

57 commits

Author SHA1 Message Date
Kayshen-X ff8b73420c chore: bump version to 0.8.3 2026-08-06 21:15:39 +08:00
Kayshen-X 1b020cebb5 fix(mcp): nest ping identity under _meta so strict clients accept the server
The MCP spec says a ping result is empty, but both ping formatters put
the OpenPencil discovery identity (server/mode/token) at the result top
level. Gemini CLI validates ping with the TS SDK's strict EmptyResultSchema
and marked the server disconnected with 'Unrecognized keys: server, mode,
token' (issue #199). _meta is the spec's sanctioned extension point and
the only key the strict schema permits, so the identity now rides there;
the op CLI reads _meta first and falls back to the legacy top-level shape
so it still discovers a running pre-0.8.3 editor. (A pre-0.8.3 op CLI
cannot discover a 0.8.3 live editor — the CLI ships with the app, so only
a stale op on PATH hits this.)
2026-08-05 22:33:10 +08:00
Kayshen-X da83157b73 feat(html): overhaul HTML and browser-snapshot import fidelity
A multi-phase campaign to make importing real modern web pages
(Tailwind output, landing pages, component-library HTML) faithful.

Layout: bake CSS transforms (translate/scale/rotate incl. the
translate(-50%,-50%) centering idiom), emulate flex-wrap via row
chunking, honor grid span/line placement, apply position:relative
offsets through synthetic wrapper frames (jian has no offset-without-
reflow), aspect-ratio, per-child auto-margin alignment, and a
configurable viewport height (threaded through the CLI and MCP).

Content: list markers (incl. reversed/roman/alpha), basic table layout
(tr->row, colspan), <picture>/srcset candidate selection, @font-face
visibility warnings, background-size/position mapped to the image
fill's crop transform, and text-shadow.

Diagnostics: replace the untyped Vec<String> warnings with a typed
ImportWarning enum (stable per-variant codes, byte-identical Display so
CLI/MCP output is unchanged), localized into all 15 locales, surfaced
through a non-modal post-import diagnostics panel wired into both hosts.
The desktop path now forwards every warning, not just the first.

Snapshot import: fix inverted child paint order (the cause of whole
overlays vanishing under full-bleed backgrounds), stop clipping text to
the browser-measured box under font-metric drift, vectorize inline SVG
to editable paths, and capture per-corner radii, background paint,
position/z-index, video posters, page background, and open shadow DOM.

The extension's tokenless snapshot-ingress route lives here too
(op-host-services), scoped to a chrome-extension origin and the single
insert-only import tool.

Known follow-up: rich inline text runs (links/code spans + wrapping)
can still overlap in the snapshot path.
2026-08-04 21:47:49 +08:00
Kayshen-X 5f04e26c1a chore(rust): align workspace checks 2026-08-01 16:19:26 +08:00
Kayshen-X 7c4f38cd4e fix(mcp): authenticate the live endpoint and degrade the bootstrap cache
The live MCP endpoint on 127.0.0.1 was a bypass of the collaboration
admission model. Its per-instance token authenticated only the ping probe
and shutdown, so document reads and writes were available to any local
process, and nothing validated Origin or Host — a page in a browser on the
same machine could reach it by DNS rebinding. During a session that is the
shared document, not just this user's file.

Every stateful call now requires the instance token, compared without an
early exit. Host must be a numeric loopback literal on the bound port, and
an Origin, when present, must match it; a request with no Origin still
works, which is what real CLI clients send. OPTIONS, initialize, and ping
stay tokenless so CLI discovery keeps working, and CollabGatePolicy is
untouched — this sits in front of it.

The `op` CLI did not send the token, so authenticating tool calls would
have returned 401 for every `op` invocation against a live editor. The
token was already in the port file next to the port; it is now resolved
with the port and travels as a header. Ping and shutdown keep their
existing tokenless wire contract.

Bootstrap cache: reads now degrade like writes already did. An unreadable
or corrupt cache leaves this start with no anti-rollback generation floor,
which is the position an absent cache has always left it in, and which the
threat model already accepts because deleting the file achieves the same
thing with no more privilege than corrupting it. Refusing bought no
security and cost the ability to collaborate at all. The tests state the
price plainly: with no floor the lower-generation document is accepted,
and `rollback_floor_armed` has to report it.

Threat model: correct an overstatement. Peer admission requires the remote
ticket's subject to equal the local account, so the product pairs only
devices of one account today. A relay operator reconstructs which devices
of an account sync and when — not a cross-account collaboration graph.
Also records that the relay reads exactly one field out of the ticket it
verifies, the expiry, which makes the identity disclosure gratuitous
rather than load-bearing, and states what a minimized credential would and
would not buy.
2026-08-01 12:23:09 +08:00
Kayshen-X 90870370ad refactor: typed error enums across the whole workspace
Completes the stringly-error conversion: 341 remaining
Result<_, String> signatures drop to two documented boundary sites
(a String-compat wrapper consumed across a crate boundary and a
test-only diagnostic helper). Eighty-plus enums follow the
established recipe — one enum per failure domain in a sibling
module, byte-identical Display text, From impls replacing map_err
adapters. mcp_live is fully typed (the screenshot channel included)
and all six temporary String bridges are deleted. The flaky
cli-model-discovery trio is made load-proof: exec'd sleeps so the
probe's kill actually closes the pipes, a serializing test lock,
and an escalating budget with a deadline-boundedness assertion.
2026-07-27 21:09:06 +08:00
Kayshen-X def6a8bcdd refactor: final 800-line sweep across editor, mcp, services, and tool crates
Pure code motion: twenty-eight remaining oversized modules split into
spine + sibling layouts with re-exports keeping every import path and
test name stable. op-codegen, op-smoke, op-mcp, op-design-lint,
op-host-services, op-host-desktop, op-cli, op-i18n, op-editor-core,
op-editor-ui, and op-pen-loader no longer have any file over the cap.
2026-07-26 22:34:37 +08:00
Kayshen-X 0fc6753dd9 refactor(cli,mcp,web): typed error enums for the densest stringly paths
CliError/SkillInstallError carry every op-cli failure (94 sites),
ProgramError types batch_program (14), WebCanvasError maps route
failures onto their existing HTTP statuses (23 -> 6 deliberate
boundary adapters). Display output is byte-identical to the old
strings so caller-visible text and tests are unchanged.
2026-07-26 13:20:59 +08:00
Kayshen-X bba6f338d6 refactor: dedupe cross-crate code and converge hardcoded literals
New leaf crate op-util single-sources hex-color parsing (9 divergent
copies, one with a non-ASCII panic), JSON escaping (one copy was
lossy), and HTML/XML escaping (one copy missed the quote entity — an
attribute-injection gap). Desktop now delegates image generate/search,
settings payload serde, and the --mcp/--serve-web argv dispatch to
op-host-services / op-editor-host-core instead of carrying drifted
copies. Byte-identical widget_host twin files collapse into shared
op-editor-core host_ui_transitions. Auth routes, the MCP port, product
name, env-var names, service URLs, and status colors move to single
shared constants / theme tokens; the stale claude-sonnet-4-5 default
model id is corrected.
2026-07-26 11:24:22 +08:00
Fini 124db9d144 fix(agent): retire gemini cli provider, add antigravity and grok build 2026-07-24 21:11:15 +08:00
Kayshen-X 70e202d802 feat(editor): improve document workflows and rendering 2026-07-23 21:15:04 +08:00
Kayshen-X 3352bb371e feat(cli): import:html url routing with --out and import:snapshot subcommand 2026-07-19 20:45:03 +08:00
Kayshen-X 1fdccd1c3b feat(cli): import:html subcommand mapping to the import_html mcp tool 2026-07-18 14:16:43 +08:00
Kayshen-X 612a453942 feat(figma): route host image transform through fig import for downscaled embeds 2026-07-18 13:11:52 +08:00
Kayshen-X 6a38b445de fix(cli): land opencode skill install in the scanned skills dir
The opencode target wrote a plugin entry the loader can never use (no
JS entrypoint, and plugin packages' skills/ are never scanned), so
'op install --target opencode' delivered nothing. Mirror the codex
layout instead: bundle under ~/.config/opencode/openpencil-skill with
a skills/ symlink opencode's {skill,skills}/**/SKILL.md scan picks up.
The installer-owned entry is recreated on every install so stale
squatters can't shadow it; remove_path only treats NotFound as absent
and handles dangling Windows directory symlinks.
2026-07-17 20:18:26 +08:00
Kayshen-X c355719fd5 fix(ci): clear Rust workflow blockers 2026-07-15 22:47:39 +08:00
Kayshen-X 7c8e2abfa7 test(cli): enforce complete bundle templating 2026-07-15 21:17:21 +08:00
Kayshen-X 83063bc279 refactor(cli): render bundled skill version from Cargo 2026-07-15 21:17:21 +08:00
Kayshen-X e0a2bd4e69 refactor: derive Rust product versions from Cargo 2026-07-15 21:17:20 +08:00
Kayshen-X 20bf8f123b refactor(cli): split app control tests 2026-07-13 21:41:23 +08:00
Danny Ahn f8cfcab7fd fix(cli): validate document before starting headless MCP server
Preflight headless document loading so malformed or binary archives fail with a clear, actionable error before the MCP server starts.

Keep the CLI parser dependency lightweight by disabling op-pen-loader default features and include the updated lockfile plus regression coverage.
2026-07-13 14:29:48 +08:00
Kayshen-X 7ec373c9a7 feat(cli): export pages nodes and live selection 2026-07-12 17:52:36 +08:00
Kayshen-X 686536a15e feat(openpencil): add code-to-design conversion flow 2026-07-04 13:23:28 +08:00
Kayshen-X f4e8e62ec0 style: rustfmt drift in op-cli design routing and native widget host 2026-07-03 22:32:13 +08:00
Kayshen-X b218a1e15d feat(cli): route op design --script / @file.js payloads to batch_design script mode
op design gains explicit script routing (--script flag, implied for
@file.js/.mjs payloads) and the vendored openpencil-skill bundle
(0.8.0) teaches script mode with the same contract the internal
SCRIPT_FORMAT prompt uses.
2026-07-03 22:08:24 +08:00
Kayshen-X 47ff290cf6 fix(desktop): windows console, spawn, and url-opening hygiene
Four Windows runtime defects from the platform audit:

- The binary stayed in the console subsystem, parking a console window
  behind the GUI when launched from Explorer. Release builds now set
  windows_subsystem = "windows"; debug keeps stderr tracing visible.
- Background CLI probes (model discovery, provider version checks) and
  the vendored Claude SDK's per-turn spawns lacked CREATE_NO_WINDOW,
  flashing console windows once the GUI detaches from the console.
- MCP stdio servers naming .cmd/.bat shims (npx and most npm-installed
  servers) could not spawn: CreateProcess cannot execute shims and Rust
  1.77+ refuses them as program names. vendor/agent now resolves the
  command PATHEXT-style against the PATH the server will actually see
  (per-server env override wins) and routes only genuine shims through
  cmd /c — real executables keep direct spawn semantics.
- cmd /C start truncated URLs at `&` (every OAuth authorize URL). The
  URL now travels double-quoted via raw_arg so cmd keeps it literal.
2026-07-03 00:08:21 +08:00
Kayshen-X 941d51f805 feat(process): extract shared process io primitives 2026-06-14 10:54:26 +08:00
Kayshen-X 4d9b2d783d feat(rpc): extract shared JSON-RPC transport 2026-06-14 10:33:21 +08:00
Kayshen-X 811b02d155 feat(config): add shared OpenPencil config store 2026-06-14 10:17:22 +08:00
Kayshen-X 55982477fd feat(cli): codegen commands wired to real tools, status pid, web start json 2026-06-12 23:28:06 +08:00
Kayshen-X aa0a29b439 fix(ci): handle windows cli paths 2026-06-06 14:26:55 +08:00
Kayshen-X 6655b029fb fix(ci): restore rust cli bundle checks 2026-06-06 13:02:37 +08:00
Kayshen-X 54fb746881 feat(mcp): expand rust editor mcp surface 2026-06-05 22:19:08 +08:00
Kayshen-X 9edc9f71c3 feat(cli): expand CLI command and flag surface
Add CLI path-args, file-flag, selection and design command coverage matching the expanded MCP tool surface, with tests and usage text.
2026-06-02 09:42:06 +08:00
Kayshen-X a26e1b0f48 fix(mcp): support ts move copy targets 2026-06-02 09:42:01 +08:00
Kayshen-X dd34ca8526 fix(mcp): accept ts delete page targets 2026-06-02 09:42:00 +08:00
Kayshen-X 4f251c138c fix(mcp): accept ts update payloads 2026-06-02 09:41:59 +08:00
Kayshen-X 79a2d0830c fix(mcp): support insert parent and page targets 2026-06-02 09:41:57 +08:00
Kayshen-X bbb26b86e8 fix(mcp): support svg import page targets 2026-06-02 09:41:56 +08:00
Kayshen-X aefdf1800f fix(mcp): support svg import parent 2026-06-02 09:41:55 +08:00
Kayshen-X 61f50999e2 fix(mcp): accept batch design operations in rust 2026-06-02 09:41:52 +08:00
Kayshen-X 0362ba3993 fix(cli): add skill install command parity 2026-06-02 09:41:50 +08:00
Kayshen-X 40d3371448 fix(cli): add rust mcp start stop commands 2026-06-02 09:41:49 +08:00
Kayshen-X 7ea28b32c4 fix(cli): add save command parity 2026-06-02 09:41:48 +08:00
Kayshen-X 68394826fe fix(cli): add figma import parity 2026-06-02 09:41:47 +08:00
Kayshen-X 09277fa77c fix(cli): report mcp status without server 2026-06-02 09:41:46 +08:00
Kayshen-X 9d5edd5812 fix(cli): add codegen command parity 2026-06-02 09:41:45 +08:00
Kayshen-X ce813bcb3e fix(mcp): add open document parity 2026-06-02 09:41:40 +08:00
Kayshen-X cb1cf55ae9 fix(mcp): add batch get parity 2026-06-02 09:41:39 +08:00
Kayshen-X 1055c8c1b3 fix(mcp): add theme preset parity 2026-06-02 09:41:34 +08:00