- Auto-update on both macOS and Windows is now battle-hardened through
the preview cycle; list the 7 additional hardening PRs that landed
since the initial draft (#2565, #2575, #2592, #2595, #2677, #2687, #2700)
and tighten the headline.
- Remove the 'Resume conversation in a new chat' bullet — the UI entry
point was reverted in #2562 before stable cut.
* fix(desktop): export PDF saves to a file instead of the OS print dialog
The `od:print-pdf` IPC handler called `webContents.print()`, which
opens the printer-first macOS system print dialog. That handler is the
destination of the renderer's `window.__odDesktop.printPdf()` bridge,
so on desktop "Export PDF" felt like a print flow rather than a file
export — from both the PreviewModal share menu (which always uses this
path) and the FileViewer share menu (whose daemon-route fallback lands
here too).
Route the handler through a direct Save-as-PDF flow instead: a native
Save dialog, then `webContents.printToPDF()` straight to the chosen
file — the same shape `exportPdfFromHtml` already uses for the
daemon-backed export path. The flow is extracted into
`savePrintReadyDocumentAsPdf` behind a structural `PrintReadyPdfTarget`
surface that has no `print()` method, so the regression cannot be
reintroduced.
Fixes#1774
Co-authored-by: multica-agent <github@multica.ai>
* fix(desktop): preserve PDF page sizing in print bridge
Co-authored-by: multica-agent <github@multica.ai>
---------
Co-authored-by: multica-agent <github@multica.ai>
Second-pass merge layering 41+ new commits from origin/main on top of
the first reconcile commit. Headline upstream additions absorbed:
- 0.7.0 release: redesigned chat bubble user-text styling, neutralised
palette, lucide icons, ElevenLabs audio voice option discovery in the
prompt composer, analytics tracking (PostHog) wired across home /
studio / create surfaces, Prometheus `/api/metrics` endpoint,
critique-theater drop-in mount with a settings toggle.
- Misc upstream fixes (titlebar padding, release header layout, deck
preview chrome, feedback form auto-scroll, conversation-created SSE
on routine runs, etc.)
Conflict resolutions (12 files, ~22 hunks):
- contracts barrel + prompts/system: union of both sides; new analytics
exports (`./analytics/events`, `./analytics/public-params`) added
alongside garnet's plugin/atom/genui exports. Both ElevenLabs voice
fields (audioVoiceOptions/audioVoiceOptionsError, main) and
pluginBlock/activeStageBlocks (garnet) preserved on ComposeInput.
- daemon/server.ts: Prometheus `/api/metrics` route inserted after
garnet's `/api/daemon/shutdown`. main's `createAnalyticsService` call
added before the chat-run service init alongside the prior reconcile
note about the dropped legacy POST /api/projects body.
- App.tsx: handleCreateProject now consumes both garnet's plugin
fields (pluginId / appliedPluginSnapshotId / pluginInputs /
autoSendFirstMessage) and main's analytics requestId. Tracking
fires success + failure paths; PluginLoopHome auto-send sessionStorage
flag is preserved.
- ProjectView.tsx: the garnet auto-send useEffect coexists with main's
`useCritiqueTheaterEnabled()` hook.
- ChatComposer.tsx: imports merged (drop now-unused fetchSkills,
add analytics provider + tracking + buildVisualAnnotationAttachment).
- index.css: main's redesigned `.msg.user .user-text` chat bubble
styling wins over garnet's plain text rule; garnet's
`.msg-plugin-chip*` rules preserved alongside.
- EntryView.tsx: accepted HEAD (garnet wrapper) — consistent with
reconcile decision #2. main's added PetRail / TopTab / analytics
view tracking is intentionally NOT brought into the wrapper; the
follow-up to re-integrate PetRail / image-templates / video-templates
into EntryShell still stands and now also covers analytics
view-tracking hooks.
- daemon/package.json + pnpm-lock: merged dep set (tar + posthog-node +
prom-client coexist).
- Test fixtures (FileWorkspace.test): kept garnet's plugin-folders
describe block intact; main's projectKind="prototype" addition is
dropped where it conflicted with garnet's plugin-folder fixture
files.
Verification: `pnpm install` (after lockfile reconciled), `pnpm typecheck`
exits 0 across all workspace packages.
Follow-up not done in this commit:
- PetRail / image-templates / video-templates / 0.7.0 analytics
view-tracking hooks need to be added to EntryShell.
- Critique-theater settings toggle UX (added on main) lives in the
SettingsDialog hierarchy; the reconcile state preserves the
SettingsDialog so this should work without changes, but no
end-to-end verification yet.
Merge of `origin/main` (`03ed3960`, 2026-05-13 pre-0.7.0) into the
161-commit garnet-hemisphere line, reconciling the product-vibe-coded
plugin/marketplace/EntryShell surfaces from garnet with the routines /
skills / live-artifacts feature work landed on main since the fork point.
Headline decisions (full rationale + side-by-side screenshots in
`specs/change/20260513-garnet-skills-automations/reconcile-result-vs-garnet.md`):
- #1 SettingsDialog: keep main's Memory / Skills / External MCP /
Connectors / Routines / MCP server nav items even though the top-level
/integrations + /automations routes also cover them. Two entries
coexist for now; revisit once Track A/B fill in the placeholder content.
- #2 EntryView: accept garnet's thin wrapper delegating to EntryShell.
Main's PetRail sidebar + image-templates/video-templates tabs are
intentionally deferred to a follow-up that re-integrates them into
the new EntryShell layout.
- #3 /integrations + /automations top-level routes: kept (garnet's
product intent). Skills tab is still a "Coming soon" placeholder
awaiting Track A; Routines/Schedules/Live-artifacts cards on
/automations are still mock awaiting Track B.
- #5 DesignFilesPanel: hybrid — main's pagination as primary list,
garnet's Plugin folders section preserved between the live-artifacts
block and the pagination block. (by-kind sections drop in favour of
pagination; plugin-folders rendering stays because it is a
garnet-specific product addition.)
- #7 server.ts (10 hunks, ~5400 conflict lines): manual hunk-by-hunk
merge. Both daemon admin routes + plugin/genui routes (garnet) and
routines/memory/skills upgrades (main) preserved. Garnet's inline
project route block kept alongside main's `registerProjectRoutes` /
`registerProjectUploadRoutes` modular wiring — duplicate route
audit is a follow-up. Garnet's POST /api/projects plugin-snapshot
resolution + default-scenario fallback is intentionally dropped from
the inline body (now handled by registerProjectRoutes) and listed for
follow-up re-integration into `project-routes.ts`.
Verification (worktree at /Users/elian/Documents/open-design-garnet):
- `pnpm typecheck` exits 0 across all workspace packages
- daemon (`pnpm tools-dev run web --namespace reconcile-shots`) boots,
serves `/api/daemon/status` healthy, and survives a Playwright
walkthrough of /integrations / /automations / home / projects /
design-systems / plugins / settings dialog
- `@open-design/plugin-runtime` package built (was missing dist/ on
garnet); without it the daemon's plugins/* imports fail at boot
Track A (Skills tab → real SkillsSection) and Track B (Automations
cards → real routines / live-artifacts backend) are the two remaining
follow-ups blocking the placeholder/mock content from going live. See
`spec.md` and `track-skills.md` in the same directory.
Plan NN2 — sync CHANGELOG.md with the NN-series shipped this turn:
NN1. `od plugin events purge` admin escape hatch
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan LL2 — sync CHANGELOG.md with the LL-series shipped this turn:
LL1. `od daemon db verify` SQLite integrity check
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan JJ2 — sync CHANGELOG.md with the JJ-series shipped this turn:
JJ1. More plugin event producer hooks
(upgrade-vs-install, trust-changed, snapshot-pruned,
marketplace-refreshed)
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan II2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the II-series shipped this turn:
II1. Plugin event ring buffer + SSE tail
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan HH3 — sync CHANGELOG.md with the HH-series shipped this turn:
HH1. `od plugin doctor --strict` + verify strict propagation
HH2. `od daemon db vacuum`
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan GG2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the GG-series shipped this turn:
GG1. `od daemon db status` SQLite inventory
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan FF2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the FF-series shipped this turn:
FF1. `od plugin verify <id>` CI meta-command
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan EE2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the EE-series shipped this turn:
EE1. `od plugin simulate <id>` pipeline dry-run
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan DD3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the DD-series shipped this turn:
DD1. `od plugin stats` inventory health report
DD2. `od plugin canon --check <expected-file>` byte-equality fixtures
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan CC2 — sync CHANGELOG.md with the CC-series shipped this turn:
CC1. `od plugin canon <snapshotId>` show canonical prompt block
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan BB3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the BB-series shipped this turn:
BB1. `od plugin snapshots show <id>`
BB2. `od plugin snapshots diff <a> <b>` + diffSnapshots() helper
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan AA3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the AA-series shipped this turn:
AA1. `od plugin diff <a> <b>` author tooling
AA2. `od atoms info <id>` + atom catalog drift fix
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan Z3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the Z-series shipped this turn:
Z1. patch-edit atomic file writes (Phase 7 safety patch)
Z2. `od plugin upgrade <id>` re-install from recorded source
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan Y2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the Y-series shipped this turn:
Y1. `od plugin search <query>` + filters on `od plugin list`
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan X2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the X-series shipped this turn:
X1. `od plugin pack <folder>` distribution archive
The Phase 4 author dev-loop is now closed end-to-end:
od plugin scaffold --id <id> # bootstrap a folder
od plugin validate <folder> # lint before install
od plugin pack <folder> # build a .tgz archive
od plugin install --source <path> # install (local OR https)
od plugin export <projectId> # build a publish-ready folder
od plugin publish ... # generate catalog PR link
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan W2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the W-series shipped this turn:
W1. `od plugin validate <folder>` author-side lint
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan V2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the V-series shipped this turn:
V1. OD_BUNDLED_ATOM_PROMPTS default flipped to ON
Living plan now reads:
Phase 4 \u2192 'full incl. OD_BUNDLED_ATOM_PROMPTS default ON'
Remaining backlog: postgres adapter wiring inside the DaemonDb
resolver — the only stubbed item left.
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan U2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the U-series shipped this turn:
U1. S3ProjectStorage live impl via AWS SigV4
Living plan now reads:
Phase 5 \u2192 'full incl. live S3 impl; postgres adapter still stubbed'
Remaining backlog:
- Promote OD_BUNDLED_ATOM_PROMPTS=1 to default (audit-blocked)
- Postgres adapter wiring inside DaemonDb resolver
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan T3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the T-series shipped this turn:
T1. runAndPersistHandoff() + auto-handoff from diff-review bridge
T2. figma-migration pipeline e2e smoke test
Phase 8 promotion ladder now closes end-to-end without an agent turn:
GenUI Accept \u2192 review/decision.json + handoff/manifest.json with
handoffKind set.
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan S3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the S-series shipped this turn:
S1. runHandoffAtom() pipeline-driven promotion-ladder bridge
S2. Full code-migration pipeline e2e smoke test
Living plan now records:
Phase 7 \u2705 + 'full pipeline e2e covered by smoke test'
Phase 8 \u2705 + 'handoff promotion ladder bridge landed'
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan R2 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the R-series shipped this turn:
R1. diff-review GenUI \u2192 review/decision.json bridge
Living plan now reads:
Phase 8 → \u2705 COMPLETE end-to-end. Patch substrate +
diff-review atom + auto-surface + native UI mount + GenUI \u2192
runDiffReview bridge all landed.
Phase 6 → \u2705 COMPLETE.
Phase 7 → \u2705 COMPLETE.
Remaining backlog:
- Promote OD_BUNDLED_ATOM_PROMPTS=1 to default (audit-blocked)
- AWS SDK wiring inside S3ProjectStorage
- Postgres adapter wiring inside DaemonDb resolver
Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan Q3 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the Q-series shipped this turn:
Q1. Native diff-review UI on GenUISurfaceRenderer (Phase 8 entry slice)
Q2. figma-extract asset rasterisation second pass (Phase 6 entry slice)
Living plan now reads:
Phase 6 → COMPLETE: figma-extract REST + token-map crosswalk +
asset rasterisation second pass via GET /v1/images.
Phase 8 → patch + review + auto-surface + native review UI all
landed. The remaining slice is wiring the GenUI response back
through runDiffReview() to auto-update review/decision.json
(today the daemon stores the response on the run; the
diff-review runner reads it on next invocation).
Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan P4 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the P-series shipped this turn:
P1. token-map atom impl (Phase 6/7 entry slice)
P2. figma-extract atom impl (Phase 6 entry slice)
P3. Auto-derived choice surface for diff-review (Phase 8 entry slice)
Living plan now reads:
Phase 6 → COMPLETE: figma-extract REST shell-out + token-map
crosswalk both implemented. Bundled scenario plugin
od-figma-migration ships the canonical pipeline. Asset
rasterisation second pass (offlineAssets=false) stays
scheduled.
Phase 7 → COMPLETE (continued from O-series): all six atom impls.
Phase 8 → patch + review + auto-surface substrate landed; native
UI mount in the web composer stays scheduled.
Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.
Co-authored-by: Tom Huang <1043269994@qq.com>
Plan O6 — sync docs/plans/plugins-implementation.md and CHANGELOG.md
with the O-series shipped this turn:
O1. Bundled-scenario pipeline fallback resolver (spec §23.3.3)
O2. design-extract atom impl (Phase 6/7 entry slice)
O3. rewrite-plan atom impl (Phase 7 entry slice)
O4. patch-edit atom impl (Phase 7 entry slice)
O5. diff-review atom impl (Phase 7-8 entry slice)
Living plan now reads:
Phase 7 → ALL SIX atoms IMPLEMENTED (build-test + code-import +
design-extract + rewrite-plan + patch-edit + diff-review).
Bundled scenario plugin od-code-migration ships the canonical
pipeline. Live HTTP wiring for the per-stage runner stays
scheduled.
Phase 8 → patch + review substrate landed; native review-and-apply
UI mounting diff-review through a GenUI choice surface stays
scheduled.
Phase 6 → SKILL.md substrate + scenario plugin registered;
design-extract impl is reused under the figma-migration
flow as well.
Changelog names every shipped surface so a reviewer can audit the
delta without reading the plan.
Co-authored-by: Tom Huang <1043269994@qq.com>
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
- Pipeline runner wired into POST /api/runs (e2e-3 full §8 contract).
- od doctor (repo-wide diagnostics) + od config get/set/list/unset.
- Phase 4 §23 entry slice — bundled atom plugins + boot walker.
docs/plans/plugins-implementation.md §3 / §6 / §8 / §9 flipped:
- Architecture-state table records scaffold / export / publish /
bundled / plugins/_official/atoms as shipped.
- §6 Phase 4 deliverable list flips bundled atom extraction +
full CLI parity remainder; the system.ts → SKILL.md prompt
rewiring stays open as the next planned PR.
- §8 e2e-3 row flips from entry-slice to full §8 contract:
plugins-headless-run.test.ts asserts the first SSE event on a
pipeline-bearing run is pipeline_stage_started.
- §9 Status snapshot updated; head of the queue is now
composeSystemPrompt() reading atom fragments from
plugins/_official/atoms/<atom>/SKILL.md, then the AG-UI adapter,
then Phase 5 Docker image.
Final gates: pnpm guard ✓, daemon 1481 tests ✓, web 586 tests ✓.
Co-authored-by: Tom Huang <1043269994@qq.com>
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
- Phase 4 publish CLI (od plugin publish --to <catalog> [--open]).
- CLI parity remainder (od atoms / skills / design-systems / craft /
status / version).
- od marketplace search across configured catalogs.
docs/plans/plugins-implementation.md §3 / §6 / §9 flipped:
- The CLI table records publish + atoms + skills + design-systems +
craft + status + version + marketplace search as shipped, with the
only remaining open verbs being od doctor + od config get/set/list.
- Phase 4 deliverable list flips publish to shipped.
- Status snapshot moves marketplace search and library CLI parity
out of next-planned and into shipped; head of the queue is now the
pipeline-runner-into-startChatRun integration plus Phase 4 atom
migration into plugins/_official/ and the AG-UI adapter package.
Final gates: pnpm guard ✓, daemon 1475 tests ✓, web 586 tests ✓.
Co-authored-by: Tom Huang <1043269994@qq.com>
CHANGELOG.md ## Unreleased gets a new bullet block summarising:
- Phase 4 author tooling: od plugin scaffold + od plugin export with
provenance README + claude-plugin / agent-skill targets.
- Phase 2B marketplace deep UI: /marketplace + /marketplace/:id
routes, MarketplaceView grid + filters + configured catalogs panel,
PluginDetailView with capability + connector + GenUI surface
summaries plus a 'Use this plugin' button.
- Phase 2B ChatComposer mount of PluginsSection.
- docs/atoms.md as the canonical first-party atom catalog reference.
docs/plans/plugins-implementation.md §3 / §6 / §9 flipped:
- The web component table now records MarketplaceView + PluginDetailView
as shipped (with the routes attached) and the ChatComposer rail mount
flipped from absent → shipped.
- The CLI table records od plugin scaffold + od plugin export as
shipped Phase 4 deliverables; od plugin publish stays absent.
- The Phase 4 deliverable list flips: docs/atoms.md, scaffold, export,
and run shorthand are all checked. Atom migration into
plugins/_official/, AG-UI adapter, plugin manifest .component
capability, and CLI parity remainder stay open.
- §9 Status snapshot updated; next-planned-PR cell moves the
pipeline-runner-into-startChatRun integration to the head of the
queue and points at the remaining Phase 4 / 5 backlog.
Final gates: pnpm guard ✓, daemon 1465 tests ✓, web 586 tests ✓.
Co-authored-by: Tom Huang <1043269994@qq.com>
CHANGELOG.md gets a new bullet block summarising:
- Phase 1 follow-up CLI (od project / run / files / conversation).
- Phase 1.5 headless lifecycle (od daemon start --headless / --serve-web /
status / stop) with backing /api/daemon/status + /api/daemon/shutdown.
- Phase 3 'od plugin install <name>' resolution through configured
marketplaces.
- Web composer mount: PluginsSection + NewProjectPanel integration.
docs/plans/plugins-implementation.md §3 / §6 / §8 / §9 flipped:
- The Phase 1.5 deliverable list moves from open boxes to shipped
rows.
- The CLI table moves od project / run / files / conversation /
daemon to shipped, with the lone remaining deferrals (od files
diff, od project import, od conversation new, od marketplace
search) called out explicitly.
- The web component table records PluginsSection + the
NewProjectPanel mount as shipped, with the deeper ChatComposer
mount + MarketplaceView + PluginDetailView still scheduled for
Phase 2B.
- Phase 3 marks 'od plugin install <name>' as shipped; the Phase 3
items still open are: trust UI, bundle-plugin installer, full
doctor expansion.
- §8 e2e-3 flips to entry-slice complete (HTTP-layer walkthrough);
the live-agent-loop integration moves to the next-planned-PR cell.
- §9 Status snapshot updated.
Final gates green: pnpm guard ✓, daemon 1455 tests ✓, web 579 tests ✓.
Co-authored-by: Tom Huang <1043269994@qq.com>