@hegemonart/get-design-done 1.30.6 → 1.31.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.
Files changed (175) hide show
  1. package/.claude-plugin/marketplace.json +6 -3
  2. package/.claude-plugin/plugin.json +5 -2
  3. package/CHANGELOG.md +105 -0
  4. package/NOTICE +224 -0
  5. package/README.md +22 -1
  6. package/SKILL.md +1 -0
  7. package/agents/design-authority-watcher.md +1 -1
  8. package/agents/perf-analyzer.md +2 -2
  9. package/bin/gdd-mcp +78 -0
  10. package/bin/gdd-sdk +34 -24
  11. package/bin/gdd-state-mcp +78 -0
  12. package/{README.de.md → docs/i18n/README.de.md} +1 -1
  13. package/{README.fr.md → docs/i18n/README.fr.md} +1 -1
  14. package/{README.it.md → docs/i18n/README.it.md} +1 -1
  15. package/{README.ja.md → docs/i18n/README.ja.md} +1 -1
  16. package/{README.ko.md → docs/i18n/README.ko.md} +1 -1
  17. package/{README.zh-CN.md → docs/i18n/README.zh-CN.md} +1 -1
  18. package/hooks/_hook-emit.js +1 -1
  19. package/hooks/budget-enforcer.ts +5 -5
  20. package/hooks/context-exhaustion.ts +2 -2
  21. package/hooks/gdd-precompact-snapshot.js +3 -3
  22. package/hooks/gdd-read-injection-scanner.ts +2 -2
  23. package/hooks/gdd-sessionstart-recap.js +1 -1
  24. package/hooks/gdd-turn-closeout.js +1 -1
  25. package/package.json +24 -10
  26. package/recipes/.gitkeep +0 -0
  27. package/reference/schemas/recipe.schema.json +33 -0
  28. package/scripts/cli/gdd-events.mjs +5 -5
  29. package/scripts/lib/cache/gdd-cache-manager.cjs +1 -1
  30. package/scripts/lib/cli/index.ts +22 -160
  31. package/scripts/lib/connection-probe/index.cjs +1 -1
  32. package/scripts/lib/discuss-parallel-runner/aggregator.ts +1 -1
  33. package/scripts/lib/discuss-parallel-runner/index.ts +1 -1
  34. package/scripts/lib/error-classifier.cjs +24 -227
  35. package/scripts/lib/event-stream/index.ts +25 -193
  36. package/scripts/lib/figma-extract/digest.cjs +430 -0
  37. package/scripts/lib/figma-extract/parse-url.cjs +87 -0
  38. package/scripts/lib/figma-extract/payload-schema.json +108 -0
  39. package/scripts/lib/figma-extract/pull.cjs +394 -0
  40. package/scripts/lib/figma-extract/receiver.cjs +273 -0
  41. package/scripts/lib/figma-extract/render-md.cjs +143 -0
  42. package/scripts/lib/figma-extract/styles-resolver.cjs +147 -0
  43. package/scripts/lib/figma-extract/walk.cjs +100 -0
  44. package/scripts/lib/gdd-errors/index.ts +24 -213
  45. package/scripts/lib/gdd-state/index.ts +23 -161
  46. package/scripts/lib/health-mirror/index.cjs +88 -1
  47. package/scripts/lib/iteration-budget.cjs +23 -199
  48. package/scripts/lib/jittered-backoff.cjs +24 -107
  49. package/scripts/lib/lockfile.cjs +23 -195
  50. package/scripts/lib/logger/index.ts +1 -1
  51. package/scripts/lib/parallelism-engine/concurrency-tuner.cjs +1 -1
  52. package/scripts/lib/perf-analyzer/index.cjs +1 -1
  53. package/scripts/lib/pipeline-runner/index.ts +4 -4
  54. package/scripts/lib/pipeline-runner/state-machine.ts +1 -1
  55. package/scripts/lib/prompt-dedup/index.cjs +1 -1
  56. package/scripts/lib/rate-guard.cjs +2 -2
  57. package/scripts/lib/recipe-loader.cjs +142 -0
  58. package/scripts/lib/session-runner/errors.ts +3 -3
  59. package/scripts/lib/session-runner/index.ts +3 -3
  60. package/scripts/lib/session-runner/transcript.ts +1 -1
  61. package/scripts/lib/tool-scoping/index.ts +1 -1
  62. package/scripts/mcp-servers/gdd-mcp/server.ts +29 -311
  63. package/scripts/mcp-servers/gdd-state/server.ts +28 -282
  64. package/sdk/README.md +45 -0
  65. package/{scripts/lib → sdk}/cli/commands/audit.ts +3 -3
  66. package/{scripts/lib → sdk}/cli/commands/init.ts +3 -3
  67. package/{scripts/lib → sdk}/cli/commands/query.ts +4 -4
  68. package/{scripts/lib → sdk}/cli/commands/run.ts +5 -5
  69. package/{scripts/lib → sdk}/cli/commands/stage.ts +5 -5
  70. package/sdk/cli/index.js +8091 -0
  71. package/sdk/cli/index.ts +172 -0
  72. package/{scripts/lib → sdk}/cli/parse-args.ts +2 -2
  73. package/{scripts/lib/gdd-errors → sdk/errors}/classification.ts +1 -1
  74. package/sdk/errors/index.ts +218 -0
  75. package/{scripts/lib → sdk}/event-stream/emitter.ts +1 -1
  76. package/sdk/event-stream/index.ts +197 -0
  77. package/{scripts/lib → sdk}/event-stream/reader.ts +1 -1
  78. package/{scripts/lib → sdk}/event-stream/types.ts +2 -2
  79. package/{scripts/lib → sdk}/event-stream/writer.ts +1 -1
  80. package/sdk/index.ts +19 -0
  81. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/README.md +3 -3
  82. package/sdk/mcp/gdd-mcp/server.js +1924 -0
  83. package/sdk/mcp/gdd-mcp/server.ts +325 -0
  84. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_cycle_recap.ts +3 -3
  85. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_decisions_list.ts +2 -2
  86. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_events_tail.ts +3 -3
  87. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_health.ts +2 -2
  88. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_intel_get.ts +2 -2
  89. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_learnings_digest.ts +2 -2
  90. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_phase_current.ts +2 -2
  91. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_phases_list.ts +2 -2
  92. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_plans_list.ts +2 -2
  93. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_reflections_latest.ts +2 -2
  94. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_status.ts +3 -3
  95. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_telemetry_query.ts +3 -3
  96. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/index.ts +2 -2
  97. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/shared.ts +3 -3
  98. package/sdk/mcp/gdd-state/server.js +2790 -0
  99. package/sdk/mcp/gdd-state/server.ts +294 -0
  100. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_blocker.ts +3 -3
  101. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_decision.ts +3 -3
  102. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_must_have.ts +3 -3
  103. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/checkpoint.ts +2 -2
  104. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/frontmatter_update.ts +2 -2
  105. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/get.ts +3 -3
  106. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/index.ts +1 -1
  107. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/probe_connections.ts +3 -3
  108. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/resolve_blocker.ts +3 -3
  109. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/set_status.ts +2 -2
  110. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/shared.ts +8 -8
  111. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/transition_stage.ts +4 -4
  112. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/update_progress.ts +2 -2
  113. package/sdk/primitives/error-classifier.cjs +232 -0
  114. package/sdk/primitives/iteration-budget.cjs +205 -0
  115. package/sdk/primitives/jittered-backoff.cjs +112 -0
  116. package/sdk/primitives/lockfile.cjs +201 -0
  117. package/{scripts/lib/gdd-state → sdk/state}/gates.ts +1 -1
  118. package/sdk/state/index.ts +167 -0
  119. package/{scripts/lib/gdd-state → sdk/state}/lockfile.ts +1 -1
  120. package/{scripts/lib/gdd-state → sdk/state}/mutator.ts +1 -1
  121. package/{scripts/lib/gdd-state → sdk/state}/parser.ts +1 -1
  122. package/{scripts/lib/gdd-state → sdk/state}/types.ts +4 -4
  123. package/skills/figma-extract/SKILL.md +64 -0
  124. package/skills/health/SKILL.md +10 -0
  125. package/skills/quality-gate/SKILL.md +2 -2
  126. package/scripts/aggregate-agent-metrics.ts +0 -282
  127. package/scripts/bootstrap-manifest.txt +0 -3
  128. package/scripts/bootstrap.sh +0 -80
  129. package/scripts/build-distribution-bundles.cjs +0 -549
  130. package/scripts/build-intel.cjs +0 -486
  131. package/scripts/codegen-schema-types.ts +0 -149
  132. package/scripts/detect-stale-refs.cjs +0 -107
  133. package/scripts/e2e/run-headless.ts +0 -514
  134. package/scripts/extract-changelog-section.cjs +0 -58
  135. package/scripts/gsd-cleanup-incubator.cjs +0 -367
  136. package/scripts/injection-patterns.cjs +0 -58
  137. package/scripts/lint-agentskills-spec.cjs +0 -457
  138. package/scripts/release-smoke-test.cjs +0 -200
  139. package/scripts/rollback-release.sh +0 -42
  140. package/scripts/run-injection-scanner-ci.cjs +0 -83
  141. package/scripts/tests/test-authority-rejected-kinds.sh +0 -58
  142. package/scripts/tests/test-authority-watcher-diff.sh +0 -113
  143. package/scripts/tests/test-motion-provenance.sh +0 -64
  144. package/scripts/validate-frontmatter.ts +0 -409
  145. package/scripts/validate-incubator-scope.cjs +0 -133
  146. package/scripts/validate-schemas.ts +0 -401
  147. package/scripts/validate-skill-length.cjs +0 -283
  148. package/scripts/verify-version-sync.cjs +0 -30
  149. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_cycle_recap.schema.json +0 -0
  150. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_decisions_list.schema.json +0 -0
  151. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_events_tail.schema.json +0 -0
  152. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_health.schema.json +0 -0
  153. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_intel_get.schema.json +0 -0
  154. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_learnings_digest.schema.json +0 -0
  155. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_phase_current.schema.json +0 -0
  156. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_phases_list.schema.json +0 -0
  157. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_plans_list.schema.json +0 -0
  158. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_reflections_latest.schema.json +0 -0
  159. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_status.schema.json +0 -0
  160. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_telemetry_query.schema.json +0 -0
  161. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_blocker.schema.json +0 -0
  162. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_decision.schema.json +0 -0
  163. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_must_have.schema.json +0 -0
  164. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/checkpoint.schema.json +0 -0
  165. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/frontmatter_update.schema.json +0 -0
  166. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/get.schema.json +0 -0
  167. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/probe_connections.schema.json +0 -0
  168. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/resolve_blocker.schema.json +0 -0
  169. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/set_status.schema.json +0 -0
  170. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/transition_stage.schema.json +0 -0
  171. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/update_progress.schema.json +0 -0
  172. /package/{scripts/lib → sdk/primitives}/error-classifier.d.cts +0 -0
  173. /package/{scripts/lib → sdk/primitives}/iteration-budget.d.cts +0 -0
  174. /package/{scripts/lib → sdk/primitives}/jittered-backoff.d.cts +0 -0
  175. /package/{scripts/lib → sdk/primitives}/lockfile.d.cts +0 -0
@@ -1,282 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * aggregate-agent-metrics.ts — Incremental per-agent aggregator.
4
- *
5
- * Reads: .design/telemetry/costs.jsonl (append-only ledger from
6
- * hooks/budget-enforcer.js)
7
- * agents/{agent}.md (frontmatter source for default-tier, parallel-safe,
8
- * reads-only, typical-duration-seconds)
9
- * Writes: .design/agent-metrics.json (atomic overwrite via tmp-file + rename)
10
- * .design/telemetry/phase-totals.json (same, WR-02)
11
- *
12
- * Invoked:
13
- * 1. Detached child of hooks/budget-enforcer.js after every telemetry write.
14
- * 2. Directly by /gdd:optimize skill as an explicit refresh step.
15
- * 3. Manually: `node --experimental-strip-types scripts/aggregate-agent-metrics.ts`
16
- * 4. With `--help` to print usage (used by the Plan 20-00 smoke check).
17
- *
18
- * OPT-09 contract: fields must match Phase 11 reflector's expectations.
19
- *
20
- * Converted from scripts/aggregate-agent-metrics.js in Plan 20-00 (Tier-1).
21
- * Behavior preserved verbatim.
22
- */
23
-
24
- import {
25
- existsSync,
26
- mkdirSync,
27
- readFileSync,
28
- writeFileSync,
29
- renameSync,
30
- } from 'node:fs';
31
- import { join, dirname, basename } from 'node:path';
32
-
33
- // Generated-type import (unused at runtime, erased by strip-types) to satisfy
34
- // Plan 20-00's requirement that every Tier-1 TS file participates in the
35
- // codegen graph. We pick AuthoritySnapshotSchema as a stable anchor and
36
- // re-export for downstream callers.
37
- import type { AuthoritySnapshotSchema } from '../reference/schemas/generated.js';
38
- export type { AuthoritySnapshotSchema };
39
-
40
- const CWD: string = process.cwd();
41
- const TELEMETRY_PATH: string = join(CWD, '.design', 'telemetry', 'costs.jsonl');
42
- const METRICS_PATH: string = join(CWD, '.design', 'agent-metrics.json');
43
- const PHASE_TOTALS_PATH: string = join(CWD, '.design', 'telemetry', 'phase-totals.json');
44
- const AGENTS_DIR: string = join(CWD, 'agents');
45
-
46
- /**
47
- * Subset of the agent-markdown frontmatter we care about. `null` means the
48
- * field is absent or unparseable (aggregator is tolerant — degraded mode
49
- * preferred over hard-fail per OPT-09).
50
- */
51
- interface AgentFrontmatter {
52
- default_tier: string | null;
53
- parallel_safe: boolean | null;
54
- reads_only: boolean | null;
55
- typical_duration_seconds: number | null;
56
- }
57
-
58
- /** ---- frontmatter reader (no YAML dep) ---- */
59
- function readAgentFrontmatter(agentName: string): Partial<AgentFrontmatter> {
60
- const p: string = join(AGENTS_DIR, `${agentName}.md`);
61
- if (!existsSync(p)) return {};
62
- try {
63
- const content: string = readFileSync(p, 'utf8');
64
- const fm = content.match(/^---\s*\n([\s\S]*?)\n---/);
65
- if (!fm) return {};
66
- const body: string = fm[1] ?? '';
67
- const get = (key: string): string | null => {
68
- const m = body.match(new RegExp(`^${key}:\\s*"?([^"\\n]+)"?`, 'm'));
69
- return m && m[1] !== undefined ? m[1].trim() : null;
70
- };
71
- const defaultTier: string | null = get('default-tier');
72
- const parallelSafe: string | null = get('parallel-safe');
73
- const readsOnly: string | null = get('reads-only');
74
- const typicalDuration: string | null = get('typical-duration-seconds');
75
- return {
76
- default_tier: defaultTier ?? null,
77
- parallel_safe: parallelSafe === null ? null : /^(true|yes)$/i.test(parallelSafe),
78
- reads_only: readsOnly === null ? null : /^(true|yes)$/i.test(readsOnly),
79
- typical_duration_seconds:
80
- typicalDuration === null ? null : Number(typicalDuration) || null,
81
- };
82
- } catch {
83
- return {};
84
- }
85
- }
86
-
87
- /**
88
- * Shape of a single row in .design/telemetry/costs.jsonl. Mirrors the OPT-09
89
- * schema: nine mandatory fields + four optional diagnostic fields. Unknown
90
- * keys are tolerated (Phase 11 reflector ignores them).
91
- */
92
- export interface CostRow {
93
- ts?: string;
94
- agent?: string;
95
- tier?: string;
96
- tokens_in?: number | string;
97
- tokens_out?: number | string;
98
- cache_hit?: boolean;
99
- est_cost_usd?: number | string;
100
- cycle?: string;
101
- phase?: string;
102
- // Optional / diagnostic
103
- tier_downgraded?: boolean;
104
- enforcement_mode?: string;
105
- lazy_skipped?: boolean;
106
- block_reason?: string;
107
- }
108
-
109
- /** ---- telemetry reader ---- */
110
- function readTelemetryRows(): CostRow[] {
111
- if (!existsSync(TELEMETRY_PATH)) return [];
112
- const raw: string = readFileSync(TELEMETRY_PATH, 'utf8');
113
- const out: CostRow[] = [];
114
- for (const line of raw.split(/\r?\n/)) {
115
- if (!line.trim()) continue;
116
- try {
117
- out.push(JSON.parse(line) as CostRow);
118
- } catch {
119
- // tolerant: skip malformed lines (partial write, truncation)
120
- }
121
- }
122
- return out;
123
- }
124
-
125
- /** Per-agent roll-up accumulator. */
126
- interface AgentAccumulator {
127
- total_spawns: number;
128
- total_cost_usd: number;
129
- total_tokens_in: number;
130
- total_tokens_out: number;
131
- cache_hits: number;
132
- lazy_skips: number;
133
- }
134
-
135
- /** Final per-agent shape written to .design/agent-metrics.json. */
136
- export interface AgentMetrics {
137
- typical_duration_seconds: number | null | undefined;
138
- default_tier: string | null | undefined;
139
- parallel_safe: boolean | null | undefined;
140
- reads_only: boolean | null | undefined;
141
- total_spawns: number;
142
- total_cost_usd: number;
143
- total_tokens_in: number;
144
- total_tokens_out: number;
145
- cache_hit_rate: number;
146
- lazy_skip_rate: number;
147
- }
148
-
149
- /** ---- aggregator ---- */
150
- function aggregate(rows: readonly CostRow[]): Record<string, AgentMetrics> {
151
- const byAgent = new Map<string, AgentAccumulator>();
152
- for (const r of rows) {
153
- // Blocked rows represent a spawn that was denied at the hook — the agent
154
- // never actually ran, so it must not contribute to spawn counts, cost, or
155
- // token totals. Skip them here (mirror of the filter in aggregateByPhase).
156
- if (r.block_reason) continue;
157
- const agent: string = r.agent ?? 'unknown';
158
- let a = byAgent.get(agent);
159
- if (!a) {
160
- a = {
161
- total_spawns: 0,
162
- total_cost_usd: 0,
163
- total_tokens_in: 0,
164
- total_tokens_out: 0,
165
- cache_hits: 0,
166
- lazy_skips: 0,
167
- };
168
- byAgent.set(agent, a);
169
- }
170
- a.total_spawns += 1;
171
- a.total_cost_usd += Number(r.est_cost_usd ?? 0);
172
- a.total_tokens_in += Number(r.tokens_in ?? 0);
173
- a.total_tokens_out += Number(r.tokens_out ?? 0);
174
- if (r.cache_hit === true) a.cache_hits += 1;
175
- if (r.lazy_skipped === true) a.lazy_skips += 1;
176
- }
177
-
178
- const out: Record<string, AgentMetrics> = {};
179
- for (const [agent, a] of byAgent.entries()) {
180
- const fm = readAgentFrontmatter(agent);
181
- const spawns: number = a.total_spawns || 1; // guard div-by-zero
182
- out[agent] = {
183
- typical_duration_seconds: fm.typical_duration_seconds,
184
- default_tier: fm.default_tier,
185
- parallel_safe: fm.parallel_safe,
186
- reads_only: fm.reads_only,
187
- total_spawns: a.total_spawns,
188
- total_cost_usd: Number(a.total_cost_usd.toFixed(6)),
189
- total_tokens_in: a.total_tokens_in,
190
- total_tokens_out: a.total_tokens_out,
191
- cache_hit_rate: Number((a.cache_hits / spawns).toFixed(4)),
192
- lazy_skip_rate: Number((a.lazy_skips / spawns).toFixed(4)),
193
- };
194
- }
195
- return out;
196
- }
197
-
198
- /** ---- atomic write ---- */
199
- function writeAtomic(filePath: string, content: string): void {
200
- const dir: string = dirname(filePath);
201
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
202
- const tmp: string = join(
203
- dir,
204
- `.${basename(filePath)}.${process.pid}.${Date.now()}.tmp`,
205
- );
206
- writeFileSync(tmp, content, 'utf8');
207
- renameSync(tmp, filePath);
208
- }
209
-
210
- /** ---- phase totals aggregator (WR-02: avoids full JSONL replay in budget enforcer) ---- */
211
- function aggregateByPhase(rows: readonly CostRow[]): Record<string, number> {
212
- const byPhase: Record<string, number> = {};
213
- for (const r of rows) {
214
- // Blocked rows represent spawns that were denied by the hook — the agent
215
- // never ran, so their est_cost_usd must not inflate cumulative phase spend.
216
- // Counting them would make future hard-block and soft-threshold checks
217
- // stricter than intended on every repeat cap hit.
218
- if (r.block_reason) continue;
219
- const phase: string = r.phase ?? 'unknown';
220
- byPhase[phase] = (byPhase[phase] ?? 0) + Number(r.est_cost_usd ?? 0);
221
- }
222
- // Round to 6dp to match per-agent precision
223
- for (const k of Object.keys(byPhase)) {
224
- const v: number = byPhase[k] ?? 0;
225
- byPhase[k] = Number(v.toFixed(6));
226
- }
227
- return byPhase;
228
- }
229
-
230
- /** ---- usage / --help ---- */
231
- function printHelp(): void {
232
- console.log(
233
- `aggregate-agent-metrics.ts — Aggregate per-agent telemetry from .design/telemetry/costs.jsonl.\n` +
234
- `\n` +
235
- `Usage:\n` +
236
- ` node --experimental-strip-types scripts/aggregate-agent-metrics.ts\n` +
237
- ` node --experimental-strip-types scripts/aggregate-agent-metrics.ts --help\n` +
238
- `\n` +
239
- `Reads: .design/telemetry/costs.jsonl\n` +
240
- ` agents/<agent>.md (frontmatter)\n` +
241
- `Writes: .design/agent-metrics.json\n` +
242
- ` .design/telemetry/phase-totals.json\n` +
243
- `\n` +
244
- `Invoked:\n` +
245
- ` - Detached child of hooks/budget-enforcer.js after every telemetry row.\n` +
246
- ` - Directly by /gdd:optimize as an explicit refresh step.\n` +
247
- ` - Manually, on demand.\n`,
248
- );
249
- }
250
-
251
- /** ---- main ---- */
252
- function main(): void {
253
- if (process.argv.includes('--help') || process.argv.includes('-h')) {
254
- printHelp();
255
- process.exit(0);
256
- }
257
-
258
- const rows: CostRow[] = readTelemetryRows();
259
- const agents = aggregate(rows);
260
- const payload = {
261
- generated_at: new Date().toISOString(),
262
- agents,
263
- };
264
- writeAtomic(METRICS_PATH, JSON.stringify(payload, null, 2) + '\n');
265
- // Write lightweight phase-totals.json so budget-enforcer can read phase
266
- // spend in O(1) without replaying the full JSONL on every agent spawn
267
- // (WR-02).
268
- const phaseTotals = {
269
- generated_at: new Date().toISOString(),
270
- totals: aggregateByPhase(rows),
271
- };
272
- writeAtomic(PHASE_TOTALS_PATH, JSON.stringify(phaseTotals, null, 2) + '\n');
273
- }
274
-
275
- try {
276
- main();
277
- } catch (err) {
278
- // Fail open: aggregator must never block the hook or /gdd:optimize flow.
279
- const msg: string = err instanceof Error ? err.message : String(err);
280
- process.stderr.write(`aggregate-agent-metrics: ${msg}\n`);
281
- process.exit(0);
282
- }
@@ -1,3 +0,0 @@
1
- get-design-done-bootstrap
2
- v1
3
- awesome-design-md@VoltAgent
@@ -1,80 +0,0 @@
1
- #!/usr/bin/env bash
2
- # get-design-done bootstrap
3
- # Auto-provisions companion resources that get-design-done references but which
4
- # are not Claude Code plugins (so they cannot be listed in `dependencies`).
5
- #
6
- # Runs on SessionStart. Idempotent: uses a marker in ${CLAUDE_PLUGIN_DATA} so it
7
- # only performs network work on first install or when the bundled manifest changes.
8
- #
9
- # Resources provisioned:
10
- # - ~/.claude/libs/awesome-design-md (VoltAgent/awesome-design-md)
11
- #
12
- # Resources NOT provisioned (install separately, see README):
13
- # - emil-design-eng skill — no canonical upstream
14
- # - refero MCP — optional, add to your Claude config if you have access
15
-
16
- set -u
17
-
18
- PLUGIN_DATA="${CLAUDE_PLUGIN_DATA:-$HOME/.claude/plugins/data/get-design-done}"
19
- PLUGIN_DATA="${PLUGIN_DATA//\\//}" # Normalize Windows backslashes to forward slashes
20
- PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
21
- PLUGIN_ROOT="${PLUGIN_ROOT//\\//}" # Normalize Windows backslashes to forward slashes
22
- MANIFEST="${PLUGIN_ROOT}/scripts/bootstrap-manifest.txt"
23
- MARKER="${PLUGIN_DATA}/bootstrap-manifest.txt"
24
-
25
- mkdir -p "${PLUGIN_DATA}" "${HOME}/.claude/libs" "${HOME}/.claude/skills"
26
-
27
- # Skip if bundled manifest matches the last-run marker (no-op on every other session).
28
- if [[ -f "${MANIFEST}" && -f "${MARKER}" ]] && diff -q "${MANIFEST}" "${MARKER}" >/dev/null 2>&1; then
29
- exit 0
30
- fi
31
-
32
- log() { printf '[get-design-done bootstrap] %s\n' "$*" >&2; }
33
-
34
- clone_or_update() {
35
- local repo_url="$1"
36
- local target="$2"
37
- if [[ -d "${target}/.git" ]]; then
38
- log "updating ${target}"
39
- git -C "${target}" pull --quiet --ff-only 2>/dev/null || log "pull failed for ${target} (continuing)"
40
- elif [[ -d "${target}" ]]; then
41
- log "${target} exists and is not a git checkout — skipping"
42
- else
43
- log "cloning ${repo_url} -> ${target}"
44
- git clone --quiet --depth 1 "${repo_url}" "${target}" || log "clone failed for ${repo_url}"
45
- fi
46
- }
47
-
48
- # Required library: awesome-design-md
49
- clone_or_update "https://github.com/VoltAgent/awesome-design-md.git" "${HOME}/.claude/libs/awesome-design-md"
50
-
51
- # Soft notice for companion skills we cannot auto-install.
52
- if [[ ! -d "${HOME}/.claude/skills/emil-design-eng" ]]; then
53
- log "optional: emil-design-eng skill not found in ~/.claude/skills. See get-design-done README for install options."
54
- fi
55
-
56
- # Phase 10.1: ensure .design/budget.json exists with defaults (D-12)
57
- DESIGN_DIR="$(pwd)/.design"
58
- mkdir -p "${DESIGN_DIR}"
59
- if [ ! -f "${DESIGN_DIR}/budget.json" ]; then
60
- cat > "${DESIGN_DIR}/budget.json" <<'BUDGET_EOF'
61
- {
62
- "per_task_cap_usd": 2.00,
63
- "per_phase_cap_usd": 20.00,
64
- "tier_overrides": {},
65
- "auto_downgrade_on_cap": true,
66
- "cache_ttl_seconds": 3600,
67
- "enforcement_mode": "enforce"
68
- }
69
- BUDGET_EOF
70
- fi
71
-
72
- # Phase 10.1: ensure .design/telemetry/ directory is writable
73
- mkdir -p "${DESIGN_DIR}/telemetry"
74
-
75
- # Record success so we don't re-run until the bundled manifest changes.
76
- if [[ -f "${MANIFEST}" ]]; then
77
- cp "${MANIFEST}" "${MARKER}"
78
- fi
79
-
80
- exit 0