@hegemonart/get-design-done 1.23.0 → 1.24.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 +97 -0
- package/README.md +36 -7
- package/package.json +2 -1
- package/scripts/install.cjs +164 -116
- package/scripts/lib/adaptive-mode.cjs +170 -0
- package/scripts/lib/bandit-router.cjs +368 -0
- package/scripts/lib/hedge-ensemble.cjs +217 -0
- package/scripts/lib/install/config-dir.cjs +55 -0
- package/scripts/lib/install/installer.cjs +244 -0
- package/scripts/lib/install/interactive.cjs +142 -0
- package/scripts/lib/install/merge.cjs +103 -0
- package/scripts/lib/install/runtimes.cjs +172 -0
- package/scripts/lib/mmr-rerank.cjs +154 -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.24.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.24.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.24.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.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "hegemonart",
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,103 @@ All notable changes to get-design-done are documented here. Versions follow [sem
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [1.24.0] — 2026-04-25
|
|
8
|
+
|
|
9
|
+
Phase 24 Multi-Runtime Installer milestone — `npx @hegemonart/get-design-done` with no flags now launches a polished interactive install session (`@clack/prompts`) that walks the user through a multi-select of all 14 supported AI coding runtimes plus a Global/Local radio. Scripted / CI installs continue to work via the existing flag surface unchanged. Strict superset over v1.23.5: any non-zero invocation still works exactly as before.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Per-runtime install matrix** — `scripts/lib/install/runtimes.cjs` exports a 14-entry frozen list. Each entry: `{id, displayName, configDirEnv, configDirFallback, kind, files, marketplaceEntry?}`. Two install kinds are supported: `claude-marketplace` (registers an `extraKnownMarketplaces` entry + flips `enabledPlugins[<plugin>@<marketplace>]`, today only Claude Code) and `agents-md` (drops a runtime-specific instructions file in the runtime's config dir, used by the other 13). Adding a new runtime is one append to this file + one append to `test-fixture/baselines/phase-24/runtimes.txt`. (Plan 24-01)
|
|
14
|
+
|
|
15
|
+
- **14 runtimes scoped** — Claude Code, OpenCode, Gemini CLI, Kilo Code, OpenAI Codex CLI, GitHub Copilot CLI, Cursor, Windsurf, Antigravity, Augment, Trae, Qwen Code, CodeBuddy, Cline. Gemini drops `GEMINI.md`; the other 12 `agents-md` runtimes drop `AGENTS.md`. (Plan 24-01)
|
|
16
|
+
|
|
17
|
+
- **Config-dir lookup chain** — `scripts/lib/install/config-dir.cjs` exposes `resolveConfigDir(runtimeId, opts)` and `resolveAllConfigDirs(opts)`. Precedence: explicit `--config-dir` flag > per-runtime env var (`CLAUDE_CONFIG_DIR`, `OPENCODE_CONFIG_DIR`, `GEMINI_CONFIG_DIR`, `CODEX_HOME`, `CURSOR_CONFIG_DIR`, …) > POSIX/Windows fallback at `$HOME/$USERPROFILE` joined with the runtime's `configDirFallback`. Mirrors GSD `install.js`'s lookup pattern. (Plan 24-01)
|
|
18
|
+
|
|
19
|
+
- **Settings merge / unmerge primitives** — `scripts/lib/install/merge.cjs` exports pure `mergeClaudeSettings(existing, marketplaceEntry) → {next, changed}` and `removeClaudeSettings(existing, marketplaceEntry) → {next, changed}`. Both are idempotent and preserve unrelated user keys. `buildAgentsFileContent(runtime)` produces the runtime-tagged AGENTS.md/GEMINI.md payload with a `<!-- get-design-done plugin instructions -->` fingerprint. `isPluginOwned(content)` is the inverse used by uninstall + foreign-file detection. (Plan 24-02)
|
|
20
|
+
|
|
21
|
+
- **Per-runtime install/uninstall orchestrator** — `scripts/lib/install/installer.cjs` exports `installRuntime(runtimeId, opts)` and `uninstallRuntime(runtimeId, opts)`, both returning a structured `Result = {runtime, path, action: 'created'|'updated'|'unchanged'|'removed'|'skipped-foreign', dryRun, reason?}`. Atomic writes (`.tmp-<pid>` + rename) throughout. Foreign AGENTS.md/GEMINI.md files (no plugin fingerprint) are never clobbered — install reports `skipped-foreign` with a remediation hint. `detectInstalled(opts)` scans every runtime's config dir and returns the IDs that have a plugin-owned install. (Plan 24-02)
|
|
22
|
+
|
|
23
|
+
- **`@clack/prompts` interactive session** — `scripts/lib/install/interactive.cjs` exports `runInteractiveInstall()` (3 steps: multi-select runtimes → Global/Local radio → confirmation) and `runInteractiveUninstall(opts)` (2 steps: multi-select detected-installed → confirmation). ESC at any step returns `null` so the entrypoint exits 0 with a "cancelled" message — no partial writes. `@clack/prompts ^0.7.0` added as a runtime dependency (~8KB). (Plan 24-03)
|
|
24
|
+
|
|
25
|
+
- **Multi-runtime entrypoint** — `scripts/install.cjs` rewritten as a router. Decision tree: zero flags + TTY → interactive multi-select; zero flags + non-TTY (CI, pipes) → defaults to `--claude --global` for backwards compatibility with v1.23.5; any explicit per-runtime flag (or `--all`) → scripted, no prompts. `--uninstall` with no runtime list also enters interactive mode and only shows runtimes detected as installed. Per-runtime summary printed at the end with per-runtime path + action. (Plan 24-04)
|
|
26
|
+
|
|
27
|
+
- **Existing flag surface preserved 1:1** — `--claude`, `--opencode`, `--gemini`, `--kilo`, `--codex`, `--copilot`, `--cursor`, `--windsurf`, `--antigravity`, `--augment`, `--trae`, `--qwen`, `--codebuddy`, `--cline`, `--all`, `--global`, `--local`, `--uninstall`, `--config-dir <path>`, `--dry-run`, `--help`, `-h`. Existing CI installs (`CLAUDE_CONFIG_DIR=/tmp npx @hegemonart/get-design-done`) continue to work with no source changes. (Plan 24-04)
|
|
28
|
+
|
|
29
|
+
- **Idempotent + foreign-safe install** — re-running install over an already-installed runtime emits `unchanged` with the v1.23.5 "already registered" message preserved. AGENTS.md / GEMINI.md files NOT authored by this plugin are detected via missing fingerprint and never overwritten or deleted by uninstall. (Plan 24-02)
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- `tests/semver-compare.test.cjs` `OFF_CADENCE_VERSIONS` gains `1.24.0`.
|
|
34
|
+
- `scripts/install.cjs` — full rewrite. The original v1.23.5 single-runtime marketplace registration logic is now extracted into `scripts/lib/install/merge.cjs` (`mergeClaudeSettings` / `removeClaudeSettings`) and reused by the new orchestrator.
|
|
35
|
+
|
|
36
|
+
### Tests
|
|
37
|
+
|
|
38
|
+
- `tests/install-runtimes.test.cjs` — 14-entry shape, kind/file mapping per runtime, baseline-file alignment, ID uniqueness, unknown-runtime throws (10 tests).
|
|
39
|
+
- `tests/install-config-dir.test.cjs` — env override, explicit override, fallback resolution, empty env-var fallthrough, all-runtimes resolution (8).
|
|
40
|
+
- `tests/install-merge.test.cjs` — merge/remove idempotency + key preservation, fingerprint helpers, full install→idempotent→uninstall round-trips for both kinds, foreign-file refusal + missing-target uninstall (15).
|
|
41
|
+
- `tests/phase-24-baseline.test.cjs` — 3-manifest version alignment at 1.24.0, `@clack/prompts` registration, surface-export contract per module, runtimes.txt baseline match, install.cjs rewrite anchor (8).
|
|
42
|
+
- All 7 existing `tests/install-script.test.cjs` end-to-end spawn tests pass against the rewritten entrypoint.
|
|
43
|
+
|
|
44
|
+
Total: 41 new tests. All Phase 20/21/22/23/23.5 tests still green.
|
|
45
|
+
|
|
46
|
+
### Deferred
|
|
47
|
+
|
|
48
|
+
- Stdin-simulation integration tests for the interactive flow itself (requires a PTY shim; manual smoke-test on Windows CMD / PowerShell / Windows Terminal covers v1).
|
|
49
|
+
- Auto-detection of installed runtimes during the install flow (multi-select with all 14 visible is sufficient for v1; uninstall flow already filters to detected-installed via `detectInstalled`).
|
|
50
|
+
- Per-runtime MCP server registration writes — each runtime's MCP entry format differs and the install matrix records the format but does not generate the entries.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## [1.23.5] — 2026-04-25
|
|
55
|
+
|
|
56
|
+
Phase 23.5 No-Regret Adaptive Layer milestone — turns the passive Phase 22–23 observability + validation infrastructure into a closed self-tuning loop. Three tightly-scoped no-regret algorithms sharing one feature-flag ladder. Single-user viable via informed Beta-prior bootstrap (no shared telemetry required). Ships as a decimal patch on the v1.23 minor — does NOT shift Phase 24 → v1.24.0.
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- **Bandit router** — `scripts/lib/bandit-router.cjs` implements contextual Thompson sampling over `(agent_type, touches_size_bin) → {haiku, sonnet, opus}`. Per-arm `Beta(α, β)` posterior at `.design/telemetry/posterior.json` (atomic .tmp + rename). Discounted Thompson via per-arm time-decay factor `ρ^days_since_last_use` applied at sample time (default ρ=0.988 → 60-day half-life). Informed bootstrap: each arm starts at `Beta(α, β)` with α weighted toward the historical tier success rate (haiku=0.6, sonnet=0.8, opus=0.85) and `α + β ≈ 10` so 5–10 local samples shift the posterior. Two-stage lexicographic reward: `if !solidify_pass: 0; elif user_undo_in_session: 0; else: 1 − λ · normalize(cost + ε · wall_time)`. API: `pull / update / reset / loadPosterior / savePosterior / computeReward`. Touches-size bins: `tiny <5`, `small 5–15`, `medium 16–50`, `large >50` globs. (Plan 23.5-01)
|
|
61
|
+
|
|
62
|
+
- **Hedge ensemble** — `scripts/lib/hedge-ensemble.cjs` implements parameter-free AdaNormalHedge weighted-majority over verifier + checker agents. Weights persist at `.design/telemetry/hedge-weights.json`. Update rule: `η_i = sqrt(ln(N) / max(1, cumLoss2_i))` per-agent learning rate; `w_i *= exp(-η_i * loss_i)`; renormalise. Vote semantics: weighted sum normalised by the SUM of voting agents' weights — agents in the pool that didn't vote this round don't dilute the verdict. API: `loss / vote / weights / loadWeights / saveWeights`. Default vote threshold 0.5. (Plan 23.5-02)
|
|
63
|
+
|
|
64
|
+
- **MMR re-rank** — `scripts/lib/mmr-rerank.cjs` implements Maximal Marginal Relevance over scored items. Solves the "all 5 surfaced learnings are about the same thing" failure mode in the Phase 14.5 decision-injector. Greedy criterion: `next = argmax_{i ∉ selected} λ * relevance(i) − (1 − λ) * max_sim(i, selected)`. Similarity = Jaccard on word n-grams (default n=2). λ default 0.7. No external deps, no embedding API. API: `rerank / similarity / tokenize / ngrams / jaccard`. (Plan 23.5-03)
|
|
65
|
+
|
|
66
|
+
- **Adaptive-mode feature flag ladder** — `scripts/lib/adaptive-mode.cjs` is the single source of truth for which Phase 23.5 components are active. Three modes:
|
|
67
|
+
- `static` (DEFAULT) — Phase 10.1 behaviour. Static `tier_overrides` applies. No posterior writes / no hedge updates / no MMR.
|
|
68
|
+
- `hedge` — Adds AdaNormalHedge consensus + MMR re-rank. Routing still static (bandit OFF). Safest intro level.
|
|
69
|
+
- `full` — Adds bandit Thompson-sampling routing + reflector confidence-interval proposals. Both posterior + hedge persist.
|
|
70
|
+
Read from `.design/budget.json.adaptive_mode` with safe fallback to `static` on missing/malformed/unknown values. API: `getMode / setMode / caps / isBanditEnabled / isHedgeEnabled / isMmrEnabled / isReflectorProposalsEnabled`. (Plan 23.5-04)
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
|
|
74
|
+
- `tests/semver-compare.test.cjs` `OFF_CADENCE_VERSIONS` gains `1.23.5`.
|
|
75
|
+
- `test-fixture/baselines/phase-20/resilience-primitives.txt` regenerated alphabetically with all four new `.cjs` modules added.
|
|
76
|
+
|
|
77
|
+
### Tests
|
|
78
|
+
|
|
79
|
+
- `tests/bandit-router.test.cjs` — bin partitioning, prior elevation per tier, beta sampling, pull persistence, missing-input throws, update/reward/clamp, reset, decay-toward-prior, all reward branches, load+save, 60-round convergence smoke test (18 tests)
|
|
80
|
+
- `tests/hedge-ensemble.test.cjs` — init uniform, high-loss penalty, normalisation, simple vs weighted vote, boolean=numeric equivalence, custom threshold, empty votes, loss clamp, NaN throw, round-trip (14)
|
|
81
|
+
- `tests/mmr-rerank.test.cjs` — tokenize edges, ngram size+fallback, similarity properties, λ=1 pure relevance, λ=0 pure diversity, textOf/relevanceOf overrides, empty input, non-array throw, k>length truncation, defaults, jaccard guards, canonical "5 D-13 hits" scenario (18)
|
|
82
|
+
- `tests/adaptive-mode.test.cjs` — missing-file fallback, malformed-JSON fallback, unknown-mode quiet fallback, all 3 capability matrices, all 4 predicates, setMode preserves other fields, parent-dir creation, mode rejection, exports, absolute-path support (13)
|
|
83
|
+
- `tests/phase-23.5-baseline.test.cjs` — Phase 23.5 regression baseline (8)
|
|
84
|
+
|
|
85
|
+
Total: 71 new tests. All Phase 20/21/22/23 tests still green.
|
|
86
|
+
|
|
87
|
+
### Reflector integration
|
|
88
|
+
|
|
89
|
+
The Phase 22 code-level reflector reads `posterior.json` + hedge weights at run time (under `adaptive_mode: "full"`). When `stddev(Beta(α, β)) < 0.05` for a single-arm dominant tier, it proposes `tier_overrides` updates via `/gdd:apply-reflections`. Pure-read; never auto-writes. Same proposal pattern as Plan 23-06 touches pattern miner.
|
|
90
|
+
|
|
91
|
+
### Deferred (evidence-gated, per ROADMAP)
|
|
92
|
+
|
|
93
|
+
- Hierarchical shared prior (revisit after 20+ cycles of single-user convergence data)
|
|
94
|
+
- Dense-embedding retrieval (revisit if MMR-only miss-rate exceeds 15%)
|
|
95
|
+
- Offline policy evaluation harness (bootstraps from bandit's stochastic logs once accumulated)
|
|
96
|
+
- Auto changepoint detection (manual `/gdd:bandit-reset --reason "<msg>"` covers v1)
|
|
97
|
+
|
|
98
|
+
### Explicitly out of scope
|
|
99
|
+
|
|
100
|
+
- HDBSCAN auto-crystallization, BOCPD changepoint detection, Personalized PageRank, MinHash/LSH dedup, Borda/Kemeny rank aggregation, submodular greedy — each rejected with rationale in ROADMAP.md.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
7
104
|
## [1.23.0] — 2026-04-25
|
|
8
105
|
|
|
9
106
|
Phase 23 GDD SDK Domain Primitives milestone — lands the highest-leverage code primitives from the ROADMAP "GDD SDK Domain Primitives" entry as typed Node modules with tests. 10 atomic plans (23-01 through 23-10), additive — every Phase 20/21/22 consumer keeps working unchanged. Distribution as separate `@hegemonart/gdd-sdk` npm package and screenshot-capture orchestration are explicitly deferred to follow-up phases.
|
package/README.md
CHANGED
|
@@ -104,7 +104,11 @@ Built-in quality gates catch real problems: Handoff Faithfulness scoring on Clau
|
|
|
104
104
|
- **Component generators** — 21st.dev Magic MCP adds a prior-art gate before any greenfield build; Magic Patterns generates DS-aware components with a `preview_url` for visual verification. Both feed into a shared `design-component-generator` agent.
|
|
105
105
|
- **Twelve tool connections** — Four new connections (paper.design, pencil.dev, 21st.dev, Magic Patterns) join the original eight. All are optional; the pipeline degrades gracefully to fallbacks when any connection is unavailable.
|
|
106
106
|
|
|
107
|
-
## What's New in v1.
|
|
107
|
+
## What's New in v1.24.0
|
|
108
|
+
|
|
109
|
+
**Multi-runtime installer** (headline upgrade) — `npx @hegemonart/get-design-done` with no flags now opens a polished interactive multi-select (`@clack/prompts`) for all 14 supported AI coding runtimes — Claude Code, OpenCode, Gemini CLI, Kilo Code, OpenAI Codex CLI, GitHub Copilot CLI, Cursor, Windsurf, Antigravity, Augment, Trae, Qwen Code, CodeBuddy, Cline. Pick any subset, choose Global or Local, confirm, done. Idempotent + foreign-AGENTS.md-safe. Scripted CI installs continue to work via the existing flag surface unchanged. See the [Getting Started](#getting-started) section below.
|
|
110
|
+
|
|
111
|
+
### Previously in v1.21.0
|
|
108
112
|
|
|
109
113
|
**Headless SDK** (headline upgrade) — the plugin now ships a `gdd-sdk` CLI that runs the full design pipeline without Claude Code. Five subcommands (`run`, `stage`, `query`, `audit`, `init`) work on any CI runner with Node 22+ and an `ANTHROPIC_API_KEY`. See the [Headless SDK](#headless-sdk) section below for examples.
|
|
110
114
|
|
|
@@ -134,14 +138,22 @@ Built-in quality gates catch real problems: Handoff Faithfulness scoring on Clau
|
|
|
134
138
|
npx @hegemonart/get-design-done@latest
|
|
135
139
|
```
|
|
136
140
|
|
|
137
|
-
|
|
141
|
+
In a TTY this opens a polished interactive multi-select (`@clack/prompts`) — pick which AI runtimes to install into and whether to install Globally or Locally. Press `[a]` to select all 14 supported runtimes at once. In non-TTY contexts (CI, pipes), the same command falls back to `--claude --global` for full backwards compatibility with v1.23.5 and earlier.
|
|
142
|
+
|
|
143
|
+
After install, restart the affected runtime(s) (or run `/reload-plugins` for Claude Code) and the pipeline is live.
|
|
144
|
+
|
|
145
|
+
**Supported runtimes** *(v1.24.0+)*
|
|
146
|
+
|
|
147
|
+
Claude Code, OpenCode, Gemini CLI, Kilo Code, OpenAI Codex CLI, GitHub Copilot CLI, Cursor, Windsurf, Antigravity, Augment, Trae, Qwen Code, CodeBuddy, Cline.
|
|
148
|
+
|
|
149
|
+
Claude Code uses marketplace registration (`extraKnownMarketplaces` + `enabledPlugins` in `settings.json`); the other 13 runtimes follow the AGENTS.md / GEMINI.md convention — the installer drops a fingerprinted instructions file in the runtime's config dir (and refuses to overwrite an existing AGENTS.md it didn't author).
|
|
138
150
|
|
|
139
151
|
**What the installer does**
|
|
140
152
|
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
- Preserves every other key in your settings — theme, permissions, other marketplaces — untouched
|
|
144
|
-
- Idempotent: safe to re-run; no duplicate entries
|
|
153
|
+
- For Claude Code: registers the `github:hegemonart/get-design-done` marketplace in `extraKnownMarketplaces` and flips `enabledPlugins["get-design-done@get-design-done"]` to `true`.
|
|
154
|
+
- For AGENTS.md runtimes: drops a fingerprinted `AGENTS.md` (or `GEMINI.md`) in the runtime's config dir.
|
|
155
|
+
- Preserves every other key in your settings — theme, permissions, other marketplaces — untouched.
|
|
156
|
+
- Idempotent: safe to re-run; no duplicate entries; foreign AGENTS.md files are never overwritten.
|
|
145
157
|
|
|
146
158
|
On first Claude Code launch after install, a `SessionStart` bootstrap hook provisions the companion reference library `~/.claude/libs/awesome-design-md` (idempotent — subsequent sessions run `git pull --ff-only`).
|
|
147
159
|
|
|
@@ -158,13 +170,30 @@ A one-line SessionStart nudge surfaces `/gdd:start` in fresh repos; run `/gdd:st
|
|
|
158
170
|
### Non-interactive install (CI, Docker, scripts)
|
|
159
171
|
|
|
160
172
|
```bash
|
|
161
|
-
# Dry-run: print the diff, don't write
|
|
173
|
+
# Dry-run: print the diff, don't write (Claude Code only by default)
|
|
162
174
|
npx @hegemonart/get-design-done@latest --dry-run
|
|
163
175
|
|
|
164
176
|
# Custom config dir (Docker, non-default Claude root)
|
|
165
177
|
CLAUDE_CONFIG_DIR=/workspace/.claude npx @hegemonart/get-design-done@latest
|
|
178
|
+
|
|
179
|
+
# Pick specific runtimes (any flag → scripted, no prompts)
|
|
180
|
+
npx @hegemonart/get-design-done@latest --claude --opencode --gemini
|
|
181
|
+
|
|
182
|
+
# Install into every supported runtime
|
|
183
|
+
npx @hegemonart/get-design-done@latest --all
|
|
184
|
+
|
|
185
|
+
# Local install (drops files into the current working directory)
|
|
186
|
+
npx @hegemonart/get-design-done@latest --opencode --local
|
|
187
|
+
|
|
188
|
+
# Uninstall — bare flag enters interactive multi-select of detected runtimes
|
|
189
|
+
npx @hegemonart/get-design-done@latest --uninstall
|
|
190
|
+
|
|
191
|
+
# Uninstall scripted (no prompt)
|
|
192
|
+
npx @hegemonart/get-design-done@latest --uninstall --claude --gemini
|
|
166
193
|
```
|
|
167
194
|
|
|
195
|
+
Per-runtime env-var overrides: `CLAUDE_CONFIG_DIR`, `OPENCODE_CONFIG_DIR`, `GEMINI_CONFIG_DIR`, `CODEX_HOME`, `CURSOR_CONFIG_DIR`, `KILO_CONFIG_DIR`, `COPILOT_CONFIG_DIR`, `WINDSURF_CONFIG_DIR`, `ANTIGRAVITY_CONFIG_DIR`, `AUGMENT_CONFIG_DIR`, `TRAE_CONFIG_DIR`, `QWEN_CONFIG_DIR`, `CODEBUDDY_CONFIG_DIR`, `CLINE_CONFIG_DIR`. Each falls back to `$HOME / $USERPROFILE` joined with the runtime's default subdirectory (e.g. `~/.claude`, `~/.gemini`, `~/.config/opencode`).
|
|
196
|
+
|
|
168
197
|
### Alternative: Claude Code CLI
|
|
169
198
|
|
|
170
199
|
Prefer to skip the npm package entirely? Use the native plugin CLI:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hegemonart/get-design-done",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
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",
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"hooks": "hooks/hooks.json",
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"@anthropic-ai/claude-agent-sdk": "^0.2.119",
|
|
87
|
+
"@clack/prompts": "^0.7.0",
|
|
87
88
|
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
88
89
|
},
|
|
89
90
|
"optionalDependencies": {
|
package/scripts/install.cjs
CHANGED
|
@@ -2,153 +2,201 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
// npx @hegemonart/get-design-done
|
|
5
|
-
//
|
|
5
|
+
// Multi-runtime installer for the get-design-done plugin.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// Runtime selection:
|
|
8
|
+
// • zero-flag in TTY → @clack/prompts interactive multi-select
|
|
9
|
+
// • zero-flag in non-TTY → defaults to --claude --global (back-compat)
|
|
10
|
+
// • any explicit flag → scripted, no prompts
|
|
10
11
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
''
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
' CLAUDE_CONFIG_DIR Override the Claude config directory',
|
|
41
|
-
' (default: ~/.claude)',
|
|
42
|
-
'',
|
|
43
|
-
'After install, restart Claude Code to load the plugin.',
|
|
44
|
-
'',
|
|
45
|
-
].join('\n'),
|
|
46
|
-
);
|
|
47
|
-
process.exit(0);
|
|
12
|
+
// Per-runtime flags: --claude, --opencode, --gemini, --kilo, --codex,
|
|
13
|
+
// --copilot, --cursor, --windsurf, --antigravity, --augment, --trae,
|
|
14
|
+
// --qwen, --codebuddy, --cline. --all selects every runtime.
|
|
15
|
+
//
|
|
16
|
+
// Modifiers: --global (default) | --local; --uninstall; --dry-run;
|
|
17
|
+
// --config-dir <path>; --help / -h.
|
|
18
|
+
|
|
19
|
+
const path = require('node:path');
|
|
20
|
+
|
|
21
|
+
const { listRuntimes, listRuntimeIds } = require('./lib/install/runtimes.cjs');
|
|
22
|
+
const { installRuntime, uninstallRuntime } = require('./lib/install/installer.cjs');
|
|
23
|
+
|
|
24
|
+
function parseArgs(argv) {
|
|
25
|
+
const args = argv.slice(2);
|
|
26
|
+
const flags = new Set();
|
|
27
|
+
let configDir = null;
|
|
28
|
+
for (let i = 0; i < args.length; i++) {
|
|
29
|
+
const a = args[i];
|
|
30
|
+
if (a === '--config-dir') {
|
|
31
|
+
configDir = args[++i] || null;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (a.startsWith('--config-dir=')) {
|
|
35
|
+
configDir = a.slice('--config-dir='.length);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
flags.add(a);
|
|
39
|
+
}
|
|
40
|
+
return { flags, configDir };
|
|
48
41
|
}
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
function helpText() {
|
|
44
|
+
const ids = listRuntimes()
|
|
45
|
+
.map((r) => ` --${r.id.padEnd(12)} ${r.displayName}`)
|
|
46
|
+
.join('\n');
|
|
47
|
+
return [
|
|
48
|
+
'npx @hegemonart/get-design-done — install the plugin into one or more runtimes',
|
|
49
|
+
'',
|
|
50
|
+
'Zero-flag in a TTY launches the interactive multi-select.',
|
|
51
|
+
'Zero-flag in a non-TTY (CI, pipes) defaults to --claude --global.',
|
|
52
|
+
'',
|
|
53
|
+
'Per-runtime flags:',
|
|
54
|
+
ids,
|
|
55
|
+
' --all Select every runtime',
|
|
56
|
+
'',
|
|
57
|
+
'Modifiers:',
|
|
58
|
+
' --global Install at $HOME / $USERPROFILE level (default)',
|
|
59
|
+
' --local Install in current working directory',
|
|
60
|
+
' --uninstall Remove the plugin from selected runtimes',
|
|
61
|
+
' --dry-run Print the diff without writing',
|
|
62
|
+
' --config-dir D Override the config directory',
|
|
63
|
+
' --help, -h Show this message',
|
|
64
|
+
'',
|
|
65
|
+
'Environment overrides (per-runtime):',
|
|
66
|
+
' CLAUDE_CONFIG_DIR, OPENCODE_CONFIG_DIR, GEMINI_CONFIG_DIR,',
|
|
67
|
+
' CODEX_HOME, CURSOR_CONFIG_DIR, … (one per runtime)',
|
|
68
|
+
'',
|
|
69
|
+
].join('\n');
|
|
70
|
+
}
|
|
51
71
|
|
|
52
|
-
function
|
|
53
|
-
if (
|
|
54
|
-
|
|
72
|
+
function runtimesFromFlags(flags) {
|
|
73
|
+
if (flags.has('--all')) return listRuntimeIds();
|
|
74
|
+
const picked = [];
|
|
75
|
+
for (const id of listRuntimeIds()) {
|
|
76
|
+
if (flags.has(`--${id}`)) picked.push(id);
|
|
55
77
|
}
|
|
56
|
-
return
|
|
78
|
+
return picked;
|
|
57
79
|
}
|
|
58
80
|
|
|
59
|
-
function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (!raw.trim()) return {};
|
|
64
|
-
return JSON.parse(raw);
|
|
65
|
-
} catch (err) {
|
|
66
|
-
process.stderr.write(
|
|
67
|
-
`get-design-done installer: cannot parse ${settingsPath} as JSON\n` +
|
|
68
|
-
` ${err.message}\n` +
|
|
69
|
-
` Fix the file manually or delete it, then re-run.\n`,
|
|
70
|
-
);
|
|
71
|
-
process.exit(1);
|
|
81
|
+
async function pickRuntimesInteractively(opts) {
|
|
82
|
+
const { runInteractiveInstall, runInteractiveUninstall } = require('./lib/install/interactive.cjs');
|
|
83
|
+
if (opts.uninstall) {
|
|
84
|
+
return runInteractiveUninstall(opts);
|
|
72
85
|
}
|
|
86
|
+
return runInteractiveInstall();
|
|
73
87
|
}
|
|
74
88
|
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const marketplaces = { ...(next.extraKnownMarketplaces || {}) };
|
|
79
|
-
const marketplaceEntry = {
|
|
80
|
-
source: { source: 'github', repo: REPO },
|
|
81
|
-
};
|
|
82
|
-
const marketplaceChanged =
|
|
83
|
-
JSON.stringify(marketplaces[MARKETPLACE_NAME]) !==
|
|
84
|
-
JSON.stringify(marketplaceEntry);
|
|
85
|
-
marketplaces[MARKETPLACE_NAME] = marketplaceEntry;
|
|
86
|
-
next.extraKnownMarketplaces = marketplaces;
|
|
87
|
-
|
|
88
|
-
const enabled = { ...(next.enabledPlugins || {}) };
|
|
89
|
-
const enabledChanged = enabled[ENABLED_KEY] !== true;
|
|
90
|
-
enabled[ENABLED_KEY] = true;
|
|
91
|
-
next.enabledPlugins = enabled;
|
|
92
|
-
|
|
93
|
-
return { next, changed: marketplaceChanged || enabledChanged };
|
|
89
|
+
function resolveLocalConfigDir(runtime) {
|
|
90
|
+
return path.resolve(process.cwd(), runtime.configDirFallback);
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
function shouldUseInteractive(flags) {
|
|
94
|
+
// Any of these flags means "scripted mode":
|
|
95
|
+
// per-runtime, --all, --uninstall (with explicit list), --help
|
|
96
|
+
if (flags.has('--all')) return false;
|
|
97
|
+
for (const id of listRuntimeIds()) {
|
|
98
|
+
if (flags.has(`--${id}`)) return false;
|
|
99
|
+
}
|
|
100
|
+
// Bare --uninstall (no runtime list) is itself a trigger for interactive
|
|
101
|
+
// select-which-to-remove flow, so it returns true.
|
|
102
|
+
return Boolean(process.stdout.isTTY) && Boolean(process.stdin.isTTY);
|
|
100
103
|
}
|
|
101
104
|
|
|
102
|
-
function
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
+
function summariseResults(results) {
|
|
106
|
+
const lines = [];
|
|
107
|
+
for (const r of results) {
|
|
108
|
+
const tag = r.dryRun ? '[dry-run] ' : '';
|
|
109
|
+
const status = r.action;
|
|
110
|
+
lines.push(`${tag}• ${r.runtime.padEnd(12)} ${status.padEnd(16)} ${r.path}`);
|
|
111
|
+
if (r.reason) lines.push(` ${r.reason}`);
|
|
112
|
+
}
|
|
113
|
+
return lines.join('\n');
|
|
114
|
+
}
|
|
105
115
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
async function main() {
|
|
117
|
+
const { flags, configDir } = parseArgs(process.argv);
|
|
118
|
+
|
|
119
|
+
if (flags.has('--help') || flags.has('-h')) {
|
|
120
|
+
process.stdout.write(helpText());
|
|
121
|
+
process.exit(0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const dryRun = flags.has('--dry-run');
|
|
125
|
+
const uninstall = flags.has('--uninstall');
|
|
126
|
+
const local = flags.has('--local');
|
|
127
|
+
const explicitRuntimes = runtimesFromFlags(flags);
|
|
128
|
+
|
|
129
|
+
let runtimes = explicitRuntimes;
|
|
130
|
+
let location = local ? 'local' : 'global';
|
|
131
|
+
|
|
132
|
+
if (runtimes.length === 0) {
|
|
133
|
+
if (shouldUseInteractive(flags)) {
|
|
134
|
+
const opts = { uninstall };
|
|
135
|
+
const picked = await pickRuntimesInteractively(opts);
|
|
136
|
+
if (picked == null) {
|
|
137
|
+
process.exit(0);
|
|
138
|
+
}
|
|
139
|
+
runtimes = picked.runtimes;
|
|
140
|
+
if (picked.location) location = picked.location;
|
|
111
141
|
} else {
|
|
112
|
-
|
|
142
|
+
// Non-TTY zero-flag fallback: back-compat with v1.23.5 behaviour.
|
|
143
|
+
runtimes = ['claude'];
|
|
144
|
+
location = local ? 'local' : 'global';
|
|
113
145
|
}
|
|
114
146
|
}
|
|
115
147
|
|
|
116
|
-
const
|
|
117
|
-
const {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
148
|
+
const results = [];
|
|
149
|
+
const { getRuntime } = require('./lib/install/runtimes.cjs');
|
|
150
|
+
for (const id of runtimes) {
|
|
151
|
+
const runtime = getRuntime(id);
|
|
152
|
+
const opts = { dryRun };
|
|
153
|
+
if (configDir) {
|
|
154
|
+
opts.configDir = configDir;
|
|
155
|
+
} else if (location === 'local') {
|
|
156
|
+
opts.configDir = resolveLocalConfigDir(runtime);
|
|
157
|
+
}
|
|
158
|
+
const result = uninstall
|
|
159
|
+
? uninstallRuntime(id, opts)
|
|
160
|
+
: installRuntime(id, opts);
|
|
161
|
+
results.push(result);
|
|
126
162
|
}
|
|
127
163
|
|
|
128
|
-
|
|
164
|
+
const verb = uninstall ? 'uninstall' : 'install';
|
|
165
|
+
const allUnchanged = results.length > 0 && results.every((r) => r.action === 'unchanged');
|
|
166
|
+
if (allUnchanged && !dryRun) {
|
|
129
167
|
process.stdout.write(
|
|
130
|
-
|
|
131
|
-
`
|
|
132
|
-
|
|
168
|
+
[
|
|
169
|
+
`get-design-done is already registered (${runtimes.length} runtime(s) unchanged):`,
|
|
170
|
+
summariseResults(results),
|
|
171
|
+
'',
|
|
172
|
+
'Nothing to do. Restart the affected runtime(s) if you have not yet.',
|
|
173
|
+
'',
|
|
174
|
+
].join('\n'),
|
|
133
175
|
);
|
|
134
176
|
return;
|
|
135
177
|
}
|
|
136
|
-
|
|
137
|
-
atomicWrite(settingsPath, formatted);
|
|
138
|
-
|
|
139
178
|
process.stdout.write(
|
|
140
179
|
[
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
180
|
+
dryRun
|
|
181
|
+
? `[dry-run] would ${verb} into ${runtimes.length} runtime(s):`
|
|
182
|
+
: `${verb} complete (${runtimes.length} runtime(s)):`,
|
|
183
|
+
summariseResults(results),
|
|
144
184
|
'',
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
' 3. Verify with: /plugin list',
|
|
185
|
+
uninstall
|
|
186
|
+
? ''
|
|
187
|
+
: 'Restart the affected runtime(s) for the plugin to load.',
|
|
149
188
|
'',
|
|
150
189
|
].join('\n'),
|
|
151
190
|
);
|
|
152
191
|
}
|
|
153
192
|
|
|
154
|
-
main()
|
|
193
|
+
main().catch((err) => {
|
|
194
|
+
if (err && err.code === 'EINSTALLER_BAD_JSON') {
|
|
195
|
+
process.stderr.write(`${err.message}\n`);
|
|
196
|
+
} else {
|
|
197
|
+
process.stderr.write(
|
|
198
|
+
`get-design-done installer error: ${err && err.stack ? err.stack : err}\n`,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
process.exit(1);
|
|
202
|
+
});
|