@hegemonart/get-design-done 1.59.2 → 1.59.4
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 +56 -0
- package/SKILL.md +2 -0
- package/agents/design-advisor.md +1 -1
- package/agents/design-context-checker-gate.md +0 -1
- package/agents/design-context-checker.md +0 -1
- package/agents/design-context-reviewer-gate.md +0 -1
- package/agents/design-context-reviewer.md +0 -1
- package/agents/design-integration-checker-gate.md +0 -1
- package/agents/design-integration-checker.md +0 -1
- package/agents/design-plan-checker.md +0 -1
- package/agents/design-verifier-gate.md +0 -1
- package/agents/design-verifier.md +0 -1
- package/agents/prototype-gate.md +0 -1
- package/agents/quality-gate-runner.md +0 -1
- package/figma-plugin/README.md +61 -0
- package/figma-plugin/code.ts +36 -0
- package/figma-plugin/manifest.json +12 -0
- package/figma-plugin/package-lock.json +35 -0
- package/figma-plugin/package.json +12 -0
- package/figma-plugin/src/export-variables.ts +144 -0
- package/figma-plugin/src/payload-schema.ts +250 -0
- package/figma-plugin/tsconfig.json +16 -0
- package/figma-plugin/ui.html +44 -0
- package/hooks/gdd-intel-trigger.js +3 -3
- package/package.json +6 -1
- package/reference/DEPRECATIONS.md +3 -3
- package/reference/live-mode-integration.md +1 -1
- package/reference/registry.json +1 -1
- package/reference/skill-metadata.md +4 -4
- package/reference/skill-placeholders.md +2 -2
- package/scripts/build-skills.cjs +146 -0
- package/scripts/generate-skill-frontmatter.cjs +243 -0
- package/scripts/lib/manifest/scaffolder.cjs +1 -1
- package/scripts/lib/manifest/schemas/skills.schema.json +1 -1
- package/scripts/lib/manifest/skills.json +1 -1
- package/scripts/lib/new-addendum.cjs +1 -1
- package/scripts/skill-templates/README.md +90 -0
- package/scripts/skill-templates/add-backlog/SKILL.md +48 -0
- package/scripts/skill-templates/analyze-dependencies/SKILL.md +95 -0
- package/scripts/skill-templates/apply-reflections/SKILL.md +109 -0
- package/scripts/skill-templates/apply-reflections/apply-reflections-procedure.md +170 -0
- package/scripts/skill-templates/audit/SKILL.md +79 -0
- package/scripts/skill-templates/bandit-reset/SKILL.md +91 -0
- package/scripts/skill-templates/bandit-status/SKILL.md +94 -0
- package/scripts/skill-templates/benchmark/SKILL.md +65 -0
- package/scripts/skill-templates/bootstrap-ds/SKILL.md +43 -0
- package/scripts/skill-templates/brief/SKILL.md +145 -0
- package/scripts/skill-templates/budget/SKILL.md +45 -0
- package/scripts/skill-templates/cache-manager/SKILL.md +66 -0
- package/scripts/skill-templates/cache-manager/cache-policy.md +126 -0
- package/scripts/skill-templates/check-update/SKILL.md +98 -0
- package/scripts/skill-templates/compare/SKILL.md +82 -0
- package/scripts/skill-templates/compare/compare-rubric.md +171 -0
- package/scripts/skill-templates/complete-cycle/SKILL.md +81 -0
- package/scripts/skill-templates/connections/SKILL.md +71 -0
- package/scripts/skill-templates/connections/connections-onboarding.md +608 -0
- package/scripts/skill-templates/context/SKILL.md +137 -0
- package/scripts/skill-templates/continue/SKILL.md +24 -0
- package/scripts/skill-templates/darkmode/SKILL.md +76 -0
- package/scripts/skill-templates/darkmode/darkmode-audit-procedure.md +258 -0
- package/scripts/skill-templates/debug/SKILL.md +41 -0
- package/scripts/skill-templates/debug/debug-feedback-loops.md +119 -0
- package/scripts/skill-templates/design/SKILL.md +118 -0
- package/scripts/skill-templates/design/design-procedure.md +304 -0
- package/scripts/skill-templates/discuss/SKILL.md +96 -0
- package/scripts/skill-templates/do/SKILL.md +45 -0
- package/scripts/skill-templates/explore/SKILL.md +118 -0
- package/scripts/skill-templates/explore/explore-procedure.md +267 -0
- package/scripts/skill-templates/export/SKILL.md +30 -0
- package/scripts/skill-templates/extract-learnings/SKILL.md +114 -0
- package/scripts/skill-templates/fast/SKILL.md +91 -0
- package/scripts/skill-templates/figma-extract/SKILL.md +64 -0
- package/scripts/skill-templates/figma-write/SKILL.md +50 -0
- package/scripts/skill-templates/graphify/SKILL.md +49 -0
- package/scripts/skill-templates/health/SKILL.md +99 -0
- package/scripts/skill-templates/health/health-mcp-detection.md +44 -0
- package/scripts/skill-templates/health/health-skill-length-report.md +69 -0
- package/scripts/skill-templates/help/SKILL.md +60 -0
- package/scripts/skill-templates/instinct/SKILL.md +111 -0
- package/scripts/skill-templates/list-assumptions/SKILL.md +61 -0
- package/scripts/skill-templates/list-pins/SKILL.md +27 -0
- package/scripts/skill-templates/live/SKILL.md +98 -0
- package/scripts/skill-templates/locale/SKILL.md +51 -0
- package/scripts/skill-templates/map/SKILL.md +89 -0
- package/scripts/skill-templates/migrate/SKILL.md +70 -0
- package/scripts/skill-templates/migrate-context/SKILL.md +123 -0
- package/scripts/skill-templates/new-addendum/SKILL.md +81 -0
- package/scripts/skill-templates/new-cycle/SKILL.md +37 -0
- package/scripts/skill-templates/new-project/SKILL.md +53 -0
- package/scripts/skill-templates/new-skill/SKILL.md +90 -0
- package/scripts/skill-templates/next/SKILL.md +68 -0
- package/scripts/skill-templates/note/SKILL.md +48 -0
- package/scripts/skill-templates/openrouter-status/SKILL.md +86 -0
- package/scripts/skill-templates/optimize/SKILL.md +97 -0
- package/scripts/skill-templates/override/SKILL.md +86 -0
- package/scripts/skill-templates/paper-write/SKILL.md +54 -0
- package/scripts/skill-templates/pause/SKILL.md +77 -0
- package/scripts/skill-templates/peer-cli-add/SKILL.md +88 -0
- package/scripts/skill-templates/peer-cli-add/peer-cli-protocol.md +161 -0
- package/scripts/skill-templates/peer-cli-customize/SKILL.md +89 -0
- package/scripts/skill-templates/peers/SKILL.md +96 -0
- package/scripts/skill-templates/pencil-write/SKILL.md +54 -0
- package/scripts/skill-templates/pin/SKILL.md +37 -0
- package/scripts/skill-templates/plan/SKILL.md +105 -0
- package/scripts/skill-templates/plan/plan-procedure.md +278 -0
- package/scripts/skill-templates/plant-seed/SKILL.md +48 -0
- package/scripts/skill-templates/pr-branch/SKILL.md +32 -0
- package/scripts/skill-templates/progress/SKILL.md +107 -0
- package/scripts/skill-templates/quality-gate/SKILL.md +90 -0
- package/scripts/skill-templates/quality-gate/threat-modeling.md +101 -0
- package/scripts/skill-templates/quick/SKILL.md +44 -0
- package/scripts/skill-templates/reapply-patches/SKILL.md +32 -0
- package/scripts/skill-templates/recall/SKILL.md +75 -0
- package/scripts/skill-templates/reflect/SKILL.md +85 -0
- package/scripts/skill-templates/reflect/procedures/capability-gap-scan.md +119 -0
- package/scripts/skill-templates/report-issue/SKILL.md +53 -0
- package/scripts/skill-templates/report-issue/report-issue-procedure.md +119 -0
- package/scripts/skill-templates/resume/SKILL.md +93 -0
- package/scripts/skill-templates/review-backlog/SKILL.md +46 -0
- package/scripts/skill-templates/review-decisions/SKILL.md +42 -0
- package/scripts/skill-templates/roi/SKILL.md +54 -0
- package/scripts/skill-templates/rollout-status/SKILL.md +35 -0
- package/scripts/skill-templates/router/SKILL.md +89 -0
- package/scripts/skill-templates/router/capability-gap-emitter.md +65 -0
- package/scripts/skill-templates/router/router-pick-emitter.md +78 -0
- package/scripts/skill-templates/router/router-rules.md +84 -0
- package/scripts/skill-templates/settings/SKILL.md +87 -0
- package/scripts/skill-templates/ship/SKILL.md +48 -0
- package/scripts/skill-templates/sketch/SKILL.md +78 -0
- package/scripts/skill-templates/sketch-wrap-up/SKILL.md +92 -0
- package/scripts/skill-templates/skill-manifest/SKILL.md +79 -0
- package/scripts/skill-templates/spike/SKILL.md +67 -0
- package/scripts/skill-templates/spike-wrap-up/SKILL.md +86 -0
- package/scripts/skill-templates/start/SKILL.md +67 -0
- package/scripts/skill-templates/start/start-procedure.md +115 -0
- package/scripts/skill-templates/state/SKILL.md +106 -0
- package/scripts/skill-templates/stats/SKILL.md +51 -0
- package/scripts/skill-templates/style/SKILL.md +71 -0
- package/scripts/skill-templates/style/style-doc-procedure.md +150 -0
- package/scripts/skill-templates/synthesize/SKILL.md +94 -0
- package/scripts/skill-templates/timeline/SKILL.md +66 -0
- package/scripts/skill-templates/todo/SKILL.md +64 -0
- package/scripts/skill-templates/turn-closeout/SKILL.md +95 -0
- package/scripts/skill-templates/undo/SKILL.md +31 -0
- package/scripts/skill-templates/unlock-decision/SKILL.md +54 -0
- package/scripts/skill-templates/unpin/SKILL.md +31 -0
- package/scripts/skill-templates/update/SKILL.md +56 -0
- package/scripts/skill-templates/using-gdd/SKILL.md +78 -0
- package/scripts/skill-templates/verify/SKILL.md +113 -0
- package/scripts/skill-templates/verify/verify-procedure.md +511 -0
- package/scripts/skill-templates/warm-cache/SKILL.md +81 -0
- package/scripts/skill-templates/watch-authorities/SKILL.md +82 -0
- package/scripts/skill-templates/zoom-out/SKILL.md +26 -0
- package/sdk/cli/commands/build.ts +2 -2
- package/sdk/cli/index.js +2 -2
- package/sdk/cli/index.ts +1 -1
- package/skills/README.md +22 -14
- package/skills/help/SKILL.md +28 -55
- package/skills/new-skill/SKILL.md +5 -5
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
// figma-plugin/src/payload-schema.ts — Plan 31-05 (Wave B.2)
|
|
2
|
+
//
|
|
3
|
+
// Single plugin-side definition of the GDD Sync payload: the TS mirror of
|
|
4
|
+
// scripts/lib/figma-extract/payload-schema.json (31-06), the shared Path C
|
|
5
|
+
// contract (D-04, D-13). code.ts + export-variables.ts import the payload type
|
|
6
|
+
// from here; buildPayload below is the PURE, network-free core the offline test
|
|
7
|
+
// drives against a figma.variables mock.
|
|
8
|
+
//
|
|
9
|
+
// Two consumers, one payload (the make-or-break interop requirement):
|
|
10
|
+
// 1. Receiver (31-06) validates source + collections[] + variables[] against
|
|
11
|
+
// payload-schema.json before writing variables.json.
|
|
12
|
+
// 2. The digest's normalizePluginPayload (31-02) reads a FLAT tokens[] array
|
|
13
|
+
// (preferred) or payload.meta.* — it does NOT read top-level variables[].
|
|
14
|
+
// So the payload ALSO carries tokens[] (colors->hex, aliases->{name}, modes
|
|
15
|
+
// keyed by mode NAME) so plugin variables surface in DESIGN.md.
|
|
16
|
+
// additionalProperties:true permits the extra tokens[]. One object, both ends.
|
|
17
|
+
//
|
|
18
|
+
// D-13: ALL local variables are emitted — no published-only filter here; the
|
|
19
|
+
// digest filters.
|
|
20
|
+
|
|
21
|
+
/** Figma colour: 0..1 floats. `a` optional (RGB vs RGBA). */
|
|
22
|
+
export interface GddRgba {
|
|
23
|
+
r: number;
|
|
24
|
+
g: number;
|
|
25
|
+
b: number;
|
|
26
|
+
a?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Alias marker — kept resolvable: target id always, target name when looked up. */
|
|
30
|
+
export interface GddVariableAlias {
|
|
31
|
+
type: 'VARIABLE_ALIAS';
|
|
32
|
+
id: string;
|
|
33
|
+
name?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** A per-mode value in the receiver-facing variables[] (raw, unrendered). */
|
|
37
|
+
export type GddVariableValue =
|
|
38
|
+
| number
|
|
39
|
+
| string
|
|
40
|
+
| boolean
|
|
41
|
+
| GddRgba
|
|
42
|
+
| GddVariableAlias;
|
|
43
|
+
|
|
44
|
+
// ── Receiver-facing shapes (validated against payload-schema.json) ────────────
|
|
45
|
+
|
|
46
|
+
export interface GddSyncMode {
|
|
47
|
+
modeId: string;
|
|
48
|
+
name: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface GddSyncCollection {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
modes: GddSyncMode[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface GddSyncVariable {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
/** COLOR | FLOAT | STRING | BOOLEAN (schema enum). */
|
|
61
|
+
resolvedType: string;
|
|
62
|
+
collectionId: string;
|
|
63
|
+
/** Keyed by modeId. Raw value or alias marker (digest renders later). */
|
|
64
|
+
valuesByMode: Record<string, GddVariableValue>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ── Digest-interop shape: the FLAT tokens[] normalizePluginPayload reads ───────
|
|
68
|
+
// Matches digest.cjs extractTokensFromVariables() output so DESIGN.md is
|
|
69
|
+
// identical across paths: { name, type, collection, modes:{ <modeName>: rendered } }
|
|
70
|
+
// where rendered = hex for colours, `{targetName}` for aliases, primitive otherwise.
|
|
71
|
+
|
|
72
|
+
export interface GddSyncToken {
|
|
73
|
+
name: string;
|
|
74
|
+
type: string;
|
|
75
|
+
/** Collection NAME (not id) — matches digest Path A. */
|
|
76
|
+
collection?: string;
|
|
77
|
+
/** Keyed by mode NAME → rendered value. */
|
|
78
|
+
modes: Record<string, unknown>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface GddSyncPayload {
|
|
82
|
+
/** Path C marker the digest/receiver key on. Literal — never anything else. */
|
|
83
|
+
source: 'gdd-plugin';
|
|
84
|
+
fileKey?: string;
|
|
85
|
+
exportedAt?: string;
|
|
86
|
+
collections: GddSyncCollection[];
|
|
87
|
+
/** ALL local variables, raw values (D-13). */
|
|
88
|
+
variables: GddSyncVariable[];
|
|
89
|
+
/** Flat rendered tokens the digest consumes (variables[] is ignored there). */
|
|
90
|
+
tokens: GddSyncToken[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ── Pure value rendering (shared by the flat tokens[] builder) ────────────────
|
|
94
|
+
|
|
95
|
+
function isRgba(v: unknown): v is GddRgba {
|
|
96
|
+
return (
|
|
97
|
+
typeof v === 'object' &&
|
|
98
|
+
v !== null &&
|
|
99
|
+
typeof (v as GddRgba).r === 'number' &&
|
|
100
|
+
typeof (v as GddRgba).g === 'number' &&
|
|
101
|
+
typeof (v as GddRgba).b === 'number'
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function isAlias(v: unknown): v is GddVariableAlias {
|
|
106
|
+
return (
|
|
107
|
+
typeof v === 'object' &&
|
|
108
|
+
v !== null &&
|
|
109
|
+
(v as GddVariableAlias).type === 'VARIABLE_ALIAS' &&
|
|
110
|
+
typeof (v as GddVariableAlias).id === 'string'
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Render Figma {r,g,b,a?} (0..1) to hex — mirrors digest.cjs rgbToHex. */
|
|
115
|
+
export function rgbToHex({ r, g, b, a }: GddRgba): string {
|
|
116
|
+
const to = (v: number): string =>
|
|
117
|
+
Math.round(v * 255)
|
|
118
|
+
.toString(16)
|
|
119
|
+
.padStart(2, '0');
|
|
120
|
+
const hex = `#${to(r)}${to(g)}${to(b)}`;
|
|
121
|
+
return a !== undefined && a < 1 ? `${hex}${to(a)}` : hex;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** colour→hex, alias→`{targetName}` (or `{id}`), else primitive passthrough. */
|
|
125
|
+
export function renderTokenValue(raw: GddVariableValue): unknown {
|
|
126
|
+
if (isRgba(raw)) return rgbToHex(raw);
|
|
127
|
+
if (isAlias(raw)) return `{${raw.name || raw.id}}`;
|
|
128
|
+
return raw;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ── The single pure builder (network-free; the testable core) ─────────────────
|
|
132
|
+
|
|
133
|
+
/** Minimal collection shape buildPayload needs (mirrors VariableCollection). */
|
|
134
|
+
export interface RawCollectionLike {
|
|
135
|
+
id: string;
|
|
136
|
+
name: string;
|
|
137
|
+
modes: ReadonlyArray<{ modeId: string; name: string }>;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Minimal variable shape buildPayload needs (mirrors Variable). */
|
|
141
|
+
export interface RawVariableLike {
|
|
142
|
+
id: string;
|
|
143
|
+
name: string;
|
|
144
|
+
resolvedType: string;
|
|
145
|
+
variableCollectionId: string;
|
|
146
|
+
valuesByMode: Record<string, GddVariableValue>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Resolve a variable id → name (Figma's getVariableById(...)?.name). */
|
|
150
|
+
export type VariableNameResolver = (id: string) => string | undefined;
|
|
151
|
+
|
|
152
|
+
export interface BuildPayloadOptions {
|
|
153
|
+
fileKey?: string;
|
|
154
|
+
exportedAt?: string;
|
|
155
|
+
resolveName?: VariableNameResolver;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Build a GddSyncPayload from raw collections + variables. PURE: no Figma
|
|
160
|
+
* globals, no network. Emits ALL variables passed in (D-13). Produces BOTH the
|
|
161
|
+
* receiver-facing variables[] (raw values, alias markers retained with resolved
|
|
162
|
+
* name) AND the flat rendered tokens[] the digest consumes.
|
|
163
|
+
*/
|
|
164
|
+
export function buildPayload(
|
|
165
|
+
rawCollections: ReadonlyArray<RawCollectionLike>,
|
|
166
|
+
rawVariables: ReadonlyArray<RawVariableLike>,
|
|
167
|
+
opts: BuildPayloadOptions = {}
|
|
168
|
+
): GddSyncPayload {
|
|
169
|
+
const resolveName: VariableNameResolver = opts.resolveName || (() => undefined);
|
|
170
|
+
|
|
171
|
+
const collections: GddSyncCollection[] = rawCollections.map((c) => ({
|
|
172
|
+
id: c.id,
|
|
173
|
+
name: c.name,
|
|
174
|
+
modes: c.modes.map((m) => ({ modeId: m.modeId, name: m.name })),
|
|
175
|
+
}));
|
|
176
|
+
const collectionById = new Map<string, GddSyncCollection>(
|
|
177
|
+
collections.map((c) => [c.id, c])
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const variables: GddSyncVariable[] = [];
|
|
181
|
+
const tokens: GddSyncToken[] = [];
|
|
182
|
+
|
|
183
|
+
for (const v of rawVariables) {
|
|
184
|
+
// Receiver-facing valuesByMode: raw values, but resolve alias targets to a
|
|
185
|
+
// name (keep id + type) so it stays auditable. Keyed by modeId (schema).
|
|
186
|
+
const rawValuesByMode: Record<string, GddVariableValue> = {};
|
|
187
|
+
for (const modeId of Object.keys(v.valuesByMode)) {
|
|
188
|
+
const value = v.valuesByMode[modeId];
|
|
189
|
+
rawValuesByMode[modeId] = isAlias(value)
|
|
190
|
+
? { type: 'VARIABLE_ALIAS', id: value.id, name: resolveName(value.id) }
|
|
191
|
+
: value;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
variables.push({
|
|
195
|
+
id: v.id,
|
|
196
|
+
name: v.name,
|
|
197
|
+
resolvedType: v.resolvedType,
|
|
198
|
+
collectionId: v.variableCollectionId,
|
|
199
|
+
valuesByMode: rawValuesByMode,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Flat token for the digest: rendered values keyed by mode NAME so a
|
|
203
|
+
// multi-mode (light/dark) variable round-trips.
|
|
204
|
+
const collection = collectionById.get(v.variableCollectionId);
|
|
205
|
+
const modesByName: Record<string, unknown> = {};
|
|
206
|
+
const modeList = collection ? collection.modes : [];
|
|
207
|
+
if (modeList.length > 0) {
|
|
208
|
+
for (const mode of modeList) {
|
|
209
|
+
const raw = rawValuesByMode[mode.modeId];
|
|
210
|
+
if (raw !== undefined) modesByName[mode.name] = renderTokenValue(raw);
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
// No collection metadata — fall back to modeId so nothing is dropped.
|
|
214
|
+
for (const modeId of Object.keys(rawValuesByMode)) {
|
|
215
|
+
modesByName[modeId] = renderTokenValue(rawValuesByMode[modeId]);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
tokens.push({
|
|
220
|
+
name: v.name,
|
|
221
|
+
type: v.resolvedType,
|
|
222
|
+
collection: collection ? collection.name : undefined,
|
|
223
|
+
modes: modesByName,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const payload: GddSyncPayload = {
|
|
228
|
+
source: 'gdd-plugin',
|
|
229
|
+
collections,
|
|
230
|
+
variables,
|
|
231
|
+
tokens,
|
|
232
|
+
};
|
|
233
|
+
if (opts.fileKey) payload.fileKey = opts.fileKey;
|
|
234
|
+
if (opts.exportedAt) payload.exportedAt = opts.exportedAt;
|
|
235
|
+
return payload;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Narrow an unknown to GddSyncPayload: the literal source marker + the two
|
|
240
|
+
* required arrays. Cheap structural check (the receiver validates fully).
|
|
241
|
+
*/
|
|
242
|
+
export function isGddSyncPayload(x: unknown): x is GddSyncPayload {
|
|
243
|
+
if (typeof x !== 'object' || x === null) return false;
|
|
244
|
+
const p = x as Partial<GddSyncPayload>;
|
|
245
|
+
return (
|
|
246
|
+
p.source === 'gdd-plugin' &&
|
|
247
|
+
Array.isArray(p.collections) &&
|
|
248
|
+
Array.isArray(p.variables)
|
|
249
|
+
);
|
|
250
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"module": "amd",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"lib": ["ES2017"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"outFile": "code.js",
|
|
9
|
+
"noEmitOnError": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"typeRoots": ["./node_modules/@types", "./node_modules/@figma"]
|
|
14
|
+
},
|
|
15
|
+
"include": ["code.ts", "src/**/*.ts"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<style>
|
|
6
|
+
body {
|
|
7
|
+
font-family: Inter, system-ui, sans-serif;
|
|
8
|
+
margin: 0;
|
|
9
|
+
padding: 16px;
|
|
10
|
+
font-size: 12px;
|
|
11
|
+
color: #1a1a1a;
|
|
12
|
+
}
|
|
13
|
+
button {
|
|
14
|
+
width: 100%;
|
|
15
|
+
padding: 10px;
|
|
16
|
+
font-size: 13px;
|
|
17
|
+
font-weight: 600;
|
|
18
|
+
color: #fff;
|
|
19
|
+
background: #18a0fb;
|
|
20
|
+
border: none;
|
|
21
|
+
border-radius: 6px;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
}
|
|
24
|
+
button:hover {
|
|
25
|
+
background: #0d8de0;
|
|
26
|
+
}
|
|
27
|
+
#status {
|
|
28
|
+
margin-top: 12px;
|
|
29
|
+
min-height: 16px;
|
|
30
|
+
color: #555;
|
|
31
|
+
}
|
|
32
|
+
</style>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<button id="export">Export to GDD</button>
|
|
36
|
+
<p id="status">Reads local Figma variables and POSTs them to the GDD receiver on localhost:5179.</p>
|
|
37
|
+
<script>
|
|
38
|
+
document.getElementById('export').onclick = function () {
|
|
39
|
+
document.getElementById('status').textContent = 'Exporting…';
|
|
40
|
+
parent.postMessage({ pluginMessage: { type: 'export' } }, '*');
|
|
41
|
+
};
|
|
42
|
+
</script>
|
|
43
|
+
</body>
|
|
44
|
+
</html>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* hooks/gdd-intel-trigger.js — D5 (PostToolUse on Edit|Write)
|
|
5
5
|
*
|
|
6
6
|
* On every Edit/Write that touches a design-authoritative surface
|
|
7
|
-
* (skills/**, agents/**, reference/**, skill-templates/**), spawn a
|
|
7
|
+
* (skills/**, agents/**, reference/**, scripts/skill-templates/**), spawn a
|
|
8
8
|
* background, detached refresh of the .design/intel/ store so downstream
|
|
9
9
|
* consumers (router, planner, audits) see the latest extracts without the
|
|
10
10
|
* user paying for a full rebuild on the next /gdd run.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* camelCase field names (tool_name/toolName, tool_input/toolInput,
|
|
15
15
|
* file_path/filePath/path).
|
|
16
16
|
* 2. If the edited path matches
|
|
17
|
-
* ^(skills|agents|reference|skill-templates)/.*\.(md|json)$
|
|
17
|
+
* ^(skills|agents|reference|scripts/skill-templates)/.*\.(md|json)$
|
|
18
18
|
* (path-separator-agnostic), schedule a background refresh.
|
|
19
19
|
* 3. Otherwise no-op — write {continue:true} and exit 0.
|
|
20
20
|
* 4. Always exit 0. Never block. Never surface errors. Errors only ever
|
|
@@ -55,7 +55,7 @@ const path = require('node:path');
|
|
|
55
55
|
const { spawn } = require('node:child_process');
|
|
56
56
|
|
|
57
57
|
const LOCK_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
58
|
-
const TARGET_RE = /^(?:skills|agents|reference|
|
|
58
|
+
const TARGET_RE = /^(?:skills|agents|reference|scripts\/skill-templates)\/.*\.(?:md|json)$/;
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* Extract the edited file path + tool name from a PostToolUse payload.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hegemonart/get-design-done",
|
|
3
|
-
"version": "1.59.
|
|
3
|
+
"version": "1.59.4",
|
|
4
4
|
"description": "A design-quality pipeline for AI coding agents: brief, explore, plan, design, and verify UI work against your design system.",
|
|
5
5
|
"author": "Hegemon",
|
|
6
6
|
"homepage": "https://github.com/hegemonart/get-design-done",
|
|
@@ -25,9 +25,13 @@
|
|
|
25
25
|
"docs/i18n/",
|
|
26
26
|
"scripts/lib/",
|
|
27
27
|
"scripts/cli/",
|
|
28
|
+
"scripts/skill-templates/",
|
|
28
29
|
"scripts/install.cjs",
|
|
29
30
|
"scripts/injection-patterns.cjs",
|
|
30
31
|
"scripts/bootstrap.cjs",
|
|
32
|
+
"scripts/build-skills.cjs",
|
|
33
|
+
"scripts/generate-skill-frontmatter.cjs",
|
|
34
|
+
"figma-plugin/",
|
|
31
35
|
"SKILL.md",
|
|
32
36
|
"README.md",
|
|
33
37
|
"CHANGELOG.md",
|
|
@@ -62,6 +66,7 @@
|
|
|
62
66
|
"test:behavior": "node scripts/run-behavior-tests.cjs",
|
|
63
67
|
"typecheck": "tsc --noEmit",
|
|
64
68
|
"codegen:schemas": "node --experimental-strip-types scripts/codegen-schema-types.ts",
|
|
69
|
+
"codegen:schemas:check": "node --experimental-strip-types scripts/codegen-schema-types.ts --check",
|
|
65
70
|
"lint:md": "npx --yes markdownlint-cli2 \"**/*.md\" \"#**/node_modules\" \"#.planning\" \"#.claude\" \"#test/fixtures/baselines\"",
|
|
66
71
|
"lint:links": "npx --yes lychee --no-progress --accept 200,206,403,429 \"**/*.md\" || true",
|
|
67
72
|
"lint:agentskills": "node scripts/lint-agentskills-spec.cjs",
|
|
@@ -31,7 +31,7 @@ the scanner pattern list in lockstep.
|
|
|
31
31
|
## Authoring surfaces
|
|
32
32
|
|
|
33
33
|
- **`skills/` as the authoring source** → **`source/skills/`** (Phase 42, deprecated)
|
|
34
|
-
→ **`skill-templates/`** (v1.58.0, current).
|
|
34
|
+
→ **`skill-templates/`** (v1.58.0) → **`scripts/skill-templates/`** (v1.59, current). Migration:
|
|
35
35
|
|
|
36
36
|
- **Phase 42** introduced multi-harness compilation. Skills moved to `source/skills/` with
|
|
37
37
|
placeholders (`{{command_prefix}}` et al.; see `reference/skill-placeholders.md`) and the
|
|
@@ -43,10 +43,10 @@ the scanner pattern list in lockstep.
|
|
|
43
43
|
tarball via `prepack`. Net: 232 tracked files dropped to 116, with no change to end-user
|
|
44
44
|
install experience (the tarball still ships `skills/` pre-built).
|
|
45
45
|
|
|
46
|
-
Migration for contributors: **edit `skill-templates/`, never `skills/` directly**. After edits,
|
|
46
|
+
Migration for contributors: **edit `scripts/skill-templates/`, never `skills/` directly**. After edits,
|
|
47
47
|
`npm run build:skills` regenerates `skills/` locally (or `npm install` does it automatically).
|
|
48
48
|
`.claude-plugin/plugin.json`'s `"skills": ["./skills/"]` is unchanged - the plugin still loads
|
|
49
|
-
`skills/`, now produced from `skill-templates/`. The `detect-stale-refs.cjs` list is extended to
|
|
49
|
+
`skills/`, now produced from `scripts/skill-templates/`. The `detect-stale-refs.cjs` list is extended to
|
|
50
50
|
emit warnings on lingering `source/skills/` path references.
|
|
51
51
|
|
|
52
52
|
## Scanner scope
|
|
@@ -9,7 +9,7 @@ last_updated: 2026-06-03
|
|
|
9
9
|
|
|
10
10
|
# Live Mode Integration
|
|
11
11
|
|
|
12
|
-
This file is the meta-rules companion to the `gdd-live` skill (`skill-templates/live/SKILL.md`). It describes how `/gdd:live` turns a running dev server into a live design surface: the user picks a DOM element, the agent generates N variants in one batch, the variants hot-swap in place, the user accepts or discards, and the whole session persists. For the SKILL.md structural contract (line cap, description budget, frontmatter), see `./skill-authoring-contract.md`. The variants themselves are grounded in the Phase 45 domain indexes (`./spatial.md`, `./interaction.md`, `./color.md`, `./typography.md`, `./motion.md`).
|
|
12
|
+
This file is the meta-rules companion to the `gdd-live` skill (`scripts/skill-templates/live/SKILL.md`). It describes how `/gdd:live` turns a running dev server into a live design surface: the user picks a DOM element, the agent generates N variants in one batch, the variants hot-swap in place, the user accepts or discards, and the whole session persists. For the SKILL.md structural contract (line cap, description budget, frontmatter), see `./skill-authoring-contract.md`. The variants themselves are grounded in the Phase 45 domain indexes (`./spatial.md`, `./interaction.md`, `./color.md`, `./typography.md`, `./motion.md`).
|
|
13
13
|
|
|
14
14
|
There is NO bundled browser automation. The skill drives the Claude Preview MCP at runtime; the modules under `scripts/lib/live/` are pure and dependency-free.
|
|
15
15
|
|
package/reference/registry.json
CHANGED
|
@@ -1071,7 +1071,7 @@
|
|
|
1071
1071
|
"path": "reference/skill-placeholders.md",
|
|
1072
1072
|
"type": "meta-rules",
|
|
1073
1073
|
"phase": 42,
|
|
1074
|
-
"description": "Multi-harness skill-placeholder catalogue: the four placeholders ({{command_prefix}}/{{model}}/{{config_file}}/{{ask_instruction}}) + per-harness substitution table + the \\{{...}} escape + the <!-- harness-only: a,b --> block rule. Skills authored once in skill-templates/, compiled per-harness by scripts/build-skills.cjs via scripts/lib/build/factory.cjs reading scripts/lib/manifest/harnesses.json."
|
|
1074
|
+
"description": "Multi-harness skill-placeholder catalogue: the four placeholders ({{command_prefix}}/{{model}}/{{config_file}}/{{ask_instruction}}) + per-harness substitution table + the \\{{...}} escape + the <!-- harness-only: a,b --> block rule. Skills authored once in scripts/skill-templates/, compiled per-harness by scripts/build-skills.cjs via scripts/lib/build/factory.cjs reading scripts/lib/manifest/harnesses.json."
|
|
1075
1075
|
},
|
|
1076
1076
|
{
|
|
1077
1077
|
"name": "color",
|
|
@@ -10,7 +10,7 @@ last_updated: 2026-06-02
|
|
|
10
10
|
# Skill Metadata Single Source of Truth
|
|
11
11
|
|
|
12
12
|
`scripts/lib/manifest/skills.json` is the one place skill frontmatter is authored. A
|
|
13
|
-
generator projects it onto every `skill-templates/<id>/SKILL.md`, the build step compiles
|
|
13
|
+
generator projects it onto every `scripts/skill-templates/<id>/SKILL.md`, the build step compiles
|
|
14
14
|
those into the shipped trees, and CI gates keep the three copies identical. This doc
|
|
15
15
|
explains the file, the generator, and the description budget. For the structural rules a
|
|
16
16
|
SKILL.md body must follow (line cap, progressive disclosure, frontmatter required fields),
|
|
@@ -20,7 +20,7 @@ see `./skill-authoring-contract.md`.
|
|
|
20
20
|
|
|
21
21
|
The file is a JSON object: a `schema_version` integer and a `skills` array. Each array
|
|
22
22
|
element is one skill record. Only `name` is required (it must equal the
|
|
23
|
-
`skill-templates/<id>/` directory name); every other field is optional and omitted when it
|
|
23
|
+
`scripts/skill-templates/<id>/` directory name); every other field is optional and omitted when it
|
|
24
24
|
has no value.
|
|
25
25
|
|
|
26
26
|
```json
|
|
@@ -50,7 +50,7 @@ Metadata flows in one direction, and a `*:check` gate guards each hop:
|
|
|
50
50
|
```text
|
|
51
51
|
skills.json
|
|
52
52
|
-> generate-skill-frontmatter (npm run generate:skill-frontmatter)
|
|
53
|
-
-> skill-templates/<id>/SKILL.md
|
|
53
|
+
-> scripts/skill-templates/<id>/SKILL.md
|
|
54
54
|
-> build:skills (npm run build:skills)
|
|
55
55
|
-> skills/ + dist/claude-code/
|
|
56
56
|
```
|
|
@@ -64,7 +64,7 @@ skills.json
|
|
|
64
64
|
- `--check`: the CI drift gate. It writes nothing and exits non-zero when any committed
|
|
65
65
|
frontmatter differs from what the manifest would generate.
|
|
66
66
|
|
|
67
|
-
`scripts/build-skills.cjs` then propagates `skill-templates/` into the committed `skills/`
|
|
67
|
+
`scripts/build-skills.cjs` then propagates `scripts/skill-templates/` into the committed `skills/`
|
|
68
68
|
tree and `dist/claude-code/`; its own check mode asserts that the built output equals the
|
|
69
69
|
committed output. So the contract is: edit `skills.json`, regenerate, build. Never
|
|
70
70
|
hand-edit a managed frontmatter line in `SKILL.md`, because the drift gate will fail.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Skill Placeholders - Multi-Harness Source Compilation
|
|
2
2
|
|
|
3
|
-
> Phase 42. Skills are authored once in `skill-templates/` with placeholders and compiled per-harness into
|
|
3
|
+
> Phase 42. Skills are authored once in `scripts/skill-templates/` with placeholders and compiled per-harness into
|
|
4
4
|
> `dist/<bundle>/<config-dir>/skills/...` by `scripts/build-skills.cjs` (the pure transform lives in
|
|
5
5
|
> `scripts/lib/build/factory.cjs`; the per-harness values in `scripts/lib/build/harness-configs.cjs`,
|
|
6
6
|
> which reads the Phase 41.5 manifest root `scripts/lib/manifest/harnesses.json`). The Claude-Code
|
|
@@ -68,4 +68,4 @@ scope (a maintenance trap) - see the Phase 42 CONTEXT.
|
|
|
68
68
|
## Validation
|
|
69
69
|
|
|
70
70
|
`test/suite/phase-42-placeholders.test.cjs` asserts that every placeholder actually used across
|
|
71
|
-
`skill-templates/` is documented in this file, and that `skill-templates/` mirrors the `skills/` skill count.
|
|
71
|
+
`scripts/skill-templates/` is documented in this file, and that `scripts/skill-templates/` mirrors the `skills/` skill count.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Phase 42 — multi-harness skill build orchestrator.
|
|
3
|
+
// v1.58.0 renamed source/skills/ → skill-templates/ (the source/ wrapper held only skills/
|
|
4
|
+
// and added nothing). v1.58.0 ALSO gitignored skills/ as a pure build artifact — that broke
|
|
5
|
+
// the Claude Code marketplace install path (Claude Code git-clones the plugin without running
|
|
6
|
+
// `npm install`, so `./skills/` was absent post-clone). v1.58.1 reverts the gitignore:
|
|
7
|
+
// skills/ is committed again so git-clone-based installs work; scripts/skill-templates/ remains the
|
|
8
|
+
// canonical editable source; `prepare` still regenerates skills/ on contributor checkouts.
|
|
9
|
+
//
|
|
10
|
+
// node scripts/build-skills.cjs [--harness <id>] [--check] [--zip]
|
|
11
|
+
//
|
|
12
|
+
// Reads scripts/skill-templates/**/*.md, applies the pure factory per harness config, and writes:
|
|
13
|
+
// - skills/** (the committed Claude-Code surface, regenerated in place)
|
|
14
|
+
// - dist/<bundleSlug>/<configDir>/skills/** (per-harness bundles; build-only artifacts, gitignored)
|
|
15
|
+
//
|
|
16
|
+
// --check : no writes; verify the committed skills/ equals compile(scripts/skill-templates/),
|
|
17
|
+
// exit 1 on any byte drift. This is the CI drift gate.
|
|
18
|
+
// --harness <id> : restrict to one harness (skips the skills/ in-place regen unless id === claude).
|
|
19
|
+
// --zip : after building, tar -czf dist/<bundleSlug>.tgz each bundle (graceful skip if tar absent).
|
|
20
|
+
//
|
|
21
|
+
// Idempotent + byte-stable: file walk is sorted; bytes are written verbatim (line endings preserved).
|
|
22
|
+
|
|
23
|
+
const fs = require('fs');
|
|
24
|
+
const path = require('path');
|
|
25
|
+
const { spawnSync } = require('child_process');
|
|
26
|
+
const { compile } = require('./lib/build/factory.cjs');
|
|
27
|
+
const { CONFIGS, byId, claude } = require('./lib/build/harness-configs.cjs');
|
|
28
|
+
|
|
29
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
30
|
+
const SRC = path.join(ROOT, 'scripts', 'skill-templates');
|
|
31
|
+
const SKILLS = path.join(ROOT, 'skills');
|
|
32
|
+
const DIST = path.join(ROOT, 'dist');
|
|
33
|
+
|
|
34
|
+
function parseArgs(argv) {
|
|
35
|
+
const out = { check: false, zip: false, harness: null };
|
|
36
|
+
for (let i = 0; i < argv.length; i++) {
|
|
37
|
+
const a = argv[i];
|
|
38
|
+
if (a === '--check') out.check = true;
|
|
39
|
+
else if (a === '--zip') out.zip = true;
|
|
40
|
+
else if (a === '--harness') out.harness = argv[++i];
|
|
41
|
+
else if (a.startsWith('--harness=')) out.harness = a.slice('--harness='.length);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function walkMd(dir) {
|
|
47
|
+
const out = [];
|
|
48
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true }).sort((x, y) => x.name.localeCompare(y.name))) {
|
|
49
|
+
const p = path.join(dir, e.name);
|
|
50
|
+
if (e.isDirectory()) out.push(...walkMd(p));
|
|
51
|
+
else if (e.isFile() && e.name.endsWith('.md')) out.push(p);
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Compile every source file for one config -> Map<relPath, string>. */
|
|
57
|
+
function compileAll(config) {
|
|
58
|
+
const result = new Map();
|
|
59
|
+
for (const abs of walkMd(SRC)) {
|
|
60
|
+
const rel = path.relative(SRC, abs).split(path.sep).join('/');
|
|
61
|
+
result.set(rel, compile(fs.readFileSync(abs, 'utf8'), config));
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function writeMap(map, destRoot) {
|
|
67
|
+
let written = 0;
|
|
68
|
+
for (const [rel, text] of map) {
|
|
69
|
+
const dst = path.join(destRoot, rel.split('/').join(path.sep));
|
|
70
|
+
fs.mkdirSync(path.dirname(dst), { recursive: true });
|
|
71
|
+
fs.writeFileSync(dst, text);
|
|
72
|
+
written++;
|
|
73
|
+
}
|
|
74
|
+
return written;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function bundleDir(config) {
|
|
78
|
+
return path.join(DIST, config.bundleSlug, config.configDir, 'skills');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Compare a compiled map against on-disk files under destRoot. Returns array of drifting rel paths. */
|
|
82
|
+
function diffMap(map, destRoot) {
|
|
83
|
+
const drift = [];
|
|
84
|
+
for (const [rel, text] of map) {
|
|
85
|
+
const dst = path.join(destRoot, rel.split('/').join(path.sep));
|
|
86
|
+
let cur = null;
|
|
87
|
+
try { cur = fs.readFileSync(dst, 'utf8'); } catch { /* missing */ }
|
|
88
|
+
if (cur !== text) drift.push(rel);
|
|
89
|
+
}
|
|
90
|
+
return drift;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function runCheck() {
|
|
94
|
+
// v1.58.1: skills/ is committed (reverts v1.58.0 gitignore — Claude Code marketplace
|
|
95
|
+
// git-clones the plugin without running npm install, so `./skills/` MUST exist post-clone).
|
|
96
|
+
// --check is back to its original Phase 42 semantics: gate that committed skills/ matches
|
|
97
|
+
// compile(scripts/skill-templates/). If contributors edit scripts/skill-templates/ without re-running
|
|
98
|
+
// `npm run build:skills`, this catches the drift.
|
|
99
|
+
const cfg = claude();
|
|
100
|
+
const map = compileAll(cfg);
|
|
101
|
+
const driftSkills = diffMap(map, SKILLS);
|
|
102
|
+
if (driftSkills.length) {
|
|
103
|
+
process.stderr.write('build-skills --check: DRIFT detected (run `npm run build:skills` and commit).\n');
|
|
104
|
+
for (const r of driftSkills.slice(0, 10)) process.stderr.write(` skills/${r}\n`);
|
|
105
|
+
if (driftSkills.length > 10) process.stderr.write(' ...\n');
|
|
106
|
+
return 1;
|
|
107
|
+
}
|
|
108
|
+
process.stderr.write(`build-skills --check: OK - skills/ matches scripts/skill-templates/ (${map.size} files).\n`);
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function tarBundle(config) {
|
|
113
|
+
const tgz = path.join(DIST, `${config.bundleSlug}.tgz`);
|
|
114
|
+
const r = spawnSync('tar', ['-czf', tgz, '-C', DIST, config.bundleSlug], { stdio: 'ignore' });
|
|
115
|
+
if (r.error || r.status !== 0) {
|
|
116
|
+
process.stderr.write(` (zip skipped for ${config.bundleSlug}: tar unavailable)\n`);
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function runBuild(opts) {
|
|
123
|
+
const targets = opts.harness ? [byId(opts.harness)].filter(Boolean) : CONFIGS;
|
|
124
|
+
if (opts.harness && targets.length === 0) {
|
|
125
|
+
process.stderr.write(`build-skills: unknown harness '${opts.harness}'\n`);
|
|
126
|
+
return 1;
|
|
127
|
+
}
|
|
128
|
+
let total = 0;
|
|
129
|
+
for (const cfg of targets) {
|
|
130
|
+
const map = compileAll(cfg);
|
|
131
|
+
total += writeMap(map, bundleDir(cfg));
|
|
132
|
+
if (cfg.id === 'claude') writeMap(map, SKILLS); // regenerate the committed Claude surface in place
|
|
133
|
+
if (opts.zip) tarBundle(cfg);
|
|
134
|
+
process.stderr.write(` built ${cfg.bundleSlug} (${map.size} files)${cfg.id === 'claude' ? ' + skills/' : ''}\n`);
|
|
135
|
+
}
|
|
136
|
+
process.stderr.write(`build-skills: wrote ${total} files across ${targets.length} harness bundle(s).\n`);
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function main(argv) {
|
|
141
|
+
const opts = parseArgs(argv);
|
|
142
|
+
return opts.check ? runCheck() : runBuild(opts);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (require.main === module) process.exit(main(process.argv.slice(2)));
|
|
146
|
+
module.exports = { main, parseArgs, compileAll, bundleDir };
|