@hegemonart/get-design-done 1.14.1 → 1.14.2

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.
@@ -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). Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation (auto-tag + GitHub Release + release-time smoke test).",
8
- "version": "1.14.1"
8
+ "version": "1.14.2"
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.",
15
- "version": "1.14.1",
15
+ "version": "1.14.2",
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.14.1",
4
+ "version": "1.14.2",
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.",
6
6
  "author": {
7
7
  "name": "hegemonart",
package/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ All notable changes to get-design-done are documented here. Versions follow [sem
4
4
 
5
5
  ---
6
6
 
7
+ ## [1.14.2] — 2026-04-20
8
+
9
+ ### Added — Multi-format Claude Design handoff ingestion
10
+
11
+ - **URL entry point**: detect `https://api.anthropic.com/v1/design/h/<hash>` in agent prompt (native "Send to local coding agent" flow); `WebFetch` with `Content-Type` routing — HTML parsed directly, ZIP downloaded and extracted
12
+ - **ZIP bundle**: extract to `.design/handoff/`, find primary HTML + readme, parse normally, clean up after
13
+ - **PDF format**: `pdftotext` text extraction; grep for token values; all decisions tagged `(tentative — text-only)` since no CSS is present
14
+ - **PPTX format**: slide XML text extraction (`ppt/slides/*.xml`); same tentative-only tagging as PDF
15
+ - Updated synthesizer parsing algorithm step 1 with format dispatch before parsing
16
+ - Updated probe pattern: URL detection takes priority over file path lookup
17
+ - New `handoff_source` values: `claude-design-url`, `claude-design-zip`, `claude-design-pdf`, `claude-design-pptx`
18
+
19
+ ---
20
+
7
21
  ## [1.14.1] — 2026-04-19
8
22
 
9
23
  ### Fixed — Security hardening (full codebase review)
@@ -99,10 +99,29 @@ Read .design/STATE.md
99
99
 
100
100
  ### Parsing algorithm (handoff mode)
101
101
 
102
- 1. **Read bundle path** from STATE.md `handoff_path` field (or resolve from `handoff_source` if `handoff_path` is missing).
102
+ 1. **Resolve the bundle** from STATE.md fields in priority order:
103
103
 
104
- 2. **Parse HTML export** (primary):
105
- - Read the HTML file with the Read tool
104
+ ```
105
+ handoff_url present → fetch URL with WebFetch tool
106
+ check Content-Type:
107
+ text/html → use response body as html_content (goto step 2)
108
+ application/zip → save to .design/handoff/bundle.zip, goto ZIP branch
109
+ other → warn user, abort handoff mode
110
+ handoff_path present → check extension:
111
+ .html → read file, goto step 2
112
+ .zip → goto ZIP branch
113
+ .pdf → goto PDF branch
114
+ .pptx / .pptx → goto PPTX branch
115
+ neither present → warn "no handoff_path or handoff_url in STATE.md", abort handoff mode
116
+ ```
117
+
118
+ **ZIP branch:** Extract `.design/handoff/bundle.zip` to `.design/handoff/extracted/`. Find primary HTML (`index.html`, `design.html`, or first `.html` at root). Find spec file (`readme.md`, `spec.md`, or first `.md` at root). Set html_content + spec_content. Delete `.design/handoff/extracted/` after parsing.
119
+
120
+ **PDF branch:** Extract all text content (Bash: `pdftotext <file> -` or python `pdfminer`). Set text_content. Skip to step 3b.
121
+
122
+ **PPTX branch:** Extract slide text (Bash: unzip `.pptx`, parse `ppt/slides/*.xml` for `<a:t>` text nodes). Set text_content. Skip to step 3b.
123
+
124
+ 2. **Parse HTML export** (primary — html_content available):
106
125
  - Extract all CSS custom properties from `<style>` blocks: grep for `--[a-z]+-[a-z-]+:\s*[^;]+`
107
126
  - Categorize by prefix:
108
127
  - `--color-*` → `[Color]` decisions
@@ -114,15 +133,23 @@ Read .design/STATE.md
114
133
  - Extract component names from `class="component-*"` or `data-component="*"` patterns → `[Component]` decisions
115
134
  - Detect layout patterns: `display: grid`, `display: flex` in component-level sections → `[Layout]` decisions
116
135
 
117
- 3. **Parse spec markdown** (secondary, if present):
118
- - Look for `.md` or `.json` files in the same directory as the HTML export
136
+ 3. **Parse spec text** (secondary):
137
+
138
+ 3a. **Spec markdown / JSON** (if html_content path had a `.md` sibling, or ZIP contained spec):
119
139
  - Grep for `Decision:`, `Rationale:`, `Token:`, `Component:` prefixes
120
140
  - Treat found lines as pre-formed D-XX entries
121
141
 
142
+ 3b. **PDF / PPTX text** (text_content only, no HTML):
143
+ - Grep text_content for same prefixes as 3a
144
+ - Also grep for hex colors (`#[0-9a-fA-F]{3,6}`), rem/px values (`[\d.]+rem|[\d]+px`), font names
145
+ - Tag ALL entries `(tentative — text-only, no CSS confirmation)`
146
+ - Note in STATE.md: `handoff_format: pdf` or `handoff_format: pptx` with caveat that token values need user confirmation
147
+
122
148
  4. **Translate to D-XX decisions**:
123
149
  - CSS custom property: `D-NN: [Category] Token name: value (source: claude-design-handoff) (tentative — confirm with user)`
124
150
  - Explicit spec markdown decision: `D-NN: [Category] decision text (source: claude-design-handoff) (locked — from handoff spec)`
125
151
  - Inferred component/layout: `D-NN: [Category] inferred text (source: claude-design-handoff) (tentative — inferred)`
152
+ - PDF/PPTX text value: `D-NN: [Category] extracted text (source: claude-design-pdf/pptx) (tentative — text-only, no CSS confirmation)`
126
153
 
127
154
  5. **Append to STATE.md `<decisions>` block** under `### Handoff-sourced decisions` subsection header.
128
155
 
@@ -6,20 +6,94 @@ This file is the connection specification for Claude Design (https://claude.ai/d
6
6
 
7
7
  ## What Is a Claude Design Handoff Bundle?
8
8
 
9
- Claude Design produces AI-generated designs that can be exported as **handoff bundles**. A bundle contains:
9
+ Claude Design produces AI-generated designs that can be exported in several formats or sent directly to Claude Code via a hosted URL. The pipeline supports all of them.
10
10
 
11
- | Artifact | Format | Contains |
12
- |----------|--------|---------|
13
- | Standalone HTML export | `.html` | Rendered component tree, inline CSS (design tokens as CSS custom properties), component structure, color/spacing/typography values |
14
- | Design spec (optional) | `.md` or `.json` | Design decisions as structured text, token tables, component annotations |
15
- | Assets (optional) | `assets/` dir | Icons, images referenced by the HTML export |
11
+ ### Entry Points
16
12
 
17
- **Bundle entry point:** The primary parseable artifact is the HTML export. It contains inline `<style>` blocks with CSS custom properties (e.g., `--color-primary: #3B82F6`) and class-level token usage.
13
+ | Source | How it arrives | handoff_source value |
14
+ |--------|---------------|----------------------|
15
+ | **"Send to local coding agent"** | Anthropic-hosted URL in the agent prompt | `claude-design-url` |
16
+ | **"Download zip"** | `.zip` bundle dropped into project | `claude-design-zip` |
17
+ | **"Save as standalone HTML"** | `.html` file dropped into project | `claude-design-html` |
18
+ | **"Save as PDF"** | `.pdf` file (spec text extraction only) | `claude-design-pdf` |
19
+ | **"Save as PPTX"** | `.pptx` file (spec text extraction only) | `claude-design-pptx` |
20
+ | **Bundle directory** | Unzipped directory with HTML + spec + assets | `claude-design-bundle` |
18
21
 
19
- **Bundle discovery:** The pipeline looks for the bundle in:
20
- 1. The path passed via `--from-handoff <path>` flag or `handoff <path>` sub-command
21
- 2. The value of `handoff_source` in `.design/STATE.md` (if a prior session already set it)
22
- 3. A `claude-design-handoff.html` file in the project root (convention — not required)
22
+ ### Bundle contents by format
23
+
24
+ | Format | Primary artifact | Design tokens | Spec text | Images |
25
+ |--------|-----------------|---------------|-----------|--------|
26
+ | URL (hosted) | Fetched HTML | ✅ CSS custom props | ✅ if readme present | ✅ |
27
+ | ZIP | Unzipped HTML | ✅ CSS custom props | ✅ `readme.md` inside | ✅ |
28
+ | Standalone HTML | `.html` file | ✅ CSS custom props | ✅ if `.md` alongside | ✅ inline |
29
+ | PDF | `.pdf` text | ❌ (no CSS) | ✅ extracted text | ❌ |
30
+ | PPTX | `.pptx` slides | ❌ (no CSS) | ✅ slide text only | ❌ |
31
+
32
+ **Bundle entry point:** The primary parseable artifact is always the HTML — it contains inline `<style>` blocks with CSS custom properties (e.g., `--color-primary: #3B82F6`) and class-level token usage. PDF and PPTX are text-extraction fallbacks when no HTML is available.
33
+
34
+ **Bundle discovery:** The pipeline looks for the bundle in this priority order:
35
+ 1. A `https://api.anthropic.com/v1/design/h/` URL in the agent invocation arguments
36
+ 2. The path passed via `--from-handoff <path>` flag or `handoff <path>` sub-command
37
+ 3. The value of `handoff_source` in `.design/STATE.md` (if a prior session already set it)
38
+ 4. A `claude-design-handoff.{html,zip,pdf,pptx}` file in the project root (convention — not required)
39
+
40
+ ---
41
+
42
+ ## Format-Specific Ingestion
43
+
44
+ ### URL format — `https://api.anthropic.com/v1/design/h/<hash>`
45
+
46
+ This is the native entry point when the user clicks **"Send to local coding agent"** in Claude Design. The agent prompt arrives as:
47
+
48
+ ```
49
+ Fetch this design file, read its readme, and implement the relevant aspects of the design. https://api.anthropic.com/v1/design/h/<hash>
50
+ Implement: <user description>
51
+ ```
52
+
53
+ **Detection:** grep the raw arguments/prompt for the pattern `https://api\.anthropic\.com/v1/design/h/[A-Za-z0-9_-]+`.
54
+
55
+ **Fetch sequence:**
56
+ 1. `WebFetch` the URL — the response is either an HTML bundle or a redirect to a ZIP download
57
+ 2. If `Content-Type: text/html` → treat as standalone HTML, parse normally
58
+ 3. If `Content-Type: application/zip` or redirect to `.zip` → download to `.design/handoff/claude-design-handoff.zip`, then follow ZIP ingestion below
59
+ 4. Check the response for an embedded `readme.md` link (often served alongside) — fetch it separately if present
60
+ 5. Set `handoff_source: claude-design-url` and `handoff_url: <url>` in STATE.md
61
+
62
+ **Implement description:** The text after `Implement:` in the agent prompt is the user's implementation scope — capture it as a project note, not a D-XX decision.
63
+
64
+ ### ZIP format
65
+
66
+ **Detection:** input path ends in `.zip` OR fetched from URL as zip.
67
+
68
+ **Ingestion sequence:**
69
+ 1. Extract to `.design/handoff/` (temp directory, not committed)
70
+ 2. Find the primary HTML: `index.html`, `design.html`, or any `.html` at root
71
+ 3. Find spec: `readme.md`, `spec.md`, `design.md`, or any `.md` at root
72
+ 4. Parse HTML + spec using the standard field catalogue below
73
+ 5. Clean up `.design/handoff/` after parsing (keep only extracted decisions in STATE.md)
74
+
75
+ ### PDF format
76
+
77
+ **Detection:** input path ends in `.pdf`.
78
+
79
+ **Ingestion:** PDF yields no CSS custom properties — token extraction is not possible. Instead:
80
+ 1. Extract all text content (pdftotext or equivalent)
81
+ 2. Grep for `Decision:`, `Rationale:`, `Token:`, `Color:`, `Typography:`, `Spacing:` prefixes
82
+ 3. Treat matched lines as spec text → translate to D-XX entries tagged `(source: claude-design-pdf)` + `(tentative — text-only, no CSS confirmation)`
83
+ 4. Note in STATE.md: `handoff_format: pdf` + caveat that token values were extracted from text, not CSS
84
+
85
+ **Limitation:** PDF handoffs cannot produce `(locked)` token decisions — all are `(tentative)`. Surface this explicitly to the user in the discussant step.
86
+
87
+ ### PPTX format
88
+
89
+ **Detection:** input path ends in `.pptx`.
90
+
91
+ **Ingestion:** Same as PDF — text extraction only, no CSS tokens.
92
+ 1. Extract slide text (python-pptx or unzip `.pptx` and parse `ppt/slides/*.xml`)
93
+ 2. Same grep patterns as PDF
94
+ 3. Tag all entries `(source: claude-design-pptx)` + `(tentative — text-only)`
95
+
96
+ **Limitation:** Same as PDF — all decisions are tentative. PPTX format is the weakest source; prefer HTML or ZIP if available.
23
97
 
24
98
  ---
25
99
 
@@ -114,13 +188,15 @@ Claude Design is not an MCP server — it has no tools to probe via ToolSearch.
114
188
 
115
189
  ```
116
190
  At scan stage entry:
117
- 1. Check STATE.md <position> for handoff_source field
191
+ 1. Check invocation arguments/prompt for https://api.anthropic.com/v1/design/h/ URL
118
192
  2. Check $ARGUMENTS for --from-handoff <path> flag
119
- 3. Check project root for claude-design-handoff.html
193
+ 3. Check STATE.md <position> for handoff_source / handoff_url / handoff_path field
194
+ 4. Check project root for claude-design-handoff.{html,zip,pdf,pptx}
120
195
 
121
- Bundle path found AND file exists → claude_design: available
122
- Bundle path provided but file missing/bad → claude_design: unavailable
123
- No bundle path, no file → claude_design: not_configured
196
+ URL detected (step 1) → claude_design: available (fetch at ingest time)
197
+ File path found AND file exists → claude_design: available
198
+ Path/URL provided but unreachable/bad → claude_design: unavailable
199
+ → None of the above → claude_design: not_configured
124
200
  ```
125
201
 
126
202
  Write result to STATE.md `<connections>` at scan entry.
@@ -168,17 +244,25 @@ skipped_stages: scan, discover, plan
168
244
 
169
245
  **`handoff_source` values:**
170
246
 
171
- | Value | Meaning |
172
- |-------|---------|
173
- | `claude-design-html` | Bundle is a standalone HTML export from Claude Design |
174
- | `claude-design-bundle` | Bundle is a directory with HTML + spec markdown + assets |
175
- | `manual` | User manually initialized STATE.md with design decisions (no bundle file) |
247
+ | Value | Meaning | Token quality |
248
+ |-------|---------|---------------|
249
+ | `claude-design-url` | Fetched from Anthropic-hosted URL (Send to local coding agent) | High — HTML |
250
+ | `claude-design-zip` | ZIP bundle dropped into project | High HTML inside |
251
+ | `claude-design-html` | Standalone HTML export | High CSS custom props |
252
+ | `claude-design-bundle` | Directory with HTML + spec markdown + assets | High — CSS custom props |
253
+ | `claude-design-pdf` | PDF export (text extraction only) | Low — text only, all tentative |
254
+ | `claude-design-pptx` | PPTX export (text extraction only) | Low — text only, all tentative |
255
+ | `manual` | User manually initialized STATE.md with design decisions (no bundle file) | N/A |
176
256
 
177
257
  ---
178
258
 
179
259
  ## Caveats and Pitfalls
180
260
 
181
- 1. **Handoff bundle format is undocumented by Anthropic.** The Claude Design handoff bundle format is inferred from the product announcement and common HTML export patterns. The pipeline uses defensive parsing: grep for CSS custom properties in `<style>` tags, extract component class names from `class="component-*"` patterns, and fall back to the spec markdown/JSON if CSS parsing yields no results. If the format changes in a future Claude Design release, update this spec and the synthesizer's parsing patterns.
261
+ 1. **Handoff bundle format is undocumented by Anthropic.** The Claude Design handoff bundle format is inferred from the product UI and common HTML export patterns. The pipeline uses defensive parsing: grep for CSS custom properties in `<style>` tags, extract component class names from `class="component-*"` patterns, and fall back to the spec markdown/JSON if CSS parsing yields no results. If the format changes in a future Claude Design release, update this spec and the synthesizer's parsing patterns. The URL endpoint (`/v1/design/h/<hash>`) may return different content types — always check `Content-Type` before deciding whether to parse as HTML or unzip.
262
+
263
+ 6. **PDF and PPTX handoffs produce only tentative decisions.** These formats contain no CSS — all token values must be inferred from prose. Never promote PDF/PPTX-sourced decisions to `(locked)` without explicit user confirmation. If the user provides both a PDF and an HTML export, always prefer the HTML.
264
+
265
+ 7. **ZIP extraction is ephemeral.** Extracted ZIP contents go to `.design/handoff/` and are deleted after parsing. Only the extracted D-XX decisions are persisted to STATE.md. Never commit the raw extracted files.
182
266
 
183
267
  2. **`(tentative)` decisions MUST be confirmed by the user.** The discussant `--from-handoff` mode surfaces all tentative decisions for confirmation before proceeding to verify. Do NOT skip this step — implementing against unconfirmed inferred values is the primary failure mode of handoff-sourced workflows.
184
268
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hegemonart/get-design-done",
3
- "version": "1.14.1",
3
+ "version": "1.14.2",
4
4
  "description": "A Claude Code plugin for systematic design improvement",
5
5
  "author": "Hegemon",
6
6
  "homepage": "https://github.com/hegemonart/get-design-done",
@@ -25,6 +25,9 @@
25
25
  "CHANGELOG.md",
26
26
  "LICENSE"
27
27
  ],
28
+ "bin": {
29
+ "get-design-done": "./scripts/install.cjs"
30
+ },
28
31
  "publishConfig": {
29
32
  "access": "public",
30
33
  "provenance": true
@@ -1,65 +0,0 @@
1
- # Branch Protection — Two-Phase Rollout
2
-
3
- Per D-16 / D-17: branch protection on `main` is rolled out in two phases. The
4
- repo admin applies each phase manually via `scripts/apply-branch-protection.sh`
5
- (no CI automation — avoids leaking repo admin credentials).
6
-
7
- ## Phase A — Advisory (initial state)
8
-
9
- Status checks **run** on every push, but they are **not required to merge**.
10
- This is the default posture while CI stabilizes and baselines are established.
11
-
12
- Apply:
13
-
14
- ```bash
15
- bash scripts/apply-branch-protection.sh --advisory
16
- ```
17
-
18
- Effects:
19
-
20
- - Required status checks: **none** (checks run but don't block)
21
- - `main` accepts direct pushes (the solo maintainer's existing workflow)
22
- - Force-push: allowed by admins
23
-
24
- ## Phase B — Enforcing (after first clean release)
25
-
26
- After the first full release cycle ships clean (plan 13-06 / 13-07 smoke test
27
- passes on a real tag + GitHub Release), tighten to enforcing.
28
-
29
- Apply:
30
-
31
- ```bash
32
- bash scripts/apply-branch-protection.sh --enforcing
33
- ```
34
-
35
- Effects:
36
-
37
- - Required status checks (all must pass to merge):
38
- - `Lint (markdown + frontmatter + stale-refs)`
39
- - `Validate (schemas + plugin + shellcheck)`
40
- - `Test (Node 22 / ubuntu-latest)`
41
- - `Test (Node 22 / macos-latest)`
42
- - `Test (Node 22 / windows-latest)`
43
- - `Test (Node 24 / ubuntu-latest)`
44
- - `Test (Node 24 / macos-latest)`
45
- - `Test (Node 24 / windows-latest)`
46
- - `Security (secrets + injection scan)`
47
- - `Size budget (blocking)`
48
- - Require linear history (no merge commits)
49
- - Disallow force-push
50
- - Admins still bypass for emergency fixes (logged)
51
-
52
- ## When to promote Phase A → Phase B
53
-
54
- - [ ] Wave A + B of Phase 13 merged to main
55
- - [ ] `release.yml` (plan 13-06) merged and triggered at least once successfully
56
- - [ ] Release smoke test (plan 13-07) passed on a real tag
57
- - [ ] Baseline lock (plan 13-08) committed
58
-
59
- When all four are true, run `apply-branch-protection.sh --enforcing`.
60
-
61
- ## Rollback
62
-
63
- To revert either phase: `apply-branch-protection.sh --disable` removes all
64
- protection rules. Use only if a protection misconfiguration is blocking a
65
- legitimate merge.
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env bash
2
- # apply-branch-protection.sh — manually apply branch protection to `main`.
3
- # Per D-16: this script is run by the repo admin locally, NOT from CI.
4
- # Usage:
5
- # bash scripts/apply-branch-protection.sh --advisory
6
- # bash scripts/apply-branch-protection.sh --enforcing
7
- # bash scripts/apply-branch-protection.sh --disable
8
-
9
- set -euo pipefail
10
-
11
- MODE="${1:-}"
12
- REPO="${GITHUB_REPOSITORY:-hegemonart/get-design-done}"
13
-
14
- if ! command -v gh >/dev/null 2>&1; then
15
- echo "ERROR: gh CLI not found. Install from https://cli.github.com/"
16
- exit 1
17
- fi
18
-
19
- case "$MODE" in
20
- --advisory)
21
- echo "Applying ADVISORY branch protection to $REPO main..."
22
- gh api -X PUT "repos/${REPO}/branches/main/protection" \
23
- -H "Accept: application/vnd.github+json" \
24
- -f "required_status_checks=null" \
25
- -F "enforce_admins=false" \
26
- -f "required_pull_request_reviews=null" \
27
- -F "restrictions=null" \
28
- -F "required_linear_history=false" \
29
- -F "allow_force_pushes=true" \
30
- -F "allow_deletions=false"
31
- echo "Advisory mode applied. CI checks will run but not block merges."
32
- ;;
33
- --enforcing)
34
- echo "Applying ENFORCING branch protection to $REPO main..."
35
- # Status check names must match the `name:` field of each job exactly.
36
- # See reference/BRANCH-PROTECTION.md §Phase B for the authoritative list.
37
- gh api -X PUT "repos/${REPO}/branches/main/protection" \
38
- -H "Accept: application/vnd.github+json" \
39
- --input - <<'JSON'
40
- {
41
- "required_status_checks": {
42
- "strict": true,
43
- "contexts": [
44
- "Lint (markdown + frontmatter + stale-refs)",
45
- "Validate (schemas + plugin + shellcheck)",
46
- "Test (Node 22 / ubuntu-latest)",
47
- "Test (Node 22 / macos-latest)",
48
- "Test (Node 22 / windows-latest)",
49
- "Test (Node 24 / ubuntu-latest)",
50
- "Test (Node 24 / macos-latest)",
51
- "Test (Node 24 / windows-latest)",
52
- "Security (secrets + injection scan)",
53
- "Size budget (blocking)"
54
- ]
55
- },
56
- "enforce_admins": false,
57
- "required_pull_request_reviews": null,
58
- "restrictions": null,
59
- "required_linear_history": true,
60
- "allow_force_pushes": false,
61
- "allow_deletions": false
62
- }
63
- JSON
64
- echo "Enforcing mode applied. CI must pass before merge; linear history required."
65
- ;;
66
- --disable)
67
- echo "Removing branch protection from $REPO main..."
68
- gh api -X DELETE "repos/${REPO}/branches/main/protection" || true
69
- echo "Protection removed."
70
- ;;
71
- *)
72
- echo "Usage: $0 --advisory | --enforcing | --disable"
73
- exit 1
74
- ;;
75
- esac