gspec 1.18.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/bin/emitters.js +71 -12
- package/bin/gspec.js +69 -7
- package/commands/gspec.profile.md +4 -51
- package/dist/antigravity/gspec-analyze/SKILL.md +2 -2
- package/dist/antigravity/gspec-architect/SKILL.md +2 -2
- package/dist/antigravity/gspec-audit/SKILL.md +2 -2
- package/dist/antigravity/gspec-feature/SKILL.md +2 -2
- package/dist/antigravity/gspec-implement/SKILL.md +2 -2
- package/dist/antigravity/gspec-migrate/SKILL.md +2 -2
- package/dist/antigravity/gspec-plan/SKILL.md +2 -2
- package/dist/antigravity/gspec-practices/SKILL.md +2 -2
- package/dist/antigravity/gspec-profile/SKILL.md +6 -53
- package/dist/antigravity/gspec-research/SKILL.md +2 -2
- package/dist/antigravity/gspec-stack/SKILL.md +2 -2
- package/dist/antigravity/gspec-style/SKILL.md +2 -2
- package/dist/claude/gspec-analyze/SKILL.md +2 -2
- package/dist/claude/gspec-architect/SKILL.md +2 -2
- package/dist/claude/gspec-audit/SKILL.md +2 -2
- package/dist/claude/gspec-feature/SKILL.md +2 -2
- package/dist/claude/gspec-implement/SKILL.md +2 -2
- package/dist/claude/gspec-migrate/SKILL.md +2 -2
- package/dist/claude/gspec-plan/SKILL.md +2 -2
- package/dist/claude/gspec-practices/SKILL.md +2 -2
- package/dist/claude/gspec-profile/SKILL.md +6 -53
- package/dist/claude/gspec-research/SKILL.md +2 -2
- package/dist/claude/gspec-stack/SKILL.md +2 -2
- package/dist/claude/gspec-style/SKILL.md +2 -2
- package/dist/codex/gspec-analyze/SKILL.md +2 -2
- package/dist/codex/gspec-architect/SKILL.md +2 -2
- package/dist/codex/gspec-audit/SKILL.md +2 -2
- package/dist/codex/gspec-feature/SKILL.md +2 -2
- package/dist/codex/gspec-implement/SKILL.md +2 -2
- package/dist/codex/gspec-migrate/SKILL.md +2 -2
- package/dist/codex/gspec-plan/SKILL.md +2 -2
- package/dist/codex/gspec-practices/SKILL.md +2 -2
- package/dist/codex/gspec-profile/SKILL.md +6 -53
- package/dist/codex/gspec-research/SKILL.md +2 -2
- package/dist/codex/gspec-stack/SKILL.md +2 -2
- package/dist/codex/gspec-style/SKILL.md +2 -2
- package/dist/cursor/gspec-analyze.mdc +1 -1
- package/dist/cursor/gspec-architect.mdc +1 -1
- package/dist/cursor/gspec-audit.mdc +1 -1
- package/dist/cursor/gspec-feature.mdc +1 -1
- package/dist/cursor/gspec-implement.mdc +1 -1
- package/dist/cursor/gspec-migrate.mdc +1 -1
- package/dist/cursor/gspec-plan.mdc +1 -1
- package/dist/cursor/gspec-practices.mdc +1 -1
- package/dist/cursor/gspec-profile.mdc +5 -52
- package/dist/cursor/gspec-research.mdc +1 -1
- package/dist/cursor/gspec-stack.mdc +1 -1
- package/dist/cursor/gspec-style.mdc +1 -1
- package/dist/opencode/commands/gspec-analyze.md +253 -0
- package/dist/opencode/commands/gspec-architect.md +363 -0
- package/dist/opencode/commands/gspec-audit.md +281 -0
- package/dist/opencode/commands/gspec-feature.md +214 -0
- package/dist/opencode/commands/gspec-implement.md +229 -0
- package/dist/opencode/commands/gspec-migrate.md +142 -0
- package/dist/opencode/commands/gspec-plan.md +156 -0
- package/dist/opencode/commands/gspec-practices.md +137 -0
- package/dist/opencode/commands/gspec-profile.md +194 -0
- package/dist/opencode/commands/gspec-research.md +303 -0
- package/dist/opencode/commands/gspec-stack.md +301 -0
- package/dist/opencode/commands/gspec-style.md +276 -0
- package/dist/opencode/{gspec-analyze → skills/gspec-analyze}/SKILL.md +2 -2
- package/dist/opencode/{gspec-architect → skills/gspec-architect}/SKILL.md +2 -2
- package/dist/opencode/{gspec-audit → skills/gspec-audit}/SKILL.md +2 -2
- package/dist/opencode/{gspec-feature → skills/gspec-feature}/SKILL.md +2 -2
- package/dist/opencode/{gspec-implement → skills/gspec-implement}/SKILL.md +2 -2
- package/dist/opencode/{gspec-migrate → skills/gspec-migrate}/SKILL.md +2 -2
- package/dist/opencode/{gspec-plan → skills/gspec-plan}/SKILL.md +2 -2
- package/dist/opencode/{gspec-practices → skills/gspec-practices}/SKILL.md +2 -2
- package/dist/opencode/{gspec-profile → skills/gspec-profile}/SKILL.md +6 -53
- package/dist/opencode/{gspec-research → skills/gspec-research}/SKILL.md +2 -2
- package/dist/opencode/{gspec-stack → skills/gspec-stack}/SKILL.md +2 -2
- package/dist/opencode/{gspec-style → skills/gspec-style}/SKILL.md +2 -2
- package/dist/pi/prompts/gspec-analyze.md +253 -0
- package/dist/pi/prompts/gspec-architect.md +363 -0
- package/dist/pi/prompts/gspec-audit.md +281 -0
- package/dist/pi/prompts/gspec-feature.md +214 -0
- package/dist/pi/prompts/gspec-implement.md +229 -0
- package/dist/pi/prompts/gspec-migrate.md +142 -0
- package/dist/pi/prompts/gspec-plan.md +156 -0
- package/dist/pi/prompts/gspec-practices.md +137 -0
- package/dist/pi/prompts/gspec-profile.md +194 -0
- package/dist/pi/prompts/gspec-research.md +303 -0
- package/dist/pi/prompts/gspec-stack.md +301 -0
- package/dist/pi/prompts/gspec-style.md +276 -0
- package/dist/pi/skills/gspec-analyze/SKILL.md +253 -0
- package/dist/pi/skills/gspec-architect/SKILL.md +363 -0
- package/dist/pi/skills/gspec-audit/SKILL.md +281 -0
- package/dist/pi/skills/gspec-feature/SKILL.md +214 -0
- package/dist/pi/skills/gspec-implement/SKILL.md +230 -0
- package/dist/pi/skills/gspec-migrate/SKILL.md +142 -0
- package/dist/pi/skills/gspec-plan/SKILL.md +156 -0
- package/dist/pi/skills/gspec-practices/SKILL.md +137 -0
- package/dist/pi/skills/gspec-profile/SKILL.md +194 -0
- package/dist/pi/skills/gspec-research/SKILL.md +303 -0
- package/dist/pi/skills/gspec-stack/SKILL.md +301 -0
- package/dist/pi/skills/gspec-style/SKILL.md +276 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -165,7 +165,8 @@ The CLI will ask which platform you're installing for:
|
|
|
165
165
|
| Cursor | `.cursor/commands/` |
|
|
166
166
|
| Antigravity | `.agent/skills/` |
|
|
167
167
|
| Codex | `.agents/skills/` |
|
|
168
|
-
| Open Code | `.opencode/skills/` |
|
|
168
|
+
| Open Code | `.opencode/commands/` + `.opencode/skills/` |
|
|
169
|
+
| Pi | `.pi/prompts/` + `.pi/skills/` |
|
|
169
170
|
|
|
170
171
|
You can skip the prompt by passing a target directly:
|
|
171
172
|
|
|
@@ -175,6 +176,7 @@ npx gspec --target cursor
|
|
|
175
176
|
npx gspec --target antigravity
|
|
176
177
|
npx gspec --target codex
|
|
177
178
|
npx gspec --target opencode
|
|
179
|
+
npx gspec --target pi
|
|
178
180
|
```
|
|
179
181
|
|
|
180
182
|
That's it. The commands are immediately available in your AI tool.
|
|
@@ -257,7 +259,8 @@ Most specs are Markdown. The style guide can also be a self-contained HTML file
|
|
|
257
259
|
| [Cursor](https://www.cursor.com/) | Commands format | Supported |
|
|
258
260
|
| [Antigravity](https://www.antigravity.dev/) | Skills format | Supported |
|
|
259
261
|
| [Codex](https://developers.openai.com/codex/cli/) | Skills format | Supported |
|
|
260
|
-
| [Open Code](https://opencode.ai/) |
|
|
262
|
+
| [Open Code](https://opencode.ai/) | Commands + skills | Supported |
|
|
263
|
+
| [Pi](https://pi.dev/) | Prompts + skills | Supported |
|
|
261
264
|
|
|
262
265
|
## Project Status
|
|
263
266
|
|
package/bin/emitters.js
CHANGED
|
@@ -4,15 +4,57 @@ import { join } from 'node:path';
|
|
|
4
4
|
// Placeholder pattern used in generic command files
|
|
5
5
|
export const PLACEHOLDER_RE = /<<<\w+>>>/g;
|
|
6
6
|
|
|
7
|
+
// Emit a YAML scalar safely. Skill descriptions contain ": ", embedded "…"
|
|
8
|
+
// examples, and other characters that break unquoted plain scalars, so every
|
|
9
|
+
// value goes out as a double-quoted scalar with the minimal escape set
|
|
10
|
+
// required by the YAML 1.2 spec (backslash, double-quote, and control chars).
|
|
11
|
+
function yamlScalar(value) {
|
|
12
|
+
const str = String(value);
|
|
13
|
+
const escaped = str
|
|
14
|
+
.replace(/\\/g, '\\\\')
|
|
15
|
+
.replace(/"/g, '\\"')
|
|
16
|
+
.replace(/\r/g, '\\r')
|
|
17
|
+
.replace(/\n/g, '\\n')
|
|
18
|
+
.replace(/\t/g, '\\t');
|
|
19
|
+
return `"${escaped}"`;
|
|
20
|
+
}
|
|
21
|
+
|
|
7
22
|
export function buildFrontmatter(fields) {
|
|
8
23
|
const lines = ['---'];
|
|
9
24
|
for (const [key, value] of Object.entries(fields)) {
|
|
10
|
-
lines.push(`${key}: ${value}`);
|
|
25
|
+
lines.push(`${key}: ${yamlScalar(value)}`);
|
|
11
26
|
}
|
|
12
27
|
lines.push('---');
|
|
13
28
|
return lines.join('\n');
|
|
14
29
|
}
|
|
15
30
|
|
|
31
|
+
// Dual emission shared by targets that split Claude Code's skill behavior across
|
|
32
|
+
// two mechanisms: a slash command the user invokes (/gspec-*) and a skill the
|
|
33
|
+
// agent auto-loads by description. Each prompt ships twice. Targets differ only
|
|
34
|
+
// in where the command file lives (`commandsSubdir`); the skill always lands in
|
|
35
|
+
// `skills/<name>/SKILL.md`.
|
|
36
|
+
async function emitDual(outDir, content, meta, commandsSubdir) {
|
|
37
|
+
// Command files support $ARGUMENTS substitution, same as Claude Code.
|
|
38
|
+
const commandFrontmatter = buildFrontmatter({
|
|
39
|
+
description: meta.description,
|
|
40
|
+
});
|
|
41
|
+
const commandBody = content.replace(PLACEHOLDER_RE, '$ARGUMENTS');
|
|
42
|
+
const commandsDir = join(outDir, commandsSubdir);
|
|
43
|
+
await mkdir(commandsDir, { recursive: true });
|
|
44
|
+
await writeFile(join(commandsDir, `${meta.name}.md`), commandFrontmatter + '\n\n' + commandBody, 'utf-8');
|
|
45
|
+
|
|
46
|
+
// Skill content is loaded as context, not expanded as a template, so strip
|
|
47
|
+
// the placeholder lines rather than mapping them to $ARGUMENTS.
|
|
48
|
+
const skillFrontmatter = buildFrontmatter({
|
|
49
|
+
name: meta.name,
|
|
50
|
+
description: meta.description,
|
|
51
|
+
});
|
|
52
|
+
const skillBody = content.replace(/^.*<<<\w+>>>.*$\n?/gm, '');
|
|
53
|
+
const skillDir = join(outDir, 'skills', meta.name);
|
|
54
|
+
await mkdir(skillDir, { recursive: true });
|
|
55
|
+
await writeFile(join(skillDir, 'SKILL.md'), skillFrontmatter + '\n\n' + skillBody, 'utf-8');
|
|
56
|
+
}
|
|
57
|
+
|
|
16
58
|
// Platform target definitions: how to emit a skill file for each AI tool.
|
|
17
59
|
// Used by both `scripts/build.js` (writing to dist/) and `bin/gspec.js`
|
|
18
60
|
// (writing user-installed extensions directly to a project's install dir).
|
|
@@ -39,6 +81,7 @@ export const TARGETS = {
|
|
|
39
81
|
distSubdir: 'cursor',
|
|
40
82
|
installDir: '.cursor/commands',
|
|
41
83
|
layout: 'flat',
|
|
84
|
+
fileExt: '.mdc',
|
|
42
85
|
// .cursor/commands/<name>.mdc (flat file)
|
|
43
86
|
async emit(outDir, content, meta) {
|
|
44
87
|
const frontmatter = buildFrontmatter({
|
|
@@ -87,18 +130,34 @@ export const TARGETS = {
|
|
|
87
130
|
opencode: {
|
|
88
131
|
label: 'Open Code',
|
|
89
132
|
distSubdir: 'opencode',
|
|
90
|
-
installDir: '.opencode
|
|
91
|
-
layout: '
|
|
92
|
-
|
|
133
|
+
installDir: '.opencode',
|
|
134
|
+
layout: 'dual',
|
|
135
|
+
fileExt: '.md',
|
|
136
|
+
commandsSubdir: 'commands',
|
|
137
|
+
// opencode splits skill behavior across two mechanisms:
|
|
138
|
+
// .opencode/commands/<name>.md slash command the user invokes (/gspec-*)
|
|
139
|
+
// .opencode/skills/<name>/SKILL.md skill the agent auto-loads by description
|
|
140
|
+
// On a name collision opencode's slash menu prefers the file command, so
|
|
141
|
+
// both can coexist safely.
|
|
93
142
|
async emit(outDir, content, meta) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
143
|
+
await emitDual(outDir, content, meta, this.commandsSubdir);
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
pi: {
|
|
147
|
+
label: 'Pi',
|
|
148
|
+
distSubdir: 'pi',
|
|
149
|
+
installDir: '.pi',
|
|
150
|
+
layout: 'dual',
|
|
151
|
+
fileExt: '.md',
|
|
152
|
+
commandsSubdir: 'prompts',
|
|
153
|
+
// Pi mirrors opencode's dual model but names the command directory
|
|
154
|
+
// differently:
|
|
155
|
+
// .pi/prompts/<name>.md prompt template the user invokes (/gspec-*)
|
|
156
|
+
// .pi/skills/<name>/SKILL.md skill the agent auto-loads by description
|
|
157
|
+
// Pi prompt templates expand shell-style placeholders ($ARGUMENTS / $@),
|
|
158
|
+
// so the same $ARGUMENTS substitution Claude Code uses applies here.
|
|
159
|
+
async emit(outDir, content, meta) {
|
|
160
|
+
await emitDual(outDir, content, meta, this.commandsSubdir);
|
|
102
161
|
},
|
|
103
162
|
},
|
|
104
163
|
};
|
package/bin/gspec.js
CHANGED
|
@@ -51,6 +51,7 @@ const TARGET_CHOICES = [
|
|
|
51
51
|
{ key: '3', name: 'antigravity', label: 'Antigravity' },
|
|
52
52
|
{ key: '4', name: 'codex', label: 'Codex' },
|
|
53
53
|
{ key: '5', name: 'opencode', label: 'Open Code' },
|
|
54
|
+
{ key: '6', name: 'pi', label: 'Pi' },
|
|
54
55
|
];
|
|
55
56
|
|
|
56
57
|
function promptTarget() {
|
|
@@ -63,7 +64,7 @@ function promptTarget() {
|
|
|
63
64
|
console.log();
|
|
64
65
|
|
|
65
66
|
return new Promise((resolve) => {
|
|
66
|
-
rl.question(chalk.bold(' Select [1-
|
|
67
|
+
rl.question(chalk.bold(' Select [1-6]: '), (answer) => {
|
|
67
68
|
rl.close();
|
|
68
69
|
const trimmed = answer.trim().toLowerCase();
|
|
69
70
|
|
|
@@ -76,7 +77,7 @@ function promptTarget() {
|
|
|
76
77
|
if (byName) return resolve(byName.name);
|
|
77
78
|
|
|
78
79
|
console.error(chalk.red(`\nInvalid selection: "${answer.trim()}"`));
|
|
79
|
-
console.error(`Valid options: 1, 2, 3, 4, 5, claude, cursor, antigravity, codex, opencode`);
|
|
80
|
+
console.error(`Valid options: 1, 2, 3, 4, 5, 6, claude, cursor, antigravity, codex, opencode, pi`);
|
|
80
81
|
process.exit(1);
|
|
81
82
|
});
|
|
82
83
|
});
|
|
@@ -353,7 +354,7 @@ async function findExistingFiles(target, cwd) {
|
|
|
353
354
|
|
|
354
355
|
if (target.layout === 'flat') {
|
|
355
356
|
const srcEntries = await readdir(target.sourceDir);
|
|
356
|
-
for (const file of srcEntries.filter(f => f.endsWith(
|
|
357
|
+
for (const file of srcEntries.filter(f => f.endsWith(target.fileExt))) {
|
|
357
358
|
try {
|
|
358
359
|
await stat(join(destBase, file));
|
|
359
360
|
existing.push(file);
|
|
@@ -361,6 +362,28 @@ async function findExistingFiles(target, cwd) {
|
|
|
361
362
|
if (e.code !== 'ENOENT') throw e;
|
|
362
363
|
}
|
|
363
364
|
}
|
|
365
|
+
} else if (target.layout === 'dual') {
|
|
366
|
+
const commandsSubdir = target.commandsSubdir;
|
|
367
|
+
const commandFiles = await readdir(join(target.sourceDir, commandsSubdir));
|
|
368
|
+
for (const file of commandFiles.filter(f => f.endsWith(target.fileExt))) {
|
|
369
|
+
try {
|
|
370
|
+
await stat(join(destBase, commandsSubdir, file));
|
|
371
|
+
existing.push(`${commandsSubdir}/${file}`);
|
|
372
|
+
} catch (e) {
|
|
373
|
+
if (e.code !== 'ENOENT') throw e;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const skillEntries = await readdir(join(target.sourceDir, 'skills'));
|
|
377
|
+
for (const entry of skillEntries) {
|
|
378
|
+
const info = await stat(join(target.sourceDir, 'skills', entry));
|
|
379
|
+
if (!info.isDirectory()) continue;
|
|
380
|
+
try {
|
|
381
|
+
await stat(join(destBase, 'skills', entry, 'SKILL.md'));
|
|
382
|
+
existing.push(`skills/${entry}/SKILL.md`);
|
|
383
|
+
} catch (e) {
|
|
384
|
+
if (e.code !== 'ENOENT') throw e;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
364
387
|
} else {
|
|
365
388
|
const srcEntries = await readdir(target.sourceDir);
|
|
366
389
|
for (const entry of srcEntries) {
|
|
@@ -398,16 +421,45 @@ async function installDirectory(target, cwd) {
|
|
|
398
421
|
return skills.length;
|
|
399
422
|
}
|
|
400
423
|
|
|
424
|
+
async function installDual(target, cwd) {
|
|
425
|
+
const commandsSubdir = target.commandsSubdir;
|
|
426
|
+
const commandsSrc = join(target.sourceDir, commandsSubdir);
|
|
427
|
+
const commandsDest = join(cwd, target.installDir, commandsSubdir);
|
|
428
|
+
await mkdir(commandsDest, { recursive: true });
|
|
429
|
+
const commandFiles = (await readdir(commandsSrc)).filter(f => f.endsWith(target.fileExt));
|
|
430
|
+
for (const file of commandFiles) {
|
|
431
|
+
const content = await readFile(join(commandsSrc, file), 'utf-8');
|
|
432
|
+
await writeFile(join(commandsDest, file), content, 'utf-8');
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const skillsSrc = join(target.sourceDir, 'skills');
|
|
436
|
+
const entries = await readdir(skillsSrc);
|
|
437
|
+
const skills = [];
|
|
438
|
+
for (const entry of entries) {
|
|
439
|
+
const info = await stat(join(skillsSrc, entry));
|
|
440
|
+
if (info.isDirectory()) skills.push(entry);
|
|
441
|
+
}
|
|
442
|
+
for (const skill of skills) {
|
|
443
|
+
const destDir = join(cwd, target.installDir, 'skills', skill);
|
|
444
|
+
await mkdir(destDir, { recursive: true });
|
|
445
|
+
const content = await readFile(join(skillsSrc, skill, 'SKILL.md'), 'utf-8');
|
|
446
|
+
await writeFile(join(destDir, 'SKILL.md'), content, 'utf-8');
|
|
447
|
+
console.log(` ${chalk.green('+')} ${skill} ${chalk.dim('(command + skill)')}`);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return skills.length;
|
|
451
|
+
}
|
|
452
|
+
|
|
401
453
|
async function installFlat(target, cwd) {
|
|
402
454
|
const entries = await readdir(target.sourceDir);
|
|
403
|
-
const files = entries.filter(f => f.endsWith(
|
|
455
|
+
const files = entries.filter(f => f.endsWith(target.fileExt));
|
|
404
456
|
const destDir = join(cwd, target.installDir);
|
|
405
457
|
await mkdir(destDir, { recursive: true });
|
|
406
458
|
|
|
407
459
|
for (const file of files) {
|
|
408
460
|
const content = await readFile(join(target.sourceDir, file), 'utf-8');
|
|
409
461
|
await writeFile(join(destDir, file), content, 'utf-8');
|
|
410
|
-
const name = file.
|
|
462
|
+
const name = file.slice(0, -target.fileExt.length);
|
|
411
463
|
console.log(` ${chalk.green('+')} ${name}`);
|
|
412
464
|
}
|
|
413
465
|
|
|
@@ -454,7 +506,9 @@ async function install(targetName, cwd) {
|
|
|
454
506
|
|
|
455
507
|
const count = target.layout === 'flat'
|
|
456
508
|
? await installFlat(target, cwd)
|
|
457
|
-
:
|
|
509
|
+
: target.layout === 'dual'
|
|
510
|
+
? await installDual(target, cwd)
|
|
511
|
+
: await installDirectory(target, cwd);
|
|
458
512
|
|
|
459
513
|
console.log(chalk.bold(`\n${count} skills installed to ${target.installDir}/\n`));
|
|
460
514
|
|
|
@@ -493,6 +547,13 @@ const SPEC_SYNC = {
|
|
|
493
547
|
mode: 'append',
|
|
494
548
|
wrap: (content) => content,
|
|
495
549
|
},
|
|
550
|
+
pi: {
|
|
551
|
+
// Pi loads project instructions from AGENTS.md in the current directory
|
|
552
|
+
// (concatenated with ~/.pi/agent/AGENTS.md and any parents).
|
|
553
|
+
file: 'AGENTS.md',
|
|
554
|
+
mode: 'append',
|
|
555
|
+
wrap: (content) => content,
|
|
556
|
+
},
|
|
496
557
|
};
|
|
497
558
|
|
|
498
559
|
const GSPEC_SECTION_MARKER = '<!-- gspec:spec-sync -->';
|
|
@@ -549,6 +610,7 @@ const MIGRATE_COMMANDS = {
|
|
|
549
610
|
antigravity: '/gspec-migrate',
|
|
550
611
|
codex: '/gspec-migrate',
|
|
551
612
|
opencode: '/gspec-migrate',
|
|
613
|
+
pi: '/gspec-migrate',
|
|
552
614
|
};
|
|
553
615
|
|
|
554
616
|
function parseSpecVersion(content) {
|
|
@@ -1369,7 +1431,7 @@ program
|
|
|
1369
1431
|
.name('gspec')
|
|
1370
1432
|
.description('Install gspec specification commands')
|
|
1371
1433
|
.version(pkg.version)
|
|
1372
|
-
.option('-t, --target <target>', 'target platform (claude, cursor, antigravity, codex, opencode)')
|
|
1434
|
+
.option('-t, --target <target>', 'target platform (claude, cursor, antigravity, codex, opencode, pi)')
|
|
1373
1435
|
.action(async (opts) => {
|
|
1374
1436
|
console.log(BANNER);
|
|
1375
1437
|
|
|
@@ -31,7 +31,6 @@ You should:
|
|
|
31
31
|
- The product type is ambiguous
|
|
32
32
|
- The target audience or user is unclear
|
|
33
33
|
- The core value proposition is ambiguous
|
|
34
|
-
- *(Commercial products only)* The business model or monetization strategy is unspecified
|
|
35
34
|
- *(Commercial products only)* Competitive positioning is unknown
|
|
36
35
|
- **When asking questions**, offer 2-3 specific suggestions to guide the discussion
|
|
37
36
|
- Write for the audience the product actually has (internal stakeholders, end users, contributors, the public, etc.)
|
|
@@ -39,6 +38,7 @@ You should:
|
|
|
39
38
|
- Focus on the "what" and "why", not the "how"
|
|
40
39
|
- Use clear, jargon-free language where possible
|
|
41
40
|
- **Mark sections as "Not Applicable"** when they don't apply to this product, and briefly note why (e.g., "Not applicable — internal tool, no external market"). Do not fabricate content to fill a section.
|
|
41
|
+
- **Do not include business model, pricing, or success metrics sections** unless the user explicitly asks for them — those are go-to-market concerns, not product identity.
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -124,23 +124,7 @@ You should:
|
|
|
124
124
|
- Indirect competitors, alternatives, or incumbent approaches
|
|
125
125
|
- White space or gaps this product fills
|
|
126
126
|
|
|
127
|
-
### 8.
|
|
128
|
-
|
|
129
|
-
*Skip or mark "Not Applicable" for non-commercial products (internal tools, open source, personal projects, research). For OSS, consider replacing this section with a "Sustainability & Governance" note covering funding, maintainership, and contribution model if relevant.*
|
|
130
|
-
|
|
131
|
-
#### Revenue Model
|
|
132
|
-
- How the product makes money (subscription, transaction fees, freemium, ads, etc.)
|
|
133
|
-
- Pricing strategy (high-level)
|
|
134
|
-
|
|
135
|
-
#### Customer Acquisition
|
|
136
|
-
- How customers discover and adopt the product
|
|
137
|
-
- Key channels
|
|
138
|
-
|
|
139
|
-
#### Growth Strategy
|
|
140
|
-
- How the product plans to scale
|
|
141
|
-
- Expansion opportunities
|
|
142
|
-
|
|
143
|
-
### 9. Brand & Positioning
|
|
127
|
+
### 8. Brand & Positioning
|
|
144
128
|
|
|
145
129
|
*Skip or simplify for internal tools and products with no external-facing presence. Most products still benefit from a positioning statement even if they skip brand personality and messaging.*
|
|
146
130
|
|
|
@@ -155,24 +139,7 @@ You should:
|
|
|
155
139
|
- Core messages to communicate consistently
|
|
156
140
|
- Elevator pitch
|
|
157
141
|
|
|
158
|
-
###
|
|
159
|
-
|
|
160
|
-
*Adapt to the product type. Always include user/adoption metrics if meaningful. Include business metrics only for commercial products.*
|
|
161
|
-
|
|
162
|
-
#### Adoption & Engagement Metrics
|
|
163
|
-
- Adoption or usage rates (installs, active users, repo stars, internal rollout percentage, etc.)
|
|
164
|
-
- Engagement metrics appropriate to the product
|
|
165
|
-
- User satisfaction (NPS, CSAT, contributor sentiment, internal feedback, etc.)
|
|
166
|
-
|
|
167
|
-
#### Business Metrics *(commercial products only)*
|
|
168
|
-
- Revenue targets
|
|
169
|
-
- Paid user growth goals
|
|
170
|
-
- Market share objectives
|
|
171
|
-
|
|
172
|
-
#### Project Health Metrics *(optional, especially for OSS / internal tools)*
|
|
173
|
-
- Contributor count, issue response time, release cadence, uptime, etc.
|
|
174
|
-
|
|
175
|
-
### 11. Public-Facing Information (Optional)
|
|
142
|
+
### 9. Public-Facing Information (Optional)
|
|
176
143
|
|
|
177
144
|
*Skip entirely for internal tools, private projects, or anything without a public presence.*
|
|
178
145
|
|
|
@@ -191,21 +158,7 @@ You should:
|
|
|
191
158
|
- Media kit essentials
|
|
192
159
|
- Key talking points
|
|
193
160
|
|
|
194
|
-
###
|
|
195
|
-
|
|
196
|
-
#### Current Focus
|
|
197
|
-
- What's being built now
|
|
198
|
-
- Immediate priorities
|
|
199
|
-
|
|
200
|
-
#### Near-Term (Next)
|
|
201
|
-
- Planned enhancements
|
|
202
|
-
- Next major milestones
|
|
203
|
-
|
|
204
|
-
#### Long-Term Vision (Later)
|
|
205
|
-
- Future capabilities
|
|
206
|
-
- Strategic direction
|
|
207
|
-
|
|
208
|
-
### 13. Risks & Assumptions
|
|
161
|
+
### 10. Risks & Assumptions
|
|
209
162
|
|
|
210
163
|
#### Key Assumptions
|
|
211
164
|
- What we believe to be true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-analyze
|
|
3
|
-
description: Analyze gspec/
|
|
2
|
+
name: "gspec-analyze"
|
|
3
|
+
description: "Analyze gspec/ for cross-spec contradictions across profile, stack, style, practices, architecture, features. With a feature slug, narrows to that PRD plus an ambiguity sweep. TRIGGER to cross-check or reconcile specs, or find gaps in a PRD."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Specification Analyst at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-architect
|
|
3
|
-
description: Define or update
|
|
2
|
+
name: "gspec-architect"
|
|
3
|
+
description: "Define or update gspec/architecture.md — project structure, data model, API design, component hierarchy, and environment/config. TRIGGER when the user wants to design or document codebase structure before implementation."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Senior Software Architect at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-audit
|
|
3
|
-
description: Audit gspec/
|
|
2
|
+
name: "gspec-audit"
|
|
3
|
+
description: "Audit gspec/ against the codebase to find drift, then reconcile each discrepancy. Detects orphan capabilities (features the code implements with no PRD). TRIGGER to check specs against code, sync with reality, or find unspecced features."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Specification Auditor at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-feature
|
|
3
|
-
description: Generate
|
|
2
|
+
name: "gspec-feature"
|
|
3
|
+
description: "Generate PRDs for features in gspec/features/. TRIGGER when the user wants to plan, spec, propose, or document a feature before coding — e.g. \"add a feature for X\", \"write a PRD\", \"spec out Y\", \"plan this feature\", \"draft requirements\"."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a senior Product Manager at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-implement
|
|
3
|
-
description: Implement
|
|
2
|
+
name: "gspec-implement"
|
|
3
|
+
description: "Implement software defined by gspec/ specs — phased build with tests and checkpoints. STRONGLY TRIGGER when the user asks to build, implement, code, scaffold, or ship specced work, or references an unchecked capability in gspec/features/*.md."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Senior Software Engineer and Tech Lead at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-migrate
|
|
3
|
-
description: Migrate gspec/ files to the current spec format
|
|
2
|
+
name: "gspec-migrate"
|
|
3
|
+
description: "Migrate gspec/ files to the current spec format when upgrading gspec. TRIGGER when the user sees an outdated-version warning or asks to upgrade specs — e.g. \"migrate my specs\", \"my specs are outdated\", \"fix the spec-version warning\"."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Technical Documentation Migration Specialist.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-plan
|
|
3
|
-
description: Decompose a feature PRD
|
|
2
|
+
name: "gspec-plan"
|
|
3
|
+
description: "Decompose a feature PRD into an ordered, dependency-aware plan with parallel-execution markers, written to <feature>.plan.md. Runs between gspec-feature and gspec-implement. TRIGGER when the user wants to sequence work or build a plan from a PRD."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Senior Engineering Lead at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-practices
|
|
3
|
-
description: Define or update
|
|
2
|
+
name: "gspec-practices"
|
|
3
|
+
description: "Define or update gspec/practices.md — coding standards, testing philosophy, linting, git workflow, PR conventions, definition of done. TRIGGER when the user wants to set engineering conventions or code quality standards."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Software Engineering Practice Lead at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-profile
|
|
3
|
-
description: Generate or update
|
|
2
|
+
name: "gspec-profile"
|
|
3
|
+
description: "Generate or update gspec/profile.md — what the product is, who it serves, and why. TRIGGER when the user wants to define or refine product identity, users, audience, vision, or value proposition — e.g. \"define my product\", \"what is this app\"."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Product Strategist.
|
|
@@ -36,7 +36,6 @@ You should:
|
|
|
36
36
|
- The product type is ambiguous
|
|
37
37
|
- The target audience or user is unclear
|
|
38
38
|
- The core value proposition is ambiguous
|
|
39
|
-
- *(Commercial products only)* The business model or monetization strategy is unspecified
|
|
40
39
|
- *(Commercial products only)* Competitive positioning is unknown
|
|
41
40
|
- **When asking questions**, offer 2-3 specific suggestions to guide the discussion
|
|
42
41
|
- Write for the audience the product actually has (internal stakeholders, end users, contributors, the public, etc.)
|
|
@@ -44,6 +43,7 @@ You should:
|
|
|
44
43
|
- Focus on the "what" and "why", not the "how"
|
|
45
44
|
- Use clear, jargon-free language where possible
|
|
46
45
|
- **Mark sections as "Not Applicable"** when they don't apply to this product, and briefly note why (e.g., "Not applicable — internal tool, no external market"). Do not fabricate content to fill a section.
|
|
46
|
+
- **Do not include business model, pricing, or success metrics sections** unless the user explicitly asks for them — those are go-to-market concerns, not product identity.
|
|
47
47
|
|
|
48
48
|
---
|
|
49
49
|
|
|
@@ -129,23 +129,7 @@ You should:
|
|
|
129
129
|
- Indirect competitors, alternatives, or incumbent approaches
|
|
130
130
|
- White space or gaps this product fills
|
|
131
131
|
|
|
132
|
-
### 8.
|
|
133
|
-
|
|
134
|
-
*Skip or mark "Not Applicable" for non-commercial products (internal tools, open source, personal projects, research). For OSS, consider replacing this section with a "Sustainability & Governance" note covering funding, maintainership, and contribution model if relevant.*
|
|
135
|
-
|
|
136
|
-
#### Revenue Model
|
|
137
|
-
- How the product makes money (subscription, transaction fees, freemium, ads, etc.)
|
|
138
|
-
- Pricing strategy (high-level)
|
|
139
|
-
|
|
140
|
-
#### Customer Acquisition
|
|
141
|
-
- How customers discover and adopt the product
|
|
142
|
-
- Key channels
|
|
143
|
-
|
|
144
|
-
#### Growth Strategy
|
|
145
|
-
- How the product plans to scale
|
|
146
|
-
- Expansion opportunities
|
|
147
|
-
|
|
148
|
-
### 9. Brand & Positioning
|
|
132
|
+
### 8. Brand & Positioning
|
|
149
133
|
|
|
150
134
|
*Skip or simplify for internal tools and products with no external-facing presence. Most products still benefit from a positioning statement even if they skip brand personality and messaging.*
|
|
151
135
|
|
|
@@ -160,24 +144,7 @@ You should:
|
|
|
160
144
|
- Core messages to communicate consistently
|
|
161
145
|
- Elevator pitch
|
|
162
146
|
|
|
163
|
-
###
|
|
164
|
-
|
|
165
|
-
*Adapt to the product type. Always include user/adoption metrics if meaningful. Include business metrics only for commercial products.*
|
|
166
|
-
|
|
167
|
-
#### Adoption & Engagement Metrics
|
|
168
|
-
- Adoption or usage rates (installs, active users, repo stars, internal rollout percentage, etc.)
|
|
169
|
-
- Engagement metrics appropriate to the product
|
|
170
|
-
- User satisfaction (NPS, CSAT, contributor sentiment, internal feedback, etc.)
|
|
171
|
-
|
|
172
|
-
#### Business Metrics *(commercial products only)*
|
|
173
|
-
- Revenue targets
|
|
174
|
-
- Paid user growth goals
|
|
175
|
-
- Market share objectives
|
|
176
|
-
|
|
177
|
-
#### Project Health Metrics *(optional, especially for OSS / internal tools)*
|
|
178
|
-
- Contributor count, issue response time, release cadence, uptime, etc.
|
|
179
|
-
|
|
180
|
-
### 11. Public-Facing Information (Optional)
|
|
147
|
+
### 9. Public-Facing Information (Optional)
|
|
181
148
|
|
|
182
149
|
*Skip entirely for internal tools, private projects, or anything without a public presence.*
|
|
183
150
|
|
|
@@ -196,21 +163,7 @@ You should:
|
|
|
196
163
|
- Media kit essentials
|
|
197
164
|
- Key talking points
|
|
198
165
|
|
|
199
|
-
###
|
|
200
|
-
|
|
201
|
-
#### Current Focus
|
|
202
|
-
- What's being built now
|
|
203
|
-
- Immediate priorities
|
|
204
|
-
|
|
205
|
-
#### Near-Term (Next)
|
|
206
|
-
- Planned enhancements
|
|
207
|
-
- Next major milestones
|
|
208
|
-
|
|
209
|
-
#### Long-Term Vision (Later)
|
|
210
|
-
- Future capabilities
|
|
211
|
-
- Strategic direction
|
|
212
|
-
|
|
213
|
-
### 13. Risks & Assumptions
|
|
166
|
+
### 10. Risks & Assumptions
|
|
214
167
|
|
|
215
168
|
#### Key Assumptions
|
|
216
169
|
- What we believe to be true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-research
|
|
3
|
-
description: Research competitors
|
|
2
|
+
name: "gspec-research"
|
|
3
|
+
description: "Research competitors from gspec/profile.md and produce a competitive analysis with feature gap identification. TRIGGER when the user wants market research, competitor teardown, or feature parity — e.g. \"research competitors\", \"find feature gaps\"."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Senior Product Strategist and Competitive Intelligence Analyst at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-stack
|
|
3
|
-
description: Define or update
|
|
2
|
+
name: "gspec-stack"
|
|
3
|
+
description: "Define or update gspec/stack.md — frameworks, libraries, databases, hosting, CI/CD, and infrastructure. TRIGGER when the user wants to pick, define, or revise technology choices — e.g. \"what stack should I use\", \"pick a framework\"."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Senior Software Architect at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-style
|
|
3
|
-
description: Generate or update the visual style guide
|
|
2
|
+
name: "gspec-style"
|
|
3
|
+
description: "Generate or update the visual style guide (gspec/style.html or gspec/style.md) — tokens, palette, typography, spacing, components. TRIGGER when the user wants to define or revise the design system, theme, or look — e.g. \"pick brand colors\"."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a senior UI/UX Designer and Design Systems Architect at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-analyze
|
|
3
|
-
description: Analyze gspec/
|
|
2
|
+
name: "gspec-analyze"
|
|
3
|
+
description: "Analyze gspec/ for cross-spec contradictions across profile, stack, style, practices, architecture, features. With a feature slug, narrows to that PRD plus an ambiguity sweep. TRIGGER to cross-check or reconcile specs, or find gaps in a PRD."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Specification Analyst at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-architect
|
|
3
|
-
description: Define or update
|
|
2
|
+
name: "gspec-architect"
|
|
3
|
+
description: "Define or update gspec/architecture.md — project structure, data model, API design, component hierarchy, and environment/config. TRIGGER when the user wants to design or document codebase structure before implementation."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Senior Software Architect at a high-performing software company.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: gspec-audit
|
|
3
|
-
description: Audit gspec/
|
|
2
|
+
name: "gspec-audit"
|
|
3
|
+
description: "Audit gspec/ against the codebase to find drift, then reconcile each discrepancy. Detects orphan capabilities (features the code implements with no PRD). TRIGGER to check specs against code, sync with reality, or find unspecced features."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You are a Specification Auditor at a high-performing software company.
|