claude-blueprint 1.0.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/.claude-plugin/plugin.json +26 -0
- package/LICENSE +21 -0
- package/README.md +387 -0
- package/agents/adr-architect-cartographer.md +179 -0
- package/agents/adr-bug-surface-mapper.md +154 -0
- package/agents/adr-compliance-auditor.md +146 -0
- package/agents/adr-consistency-auditor.md +131 -0
- package/agents/adr-conways-law-analyzer.md +170 -0
- package/agents/adr-devils-advocate.md +161 -0
- package/agents/adr-impact-analyzer.md +135 -0
- package/agents/adr-maintainability-assessor.md +162 -0
- package/agents/adr-researcher.md +134 -0
- package/agents/adr-retrospective.md +204 -0
- package/agents/adr-testing-strategy-evaluator.md +164 -0
- package/agents/persona.md +36 -0
- package/bin/cli.js +33 -0
- package/commands/architect.md +66 -0
- package/commands/audit.md +41 -0
- package/commands/blueprint.md +63 -0
- package/commands/debt.md +102 -0
- package/commands/digest.md +106 -0
- package/commands/drift.md +104 -0
- package/commands/eli5.md +149 -0
- package/commands/evaluate.md +61 -0
- package/commands/fitness.md +119 -0
- package/commands/guard.md +102 -0
- package/commands/health.md +139 -0
- package/commands/help.md +119 -0
- package/commands/hooks.md +131 -0
- package/commands/impact.md +38 -0
- package/commands/init.md +229 -0
- package/commands/list.md +51 -0
- package/commands/new.md +74 -0
- package/commands/rearchitect.md +45 -0
- package/commands/retro.md +50 -0
- package/commands/review.md +50 -0
- package/commands/search.md +28 -0
- package/commands/status.md +189 -0
- package/commands/timeline.md +113 -0
- package/commands/transition.md +83 -0
- package/config/lifecycle.toml +71 -0
- package/config/relationships.toml +22 -0
- package/config/state.toml +21 -0
- package/config/taxonomy.toml +118 -0
- package/package.json +27 -0
- package/src/claude-md.js +57 -0
- package/src/install.js +83 -0
- package/src/paths.js +25 -0
- package/src/verify.js +95 -0
package/src/claude-md.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
2
|
+
|
|
3
|
+
const BEGIN = '<!-- BEGIN blueprint -->';
|
|
4
|
+
const END = '<!-- END blueprint -->';
|
|
5
|
+
|
|
6
|
+
const SECTION = `${BEGIN}
|
|
7
|
+
## blueprint
|
|
8
|
+
|
|
9
|
+
Architecture Decision Records with teeth. Cranky senior engineer persona.
|
|
10
|
+
|
|
11
|
+
### Commands
|
|
12
|
+
|
|
13
|
+
| Command | What it does |
|
|
14
|
+
|---------|-------------|
|
|
15
|
+
| \`/blueprint:help\` | Full reference + contextual suggestions |
|
|
16
|
+
| \`/blueprint:list\` | ADR table + next actions |
|
|
17
|
+
| \`/blueprint:new "topic"\` | Create ADR (add \`--research\` for evidence) |
|
|
18
|
+
| \`/blueprint:review N\` | Devil's advocate challenge before acceptance |
|
|
19
|
+
| \`/blueprint:transition accept N\` | Accept / reject / defer / deprecate |
|
|
20
|
+
| \`/blueprint:search "term"\` | Find decisions by topic |
|
|
21
|
+
| \`/blueprint:impact N\` | Check for cross-ADR conflicts |
|
|
22
|
+
| \`/blueprint:audit\` | Verify codebase follows accepted decisions |
|
|
23
|
+
| \`/blueprint:retro\` | Post-fix retrospective (band-aid or systemic?) |
|
|
24
|
+
| \`/blueprint:evaluate\` | 5-agent architecture evaluation team |
|
|
25
|
+
| \`/blueprint:rearchitect "topic"\` | Research + supersede a decision |
|
|
26
|
+
|
|
27
|
+
### Architecture Evaluation Dimensions
|
|
28
|
+
|
|
29
|
+
| Dimension | Command |
|
|
30
|
+
|-----------|---------|
|
|
31
|
+
| Structural consistency | \`/blueprint:evaluate consistency\` |
|
|
32
|
+
| Bug surface mapping | \`/blueprint:evaluate bugs\` |
|
|
33
|
+
| Long-term maintainability | \`/blueprint:evaluate maintainability\` |
|
|
34
|
+
| Testing strategy | \`/blueprint:evaluate testing\` |
|
|
35
|
+
| Conway's Law alignment | \`/blueprint:evaluate conways\` |
|
|
36
|
+
${END}`;
|
|
37
|
+
|
|
38
|
+
export async function updateClaudeMd(claudeMdPath) {
|
|
39
|
+
let content = '';
|
|
40
|
+
try {
|
|
41
|
+
content = await readFile(claudeMdPath, 'utf-8');
|
|
42
|
+
} catch {
|
|
43
|
+
// File doesn't exist yet
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const regex = new RegExp(
|
|
47
|
+
`${BEGIN.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[\\s\\S]*?${END.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
if (regex.test(content)) {
|
|
51
|
+
content = content.replace(regex, SECTION);
|
|
52
|
+
} else {
|
|
53
|
+
content = content ? content.trimEnd() + '\n\n' + SECTION + '\n' : SECTION + '\n';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await writeFile(claudeMdPath, content, 'utf-8');
|
|
57
|
+
}
|
package/src/install.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readdir, copyFile, mkdir } from 'fs/promises';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { getTargetPaths } from './paths.js';
|
|
5
|
+
import { updateClaudeMd } from './claude-md.js';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const PLUGIN_ROOT = join(__dirname, '..');
|
|
9
|
+
|
|
10
|
+
export async function install(opts) {
|
|
11
|
+
let scope = opts.global ? 'global' : opts.project ? 'project' : null;
|
|
12
|
+
|
|
13
|
+
if (!scope) {
|
|
14
|
+
const { select } = await import('@inquirer/prompts');
|
|
15
|
+
scope = await select({
|
|
16
|
+
message: 'Where should blueprint be installed?',
|
|
17
|
+
choices: [
|
|
18
|
+
{ name: 'Global (~/.claude/) — available in all projects', value: 'global' },
|
|
19
|
+
{ name: 'Project (.claude/) — this project only', value: 'project' },
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const { default: ora } = await import('ora');
|
|
25
|
+
const paths = getTargetPaths(scope);
|
|
26
|
+
|
|
27
|
+
// Create directories
|
|
28
|
+
const spinner = ora('Creating directories...').start();
|
|
29
|
+
for (const subDir of ['', 'help', 'list', 'new', 'review', 'transition', 'search', 'impact', 'audit', 'retro', 'evaluate', 'rearchitect', 'agents', 'config']) {
|
|
30
|
+
await mkdir(join(paths.commands, subDir), { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
spinner.succeed('Directories created');
|
|
33
|
+
|
|
34
|
+
// Copy root command (router)
|
|
35
|
+
spinner.start('Installing router...');
|
|
36
|
+
await copyFile(
|
|
37
|
+
join(PLUGIN_ROOT, 'commands', 'blueprint.md'),
|
|
38
|
+
join(paths.commands, 'SKILL.md'),
|
|
39
|
+
);
|
|
40
|
+
spinner.succeed('Router installed');
|
|
41
|
+
|
|
42
|
+
// Copy sub-commands as SKILL.md in their directories
|
|
43
|
+
spinner.start('Installing commands...');
|
|
44
|
+
const commands = ['help', 'list', 'new', 'review', 'transition', 'search', 'impact', 'audit', 'retro', 'evaluate', 'rearchitect'];
|
|
45
|
+
for (const cmd of commands) {
|
|
46
|
+
await copyFile(
|
|
47
|
+
join(PLUGIN_ROOT, 'commands', `${cmd}.md`),
|
|
48
|
+
join(paths.commands, cmd, 'SKILL.md'),
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
spinner.succeed(`${commands.length} commands installed`);
|
|
52
|
+
|
|
53
|
+
// Copy agents
|
|
54
|
+
spinner.start('Installing agents...');
|
|
55
|
+
const agentFiles = await readdir(join(PLUGIN_ROOT, 'agents'));
|
|
56
|
+
for (const file of agentFiles) {
|
|
57
|
+
await copyFile(
|
|
58
|
+
join(PLUGIN_ROOT, 'agents', file),
|
|
59
|
+
join(paths.agents, file),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
spinner.succeed(`${agentFiles.length} agents installed`);
|
|
63
|
+
|
|
64
|
+
// Copy config
|
|
65
|
+
spinner.start('Installing config...');
|
|
66
|
+
const configFiles = await readdir(join(PLUGIN_ROOT, 'config'));
|
|
67
|
+
for (const file of configFiles) {
|
|
68
|
+
await copyFile(
|
|
69
|
+
join(PLUGIN_ROOT, 'config', file),
|
|
70
|
+
join(paths.config, file),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
spinner.succeed(`${configFiles.length} config files installed`);
|
|
74
|
+
|
|
75
|
+
// Update CLAUDE.md
|
|
76
|
+
spinner.start('Updating CLAUDE.md...');
|
|
77
|
+
await updateClaudeMd(paths.claudeMd);
|
|
78
|
+
spinner.succeed('CLAUDE.md updated');
|
|
79
|
+
|
|
80
|
+
console.log(`\n✓ blueprint installed (${scope})`);
|
|
81
|
+
console.log(` Commands: ${paths.commands}`);
|
|
82
|
+
console.log(` Run /blueprint:help to get started\n`);
|
|
83
|
+
}
|
package/src/paths.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { homedir } from 'os';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
|
|
4
|
+
export function getTargetPaths(scope) {
|
|
5
|
+
if (scope === 'global') {
|
|
6
|
+
const base = join(homedir(), '.claude');
|
|
7
|
+
return {
|
|
8
|
+
commands: join(base, 'commands', 'blueprint'),
|
|
9
|
+
agents: join(base, 'commands', 'blueprint', 'agents'),
|
|
10
|
+
config: join(base, 'commands', 'blueprint', 'config'),
|
|
11
|
+
claudeMd: join(base, 'CLAUDE.md'),
|
|
12
|
+
scope: 'global',
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Project scope
|
|
17
|
+
const base = join(process.cwd(), '.claude');
|
|
18
|
+
return {
|
|
19
|
+
commands: join(base, 'commands', 'blueprint'),
|
|
20
|
+
agents: join(base, 'commands', 'blueprint', 'agents'),
|
|
21
|
+
config: join(base, 'commands', 'blueprint', 'config'),
|
|
22
|
+
claudeMd: join(process.cwd(), 'CLAUDE.md'),
|
|
23
|
+
scope: 'project',
|
|
24
|
+
};
|
|
25
|
+
}
|
package/src/verify.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { access } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { getTargetPaths } from './paths.js';
|
|
4
|
+
|
|
5
|
+
const EXPECTED_COMMANDS = [
|
|
6
|
+
'SKILL.md',
|
|
7
|
+
'help/SKILL.md',
|
|
8
|
+
'list/SKILL.md',
|
|
9
|
+
'new/SKILL.md',
|
|
10
|
+
'review/SKILL.md',
|
|
11
|
+
'transition/SKILL.md',
|
|
12
|
+
'search/SKILL.md',
|
|
13
|
+
'impact/SKILL.md',
|
|
14
|
+
'audit/SKILL.md',
|
|
15
|
+
'retro/SKILL.md',
|
|
16
|
+
'evaluate/SKILL.md',
|
|
17
|
+
'rearchitect/SKILL.md',
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const EXPECTED_AGENTS = [
|
|
21
|
+
'persona.md',
|
|
22
|
+
'adr-researcher.md',
|
|
23
|
+
'adr-devils-advocate.md',
|
|
24
|
+
'adr-impact-analyzer.md',
|
|
25
|
+
'adr-compliance-auditor.md',
|
|
26
|
+
'adr-consistency-auditor.md',
|
|
27
|
+
'adr-bug-surface-mapper.md',
|
|
28
|
+
'adr-maintainability-assessor.md',
|
|
29
|
+
'adr-testing-strategy-evaluator.md',
|
|
30
|
+
'adr-conways-law-analyzer.md',
|
|
31
|
+
'adr-retrospective.md',
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const EXPECTED_CONFIG = [
|
|
35
|
+
'lifecycle.toml',
|
|
36
|
+
'taxonomy.toml',
|
|
37
|
+
'state.toml',
|
|
38
|
+
'relationships.toml',
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
async function fileExists(path) {
|
|
42
|
+
try {
|
|
43
|
+
await access(path);
|
|
44
|
+
return true;
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function verify(opts) {
|
|
51
|
+
const scopes = opts.scope ? [opts.scope] : ['global', 'project'];
|
|
52
|
+
let found = false;
|
|
53
|
+
|
|
54
|
+
for (const scope of scopes) {
|
|
55
|
+
const paths = getTargetPaths(scope);
|
|
56
|
+
const exists = await fileExists(join(paths.commands, 'SKILL.md'));
|
|
57
|
+
if (!exists) continue;
|
|
58
|
+
found = true;
|
|
59
|
+
|
|
60
|
+
console.log(`\n✓ blueprint found (${scope}): ${paths.commands}\n`);
|
|
61
|
+
|
|
62
|
+
let missing = 0;
|
|
63
|
+
|
|
64
|
+
// Check commands
|
|
65
|
+
for (const cmd of EXPECTED_COMMANDS) {
|
|
66
|
+
const ok = await fileExists(join(paths.commands, cmd));
|
|
67
|
+
console.log(` ${ok ? '✓' : '✗'} commands/${cmd}`);
|
|
68
|
+
if (!ok) missing++;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check agents
|
|
72
|
+
for (const agent of EXPECTED_AGENTS) {
|
|
73
|
+
const ok = await fileExists(join(paths.agents, agent));
|
|
74
|
+
console.log(` ${ok ? '✓' : '✗'} agents/${agent}`);
|
|
75
|
+
if (!ok) missing++;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check config
|
|
79
|
+
for (const cfg of EXPECTED_CONFIG) {
|
|
80
|
+
const ok = await fileExists(join(paths.config, cfg));
|
|
81
|
+
console.log(` ${ok ? '✓' : '✗'} config/${cfg}`);
|
|
82
|
+
if (!ok) missing++;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Check CLAUDE.md
|
|
86
|
+
const claudeOk = await fileExists(paths.claudeMd);
|
|
87
|
+
console.log(` ${claudeOk ? '✓' : '✗'} CLAUDE.md`);
|
|
88
|
+
|
|
89
|
+
console.log(`\n ${missing === 0 ? '✓ Installation complete' : `✗ ${missing} files missing — run claude-blueprint install`}\n`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!found) {
|
|
93
|
+
console.log('\n✗ blueprint not found. Run: claude-blueprint install\n');
|
|
94
|
+
}
|
|
95
|
+
}
|