codingbuddy-rules 5.4.0 → 5.5.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/.ai-rules/adapters/claude-code.md +52 -2
- package/bin/cli.js +32 -12
- package/lib/init/detect-tools.js +40 -0
- package/lib/init/generate-adapter.js +76 -0
- package/lib/init/team.js +76 -0
- package/package.json +1 -1
|
@@ -6,6 +6,52 @@ This guide explains how to use the common AI rules (`.ai-rules/`) in Claude Code
|
|
|
6
6
|
|
|
7
7
|
Claude Code uses the `.claude/` directory for project-specific custom instructions, referencing the common rules from `.ai-rules/`.
|
|
8
8
|
|
|
9
|
+
## Collective Intelligence with `activate` + Claude Native Teams
|
|
10
|
+
|
|
11
|
+
### The `activate` Tool (Recommended Entry Point)
|
|
12
|
+
|
|
13
|
+
The `activate` MCP tool is the **one-shot entry point** for collective intelligence workflows in Claude Code. It replaces the multi-step `parse_mode` + `dispatch_agents` ceremony with a single call.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
activate({ prompt: "design auth feature", mode: "PLAN" })
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Returns:**
|
|
20
|
+
- `mode` — resolved workflow mode
|
|
21
|
+
- `rules` — loaded rules for the mode
|
|
22
|
+
- `primaryAgent` — agent name + full system prompt
|
|
23
|
+
- `specialists` — recommended specialists with full prompts
|
|
24
|
+
- `discussion` — format guide for approve/concern/reject consensus
|
|
25
|
+
- `nativeIntegration` — guidance for Teams, Memory, orchestration
|
|
26
|
+
|
|
27
|
+
### Running a Specialist Council via Claude Native Teams
|
|
28
|
+
|
|
29
|
+
When `activate` returns specialists, use Claude native Teams for real-time debate:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
1. activate({ prompt }) → get specialists
|
|
33
|
+
2. TeamCreate({ team_name: "plan-council" })
|
|
34
|
+
3. For each specialist: Agent({ team_name, name: specialist.name, prompt: specialist.prompt })
|
|
35
|
+
4. Specialists analyze independently → cross-review → consensus
|
|
36
|
+
5. Collect findings → summarize to user
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Claude Code Native Feature Mapping
|
|
40
|
+
|
|
41
|
+
Use Claude Code native features instead of legacy codingbuddy tools:
|
|
42
|
+
|
|
43
|
+
| Need | Use This | Instead of |
|
|
44
|
+
|------|----------|------------|
|
|
45
|
+
| Workflow entry | `activate` | `parse_mode` + `dispatch_agents` |
|
|
46
|
+
| Cross-session context | Claude Code Memory | `update_context` / `create_briefing` / `resume_session` |
|
|
47
|
+
| Specialist execution | Claude native Teams | subagent dispatch |
|
|
48
|
+
| Task exploration | `/dream` | `analyze_task` |
|
|
49
|
+
| Planning approval | `EnterPlanMode` | planning stage routing |
|
|
50
|
+
| Repeated execution | `/loop` | AUTO mode repetition |
|
|
51
|
+
| Clarification | `AskUserQuestion` | clarification gate |
|
|
52
|
+
|
|
53
|
+
> **Note**: `parse_mode` remains available for non-Claude Code hosts (Cursor, Codex, etc.).
|
|
54
|
+
|
|
9
55
|
## 🆕 Code Conventions Support
|
|
10
56
|
|
|
11
57
|
CodingBuddy now automatically enforces project code conventions from config files:
|
|
@@ -325,9 +371,13 @@ AI assistants should display the `activation_message.formatted` field at the sta
|
|
|
325
371
|
|
|
326
372
|
CodingBuddy supports parallel execution of multiple specialist agents for comprehensive analysis.
|
|
327
373
|
|
|
328
|
-
###
|
|
374
|
+
### Recommended: Claude Native Teams (Primary Strategy)
|
|
375
|
+
|
|
376
|
+
In Claude Code environments, use **Claude native Teams** as the primary execution strategy for specialist councils. The `activate` tool returns specialist prompts ready for Teams execution. See the "Collective Intelligence with `activate`" section above for the full workflow.
|
|
377
|
+
|
|
378
|
+
### Legacy: SubAgent / TaskMaestro Strategies
|
|
329
379
|
|
|
330
|
-
|
|
380
|
+
For non-Claude Code hosts or when Teams is not available, parallel execution is recommended when `parse_mode` returns a `parallelAgentsRecommendation` field:
|
|
331
381
|
|
|
332
382
|
| Mode | Default Specialists | Use Case |
|
|
333
383
|
|------|---------------------|----------|
|
package/bin/cli.js
CHANGED
|
@@ -16,13 +16,16 @@ Usage:
|
|
|
16
16
|
codingbuddy <command> [options]
|
|
17
17
|
|
|
18
18
|
Commands:
|
|
19
|
-
init
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
init Initialize .ai-rules in the current project
|
|
20
|
+
init --team Detect AI tools and generate adapter configs for all
|
|
21
|
+
validate Validate .ai-rules structure (agents JSON, rules markdown)
|
|
22
|
+
list-agents List available specialist agents
|
|
22
23
|
|
|
23
24
|
Options:
|
|
24
|
-
--help, -h
|
|
25
|
-
--version, -v
|
|
25
|
+
--help, -h Show this help message
|
|
26
|
+
--version, -v Show version
|
|
27
|
+
--dry-run Preview changes without writing (init --team)
|
|
28
|
+
--force Overwrite without backup (init --team)
|
|
26
29
|
`.trim(),
|
|
27
30
|
);
|
|
28
31
|
}
|
|
@@ -130,12 +133,23 @@ function validate() {
|
|
|
130
133
|
console.log('\nAll validations passed');
|
|
131
134
|
}
|
|
132
135
|
|
|
133
|
-
function init() {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
function init(flags) {
|
|
137
|
+
if (flags.team) {
|
|
138
|
+
const { runTeam } = require('../lib/init/team');
|
|
139
|
+
runTeam(process.cwd(), {
|
|
140
|
+
dryRun: flags.dryRun,
|
|
141
|
+
force: flags.force,
|
|
142
|
+
}).catch(err => {
|
|
143
|
+
console.error('Error:', err.message);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
|
146
|
+
} else {
|
|
147
|
+
const { run } = require('../lib/init');
|
|
148
|
+
run().catch(err => {
|
|
149
|
+
console.error('Error:', err.message);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
139
153
|
}
|
|
140
154
|
|
|
141
155
|
// --- Main ---
|
|
@@ -153,9 +167,15 @@ if (command === '--version' || command === '-v') {
|
|
|
153
167
|
process.exit(0);
|
|
154
168
|
}
|
|
155
169
|
|
|
170
|
+
const flags = {
|
|
171
|
+
team: args.includes('--team'),
|
|
172
|
+
dryRun: args.includes('--dry-run'),
|
|
173
|
+
force: args.includes('--force'),
|
|
174
|
+
};
|
|
175
|
+
|
|
156
176
|
switch (command) {
|
|
157
177
|
case 'init':
|
|
158
|
-
init();
|
|
178
|
+
init(flags);
|
|
159
179
|
break;
|
|
160
180
|
case 'validate':
|
|
161
181
|
validate();
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Supported AI coding tool definitions.
|
|
8
|
+
* Each entry maps a tool name to its config directory and indicator file.
|
|
9
|
+
*/
|
|
10
|
+
const AI_TOOLS = [
|
|
11
|
+
{ name: 'cursor', configDir: '.cursor', indicator: 'rules' },
|
|
12
|
+
{ name: 'claude-code', configDir: '.claude', indicator: 'settings.json' },
|
|
13
|
+
{ name: 'codex', configDir: '.codex', indicator: 'instructions.md' },
|
|
14
|
+
{ name: 'antigravity', configDir: '.antigravity', indicator: 'instructions.md' },
|
|
15
|
+
{ name: 'amazon-q', configDir: '.q', indicator: 'settings.json' },
|
|
16
|
+
{ name: 'kiro', configDir: '.kiro', indicator: 'settings.json' },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Detect installed AI coding tools by scanning for their config directories.
|
|
21
|
+
* @param {string} cwd - Directory to scan
|
|
22
|
+
* @returns {Array<{ name: string, configDir: string, indicator: string, exists: boolean, hasConfig: boolean }>}
|
|
23
|
+
*/
|
|
24
|
+
function detectTools(cwd) {
|
|
25
|
+
return AI_TOOLS.map(tool => {
|
|
26
|
+
const dirPath = path.join(cwd, tool.configDir);
|
|
27
|
+
const exists = fs.existsSync(dirPath);
|
|
28
|
+
const hasConfig =
|
|
29
|
+
exists && fs.existsSync(path.join(dirPath, tool.indicator));
|
|
30
|
+
return {
|
|
31
|
+
name: tool.name,
|
|
32
|
+
configDir: tool.configDir,
|
|
33
|
+
indicator: tool.indicator,
|
|
34
|
+
exists,
|
|
35
|
+
hasConfig,
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = { detectTools, AI_TOOLS };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Maps tool names to their adapter template file and output target path.
|
|
8
|
+
*/
|
|
9
|
+
const ADAPTER_MAP = {
|
|
10
|
+
cursor: { adapter: 'cursor.md', target: '.cursor/rules/codingbuddy.mdc' },
|
|
11
|
+
'claude-code': { adapter: 'claude-code.md', target: '.claude/CLAUDE.md' },
|
|
12
|
+
codex: { adapter: 'codex.md', target: '.codex/instructions.md' },
|
|
13
|
+
antigravity: { adapter: 'antigravity.md', target: '.antigravity/instructions.md' },
|
|
14
|
+
'amazon-q': { adapter: 'q.md', target: '.q/rules/codingbuddy.md' },
|
|
15
|
+
kiro: { adapter: 'kiro.md', target: '.kiro/rules/codingbuddy.md' },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Generate adapter-specific configs for detected AI tools from shared .ai-rules.
|
|
20
|
+
* @param {string} cwd - Project root directory
|
|
21
|
+
* @param {Array<{ name: string }>} detectedTools - Tools to generate configs for
|
|
22
|
+
* @param {{ dryRun?: boolean, force?: boolean }} [options]
|
|
23
|
+
* @returns {{ generated: Array, backedUp: Array, skipped: Array }}
|
|
24
|
+
*/
|
|
25
|
+
function generateAdapterConfigs(cwd, detectedTools, options) {
|
|
26
|
+
const { dryRun = false, force = false } = options || {};
|
|
27
|
+
const result = { generated: [], backedUp: [], skipped: [] };
|
|
28
|
+
const adaptersDir = path.join(cwd, '.ai-rules', 'adapters');
|
|
29
|
+
|
|
30
|
+
for (const tool of detectedTools) {
|
|
31
|
+
if (!Object.hasOwn(ADAPTER_MAP, tool.name)) {
|
|
32
|
+
result.skipped.push({ tool: tool.name, reason: 'no adapter mapping' });
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const mapping = ADAPTER_MAP[tool.name];
|
|
37
|
+
const adapterPath = path.join(adaptersDir, mapping.adapter);
|
|
38
|
+
if (!fs.existsSync(adapterPath)) {
|
|
39
|
+
result.skipped.push({ tool: tool.name, reason: 'adapter template not found' });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const targetPath = path.join(cwd, mapping.target);
|
|
44
|
+
|
|
45
|
+
if (dryRun) {
|
|
46
|
+
result.generated.push({ tool: tool.name, path: mapping.target, action: 'would-create' });
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Read adapter template (only when not dry-run)
|
|
51
|
+
const content = fs.readFileSync(adapterPath, 'utf-8');
|
|
52
|
+
|
|
53
|
+
// Backup existing config unless --force; skip symlinks for safety
|
|
54
|
+
if (fs.existsSync(targetPath) && !force) {
|
|
55
|
+
const stat = fs.lstatSync(targetPath);
|
|
56
|
+
if (!stat.isSymbolicLink()) {
|
|
57
|
+
const backupDir = path.join(cwd, '.codingbuddy-backup');
|
|
58
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
59
|
+
const timestamp = Date.now();
|
|
60
|
+
const backupName = path.basename(mapping.target) + '.' + timestamp + '.bak';
|
|
61
|
+
const backupPath = path.join(backupDir, tool.name + '-' + backupName);
|
|
62
|
+
fs.copyFileSync(targetPath, backupPath);
|
|
63
|
+
result.backedUp.push({ tool: tool.name, from: mapping.target, to: backupPath });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Write adapter config
|
|
68
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
69
|
+
fs.writeFileSync(targetPath, content, 'utf-8');
|
|
70
|
+
result.generated.push({ tool: tool.name, path: mapping.target, action: 'created' });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = { generateAdapterConfigs, ADAPTER_MAP };
|
package/lib/init/team.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { detectTools } = require('./detect-tools');
|
|
4
|
+
const { generateAdapterConfigs } = require('./generate-adapter');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Run the team bootstrap flow: detect AI tools + generate adapter configs.
|
|
8
|
+
* @param {string} [cwd=process.cwd()]
|
|
9
|
+
* @param {{ dryRun?: boolean, force?: boolean }} [options]
|
|
10
|
+
* @returns {Promise<{ detected: number, generated: number, backedUp: number, skipped: number }>}
|
|
11
|
+
*/
|
|
12
|
+
async function runTeam(cwd, options) {
|
|
13
|
+
const targetDir = cwd || process.cwd();
|
|
14
|
+
const { dryRun = false, force = false } = options || {};
|
|
15
|
+
|
|
16
|
+
console.log('\n codingbuddy init --team\n');
|
|
17
|
+
|
|
18
|
+
// Step 1: Detect AI tools
|
|
19
|
+
console.log(' Scanning for AI coding tools...');
|
|
20
|
+
const tools = detectTools(targetDir);
|
|
21
|
+
const detected = tools.filter(t => t.exists);
|
|
22
|
+
const notDetected = tools.filter(t => !t.exists);
|
|
23
|
+
|
|
24
|
+
if (detected.length > 0) {
|
|
25
|
+
console.log(` Found ${detected.length} tool(s):`);
|
|
26
|
+
for (const tool of detected) {
|
|
27
|
+
const status = tool.hasConfig
|
|
28
|
+
? '\u26a0 has existing config \u2014 will overwrite (backup auto-created)'
|
|
29
|
+
: '(no config)';
|
|
30
|
+
console.log(` \u2713 ${tool.name} ${status}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (notDetected.length > 0) {
|
|
35
|
+
console.log(` Not found: ${notDetected.map(t => t.name).join(', ')}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Step 2: Generate adapter configs
|
|
39
|
+
if (detected.length === 0) {
|
|
40
|
+
console.log('\n No AI tools detected. Nothing to configure.\n');
|
|
41
|
+
return { detected: 0, generated: 0, backedUp: 0, skipped: 0 };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (dryRun) {
|
|
45
|
+
console.log('\n Dry run \u2014 previewing changes:');
|
|
46
|
+
} else {
|
|
47
|
+
console.log('\n Generating adapter configs...');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const result = generateAdapterConfigs(targetDir, detected, { dryRun, force });
|
|
51
|
+
|
|
52
|
+
for (const item of result.generated) {
|
|
53
|
+
const verb = dryRun ? 'would create' : 'created';
|
|
54
|
+
console.log(` ${verb}: ${item.path}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (const item of result.backedUp) {
|
|
58
|
+
console.log(` backed up: ${item.from}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const item of result.skipped) {
|
|
62
|
+
console.log(` skipped: ${item.tool} (${item.reason})`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const verb = dryRun ? 'would be generated' : 'generated';
|
|
66
|
+
console.log(`\n Done! ${result.generated.length} config(s) ${verb}.\n`);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
detected: detected.length,
|
|
70
|
+
generated: result.generated.length,
|
|
71
|
+
backedUp: result.backedUp.length,
|
|
72
|
+
skipped: result.skipped.length,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = { runTeam };
|