@givolt/i3-composer-agent 2.0.0 → 2.1.1
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/.agents/plugins/marketplace.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +37 -33
- package/bin/agent-targets.json +11 -0
- package/bin/asset-fingerprint.cjs +38 -0
- package/bin/cleanup-backups.cjs +16 -0
- package/bin/i3-composer-agent.cjs +28 -12
- package/bin/install.cjs +74 -28
- package/bin/native-content.cjs +29 -0
- package/bin/wizard.cjs +3 -1
- package/docs/antigravity-setup.md +1 -1
- package/docs/codebuddy-setup.md +16 -3
- package/docs/cursor-setup.md +2 -2
- package/docs/getting-started.md +0 -2
- package/docs/opencode-setup.md +4 -4
- package/docs/workbuddy-setup.md +106 -0
- package/package.json +36 -20
- package/plugin.json +1 -1
- package/CHANGELOG.md +0 -51
- package/NOTICE.md +0 -15
- package/docs/advanced-per-agent-configuration.md +0 -70
- package/docs/comparison.md +0 -131
- package/docs/developer-onboarding.md +0 -116
- package/docs/skill-anatomy.md +0 -203
- package/evals/README.md +0 -101
- package/evals/cases/i3-api-and-interface-design.json +0 -45
- package/evals/cases/i3-browser-testing-with-devtools.json +0 -44
- package/evals/cases/i3-ci-cd-and-automation.json +0 -45
- package/evals/cases/i3-code-review-and-quality.json +0 -49
- package/evals/cases/i3-code-simplification.json +0 -45
- package/evals/cases/i3-constraint-driven-development.json +0 -79
- package/evals/cases/i3-context-engineering.json +0 -44
- package/evals/cases/i3-debugging-and-error-recovery.json +0 -58
- package/evals/cases/i3-deprecation-and-migration.json +0 -52
- package/evals/cases/i3-documentation-and-adrs.json +0 -44
- package/evals/cases/i3-doubt-driven-development.json +0 -43
- package/evals/cases/i3-frontend-ui-engineering.json +0 -52
- package/evals/cases/i3-git-workflow-and-versioning.json +0 -47
- package/evals/cases/i3-idea-refine.json +0 -43
- package/evals/cases/i3-incremental-implementation.json +0 -57
- package/evals/cases/i3-interview-me.json +0 -42
- package/evals/cases/i3-observability-and-instrumentation.json +0 -44
- package/evals/cases/i3-performance-optimization.json +0 -53
- package/evals/cases/i3-planning-and-task-breakdown.json +0 -45
- package/evals/cases/i3-security-and-hardening.json +0 -53
- package/evals/cases/i3-shipping-and-launch.json +0 -56
- package/evals/cases/i3-source-driven-development.json +0 -44
- package/evals/cases/i3-spec-driven-development.json +0 -72
- package/evals/cases/i3-test-driven-development.json +0 -73
- package/evals/cases/i3-using-agent-skills.json +0 -44
- package/evals/fixtures/i3-api-and-interface-design/service-brief.md +0 -19
- package/evals/fixtures/i3-browser-testing-with-devtools/README.md +0 -5
- package/evals/fixtures/i3-browser-testing-with-devtools/index.html +0 -24
- package/evals/fixtures/i3-browser-testing-with-devtools/server.js +0 -15
- package/evals/fixtures/i3-ci-cd-and-automation/package.json +0 -8
- package/evals/fixtures/i3-ci-cd-and-automation/src/slug.js +0 -3
- package/evals/fixtures/i3-ci-cd-and-automation/test/slug.test.js +0 -9
- package/evals/fixtures/i3-code-review-and-quality/user-search.diff +0 -16
- package/evals/fixtures/i3-code-simplification/config-parser.js +0 -46
- package/evals/fixtures/i3-code-simplification/config-parser.test.js +0 -15
- package/evals/fixtures/i3-context-engineering/context-audit.md +0 -15
- package/evals/fixtures/i3-debugging-and-error-recovery/pagination.js +0 -8
- package/evals/fixtures/i3-debugging-and-error-recovery/pagination.test.js +0 -9
- package/evals/fixtures/i3-debugging-and-error-recovery/time-pressure.md +0 -6
- package/evals/fixtures/i3-deprecation-and-migration/api-inventory.md +0 -9
- package/evals/fixtures/i3-documentation-and-adrs/decision-context.md +0 -16
- package/evals/fixtures/i3-doubt-driven-development/migration-plan.md +0 -19
- package/evals/fixtures/i3-frontend-ui-engineering/Button.tsx +0 -7
- package/evals/fixtures/i3-frontend-ui-engineering/design-system.md +0 -11
- package/evals/fixtures/i3-git-workflow-and-versioning/.eval/working-tree.patch +0 -21
- package/evals/fixtures/i3-git-workflow-and-versioning/app.js +0 -7
- package/evals/fixtures/i3-git-workflow-and-versioning/app.test.js +0 -9
- package/evals/fixtures/i3-incremental-implementation/reports.js +0 -7
- package/evals/fixtures/i3-incremental-implementation/reports.test.js +0 -12
- package/evals/fixtures/i3-incremental-implementation/tasks/plan.md +0 -8
- package/evals/fixtures/i3-observability-and-instrumentation/operations.md +0 -11
- package/evals/fixtures/i3-observability-and-instrumentation/payment-retry.js +0 -14
- package/evals/fixtures/i3-performance-optimization/benchmark.js +0 -15
- package/evals/fixtures/i3-performance-optimization/products.js +0 -14
- package/evals/fixtures/i3-planning-and-task-breakdown/notifications-spec.md +0 -18
- package/evals/fixtures/i3-security-and-hardening/webhook.js +0 -11
- package/evals/fixtures/i3-security-and-hardening/webhook.test.js +0 -13
- package/evals/fixtures/i3-shipping-and-launch/authority-pressure.md +0 -6
- package/evals/fixtures/i3-shipping-and-launch/launch-status.md +0 -11
- package/evals/fixtures/i3-source-driven-development/framework-task.md +0 -10
- package/evals/fixtures/i3-spec-driven-development/billing-brief.md +0 -16
- package/evals/fixtures/i3-test-driven-development/BUG.md +0 -10
- package/evals/fixtures/i3-test-driven-development/README.md +0 -28
- package/evals/fixtures/i3-test-driven-development/package.json +0 -9
- package/evals/fixtures/i3-test-driven-development/src/split.js +0 -8
- package/evals/fixtures/i3-test-driven-development/test/split.test.js +0 -13
- package/evals/fixtures/i3-using-agent-skills/incident.md +0 -6
- package/evals/fixtures/incremental-implementation-pressure/draft-export.js +0 -17
- package/evals/fixtures/incremental-implementation-pressure/scenario.md +0 -9
- package/evals/fixtures/spec-driven-development-decomposition/portal-brief.md +0 -22
- package/evals/fixtures/test-driven-development-ecosystem/README.md +0 -9
- package/evals/fixtures/test-driven-development-ecosystem/ledger.py +0 -15
- package/evals/fixtures/test-driven-development-ecosystem/test_ledger.py +0 -19
- package/evals/plugin/code-review-fires/graders/off-by-one.md +0 -7
- package/evals/plugin/code-review-fires/graders/severity-labels.md +0 -4
- package/evals/plugin/code-review-fires/graders/skill-fired.md +0 -5
- package/evals/plugin/code-review-fires/prompt.md +0 -31
- package/evals/plugin/code-review-stays-quiet/graders/not-fired.md +0 -8
- package/evals/plugin/code-review-stays-quiet/graders/tdd-fired.md +0 -6
- package/evals/plugin/code-review-stays-quiet/prompt.md +0 -8
- package/evals/plugin/code-review-stays-quiet-on-commit-message/graders/not-fired.md +0 -8
- package/evals/plugin/code-review-stays-quiet-on-commit-message/prompt.md +0 -25
- package/evals/skill-impact.md +0 -6
- package/rebrand/INSTALLATION-SPEC.md +0 -47
- package/rebrand/MAINTENANCE.md +0 -114
- package/rebrand/NOTICE.md +0 -15
- package/rebrand/PR-WORKFLOW.md +0 -34
- package/rebrand/PREFIX-SPEC.md +0 -16
- package/rebrand/UNIFICATION-SPEC.md +0 -33
- package/rebrand/VALIDATION.md +0 -32
- package/rebrand/VERSIONING.md +0 -35
- package/rebrand/apply.cjs +0 -217
- package/rebrand/brand.json +0 -13
- package/rebrand/catalog.cjs +0 -70
- package/rebrand/fork-patches.json +0 -27
- package/rebrand/identifiers.cjs +0 -41
- package/rebrand/overlay/.github/workflows/test-plugin-install.yml +0 -177
- package/rebrand/overlay/CHANGELOG.md +0 -51
- package/rebrand/overlay/bin/agent-targets.json +0 -726
- package/rebrand/overlay/bin/i3-composer-agent.cjs +0 -190
- package/rebrand/overlay/bin/install.cjs +0 -180
- package/rebrand/overlay/bin/skills-registry.LICENSE +0 -21
- package/rebrand/overlay/bin/wizard.cjs +0 -66
- package/rebrand/overlay/scripts/validate-brand.cjs +0 -44
- package/rebrand/overlay/tests/bundle.test.cjs +0 -85
- package/rebrand/overlay/tests/installer.test.cjs +0 -241
- package/rebrand/package.template.json +0 -82
- package/rebrand/rebrand.sh +0 -4
- package/rebrand/record-upstream.cjs +0 -37
- package/rebrand/templates/README.md +0 -130
- package/rebrand/templates/codebuddy-setup.md +0 -89
- package/rebrand/templates/codex-setup.md +0 -45
- package/rebrand/tests/pipeline.test.cjs +0 -253
- package/rebrand/upstream.json +0 -171
- package/scripts/floor-guard-reference-test.js +0 -291
- package/scripts/lib/skill-lint-test.js +0 -650
- package/scripts/lib/skill-lint.js +0 -586
- package/scripts/run-evals-test.js +0 -623
- package/scripts/run-evals.js +0 -638
- package/scripts/validate-artifact-paths-test.js +0 -179
- package/scripts/validate-artifact-paths.js +0 -130
- package/scripts/validate-brand.cjs +0 -44
- package/scripts/validate-commands-test.js +0 -216
- package/scripts/validate-commands.js +0 -223
- package/scripts/validate-reference-links-test.js +0 -495
- package/scripts/validate-reference-links.js +0 -187
- package/scripts/validate-skills.js +0 -69
- package/scripts/validate-versions-test.js +0 -32
- package/scripts/validate-versions.js +0 -35
- package/tests/bundle.test.cjs +0 -85
- package/tests/installer.test.cjs +0 -241
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* validate-commands.js
|
|
4
|
-
*
|
|
5
|
-
* Guards against silent drift across the three slash-command directories:
|
|
6
|
-
* .claude/commands/ (.md — Claude Code)
|
|
7
|
-
* .gemini/commands/ (.toml — Gemini CLI)
|
|
8
|
-
* commands/ (.toml — Antigravity CLI)
|
|
9
|
-
*
|
|
10
|
-
* Checks (errors block CI):
|
|
11
|
-
* - Every command present in one directory exists in all three
|
|
12
|
-
* - The 'description' field is identical across all three equivalents
|
|
13
|
-
* - Claude command frontmatter is valid YAML, not merely splittable
|
|
14
|
-
*
|
|
15
|
-
* What this does NOT check:
|
|
16
|
-
* Prompt body differences are intentional — each tool has its own
|
|
17
|
-
* syntax ($ARGUMENTS, i3-composer-agent: prefixes, GEMINI.md vs CLAUDE.md).
|
|
18
|
-
*
|
|
19
|
-
* Exit codes: 0 = all clear, 1 = one or more errors
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
'use strict';
|
|
23
|
-
|
|
24
|
-
const fs = require('fs');
|
|
25
|
-
const path = require('path');
|
|
26
|
-
|
|
27
|
-
// The same frontmatter-validity rules validate-skills applies to SKILL.md.
|
|
28
|
-
// `descriptionFromMd` below splits each line on its first colon, exactly as the
|
|
29
|
-
// skill reader used to, so a command whose frontmatter is not valid YAML passes
|
|
30
|
-
// every check here — and Claude Code parses that frontmatter when the command is
|
|
31
|
-
// loaded. The #494 thread verified all 25 SKILL.md files AND the command files by
|
|
32
|
-
// hand; this makes the second half a check too.
|
|
33
|
-
const { frontmatterYamlErrors } = require(path.join(__dirname, 'lib', 'skill-lint.js'));
|
|
34
|
-
|
|
35
|
-
// ─── Config ───────────────────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
-
const ROOT = path.resolve(__dirname, '..');
|
|
38
|
-
|
|
39
|
-
const DIRS = {
|
|
40
|
-
claude: { dir: path.join(ROOT, '.claude', 'commands'), ext: '.md' },
|
|
41
|
-
gemini: { dir: path.join(ROOT, '.gemini', 'commands'), ext: '.toml' },
|
|
42
|
-
antigravity:{ dir: path.join(ROOT, 'commands'), ext: '.toml' },
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
// Commands where the file stem differs between Claude and the TOML dirs.
|
|
46
|
-
// Key = Claude stem, value = TOML stem.
|
|
47
|
-
const NAME_MAP = {
|
|
48
|
-
plan: 'planning',
|
|
49
|
-
'i3-plan': 'i3-planning',
|
|
50
|
-
};
|
|
51
|
-
const NAME_MAP_REVERSE = Object.fromEntries(
|
|
52
|
-
Object.entries(NAME_MAP).map(([k, v]) => [v, k])
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
// ─── Parsers ──────────────────────────────────────────────────────────────────
|
|
56
|
-
|
|
57
|
-
function descriptionFromMd(filePath) {
|
|
58
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
59
|
-
const match = content.match(/^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*\r?\n/);
|
|
60
|
-
if (!match) return null;
|
|
61
|
-
for (const line of match[1].split(/\r?\n/)) {
|
|
62
|
-
const colonIdx = line.indexOf(':');
|
|
63
|
-
if (colonIdx === -1) continue;
|
|
64
|
-
if (line.slice(0, colonIdx).trim() === 'description') {
|
|
65
|
-
return line.slice(colonIdx + 1).trim().replace(/^['"]|['"]$/g, '');
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function descriptionFromToml(filePath) {
|
|
72
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
73
|
-
const doubleMatch = content.match(/^description\s*=\s*"((?:[^"\\]|\\.)*)"/m);
|
|
74
|
-
if (doubleMatch) return doubleMatch[1].replace(/\\"/g, '"');
|
|
75
|
-
const singleMatch = content.match(/^description\s*=\s*'([^']*)'/m);
|
|
76
|
-
return singleMatch ? singleMatch[1] : null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ─── Loader ───────────────────────────────────────────────────────────────────
|
|
80
|
-
|
|
81
|
-
function loadCommands({ dir, ext }) {
|
|
82
|
-
if (!fs.existsSync(dir)) return {};
|
|
83
|
-
return Object.fromEntries(
|
|
84
|
-
fs.readdirSync(dir)
|
|
85
|
-
.filter(f => f.endsWith(ext))
|
|
86
|
-
.map(f => {
|
|
87
|
-
const stem = path.basename(f, ext);
|
|
88
|
-
const full = path.join(dir, f);
|
|
89
|
-
try {
|
|
90
|
-
const desc = ext === '.md' ? descriptionFromMd(full) : descriptionFromToml(full);
|
|
91
|
-
return [stem, desc];
|
|
92
|
-
} catch (e) {
|
|
93
|
-
console.log(` ✗ ${stem} — cannot read file: ${e.message}`);
|
|
94
|
-
return [stem, null];
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// ─── Main ─────────────────────────────────────────────────────────────────────
|
|
101
|
-
|
|
102
|
-
function main() {
|
|
103
|
-
const byTool = {
|
|
104
|
-
claude: loadCommands(DIRS.claude),
|
|
105
|
-
gemini: loadCommands(DIRS.gemini),
|
|
106
|
-
antigravity: loadCommands(DIRS.antigravity),
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
// Canonical command list: use Claude stems as the reference.
|
|
110
|
-
// Map each Claude stem to its TOML equivalent for lookup.
|
|
111
|
-
const claudeStems = Object.keys(byTool.claude).sort();
|
|
112
|
-
const allTomlStems = new Set([
|
|
113
|
-
...Object.keys(byTool.gemini),
|
|
114
|
-
...Object.keys(byTool.antigravity),
|
|
115
|
-
]);
|
|
116
|
-
const allCanonicalStems = new Set([
|
|
117
|
-
...claudeStems,
|
|
118
|
-
...[...allTomlStems].map(s => NAME_MAP_REVERSE[s] ?? s),
|
|
119
|
-
]);
|
|
120
|
-
|
|
121
|
-
let errors = 0;
|
|
122
|
-
|
|
123
|
-
// ── Parity check ────────────────────────────────────────────────────────────
|
|
124
|
-
console.log('Checking command parity...');
|
|
125
|
-
|
|
126
|
-
// Commands in Claude not found in TOML dirs
|
|
127
|
-
for (const stem of claudeStems) {
|
|
128
|
-
const tomlStem = NAME_MAP[stem] ?? stem;
|
|
129
|
-
const missing = [];
|
|
130
|
-
if (!(tomlStem in byTool.gemini)) missing.push('.gemini/commands');
|
|
131
|
-
if (!(tomlStem in byTool.antigravity)) missing.push('commands');
|
|
132
|
-
if (missing.length) {
|
|
133
|
-
console.log(` ✗ ${stem} — missing in: ${missing.join(', ')}`);
|
|
134
|
-
errors++;
|
|
135
|
-
} else {
|
|
136
|
-
console.log(` ✓ ${stem}${stem !== tomlStem ? ` (${tomlStem} in toml dirs)` : ''}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Commands in TOML dirs not found in Claude
|
|
141
|
-
for (const stem of [...allTomlStems].sort()) {
|
|
142
|
-
const claudeStem = NAME_MAP_REVERSE[stem] ?? stem;
|
|
143
|
-
if (!(claudeStem in byTool.claude)) {
|
|
144
|
-
console.log(` ✗ ${stem} — present in toml dirs but missing in .claude/commands`);
|
|
145
|
-
errors++;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// ── Claude frontmatter validity ─────────────────────────────────────────────
|
|
150
|
-
// Only the .md directory: the TOML dirs are parsed by a real TOML parser
|
|
151
|
-
// already, so a malformed one surfaces as a missing description above.
|
|
152
|
-
console.log('\nChecking Claude command frontmatter...');
|
|
153
|
-
|
|
154
|
-
for (const stem of claudeStems) {
|
|
155
|
-
const full = path.join(DIRS.claude.dir, `${stem}${DIRS.claude.ext}`);
|
|
156
|
-
let yamlErrors = [];
|
|
157
|
-
try {
|
|
158
|
-
yamlErrors = frontmatterYamlErrors(fs.readFileSync(full, 'utf8'));
|
|
159
|
-
} catch (e) {
|
|
160
|
-
console.log(` ✗ ${stem} — cannot read file: ${e.message}`);
|
|
161
|
-
errors++;
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
if (yamlErrors.length === 0) {
|
|
165
|
-
console.log(` ✓ ${stem}`);
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
console.log(` ✗ ${stem}`);
|
|
169
|
-
for (const message of yamlErrors) {
|
|
170
|
-
console.log(` ${message}`);
|
|
171
|
-
errors++;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// ── Description sync check ──────────────────────────────────────────────────
|
|
176
|
-
console.log('\nChecking description sync...');
|
|
177
|
-
|
|
178
|
-
for (const claudeStem of claudeStems) {
|
|
179
|
-
const tomlStem = NAME_MAP[claudeStem] ?? claudeStem;
|
|
180
|
-
const descClaude = byTool.claude[claudeStem];
|
|
181
|
-
const descGemini = byTool.gemini[tomlStem];
|
|
182
|
-
const descAgy = byTool.antigravity[tomlStem];
|
|
183
|
-
|
|
184
|
-
const malformed = [
|
|
185
|
-
['.claude/commands', byTool.claude, claudeStem],
|
|
186
|
-
['.gemini/commands', byTool.gemini, tomlStem],
|
|
187
|
-
['commands/', byTool.antigravity, tomlStem],
|
|
188
|
-
].filter(([, commands, stem]) => Object.prototype.hasOwnProperty.call(commands, stem) && commands[stem] == null);
|
|
189
|
-
|
|
190
|
-
if (malformed.length) {
|
|
191
|
-
console.log(` ✗ ${claudeStem}`);
|
|
192
|
-
for (const [toolDir, , stem] of malformed) {
|
|
193
|
-
console.log(` ${toolDir}/${stem} — missing or malformed description`);
|
|
194
|
-
}
|
|
195
|
-
errors++;
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (descClaude == null || descGemini == null || descAgy == null) {
|
|
200
|
-
// Missing file already flagged by parity check
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const allMatch = descClaude === descGemini && descGemini === descAgy;
|
|
205
|
-
|
|
206
|
-
if (allMatch) {
|
|
207
|
-
console.log(` ✓ ${claudeStem}`);
|
|
208
|
-
} else {
|
|
209
|
-
console.log(` ✗ ${claudeStem}`);
|
|
210
|
-
console.log(` .claude: ${descClaude}`);
|
|
211
|
-
console.log(` .gemini: ${descGemini}`);
|
|
212
|
-
console.log(` commands/: ${descAgy}`);
|
|
213
|
-
errors++;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const status = errors > 0 ? 'FAILED' : 'PASSED';
|
|
218
|
-
console.log(`\n${allCanonicalStems.size} commands checked — ${errors} error(s) — ${status}`);
|
|
219
|
-
|
|
220
|
-
if (errors > 0) process.exit(1);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
main();
|