@clipbus/plugin-sdk 0.8.5 → 0.8.7
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/dist/preview/chrome.d.ts +34 -10
- package/dist/preview/index.cjs +822 -193
- package/dist/preview/index.d.cts +9 -4
- package/dist/preview/index.d.ts +9 -4
- package/dist/preview/index.js +822 -193
- package/dist/preview/inputPanel.d.ts +57 -0
- package/dist/preview/styles.d.ts +18 -14
- package/docs/preview.md +74 -11
- package/package.json +1 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire Input panel — collapsible sections for the full WirePayloads snapshot.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Classify wire sections into ordered content / infra groups.
|
|
6
|
+
* - Parse embedded payloadJson strings into readable nested JSON (or raw fallback).
|
|
7
|
+
* - Render the collapsible section DOM into a container element.
|
|
8
|
+
*
|
|
9
|
+
* Per-section toggle is INDEPENDENT (not single-open); single-open behaviour is
|
|
10
|
+
* the OUT accordion's contract only.
|
|
11
|
+
*
|
|
12
|
+
* Pure functions (classifyWireSections, parsePayloadJson) are exported for unit
|
|
13
|
+
* testing, following the same convention as groupScenariosByMode in chrome.ts.
|
|
14
|
+
*/
|
|
15
|
+
import type { WirePayloads } from './wire.js';
|
|
16
|
+
export interface WireSection {
|
|
17
|
+
/** The payload key name (e.g. 'context', 'item', 'attachment'). */
|
|
18
|
+
key: string;
|
|
19
|
+
/** content = item + attachment/draft (user-facing data; open by default).
|
|
20
|
+
* infra = context + theme + locale (plumbing; collapsed by default). */
|
|
21
|
+
kind: 'content' | 'infra';
|
|
22
|
+
/** Whether the section is expanded when first rendered. */
|
|
23
|
+
defaultOpen: boolean;
|
|
24
|
+
/** The raw payload value for this key. */
|
|
25
|
+
value: unknown;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Classify wire payload sections into display order with open/collapsed defaults.
|
|
29
|
+
*
|
|
30
|
+
* Fixed order: context · item · attachment(renderer)/draft(action) · theme · locale
|
|
31
|
+
* content: item + attachment/draft — defaultOpen true (user compares these with output)
|
|
32
|
+
* infra: context + theme + locale — defaultOpen false (plumbing, low signal)
|
|
33
|
+
*/
|
|
34
|
+
export declare function classifyWireSections(payloads: WirePayloads): WireSection[];
|
|
35
|
+
/**
|
|
36
|
+
* Parse a raw value as JSON; never throws.
|
|
37
|
+
*
|
|
38
|
+
* Returns `{ ok: true, value }` when `raw` is a string that JSON.parse()s
|
|
39
|
+
* successfully. Returns `{ ok: false, raw }` on any failure — the caller
|
|
40
|
+
* renders `raw` verbatim (Fail loud: the parse failure is visible, not silent).
|
|
41
|
+
*/
|
|
42
|
+
export declare function parsePayloadJson(raw: unknown): {
|
|
43
|
+
ok: true;
|
|
44
|
+
value: unknown;
|
|
45
|
+
} | {
|
|
46
|
+
ok: false;
|
|
47
|
+
raw: unknown;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Build (or replace) the Wire Input collapsible sections inside `containerEl`.
|
|
51
|
+
*
|
|
52
|
+
* Called on each scenario activation and theme change (the theme section
|
|
53
|
+
* reflects the new preset). Re-calling clears and rebuilds all sections.
|
|
54
|
+
*
|
|
55
|
+
* Sections are independently togglable — opening one does NOT collapse others.
|
|
56
|
+
*/
|
|
57
|
+
export declare function renderWireInput(containerEl: HTMLElement, payloads: WirePayloads): void;
|
package/dist/preview/styles.d.ts
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CSS for the preview workbench chrome.
|
|
2
|
+
* CSS for the Wire Bench preview workbench chrome.
|
|
3
3
|
* Injected as a <style> tag at runtime — no framework required.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* Design: Wire Bench (2026-06-28).
|
|
6
|
+
* - Stable chrome palette (--bench-* tokens) decoupled from native theme
|
|
7
|
+
* presets — the instrument background never changes; only the specimen
|
|
8
|
+
* card + plugin slot recolour when the theme picker switches. This
|
|
9
|
+
* intentionally reverses the prior native-fidelity D3 decision (backdrop
|
|
10
|
+
* was theme-synced). See spec §5.1 and preview.md §theme-decoupling.
|
|
11
|
+
* - Blueprint grid background, Space Grotesk + IBM Plex Mono type system.
|
|
12
|
+
* - Layout: header(controls) + horizontal rule + stage(workspace + dock).
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* Frozen geometry (pixel-identical to HEAD — do not change):
|
|
15
|
+
* .cbp-wb__card-shell — 10px padding / 7px radius / 1px tint border / surfaceElevated bg
|
|
16
|
+
* .cbp-wb__viewport — max-height 800px / overflow-y auto
|
|
17
|
+
* .cbp-wb__webview — width/height 100%
|
|
18
|
+
* .cbp-wb__strip — flex left-aligned / gap 10px
|
|
19
|
+
* .cbp-wb__button — 4px 10px padding / 999px radius
|
|
20
|
+
* Card-side --cbp-wb-* vars are still written by applyTheme() so the card
|
|
21
|
+
* recolours with the theme. The chrome itself uses --bench-* (constant).
|
|
18
22
|
*/
|
|
19
|
-
export declare const previewStyles = "\n/* \u2500\u2500 CSS variable defaults (graphite dark) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb {\n --cbp-wb-backdrop: #16181C;\n --cbp-wb-accent: #43C6AC;\n --cbp-wb-surface-elevated: rgba(35,37,42,.78);\n --cbp-wb-border: rgba(255,255,255,.10);\n --cbp-wb-text: #F3F4F6;\n --cbp-wb-text-secondary: #C2C6CF;\n}\n\n/* \u2500\u2500 Root chrome \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb {\n min-height: 100%;\n padding: 24px;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n font-size: 13px;\n box-sizing: border-box;\n color: var(--cbp-wb-text);\n background: var(--cbp-wb-backdrop);\n}\n\n*, .cbp-wb * {\n box-sizing: border-box;\n}\n\n/* \u2500\u2500 Theme-aware scrollbars \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* The default OS / WebKit scrollbar is an opaque bar (white on dark themes)\n that reads as jarring. Restyle every scroll area under the workbench \u2014 chrome\n (log panel) AND plugin content inside the slot \u2014 into a thin, translucent,\n theme-synced overlay that mirrors the native host's subtle scrollbars. The\n --cbp-wb-* vars cascade from the workbench root into the plugin slot, so one\n rule set covers both surfaces and recolours automatically on theme switch. */\n.cbp-wb,\n.cbp-wb * {\n scrollbar-width: thin;\n scrollbar-color: color-mix(in srgb, var(--cbp-wb-text-secondary) 30%, transparent) transparent;\n}\n\n.cbp-wb ::-webkit-scrollbar {\n width: 9px;\n height: 9px;\n}\n\n.cbp-wb ::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.cbp-wb ::-webkit-scrollbar-thumb {\n background-color: color-mix(in srgb, var(--cbp-wb-text-secondary) 30%, transparent);\n border-radius: 999px;\n border: 2px solid transparent;\n background-clip: padding-box;\n}\n\n.cbp-wb ::-webkit-scrollbar-thumb:hover {\n background-color: color-mix(in srgb, var(--cbp-wb-text-secondary) 50%, transparent);\n background-clip: padding-box;\n}\n\n.cbp-wb ::-webkit-scrollbar-corner {\n background: transparent;\n}\n\n/* \u2500\u2500 Controls bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__controls {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: flex-end;\n margin-bottom: 20px;\n}\n\n.cbp-wb__control {\n display: grid;\n gap: 6px;\n}\n\n.cbp-wb__control-label {\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--cbp-wb-text-secondary);\n}\n\n.cbp-wb__control select,\n.cbp-wb__scenario-select {\n min-width: 160px;\n padding: 10px 12px;\n border-radius: 12px;\n border: 1px solid var(--cbp-wb-border);\n background: color-mix(in srgb, var(--cbp-wb-backdrop) 70%, transparent);\n color: var(--cbp-wb-text);\n font-size: 13px;\n font-family: inherit;\n}\n\n/* \u2500\u2500 Width slider \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__width-slider {\n width: 140px;\n accent-color: var(--cbp-wb-accent);\n cursor: pointer;\n}\n\n/* \u2500\u2500 Canvas layout (host frame on top, native-call log below) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__canvas {\n display: flex;\n flex-direction: column;\n gap: 20px;\n align-items: center;\n}\n\n/* Host frame hugs the fixed-width viewport (no flex:1 stretch) so a wide\n browser window leaves neutral backdrop on the sides instead of a large\n empty framed area \u2014 the centered, native-like card the viewport expects. */\n.cbp-wb__host-frame {\n min-width: 0;\n padding: 16px;\n border-radius: 16px;\n background: color-mix(in srgb, var(--cbp-wb-surface-elevated) 40%, transparent);\n border: 1px solid var(--cbp-wb-border);\n display: flex;\n flex-direction: column;\n align-items: center;\n}\n\n/* \u2500\u2500 Frame title \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__frame-title {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 12px;\n font-size: 12px;\n font-weight: 700;\n letter-spacing: 0.04em;\n color: var(--cbp-wb-text-secondary);\n width: 100%;\n}\n\n/* \u2500\u2500 Viewport shell: centers the viewport horizontally \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__viewport-shell {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n width: 100%;\n}\n\n/* Body clip box. NO border-radius of its own \u2014 the card shell (its parent)\n owns the rounding. A radius here would clip the card's own corners/border. */\n.cbp-wb__viewport {\n width: 100%;\n /* Native hard ceiling (AttachmentRenderHeightConstants.ceiling = 800): the\n body never grows past this even under the 'auto' content-driven policy. */\n max-height: 800px;\n /* At the ceiling, content SCROLLS inside the (fixed) card chrome \u2014 it does\n not clip away or push the card taller. */\n overflow-y: auto;\n overflow-x: hidden;\n transition: height 0.1s ease;\n}\n\n/* \u2500\u2500 Native card shell \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Geometry source: AttachmentRenderCardShell.swift:24-59 */\n/* 10 pt padding / 7 pt continuous radius / 1 pt accent border / elevated bg */\n/* Outer card: stacks the body (viewport) above the host action strip, like */\n/* native VStack { body; actions }. Width is set inline; height auto-wraps. */\n.cbp-wb__card-shell {\n display: flex;\n flex-direction: column;\n gap: 8px; /* native cardSpacing: body \u2194 action strip */\n padding: 10px; /* native cardPadding */\n border-radius: 7px; /* native radius.panelInner (replaces the 20px viewport clip) */\n /* Border tint = the attachment's tintColor (--cbp-wb-card-tint, set per\n scenario from scenario.accentHex), falling back to the theme accent \u2014\n mirrors native, where the card border uses record.tintColor. */\n border: 1px solid color-mix(in srgb, var(--cbp-wb-card-tint, var(--cbp-wb-accent)) 26%, transparent);\n background: var(--cbp-wb-surface-elevated);\n /* No box-shadow per native spec */\n}\n\n.cbp-wb__webview {\n width: 100%;\n height: 100%;\n /* Fixed/bounded body shorter than its content \u2192 scroll inside. (Only the one\n element whose content actually exceeds its box scrolls, so there is never a\n double scrollbar: in 'auto' the viewport scrolls; in fixed/bounded the\n webview does.) */\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* \u2500\u2500 Host button strip (inside the card, below the body) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Native action row: HStack { buttons; Spacer } \u2192 left-aligned, compact. */\n.cbp-wb__strip {\n display: flex;\n flex-wrap: wrap;\n gap: 10px; /* native action HStack spacing */\n justify-content: flex-start; /* left-aligned, not centered */\n}\n\n/* No buttons \u2192 no strip box, and the card's flex gap reserves nothing. */\n.cbp-wb__strip:empty {\n display: none;\n}\n\n.cbp-wb__button {\n appearance: none;\n border: 1px solid var(--cbp-wb-border);\n border-radius: 999px;\n padding: 4px 10px; /* native actionPadding \u2248 3 v / 8 h \u2014 was 10/16 (too large) */\n background: color-mix(in srgb, var(--cbp-wb-surface-elevated) 60%, transparent);\n color: var(--cbp-wb-text-secondary);\n font-size: 12px;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n}\n\n.cbp-wb__button--primary {\n background: var(--cbp-wb-accent);\n color: var(--cbp-wb-backdrop);\n border-color: var(--cbp-wb-accent);\n}\n\n/* \u2500\u2500 Log panel (fixed-width right column) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__log {\n width: 100%;\n max-width: 720px;\n padding: 14px 16px;\n border-radius: 16px;\n background: color-mix(in srgb, var(--cbp-wb-surface-elevated) 50%, transparent);\n border: 1px solid var(--cbp-wb-border);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n gap: 0;\n}\n\n.cbp-wb__log-title {\n margin: 0 0 10px;\n font-size: 12px;\n font-weight: 800;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--cbp-wb-text);\n}\n\n.cbp-wb__log-empty {\n font-size: 12px;\n color: color-mix(in srgb, var(--cbp-wb-text-secondary) 60%, transparent);\n font-style: italic;\n}\n\n.cbp-wb__log-list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n max-height: 220px;\n overflow-y: auto;\n}\n\n.cbp-wb__log-entry {\n border-radius: 8px;\n padding: 8px 10px;\n background: color-mix(in srgb, var(--cbp-wb-surface-elevated) 60%, transparent);\n font-family: ui-monospace, \"SFMono-Regular\", Menlo, monospace;\n font-size: 11px;\n line-height: 1.5;\n word-break: break-all;\n}\n\n.cbp-wb__log-entry-method {\n font-weight: 700;\n color: var(--cbp-wb-accent);\n}\n\n.cbp-wb__log-entry-seq {\n font-weight: 400;\n color: var(--cbp-wb-text-secondary);\n margin-left: 6px;\n}\n\n.cbp-wb__log-entry-payload {\n margin-top: 2px;\n color: var(--cbp-wb-text-secondary);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n";
|
|
23
|
+
export declare const previewStyles = "\n@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');\n\n/* \u2500\u2500 Wire Bench chrome tokens (stable \u2014 independent of native theme preset) \u2500 */\n/* Intentional decoupling: the workbench chrome is a tool, not a specimen. */\n/* The electric violet signal colour (#7B61FF) is chosen to not clash with */\n/* any of the 4 native theme accents (teal / orange / blue / amber). */\n.cbp-wb {\n --bench: #14161D;\n --bench-2: #1A1D26;\n --bench-3: #222634;\n --bench-line: rgba(152,164,196,.12);\n --bench-line-2: rgba(152,164,196,.20);\n --bench-ink: #E8EAF2;\n --bench-ink-dim: #969EB2;\n --bench-ink-faint: #646B7E;\n --bench-signal: #7B61FF;\n --bench-signal-2: #B9A8FF;\n --bench-signal-soft: rgba(123,97,255,.16);\n}\n\n/* \u2500\u2500 Card-side theme vars (graphite defaults; applyTheme() overwrites these) \u2500 */\n/* These track the active preset so the specimen card (card-shell / buttons) */\n/* still recolours when the theme picker changes \u2014 native fidelity for the */\n/* card interior. The chrome itself never reads these for its own background. */\n.cbp-wb {\n --cbp-wb-backdrop: #16181C;\n --cbp-wb-accent: #43C6AC;\n --cbp-wb-surface-elevated: rgba(35,37,42,.78);\n --cbp-wb-border: rgba(255,255,255,.10);\n --cbp-wb-text: #F3F4F6;\n --cbp-wb-text-secondary: #C2C6CF;\n}\n\n/* \u2500\u2500 Root chrome \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Background uses --bench (stable), not --cbp-wb-backdrop (theme-driven). */\n/* Blueprint grid is a visual signature of the instrument chrome. */\n.cbp-wb {\n min-height: 100%;\n padding: 28px 26px 34px;\n font-family: \"Space Grotesk\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n font-size: 14px;\n box-sizing: border-box;\n color: var(--bench-ink);\n background:\n linear-gradient(var(--bench-line) 1px, transparent 1px),\n linear-gradient(90deg, var(--bench-line) 1px, transparent 1px),\n var(--bench);\n background-size: 32px 32px, 32px 32px, auto;\n background-position: -1px -1px, -1px -1px, 0 0;\n -webkit-font-smoothing: antialiased;\n}\n\n*, .cbp-wb * {\n box-sizing: border-box;\n}\n\n/* \u2500\u2500 Theme-aware scrollbars \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Restyle every scroll area \u2014 chrome AND plugin content inside the slot \u2014 */\n/* into a thin, translucent bench-toned overlay. Uses bench-ink-dim (stable) */\n/* rather than --cbp-wb-text-secondary so the scrollbar doesn't recolour */\n/* when the theme switches (intentional \u2014 chrome palette is stable). */\n/* The --cbp-wb-* vars still cascade into the plugin slot for its own use. */\n.cbp-wb,\n.cbp-wb * {\n scrollbar-width: thin;\n scrollbar-color: color-mix(in srgb, var(--bench-ink-dim) 30%, transparent) transparent;\n}\n\n.cbp-wb ::-webkit-scrollbar {\n width: 9px;\n height: 9px;\n}\n\n.cbp-wb ::-webkit-scrollbar-track {\n background: transparent;\n}\n\n.cbp-wb ::-webkit-scrollbar-thumb {\n background-color: color-mix(in srgb, var(--bench-ink-dim) 30%, transparent);\n border-radius: 999px;\n border: 2px solid transparent;\n background-clip: padding-box;\n}\n\n.cbp-wb ::-webkit-scrollbar-thumb:hover {\n background-color: color-mix(in srgb, var(--bench-ink-dim) 50%, transparent);\n background-clip: padding-box;\n}\n\n.cbp-wb ::-webkit-scrollbar-corner {\n background: transparent;\n}\n\n/* \u2500\u2500 Header: brand wordmark + controls console \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__header {\n display: flex;\n justify-content: space-between;\n align-items: flex-end;\n gap: 24px;\n flex-wrap: wrap;\n margin-bottom: 16px;\n}\n\n.cbp-wb__brand {\n display: flex;\n flex-direction: column;\n gap: 5px;\n}\n\n.cbp-wb__brand-sn {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11.5px;\n letter-spacing: .16em;\n color: var(--bench-ink-faint);\n text-transform: uppercase;\n}\n\n.cbp-wb__brand-mark {\n font-size: 28px;\n font-weight: 700;\n letter-spacing: -.01em;\n line-height: 1;\n}\n\n.cbp-wb__brand-mark b { color: var(--bench-signal-2); }\n.cbp-wb__brand-mark span { color: var(--bench-ink); }\n\n/* \u2500\u2500 Controls console (Surface / Scenario / Theme / Width) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__controls {\n display: flex;\n gap: 11px;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n.cbp-wb__control {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.cbp-wb__control-label {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11px;\n letter-spacing: .14em;\n text-transform: uppercase;\n color: var(--bench-ink-faint);\n}\n\n/* Scenario + Theme selects */\n.cbp-wb__control select,\n.cbp-wb__scenario-select {\n background: var(--bench-2);\n border: 1px solid var(--bench-line);\n border-radius: 11px;\n color: var(--bench-ink);\n font: inherit;\n font-size: 13px;\n padding: 8px 13px;\n min-width: 158px;\n}\n\n/* Width slider */\n.cbp-wb__width-slider {\n accent-color: var(--bench-signal);\n width: 128px;\n cursor: pointer;\n}\n\n/* Current width value shown inline with the label */\n.cbp-wb__width-val {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n color: var(--bench-ink-dim);\n}\n\n/* \u2500\u2500 Horizontal rule separating header from stage \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__rule {\n height: 1px;\n background: var(--bench-line);\n margin: 0 0 22px;\n}\n\n/* \u2500\u2500 Stage: workspace (hero) left + dock right \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__stage {\n display: flex;\n gap: 22px;\n align-items: flex-start;\n}\n\n/* \u2500\u2500 Workspace \u2014 hero, fills the left column \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__workspace {\n flex: 1 1 auto;\n min-width: 0;\n display: flex;\n flex-direction: column;\n}\n\n.cbp-wb__ws-head {\n display: flex;\n align-items: baseline;\n gap: 13px;\n margin-bottom: 13px;\n}\n\n.cbp-wb__ws-kicker {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n font-weight: 600;\n letter-spacing: .2em;\n color: var(--bench-signal-2);\n}\n\n.cbp-wb__ws-title {\n font-size: 23px;\n font-weight: 700;\n letter-spacing: -.01em;\n}\n\n.cbp-wb__ws-sub {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n color: var(--bench-ink-faint);\n}\n\n/* Mode + scenario chip \u2014 right-aligned in the ws-head */\n.cbp-wb__ws-chip {\n margin-left: auto;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n color: var(--bench-ink-dim);\n background: var(--bench-2);\n border: 1px solid var(--bench-line);\n border-radius: 9px;\n padding: 6px 11px;\n white-space: nowrap;\n}\n\n/* \u2500\u2500 Workspace surface \u2014 glass stage that holds the specimen card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* min-height fills the viewport column height (hero). The card is anchored */\n/* at the top; excess space becomes the \"growth floor\" labelling the 800 cap. */\n.cbp-wb__ws-surface {\n position: relative;\n border: 1px solid var(--bench-line);\n border-radius: 18px;\n background:\n radial-gradient(120% 64% at 50% 0%, var(--bench-signal-soft), transparent 56%),\n var(--bench-2);\n min-height: calc(100vh - 150px);\n padding: 34px 36px 18px;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n overflow: auto;\n}\n\n/* Violet accent line across the top edge \u2014 signal that this is live */\n.cbp-wb__ws-surface::before {\n content: \"\";\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n height: 2px;\n background: linear-gradient(90deg, transparent, var(--bench-signal-soft), transparent);\n}\n\n/* Small tape label anchored top-left inside the surface */\n.cbp-wb__ws-tape {\n position: absolute;\n top: 13px;\n left: 20px;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11px;\n letter-spacing: .14em;\n text-transform: uppercase;\n color: var(--bench-ink-faint);\n}\n\n/* Wrapper that provides a positioning context for the \"card internals\" tag */\n.cbp-wb__specimen-wrap {\n position: relative;\n margin-top: 20px;\n}\n\n/* Dimensions readout (WxH) below the specimen */\n.cbp-wb__ws-dims {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n color: var(--bench-ink-faint);\n letter-spacing: .06em;\n}\n\n/* Growth floor \u2014 pushes to the bottom of the surface, labels the 800 ceiling */\n/* Turns the blank space below the card into meaningful information: */\n/* \"this gap is the room left before the native height cap\". */\n.cbp-wb__ws-floor {\n margin-top: auto;\n width: 100%;\n padding-top: 16px;\n border-top: 1px dashed var(--bench-line-2);\n display: flex;\n justify-content: center;\n gap: 10px;\n align-items: center;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11.5px;\n letter-spacing: .07em;\n color: var(--bench-ink-faint);\n}\n\n.cbp-wb__ws-floor-pip {\n color: var(--bench-signal-2);\n font-size: 13px;\n}\n\n/* \u2500\u2500 Dock \u2014 two attachment cards, position:sticky \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Sticks to the top so the workspace can grow vertically without pushing */\n/* the OUT card out of view. Right column is always in frame. */\n.cbp-wb__dock {\n flex: 0 0 470px;\n position: sticky;\n top: 8px;\n align-self: flex-start;\n max-height: calc(100vh - 54px);\n overflow: auto;\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n/* \u2500\u2500 Attachment card (IN and OUT share this shell) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cbp-wb__att {\n position: relative;\n background: var(--bench-2);\n border: 1px solid var(--bench-line);\n border-radius: 18px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.cbp-wb__att-head {\n display: flex;\n align-items: center;\n gap: 11px;\n padding: 14px 17px;\n border-bottom: 1px solid var(--bench-line);\n flex: none;\n}\n\n.cbp-wb__att-code {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n font-weight: 600;\n letter-spacing: .16em;\n color: var(--bench-signal-2);\n}\n\n.cbp-wb__att-title {\n font-size: 15.5px;\n font-weight: 700;\n}\n\n.cbp-wb__att-dir {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11.5px;\n color: var(--bench-ink-faint);\n}\n\n.cbp-wb__att-meta {\n margin-left: auto;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n color: var(--bench-ink-dim);\n}\n\n.cbp-wb__att-scroll {\n overflow: auto;\n padding: 7px 0;\n}\n\n.cbp-wb__att--in .cbp-wb__att-scroll { max-height: 474px; }\n.cbp-wb__att--out .cbp-wb__att-scroll { max-height: 320px; }\n\n/* \u2500\u2500 Wire Input sections (IN panel \u2014 host\u2192plugin) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Section dividers; first child has no top border. */\n.cbp-wb__wire-sec {\n border-top: 1px solid var(--bench-line);\n}\n\n.cbp-wb__wire-sec:first-child {\n border-top: 0;\n}\n\n/* Clickable header row: chevron + key + kind tag + collapsed summary */\n.cbp-wb__wire-sec-head {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 11px 17px;\n cursor: pointer;\n user-select: none;\n}\n\n.cbp-wb__wire-sec-chev {\n font-size: 10px;\n width: 10px;\n color: var(--bench-ink-faint);\n flex: none;\n}\n\n.cbp-wb__wire-sec--open .cbp-wb__wire-sec-chev {\n color: var(--bench-signal-2);\n}\n\n.cbp-wb__wire-sec-key {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 13px;\n font-weight: 600;\n color: var(--bench-ink);\n}\n\n.cbp-wb__wire-sec-tag {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 10.5px;\n color: var(--bench-ink-faint);\n letter-spacing: .04em;\n border: 1px solid var(--bench-line);\n border-radius: 5px;\n padding: 1px 6px;\n}\n\n/* Content sections are highlighted \u2014 these are the user-facing payloads */\n.cbp-wb__wire-sec-tag--content {\n color: var(--bench-signal-2);\n border-color: color-mix(in srgb, var(--bench-signal) 35%, transparent);\n}\n\n.cbp-wb__wire-sec-sum {\n margin-left: auto;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11.5px;\n color: var(--bench-ink-faint);\n max-width: 44%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Collapsible payload body \u2014 hidden until the section is open */\n.cbp-wb__wire-sec-body {\n display: none;\n padding: 0 17px 14px 32px;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 13px;\n line-height: 1.65;\n white-space: pre;\n color: var(--bench-ink);\n overflow-x: auto;\n}\n\n.cbp-wb__wire-sec--open .cbp-wb__wire-sec-body {\n display: block;\n}\n\n/* \u2500\u2500 Native Calls accordion (OUT panel \u2014 plugin\u2192host) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Single-open: exactly one entry is expanded at a time. Newest entry auto- */\n/* opens on arrival and collapses all prior entries. Clicking an open entry */\n/* closes it; clicking a closed entry opens it and closes the rest. */\n.cbp-wb__calls {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 11px 15px;\n}\n\n/* Empty-state label shown before any calls arrive */\n.cbp-wb__calls-empty {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12px;\n color: var(--bench-ink-faint);\n padding: 12px 17px;\n font-style: italic;\n}\n\n/* .cbp-wb__log-entry \u2014 ONE per native call (class name frozen by tests and */\n/* native fidelity contract). Serves as the accordion item outer shell. */\n.cbp-wb__log-entry {\n background: var(--bench-3);\n border: 1px solid var(--bench-line);\n border-radius: 11px;\n overflow: hidden;\n}\n\n/* Open state: signal-tinted border + soft glow */\n.cbp-wb__log-entry--open {\n border-color: color-mix(in srgb, var(--bench-signal) 42%, transparent);\n box-shadow: 0 0 0 1px var(--bench-signal-soft);\n}\n\n/* Clickable top row: chevron + sequence number + method name + summary */\n.cbp-wb__log-entry-top {\n display: flex;\n gap: 10px;\n align-items: center;\n padding: 10px 13px;\n cursor: pointer;\n user-select: none;\n}\n\n.cbp-wb__log-entry-chev {\n font-size: 10px;\n width: 10px;\n color: var(--bench-ink-faint);\n flex: none;\n}\n\n.cbp-wb__log-entry--open .cbp-wb__log-entry-chev {\n color: var(--bench-signal-2);\n}\n\n.cbp-wb__log-entry-seq {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11px;\n color: var(--bench-ink-faint);\n}\n\n/* .cbp-wb__log-entry-method \u2014 method name (class name frozen by tests). */\n.cbp-wb__log-entry-method {\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 13px;\n font-weight: 600;\n color: var(--bench-signal-2);\n}\n\n/* One-line payload summary visible in collapsed state; hidden when expanded */\n.cbp-wb__log-entry-sum {\n margin-left: auto;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 11.5px;\n color: var(--bench-ink-faint);\n max-width: 50%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.cbp-wb__log-entry--open .cbp-wb__log-entry-sum {\n display: none;\n}\n\n/* Collapsible payload body \u2014 shown only when the entry is open */\n.cbp-wb__log-entry-body {\n display: none;\n padding: 0 13px 12px 32px;\n font-family: \"IBM Plex Mono\", ui-monospace, Menlo, monospace;\n font-size: 12.5px;\n line-height: 1.6;\n white-space: pre;\n color: var(--bench-ink);\n overflow-x: auto;\n}\n\n.cbp-wb__log-entry--open .cbp-wb__log-entry-body {\n display: block;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* FROZEN SPECIMEN GEOMETRY \u2014 pixel-identical to HEAD (native measurement */\n/* parity). Class names, padding, radius, border, and overflow rules are all */\n/* verbatim from the prior implementation. Only the surrounding layout */\n/* changed (canvas \u2192 stage / workspace). DO NOT adjust values below. */\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/* Body clip box. NO border-radius of its own \u2014 the card shell (its parent)\n owns the rounding. A radius here would clip the card's own corners/border. */\n.cbp-wb__viewport {\n width: 100%;\n /* Native hard ceiling (AttachmentRenderHeightConstants.ceiling = 800): the\n body never grows past this even under the 'auto' content-driven policy. */\n max-height: 800px;\n /* At the ceiling, content SCROLLS inside the (fixed) card chrome \u2014 it does\n not clip away or push the card taller. */\n overflow-y: auto;\n overflow-x: hidden;\n transition: height 0.1s ease;\n}\n\n/* Native card shell: 10 pt padding / 7 pt radius / 1 pt accent border / elevated bg */\n/* Geometry source: AttachmentRenderCardShell.swift:24-59 */\n/* Outer card stacks the body (viewport) above the host action strip: */\n/* native VStack { body; actions }. Width is set inline; height auto-wraps. */\n.cbp-wb__card-shell {\n display: flex;\n flex-direction: column;\n gap: 8px; /* native cardSpacing: body \u2194 action strip */\n padding: 10px; /* native cardPadding */\n border-radius: 7px; /* native radius.panelInner */\n /* Border tint = the attachment's tintColor (--cbp-wb-card-tint, set per\n scenario from scenario.accentHex), falling back to the theme accent \u2014\n mirrors native, where the card border uses record.tintColor. */\n border: 1px solid color-mix(in srgb, var(--cbp-wb-card-tint, var(--cbp-wb-accent)) 26%, transparent);\n background: var(--cbp-wb-surface-elevated);\n /* No box-shadow per native spec */\n}\n\n.cbp-wb__webview {\n width: 100%;\n height: 100%;\n /* Fixed/bounded body shorter than its content \u2192 scroll inside. (Only the one\n element whose content actually exceeds its box scrolls, so there is never a\n double scrollbar: in 'auto' the viewport scrolls; in fixed/bounded the\n webview does.) */\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* Host button strip (inside the card, below the body) */\n/* Native action row: HStack { buttons; Spacer } \u2192 left-aligned, compact. */\n.cbp-wb__strip {\n display: flex;\n flex-wrap: wrap;\n gap: 10px; /* native action HStack spacing */\n justify-content: flex-start; /* left-aligned, not centered */\n}\n\n/* No buttons \u2192 no strip box, and the card's flex gap reserves nothing. */\n.cbp-wb__strip:empty {\n display: none;\n}\n\n.cbp-wb__button {\n appearance: none;\n border: 1px solid var(--cbp-wb-border);\n border-radius: 999px;\n padding: 4px 10px; /* native actionPadding \u2248 3 v / 8 h */\n background: color-mix(in srgb, var(--cbp-wb-surface-elevated) 60%, transparent);\n color: var(--cbp-wb-text-secondary);\n font-size: 12px;\n font-weight: 600;\n font-family: inherit;\n cursor: pointer;\n}\n\n.cbp-wb__button--primary {\n background: var(--cbp-wb-accent);\n color: var(--cbp-wb-backdrop);\n border-color: var(--cbp-wb-accent);\n}\n\n/* \u2500\u2500 Responsive reflow \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* The side-by-side stage assumes a wide display: the renderer card runs up to\n 900px and must sit beside the 470px dock. Below ~1335px the card would clip\n against the dock. Stack instead \u2014 workspace on top at FULL width (the\n specimen is never clipped), dock below as a row of the two attachment cards.\n The dock drops its sticky behaviour here (it's no longer a side rail). */\n@media (max-width: 1335px) {\n .cbp-wb__stage {\n flex-direction: column;\n }\n /* Surface no longer needs to fill the viewport column \u2014 let it wrap the card\n so the dock below is reachable without a long scroll past empty space. */\n .cbp-wb__ws-surface {\n min-height: 420px;\n }\n .cbp-wb__dock {\n position: static;\n flex: none;\n width: 100%;\n max-height: none;\n flex-direction: row;\n align-items: flex-start;\n }\n .cbp-wb__att {\n flex: 1 1 0;\n min-width: 0;\n }\n}\n";
|
package/docs/preview.md
CHANGED
|
@@ -116,14 +116,41 @@ interface PreviewViewport {
|
|
|
116
116
|
|
|
117
117
|
---
|
|
118
118
|
|
|
119
|
-
##
|
|
119
|
+
## Wire Input 面板(IN · host→plugin)
|
|
120
|
+
|
|
121
|
+
Wire Bench 在右侧 dock 的 IN 卡片中展示**完整 wire 注入内容**(`WirePayloads`):
|
|
122
|
+
|
|
123
|
+
| 段 | 类型 | 默认状态 |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| `context` | infra | 折叠 |
|
|
126
|
+
| `item` | **content** | **展开** |
|
|
127
|
+
| `attachment`(renderer)/ `draft`(action)| **content** | **展开** |
|
|
128
|
+
| `theme` | infra | 折叠 |
|
|
129
|
+
| `locale` | infra | 折叠 |
|
|
130
|
+
|
|
131
|
+
- **content 段**(item + attachment/draft)默认展开,方便与右侧 OUT 输出对照。
|
|
132
|
+
- **infra 段**(context / theme / locale)默认折叠,减少干扰。
|
|
133
|
+
- 每段独立折叠,互不影响(仅 OUT 是单开 accordion)。
|
|
134
|
+
- `attachment.payloadJson` 字段:若为合法 JSON 字符串则**解析为可读嵌套 JSON**;解析失败回退原样字符串(不静默吞错)。
|
|
135
|
+
- scenario 切换或主题切换时面板自动刷新(theme 段反映最新预设)。
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Native Calls 面板(OUT · plugin→host)与 fake host
|
|
120
140
|
|
|
121
141
|
harness 安装一个最小双向 fake host:
|
|
122
142
|
|
|
123
143
|
- **host → plugin**:按 scenario 字段生成 wire payload 并注入;bootstrap、item、attachment、theme 等不需要真实宿主
|
|
124
|
-
- **plugin → host**:所有 `clipbus.*` native
|
|
144
|
+
- **plugin → host**:所有 `clipbus.*` native 调用被拦截,实时追加到右侧 dock 的 OUT 卡片;`clipbus.window.setHeight` 额外驱动视口高度;其他调用返回安全默认应答
|
|
125
145
|
|
|
126
|
-
|
|
146
|
+
OUT 卡片使用**单开 accordion**:
|
|
147
|
+
|
|
148
|
+
- 每条 native 调用产生一个折叠条目(方法名 + payload)。
|
|
149
|
+
- 新到调用**自动展开**并折叠所有旧条目——最新输出始终可见,payload 不会堆叠。
|
|
150
|
+
- 折叠态显示方法名 + 一行 payload 摘要;展开态显示完整缩进 payload。
|
|
151
|
+
- 点击折叠态条目展开它(同时收起其他);点击展开态条目收起它。
|
|
152
|
+
|
|
153
|
+
OUT 让你无需宿主即可验证 `setHeight` / `action.complete` / `clipboard.copyText` 等调用是否在正确时机触发、携带正确 payload。
|
|
127
154
|
|
|
128
155
|
---
|
|
129
156
|
|
|
@@ -146,7 +173,23 @@ harness 内置 4 套 native 主题预设,覆盖深色/浅色两种配色方案
|
|
|
146
173
|
|
|
147
174
|
---
|
|
148
175
|
|
|
149
|
-
## 工作台 UI
|
|
176
|
+
## 工作台 UI(Wire Bench)
|
|
177
|
+
|
|
178
|
+
工作台代号 **Wire Bench**,整页分为左右两栏:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
┌ WIRE BENCH ················ [Surface][Scenario][Theme][Width] ┐
|
|
182
|
+
├───────────────────────────────────┬───────────────────────────┤
|
|
183
|
+
│ PREVIEW · Workspace (hero) │ IN · Wire Input │
|
|
184
|
+
│ ┌─────────────────────────┐ │ ▶context ▼item ▼attach │
|
|
185
|
+
│ │ specimen card (frozen) │ │ ▶theme ▶locale │
|
|
186
|
+
│ │ [plugin webview] │ ├───────────────────────────┤
|
|
187
|
+
│ │ [button strip] │ │ OUT · Native Calls │
|
|
188
|
+
│ └─────────────────────────┘ │ ▼#N … ▶#N-1 … ▶#1 … │
|
|
189
|
+
│ 生长地板(ceiling ≈ 800px 余量) │ │
|
|
190
|
+
└───────────────────────────────────┴───────────────────────────┘
|
|
191
|
+
左:主工作区(占满列高) 右:dock(position:sticky)
|
|
192
|
+
```
|
|
150
193
|
|
|
151
194
|
```sh
|
|
152
195
|
npm run dev
|
|
@@ -154,14 +197,34 @@ npm run dev
|
|
|
154
197
|
|
|
155
198
|
Vite 启动后,工作台提供:
|
|
156
199
|
|
|
157
|
-
-
|
|
158
|
-
- **主题切换**(4 预设:Graphite · Ember · Porcelain · Sand
|
|
159
|
-
- **
|
|
160
|
-
-
|
|
161
|
-
- **
|
|
200
|
+
- **两级模式导航**:顶层 Surface 选择器在 **Renderer**(attachmentRenderer)和 **Action** 两种模式间切换;两种模式的 scenario 均用 `<select>` 下拉选择(文案取自 `scenario.label`)。任何时刻只渲染当前选中 scenario。URL query `?view=&scenario=&theme=` 同步,刷新不丢。
|
|
201
|
+
- **主题切换**(4 预设:Graphite · Ember · Porcelain · Sand):切换时三重作用:① 重注入 wire 主题 topic,插件已注册的 `clipbus.theme.on()` 回调立即触发;② 仅重着色**卡片壳与插件内容**(chrome 本身配色保持稳定,见下方[主题解耦](#主题解耦chrome-稳定--卡片跟-native));③ 在插件挂载槽上更新 `--clipbus-*` CSS 变量——不触发 remount,与 native `theme.onChange` 行为一致。注意:插件的 `--clipbus-accent` 是**全局主题 accent**;`scenario.accentHex` 是该附件的 **tintColor**,只染**卡片边框**(对应 native `record.tintColor`),不进插件配色。
|
|
202
|
+
- **Workspace(主工作区,左列)**:标本卡(frozen specimen)居中展示,下方有**生长地板**标注 `native ceiling ≈ 800px`,把卡片下方空白变成"到硬上限的余量"这一有意义信息。卡片再高只撑左列,不影响右侧 dock。
|
|
203
|
+
- **Dock(右列,`position:sticky`)**:卡片变高时右侧不被推走——IN / OUT 两张附件卡始终在视野内。
|
|
204
|
+
- **IN · Wire Input 面板**:见[上文 Wire Input 面板](#wire-input-面板in--hostplugin)。
|
|
205
|
+
- **OUT · Native Calls 面板**:见[上文 Native Calls 面板](#native-calls-面板out--pluginhost与-fake-host)。
|
|
206
|
+
- **Native 卡片壳**:卡片框(10 px padding / 7 px 圆角(native `radius.panelInner`)/ 1 px 描边(色取 `scenario.accentHex` 附件 tint,回退主题 accent)/ surfaceElevated 背景)是**外层卡片**,纵向堆叠 **body(插件挂载槽 `slotEl`)+ 按钮条**,对应 native `AttachmentRenderCardShell` 的 `VStack { body; actions }`。卡片宽度由滑杆控制,webview 按卡片 chrome(每边 11 px = 10 padding + 1 border)内嵌;卡片高度自动包裹 body + 按钮条。
|
|
207
|
+
- **宽度滑杆**:拖动**卡片外层宽度**(webview 随之按 chrome 内嵌),范围随 view 切换。模式默认(取自 native):renderer 初始 720 px、范围 [560,900];action 初始 350 px、范围 [300,500]。`scenario.viewport.width` 可覆盖初始值;`viewport.widthMin`/`widthMax` 可覆盖滑杆范围。
|
|
208
|
+
- **body 高度**:高度**由插件驱动**。native **没有**宿主侧"量内容定高":`auto` 在 native 解析为 `bounded(80, 800)`,且只认 `clipbus.window.setHeight`——插件**必须**用 SDK `autoFit`(或手动 `setHeight`)自撑,否则卡在 policy 最小高度被裁。harness 在插件首个 `setHeight` 前以内容高度做种子(宽松的预览便利,**非** native 行为)。所有策略统一封顶 native 硬上限 **800**(`AttachmentRenderHeightConstants.ceiling`)。
|
|
162
209
|
- **按钮条**:源自 `scenario.buttons`(及插件 `setButtons`),位于**卡片内部、body 下方、左对齐**(native action row 布局);无按钮时不占位。
|
|
163
|
-
-
|
|
164
|
-
|
|
210
|
+
- **主题感知滚动条**:工作台内所有滚动区域(dock 面板 + 插件内容)统一为细、半透明的滚动条,使用稳定的 bench 调色(不随主题变色)。
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 主题解耦:chrome 稳定 / 卡片跟 native
|
|
215
|
+
|
|
216
|
+
**本节记录一个有意的设计取舍,与前版本(native-fidelity D3)行为不同。**
|
|
217
|
+
|
|
218
|
+
前版本(`2026-06-28-plugin-preview-native-fidelity-design.md` D3):chrome 背板颜色随主题预设 `backdrop` 变色(graphite 深灰、ember 暖棕等)。
|
|
219
|
+
|
|
220
|
+
Wire Bench(`2026-06-28-plugin-preview-wire-bench-design.md` D5)**反转此行为**:
|
|
221
|
+
|
|
222
|
+
- **chrome 自身颜色稳定**(固定冷石板 `#14161D` + blueprint 网格),不随主题切换变色。
|
|
223
|
+
- **卡片壳与插件内容仍跟随主题**:`applyTheme()` 仍写入 `--cbp-wb-accent`(卡片 tint 回退 + 插件 accent)、`--cbp-wb-surface-elevated`、`--cbp-wb-border` 等卡片侧 token,`applyThemeCssVars()` 仍在插件槽更新 `--clipbus-*` 变量。
|
|
224
|
+
|
|
225
|
+
**取舍理由**:目标是「工具 chrome 是工具自己的,标本才是被观察对象」——chrome 与卡片同步变色时二者配色相互掩盖,削弱标本凸显;稳定的 chrome 使标本(native 配色的卡片)始终从工具背景中突出。
|
|
226
|
+
|
|
227
|
+
如需恢复前版本行为(chrome 背板跟主题),在 `styles.ts` 的 `.cbp-wb` 根规则中将 `background` 改回 `var(--cbp-wb-backdrop)`,并在 `chrome.ts` 的 `applyTheme()` 中恢复 `wb.style.setProperty('--cbp-wb-backdrop', preset.backdrop)`。
|
|
165
228
|
|
|
166
229
|
---
|
|
167
230
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipbus/plugin-sdk",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Typed SDK for authoring Clipbus plugins — runtime (Node.js) and UI (WebView) helpers generated from the Clipbus plugin wire contract.",
|
|
6
6
|
"keywords": [
|