@hegemonart/get-design-done 1.46.0 → 1.47.0
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +47 -0
- package/README.md +2 -0
- package/SKILL.md +2 -1
- package/dist/claude-code/.claude/skills/live/SKILL.md +98 -0
- package/package.json +1 -1
- package/reference/live-mode-integration.md +80 -0
- package/reference/registry.json +7 -0
- package/reference/schemas/events.schema.json +1 -1
- package/reference/schemas/live-session.schema.json +64 -0
- package/scripts/lib/live/bandit-feed.cjs +64 -0
- package/scripts/lib/live/events.cjs +86 -0
- package/scripts/lib/live/harness-mode.cjs +93 -0
- package/scripts/lib/live/postcheck.cjs +158 -0
- package/scripts/lib/live/runtime.cjs +233 -0
- package/scripts/lib/live/scope-guard.cjs +145 -0
- package/scripts/lib/live/session-store.cjs +364 -0
- package/scripts/lib/manifest/skills.json +8 -0
- package/skills/live/SKILL.md +98 -0
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "Get Design Done — 5-stage agent-orchestrated design pipeline with 9 connections, handoff-first workflow, bidirectional Figma write-back, 22+ specialized agents, queryable knowledge layer (intel store, dependency analysis, learnings extraction), and a self-improvement loop (reflector, frontmatter + budget feedback, global-skills layer). v1.20.0 ships the SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream, and resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) for rate-limit + 429 + context-overflow recovery. Full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation (auto-tag + GitHub Release + release-time smoke test).",
|
|
8
|
-
"version": "1.
|
|
8
|
+
"version": "1.47.0"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "get-design-done",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), Claude Design handoff, bidirectional Figma write-back, and a queryable intel store (.design/intel/) for dependency and learnings queries. Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation. Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain.",
|
|
15
|
-
"version": "1.
|
|
15
|
+
"version": "1.47.0",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "hegemonart"
|
|
18
18
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "get-design-done",
|
|
3
3
|
"short_name": "gdd",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.47.0",
|
|
5
5
|
"description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), handoff-first workflow via Claude Design bundles, bidirectional Figma write-back (annotations, Code Connect), queryable intel store (`.design/intel/`) for O(1) design surface lookups, and self-improvement loop (reflector agent, frontmatter + budget feedback, global-skills layer at `~/.claude/gdd/global-skills/`). Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings, reflect, apply-reflections. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows, lint + schema + frontmatter + stale-ref + shellcheck + gitleaks + injection-scan + blocking size-budget) and release automation (auto-tag + GitHub Release + release-time smoke test). Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain. v1.27.7 ships gdd-mcp (Phase 27.7): 12 read-only MCP tools for sub-3s priming. v1.28.0 (Phase 28): Foundational References Tier 2 — 5 new reference files (color-theory, composition, proportion-systems, i18n, contrast-advanced), 2 verifier i18n probes + 1 explore i18n-readiness probe, 12 additive cross-link insertions across 10 existing references, 2 orthogonal audit-scoring lens-tags (composition_alignment + i18n_readiness).",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "hegemonart",
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,53 @@ All notable changes to get-design-done are documented here. Versions follow [sem
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.47.0] - 2026-06-03
|
|
8
|
+
|
|
9
|
+
### Phase 47 - In-Browser Design Iteration (Live Mode)
|
|
10
|
+
|
|
11
|
+
GDD's design loop was repo-bound (edit, save, preview, screenshot) with no tight in-browser iteration. Phase 47
|
|
12
|
+
ships `/gdd:live`: pick an element on a running dev server, generate N variants in one batch, post-check each with
|
|
13
|
+
gdd-detect, hot-swap via HMR, accept or discard, and the session persists for resume. It drives the existing Preview
|
|
14
|
+
MCP connection at runtime (the same surface verify screenshots and darkmode injection already use), so there is no
|
|
15
|
+
new runtime dependency and no new egress. Planned and executed via the GSD pipeline (2 research agents + 3 parallel
|
|
16
|
+
executor subagents).
|
|
17
|
+
|
|
18
|
+
### Breaking changes
|
|
19
|
+
|
|
20
|
+
- **`capability_matrix.mcp_support` now also gates live mode.** A harness declared `mcp_support: false` runs
|
|
21
|
+
`/gdd:live` in degraded screenshot-only mode (no element-pick or HMR swap). Harness authors adding a runtime must
|
|
22
|
+
set `mcp_support` honestly, since it now drives this behavioral split in addition to MCP tool availability.
|
|
23
|
+
- **The live-session schema joins the validated set.** `reference/schemas/live-session.schema.json` is registered in
|
|
24
|
+
`validate:schemas`, and the six `live_*` event types are seeded into `reference/schemas/events.schema.json`.
|
|
25
|
+
Editing either must keep them valid (CI-gated).
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **`/gdd:live`** at `source/skills/live/SKILL.md`: boot (probe Preview, detect dev server Vite/Next/Bun/static,
|
|
30
|
+
degraded mode if no MCP), element pick, single-batch N-variant generation (default 3, loads the Phase 45 canonical
|
|
31
|
+
reference first), per-variant gdd-detect post-check (findings inline; `error` flagged, never auto-rejected),
|
|
32
|
+
accept/discard with canonical-edit selection, session persistence, and resume.
|
|
33
|
+
- **`scripts/lib/live/` substrate** (all dependency-free, all unit-tested): `session-store` (the
|
|
34
|
+
`.design/live-sessions/<id>.json` lifecycle + resume), `scope-guard` (blocks writes outside the picked element's
|
|
35
|
+
implicated source set), `postcheck` (wraps the gdd-detect engine in-memory), `events` (the six typed `live_*`
|
|
36
|
+
emitters), `bandit-feed` (accepted variants call the Phase 38 store's `observe(..., {source:'dev_time'})` at a 0.5
|
|
37
|
+
dev-time weight; the `Beta(2,8)` prior keeps them advisory), `harness-mode` (mcp_support to puppeteer/degraded),
|
|
38
|
+
`runtime` (the browser-side pick/swap script injected via `preview_eval`, keyed on `data-gdd-variant`).
|
|
39
|
+
- **`reference/live-mode-integration.md`** documents the loop, the Preview surface, the events, the session file, the
|
|
40
|
+
bandit feed, degraded mode, and the scope guard.
|
|
41
|
+
|
|
42
|
+
### Notes
|
|
43
|
+
|
|
44
|
+
- 6-manifest lockstep at **v1.47.0** + `OFF_CADENCE_VERSIONS.add('1.47.0')` + 37 `manifests-version.txt` baselines +
|
|
45
|
+
tarball golden 884 -> 895 (the `live` skill in `skills/` + `dist/claude-code/`, 7 `scripts/lib/live/*.cjs`,
|
|
46
|
+
`reference/live-mode-integration.md`, `reference/schemas/live-session.schema.json`).
|
|
47
|
+
- Testability: the deterministic substrate is fully unit-tested (session, scope, postcheck, events, bandit-feed,
|
|
48
|
+
harness-mode, runtime shape) plus a deterministic session-replay baseline at `test/fixtures/baselines/phase-47/`.
|
|
49
|
+
Live element-pick, HMR swap, and screenshots are runtime behaviors driven by the skill through the Preview
|
|
50
|
+
connection, exercised by the existing conditional main-branch E2E rather than new browserless CI suites.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
7
54
|
## [1.46.0] - 2026-06-03
|
|
8
55
|
|
|
9
56
|
### Phase 46 - Skill UX Polish
|
package/README.md
CHANGED
|
@@ -253,6 +253,8 @@ All 14 runtimes receive their native artifact layout (`skills/`, `command/`, `ag
|
|
|
253
253
|
|
|
254
254
|
**Skill UX polish (v1.46.0).** Skill frontmatter now has a single source of truth at `scripts/lib/manifest/skills.json` (description, argument hint, tools allow-list per skill); `scripts/generate-skill-frontmatter.cjs` regenerates each `source/skills/<id>/SKILL.md` from it, and `generate:skill-frontmatter:check` drift-gates the two in CI. The generator is order-preserving, so the committed tree stays a byte-for-byte fixed point and existing snapshots never churn. Power users get `/gdd:pin <skill>`, which writes standalone shortcut aliases (for example `/audit` alongside `/gdd:audit`) across every installed harness dir, each carrying a `gdd-pinned-skill` marker, plus `/gdd:unpin` and `/gdd:list-pins`. The 1024-character description budget (in place since the skill-authoring contract) is now an explicit `lint:agentskills` CI gate. **No new runtime dependency.**
|
|
255
255
|
|
|
256
|
+
**In-browser design iteration (v1.47.0).** `/gdd:live` tightens the design loop: pick an element on a running dev server, generate N variants in one batch (default 3, grounded in the Phase 45 canonical reference), post-check each with `gdd-detect`, hot-swap them via HMR, then accept or discard. Accepted variants are applied as the canonical edit and feed the Phase 38 bandit store with a `dev_time` source tag (a conservative `Beta(2,8)` prior keeps them advisory until production outcomes accumulate). The session persists to `.design/live-sessions/<id>.json` with resume, a scope guard blocks writes outside the picked element's source files, and harnesses without MCP fall back to a screenshot-only degraded mode. It drives the existing Preview connection, so there is **no new runtime dependency**.
|
|
257
|
+
|
|
256
258
|
Verify with:
|
|
257
259
|
|
|
258
260
|
```
|
package/SKILL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: get-design-done
|
|
3
3
|
short_name: gdd
|
|
4
4
|
description: "Master design pipeline for Claude Code. 5-stage workflow: Brief → Explore → Plan → Design → Verify. Run 'brief' first in any new project to capture the design problem, then 'explore' to inventory the codebase and interview for context. Invoke without arguments for status and auto-routing."
|
|
5
|
-
argument-hint: "[brief|explore|plan|design|verify|handoff|map|next|help|status|style|darkmode|compare|figma-write|graphify|discuss|list-assumptions|progress|health|todo|stats|note|plant-seed|add-backlog|review-backlog|scan|discover|settings|update|reapply-patches|audit|pause|resume|new-cycle|debug|quick|new-project|complete-cycle|fast|do|ship|undo|pr-branch|sketch|sketch-wrap-up|spike|spike-wrap-up|reflect|apply-reflections|analyze-dependencies|extract-learnings|skill-manifest|pin|unpin|list-pins|warm-cache|optimize|cache-manager|watch-authorities|check-update|benchmark|recall|timeline|continue|zoom-out]"
|
|
5
|
+
argument-hint: "[brief|explore|plan|design|verify|handoff|map|next|help|status|style|darkmode|live|compare|figma-write|graphify|discuss|list-assumptions|progress|health|todo|stats|note|plant-seed|add-backlog|review-backlog|scan|discover|settings|update|reapply-patches|audit|pause|resume|new-cycle|debug|quick|new-project|complete-cycle|fast|do|ship|undo|pr-branch|sketch|sketch-wrap-up|spike|spike-wrap-up|reflect|apply-reflections|analyze-dependencies|extract-learnings|skill-manifest|pin|unpin|list-pins|warm-cache|optimize|cache-manager|watch-authorities|check-update|benchmark|recall|timeline|continue|zoom-out]"
|
|
6
6
|
user-invocable: true
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -33,6 +33,7 @@ Each stage produces artifacts in `.design/` inside the current project.
|
|
|
33
33
|
| `help` | `get-design-done:gdd-help` | List all commands with one-line descriptions |
|
|
34
34
|
| `style [ComponentName]` | `get-design-done:gdd-style` | Generate component handoff doc → .design/DESIGN-STYLE-[Name].md |
|
|
35
35
|
| `darkmode` | `get-design-done:gdd-darkmode` | Audit dark mode architecture + contrast + anti-patterns → .design/DARKMODE-AUDIT.md |
|
|
36
|
+
| `live [--variants N] [--resume <id>] [url]` | `get-design-done:gdd-live` | Phase 47 - in-browser design iteration: pick an element on a running dev server (via the Preview connection), generate N variants, hot-swap via HMR, accept/discard; session persists to .design/live-sessions/. Degraded screenshot-only mode on harnesses without MCP |
|
|
36
37
|
| `compare` | `get-design-done:gdd-compare` | Delta between DESIGN.md baseline and DESIGN-VERIFICATION.md → .design/COMPARE-REPORT.md |
|
|
37
38
|
| `figma-write <mode>` | `get-design-done:gdd-figma-write` | Write design decisions to Figma (annotate/tokenize/mappings) |
|
|
38
39
|
| `figma-extract <file-url-or-key>` | `get-design-done:gdd-figma-extract` | Off-context Figma design-system extraction → compact local digest (DESIGN.md + tokens.json + components.json), zero raw JSON in context |
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-live
|
|
3
|
+
description: "Live in-browser design mode. The user picks a DOM element on a running dev server (via the Claude Preview MCP), the agent generates N design variants in one batch, they hot-swap in place through HMR or preview_eval using a data-gdd-variant marker, the user accepts or discards, and the whole pick-generate-accept loop persists to .design/live-sessions so it survives a crash or resume. Use when the user wants to iterate on the look of a live component against a real running server, asks to try variants on a page, or runs the live command with a url; falls back to a screenshot-only degraded mode on harnesses without MCP support."
|
|
4
|
+
argument-hint: "[--variants N] [--resume <session-id>] [url]"
|
|
5
|
+
tools: Read, Write, Edit, Bash, Glob, Grep, Task
|
|
6
|
+
user-invocable: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# gdd-live - Live In-Browser Design Mode
|
|
10
|
+
|
|
11
|
+
Pick a DOM element on a running dev server, generate competing design variants, hot-swap them in place, and accept the winner as a real source edit. Every step persists to `.design/live-sessions/<id>.json` so the session survives a crash or a later resume.
|
|
12
|
+
|
|
13
|
+
The browser-side runtime, the harness-mode gate, the session store, the events feed, the post-check, the scope guard, and the bandit feed are all separate modules under `scripts/lib/live/`. This skill describes the loop and names the module that owns each step; it does not import them.
|
|
14
|
+
|
|
15
|
+
For the full surface (the Preview MCP tools, the six `live_*` events, the session file, the bandit feed, degraded mode, the scope guard), see `../../reference/live-mode-integration.md`. For the SKILL.md structural contract, see `../../reference/skill-authoring-contract.md`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Arguments
|
|
20
|
+
|
|
21
|
+
- `[url]` - the page to drive. Optional. When omitted, detect the dev server and use its root.
|
|
22
|
+
- `--variants N` - how many variants to generate per pick. Default 3.
|
|
23
|
+
- `--resume <session-id>` - reattach to an in-progress session in `.design/live-sessions/`.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## BOOT
|
|
28
|
+
|
|
29
|
+
1. Probe the Preview MCP per `../../connections/preview.md`: `ToolSearch({ query: "Claude_Preview" })`, then `mcp__Claude_Preview__preview_list`. Empty ToolSearch means the MCP is not loaded.
|
|
30
|
+
2. Resolve the harness live mode. The capability signal is `capability_matrix.mcp_support` in `scripts/lib/manifest/harnesses.json`, projected by `scripts/lib/live/harness-mode.cjs` (`liveModeFor(harnessId)`). A `puppeteer` result means full live mode; a `degraded` result means screenshot-only.
|
|
31
|
+
3. If `mcp_support` is false for this harness, or Preview is unavailable, enter DEGRADED mode and say so plainly: variants are generated and captured as static screenshots, with no in-page hot-swap. Skip the INJECT and PICK steps; generate against the file the user names instead.
|
|
32
|
+
4. Detect the dev server. Look for Vite, Next, Bun, or a static server (check `package.json` scripts plus a `preview_list` entry). Record the server descriptor on the session.
|
|
33
|
+
5. Open or create the session via `scripts/lib/live/session-store.cjs` (`.design/live-sessions/<id>.json`). On `--resume`, load the named session (see RESUME).
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## INJECT
|
|
38
|
+
|
|
39
|
+
Inject the browser runtime once. Read `RUNTIME_JS` from `scripts/lib/live/runtime.cjs` and evaluate it in the page with `mcp__Claude_Preview__preview_eval`. The runtime is an idempotent IIFE bound to `window.__gddLive`, so a re-inject after navigation rebinds the same singleton rather than stacking listeners. It installs the pick handler and the variant-swap helpers, and stamps the live variant on the element via the `data-gdd-variant` attribute.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## PICK
|
|
44
|
+
|
|
45
|
+
1. Arm the picker (`window.__gddLive.pick()`), then guide the user to click the target element. Use `preview_click` and `preview_inspect` to confirm the element and read its computed styles and bounding box.
|
|
46
|
+
2. Read the pick report back. Its fields are documented in `pickReportShape` (selector, tagName, classList, boundingRect, computedStyle subset, current variant). The selector strategy prefers id, then a data-testid, then a tag plus class plus nth-of-type path.
|
|
47
|
+
3. Emit a `live_pick` event through `scripts/lib/live/events.cjs` and append a `pick` entry to the session.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## GENERATE (one batch)
|
|
52
|
+
|
|
53
|
+
1. Load the relevant Phase 45 canonical reference index FIRST, so variants are grounded in real guidance: the domain index that matches the picked element (for example `../../reference/spatial.md` for layout, `../../reference/interaction.md` for components and a11y, `../../reference/color.md` for color, `../../reference/typography.md` for type, `../../reference/motion.md` for animation).
|
|
54
|
+
2. Generate all N variants in ONE batch (default 3), each a distinct, hypothesis-tagged design direction for the picked element. Do not generate them one at a time.
|
|
55
|
+
3. For each variant: write the change atomically to the implicated source file, then make it live. With HMR running, the file write is enough; otherwise apply the variant in place with `window.__gddLive.swapVariant({ n, style, html })`, which sets `data-gdd-variant="n"` and applies the variant's style or markup.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## POST-CHECK
|
|
60
|
+
|
|
61
|
+
Run the post-check on each variant via `scripts/lib/live/postcheck.cjs`, which invokes `gdd-detect`. Show the findings inline next to each variant. A variant that trips a finding is flagged, NOT auto-rejected: the user still decides. Append a `live_postcheck` event per variant.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## ACCEPT / DISCARD
|
|
66
|
+
|
|
67
|
+
- ACCEPT one variant: apply the chosen variant as the canonical source edit, and revert the others in the page (`window.__gddLive.revert()` on each non-chosen element). Emit a `live_accept` event and feed the outcome to the design-variants bandit via `scripts/lib/live/bandit-feed.cjs` (a dev-time signal). Append an `accept` entry.
|
|
68
|
+
- DISCARD: revert every variant in the page back to its captured original and leave the source untouched. Emit a `live_discard` event and append a `discard` entry.
|
|
69
|
+
|
|
70
|
+
Either way, persist the result through `scripts/lib/live/session-store.cjs` before continuing.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## PERSIST
|
|
75
|
+
|
|
76
|
+
Every step (boot, pick, generate, post-check, accept, discard) is written to the session file through `scripts/lib/live/session-store.cjs` as it happens. The on-disk event log uses the `pick`, `generate`, `accept`, `discard` kinds; the telemetry stream uses the six `live_*` event types. Writes are atomic, so an interrupted step never leaves a half-written session.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## RESUME
|
|
81
|
+
|
|
82
|
+
With `--resume <session-id>`, load the named session from `.design/live-sessions/`. Only an `in_progress` session is resumable. Offer the user two choices: continue from the last recorded event (report what that was, for example "last pick was the primary button"), or start fresh (open a new session and leave the old one intact). Never silently replay completed events.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## SCOPE GUARD
|
|
87
|
+
|
|
88
|
+
Never write outside the source files implicated by the picked element. Run every proposed write through `scripts/lib/live/scope-guard.cjs`, which maps the picked selector to its owning source files and rejects edits that fall outside them. If a variant would need a change beyond that scope (a shared token, a parent layout, a new dependency), stop and surface it to the user rather than widening the blast radius.
|
|
89
|
+
|
|
90
|
+
## Constraints
|
|
91
|
+
|
|
92
|
+
- Do NOT edit files outside the picked element's implicated sources (enforced by the scope guard).
|
|
93
|
+
- Do NOT generate variants one at a time; generate the full batch, then swap.
|
|
94
|
+
- Do NOT auto-reject a variant on a post-check finding; flag it and let the user decide.
|
|
95
|
+
- In DEGRADED mode, state up front that hot-swap is unavailable and fall back to screenshots.
|
|
96
|
+
- Persist before every user-facing prompt so a crash never loses accepted work.
|
|
97
|
+
|
|
98
|
+
## LIVE COMPLETE
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hegemonart/get-design-done",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.0",
|
|
4
4
|
"description": "A design-quality pipeline for AI coding agents: brief, plan, implement, and verify UI work against your design system.",
|
|
5
5
|
"author": "Hegemon",
|
|
6
6
|
"homepage": "https://github.com/hegemonart/get-design-done",
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: live-mode-integration
|
|
3
|
+
type: meta-rules
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
phase: 47
|
|
6
|
+
tags: [live, preview-mcp, hot-swap, session, bandit, scope-guard, degraded-mode]
|
|
7
|
+
last_updated: 2026-06-03
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Live Mode Integration
|
|
11
|
+
|
|
12
|
+
This file is the meta-rules companion to the `gdd-live` skill (`source/skills/live/SKILL.md`). It describes how `/gdd:live` turns a running dev server into a live design surface: the user picks a DOM element, the agent generates N variants in one batch, the variants hot-swap in place, the user accepts or discards, and the whole session persists. For the SKILL.md structural contract (line cap, description budget, frontmatter), see `./skill-authoring-contract.md`. The variants themselves are grounded in the Phase 45 domain indexes (`./spatial.md`, `./interaction.md`, `./color.md`, `./typography.md`, `./motion.md`).
|
|
13
|
+
|
|
14
|
+
There is NO bundled browser automation. The skill drives the Claude Preview MCP at runtime; the modules under `scripts/lib/live/` are pure and dependency-free.
|
|
15
|
+
|
|
16
|
+
## The live loop
|
|
17
|
+
|
|
18
|
+
The loop is seven stages, each owned by one module under `scripts/lib/live/`:
|
|
19
|
+
|
|
20
|
+
1. BOOT. Probe the Preview MCP (see below), resolve the harness live mode, and detect the dev server (Vite, Next, Bun, or static). Open or create the session.
|
|
21
|
+
2. INJECT. Read `RUNTIME_JS` from `scripts/lib/live/runtime.cjs` and evaluate it in the page via `preview_eval`. The runtime is an idempotent IIFE on `window.__gddLive`; re-injecting after a navigation rebinds the same singleton.
|
|
22
|
+
3. PICK. The runtime arms a one-shot click handler. The clicked element is reported back as `{selector, tagName, classList, boundingRect, computedStyle subset, variant}` (the `pickReportShape` contract). The selector strategy prefers id, then a data-testid, then a tag plus class plus nth-of-type path.
|
|
23
|
+
4. GENERATE. Load the matching domain index first, then generate all N variants (default 3) in ONE batch. Each variant is written atomically to its source file and made live, either through HMR or through the runtime swap helper.
|
|
24
|
+
5. POST-CHECK. Each variant runs through `scripts/lib/live/postcheck.cjs`, which invokes `gdd-detect`. Findings show inline. A finding flags a variant; it never auto-rejects it.
|
|
25
|
+
6. ACCEPT or DISCARD. Accept applies the chosen variant as the canonical source edit, reverts the others, and feeds the bandit. Discard reverts everything and leaves the source untouched.
|
|
26
|
+
7. PERSIST. Every stage is written to the session file as it happens.
|
|
27
|
+
|
|
28
|
+
## The Preview MCP surface
|
|
29
|
+
|
|
30
|
+
Live mode drives the built-in Claude Preview MCP, the same connection documented in `../connections/preview.md`. The tools it uses:
|
|
31
|
+
|
|
32
|
+
- `preview_list` and `ToolSearch` for the availability probe.
|
|
33
|
+
- `preview_eval` to inject `RUNTIME_JS` and to read the pick report back.
|
|
34
|
+
- `preview_inspect` and `preview_click` to confirm the picked element and read its computed styles.
|
|
35
|
+
- `preview_navigate` to move between routes (the runtime re-inject is idempotent across navigations).
|
|
36
|
+
- `preview_screenshot` for evidence, and as the only output in degraded mode.
|
|
37
|
+
|
|
38
|
+
The `data-gdd-variant` attribute is the hot-swap marker. The runtime stamps `data-gdd-variant="N"` on the picked element when it applies variant N, and reads it back to know which variant is live.
|
|
39
|
+
|
|
40
|
+
## The six live events
|
|
41
|
+
|
|
42
|
+
Live mode emits six telemetry event types through `scripts/lib/live/events.cjs` onto the standard `.design/telemetry/events.jsonl` stream:
|
|
43
|
+
|
|
44
|
+
| Event | Emitted when |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `live_boot` | A session opens (BOOT completes). |
|
|
47
|
+
| `live_pick` | The user picks an element. |
|
|
48
|
+
| `live_generate` | A batch of N variants is generated. |
|
|
49
|
+
| `live_postcheck` | A variant clears or trips its post-check. |
|
|
50
|
+
| `live_accept` | The user accepts a variant. |
|
|
51
|
+
| `live_discard` | The user discards the batch. |
|
|
52
|
+
|
|
53
|
+
These telemetry events are distinct from the on-disk session log. The session file records the four lifecycle kinds (`pick`, `generate`, `accept`, `discard`); the telemetry stream carries the six `live_*` types above.
|
|
54
|
+
|
|
55
|
+
## The session file
|
|
56
|
+
|
|
57
|
+
`scripts/lib/live/session-store.cjs` owns one JSON document per session at `.design/live-sessions/<session-id>.json`, conforming to `./schemas/live-session.schema.json`. It carries `{schema_version, session_id, status, started_at, ended_at, url, dev_server, events[]}`. `status` is one of `in_progress`, `completed`, or `abandoned`; only an `in_progress` session is resumable. Writes are atomic (write to a temp file, then rename), so an interrupted step never leaves a half-written session.
|
|
58
|
+
|
|
59
|
+
On `--resume <session-id>`, the skill loads the named session and offers two choices: continue from the last recorded event, or start fresh. It never silently replays completed events.
|
|
60
|
+
|
|
61
|
+
## The bandit dev-time feed
|
|
62
|
+
|
|
63
|
+
When the user accepts a variant, `scripts/lib/live/bandit-feed.cjs` feeds that outcome to the design-variants bandit described in `./design-variants.md`. This is a dev-time signal: it records which design pattern the developer chose during live iteration. It is advisory and separate from the user-outcome A/B loop and from the routing bandit. The user always wins; the bandit only learns.
|
|
64
|
+
|
|
65
|
+
## Degraded mode
|
|
66
|
+
|
|
67
|
+
Live mode is gated on `capability_matrix.mcp_support` in `scripts/lib/manifest/harnesses.json`. `scripts/lib/live/harness-mode.cjs` projects each harness onto a mode: `liveModeFor(harnessId)` returns `puppeteer` (full live mode) when `mcp_support` is true, and `degraded` otherwise. `degradedHarnesses()` lists every screenshot-only harness.
|
|
68
|
+
|
|
69
|
+
In degraded mode there is no Preview MCP, so there is no runtime injection and no hot-swap. The skill states this up front, then generates variants against the file the user names and captures static screenshots for comparison. Degraded mode never errors; it is a documented fallback.
|
|
70
|
+
|
|
71
|
+
## Scope guard
|
|
72
|
+
|
|
73
|
+
`scripts/lib/live/scope-guard.cjs` maps the picked selector to its owning source files and rejects any write that falls outside them. A variant that would need a change beyond that scope (a shared token, a parent layout, a new dependency) stops the loop and surfaces the decision to the user, rather than silently widening the blast radius. The guard is the hard boundary on what live mode may edit.
|
|
74
|
+
|
|
75
|
+
## See also
|
|
76
|
+
|
|
77
|
+
- `./skill-authoring-contract.md` for the SKILL.md authoring rules.
|
|
78
|
+
- `./design-variants.md` for the bandit the accept step feeds.
|
|
79
|
+
- `../connections/preview.md` for the full Preview MCP connection spec.
|
|
80
|
+
- The Phase 45 domain indexes (`./spatial.md`, `./interaction.md`, `./color.md`, `./typography.md`, `./motion.md`) the generate step loads.
|
package/reference/registry.json
CHANGED
|
@@ -856,6 +856,13 @@
|
|
|
856
856
|
"phase": 46,
|
|
857
857
|
"description": "Phase 46 skill-metadata single source of truth: scripts/lib/manifest/skills.json record shape, the generate-skill-frontmatter.cjs forward/extract/check modes, the skills.json to generator to build:skills to skills/+dist build chain, the six managed frontmatter keys (canonical order, always-quoted strings) vs extra_frontmatter passthrough, the 20..1024 description budget (validate-skill-length.cjs + lint-agentskills-spec.cjs R4, lint:agentskills CI gate), and the pin metadata catalogue consumer."
|
|
858
858
|
},
|
|
859
|
+
{
|
|
860
|
+
"name": "live-mode-integration",
|
|
861
|
+
"path": "reference/live-mode-integration.md",
|
|
862
|
+
"type": "meta-rules",
|
|
863
|
+
"phase": 47,
|
|
864
|
+
"description": "Phase 47 live-mode contract for /gdd:live: the seven-stage pick to generate to accept loop, the Claude Preview MCP surface (preview_eval injects scripts/lib/live/runtime.cjs RUNTIME_JS, hot-swap via the data-gdd-variant marker), the six live_* telemetry events vs the four on-disk session kinds, the .design/live-sessions session file (scripts/lib/live/session-store.cjs + live-session.schema.json), the dev-time bandit feed (bandit-feed.cjs into design-variants), degraded screenshot-only mode gated on capability_matrix.mcp_support (harness-mode.cjs), and the scope guard (scope-guard.cjs)."
|
|
865
|
+
},
|
|
859
866
|
{
|
|
860
867
|
"name": "capability-gap-stage-gate",
|
|
861
868
|
"path": "reference/capability-gap-stage-gate.md",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"type": {
|
|
11
11
|
"type": "string",
|
|
12
12
|
"minLength": 1,
|
|
13
|
-
"description": "Free-form event type identifier. Pre-registered seeds: state.mutation, state.transition, stage.entered, stage.exited, hook.fired, error, capability_gap, kfm-candidate, router_pick, verify_outcome, rollout_started, rollout_advanced, rollout_stuck, budget_forecast, project_cap_warning, project_cap_halt."
|
|
13
|
+
"description": "Free-form event type identifier. Pre-registered seeds: state.mutation, state.transition, stage.entered, stage.exited, hook.fired, error, capability_gap, kfm-candidate, router_pick, verify_outcome, rollout_started, rollout_advanced, rollout_stuck, budget_forecast, project_cap_warning, project_cap_halt, live_session_start, live_pick, live_generate, live_accept, live_discard, live_session_end."
|
|
14
14
|
},
|
|
15
15
|
"timestamp": {
|
|
16
16
|
"type": "string",
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://github.com/hegemonart/get-design-done/reference/schemas/live-session.schema.json",
|
|
4
|
+
"title": "Live Session",
|
|
5
|
+
"description": "A single `/gdd:live` session record persisted at .design/live-sessions/<session-id>.json. Captures the pick -> generate -> accept/discard loop as an append-only event log so a session survives a crash or --resume. Written atomically by scripts/lib/live/session-store.cjs.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["schema_version", "session_id", "status", "started_at", "ended_at", "events"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema_version": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Schema version of this session record (e.g. \"47.0\")."
|
|
12
|
+
},
|
|
13
|
+
"session_id": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"minLength": 1,
|
|
16
|
+
"description": "Stable id; also the basename of the on-disk file (no path separators)."
|
|
17
|
+
},
|
|
18
|
+
"status": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"enum": ["in_progress", "completed", "abandoned"],
|
|
21
|
+
"description": "Lifecycle status. Only in_progress sessions are resumable."
|
|
22
|
+
},
|
|
23
|
+
"started_at": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"format": "date-time",
|
|
26
|
+
"description": "ISO-8601 timestamp the session was created."
|
|
27
|
+
},
|
|
28
|
+
"ended_at": {
|
|
29
|
+
"type": ["string", "null"],
|
|
30
|
+
"format": "date-time",
|
|
31
|
+
"description": "ISO-8601 timestamp the session was closed; null while in_progress."
|
|
32
|
+
},
|
|
33
|
+
"url": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "The page the element was picked from (optional)."
|
|
36
|
+
},
|
|
37
|
+
"dev_server": {
|
|
38
|
+
"description": "Dev-server descriptor (url/port/command, or a plain string). Free-form by design.",
|
|
39
|
+
"type": ["string", "object", "null"]
|
|
40
|
+
},
|
|
41
|
+
"events": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"description": "Append-only log of session events, oldest first.",
|
|
44
|
+
"items": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"required": ["kind", "at"],
|
|
47
|
+
"properties": {
|
|
48
|
+
"kind": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"enum": ["pick", "generate", "accept", "discard"],
|
|
51
|
+
"description": "Event kind."
|
|
52
|
+
},
|
|
53
|
+
"at": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"format": "date-time",
|
|
56
|
+
"description": "ISO-8601 timestamp the event was recorded."
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"additionalProperties": true
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"additionalProperties": false
|
|
64
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* scripts/lib/live/bandit-feed.cjs — Phase 47 (Live Mode) → Phase 38 design-arms bridge.
|
|
4
|
+
*
|
|
5
|
+
* When a user ACCEPTS a generated variant in /gdd:live, that acceptance is a weak,
|
|
6
|
+
* dev-time positive signal for the variant's design pattern. We fold it into the Phase 38
|
|
7
|
+
* `design_arms` posterior store as a WON observation — but at a discounted weight
|
|
8
|
+
* (DEV_TIME_WEIGHT = 0.5) because a developer's pick during authoring is advisory until
|
|
9
|
+
* real production A/B + user-research data arrives (Phase 38 D-03: advisory, never
|
|
10
|
+
* directive). The full posterior math + atomic persistence lives in the design-arms
|
|
11
|
+
* store; we only reuse it (variantKey + observe) and never duplicate the Beta math.
|
|
12
|
+
*
|
|
13
|
+
* Pure, dependency-free CommonJS. Persistence + `baseDir`/`armsPath` test-injection are
|
|
14
|
+
* inherited from the store. Ships in the npm package; requires only the in-repo store.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const { variantKey, observe } = require('../ds-arms/design-arms-store.cjs');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The dev-time acceptance weight. Half a win — a developer's accept is a discounted,
|
|
21
|
+
* advisory signal (Phase 38 D-03) until production user-outcome data shifts the arm.
|
|
22
|
+
*/
|
|
23
|
+
const DEV_TIME_WEIGHT = 0.5;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Record an accepted Live Mode variant as a discounted WON observation on its design arm.
|
|
27
|
+
*
|
|
28
|
+
* @param {object} args
|
|
29
|
+
* @param {string} args.componentType The component class (e.g. 'button', 'card').
|
|
30
|
+
* @param {string|object} args.pattern The variant's design pattern (string or object;
|
|
31
|
+
* hashed to the arm key via the store's variantKey).
|
|
32
|
+
* @param {string} [args.label] Human-readable arm label, stored on first observe.
|
|
33
|
+
* @param {number} [args.weight] Override the dev-time weight (defaults to DEV_TIME_WEIGHT).
|
|
34
|
+
* @param {string} [args.projectRoot] Repo root — forwarded to the store as `baseDir` so the
|
|
35
|
+
* arms file resolves under it (testable / hermetic).
|
|
36
|
+
* @param {string} [args.armsPath] Explicit arms-file path override (forwarded to the store).
|
|
37
|
+
* @returns {object} The updated arm posterior (as returned by the store's observe()).
|
|
38
|
+
*/
|
|
39
|
+
function recordAccepted(args = {}) {
|
|
40
|
+
const { componentType, pattern, label, projectRoot, armsPath } = args;
|
|
41
|
+
if (typeof componentType !== 'string' || componentType.length === 0) {
|
|
42
|
+
throw new TypeError('recordAccepted: componentType is required (non-empty string)');
|
|
43
|
+
}
|
|
44
|
+
if (pattern == null) {
|
|
45
|
+
throw new TypeError('recordAccepted: pattern is required');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const weight = typeof args.weight === 'number' && args.weight > 0 ? args.weight : DEV_TIME_WEIGHT;
|
|
49
|
+
const hash = variantKey(componentType, pattern);
|
|
50
|
+
|
|
51
|
+
// Forward store options only when provided so the store keeps its own defaults otherwise.
|
|
52
|
+
const opts = {};
|
|
53
|
+
if (projectRoot) opts.baseDir = projectRoot;
|
|
54
|
+
if (armsPath) opts.armsPath = armsPath;
|
|
55
|
+
|
|
56
|
+
return observe(
|
|
57
|
+
componentType,
|
|
58
|
+
hash,
|
|
59
|
+
{ won: true, weight, source: 'dev_time', label },
|
|
60
|
+
opts,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = { recordAccepted, DEV_TIME_WEIGHT };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* scripts/lib/live/events.cjs — Phase 47 (Live Mode) telemetry emitter.
|
|
4
|
+
*
|
|
5
|
+
* /gdd:live emits six event types across a session — start, pick, generate, accept,
|
|
6
|
+
* discard, end. This module is the single typed entry point: it validates the `type`
|
|
7
|
+
* against the closed LIVE_EVENT_TYPES allow-list (an unknown live type is a programmer
|
|
8
|
+
* error and is rejected) and appends the event via the in-repo event-chain emitter
|
|
9
|
+
* (scripts/lib/event-chain.cjs), the same write path router_pick uses.
|
|
10
|
+
*
|
|
11
|
+
* The emitted row carries the events.schema.json envelope fields verbatim
|
|
12
|
+
* (type / timestamp / sessionId / payload) so that, projected back to
|
|
13
|
+
* {type, timestamp, sessionId, payload}, it validates against the additive `live_*`
|
|
14
|
+
* seed types in reference/schemas/events.schema.json. `agent` + `outcome` are the
|
|
15
|
+
* chain emitter's two required fields; we set agent='live' and outcome=type.
|
|
16
|
+
*
|
|
17
|
+
* Pure, dependency-free CommonJS:
|
|
18
|
+
* - NO top-level clock: the timestamp comes from an injectable `now` (default
|
|
19
|
+
* `Date.now`), so tests are deterministic.
|
|
20
|
+
* - `baseDir` is injectable (the emitter resolves the chain file relative to it),
|
|
21
|
+
* so tests write to a temp project and never touch the repo's real stream.
|
|
22
|
+
*
|
|
23
|
+
* Ships in the npm package; requires only the in-repo event-chain emitter.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const { appendChainEvent } = require('../event-chain.cjs');
|
|
27
|
+
|
|
28
|
+
/** The six Live Mode event types. Closed allow-list — an unknown type is rejected. */
|
|
29
|
+
const LIVE_EVENT_TYPES = Object.freeze([
|
|
30
|
+
'live_session_start',
|
|
31
|
+
'live_pick',
|
|
32
|
+
'live_generate',
|
|
33
|
+
'live_accept',
|
|
34
|
+
'live_discard',
|
|
35
|
+
'live_session_end',
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const LIVE_EVENT_TYPE_SET = new Set(LIVE_EVENT_TYPES);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Emit a Live Mode telemetry event.
|
|
42
|
+
*
|
|
43
|
+
* @param {object} args
|
|
44
|
+
* @param {string} args.projectRoot Repo root — injected as the emitter `baseDir` so the
|
|
45
|
+
* chain file resolves under it (testable / hermetic).
|
|
46
|
+
* @param {string} args.type One of LIVE_EVENT_TYPES. Anything else throws.
|
|
47
|
+
* @param {string} args.sessionId Stable per-session id (correlates the event stream).
|
|
48
|
+
* @param {object} [args.payload] Free-form, event-specific payload (MVP: opaque object).
|
|
49
|
+
* @param {(() => number)} [args.now] Injectable clock returning epoch ms (default Date.now).
|
|
50
|
+
* @returns {{event_id: string, type: string, timestamp: string, sessionId: string, payload: object}}
|
|
51
|
+
* The projected envelope (also the shape that validates against events.schema.json).
|
|
52
|
+
*/
|
|
53
|
+
function emitLiveEvent(args = {}) {
|
|
54
|
+
const { projectRoot, type, sessionId, payload } = args;
|
|
55
|
+
const now = typeof args.now === 'function' ? args.now : Date.now;
|
|
56
|
+
|
|
57
|
+
if (!LIVE_EVENT_TYPE_SET.has(type)) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`emitLiveEvent: unknown live event type "${String(type)}". ` +
|
|
60
|
+
`Expected one of: ${LIVE_EVENT_TYPES.join(', ')}.`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (typeof sessionId !== 'string' || sessionId.length === 0) {
|
|
64
|
+
throw new TypeError('emitLiveEvent: sessionId is required (non-empty string)');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const timestamp = new Date(now()).toISOString();
|
|
68
|
+
const envelopePayload = payload && typeof payload === 'object' ? payload : {};
|
|
69
|
+
|
|
70
|
+
// Mirror the router_pick emit surface: write a chain row carrying the events-schema
|
|
71
|
+
// envelope fields verbatim. agent/outcome are the chain emitter's required fields.
|
|
72
|
+
const event_id = appendChainEvent({
|
|
73
|
+
baseDir: projectRoot,
|
|
74
|
+
agent: 'live',
|
|
75
|
+
outcome: type,
|
|
76
|
+
// Envelope fields preserved verbatim by appendChainEvent (opaque-extras pass-through):
|
|
77
|
+
type,
|
|
78
|
+
timestamp,
|
|
79
|
+
sessionId,
|
|
80
|
+
payload: envelopePayload,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return { event_id, type, timestamp, sessionId, payload: envelopePayload };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
module.exports = { emitLiveEvent, LIVE_EVENT_TYPES };
|