Improve the Colophon canvas plugin: authority model, theming, sticky chrome, floating validation, collapsible setup - #3
Merged
Conversation
Colophon hard-coded one authority model: .agents/design/ is *the source of truth* and Copilot generates UI from it. That's right for web/JSX-first repos (tokens compile to CSS vars) but wrong for native apps (WinUI 3 / XAML), where native XAML/C# + observed behavior are canonical and the JSON/JSX are derived, non-shipping mirrors. Raised by Scott on openclaw-windows-node#962. Introduce an explicit authority.model on design.json (canonical | derived; absent/unknown => canonical, preserving current behavior) plus canonicalSource, maintainer, and syncNote. Thread it through every agent-facing surface: - readAuthority() helper in designio.mjs - buildSummary / sessionStartContext / promptContext flip framing when derived - SKILL.md documents both modes; softens unconditional 'source of truth' - AGENTS.md pointer block emits the 'derived / native wins / maintainer' caveat (ensureAgentsPointer reads authority from design.json) - colophon tool header no longer says 'follow it exactly' for derived systems - plugin.json / marketplace.json / README qualify 'source of truth' - canvas Brand board gains an editable Authority control; scan of a repo with no web styling (the XAML case) proposes a derived system automatically - fix latent evidence.fileCount (was undefined; scan returned scannedFiles) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Design files stay the source of truth for design (framework-agnostic). Replace the canonical/derived toggle with per-surface port targets: an authoritySource (what the surface ships as, e.g. native WinUI 3/C#) and a syncSource (the reference/skill to port design into it, e.g. win-dev-skills), plus an optional helperAgent. App-wide default (authority.port) with per-area overrides (authority.portOverrides), e.g. a React-style chat surface -> Reactor. No port target => files are also the implementation SoT (web/JSX, unchanged). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…cess.cwd() The extension resolved .agents/design/ against a module-global currentWorkdir seeded from process.cwd(). In the app, a forked extension's process.cwd() is the Copilot home dir (not the repo) and sessionRef.workspacePath is the CLI session-state dir - so any tool/canvas invocation without an explicit workingDirectory loaded the wrong repo's design system, leaking one repo's styles into another session. Resolve the workspace strictly from authoritative per-invocation signals: hook input.workingDirectory (required by BaseHookInput) and canvas ctx.session.workingDirectory. The anchor (sessionWorkdir) starts null and is never seeded from process.cwd(); when unknown, loadDesign(null) falls back to the bundled sample - never another repo. Canvas actions now also consult ctx.session.workingDirectory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Addresses review feedback on the design-system authority model: - Colors are preview-only when a port target ships (native impl is canonical); agents bind each color's `resource` key (e.g. WinUI ThemeResource) instead of the preview hex. - Colors carry Light/Dark/High-contrast preview values; canvas gains a theme switch and theme-aware CSS vars / swatches. - Authority gains `owner` (who owns the canonical implementation) and `syncProcess` (how previews stay aligned), plus per-port `owner`. - New validate.mjs smoke-check (schema/parse on design.json + structural check on components.jsx) surfaces drift: a port set without resource mappings, missing owner, or missing syncProcess. Wired to /api/validate, a canvas `validate` action, and a CLI runner (exits non-zero on error). - Agent-facing context reframes design files as design SoT with the shipping implementation canonical when a port exists. - Sample seeds Light/Dark/High-contrast so the toggle/validator are demonstrable out of the box. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- The canvas page background now follows the selected preview theme's app/page background (paper) with matching ink text, and the chrome's neutral tokens (surface/line/ink/muted) are routed through the design system's --color-* vars so the whole inspector — not just the live previews — reflects Light / Dark / High-contrast. - Fix the sticky topbar: body used height:100%, which capped the body box at one viewport so the header unstuck after the first screen of scroll. Switch to min-height:100vh, and drop the stale -24px side margins left over from when the topbar lived inside .wrap. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- The validation result now renders in a fixed infobar pinned just below the sticky topbar (top offset derived from the topbar height, repositioned on resize) instead of inline in the document flow, so it stays visible while scrolling and no longer pushes content down. Opaque background, elevation shadow, and a short slide-in. - The infobar now explains what validate actually checks: design.json parsing + core token groups and components.jsx structure, and — when a native port is declared — the resource/owner/syncProcess breadcrumbs that keep the design files and the shipping app from drifting apart. The copy adapts to whether a port is declared (no port -> drift checks don't apply). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The "Set up a design system" block only appears before setup and is rarely needed once seeded, so make it a collapsible <details> disclosure with a clickable summary header and a rotating chevron. The open/closed choice is remembered best-effort in localStorage and defaults to open so first-run stays guided. Native marker is hidden; keyboard focus ring added. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR reworks the Colophon canvas plugin to make the design-vs-shipping authority model explicit (including optional per-surface “port targets”), and improves the canvas UX with theme-aware chrome, sticky header behavior, a floating validation panel, and a collapsible setup section.
Changes:
- Introduces an explicit authority/port model (
authority, port targets/overrides, resource bindings) and threads it through summaries + AGENTS.md pointer framing. - Adds a validation workflow (CLI +
/api/validate+ canvas action/UI) to smoke-check.agents/design/for schema/syntax and drift signals. - Improves canvas usability: Light/Dark/High-contrast previews, themed chrome tokens, sticky top bar fix, floating validation banner, and collapsible onboarding.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| skills/colophon/SKILL.md | Updates skill guidance to reflect “design leads, implementation ships” and the new authority/port workflow. |
| README.md | Documents authority/port targets and clarifies design intent vs shipped implementation. |
| plugin.json | Updates plugin description to include port targets and the design-vs-implementation model. |
| extensions/colophon/validate.mjs | Adds CLI/API validation for design.json + components.jsx (schema/syntax + drift-related checks). |
| extensions/colophon/styles.css | Makes chrome theme-aware, fixes sticky behavior, adds theme switch + floating validation + collapsible onboarding styles. |
| extensions/colophon/sources.mjs | Seeds authority in scratch tokens; scanner pre-fills port target for “looks native” repos and extends evidence. |
| extensions/colophon/sample/design.json | Adds authority and per-theme color variants to the bundled sample. |
| extensions/colophon/renderer.mjs | Adds theme switch UI and a validation slot near the top bar. |
| extensions/colophon/extension.mjs | Anchors workdir to session signals, adds validate action + /api/validate, and enriches tool messaging for ported repos. |
| extensions/colophon/designio.mjs | Implements authority parsing/normalization + port target rendering, preview-only color behavior, and themed CSS-var emission. |
| extensions/colophon/context.mjs | Injects authority/port target guidance into summaries and hook-provided context. |
| extensions/colophon/client.js | Adds theme switching, authority editor UI, per-theme color editing/preview, floating validation UI, and collapsible onboarding behavior. |
| .github/plugin/marketplace.json | Updates marketplace description to match the new authority/port model. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…me toggle Resolves the actionable Copilot/dual-model review findings on #3: - validate.mjs: the port drift contract (resource mapping on every color, authority.owner, authority.syncProcess) is now an ERROR when a port target is set, not a warning. Previously the CLI exited 0 even with the contract unfulfilled, so CI could not gate drift despite the docs claiming it did. Systems with no port target are unaffected (checks stay dormant). - client.js setColorValueForTheme: editing the Light preview on a color that already carries a themes map now also updates the canonical `value`, so readers that prefer `value` (baseColorValue, summaries, validation) can no longer report a stale hex that disagrees with the light preview. - renderer.mjs / client.js setTheme: theme toggle buttons now carry type="button" and aria-pressed, and setTheme keeps aria-pressed in sync so the selected theme is announced to assistive tech. type="button" added to the other topbar buttons too to avoid any default-submit behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Follow-up to the dual-model review on #3, fixing the two remaining findings: - hasPort() now counts a port target only once it names a source/owner (and overrides only once they name an area/component/source), mirroring the server-side normalization in designio.normPortTarget/readAuthority. Before, toggling a port on and leaving every field blank flipped the canvas into preview-only mode even though the empty port was dropped on save — so what you saw before saving disagreed with what persisted. The local checkbox still keys off object presence (renamed hasDefaultPort) so the fields still appear the instant you toggle it on. - render() now carries a generation counter and discards its post-await component append if a newer render started meanwhile. renderComponents() awaits a CDN fetch on first load, so a theme switch during that window could previously append a duplicate component section. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR reworks the Colophon canvas plugin (
extensions/colophon/) to address the design-authority and drift concerns Scott raised in his review of the OpenClaw seed PR, and layers on a round of canvas UX refinements so the inspector feels like part of the app it documents.Two themes run through the work:
Addresses Scott's review on openclaw/openclaw-windows-node#962 and the follow-up #962 (comment).
Addressing Scott's review
Scott's core objection was that a design system pinning raw hex values fights the real app, which sources its colors from framework-native resources — so the design files and the shipping app would drift, and it was unclear which one wins. The response is an explicit, configurable authority model rather than an implicit one:
microsoft/win-dev-skills; the chat surface (a React-style framework) can point its sync source atmicrosoft/microsoft-ui-reactor. Reactor has no helper agent yet — that's a known WIP and the config allows for it.resource,owner,syncProcess— so agents bind the real native resource instead of hardcoding preview hex (which is exactly how drift starts).validatesmoke-check enforces the contract: if a token declares a port, it must also carry theresource/owner/syncProcessbreadcrumbs that keep the design copy tied to the native copy. It stays quiet when there's no port (nothing to drift).What's in this PR
Authority & sync model
resourcebinding plusownerandsyncProcessmetadata.validate.mjs— a drift smoke-check with a/api/validateendpoint and a canvasvalidateaction. Enforces the port →resource/owner/syncProcesscontract; exits non-zero on errors for CI use.Cross-repo isolation (bug fix)
process.cwd(), so each repo's seeded design stays in that repo only.Canvas UX refinements
--color-*vars.body { height: 100% }capping the body box to one viewport and breakingposition: stickypast the first screen; changed tomin-height: 100vh.aria-live="polite"), with context-aware copy that describes exactly what is checked and adapts to whether a port is declared.<details>disclosure with a clickable summary and rotating chevron. It only appears pre-setup and is rarely needed once seeded, so it can be tucked away; open/closed is remembered best-effort and defaults to open for first-run guidance.Docs
README.mdandskills/colophon/SKILL.mdto describe the authority model, port targets, and thevalidateworkflow.Commits
26f9263Add canonical vs derived authority model to design systems16df81bRework authority into design-SoT + configurable per-area port targets7725657Fix cross-repo design-system leak: anchor workdir to session, not process.cwd()79ae758Add theme variants, resource binding, and validation to Colophona234cb6Theme the inspector background and fix sticky topbar9ba0c61Float the validation result and describe what it checksd4d7e35Make the setup section collapsibleTesting
node --checkon all edited JS;node validate.mjspasses clean on the bundled sample (no port) and produces exactly the expected warnings on a ported seed.read/validate/ theme-switch actions confirmed working across Light / Dark / HC.Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com