@hegemonart/get-design-done 1.35.3 → 1.35.5
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 +21 -0
- package/README.md +4 -0
- package/SKILL.md +1 -0
- package/connections/connections.md +10 -1
- package/connections/notion.md +57 -0
- package/package.json +1 -1
- package/reference/export-formats.md +31 -0
- package/reference/registry.json +7 -0
- package/scripts/lib/export/build-html.cjs +112 -0
- package/skills/connections/SKILL.md +4 -4
- package/skills/connections/connections-onboarding.md +13 -4
- package/skills/export/SKILL.md +30 -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.35.
|
|
8
|
+
"version": "1.35.5"
|
|
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.35.
|
|
15
|
+
"version": "1.35.5",
|
|
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.35.
|
|
4
|
+
"version": "1.35.5",
|
|
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,27 @@ All notable changes to get-design-done are documented here. Versions follow [sem
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.35.5] - 2026-06-01
|
|
8
|
+
|
|
9
|
+
### Phase 35.5 — Design-Artifact Export (`/gdd:export`)
|
|
10
|
+
|
|
11
|
+
Closes the gap that a completed cycle's design output (`EXPERIENCE.md`, `DESIGN.md`, `DESIGN-VERIFICATION.md`, the decision log, screenshots) lives only in the repo — stakeholders not in code can't consume it. `/gdd:export <cycle> --format html|pdf|notion` packages it into a shareable artifact. **No new runtime dependency** (D-02): `build-html.cjs` is a pure, dep-free assembler; the PDF format is the same HTML plus Paged.js-compatible `@page` print CSS that the user renders (GDD ships **no** PDF runtime); Notion is written via the Notion MCP. Every artifact is **redacted** (mandatory `scripts/lib/redact.cjs`); `--pseudonymize` masks git identity / paths / hostname for external sharing; `--pr` posts the HTML preview as a PR comment via `pr-commenter`.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`scripts/lib/export/build-html.cjs`** — a pure, dependency-free self-contained HTML assembler: inline `<style>`, base64-embedded screenshots, **zero external resource references**, a minimal deterministic markdown→HTML subset. `print: true` adds the Paged.js `@page` print CSS for the PDF format. Same input → byte-identical output.
|
|
16
|
+
- **`skills/export/SKILL.md`** (`/gdd:export`) — resolves the cycle, reads the design source set, redacts always (+ pseudonymizes on `--pseudonymize`), renders html/pdf via `build-html` or a Notion page via the MCP, and hands the HTML to `pr-commenter` on `--pr`.
|
|
17
|
+
- **`connections/notion.md`** — Notion MCP write-path (`mcp__notion__*`, ToolSearch probe, redact, `GDD_DISABLE_NOTION` kill-switch, degrade-to-HTML). Onboarded 18 → 19 — **export-only** (not a pipeline stage; no capability-matrix column).
|
|
18
|
+
- **`reference/export-formats.md`** — the `/gdd:export` contract (source set, the three formats, redact + `--pseudonymize`, the `--pr` hand-off, the self-contained guarantee); registered in `reference/registry.json`.
|
|
19
|
+
|
|
20
|
+
### Notes
|
|
21
|
+
|
|
22
|
+
- **No new runtime dependency** (D-02) and **no new egress** (`scan:outbound` unchanged — Notion is written via MCP tools, not raw HTTP).
|
|
23
|
+
- 6-manifest lockstep at **v1.35.5** + `OFF_CADENCE_VERSIONS.add('1.35.5')` + the 22 live-pinned `manifests-version.txt` baselines forward-propagated 1.35.3 → 1.35.5 (1.35.4 not used).
|
|
24
|
+
- The 31.5 tarball golden was regenerated as a reviewed delta: **+4** (`scripts/lib/export/build-html.cjs`, `skills/export/SKILL.md`, `connections/notion.md`, `reference/export-formats.md`), zero removals (657 → 661).
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
7
28
|
## [1.35.3] - 2026-06-01
|
|
8
29
|
|
|
9
30
|
### Phase 35.3 — Team Surfaces: Ticket Sync (Linear + Jira) — completes Phase 35
|
package/README.md
CHANGED
|
@@ -146,6 +146,10 @@ Routes pipeline events (verify-fail / audit-pass / ship) to **Slack** + **Discor
|
|
|
146
146
|
|
|
147
147
|
Links a design cycle to a **Linear** or **Jira** ticket and keeps them in sync ([`connections/linear.md`](connections/linear.md) / [`connections/jira.md`](connections/jira.md), MCP-based). [`agents/ticket-sync-agent.md`](agents/ticket-sync-agent.md) surfaces the linked ticket's comments as context when a design file opens (via the decision-injector) and, on `/gdd:complete-cycle`, transitions the ticket + posts a **redacted** summary. Per-system kill-switches (`GDD_DISABLE_LINEAR` / `GDD_DISABLE_JIRA`); degrade-to-noop (never gates the cycle). **No new runtime dependency, no new egress** (MCP tools only). Contract: [`reference/ticket-sync.md`](reference/ticket-sync.md). **Completes the Team Surfaces layer** (PR inline + notifications + ticket sync).
|
|
148
148
|
|
|
149
|
+
### Design-artifact export (v1.35.5)
|
|
150
|
+
|
|
151
|
+
`/gdd:export <cycle> --format html|pdf|notion` packages a finished cycle's design output (`EXPERIENCE.md`, `DESIGN.md`, `DESIGN-VERIFICATION.md`, the decision log, screenshots) into a stakeholder-shareable artifact — for PMs/execs/brand who aren't in the repo. The [`build-html`](scripts/lib/export/build-html.cjs) assembler emits a **self-contained** HTML (inline CSS, base64-embedded screenshots, **zero external references**); `pdf` is the same HTML plus Paged.js-compatible `@page` print CSS you render yourself; `notion` writes a page via the Notion MCP ([`connections/notion.md`](connections/notion.md), degrade-to-HTML). Every artifact is **redacted**; `--pseudonymize` masks identity/paths/hostname for external sharing; `--pr` posts the HTML preview as a PR comment via `pr-commenter`. **No new runtime dependency** (D-02: pure assembler, no PDF/markdown library). Contract: [`reference/export-formats.md`](reference/export-formats.md).
|
|
152
|
+
|
|
149
153
|
### Previous releases
|
|
150
154
|
|
|
151
155
|
- **v1.26.0** — Headless Model Resolver (per-runtime tier→model map, `resolved_models` router field, per-runtime price tables, `reasoning-class` runtime-neutral alias).
|
package/SKILL.md
CHANGED
|
@@ -99,6 +99,7 @@ Each stage produces artifacts in `.design/` inside the current project.
|
|
|
99
99
|
| `watch-authorities [--refresh] [--since <date>] [--feed <name>] [--schedule <cadence>]` | `get-design-done:gdd-watch-authorities` | Run design-authority-watcher — fetch curated feeds, diff snapshot, classify new entries → `.design/authority-report.md` (consumed by `/gdd:reflect`) |
|
|
100
100
|
| `benchmark <component\|--wave N\|--list\|--refresh component>` | `get-design-done:gdd-benchmark` | Harvest + synthesize per-component design specs from 18 design systems → `reference/components/<name>.md` |
|
|
101
101
|
| `benchmark <component\|--wave N\|--list\|--refresh component>` | `get-design-done:gdd-benchmark` | Harvest + synthesize per-component design specs from 18 design systems → `reference/components/<name>.md` |
|
|
102
|
+
| `export <cycle> --format html\|pdf\|notion [--pseudonymize] [--pr]` | `get-design-done:gdd-export` | Phase 35.5 — package a finished cycle's design output into a stakeholder-shareable artifact (self-contained HTML / Paged.js-print PDF / Notion page); redacts always, `--pseudonymize` masks identity for external sharing, `--pr` posts the HTML preview via pr-commenter |
|
|
102
103
|
|
|
103
104
|
## Handoff Routing
|
|
104
105
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This directory contains connection specifications for external tools and MCPs that the get-design-done pipeline integrates with. Each connection has its own spec file. This file is the index.
|
|
4
4
|
|
|
5
|
-
**Getting started:** run `/gdd:connections` for the interactive onboarding wizard — it probes all
|
|
5
|
+
**Getting started:** run `/gdd:connections` for the interactive onboarding wizard — it probes all 19 connections, recommends setup based on your project type, and walks you through installing each one (auto-run for reversible MCP adds, copy-command for everything else). You can also run `/gdd:connections list` for a read-only status check or `/gdd:connections <name>` to jump to a single connection's setup.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -34,6 +34,7 @@ This directory contains connection specifications for external tools and MCPs th
|
|
|
34
34
|
| Discord | Active | [`connections/discord.md`](connections/discord.md) | **Notify** (Team Surfaces) — `DISCORD_WEBHOOK_URL` channel webhook; parity with Slack; `GDD_DISABLE_DISCORD` kill-switch; degrade-to-noop |
|
|
35
35
|
| Linear | Active | [`connections/linear.md`](connections/linear.md) | **Ticket-sync** (Team Surfaces) — `mcp__linear__*` (ToolSearch probe); bidirectional cycle↔issue; redact + `GDD_DISABLE_LINEAR` kill-switch; degrade-to-noop |
|
|
36
36
|
| Jira | Active | [`connections/jira.md`](connections/jira.md) | **Ticket-sync** (Team Surfaces) — Atlassian MCP `mcp__atlassian__*` (ToolSearch probe); parity with Linear; `GDD_DISABLE_JIRA` kill-switch; degrade-to-noop |
|
|
37
|
+
| Notion | Active | [`connections/notion.md`](connections/notion.md) | **Export** write-path (not a pipeline stage) — `mcp__notion__*` (ToolSearch probe); `/gdd:export --format notion`; redact + `GDD_DISABLE_NOTION` kill-switch; degrade-to-HTML |
|
|
37
38
|
|
|
38
39
|
---
|
|
39
40
|
|
|
@@ -172,6 +173,14 @@ Step E1 — ToolSearch check:
|
|
|
172
173
|
Write mobbin status to STATE.md <connections>.
|
|
173
174
|
```
|
|
174
175
|
|
|
176
|
+
**Notion probe (ToolSearch-only — export write-path, 35.5):**
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
Step J1 — ToolSearch({ query: "notion", max_results: 5 })
|
|
180
|
+
→ Empty / GDD_DISABLE_NOTION=1 → notion: not_configured (export degrades to the HTML format)
|
|
181
|
+
→ Non-empty → notion: available
|
|
182
|
+
```
|
|
183
|
+
|
|
175
184
|
**Linear probe (ToolSearch-only — ticket-sync):**
|
|
176
185
|
|
|
177
186
|
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Notion — Connection Specification
|
|
2
|
+
|
|
3
|
+
This file is the connection specification for Notion within the get-design-done pipeline. See `connections/connections.md` for the index + capability matrix (the notion row is added at the 35.5 closeout).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Notion is the **export write-path** for `/gdd:export --format notion` (Phase 35.5). GDD generates a Notion page from a completed cycle's design artifacts — a stakeholder-shareable design-review packet. MCP-based (`mcp__notion__*`) — GDD calls MCP tools, not raw HTTP; no bundled Notion SDK, no new outbound egress. Outbound content is redacted; degrades to the self-contained HTML format when Notion is absent or disabled.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
**Prerequisites:** the Notion MCP server connected to your workspace (OAuth on first use). No GDD-held token.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
# register the Notion MCP per Notion's MCP docs, then restart the session
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Verification:**
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
ToolSearch({ query: "notion", max_results: 10 })
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Expect Notion page/block tools (`mcp__notion__*`). If empty → `notion: not_configured`. Verify exact tool names via ToolSearch; do not hardcode.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## What GDD does
|
|
30
|
+
|
|
31
|
+
On `/gdd:export --format notion`, GDD creates a page from the export source set (EXPERIENCE.md + DESIGN.md + DESIGN-VERIFICATION.md + decisions + screenshots): headings → toggle/section blocks, screenshots → image-upload blocks. Every text block is **redacted** (`scripts/lib/redact.cjs`); `--pseudonymize` additionally masks identity. Write-only (export); GDD does not read/sync Notion content.
|
|
32
|
+
|
|
33
|
+
## Redaction + kill-switch + degrade
|
|
34
|
+
|
|
35
|
+
- Every block body passes through `scripts/lib/redact.cjs` (the single chokepoint).
|
|
36
|
+
- Kill-switch: `GDD_DISABLE_NOTION=1` (env) or `.design/config.json` `"export": { "notion": { "enabled": false } }`. `gsd-health` surfaces it.
|
|
37
|
+
- **Degrade:** `notion: not_configured` / disabled / an MCP error → `/gdd:export` falls back to the self-contained `html` format + a note (the export never fails on Notion absence — D-03/D-07).
|
|
38
|
+
|
|
39
|
+
## STATE.md integration + probe
|
|
40
|
+
|
|
41
|
+
```xml
|
|
42
|
+
<connections>
|
|
43
|
+
notion: not_configured
|
|
44
|
+
</connections>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
| Value | Meaning |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `available` | ToolSearch returned `mcp__notion__*` tools AND not disabled |
|
|
50
|
+
| `unavailable` | tools present but a call errored (auth/rate) |
|
|
51
|
+
| `not_configured` | ToolSearch empty — Notion MCP not registered |
|
|
52
|
+
|
|
53
|
+
**Probe (ToolSearch-only):** `ToolSearch({ query: "notion", max_results: 5 })` → empty → `not_configured`, non-empty → `available`. Which stages probe: the export skill only (Notion is an export target, not a pipeline-stage connection).
|
|
54
|
+
|
|
55
|
+
## Anti-pattern
|
|
56
|
+
|
|
57
|
+
Don't post un-redacted artifacts; don't treat Notion as a read/sync source (export write-path only — bidirectional sync is out of scope); don't hard-require Notion (always degrade to the HTML file). Confluence is explicitly out of scope this phase (Notion-only).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hegemonart/get-design-done",
|
|
3
|
-
"version": "1.35.
|
|
3
|
+
"version": "1.35.5",
|
|
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,31 @@
|
|
|
1
|
+
# Export Formats — the `/gdd:export` contract
|
|
2
|
+
|
|
3
|
+
How `/gdd:export <cycle> --format html|pdf|notion [--pseudonymize] [--pr]` turns a completed cycle's in-repo design output into a stakeholder-shareable artifact. Dep-free: the HTML/PDF assembler is pure (`scripts/lib/export/build-html.cjs`); Notion is MCP-based; no `paged`/`puppeteer`/`pdfkit`/markdown-lib runtime.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Source set (what gets packaged)
|
|
8
|
+
|
|
9
|
+
In cycle order: `EXPERIENCE.md` (Phase 19.5 cross-cycle memory) · `.design/DESIGN.md` · `.design/DESIGN-VERIFICATION.md` · `.design/DESIGN-AUDIT.md` (if present) · the decision log (`D-XX`) · Preview/Chromatic screenshots (base64-embedded for html/pdf).
|
|
10
|
+
|
|
11
|
+
## Formats
|
|
12
|
+
|
|
13
|
+
- **`html`** (default) — `buildHtml({ title, subtitle, sections, images })` → a **single self-contained HTML** file: inline `<style>`, base64-embedded images, **zero external references** (safe to email / drop in Drive). Written to `.design/export/<cycle>.html`.
|
|
14
|
+
- **`pdf`** — the same `buildHtml({ ..., print: true })` (adds a Paged.js-compatible `@page` print stylesheet). Written to `.design/export/<cycle>.print.html`; **the user renders it** via Paged.js / headless-Chrome. GDD ships **no** PDF runtime (the print-executor precedent, D-02).
|
|
15
|
+
- **`notion`** — a Notion page via the Notion MCP (`connections/notion.md`): headings → section/toggle blocks, screenshots → image-upload blocks. Degrades to the `html` file when the Notion MCP is `not_configured`/disabled.
|
|
16
|
+
|
|
17
|
+
## Privacy (redact always; pseudonymize opt-in)
|
|
18
|
+
|
|
19
|
+
Every section is passed through `scripts/lib/redact.cjs` (secrets — the floor). `--pseudonymize` additionally applies `scripts/lib/pseudonymize.cjs` (git identity / paths / hostname / repo origin) — use it when sharing externally. Default (no flag) = redact only.
|
|
20
|
+
|
|
21
|
+
## PR integration (`--pr`)
|
|
22
|
+
|
|
23
|
+
`--pr` hands the generated self-contained HTML preview to `agents/pr-commenter.md` (Phase 35.1) to post as a PR comment — degrade-to-noop when there's no PR or pr-commenter is unavailable (never blocks the export).
|
|
24
|
+
|
|
25
|
+
## Self-contained guarantee (html/pdf)
|
|
26
|
+
|
|
27
|
+
`build-html.cjs` emits no external `src=`/`<link>`/`<script>` — CSS is inline, images are base64 `data:` URIs. Content links (`<a href="https://…">`) are preserved (they're references, not load-bearing resources). Deterministic: same input → byte-identical output (the regression baseline freezes a fixture render).
|
|
28
|
+
|
|
29
|
+
## Out of scope
|
|
30
|
+
|
|
31
|
+
Confluence (Notion-only this phase); Figma export (Phase 31); video walkthroughs; collaborative editing (read-only handoff); bidirectional Notion sync (export write-path only); a bundled PDF/markdown runtime (D-02).
|
package/reference/registry.json
CHANGED
|
@@ -930,6 +930,13 @@
|
|
|
930
930
|
"type": "heuristic",
|
|
931
931
|
"phase": 35.3,
|
|
932
932
|
"description": "Phase 35.3 ticket-sync contract — the STATE <ticket_links> cycle→ticket map, the bidirectional read (decision-injector surfaces linked-ticket comments on .design open) + write (transition + redacted summary on cycle completion) flow via MCP tools (mcp__linear__* / mcp__atlassian__*; no SDK, no raw HTTP), the default status-transition map, tracker-wins conflict resolution, the mandatory scripts/lib/redact.cjs chokepoint, and the GDD_DISABLE_LINEAR/GDD_DISABLE_JIRA kill-switches. Consumed by agents/ticket-sync-agent.md."
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
"name": "export-formats",
|
|
936
|
+
"path": "reference/export-formats.md",
|
|
937
|
+
"type": "heuristic",
|
|
938
|
+
"phase": 35.5,
|
|
939
|
+
"description": "Phase 35.5 /gdd:export contract — the source set (EXPERIENCE.md + DESIGN.md + DESIGN-VERIFICATION.md + decisions + screenshots), the three formats (self-contained HTML via scripts/lib/export/build-html.cjs, Paged.js-compatible print PDF rendered by the user, Notion page via the Notion MCP), mandatory scripts/lib/redact.cjs + the --pseudonymize opt-in (scripts/lib/pseudonymize.cjs), and the --pr hand-off to pr-commenter. No bundled PDF/markdown runtime (D-02)."
|
|
933
940
|
}
|
|
934
941
|
]
|
|
935
942
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* scripts/lib/export/build-html.cjs — Phase 35.5 self-contained HTML assembler.
|
|
4
|
+
*
|
|
5
|
+
* Pure + dep-free (D-02): no markdown library, no `paged`/`puppeteer`/`pdfkit`. Produces a
|
|
6
|
+
* SINGLE self-contained HTML string — inline <style>, base64-embedded images, ZERO external
|
|
7
|
+
* references — for the /gdd:export html + pdf formats (pdf = the same HTML + Paged.js-compatible
|
|
8
|
+
* @page print CSS the user renders, never a bundled PDF runtime). Deterministic: same input →
|
|
9
|
+
* byte-identical output (hermetic tests, D-07).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Escapes the 5 HTML-significant characters so the result is safe in BOTH element
|
|
13
|
+
// content AND double/single-quoted attribute values (e.g. <img alt="...">). Escaping
|
|
14
|
+
// the quotes is what makes attribute interpolation injection-safe (js/incomplete-html-
|
|
15
|
+
// attribute-sanitization). Order matters: & first so the entity ampersands aren't re-escaped.
|
|
16
|
+
function esc(s) {
|
|
17
|
+
return String(s)
|
|
18
|
+
.replace(/&/g, '&')
|
|
19
|
+
.replace(/</g, '<')
|
|
20
|
+
.replace(/>/g, '>')
|
|
21
|
+
.replace(/"/g, '"')
|
|
22
|
+
.replace(/'/g, ''');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Minimal, deterministic inline-markdown → HTML (escapes first, then re-introduces tags for
|
|
26
|
+
// the constructs GDD's .design markdown uses): `code`, **bold**, *italic*, [text](url).
|
|
27
|
+
function inline(text) {
|
|
28
|
+
let s = esc(text);
|
|
29
|
+
s = s.replace(/`([^`]+)`/g, (_, c) => `<code>${c}</code>`);
|
|
30
|
+
s = s.replace(/\*\*([^*]+)\*\*/g, (_, b) => `<strong>${b}</strong>`);
|
|
31
|
+
s = s.replace(/(^|[^*])\*([^*\n]+)\*/g, (_, p, i) => `${p}<em>${i}</em>`);
|
|
32
|
+
s = s.replace(/\[([^\]]+)\]\((https?:\/\/[^)\s]+|#[^)\s]*)\)/g, (_, t, u) => `<a href="${u}">${t}</a>`);
|
|
33
|
+
return s;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Block-level markdown → HTML. Handles headings, fenced code, ul/ol, blockquote, hr, images
|
|
37
|
+
// (resolved to base64 data URIs from the images map), and paragraphs.
|
|
38
|
+
function mdToHtml(md, images) {
|
|
39
|
+
const lines = String(md).replace(/\r\n/g, '\n').split('\n');
|
|
40
|
+
const out = [];
|
|
41
|
+
let i = 0;
|
|
42
|
+
const imgByName = new Map((images || []).map((im) => [im.name, im.dataUri]));
|
|
43
|
+
while (i < lines.length) {
|
|
44
|
+
const line = lines[i];
|
|
45
|
+
if (/^```/.test(line)) { // fenced code
|
|
46
|
+
const buf = []; i++;
|
|
47
|
+
while (i < lines.length && !/^```/.test(lines[i])) { buf.push(esc(lines[i])); i++; }
|
|
48
|
+
i++; out.push(`<pre><code>${buf.join('\n')}</code></pre>`); continue;
|
|
49
|
+
}
|
|
50
|
+
const h = line.match(/^(#{1,4})\s+(.*)$/);
|
|
51
|
+
if (h) { const n = h[1].length; out.push(`<h${n}>${inline(h[2])}</h${n}>`); i++; continue; }
|
|
52
|
+
if (/^\s*([-*])\s+/.test(line)) { // unordered list
|
|
53
|
+
const items = [];
|
|
54
|
+
while (i < lines.length && /^\s*([-*])\s+/.test(lines[i])) { items.push(`<li>${inline(lines[i].replace(/^\s*[-*]\s+/, ''))}</li>`); i++; }
|
|
55
|
+
out.push(`<ul>${items.join('')}</ul>`); continue;
|
|
56
|
+
}
|
|
57
|
+
if (/^\s*\d+\.\s+/.test(line)) { // ordered list
|
|
58
|
+
const items = [];
|
|
59
|
+
while (i < lines.length && /^\s*\d+\.\s+/.test(lines[i])) { items.push(`<li>${inline(lines[i].replace(/^\s*\d+\.\s+/, ''))}</li>`); i++; }
|
|
60
|
+
out.push(`<ol>${items.join('')}</ol>`); continue;
|
|
61
|
+
}
|
|
62
|
+
if (/^>\s?/.test(line)) { out.push(`<blockquote>${inline(line.replace(/^>\s?/, ''))}</blockquote>`); i++; continue; }
|
|
63
|
+
if (/^(---+|\*\*\*+)\s*$/.test(line)) { out.push('<hr>'); i++; continue; }
|
|
64
|
+
const img = line.match(/^!\[([^\]]*)\]\(([^)\s]+)\)\s*$/); // image — resolve to base64
|
|
65
|
+
if (img) {
|
|
66
|
+
const src = imgByName.get(img[2]) || (img[2].startsWith('data:') ? img[2] : '');
|
|
67
|
+
if (src) out.push(`<figure><img alt="${esc(img[1])}" src="${src}"><figcaption>${esc(img[1])}</figcaption></figure>`);
|
|
68
|
+
i++; continue;
|
|
69
|
+
}
|
|
70
|
+
if (line.trim() === '') { i++; continue; }
|
|
71
|
+
// paragraph — gather consecutive non-blank, non-block lines
|
|
72
|
+
const para = [line]; i++;
|
|
73
|
+
while (i < lines.length && lines[i].trim() !== '' && !/^(#{1,4}\s|```|>\s?|\s*[-*]\s|\s*\d+\.\s|!\[)/.test(lines[i])) { para.push(lines[i]); i++; }
|
|
74
|
+
out.push(`<p>${inline(para.join(' '))}</p>`);
|
|
75
|
+
}
|
|
76
|
+
return out.join('\n');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const SCREEN_CSS = `:root{--ink:#1a1a1a;--muted:#6b7280;--rule:#e5e7eb;--accent:#2563eb}*{box-sizing:border-box}body{margin:0;font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:var(--ink);background:#fff}main{max-width:820px;margin:0 auto;padding:48px 24px}h1{font-size:2rem;line-height:1.2;margin:0 0 .5rem}h2{font-size:1.4rem;margin:2rem 0 .5rem;padding-top:1rem;border-top:1px solid var(--rule)}h3{font-size:1.1rem;margin:1.5rem 0 .4rem}p{margin:.6rem 0}code{background:#f3f4f6;padding:.1em .35em;border-radius:4px;font-size:.9em}pre{background:#f8f9fb;border:1px solid var(--rule);border-radius:8px;padding:14px;overflow:auto}pre code{background:none;padding:0}a{color:var(--accent)}blockquote{margin:.8rem 0;padding:.4rem 1rem;border-left:3px solid var(--accent);color:var(--muted)}figure{margin:1rem 0}img{max-width:100%;height:auto;border:1px solid var(--rule);border-radius:8px}figcaption{font-size:.85rem;color:var(--muted);margin-top:.3rem}hr{border:none;border-top:1px solid var(--rule);margin:2rem 0}.gdd-meta{color:var(--muted);font-size:.9rem;margin-bottom:2rem}`;
|
|
80
|
+
const PRINT_CSS = `@page{size:A4;margin:18mm 16mm}@media print{h2{break-before:auto}figure,pre,blockquote{break-inside:avoid}main{max-width:none;padding:0}a{color:var(--ink);text-decoration:underline}}`;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* buildHtml({ title, subtitle?, sections:[{heading, markdown}], images?:[{name, dataUri}], print? })
|
|
84
|
+
* → a single self-contained HTML document string (inline CSS, base64 images, no external refs).
|
|
85
|
+
*/
|
|
86
|
+
function buildHtml(opts = {}) {
|
|
87
|
+
const title = esc(opts.title || 'GDD Design Export');
|
|
88
|
+
const css = SCREEN_CSS + (opts.print ? PRINT_CSS : '');
|
|
89
|
+
const body = (opts.sections || [])
|
|
90
|
+
.map((sec) => `<section>\n<h2>${esc(sec.heading)}</h2>\n${mdToHtml(sec.markdown || '', opts.images)}\n</section>`)
|
|
91
|
+
.join('\n');
|
|
92
|
+
const subtitle = opts.subtitle ? `<p class="gdd-meta">${esc(opts.subtitle)}</p>` : '';
|
|
93
|
+
return `<!DOCTYPE html>
|
|
94
|
+
<html lang="en">
|
|
95
|
+
<head>
|
|
96
|
+
<meta charset="utf-8">
|
|
97
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
98
|
+
<title>${title}</title>
|
|
99
|
+
<style>${css}</style>
|
|
100
|
+
</head>
|
|
101
|
+
<body>
|
|
102
|
+
<main>
|
|
103
|
+
<h1>${title}</h1>
|
|
104
|
+
${subtitle}
|
|
105
|
+
${body}
|
|
106
|
+
</main>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = { buildHtml, mdToHtml, inline, esc };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gdd-connections
|
|
3
|
-
description: "Interactive onboarding wizard for the
|
|
3
|
+
description: "Interactive onboarding wizard for the 19 external integrations the pipeline supports — probes all (`figma`, `refero`, `preview`, `storybook`, `chromatic`, `graphify`, `pinterest`, `claude-design`, `paper-design`, `pencil-dev`, `21st-dev`, `magic-patterns`, `lazyweb`, `mobbin`, `slack`, `discord`, `linear`, `jira`, `notion`), recommends based on project type, walks the user through setup (auto-run MCP install or copy-command fallback), writes results to `STATE.md <connections>`. Use after `/gdd:new-project` or whenever the user wants to add, inspect, or skip a connection. Re-runnable anytime."
|
|
4
4
|
argument-hint: "[list | <connection-name> | --auto]"
|
|
5
5
|
user-invocable: true
|
|
6
6
|
tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, ToolSearch
|
|
@@ -8,11 +8,11 @@ tools: Read, Write, Bash, Glob, Grep, AskUserQuestion, ToolSearch
|
|
|
8
8
|
|
|
9
9
|
# /gdd:connections
|
|
10
10
|
|
|
11
|
-
Interactive onboarding for the
|
|
11
|
+
Interactive onboarding for the 19 external integrations the pipeline supports. Replaces "probe silently at scan entry and hope the user noticed" with an explicit "here is what can plug in, here is how."
|
|
12
12
|
|
|
13
13
|
Canonical per-connection specs live in `../../connections/<name>.md` (one file per integration). The capability matrix + probe-pattern spec live in `../../connections/connections.md`. This skill is the **user-facing front end** for those specs.
|
|
14
14
|
|
|
15
|
-
For the
|
|
15
|
+
For the 19 probe scripts (MCP + HTTP + CLI + file probes), bucket categorization, per-connection setup screen, auto-run eligibility matrix, value-prop one-liners, and STATE.md / config.json write contracts, see `./connections-onboarding.md`. For the cross-skill probe pattern + connection-handshake summary, see `../../reference/shared-preamble.md#connection-handshake-summary`. For the cross-skill output discipline, see `../../reference/shared-preamble.md#output-contract-reminders`.
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -38,7 +38,7 @@ For the 18 probe scripts (MCP + HTTP + CLI + file probes), bucket categorization
|
|
|
38
38
|
|
|
39
39
|
## Workflow
|
|
40
40
|
|
|
41
|
-
1. **Probe all
|
|
41
|
+
1. **Probe all 19 connections** — run every probe script per `./connections-onboarding.md#step-1--probe-all-19-connections`. MCP probes use `ToolSearch` first; HTTP / CLI / file probes follow non-MCP patterns. Merge results into `STATE.md <connections>` with the three-value schema (`available | unavailable | not_configured`) — never add new values.
|
|
42
42
|
2. **Categorize + build summary** — bucket each probe result (available / recommended / optional / skipped / unavailable) using project-hint detection. Detail + recommendation mapping: `./connections-onboarding.md#step-2--bucket-categorization`.
|
|
43
43
|
3. **Print summary table** — show buckets + value-prop one-liners (verbatim from `./connections-onboarding.md#step-3--summary-table`).
|
|
44
44
|
4. **Route by mode** — `list` / `--auto` exits after summary; `<name>` jumps straight to Step 5; default mode opens an AskUserQuestion (configure recommended / pick one by one / configure all optional / re-check specific / exit). Routing detail: `./connections-onboarding.md#step-4--route-by-mode`.
|
|
@@ -9,7 +9,7 @@ last_updated: 2026-05-18
|
|
|
9
9
|
|
|
10
10
|
Source: extracted from `skills/connections/SKILL.md` (Phase 28.5 rework — D-10 extract-then-link).
|
|
11
11
|
The skill's load-bearing routing + invocation-mode dispatch stays in `../skills/connections/SKILL.md`;
|
|
12
|
-
this file holds the
|
|
12
|
+
this file holds the 19 probe scripts, bucket categorization, per-connection setup screen,
|
|
13
13
|
auto-run eligibility matrix, value-prop one-liners, and STATE.md / config.json write contracts.
|
|
14
14
|
|
|
15
15
|
# Connections Onboarding Procedure
|
|
@@ -27,7 +27,7 @@ this file does NOT duplicate them; it points at them by name.
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
## Step 1 — Probe all
|
|
30
|
+
## Step 1 — Probe all 19 connections
|
|
31
31
|
|
|
32
32
|
Run every probe below in order. MCP probes call `ToolSearch` first (deferred tools fail silently without it). Write every result to `STATE.md <connections>` when done.
|
|
33
33
|
|
|
@@ -128,6 +128,13 @@ ToolSearch({ query: "atlassian jira", max_results: 5 })
|
|
|
128
128
|
→ Non-empty → jira: available
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
+
**notion:** (export write-path — MCP)
|
|
132
|
+
```
|
|
133
|
+
ToolSearch({ query: "notion", max_results: 5 })
|
|
134
|
+
→ Empty / GDD_DISABLE_NOTION=1 → notion: not_configured
|
|
135
|
+
→ Non-empty → notion: available
|
|
136
|
+
```
|
|
137
|
+
|
|
131
138
|
### Non-MCP probes
|
|
132
139
|
|
|
133
140
|
**storybook** (HTTP):
|
|
@@ -173,7 +180,7 @@ Bash: ls .design/handoff/ 2>/dev/null || find . -maxdepth 3 \
|
|
|
173
180
|
→ Non-empty → claude_design: available
|
|
174
181
|
```
|
|
175
182
|
|
|
176
|
-
After all
|
|
183
|
+
After all 19 probes complete, merge results into `STATE.md <connections>`. Preserve the three-value schema verbatim (`available | unavailable | not_configured`). Do not add new values.
|
|
177
184
|
|
|
178
185
|
---
|
|
179
186
|
|
|
@@ -260,6 +267,7 @@ One-line value props (use verbatim):
|
|
|
260
267
|
| discord | notify — route pipeline events to a Discord channel (redacted) |
|
|
261
268
|
| linear | ticket-sync — link a cycle to a Linear issue; read comments + transition on completion |
|
|
262
269
|
| jira | ticket-sync — parity with Linear via the Atlassian MCP |
|
|
270
|
+
| notion | export — `/gdd:export --format notion` writes a stakeholder page (degrade-to-HTML) |
|
|
263
271
|
|
|
264
272
|
---
|
|
265
273
|
|
|
@@ -287,7 +295,7 @@ options:
|
|
|
287
295
|
- "Exit" → emit ## CONNECTIONS COMPLETE, exit
|
|
288
296
|
```
|
|
289
297
|
|
|
290
|
-
If recommended bucket is empty, swap that option for "Show all
|
|
298
|
+
If recommended bucket is empty, swap that option for "Show all 19 and pick."
|
|
291
299
|
|
|
292
300
|
---
|
|
293
301
|
|
|
@@ -350,6 +358,7 @@ options:
|
|
|
350
358
|
| discord | set `DISCORD_WEBHOOK_URL` env (Discord channel Webhook URL) | ✗ no | Env credential — user sets it; no install command (degrade-to-noop when unset) |
|
|
351
359
|
| linear | `claude mcp add linear ...` (Linear MCP) | ✓ yes | Reversible MCP add; OAuth on first call, no credential filesystem-write |
|
|
352
360
|
| jira | `claude mcp add atlassian ...` (Atlassian MCP) | ✓ yes | Reversible MCP add; OAuth on first call |
|
|
361
|
+
| notion | `claude mcp add notion ...` (Notion MCP) | ✓ yes | Reversible MCP add; OAuth on first call |
|
|
353
362
|
|
|
354
363
|
For non-auto-run connections, hide the "Run install command now" option entirely in 5.3.
|
|
355
364
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-export
|
|
3
|
+
description: "Packages a completed design cycle (.design artifacts + decisions + screenshots) into a stakeholder-shareable artifact — self-contained HTML, print-styled PDF (Paged.js-compatible), or a Notion page. Redacts secrets; --pseudonymize masks identity for external sharing; --pr posts the HTML preview as a PR comment. Use to hand a design-review packet to PMs/execs/brand who aren't in the repo."
|
|
4
|
+
argument-hint: "<cycle-id> --format html|pdf|notion [--pseudonymize] [--pr]"
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tools: Read, Write, Bash, Glob, Grep, ToolSearch, Task
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /gdd:export
|
|
10
|
+
|
|
11
|
+
Turns a completed cycle's in-repo design output into a shareable artifact. Closes the gap that `.design/*.md` lives only in the repo — stakeholders not in code can't consume it. The format contract + source set live in `../../reference/export-formats.md`; the Notion write-path in `../../connections/notion.md`.
|
|
12
|
+
|
|
13
|
+
## Steps
|
|
14
|
+
|
|
15
|
+
1. **Resolve the cycle.** `<cycle-id>` (or the current cycle from `.design/STATE.md`). Read the **source set**: `EXPERIENCE.md` (Phase 19.5), `.design/DESIGN.md`, `.design/DESIGN-VERIFICATION.md`, `.design/DESIGN-AUDIT.md` (if present), the decision log, and any Preview/Chromatic screenshots.
|
|
16
|
+
2. **Redact (always) + pseudonymize (opt-in).** Pass every section through `scripts/lib/redact.cjs` (secrets). If `--pseudonymize`, additionally apply `scripts/lib/pseudonymize.cjs` (git identity / paths / hostname) for external sharing. Honor `GDD_DISABLE_NOTION` for the notion format.
|
|
17
|
+
3. **Assemble per `--format`:**
|
|
18
|
+
- **`html`** (default) — `node -e "require('scripts/lib/export/build-html.cjs').buildHtml({...})"` → a **self-contained** HTML (inline CSS, base64-embedded screenshots, no external refs). Write to `.design/export/<cycle>.html`.
|
|
19
|
+
- **`pdf`** — the same `buildHtml({ ..., print: true })` (Paged.js-compatible `@page` print CSS). Write `.design/export/<cycle>.print.html`; instruct the user to render it via Paged.js / headless-Chrome (GDD ships **no** PDF runtime — D-02).
|
|
20
|
+
- **`notion`** — probe the Notion MCP (`ToolSearch({query:"notion"})`); if `available`, create a page from the same source (nested toggles + image upload) per `connections/notion.md`; if `not_configured`/disabled → degrade to the `html` format + a note.
|
|
21
|
+
4. **`--pr`** — hand the generated HTML preview to `agents/pr-commenter.md` (via `Task`) to post as a PR comment (degrade-to-noop if no PR / pr-commenter unavailable).
|
|
22
|
+
5. **Print the artifact path** (and the Notion URL / PR comment status when applicable).
|
|
23
|
+
|
|
24
|
+
## Do Not
|
|
25
|
+
|
|
26
|
+
- Do not add a PDF/markdown runtime dependency (`paged`/`puppeteer`/`pdfkit`/a markdown lib) — `build-html.cjs` is pure and the PDF is render-it-yourself print HTML (D-02).
|
|
27
|
+
- Do not emit an un-redacted artifact — redact is mandatory; pseudonymize is the external-sharing opt-in.
|
|
28
|
+
- Do not block on Notion/PR — both degrade to a noop / the html file.
|
|
29
|
+
|
|
30
|
+
## EXPORT COMPLETE
|