mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
Catalog: mode-aligned staging surfaces (persuade/operate/read/experience), star ratings on approvals feeding challenger draw weights, family retirements, authoring strategy and territory guide, rework and breadth authoring rounds, composition mining from rejected worlds. Seed: six challengers (two per tier), --reroll chains, --mode staging filter, rating-weighted draws. New-work: Present/visualize/re-roll flow, image-gen requirement, register-neutral vocabulary. Pipeline: per-mode staging prompts with split frames, hero-from-board reference generation, render-safety guards. Labs: ratings UI, unrated filter, mode chips, composition approve-guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
156 lines
6.4 KiB
Plaintext
156 lines
6.4 KiB
Plaintext
---
|
|
import '../styles/live-ui-gallery.css';
|
|
import { LIVE_COMMANDS } from '../../skill/scripts/live/vocabulary.mjs';
|
|
import { LIVE_UI_SURFACES } from '../../skill/scripts/live/ui-core.mjs';
|
|
|
|
const STATE_GROUPS = [
|
|
{
|
|
key: 'global-chrome',
|
|
label: 'Global chrome',
|
|
summary: 'Session status, page-wide tools, and steering.',
|
|
states: [
|
|
['global-ready', 'Ready', 'global-bottom-bar'],
|
|
['global-disconnected', 'Agent disconnected', 'global-bottom-bar'],
|
|
['global-foreground', 'Codex CLI fallback', 'global-bottom-bar'],
|
|
['global-tools', 'Detect + DESIGN.md', 'global-bottom-bar'],
|
|
['steer-expanded', 'Steer composing', 'global-bottom-bar'],
|
|
['steer-processing', 'Steer processing', 'global-bottom-bar'],
|
|
],
|
|
},
|
|
{
|
|
key: 'selection',
|
|
label: 'Selection',
|
|
summary: 'Target, annotate, and insert before generation.',
|
|
states: [
|
|
['configure-replace', 'Configure selection', 'element-selection-chrome'],
|
|
['action-picker', 'Action picker', 'action-picker'],
|
|
['configure-listening', 'Voice input', 'element-selection-chrome'],
|
|
['configure-locked', 'Apply locked', 'element-selection-chrome'],
|
|
['annotation', 'Annotations', 'annotation-chrome'],
|
|
['insert-placeholder', 'Insert placeholder', 'insert-mode-chrome'],
|
|
],
|
|
},
|
|
{
|
|
key: 'generation-review',
|
|
label: 'Generation + review',
|
|
summary: 'Progressive arrival, tuning, application, and confirmation.',
|
|
states: [
|
|
['generating', 'Generating', 'generating-row'],
|
|
['generation-recovery', 'Recovery', 'generating-row'],
|
|
['cycling-progressive', 'Variant 1 arrived', 'variant-cycling-row'],
|
|
['cycling-second', 'Variant 2 arrived', 'variant-cycling-row'],
|
|
['tune-open', 'Tune panel', 'variant-params-panel'],
|
|
['applying', 'Applying variant', 'saving-confirmed-rows'],
|
|
['confirmed', 'Variant applied', 'saving-confirmed-rows'],
|
|
],
|
|
},
|
|
{
|
|
key: 'copy-support',
|
|
label: 'Copy + support',
|
|
summary: 'Inline copy edits, design context, and recovery feedback.',
|
|
states: [
|
|
['edit-copy', 'Edit copy', 'edit-chrome'],
|
|
['copy-pending', 'Copy edits pending', 'pending-copy-edit-dock'],
|
|
['copy-applying', 'Copy edits applying', 'pending-copy-edit-dock'],
|
|
['copy-attention', 'Apply needs attention', 'pending-copy-edit-dock'],
|
|
['design-panel', 'DESIGN.md panel', 'design-system-panel'],
|
|
['toast-error', 'Error toast', 'toasts-and-errors'],
|
|
],
|
|
},
|
|
];
|
|
|
|
// Keep the catalog honest as Live grows. CSS isolation is a structural mount
|
|
// contract rather than a visible state; every other surface must own at least
|
|
// one snapshot here or the site build fails with the missing surface name.
|
|
const STRUCTURAL_SURFACES = new Set(['css-isolation-boundary']);
|
|
const coveredSurfaces = new Set(
|
|
STATE_GROUPS.flatMap((group) => group.states.map(([, , surface]) => surface)),
|
|
);
|
|
const visualSurfaces = LIVE_UI_SURFACES.filter((surface) => !STRUCTURAL_SURFACES.has(surface.key));
|
|
const uncoveredSurfaces = visualSurfaces.filter((surface) => !coveredSurfaces.has(surface.key));
|
|
if (uncoveredSurfaces.length > 0) {
|
|
throw new Error(`Live UI lab is missing snapshots for: ${uncoveredSurfaces.map((surface) => surface.key).join(', ')}`);
|
|
}
|
|
|
|
const statePayload = STATE_GROUPS.flatMap((group) =>
|
|
group.states.map(([key, label, surface]) => ({
|
|
key,
|
|
label,
|
|
surface,
|
|
groupKey: group.key,
|
|
group: group.label,
|
|
groupSummary: group.summary,
|
|
})),
|
|
);
|
|
const groupPayload = STATE_GROUPS.map((group) => ({
|
|
key: group.key,
|
|
label: group.label,
|
|
summary: group.summary,
|
|
states: statePayload.filter((state) => state.groupKey === group.key),
|
|
}));
|
|
const commandPayload = JSON.stringify(LIVE_COMMANDS).replace(/</g, '\\u003c');
|
|
const groupsJson = JSON.stringify(groupPayload).replace(/</g, '\\u003c');
|
|
---
|
|
|
|
<!--
|
|
Dev-only state harness for Impeccable Live. The chrome mirrors:
|
|
- skill/scripts/live-browser.js (standalone browser UI and exact wording)
|
|
- skill/scripts/live/ui-core.mjs (surface/state inventory)
|
|
- skill/scripts/live/vocabulary.mjs (canonical command labels and SVGs)
|
|
|
|
Production Live deliberately uses the same dark Neo Kinpaku chrome on light
|
|
and dark host pages (barPaletteForTheme, live-browser.js). The host control
|
|
therefore changes the canvas behind every state, not the product chrome.
|
|
-->
|
|
<section class="live-ui-gallery" data-live-ui-gallery data-dev-only="true" aria-label="Live UI state inspector">
|
|
<aside class="live-ui-gallery__sidebar">
|
|
<header class="live-ui-gallery__sidebar-head">
|
|
<span>State catalog</span>
|
|
<strong>{statePayload.length} snapshots</strong>
|
|
<small>{visualSurfaces.length} visible surfaces</small>
|
|
</header>
|
|
|
|
<nav class="live-ui-gallery__group-nav" aria-label="Live UI workflow groups" aria-keyshortcuts="ArrowUp ArrowDown Home End">
|
|
{STATE_GROUPS.map((group, index) => (
|
|
<button type="button" data-gallery-group={group.key} aria-current={index === 0 ? 'true' : 'false'}>
|
|
<span>{String(index + 1).padStart(2, '0')}</span>
|
|
<span>
|
|
<strong>{group.label}</strong>
|
|
<small>{group.states.length} states</small>
|
|
</span>
|
|
</button>
|
|
))}
|
|
</nav>
|
|
|
|
<footer>
|
|
<span>Product rule</span>
|
|
<p>Live chrome stays dark. Host context changes around it.</p>
|
|
</footer>
|
|
</aside>
|
|
|
|
<div class="live-ui-gallery__workspace">
|
|
<header class="live-ui-gallery__toolbar">
|
|
<div class="live-ui-gallery__group-readout" aria-live="polite" aria-atomic="true">
|
|
<span data-gallery-group-index>Group 01</span>
|
|
<h2 data-gallery-group-label>Global chrome</h2>
|
|
<p data-gallery-group-summary>Session status, page-wide tools, and steering.</p>
|
|
</div>
|
|
|
|
<div class="live-ui-gallery__host-switch" role="group" aria-label="Preview host theme">
|
|
<span>Host</span>
|
|
<button type="button" data-gallery-host="light" aria-pressed="true">Light</button>
|
|
<button type="button" data-gallery-host="dark" aria-pressed="false">Dark</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="live-ui-gallery__cluster" data-gallery-cluster role="list" aria-label="Global chrome states"></div>
|
|
</div>
|
|
|
|
<script is:inline type="application/json" data-live-gallery-groups set:html={groupsJson}></script>
|
|
<script is:inline type="application/json" data-live-gallery-vocabulary set:html={commandPayload}></script>
|
|
</section>
|
|
|
|
<script>
|
|
import '../scripts/live-ui-gallery.js';
|
|
</script>
|