@hegemonart/get-design-done 1.28.5 → 1.28.7

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 (71) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +102 -0
  4. package/README.md +2 -0
  5. package/package.json +1 -1
  6. package/reference/registry.json +0 -140
  7. package/reference/skill-authoring-contract.md +40 -9
  8. package/scripts/install.cjs +7 -0
  9. package/scripts/lib/install/converters/antigravity.cjs +48 -0
  10. package/scripts/lib/install/converters/augment.cjs +68 -0
  11. package/scripts/lib/install/converters/cline.cjs +206 -0
  12. package/scripts/lib/install/converters/codebuddy.cjs +55 -0
  13. package/scripts/lib/install/converters/codex.cjs +61 -0
  14. package/scripts/lib/install/converters/copilot.cjs +47 -0
  15. package/scripts/lib/install/converters/cursor.cjs +49 -0
  16. package/scripts/lib/install/converters/gemini.cjs +116 -0
  17. package/scripts/lib/install/converters/kilo.cjs +62 -0
  18. package/scripts/lib/install/converters/opencode.cjs +64 -0
  19. package/scripts/lib/install/converters/qwen.cjs +51 -0
  20. package/scripts/lib/install/converters/shared.cjs +377 -0
  21. package/scripts/lib/install/converters/trae.cjs +47 -0
  22. package/scripts/lib/install/converters/windsurf.cjs +47 -0
  23. package/scripts/lib/install/installer.cjs +529 -47
  24. package/scripts/lib/install/merge.cjs +31 -1
  25. package/scripts/lib/install/runtime-artifact-layout.cjs +431 -0
  26. package/scripts/lib/install/runtime-homes.cjs +225 -0
  27. package/scripts/lib/install/runtime-slash.cjs +172 -0
  28. package/scripts/lib/install/runtimes.cjs +25 -32
  29. package/skills/apply-reflections/SKILL.md +1 -1
  30. package/skills/cache-manager/SKILL.md +2 -2
  31. package/skills/compare/SKILL.md +8 -8
  32. package/skills/connections/SKILL.md +9 -9
  33. package/skills/darkmode/SKILL.md +8 -8
  34. package/skills/debug/SKILL.md +3 -3
  35. package/skills/design/SKILL.md +6 -6
  36. package/skills/discover/SKILL.md +7 -7
  37. package/skills/explore/SKILL.md +6 -6
  38. package/skills/health/SKILL.md +2 -2
  39. package/skills/new-cycle/SKILL.md +1 -1
  40. package/skills/peer-cli-add/SKILL.md +6 -6
  41. package/skills/peer-cli-customize/SKILL.md +5 -5
  42. package/skills/peers/SKILL.md +2 -2
  43. package/skills/plan/SKILL.md +10 -10
  44. package/skills/quality-gate/SKILL.md +1 -1
  45. package/skills/router/SKILL.md +3 -3
  46. package/skills/scan/SKILL.md +17 -17
  47. package/skills/start/SKILL.md +1 -1
  48. package/skills/style/SKILL.md +5 -5
  49. package/skills/turn-closeout/SKILL.md +1 -1
  50. package/skills/verify/SKILL.md +10 -10
  51. package/skills/warm-cache/SKILL.md +2 -2
  52. /package/{reference → skills/apply-reflections}/apply-reflections-procedure.md +0 -0
  53. /package/{reference → skills/cache-manager}/cache-policy.md +0 -0
  54. /package/{reference → skills/compare}/compare-rubric.md +0 -0
  55. /package/{reference → skills/connections}/connections-onboarding.md +0 -0
  56. /package/{reference → skills/darkmode}/darkmode-audit-procedure.md +0 -0
  57. /package/{reference → skills/debug}/debug-feedback-loops.md +0 -0
  58. /package/{reference → skills/design}/design-procedure.md +0 -0
  59. /package/{reference → skills/discover}/discover-procedure.md +0 -0
  60. /package/{reference → skills/explore}/explore-procedure.md +0 -0
  61. /package/{reference → skills/health}/health-mcp-detection.md +0 -0
  62. /package/{reference → skills/health}/health-skill-length-report.md +0 -0
  63. /package/{reference → skills/new-cycle}/milestone-completeness-rubric.md +0 -0
  64. /package/{reference → skills/peer-cli-add}/peer-cli-protocol.md +0 -0
  65. /package/{reference → skills/plan}/plan-procedure.md +0 -0
  66. /package/{reference → skills/quality-gate}/threat-modeling.md +0 -0
  67. /package/{reference → skills/router}/router-rules.md +0 -0
  68. /package/{reference → skills/scan}/scan-procedure.md +0 -0
  69. /package/{reference → skills/start}/start-procedure.md +0 -0
  70. /package/{reference → skills/style}/style-doc-procedure.md +0 -0
  71. /package/{reference → skills/verify}/verify-procedure.md +0 -0
@@ -0,0 +1,206 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/cline.cjs — Phase 28.7 (Plan 28.7-06).
5
+ *
6
+ * Cline SKILL.md converter — SPECIAL CASE per Phase 28.7 D-09.
7
+ *
8
+ * Cline does not have a `skills/<name>/SKILL.md` directory model. Per
9
+ * `runtime-artifact-layout.cjs#cline`, its `kinds: []` is intentionally
10
+ * empty and `layout.specialCase = 'clinerules-embed'` routes through
11
+ * this converter. Instead of one SKILL.md file per skill, all installed
12
+ * skills are concatenated into a single `.clinerules` file written at
13
+ * `<cline-config>/.clinerules`. That file contains a stack of markdown
14
+ * rule-blocks, one per skill, with a `## gdd-<skillName>` heading and
15
+ * description + body prose.
16
+ *
17
+ * This file exports TWO functions:
18
+ *
19
+ * 1. `convert(content, skillName, opts) → string`
20
+ * Converts ONE Claude-source SKILL.md into a `.clinerules`-format
21
+ * rule-block. The block is a markdown fragment — NOT a complete
22
+ * file. The installer (Plan 28.7-08) invokes this for each skill,
23
+ * accumulates the blocks, then calls `buildClinerulesFile` to
24
+ * assemble the final file.
25
+ *
26
+ * 2. `buildClinerulesFile(skillBlocks) → string`
27
+ * Concatenates an array of `{ name, block }` entries into the
28
+ * final `.clinerules` file content. Prepends a 4-line header
29
+ * explaining the file's origin (auto-generated from gdd skills).
30
+ *
31
+ * Output shape (one block):
32
+ *
33
+ * ## gdd-<skillName>
34
+ *
35
+ * <description from source frontmatter>
36
+ *
37
+ * <body content, slash-rewritten, prose preserved>
38
+ *
39
+ * The block contains NO YAML frontmatter (cline rules are pure
40
+ * markdown), NO `<!-- ... adapter -->` HTML comment (rules-format does
41
+ * not embed adapter headers), and NO `name:` field — the `## gdd-<name>`
42
+ * heading IS the skill identifier in cline's rule-block model.
43
+ *
44
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
45
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
46
+ * attribution. gsd-build's equivalent path is the `cline: kinds: []` +
47
+ * `.clinerules` write special-case in their bin/install.js monolith;
48
+ * our modular factor moves the rule-block emission here and lets the
49
+ * installer (Plan 28.7-08) handle the disk write.
50
+ *
51
+ * Wave-3 scope note: this is the only special-case converter in Wave 3
52
+ * (Plan 28.7-06). The other Wave 3 converter (codebuddy.cjs) follows
53
+ * the uniform skills-dir pattern. Per Phase 28.7 D-10, hermes is OUT of
54
+ * scope — no hermes.cjs is created. Hermes was the other special-case
55
+ * runtime in gsd-build's full set (nested skills/gsd/<name>/ layout per
56
+ * upstream #2841), but it is intentionally absent from GDD's 14-runtime
57
+ * set (Phase 24 D-02 runtime list invariant — see Phase 28.7 D-03).
58
+ *
59
+ * Pure / side-effect-free: no fs, no env, no path. Both exports are
60
+ * deterministic string → string transforms; the installer writes the
61
+ * assembled file via its own fs surface.
62
+ */
63
+
64
+ const shared = require('./shared.cjs');
65
+
66
+ // ---------------------------------------------------------------------------
67
+ // Internal helpers
68
+ // ---------------------------------------------------------------------------
69
+
70
+ /**
71
+ * Extract the `description:` value from a frontmatter block.
72
+ *
73
+ * Matches the first `description: <value>` line; tolerates leading
74
+ * whitespace, surrounding quotes (single or double), and CRLF endings.
75
+ * Returns the trimmed value string, or `''` if not present.
76
+ *
77
+ * Note: we don't parse YAML here — a single regex over the raw
78
+ * frontmatter is sufficient because SKILL.md descriptions are always
79
+ * single-line strings (multi-line YAML scalars are not used in the
80
+ * GDD source set).
81
+ *
82
+ * @param {string|null} frontmatter
83
+ * @returns {string}
84
+ */
85
+ function extractDescription(frontmatter) {
86
+ if (!frontmatter || typeof frontmatter !== 'string') return '';
87
+ const m = frontmatter.match(/^\s*description\s*:\s*(.*)$/m);
88
+ if (!m) return '';
89
+ let v = m[1].trim();
90
+ // Strip surrounding quotes if present.
91
+ const quoted = v.match(/^["'](.*)["']$/);
92
+ if (quoted) v = quoted[1];
93
+ return v;
94
+ }
95
+
96
+ /**
97
+ * Normalize the skill name by stripping any prior `gdd-`/`gsd-` prefix
98
+ * (case-insensitive) so we never emit `gdd-gdd-foo`. Matches
99
+ * `shared.buildFrontmatter`'s normalization for consistency.
100
+ *
101
+ * @param {string} skillName
102
+ * @returns {string}
103
+ */
104
+ function normalizeSkillName(skillName) {
105
+ return String(skillName || '').replace(/^(gdd-|gsd-)/i, '');
106
+ }
107
+
108
+ // ---------------------------------------------------------------------------
109
+ // convert — produce a single rule-block for one skill
110
+ // ---------------------------------------------------------------------------
111
+
112
+ /**
113
+ * Convert ONE Claude-source SKILL.md into a `.clinerules`-format rule
114
+ * block (a markdown fragment, not a complete file).
115
+ *
116
+ * The returned block has this shape:
117
+ *
118
+ * ## gdd-<skillName>
119
+ *
120
+ * <description if present>
121
+ *
122
+ * <body content, slash-rewritten via rewriteSlashRefs(body, 'cline')>
123
+ *
124
+ * Trailing newline is included; leading whitespace is stripped from the
125
+ * body so the heading is the first non-blank line. The installer
126
+ * (Plan 28.7-08) accumulates these blocks and joins them via
127
+ * `buildClinerulesFile`.
128
+ *
129
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
130
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
131
+ * `gdd-`/`gsd-` prefixes are stripped to prevent double-prefix.
132
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
133
+ * to `'cline'`. Currently informational only.
134
+ * @returns {string} The rule-block markdown fragment.
135
+ */
136
+ function convert(content, skillName, opts) {
137
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
138
+ const description = extractDescription(frontmatter);
139
+ const bareName = normalizeSkillName(skillName);
140
+
141
+ // Slash refs rewrite to `/gdd-name` form — cline accepts Claude-shape
142
+ // slashes (runtime-slash.cjs emits `/gdd-` for every non-codex runtime,
143
+ // and cline is not codex). Trim leading/trailing whitespace so the
144
+ // heading directly precedes the body content.
145
+ const prose = shared.rewriteSlashRefs(body, 'cline').trim();
146
+
147
+ const heading = `## gdd-${bareName}`;
148
+ const descLine = description ? `${description}\n\n` : '';
149
+
150
+ return `${heading}\n\n${descLine}${prose}\n`;
151
+ }
152
+
153
+ // ---------------------------------------------------------------------------
154
+ // buildClinerulesFile — assemble the final .clinerules file content
155
+ // ---------------------------------------------------------------------------
156
+
157
+ /**
158
+ * Assemble a final `.clinerules` file from an array of per-skill blocks.
159
+ *
160
+ * Prepends a 4-line header citing the gdd origin so anyone reading the
161
+ * generated `.clinerules` file knows it is auto-generated and the
162
+ * authoritative source is the upstream SKILL.md files. Blocks are
163
+ * separated by a blank line (`\n\n`), and the file ends with a single
164
+ * trailing newline.
165
+ *
166
+ * Called by Plan 28.7-08's installer after invoking `convert()` on each
167
+ * skill. Pure transform — does NOT write to disk.
168
+ *
169
+ * Accepts either of two shapes per entry (for installer flexibility):
170
+ * - `{ name: string, block: string }` — preferred, name is informational
171
+ * - `{ skillName: string, content: string }` — alternative legacy/test shape
172
+ *
173
+ * @param {Array<{ name?: string, skillName?: string, block?: string, content?: string }>} skillBlocks
174
+ * @returns {string} The full `.clinerules` content (ready to write).
175
+ */
176
+ function buildClinerulesFile(skillBlocks) {
177
+ const header = [
178
+ '# get-design-done rules',
179
+ '',
180
+ '<!-- Auto-generated from gdd SKILL.md sources. Edit upstream skills, not this file. -->',
181
+ '',
182
+ ].join('\n');
183
+
184
+ // Defensive: empty / non-array → header-only file.
185
+ if (!Array.isArray(skillBlocks) || skillBlocks.length === 0) {
186
+ return header + '\n';
187
+ }
188
+
189
+ const body = skillBlocks
190
+ .map((entry) => {
191
+ // Accept either `block` or `content` keys.
192
+ if (!entry || typeof entry !== 'object') return '';
193
+ const text = typeof entry.block === 'string'
194
+ ? entry.block
195
+ : typeof entry.content === 'string'
196
+ ? entry.content
197
+ : '';
198
+ return text.trim();
199
+ })
200
+ .filter((s) => s.length > 0)
201
+ .join('\n\n');
202
+
203
+ return header + body + '\n';
204
+ }
205
+
206
+ module.exports = { convert, buildClinerulesFile };
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/codebuddy.cjs — Phase 28.7 (Plan 28.7-06).
5
+ *
6
+ * CodeBuddy SKILL.md converter. Translates Claude-shape source into
7
+ * CodeBuddy's expected shape (uniform skills/<name>/SKILL.md layout —
8
+ * per `runtime-artifact-layout.cjs#codebuddy` which emits the standard
9
+ * skillsKind('skills', 'gdd-', ...) entry):
10
+ *
11
+ * - Frontmatter `name:` normalized to `gdd-<skill>` (no double-prefix).
12
+ * - Slash references in prose pass through as `/gdd-<name>` —
13
+ * CodeBuddy accepts the Claude shape. Mixed-shape inputs are
14
+ * normalized via the runtime-slash module.
15
+ * - Tool names in code fences pass through unchanged — CodeBuddy
16
+ * accepts the Claude vocabulary (Read/Write/Bash/Edit/Grep/Glob).
17
+ * - A 1-line HTML adapter header is injected at the top of the body
18
+ * to record that this file was auto-generated from Claude source.
19
+ *
20
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
21
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
22
+ * attribution. gsd-build's equivalent function is
23
+ * `convertClaudeCommandToCodeBuddySkill` in bin/install.js; our modular
24
+ * factor delegates the actual rewrites to ./shared.cjs.
25
+ *
26
+ * This converter follows the same uniform pattern as cursor / windsurf /
27
+ * trae / qwen / copilot / antigravity — it is NOT a special-case
28
+ * runtime. The only special-case converter in Wave 3 is cline.cjs (per
29
+ * D-09: rule-block embedding into `.clinerules`); hermes is OUT of
30
+ * scope per D-10 and intentionally has no converter file.
31
+ *
32
+ * Pure / side-effect-free: no fs, no env, no path. `convert` is a
33
+ * deterministic string → string transform.
34
+ */
35
+
36
+ const shared = require('./shared.cjs');
37
+
38
+ /**
39
+ * Convert Claude-source SKILL.md content for the CodeBuddy runtime.
40
+ *
41
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
42
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
43
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
44
+ * to `'codebuddy'`. Currently informational only.
45
+ * @returns {string}
46
+ */
47
+ function convert(content, skillName, opts) {
48
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
49
+ const fm = shared.buildFrontmatter(frontmatter, skillName, 'gdd-');
50
+ let out = shared.rewriteSlashRefs(body, 'codebuddy');
51
+ out = shared.ensureAdapterHeader(out, 'CodeBuddy');
52
+ return fm + out;
53
+ }
54
+
55
+ module.exports = { convert };
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/codex.cjs — Phase 28.7 (Plan 28.7-04).
5
+ *
6
+ * Codex SKILL.md converter. Translates Claude-shape source into Codex's
7
+ * expected shape:
8
+ *
9
+ * - Frontmatter `name:` normalized to `gdd-<skill>` (no double-prefix).
10
+ * - Slash references in prose rewritten from `/gdd-<name>` to
11
+ * `$gdd-<name>` (Codex's shell-variable form) via
12
+ * `../runtime-slash.cjs#formatGddSlash`. Skill names are lowercased
13
+ * on emission per Codex shell-var convention.
14
+ * - Tool names in code fences rewritten via `CODEX_TOOL_MAP` from
15
+ * `reference/codex-tools.md` (Phase 21 D-06 reuse):
16
+ * Read → read_file
17
+ * Write/Edit → apply_patch
18
+ * Bash/Grep → shell
19
+ * Glob → shell
20
+ * WebSearch → web_search
21
+ * WebFetch → shell
22
+ * Task is left untouched (Phase 21 codex-tools.md "Known gaps").
23
+ * - A 1-line HTML adapter header is injected at the top of the body
24
+ * to record that this file was auto-generated from Claude source.
25
+ *
26
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
27
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
28
+ * attribution. gsd-build's equivalent is `convertClaudeCommandToCodexSkill`
29
+ * in bin/install.js; our modular factor delegates rewrites to ./shared.cjs
30
+ * and pulls the tool map from the same module's CODEX_TOOL_MAP export.
31
+ *
32
+ * Pure / side-effect-free: no fs, no env, no path. `convert` is a
33
+ * deterministic string → string transform.
34
+ *
35
+ * Per Phase 21 codex-tools.md: tool-name rewrites are operative on the
36
+ * code-fenced INVOCATION form (`Bash(command=...)`) only. Prose mentions
37
+ * of the Claude vocabulary ("Use the Bash tool to...") round-trip
38
+ * unchanged — they're documentation, not invocations.
39
+ */
40
+
41
+ const shared = require('./shared.cjs');
42
+
43
+ /**
44
+ * Convert Claude-source SKILL.md content for the Codex runtime.
45
+ *
46
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
47
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
48
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
49
+ * to `'codex'`. Currently informational only.
50
+ * @returns {string}
51
+ */
52
+ function convert(content, skillName, opts) {
53
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
54
+ const fm = shared.buildFrontmatter(frontmatter, skillName, 'gdd-');
55
+ let out = shared.rewriteSlashRefs(body, 'codex');
56
+ out = shared.rewriteCodeFenceTools(out, shared.CODEX_TOOL_MAP);
57
+ out = shared.ensureAdapterHeader(out, 'Codex');
58
+ return fm + out;
59
+ }
60
+
61
+ module.exports = { convert };
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/copilot.cjs — Phase 28.7 (Plan 28.7-04).
5
+ *
6
+ * GitHub Copilot SKILL.md converter. Translates Claude-shape source
7
+ * into Copilot's expected shape:
8
+ *
9
+ * - Frontmatter `name:` normalized to `gdd-<skill>` (no double-prefix).
10
+ * - Slash references in prose pass through as `/gdd-<name>` —
11
+ * Copilot accepts the Claude shape. Mixed-shape inputs are
12
+ * normalized via the runtime-slash module.
13
+ * - Tool names in code fences pass through unchanged — Copilot
14
+ * accepts the Claude vocabulary (Read/Write/Bash/Edit/Grep/Glob).
15
+ * - A 1-line HTML adapter header is injected at the top of the body
16
+ * to record that this file was auto-generated from Claude source.
17
+ *
18
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
19
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
20
+ * attribution. gsd-build's equivalent function is
21
+ * `convertClaudeCommandToCopilotSkill` in bin/install.js; our modular
22
+ * factor delegates the actual rewrites to ./shared.cjs.
23
+ *
24
+ * Pure / side-effect-free: no fs, no env, no path. `convert` is a
25
+ * deterministic string → string transform.
26
+ */
27
+
28
+ const shared = require('./shared.cjs');
29
+
30
+ /**
31
+ * Convert Claude-source SKILL.md content for the Copilot runtime.
32
+ *
33
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
34
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
35
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
36
+ * to `'copilot'`. Currently informational only.
37
+ * @returns {string}
38
+ */
39
+ function convert(content, skillName, opts) {
40
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
41
+ const fm = shared.buildFrontmatter(frontmatter, skillName, 'gdd-');
42
+ let out = shared.rewriteSlashRefs(body, 'copilot');
43
+ out = shared.ensureAdapterHeader(out, 'Copilot');
44
+ return fm + out;
45
+ }
46
+
47
+ module.exports = { convert };
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/cursor.cjs — Phase 28.7 (Plan 28.7-04).
5
+ *
6
+ * Cursor SKILL.md converter. Translates Claude-shape source into
7
+ * Cursor's expected shape:
8
+ *
9
+ * - Frontmatter `name:` normalized to `gdd-<skill>` (no double-prefix).
10
+ * - Slash references in prose pass through unchanged — Cursor consumes
11
+ * the same `/gdd-<name>` shape Claude does (see runtime-slash.cjs).
12
+ * Mixed-shape inputs (`gdd-x`, `/gdd:x`) are normalized to `/gdd-x`
13
+ * so the installed skill is consistent.
14
+ * - Tool names in code fences pass through unchanged — Cursor accepts
15
+ * the Claude vocabulary (Read/Write/Bash/Edit/Grep/Glob).
16
+ * - A 1-line HTML adapter header is injected at the top of the body
17
+ * to record that this file was auto-generated from Claude source.
18
+ *
19
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
20
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
21
+ * attribution. gsd-build's equivalent function is
22
+ * `convertClaudeCommandToCursorSkill` in bin/install.js; our modular
23
+ * factor delegates the actual rewrites to ./shared.cjs.
24
+ *
25
+ * Pure / side-effect-free: no fs, no env, no path. `convert` is a
26
+ * deterministic string → string transform.
27
+ */
28
+
29
+ const shared = require('./shared.cjs');
30
+
31
+ /**
32
+ * Convert Claude-source SKILL.md content for the Cursor runtime.
33
+ *
34
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
35
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
36
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
37
+ * to `'cursor'`. Currently informational only; future per-tier branching
38
+ * may consume it.
39
+ * @returns {string}
40
+ */
41
+ function convert(content, skillName, opts) {
42
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
43
+ const fm = shared.buildFrontmatter(frontmatter, skillName, 'gdd-');
44
+ let out = shared.rewriteSlashRefs(body, 'cursor');
45
+ out = shared.ensureAdapterHeader(out, 'Cursor');
46
+ return fm + out;
47
+ }
48
+
49
+ module.exports = { convert };
@@ -0,0 +1,116 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/gemini.cjs — Phase 28.7 (Plan 28.7-07).
5
+ *
6
+ * Gemini CLI command-file converter. Translates Claude-shape SKILL.md
7
+ * source into the command-format output Gemini expects under
8
+ * `<config>/commands/gdd/<name>.md` (see Phase 28.7 D-05 +
9
+ * `runtime-artifact-layout.cjs#gemini`, which stages this converter via
10
+ * `commandsKind('commands/gdd', 'gdd-', ...)`).
11
+ *
12
+ * Translation rules:
13
+ *
14
+ * - Frontmatter `name:` normalized to `gdd-<skill>` (no double-prefix).
15
+ * - Slash references in prose pass through as `/gdd-<name>` — Gemini
16
+ * accepts the Claude-canonical slash shape via `runtime-slash.cjs`
17
+ * (rt: 'gemini' → `/gdd-`). Legacy colon and shell-variable forms
18
+ * are normalized to `/gdd-`.
19
+ * - Tool names in code fences are rewritten per `GEMINI_TOOL_MAP`
20
+ * (Phase 28.7 D-06 — reuse Phase 21 `reference/gemini-tools.md`
21
+ * authoritative table). Source of truth for the map is the Phase 21
22
+ * reference doc, NOT this file; the constant below is a frozen
23
+ * snapshot of that table as of `Last verified: 2026-04-24`. If
24
+ * Gemini ships a tool-vocabulary change, update
25
+ * `reference/gemini-tools.md` FIRST and then re-sync the constant.
26
+ * Currently mapped:
27
+ * Read → read_file
28
+ * Write → write_file
29
+ * Edit → replace
30
+ * Bash → run_shell_command
31
+ * Grep → search_file_content
32
+ * Glob → glob
33
+ * WebSearch → google_web_search
34
+ * WebFetch → web_fetch
35
+ * `Task` is intentionally absent — per Phase 21 gemini-tools.md
36
+ * "Known gaps", Gemini handles Task via a nested-CLI invocation, not
37
+ * a tool call; skills that rely on Task fall back to documentation
38
+ * prose ("on Gemini this becomes a nested gemini CLI run") that the
39
+ * converter leaves untouched.
40
+ * - Prose mentions of tool names (e.g. "use the Bash tool") are NOT
41
+ * rewritten — only the parenthesized invocation form inside fenced
42
+ * blocks gets rewritten. This matches the codex + augment converter
43
+ * policies (Phase 28.7 D-06 invocation-only convention).
44
+ * - A 1-line HTML adapter header is injected at the top of the body
45
+ * to record that this file was auto-generated from Claude source.
46
+ *
47
+ * Wave 4 layout note: Gemini uses `commands/gdd/<name>.md` (nested
48
+ * `gdd/` subdirectory under `commands/`), distinct from OpenCode + Kilo
49
+ * which use the XDG singular `command/<name>.md` layout. Both shapes
50
+ * are command-format runtimes — they differ only in destSubpath, which
51
+ * is encoded in `runtime-artifact-layout.cjs#commandsKind`.
52
+ *
53
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
54
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
55
+ * attribution. gsd-build's equivalent function is
56
+ * `convertClaudeCommandToGeminiCommand` in bin/install.js; our modular
57
+ * factor delegates the actual rewrites to ./shared.cjs and follows the
58
+ * same `tool-map + slash-rewrite + adapter-header` pattern as the codex
59
+ * (CODEX_TOOL_MAP) and augment (AUGMENT_TOOL_MAP) converters.
60
+ *
61
+ * Phase 21 reference cite (D-06): reference/gemini-tools.md is the
62
+ * canonical, version-pinned source for the tool-name mapping. Do not
63
+ * edit GEMINI_TOOL_MAP without first updating that file.
64
+ *
65
+ * Pure / side-effect-free: no fs, no env, no path. `convert` is a
66
+ * deterministic string → string transform.
67
+ */
68
+
69
+ const shared = require('./shared.cjs');
70
+
71
+ /**
72
+ * Claude tool name → Gemini tool name. Locked by Phase 21
73
+ * `reference/gemini-tools.md` (per Phase 28.7 D-06). Skills referenced
74
+ * as `Read(...)`, `Write(...)`, etc. in Claude-source code fences are
75
+ * rewritten to Gemini's vocabulary at install time.
76
+ *
77
+ * Note: `Task` is intentionally absent. Per Phase 21 gemini-tools.md
78
+ * "Known gaps", Gemini handles Task via nested-CLI invocation (not a
79
+ * tool call); the converter leaves `Task(...)` references untouched so
80
+ * fallback prose ("on Gemini this becomes a nested gemini CLI run")
81
+ * is still readable.
82
+ *
83
+ * Frozen to prevent accidental mutation. The same Object.freeze pattern
84
+ * is used by CODEX_TOOL_MAP (shared.cjs) and AUGMENT_TOOL_MAP
85
+ * (augment.cjs).
86
+ */
87
+ const GEMINI_TOOL_MAP = Object.freeze({
88
+ Read: 'read_file',
89
+ Write: 'write_file',
90
+ Edit: 'replace',
91
+ Bash: 'run_shell_command',
92
+ Grep: 'search_file_content',
93
+ Glob: 'glob',
94
+ WebSearch: 'google_web_search',
95
+ WebFetch: 'web_fetch',
96
+ });
97
+
98
+ /**
99
+ * Convert Claude-source SKILL.md content for the Gemini runtime.
100
+ *
101
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
102
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
103
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
104
+ * to `'gemini'`. Currently informational only.
105
+ * @returns {string}
106
+ */
107
+ function convert(content, skillName, opts) {
108
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
109
+ const fm = shared.buildFrontmatter(frontmatter, skillName, 'gdd-');
110
+ let out = shared.rewriteSlashRefs(body, 'gemini');
111
+ out = shared.rewriteCodeFenceTools(out, GEMINI_TOOL_MAP);
112
+ out = shared.ensureAdapterHeader(out, 'Gemini');
113
+ return fm + out;
114
+ }
115
+
116
+ module.exports = { convert, GEMINI_TOOL_MAP };
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/kilo.cjs — Phase 28.7 (Plan 28.7-07).
5
+ *
6
+ * Kilo command-file converter. Translates Claude-shape SKILL.md source
7
+ * into the command-format output Kilo expects under its XDG
8
+ * `command/<name>.md` slash-command directory (see Phase 28.7 D-05 +
9
+ * `runtime-artifact-layout.cjs#kilo`, which stages this converter via
10
+ * `commandsKind('command', 'gdd-', ...)`).
11
+ *
12
+ * Translation rules:
13
+ *
14
+ * - Frontmatter `name:` normalized to `gdd-<skill>` (no double-prefix).
15
+ * - Slash references in prose pass through as `/gdd-<name>` — Kilo
16
+ * accepts the Claude-canonical slash shape via the
17
+ * `runtime-slash.cjs` map (rt: 'kilo' → `/gdd-`). Legacy colon and
18
+ * shell-variable forms are normalized to `/gdd-`.
19
+ * - Tool names in code fences pass through unchanged — per Phase 21
20
+ * verification, Kilo accepts the Claude vocabulary
21
+ * (Read/Write/Bash/Edit/Grep/Glob) natively. No tool-map rewrite.
22
+ * - A 1-line HTML adapter header is injected at the top of the body
23
+ * to record that this file was auto-generated from Claude source.
24
+ *
25
+ * Wave 4 layout note: Kilo uses the same `command/<name>.md` flat
26
+ * layout as OpenCode (its sibling Wave 4 runtime). The converter is
27
+ * structurally identical to opencode.cjs — only the runtime string
28
+ * and adapter-display label differ. Both runtimes share the XDG
29
+ * `command/` directory convention (singular `command`, not the
30
+ * Gemini-style `commands/gdd/` nested path).
31
+ *
32
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
33
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
34
+ * attribution. gsd-build's equivalent function is
35
+ * `convertClaudeCommandToKiloCommand` in bin/install.js; our modular
36
+ * factor delegates the actual rewrites to ./shared.cjs and follows
37
+ * the same uniform pattern as opencode / cursor / qwen.
38
+ *
39
+ * Pure / side-effect-free: no fs, no env, no path. `convert` is a
40
+ * deterministic string → string transform.
41
+ */
42
+
43
+ const shared = require('./shared.cjs');
44
+
45
+ /**
46
+ * Convert Claude-source SKILL.md content for the Kilo runtime.
47
+ *
48
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
49
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
50
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
51
+ * to `'kilo'`. Currently informational only.
52
+ * @returns {string}
53
+ */
54
+ function convert(content, skillName, opts) {
55
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
56
+ const fm = shared.buildFrontmatter(frontmatter, skillName, 'gdd-');
57
+ let out = shared.rewriteSlashRefs(body, 'kilo');
58
+ out = shared.ensureAdapterHeader(out, 'Kilo');
59
+ return fm + out;
60
+ }
61
+
62
+ module.exports = { convert };
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * scripts/lib/install/converters/opencode.cjs — Phase 28.7 (Plan 28.7-07).
5
+ *
6
+ * OpenCode command-file converter. Translates Claude-shape SKILL.md
7
+ * source into the command-format output OpenCode expects under its
8
+ * XDG `command/<name>.md` slash-command directory (see Phase 28.7
9
+ * D-05 + `runtime-artifact-layout.cjs#opencode`, which stages this
10
+ * converter via `commandsKind('command', 'gdd-', ...)`).
11
+ *
12
+ * Translation rules:
13
+ *
14
+ * - Frontmatter `name:` normalized to `gdd-<skill>` (no double-prefix).
15
+ * - Slash references in prose pass through as `/gdd-<name>` —
16
+ * OpenCode accepts the Claude-canonical slash shape via the
17
+ * `runtime-slash.cjs` map (rt: 'opencode' → `/gdd-`). Legacy
18
+ * colon and shell-variable forms are normalized to `/gdd-`.
19
+ * - Tool names in code fences pass through unchanged — per Phase 21
20
+ * verification, OpenCode accepts the Claude vocabulary
21
+ * (Read/Write/Bash/Edit/Grep/Glob) natively. No tool-map rewrite.
22
+ * - A 1-line HTML adapter header is injected at the top of the body
23
+ * to record that this file was auto-generated from Claude source.
24
+ *
25
+ * Command-format vs skills-format note: OpenCode is one of three Wave 4
26
+ * runtimes (alongside kilo + gemini) whose layout is a flat
27
+ * `command/<name>.md` file rather than the per-skill folder structure
28
+ * (`skills/<name>/SKILL.md`) used by Wave 1/2/3 runtimes. The converter
29
+ * itself does NOT know its destination directory — the destSubpath is
30
+ * encoded in `runtime-artifact-layout.cjs#commandsKind`. From the
31
+ * converter's perspective, the output is still a single markdown +
32
+ * YAML-frontmatter string; the installer routes it to the right path.
33
+ *
34
+ * Architecture ported from gsd-build/get-shit-done (MIT) — per Phase
35
+ * 28.7 D-02 (port architecture, not source). See NOTICE for upstream
36
+ * attribution. gsd-build's equivalent function is
37
+ * `convertClaudeCommandToOpenCodeCommand` in bin/install.js; our
38
+ * modular factor delegates the actual rewrites to ./shared.cjs and
39
+ * follows the same uniform pattern as cursor / qwen / copilot.
40
+ *
41
+ * Pure / side-effect-free: no fs, no env, no path. `convert` is a
42
+ * deterministic string → string transform.
43
+ */
44
+
45
+ const shared = require('./shared.cjs');
46
+
47
+ /**
48
+ * Convert Claude-source SKILL.md content for the OpenCode runtime.
49
+ *
50
+ * @param {string} content Full source SKILL.md content (frontmatter + body).
51
+ * @param {string} skillName The bare skill name (e.g. `'help'`, `'explore'`).
52
+ * @param {{ runtime?: string }} [opts] Optional context — `runtime` defaults
53
+ * to `'opencode'`. Currently informational only.
54
+ * @returns {string}
55
+ */
56
+ function convert(content, skillName, opts) {
57
+ const { frontmatter, body } = shared.extractFrontmatterAndBody(content);
58
+ const fm = shared.buildFrontmatter(frontmatter, skillName, 'gdd-');
59
+ let out = shared.rewriteSlashRefs(body, 'opencode');
60
+ out = shared.ensureAdapterHeader(out, 'OpenCode');
61
+ return fm + out;
62
+ }
63
+
64
+ module.exports = { convert };