@givolt/i3-composer-agent 0.6.12 → 1.0.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 +3 -2
- package/.claude-plugin/marketplace.json +2 -1
- package/.claude-plugin/plugin.json +3 -1
- package/.codex-plugin/plugin.json +3 -1
- package/CHANGELOG.md +34 -0
- package/NOTICE.md +6 -1
- package/README.md +116 -138
- package/bin/agent-targets.json +726 -0
- package/bin/i3-composer-agent.cjs +89 -18
- package/bin/install.cjs +164 -0
- package/bin/skills-registry.LICENSE +21 -0
- package/bin/wizard.cjs +66 -0
- package/docs/antigravity-setup.md +1 -1
- package/docs/codebuddy-setup.md +55 -8
- package/docs/codex-setup.md +13 -2
- package/docs/comparison.md +1 -1
- package/hooks/sdd-cache-post.sh +0 -0
- package/hooks/sdd-cache-pre.sh +0 -0
- package/package.json +75 -17
- package/plugin.json +4 -2
- package/rebrand/INSTALLATION-SPEC.md +46 -0
- package/rebrand/MAINTENANCE.md +93 -31
- package/rebrand/NOTICE.md +14 -0
- package/rebrand/PR-WORKFLOW.md +34 -0
- package/rebrand/UNIFICATION-SPEC.md +33 -0
- package/rebrand/VALIDATION.md +32 -0
- package/rebrand/VERSIONING.md +33 -0
- package/rebrand/apply.cjs +80 -7
- package/rebrand/brand.json +6 -2
- package/rebrand/catalog.cjs +56 -0
- package/rebrand/fork-patches.json +12 -0
- package/rebrand/overlay/.github/workflows/test-plugin-install.yml +177 -0
- package/rebrand/overlay/CHANGELOG.md +34 -0
- package/rebrand/overlay/bin/agent-targets.json +726 -0
- package/rebrand/overlay/bin/i3-composer-agent.cjs +190 -0
- package/rebrand/overlay/bin/install.cjs +164 -0
- package/rebrand/overlay/bin/skills-registry.LICENSE +21 -0
- package/rebrand/overlay/bin/wizard.cjs +66 -0
- package/rebrand/overlay/scripts/validate-brand.cjs +44 -0
- package/rebrand/overlay/tests/bundle.test.cjs +85 -0
- package/rebrand/overlay/tests/installer.test.cjs +193 -0
- package/rebrand/package.template.json +82 -0
- package/rebrand/rebrand.sh +4 -0
- package/rebrand/record-upstream.cjs +37 -0
- package/rebrand/templates/README.md +83 -137
- package/rebrand/templates/codebuddy-setup.md +55 -8
- package/rebrand/templates/codex-setup.md +14 -3
- package/rebrand/tests/pipeline.test.cjs +185 -0
- package/rebrand/upstream.json +171 -0
- package/scripts/validate-brand.cjs +11 -3
- package/skills/idea-refine/scripts/idea-refine.sh +0 -0
- package/tests/bundle.test.cjs +11 -5
- package/tests/installer.test.cjs +193 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const test = require('node:test');
|
|
4
|
+
const assert = require('node:assert/strict');
|
|
5
|
+
const fs = require('node:fs');
|
|
6
|
+
const os = require('node:os');
|
|
7
|
+
const path = require('node:path');
|
|
8
|
+
const { spawnSync } = require('node:child_process');
|
|
9
|
+
const root = path.resolve(__dirname, '..');
|
|
10
|
+
const cli = path.join(root, 'bin/i3-composer-agent.cjs');
|
|
11
|
+
const upstream = require('../rebrand/upstream.json');
|
|
12
|
+
function workspace(t) {
|
|
13
|
+
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'i3-agent-install-'));
|
|
14
|
+
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
|
|
15
|
+
return fs.realpathSync(directory);
|
|
16
|
+
}
|
|
17
|
+
function run(directory, args) {
|
|
18
|
+
return spawnSync(process.execPath, [cli, ...args], { cwd: directory, encoding: 'utf8' });
|
|
19
|
+
}
|
|
20
|
+
test('native CodeBuddy installation includes short commands, personas and usable references', t => {
|
|
21
|
+
const directory = workspace(t);
|
|
22
|
+
const result = run(directory, ['--codebuddy', '--scope', 'project', '--yes']);
|
|
23
|
+
assert.equal(result.status, 0, result.stderr);
|
|
24
|
+
const base = path.join(directory, '.codebuddy');
|
|
25
|
+
assert.equal(fs.readdirSync(path.join(base, 'skills')).length, upstream.skills.length);
|
|
26
|
+
assert.equal(fs.readdirSync(path.join(base, 'commands')).length, upstream.commands.length);
|
|
27
|
+
assert.equal(fs.readdirSync(path.join(base, 'agents')).length, upstream.personas.length);
|
|
28
|
+
const command = fs.readFileSync(path.join(base, 'commands/spec.md'), 'utf8');
|
|
29
|
+
assert.match(command, /Invoke the spec-driven-development skill/);
|
|
30
|
+
assert.doesNotMatch(command, /i3-composer-agent:/);
|
|
31
|
+
const ship = fs.readFileSync(path.join(base, 'commands/ship.md'), 'utf8');
|
|
32
|
+
assert.match(ship, /\.codebuddy\/agents\//);
|
|
33
|
+
assert.doesNotMatch(ship, /\.claude\/agents\//);
|
|
34
|
+
assert.ok(fs.existsSync(path.join(base, 'references/definition-of-done.md')));
|
|
35
|
+
assert.equal(fs.readFileSync(path.join(base, 'i3-composer-agent-LICENSE'), 'utf8'), fs.readFileSync(path.join(root, 'LICENSE'), 'utf8'));
|
|
36
|
+
assert.match(fs.readFileSync(path.join(base, 'i3-composer-agent-NOTICE.md'), 'utf8'), /Addy Osmani/);
|
|
37
|
+
assert.equal(fs.existsSync(path.join(directory, 'AGENTS.md')), false);
|
|
38
|
+
assert.equal(fs.existsSync(path.join(directory, 'i3-composer-agent')), false);
|
|
39
|
+
assert.match(result.stdout, /\/spec/);
|
|
40
|
+
});
|
|
41
|
+
test('multiple tools retain their own destinations and share universal skills without duplicate work', t => {
|
|
42
|
+
const directory = workspace(t);
|
|
43
|
+
const result = run(directory, ['--agents', 'codebuddy,codex,cursor,claude-code', '--scope', 'project', '--yes']);
|
|
44
|
+
assert.equal(result.status, 0, result.stderr);
|
|
45
|
+
for (const base of ['.codebuddy', '.agents', '.claude']) {
|
|
46
|
+
assert.equal(fs.readdirSync(path.join(directory, base, 'skills')).length, upstream.skills.length);
|
|
47
|
+
assert.ok(fs.existsSync(path.join(directory, base, 'references/testing-patterns.md')));
|
|
48
|
+
}
|
|
49
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(directory, '.agents/.i3-composer-agent.json')));
|
|
50
|
+
assert.deepEqual(manifest.agents.sort(), ['codex', 'cursor']);
|
|
51
|
+
assert.equal(fs.existsSync(path.join(directory, '.agents/commands')), false);
|
|
52
|
+
});
|
|
53
|
+
test('installation dry run describes scope and destinations without changing project files', t => {
|
|
54
|
+
const directory = workspace(t);
|
|
55
|
+
const result = run(directory, ['--agents', 'codebuddy,codex', '--scope', 'project', '--dry-run']);
|
|
56
|
+
assert.equal(result.status, 0, result.stderr);
|
|
57
|
+
const plan = JSON.parse(result.stdout);
|
|
58
|
+
assert.equal(plan.mode, 'install');
|
|
59
|
+
assert.equal(plan.scope, 'project');
|
|
60
|
+
assert.equal(plan.targets.length, 2);
|
|
61
|
+
assert.deepEqual(fs.readdirSync(directory), []);
|
|
62
|
+
});
|
|
63
|
+
test('all copied Markdown reference links and stable skill frontmatter remain valid', t => {
|
|
64
|
+
const directory = workspace(t);
|
|
65
|
+
assert.equal(run(directory, ['--codebuddy', '--scope', 'project', '--yes']).status, 0);
|
|
66
|
+
const base = path.join(directory, '.codebuddy');
|
|
67
|
+
function visit(folder) {
|
|
68
|
+
for (const entry of fs.readdirSync(folder, { withFileTypes: true })) {
|
|
69
|
+
const file = path.join(folder, entry.name);
|
|
70
|
+
if (entry.isDirectory()) visit(file);
|
|
71
|
+
else if (entry.name.endsWith('.md')) {
|
|
72
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
73
|
+
for (const match of content.matchAll(/\]\(([^)]+)\)/g)) {
|
|
74
|
+
const relative = match[1].split('#')[0];
|
|
75
|
+
if (relative.includes('references/') && !/^[a-z]+:/i.test(relative)) {
|
|
76
|
+
assert.ok(fs.existsSync(path.resolve(path.dirname(file), relative)), `${file}: ${relative}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
visit(path.join(base, 'skills'));
|
|
83
|
+
for (const id of upstream.skills) {
|
|
84
|
+
const head = content => content.match(/^---\r?\n[\s\S]*?\r?\n---/)[0];
|
|
85
|
+
assert.equal(head(fs.readFileSync(path.join(base, 'skills', id, 'SKILL.md'), 'utf8')), head(fs.readFileSync(path.join(root, 'skills', id, 'SKILL.md'), 'utf8')));
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
test('existing assets are protected; confirmed replacement backs them up and preserves unrelated settings', t => {
|
|
89
|
+
const directory = workspace(t);
|
|
90
|
+
const base = path.join(directory, '.codebuddy');
|
|
91
|
+
fs.mkdirSync(path.join(base, 'commands'), { recursive: true });
|
|
92
|
+
fs.writeFileSync(path.join(base, 'commands/spec.md'), 'my custom command');
|
|
93
|
+
fs.writeFileSync(path.join(base, 'settings.json'), '{"keep":"my settings"}\n');
|
|
94
|
+
const args = ['--codebuddy', '--scope', 'project', '--yes'];
|
|
95
|
+
assert.equal(run(directory, args).status, 1);
|
|
96
|
+
assert.equal(fs.existsSync(path.join(base, 'skills')), false);
|
|
97
|
+
const result = run(directory, [...args, '--force']);
|
|
98
|
+
assert.equal(result.status, 0, result.stderr);
|
|
99
|
+
const backups = fs.readdirSync(base).filter(file => file.startsWith('.i3-composer-agent-backup-'));
|
|
100
|
+
assert.equal(backups.length, 1);
|
|
101
|
+
assert.equal(fs.readFileSync(path.join(base, backups[0], 'commands/spec.md'), 'utf8'), 'my custom command');
|
|
102
|
+
assert.equal(fs.readFileSync(path.join(base, 'settings.json'), 'utf8'), '{"keep":"my settings"}\n');
|
|
103
|
+
assert.equal(fs.existsSync(path.join(base, backups[0], 'settings.json')), false);
|
|
104
|
+
});
|
|
105
|
+
test('global installation uses injected home and config roots without touching the real user configuration', t => {
|
|
106
|
+
const directory = workspace(t);
|
|
107
|
+
const { planInstallation, executeInstallation } = require('../bin/install.cjs');
|
|
108
|
+
const plan = planInstallation({ agents: ['codebuddy', 'codex', 'claude-code', 'opencode'], scope: 'global', home: directory, env: { XDG_CONFIG_HOME: path.join(directory, 'config'), CLAUDE_CONFIG_DIR: path.join(directory, 'custom-claude') } });
|
|
109
|
+
assert.ok(plan.targets.every(target => target.skillsDirectory.startsWith(directory + path.sep)));
|
|
110
|
+
assert.ok(plan.targets.some(target => target.skillsDirectory === path.join(directory, 'custom-claude/skills')));
|
|
111
|
+
assert.ok(plan.targets.some(target => target.skillsDirectory === path.join(directory, 'config/opencode/skills')));
|
|
112
|
+
executeInstallation(plan);
|
|
113
|
+
for (const target of plan.targets) {
|
|
114
|
+
assert.equal(fs.readdirSync(target.skillsDirectory).length, upstream.skills.length);
|
|
115
|
+
assert.ok(fs.existsSync(path.join(target.referencesDirectory, 'definition-of-done.md')));
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
test('the pinned tool catalog plans all project choices and rejects unsupported global choices before writing', t => {
|
|
119
|
+
const directory = workspace(t);
|
|
120
|
+
const { registry, planInstallation } = require('../bin/install.cjs');
|
|
121
|
+
assert.equal(registry.agents.length, 79);
|
|
122
|
+
assert.equal(registry.commit, '48dc9e8eb8aa19040e91cb90ba0b642c9cbad57e');
|
|
123
|
+
const plan = planInstallation({ agents: registry.agents.map(agent => agent.id), scope: 'project', projectDir: directory });
|
|
124
|
+
assert.equal(plan.agents.length, registry.agents.length);
|
|
125
|
+
assert.ok(plan.targets.length < plan.agents.length);
|
|
126
|
+
assert.equal(new Set(plan.assets.map(asset => asset.destination)).size, plan.assets.length);
|
|
127
|
+
for (const agent of registry.agents) {
|
|
128
|
+
if (agent.globalSkillsDir) assert.ok(planInstallation({ agents: [agent.id], scope: 'global', home: directory, env: {} }).targets[0].skillsDirectory.startsWith(directory + path.sep));
|
|
129
|
+
else assert.throws(() => planInstallation({ agents: [agent.id], scope: 'global', home: directory, env: {} }), /project installation only/);
|
|
130
|
+
}
|
|
131
|
+
assert.deepEqual(fs.readdirSync(directory), []);
|
|
132
|
+
});
|
|
133
|
+
test('failed installation restores prior assets and removes all newly written files', t => {
|
|
134
|
+
const directory = workspace(t);
|
|
135
|
+
const { planInstallation, executeInstallation } = require('../bin/install.cjs');
|
|
136
|
+
const prior = path.join(directory, '.codebuddy/skills/api-and-interface-design');
|
|
137
|
+
fs.mkdirSync(prior, { recursive: true });
|
|
138
|
+
fs.writeFileSync(path.join(prior, 'custom.md'), 'prior skill content');
|
|
139
|
+
const plan = planInstallation({ agents: ['codebuddy', 'codex'], scope: 'project', projectDir: directory });
|
|
140
|
+
const realRename = fs.renameSync;
|
|
141
|
+
let failed = false;
|
|
142
|
+
fs.renameSync = (source, destination) => {
|
|
143
|
+
if (!failed && destination === plan.assets[1].destination) { failed = true; throw new Error('simulated disk failure'); }
|
|
144
|
+
return realRename(source, destination);
|
|
145
|
+
};
|
|
146
|
+
try { assert.throws(() => executeInstallation(plan, { force: true }), /simulated disk failure/); }
|
|
147
|
+
finally { fs.renameSync = realRename; }
|
|
148
|
+
assert.equal(fs.readFileSync(path.join(prior, 'custom.md'), 'utf8'), 'prior skill content');
|
|
149
|
+
assert.deepEqual(fs.readdirSync(path.dirname(prior)), ['api-and-interface-design']);
|
|
150
|
+
assert.deepEqual(fs.readdirSync(path.join(directory, '.codebuddy')), ['skills']);
|
|
151
|
+
assert.equal(fs.existsSync(path.join(directory, '.agents')), false);
|
|
152
|
+
});
|
|
153
|
+
test('replacing a skill symlink backs up the link and leaves its external source untouched', t => {
|
|
154
|
+
const directory = workspace(t);
|
|
155
|
+
const external = path.join(directory, 'external-skill');
|
|
156
|
+
const skills = path.join(directory, '.codebuddy/skills');
|
|
157
|
+
fs.mkdirSync(external);
|
|
158
|
+
fs.writeFileSync(path.join(external, 'custom.md'), 'external source');
|
|
159
|
+
fs.mkdirSync(skills, { recursive: true });
|
|
160
|
+
fs.symlinkSync(external, path.join(skills, 'spec-driven-development'), 'dir');
|
|
161
|
+
const result = run(directory, ['--codebuddy', '--scope', 'project', '--yes', '--force']);
|
|
162
|
+
assert.equal(result.status, 0, result.stderr);
|
|
163
|
+
assert.deepEqual(fs.readdirSync(external), ['custom.md']);
|
|
164
|
+
assert.equal(fs.lstatSync(path.join(skills, 'spec-driven-development')).isSymbolicLink(), false);
|
|
165
|
+
const base = path.dirname(skills);
|
|
166
|
+
const backup = fs.readdirSync(base).find(file => file.startsWith('.i3-composer-agent-backup-'));
|
|
167
|
+
assert.equal(fs.lstatSync(path.join(base, backup, 'skills/spec-driven-development')).isSymbolicLink(), true);
|
|
168
|
+
});
|
|
169
|
+
test('package destinations, shared directory symlinks and ambiguous noninteractive flags fail without writes', t => {
|
|
170
|
+
const directory = workspace(t);
|
|
171
|
+
for (const args of [ ['--codebuddy'], ['--codebuddy', '--yes'], ['--agents', 'unknown', '--scope', 'project', '--yes'], ['--codebuddy', '--scope', 'invalid', '--yes'], ['--codebuddy', '--scope', 'project', '--global', '--yes'] ]) {
|
|
172
|
+
assert.equal(run(directory, args).status, 1);
|
|
173
|
+
assert.deepEqual(fs.readdirSync(directory), []);
|
|
174
|
+
}
|
|
175
|
+
assert.equal(run(directory, ['--codebuddy', '--scope', 'project', '--yes', '--project-dir', root]).status, 1);
|
|
176
|
+
fs.mkdirSync(path.join(directory, '.codebuddy'));
|
|
177
|
+
fs.symlinkSync(path.join(root, 'skills'), path.join(directory, '.codebuddy/skills'), 'dir');
|
|
178
|
+
assert.equal(run(directory, ['--codebuddy', '--scope', 'project', '--yes', '--force']).status, 1);
|
|
179
|
+
assert.deepEqual(fs.readdirSync(path.join(directory, '.codebuddy')), ['skills']);
|
|
180
|
+
});
|
|
181
|
+
test('explicit plugin preparation remains available and does not install native host files', t => {
|
|
182
|
+
const directory = workspace(t);
|
|
183
|
+
const result = run(directory, ['--prepare', '--codebuddy']);
|
|
184
|
+
assert.equal(result.status, 0, result.stderr);
|
|
185
|
+
assert.match(result.stdout, /\/plugin install/);
|
|
186
|
+
assert.equal(fs.existsSync(path.join(directory, 'i3-composer-agent/plugin.json')), true);
|
|
187
|
+
assert.equal(fs.existsSync(path.join(directory, '.codebuddy')), false);
|
|
188
|
+
const listing = run(directory, ['--list-agents']);
|
|
189
|
+
assert.equal(listing.status, 0, listing.stderr);
|
|
190
|
+
assert.equal(listing.stdout.trim().split('\n').length, 79);
|
|
191
|
+
assert.match(listing.stdout, /codebuddy/);
|
|
192
|
+
assert.match(listing.stdout, /windsurf/);
|
|
193
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@givolt/i3-composer-agent",
|
|
3
|
+
"description": "i3 Composer Agent: production-grade engineering skills and lifecycle commands for AI coding agents.",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "Givolt",
|
|
6
|
+
"contributors": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Addy Osmani"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"bin": {
|
|
12
|
+
"i3-composer-agent": "bin/i3-composer-agent.cjs"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public",
|
|
19
|
+
"registry": "https://registry.npmjs.org/"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"bin/",
|
|
23
|
+
"skills/",
|
|
24
|
+
"references/",
|
|
25
|
+
"agents/",
|
|
26
|
+
"commands/",
|
|
27
|
+
".claude/commands/",
|
|
28
|
+
".gemini/commands/",
|
|
29
|
+
".claude-plugin/",
|
|
30
|
+
".codex-plugin/",
|
|
31
|
+
".agents/plugins/",
|
|
32
|
+
"hooks/",
|
|
33
|
+
"docs/",
|
|
34
|
+
"scripts/",
|
|
35
|
+
"evals/",
|
|
36
|
+
"rebrand/",
|
|
37
|
+
"tests/",
|
|
38
|
+
"plugin.json",
|
|
39
|
+
"NOTICE.md",
|
|
40
|
+
"CHANGELOG.md"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"rebrand": "node rebrand/apply.cjs --apply",
|
|
44
|
+
"rebrand:check": "node rebrand/apply.cjs --check",
|
|
45
|
+
"validate": "node scripts/validate-brand.cjs && node scripts/validate-skills.js && node scripts/validate-versions.js && node scripts/validate-commands.js && node scripts/validate-reference-links.js && node scripts/validate-artifact-paths.js",
|
|
46
|
+
"test": "node --test scripts/*-test.js scripts/lib/*-test.js tests/*.test.cjs rebrand/tests/*.test.cjs",
|
|
47
|
+
"prepack": "npm run validate"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"i3-composer",
|
|
51
|
+
"agent-skills",
|
|
52
|
+
"codebuddy",
|
|
53
|
+
"codex",
|
|
54
|
+
"claude-code"
|
|
55
|
+
],
|
|
56
|
+
"i3ComposerAgent": {
|
|
57
|
+
"pluginFiles": [
|
|
58
|
+
"bin",
|
|
59
|
+
"skills",
|
|
60
|
+
"references",
|
|
61
|
+
"agents",
|
|
62
|
+
"commands",
|
|
63
|
+
".claude/commands",
|
|
64
|
+
".gemini/commands",
|
|
65
|
+
".claude-plugin",
|
|
66
|
+
".codex-plugin",
|
|
67
|
+
".agents/plugins",
|
|
68
|
+
"hooks",
|
|
69
|
+
"docs",
|
|
70
|
+
"scripts",
|
|
71
|
+
"evals",
|
|
72
|
+
"rebrand",
|
|
73
|
+
"tests",
|
|
74
|
+
"plugin.json",
|
|
75
|
+
"package.json",
|
|
76
|
+
"README.md",
|
|
77
|
+
"LICENSE",
|
|
78
|
+
"NOTICE.md",
|
|
79
|
+
"CHANGELOG.md"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
const { execFileSync } = require('node:child_process');
|
|
7
|
+
const { describe, runtimeRoots, runtimeFiles } = require('./catalog.cjs');
|
|
8
|
+
const root = path.resolve(__dirname, '..');
|
|
9
|
+
const ref = process.argv[2];
|
|
10
|
+
if (!ref || ref.startsWith('-') || process.argv.length !== 3) {
|
|
11
|
+
console.error('Usage: node rebrand/record-upstream.cjs <reviewed upstream ref>');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const git = args => execFileSync('git', args, { cwd: root, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
|
|
16
|
+
const commit = git(['rev-parse', '--verify', '--end-of-options', `${ref}^{commit}`]).trim();
|
|
17
|
+
const entries = git(['ls-tree', '-rz', commit, '--', ...runtimeRoots, ...runtimeFiles]).split('\0').filter(Boolean);
|
|
18
|
+
const blobs = new Map(entries.filter(line => /^100\d+ blob /.test(line)).map(line => {
|
|
19
|
+
const [metadata, file] = line.split('\t');
|
|
20
|
+
return [file, metadata.split(' ')[2]];
|
|
21
|
+
}));
|
|
22
|
+
const read = file => git(['cat-file', 'blob', blobs.get(file)]);
|
|
23
|
+
const snapshot = {
|
|
24
|
+
upstreamCommit: commit,
|
|
25
|
+
upstreamVersion: JSON.parse(read('plugin.json')).version,
|
|
26
|
+
...describe([...blobs.keys()], read),
|
|
27
|
+
};
|
|
28
|
+
fs.writeFileSync(path.join(__dirname, 'upstream.json'), JSON.stringify(snapshot, null, 2) + '\n');
|
|
29
|
+
const brandFile = path.join(__dirname, 'brand.json');
|
|
30
|
+
const brand = JSON.parse(fs.readFileSync(brandFile, 'utf8'));
|
|
31
|
+
brand.upstreamCommit = commit;
|
|
32
|
+
fs.writeFileSync(brandFile, JSON.stringify(brand, null, 2) + '\n');
|
|
33
|
+
console.log(JSON.stringify({ commit, version: snapshot.upstreamVersion, skills: snapshot.skills.length, commands: snapshot.commands.length }));
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error(error.message);
|
|
36
|
+
process.exitCode = 1;
|
|
37
|
+
}
|
|
@@ -1,178 +1,124 @@
|
|
|
1
|
-
# i3 Composer Agent
|
|
1
|
+
# i3 Composer Agent v{{RELEASE_VERSION}}
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Based on agent-skills v{{UPSTREAM_VERSION}}**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
for AI coding agents. This is the engineering-skill product in the i3 Composer
|
|
7
|
-
family; the GSD-derived workflow product is maintained separately.
|
|
5
|
+
**Intelligence. Integration. Innovation.**
|
|
8
6
|
|
|
7
|
+
Engineering skills, lifecycle commands, and specialist personas for AI coding agents.
|
|
9
8
|
Based on [Agent Skills](https://github.com/addyosmani/agent-skills) by Addy Osmani
|
|
10
|
-
(MIT). See [NOTICE.md](NOTICE.md) for attribution
|
|
9
|
+
(MIT). See [NOTICE.md](NOTICE.md) for attribution.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
The npm package is `@givolt/i3-composer-agent`; the plugin and marketplace ID is
|
|
12
|
+
`i3-composer-agent`. Skill IDs retain their upstream names.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
`i3-composer-agent`. Skill IDs and workflow behavior retain their upstream names.
|
|
14
|
+
## Install with the wizard
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
Run in the project where you want to use the skills:
|
|
18
17
|
|
|
19
18
|
```bash
|
|
19
|
+
npx @givolt/i3-composer-agent
|
|
20
|
+
# Preselect a tool; the wizard still allows multiple selections:
|
|
20
21
|
npx @givolt/i3-composer-agent --codebuddy
|
|
21
|
-
# Or prepare a bundle for another host:
|
|
22
|
-
npx @givolt/i3-composer-agent --codex
|
|
23
|
-
npx @givolt/i3-composer-agent --claude
|
|
24
22
|
```
|
|
25
23
|
|
|
26
|
-
The
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
The interactive terminal wizard offers multiple tools, project or global scope,
|
|
25
|
+
an installation summary, and confirmation. Its 79 tool directory presets come
|
|
26
|
+
from the pinned [Vercel Skills CLI registry](https://github.com/vercel-labs/skills/blob/48dc9e8eb8aa19040e91cb90ba0b642c9cbad57e/src/agents.ts).
|
|
27
|
+
Choose by tool ID or comma-separated menu numbers. Use `--list-agents` to list
|
|
28
|
+
the choices. Directory presets are not an execution test of every host.
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Every selected tool receives all {{SKILL_COUNT}} skills and shared references.
|
|
31
|
+
CodeBuddy and Claude Code also receive {{COMMAND_COUNT}} short command workflows
|
|
32
|
+
and {{PERSONA_COUNT}} persona files. Other tools use their native skill support;
|
|
33
|
+
short lifecycle commands depend on the host. Shared destinations are installed
|
|
34
|
+
once. License and attribution files accompany each native installation.
|
|
35
|
+
Reload the IDE window or start a new session after installation. See
|
|
36
|
+
[CodeBuddy setup](docs/codebuddy-setup.md) and [Codex setup](docs/codex-setup.md).
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
/plugin marketplace add ./i3-composer-agent
|
|
34
|
-
/plugin install i3-composer-agent@i3-composer-agent
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Use the absolute directory printed by the CLI if the host has a different
|
|
38
|
-
working directory. See [CodeBuddy setup](docs/codebuddy-setup.md).
|
|
39
|
-
|
|
40
|
-
### Codex
|
|
38
|
+
For an explicit installation without prompts:
|
|
41
39
|
|
|
42
40
|
```bash
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
npx @givolt/i3-composer-agent --agents codebuddy,codex --scope project --yes
|
|
42
|
+
npx @givolt/i3-composer-agent --claude --scope global --yes
|
|
43
|
+
npx @givolt/i3-composer-agent --codebuddy --scope project --dry-run
|
|
45
44
|
```
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
Existing assets require confirmation; use `--force` with noninteractive installs.
|
|
47
|
+
Replacement preserves previous files in a `.i3-composer-agent-backup-*` directory
|
|
48
|
+
under each tool configuration root. Unrelated settings are left in place.
|
|
49
|
+
`npx -y` accepts npm's package download prompt; the package's own `--yes` flag
|
|
50
|
+
accepts the explicit installation plan.
|
|
51
|
+
|
|
52
|
+
## Prepare the complete plugin
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
For native plugin registration, including plugin hooks, explicitly prepare a
|
|
55
|
+
persistent `./i3-composer-agent/` bundle:
|
|
53
56
|
|
|
54
57
|
```bash
|
|
55
|
-
npx @givolt/i3-composer-agent --
|
|
56
|
-
npx @givolt/i3-composer-agent --
|
|
57
|
-
npx @givolt/i3-composer-agent --
|
|
58
|
+
npx @givolt/i3-composer-agent --prepare --codebuddy
|
|
59
|
+
npx @givolt/i3-composer-agent --prepare --codex
|
|
60
|
+
npx @givolt/i3-composer-agent --prepare --claude
|
|
58
61
|
```
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
## Commands
|
|
65
|
-
|
|
66
|
-
Hosts supporting Claude-compatible plugin commands load these workflows.
|
|
67
|
-
Use the namespaced form, for example `/i3-composer-agent:spec`.
|
|
68
|
-
|
|
69
|
-
| Command | Workflow |
|
|
70
|
-
| --- | --- |
|
|
71
|
-
| `/i3-composer-agent:spec` | Define objectives, constraints, and acceptance criteria |
|
|
72
|
-
| `/i3-composer-agent:plan` | Write ordered, verifiable tasks |
|
|
73
|
-
| `/i3-composer-agent:build` | Implement the next task with verification |
|
|
74
|
-
| `/i3-composer-agent:build auto` | Execute the approved plan with per-task verification |
|
|
75
|
-
| `/i3-composer-agent:test` | Test-first development and regression checks |
|
|
76
|
-
| `/i3-composer-agent:constraints` | Establish a written quality bar |
|
|
77
|
-
| `/i3-composer-agent:review` | Review code quality and correctness |
|
|
78
|
-
| `/i3-composer-agent:webperf` | Audit web performance |
|
|
79
|
-
| `/i3-composer-agent:code-simplify` | Simplify code without changing behavior |
|
|
80
|
-
| `/i3-composer-agent:ship` | Review launch readiness and rollback |
|
|
81
|
-
|
|
82
|
-
## All 25 Skills
|
|
83
|
-
|
|
84
|
-
The commands above are entry points. The pack includes 25 skills total — 24 lifecycle skills plus the `using-agent-skills` meta-skill. Each skill is a structured workflow with steps, verification gates, and anti-rationalization tables. You can also reference any skill directly.
|
|
85
|
-
|
|
86
|
-
### Meta - Discover which skill applies
|
|
63
|
+
The bundle includes skills, commands, personas, hooks and references. Run the
|
|
64
|
+
registration commands printed by the CLI in the intended host. This preparation
|
|
65
|
+
mode does not install native skills or choose the host plugin manager's scope.
|
|
87
66
|
|
|
88
|
-
|
|
89
|
-
|-------|-------------|----------|
|
|
90
|
-
| [using-agent-skills](skills/using-agent-skills/SKILL.md) | Maps incoming work to the right skill workflow and defines shared operating rules | Starting a session or deciding which skill applies |
|
|
67
|
+
CodeBuddy Code (terminal) / Claude Code:
|
|
91
68
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
| [interview-me](skills/interview-me/SKILL.md) | One-question-at-a-time interview that extracts what the user actually wants instead of what they think they should want, until ~95% confidence | The ask is underspecified, or the user invokes "interview me" / "grill me" |
|
|
97
|
-
| [idea-refine](skills/idea-refine/SKILL.md) | Structured divergent/convergent thinking to turn vague ideas into concrete proposals | You have a rough concept that needs exploration |
|
|
98
|
-
| [spec-driven-development](skills/spec-driven-development/SKILL.md) | Write a PRD covering objectives, commands, structure, code style, testing, and boundaries before any code | Starting a new project, feature, or significant change |
|
|
99
|
-
| [constraint-driven-development](skills/constraint-driven-development/SKILL.md) | Interviews you for a quality bar with sane default thresholds, writes CONSTRAINTS.md, places each check by cost, and catches agents silencing checks or skipping tests to get green | No standards are written down, or an agent is producing more than anyone reads |
|
|
100
|
-
|
|
101
|
-
### Plan - Break it down
|
|
102
|
-
|
|
103
|
-
| Skill | What It Does | Use When |
|
|
104
|
-
|-------|-------------|----------|
|
|
105
|
-
| [planning-and-task-breakdown](skills/planning-and-task-breakdown/SKILL.md) | Decompose specs into small, verifiable tasks with acceptance criteria and dependency ordering | You have a spec and need implementable units |
|
|
106
|
-
|
|
107
|
-
### Build - Write the code
|
|
108
|
-
|
|
109
|
-
| Skill | What It Does | Use When |
|
|
110
|
-
|-------|-------------|----------|
|
|
111
|
-
| [incremental-implementation](skills/incremental-implementation/SKILL.md) | Thin vertical slices - implement, test, verify, commit. Feature flags, safe defaults, rollback-friendly changes | Any change touching more than one file |
|
|
112
|
-
| [test-driven-development](skills/test-driven-development/SKILL.md) | Red-Green-Refactor, test pyramid (80/15/5), test sizes, DAMP over DRY, Beyonce Rule, browser testing | Implementing logic, fixing bugs, or changing behavior |
|
|
113
|
-
| [context-engineering](skills/context-engineering/SKILL.md) | Feed agents the right information at the right time - rules files, context packing, MCP integrations | Starting a session, switching tasks, or when output quality drops |
|
|
114
|
-
| [source-driven-development](skills/source-driven-development/SKILL.md) | Ground every framework decision in official documentation - verify, cite sources, flag what's unverified | You want authoritative, source-cited code for any framework or library |
|
|
115
|
-
| [doubt-driven-development](skills/doubt-driven-development/SKILL.md) | Adversarial fresh-context review of every non-trivial decision in-flight - CLAIM → EXTRACT → DOUBT → RECONCILE → STOP, with optional user-authorized cross-model escalation | Stakes are high (production, security, irreversible), working in unfamiliar code, or a confident output is cheaper to verify now than to debug later |
|
|
116
|
-
| [frontend-ui-engineering](skills/frontend-ui-engineering/SKILL.md) | Component architecture, design systems, state management, responsive design, WCAG 2.1 AA accessibility | Building or modifying user-facing interfaces |
|
|
117
|
-
| [api-and-interface-design](skills/api-and-interface-design/SKILL.md) | Contract-first design, Hyrum's Law, One-Version Rule, error semantics, boundary validation | Designing APIs, module boundaries, or public interfaces |
|
|
118
|
-
|
|
119
|
-
### Verify - Prove it works
|
|
120
|
-
|
|
121
|
-
| Skill | What It Does | Use When |
|
|
122
|
-
|-------|-------------|----------|
|
|
123
|
-
| [browser-testing-with-devtools](skills/browser-testing-with-devtools/SKILL.md) | Chrome DevTools MCP for live runtime data - DOM inspection, console logs, network traces, performance profiling | Building or debugging anything that runs in a browser |
|
|
124
|
-
| [debugging-and-error-recovery](skills/debugging-and-error-recovery/SKILL.md) | Five-step triage: reproduce, localize, reduce, fix, guard. Stop-the-line rule, safe fallbacks | Tests fail, builds break, or behavior is unexpected |
|
|
69
|
+
```text
|
|
70
|
+
/plugin marketplace add ./i3-composer-agent
|
|
71
|
+
/plugin install i3-composer-agent@i3-composer-agent
|
|
72
|
+
```
|
|
125
73
|
|
|
126
|
-
|
|
74
|
+
Codex:
|
|
127
75
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
| [security-and-hardening](skills/security-and-hardening/SKILL.md) | OWASP Top 10 prevention, auth patterns, secrets management, dependency auditing, three-tier boundary system | Handling user input, auth, data storage, or external integrations |
|
|
133
|
-
| [performance-optimization](skills/performance-optimization/SKILL.md) | Measure-first approach - Core Web Vitals targets, profiling workflows, bundle analysis, anti-pattern detection | Performance requirements exist or you suspect regressions |
|
|
76
|
+
```bash
|
|
77
|
+
codex plugin marketplace add ./i3-composer-agent
|
|
78
|
+
codex plugin add i3-composer-agent@i3-composer-agent
|
|
79
|
+
```
|
|
134
80
|
|
|
135
|
-
|
|
81
|
+
Start a new session after enabling the plugin. Codex uses the existing Skill
|
|
82
|
+
names, such as `$spec-driven-development`; lifecycle slash-command adaptation
|
|
83
|
+
is maintained separately.
|
|
136
84
|
|
|
137
|
-
|
|
138
|
-
|-------|-------------|----------|
|
|
139
|
-
| [git-workflow-and-versioning](skills/git-workflow-and-versioning/SKILL.md) | Trunk-based development, atomic commits, change sizing (~100 lines), the commit-as-save-point pattern | Making any code change (always) |
|
|
140
|
-
| [ci-cd-and-automation](skills/ci-cd-and-automation/SKILL.md) | Shift Left, Faster is Safer, feature flags, quality gate pipelines, failure feedback loops | Setting up or modifying build and deploy pipelines |
|
|
141
|
-
| [deprecation-and-migration](skills/deprecation-and-migration/SKILL.md) | Code-as-liability mindset, compulsory vs advisory deprecation, migration patterns, zombie code removal | Removing old systems, migrating users, or sunsetting features |
|
|
142
|
-
| [documentation-and-adrs](skills/documentation-and-adrs/SKILL.md) | Architecture Decision Records, API docs, inline documentation standards - document the *why* | Making architectural decisions, changing APIs, or shipping features |
|
|
143
|
-
| [observability-and-instrumentation](skills/observability-and-instrumentation/SKILL.md) | Structured logging, RED metrics, OpenTelemetry tracing, symptom-based alerting - instrument as you build | Adding telemetry, or shipping anything that runs in production |
|
|
144
|
-
| [shipping-and-launch](skills/shipping-and-launch/SKILL.md) | Pre-launch checklists, feature flag lifecycle, staged rollouts, rollback procedures, monitoring setup | Preparing to deploy to production |
|
|
85
|
+
## Commands
|
|
145
86
|
|
|
146
|
-
|
|
87
|
+
Native CodeBuddy and Claude Code installations use short filenames such as
|
|
88
|
+
`/spec`, `/plan`, `/build` and `/ship`. Hosts supporting Claude-compatible plugin
|
|
89
|
+
commands load the same workflows under the plugin namespace:
|
|
147
90
|
|
|
148
|
-
|
|
91
|
+
| Command | Description |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
{{COMMAND_TABLE}}
|
|
149
94
|
|
|
150
|
-
|
|
151
|
-
auditor, test engineer, and web performance auditor. Shared checklists remain in [references/](references/).
|
|
152
|
-
Their relative layout is preserved across npm packaging and bundle extraction.
|
|
95
|
+
`/i3-composer-agent:build auto` runs the existing approved-plan workflow.
|
|
153
96
|
|
|
154
|
-
##
|
|
97
|
+
## Skills
|
|
155
98
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
wrappers, and personas.
|
|
99
|
+
| Skill | Description |
|
|
100
|
+
| --- | --- |
|
|
101
|
+
{{SKILL_TABLE}}
|
|
160
102
|
|
|
161
|
-
##
|
|
103
|
+
## Bundle options
|
|
162
104
|
|
|
163
105
|
```bash
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
node scripts/run-evals.js --min-rank1 95
|
|
168
|
-
npm pack --pack-destination /path/to/release-directory
|
|
106
|
+
npx @givolt/i3-composer-agent --extract --dir /path/to/plugin
|
|
107
|
+
npx @givolt/i3-composer-agent --codebuddy --dir /path/to/plugin --dry-run
|
|
108
|
+
npx @givolt/i3-composer-agent --codebuddy --dir /path/to/plugin --force
|
|
169
109
|
```
|
|
170
110
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
111
|
+
Explicit `--dir` retains the original plugin preparation behavior. Replacement
|
|
112
|
+
preserves the previous i3 bundle as a backup. Repository-scoped
|
|
113
|
+
AGENTS.md and CLAUDE.md are not copied into business projects.
|
|
114
|
+
|
|
115
|
+
## Maintaining this fork
|
|
175
116
|
|
|
176
|
-
|
|
117
|
+
This repository is independent of the GSD-based i3 Composer Work repository.
|
|
118
|
+
`agent/source` retains upstream source and the `rebrand/` rules; `main` contains
|
|
119
|
+
the validated branded distribution. Create release candidates from the source
|
|
120
|
+
branch, replay branding, validate, then update the release branch.
|
|
177
121
|
|
|
178
|
-
|
|
122
|
+
See [maintenance](rebrand/MAINTENANCE.md), [source PR workflow](rebrand/PR-WORKFLOW.md),
|
|
123
|
+
[versioning](rebrand/VERSIONING.md), [changelog](CHANGELOG.md),
|
|
124
|
+
and [validation contract](rebrand/VALIDATION.md).
|