claude-flow-novice 2.3.8 → 2.4.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/SYNC_USAGE.md ADDED
@@ -0,0 +1,191 @@
1
+ # Claude Flow Novice - Sync Guide
2
+
3
+ ## Installation & Setup
4
+
5
+ ### 1. Install Package
6
+
7
+ ```bash
8
+ npm install claude-flow-novice
9
+ ```
10
+
11
+ ### 2. Sync Agents, Commands, and Hooks
12
+
13
+ After installation, sync the latest agents, slash commands, and validation hooks to your project:
14
+
15
+ ```bash
16
+ # Sync everything with backup
17
+ npx claude-flow-sync --backup
18
+
19
+ # Or use the longer form
20
+ node node_modules/claude-flow-novice/scripts/sync-from-package.js --backup
21
+ ```
22
+
23
+ ## Sync Options
24
+
25
+ ### Sync Everything (Recommended for first time)
26
+
27
+ ```bash
28
+ npx claude-flow-sync --backup
29
+ ```
30
+
31
+ This syncs:
32
+ - `.claude/agents/` - All agent definitions (94 files)
33
+ - `.claude/commands/` - Slash commands
34
+ - `config/hooks/` - Validation hooks
35
+
36
+ ### Selective Sync
37
+
38
+ ```bash
39
+ # Sync only agents
40
+ npx claude-flow-sync --agents --backup
41
+
42
+ # Sync only commands
43
+ npx claude-flow-sync --commands --backup
44
+
45
+ # Sync only hooks
46
+ npx claude-flow-sync --hooks --backup
47
+
48
+ # Combine multiple
49
+ npx claude-flow-sync --agents --hooks --backup
50
+ ```
51
+
52
+ ### Force Overwrite
53
+
54
+ Use `--force` to overwrite existing files without prompting:
55
+
56
+ ```bash
57
+ npx claude-flow-sync --force --backup
58
+ ```
59
+
60
+ **⚠️ Warning**: `--force` will overwrite your customizations. Always use `--backup` with `--force`.
61
+
62
+ ## Update Workflow
63
+
64
+ ### When Package Updates
65
+
66
+ ```bash
67
+ # 1. Update package
68
+ npm update claude-flow-novice
69
+
70
+ # 2. Sync new changes (creates backup automatically)
71
+ npx claude-flow-sync --backup
72
+
73
+ # 3. Review changes
74
+ git diff .claude/ config/
75
+
76
+ # 4. Merge customizations if needed
77
+ # Restore from .backup-YYYY-MM-DD if you need your custom changes
78
+ ```
79
+
80
+ ### Customizing Agents/Commands
81
+
82
+ 1. **Initial sync**:
83
+ ```bash
84
+ npx claude-flow-sync --backup
85
+ ```
86
+
87
+ 2. **Customize** your local copies in:
88
+ - `.claude/agents/`
89
+ - `.claude/commands/`
90
+ - `config/hooks/`
91
+
92
+ 3. **Update from package** (preserves your changes):
93
+ ```bash
94
+ # WITHOUT --force, you'll be warned about existing files
95
+ npx claude-flow-sync --backup
96
+
97
+ # Review what changed in the package
98
+ diff -r .claude/agents/ .claude/agents.backup-YYYY-MM-DD/
99
+
100
+ # Manually merge changes you want
101
+ ```
102
+
103
+ ## File Locations After Sync
104
+
105
+ ```
106
+ your-project/
107
+ ├── .claude/
108
+ │ ├── agents/ # ✅ Synced from package (94 files)
109
+ │ └── commands/ # ✅ Synced from package
110
+ ├── config/
111
+ │ └── hooks/ # ✅ Synced from package (13+ files)
112
+ └── node_modules/
113
+ └── claude-flow-novice/
114
+ ├── .claude/ # Source (in npm package)
115
+ ├── config/ # Source (in npm package)
116
+ └── scripts/ # Source (in npm package)
117
+ ```
118
+
119
+ ## Backup Management
120
+
121
+ Backups are created as:
122
+ - `.claude/agents.backup-2025-10-17/`
123
+ - `.claude/commands.backup-2025-10-17/`
124
+ - `config/hooks.backup-2025-10-17/`
125
+
126
+ ### Restore from Backup
127
+
128
+ ```bash
129
+ # If you need to restore
130
+ rm -rf .claude/agents/
131
+ mv .claude/agents.backup-2025-10-17/ .claude/agents/
132
+ ```
133
+
134
+ ## Examples
135
+
136
+ ### First-Time Setup
137
+ ```bash
138
+ npm install claude-flow-novice
139
+ npx claude-flow-sync --backup
140
+ ```
141
+
142
+ ### Regular Updates
143
+ ```bash
144
+ npm update claude-flow-novice
145
+ npx claude-flow-sync --backup
146
+ # Review changes with: git diff
147
+ ```
148
+
149
+ ### Force Update Everything
150
+ ```bash
151
+ npx claude-flow-sync --force --backup
152
+ ```
153
+
154
+ ### Update Only Hooks (Get Latest Validators)
155
+ ```bash
156
+ npx claude-flow-sync --hooks --force --backup
157
+ ```
158
+
159
+ ## What Gets Synced
160
+
161
+ | Directory | Files | Description |
162
+ |-----------|-------|-------------|
163
+ | `.claude/agents/` | 94 | Agent definitions (optimized, Phase 4) |
164
+ | `.claude/commands/` | 50+ | Slash commands |
165
+ | `config/hooks/` | 13+ | Validation hooks (post-edit, etc.) |
166
+
167
+ ## What Doesn't Get Synced
168
+
169
+ - `scripts/` - Only package utilities, not project-specific scripts
170
+ - `readme/` - Package documentation (not project-specific)
171
+ - `src/` - Package source code (not for project use)
172
+
173
+ ## Troubleshooting
174
+
175
+ ### "Source directory not found"
176
+ Your package might be outdated. Update it:
177
+ ```bash
178
+ npm update claude-flow-novice
179
+ ```
180
+
181
+ ### "Destination exists" Warning
182
+ Without `--force`, sync won't overwrite. Use:
183
+ ```bash
184
+ npx claude-flow-sync --force --backup
185
+ ```
186
+
187
+ ### Lost Customizations
188
+ Restore from backup:
189
+ ```bash
190
+ mv .claude/agents.backup-YYYY-MM-DD/ .claude/agents/
191
+ ```
@@ -1480,6 +1480,43 @@ class UnifiedPostEditPipeline {
1480
1480
  }
1481
1481
 
1482
1482
  const projectDir = this.findProjectRoot(filePath);
1483
+
1484
+ // TypeScript incremental type checking (single-file mode)
1485
+ if (language === 'typescript' && tool === 'tsc') {
1486
+ const tsArgs = [...args, '--skipLibCheck', filePath];
1487
+
1488
+ try {
1489
+ const result = await this.runCommand(tool, tsArgs, projectDir);
1490
+
1491
+ // Parse TypeScript error output from both stdout and stderr
1492
+ const allOutput = result.stdout + result.stderr;
1493
+ const errorLines = allOutput.split('\n').filter(line => line.includes('error TS'));
1494
+ const errorCount = errorLines.length;
1495
+
1496
+ return {
1497
+ success: result.code === 0 && errorCount === 0,
1498
+ message: result.code === 0 ? 'TypeScript compilation passed' : `${errorCount} TypeScript error(s)`,
1499
+ output: allOutput,
1500
+ errors: errorCount > 0 ? errorLines.join('\n') : '',
1501
+ errorCount,
1502
+ errorLines: errorLines.slice(0, 10), // First 10 errors for feedback
1503
+ wasmAccelerated
1504
+ };
1505
+ } catch (error) {
1506
+ // Handle TypeScript compiler crashes gracefully
1507
+ return {
1508
+ success: false,
1509
+ message: 'TypeScript compiler error',
1510
+ output: error.message || error.stderr || '',
1511
+ errors: error.message || 'TypeScript compilation failed',
1512
+ errorCount: 1,
1513
+ errorLines: [(error.message || 'Unknown compiler error')],
1514
+ wasmAccelerated
1515
+ };
1516
+ }
1517
+ }
1518
+
1519
+ // Standard type checking for other languages
1483
1520
  const result = await this.runCommand(tool, args, projectDir);
1484
1521
 
1485
1522
  return {
@@ -2126,6 +2163,18 @@ class UnifiedPostEditPipeline {
2126
2163
  if (!results.steps.typeCheck.success) {
2127
2164
  results.summary.errors.push(`Type errors in ${path.basename(filePath)}`);
2128
2165
  results.summary.success = false;
2166
+
2167
+ // Send TYPE_ERROR feedback to agent
2168
+ await this.sendAgentFeedback({
2169
+ type: 'TYPE_ERROR',
2170
+ file: filePath,
2171
+ severity: 'error',
2172
+ language,
2173
+ errorCount: results.steps.typeCheck.errorCount || 0,
2174
+ errorLines: results.steps.typeCheck.errorLines || [],
2175
+ errors: results.steps.typeCheck.errors,
2176
+ message: `${results.steps.typeCheck.errorCount || 'Unknown'} TypeScript error(s) in ${path.basename(filePath)}`
2177
+ });
2129
2178
  }
2130
2179
 
2131
2180
  // Step 4: Rust Quality Enforcement (if Rust and strict mode)
package/package.json CHANGED
@@ -1,16 +1,18 @@
1
1
  {
2
2
  "name": "claude-flow-novice",
3
- "version": "2.3.8",
3
+ "version": "2.4.0",
4
4
  "description": "AI Agent Orchestration CLI",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
7
- "claude-flow-novice": "./src/cli/index.ts"
7
+ "claude-flow-novice": "./src/cli/index.ts",
8
+ "claude-flow-sync": "./scripts/sync-from-package.js"
8
9
  },
9
10
  "files": [
10
11
  "src",
11
12
  "README.md",
12
13
  "CHANGELOG.md",
13
14
  "LICENSE",
15
+ "SYNC_USAGE.md",
14
16
  "config",
15
17
  "scripts",
16
18
  ".claude",
@@ -21,6 +23,8 @@
21
23
  "clean": "rimraf dist",
22
24
  "lint": "eslint . --ext .ts",
23
25
  "typecheck": "tsc --noEmit",
26
+ "type-coverage": "type-coverage --detail --ignore-files 'src/__tests__/**' --ignore-files '**/*.test.ts'",
27
+ "type-coverage:ci": "type-coverage --at-least 80 --ignore-files 'src/__tests__/**' --ignore-files '**/*.test.ts'",
24
28
  "test": "jest",
25
29
  "test:coverage": "jest --coverage",
26
30
  "prepublish-checks": "node scripts/prepublish-checks.js",
@@ -28,7 +32,8 @@
28
32
  "security-scan": "snyk test && npm audit --audit-level=high",
29
33
  "bundle-size-check": "bundlesize",
30
34
  "smoke-test": "npm pack && node scripts/smoke-test.js",
31
- "changelog": "standard-version"
35
+ "changelog": "standard-version",
36
+ "create:component": "node scripts/create-component.js"
32
37
  },
33
38
  "keywords": [
34
39
  "ai",
@@ -53,15 +58,19 @@
53
58
  },
54
59
  "devDependencies": {
55
60
  "@types/node": "^20.0.0",
56
- "typescript": "^5.0.0",
57
- "jest": "^29.0.0",
61
+ "bundlesize": "^0.18.1",
58
62
  "eslint": "^8.0.0",
59
- "rollup": "^3.0.0",
63
+ "husky": "^8.0.0",
64
+ "jest": "^29.0.0",
60
65
  "rimraf": "^5.0.0",
61
- "bundlesize": "^0.18.1",
62
- "snyk": "^1.0.0",
66
+ "rollup": "^3.0.0",
63
67
  "semantic-release": "^21.0.0",
68
+ "snyk": "^1.0.0",
64
69
  "standard-version": "^9.0.0",
65
- "husky": "^8.0.0"
70
+ "type-coverage": "^2.29.7",
71
+ "typescript": "^5.9.3"
72
+ },
73
+ "dependencies": {
74
+ "ioredis": "^5.8.1"
66
75
  }
67
76
  }
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Component Template Generator
5
+ * Creates TypeScript components with proper type declarations and tests
6
+ *
7
+ * Usage:
8
+ * node scripts/create-component.js <ComponentName> <directory>
9
+ *
10
+ * Example:
11
+ * node scripts/create-component.js SwarmCoordinator src/coordination
12
+ */
13
+
14
+ import fs from 'fs';
15
+ import path from 'path';
16
+ import { fileURLToPath } from 'url';
17
+
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = path.dirname(__filename);
20
+
21
+ const [, , componentName, componentDir] = process.argv;
22
+
23
+ if (!componentName || !componentDir) {
24
+ console.log(`
25
+ 🔧 Component Template Generator
26
+
27
+ Usage: node scripts/create-component.js <ComponentName> <directory>
28
+
29
+ Arguments:
30
+ ComponentName Name of the component (PascalCase)
31
+ directory Target directory (e.g., src/coordination)
32
+
33
+ Examples:
34
+ node scripts/create-component.js SwarmCoordinator src/coordination
35
+ node scripts/create-component.js TaskValidator src/validation
36
+ node scripts/create-component.js RedisClient src/services
37
+
38
+ Generated files:
39
+ ✅ <directory>/<ComponentName>.ts - Main implementation
40
+ ✅ <directory>/<ComponentName>.test.ts - Test file with basic setup
41
+ ✅ <directory>/types.ts - Type definitions (if doesn't exist)
42
+ `);
43
+ process.exit(1);
44
+ }
45
+
46
+ const projectRoot = path.resolve(__dirname, '..');
47
+
48
+ // Validate component name (PascalCase)
49
+ if (!/^[A-Z][a-zA-Z0-9]*$/.test(componentName)) {
50
+ console.error(`❌ Error: Component name must be PascalCase (e.g., SwarmCoordinator, not swarm-coordinator)`);
51
+ process.exit(1);
52
+ }
53
+
54
+ // Create directory if it doesn't exist
55
+ const targetDir = path.join(projectRoot, componentDir);
56
+ if (!fs.existsSync(targetDir)) {
57
+ fs.mkdirSync(targetDir, { recursive: true });
58
+ console.log(`📁 Created directory: ${componentDir}/`);
59
+ }
60
+
61
+ // Component file template
62
+ const componentTemplate = `/**
63
+ * ${componentName}
64
+ *
65
+ * TODO: Add component description
66
+ */
67
+
68
+ export interface ${componentName}Options {
69
+ // TODO: Define configuration options
70
+ }
71
+
72
+ export class ${componentName} {
73
+ private options: ${componentName}Options;
74
+
75
+ constructor(options: ${componentName}Options) {
76
+ this.options = options;
77
+ }
78
+
79
+ // TODO: Implement methods
80
+ async initialize(): Promise<void> {
81
+ // Initialization logic
82
+ }
83
+
84
+ async execute(): Promise<void> {
85
+ // Main execution logic
86
+ }
87
+
88
+ async cleanup(): Promise<void> {
89
+ // Cleanup logic
90
+ }
91
+ }
92
+ `;
93
+
94
+ // Test file template
95
+ const testTemplate = `import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
96
+ import { ${componentName} } from './${componentName}';
97
+
98
+ describe('${componentName}', () => {
99
+ let component: ${componentName};
100
+
101
+ beforeEach(() => {
102
+ component = new ${componentName}({
103
+ // TODO: Add test configuration
104
+ });
105
+ });
106
+
107
+ afterEach(async () => {
108
+ await component.cleanup();
109
+ });
110
+
111
+ describe('initialization', () => {
112
+ it('should initialize successfully', async () => {
113
+ await component.initialize();
114
+ // TODO: Add assertions
115
+ expect(component).toBeDefined();
116
+ });
117
+ });
118
+
119
+ describe('execution', () => {
120
+ it('should execute successfully', async () => {
121
+ await component.initialize();
122
+ await component.execute();
123
+ // TODO: Add assertions
124
+ });
125
+ });
126
+
127
+ describe('error handling', () => {
128
+ it('should handle errors gracefully', async () => {
129
+ // TODO: Test error scenarios
130
+ });
131
+ });
132
+ });
133
+ `;
134
+
135
+ // Types file template (only create if doesn't exist)
136
+ const typesTemplate = `/**
137
+ * Type definitions for ${componentDir}
138
+ */
139
+
140
+ export interface BaseOptions {
141
+ enabled?: boolean;
142
+ debug?: boolean;
143
+ }
144
+
145
+ // Add shared types here
146
+ `;
147
+
148
+ // Write component file
149
+ const componentPath = path.join(targetDir, `${componentName}.ts`);
150
+ if (fs.existsSync(componentPath)) {
151
+ console.error(`❌ Error: Component file already exists: ${componentPath}`);
152
+ process.exit(1);
153
+ }
154
+ fs.writeFileSync(componentPath, componentTemplate);
155
+ console.log(`✅ Created: ${path.relative(projectRoot, componentPath)}`);
156
+
157
+ // Write test file
158
+ const testPath = path.join(targetDir, `${componentName}.test.ts`);
159
+ if (fs.existsSync(testPath)) {
160
+ console.warn(`⚠️ Warning: Test file already exists: ${testPath} (skipping)`);
161
+ } else {
162
+ fs.writeFileSync(testPath, testTemplate);
163
+ console.log(`✅ Created: ${path.relative(projectRoot, testPath)}`);
164
+ }
165
+
166
+ // Create types file if doesn't exist
167
+ const typesPath = path.join(targetDir, 'types.ts');
168
+ if (!fs.existsSync(typesPath)) {
169
+ fs.writeFileSync(typesPath, typesTemplate);
170
+ console.log(`✅ Created: ${path.relative(projectRoot, typesPath)}`);
171
+ } else {
172
+ console.log(`ℹ️ Types file exists: ${path.relative(projectRoot, typesPath)} (not modified)`);
173
+ }
174
+
175
+ // Create index.ts barrel export if doesn't exist
176
+ const indexPath = path.join(targetDir, 'index.ts');
177
+ const exportLine = `export * from './${componentName}';\n`;
178
+
179
+ if (fs.existsSync(indexPath)) {
180
+ const content = fs.readFileSync(indexPath, 'utf8');
181
+ if (!content.includes(`from './${componentName}'`)) {
182
+ fs.appendFileSync(indexPath, exportLine);
183
+ console.log(`✅ Added export to: ${path.relative(projectRoot, indexPath)}`);
184
+ } else {
185
+ console.log(`ℹ️ Export already exists in: ${path.relative(projectRoot, indexPath)}`);
186
+ }
187
+ } else {
188
+ fs.writeFileSync(indexPath, `export * from './types';\n${exportLine}`);
189
+ console.log(`✅ Created: ${path.relative(projectRoot, indexPath)}`);
190
+ }
191
+
192
+ console.log(`
193
+ ✨ Component generated successfully!
194
+
195
+ Next steps:
196
+ 1. Implement ${componentName} logic in ${componentPath}
197
+ 2. Write tests in ${testPath}
198
+ 3. Run tests: npm test -- ${componentName}
199
+ 4. Run type check: npm run typecheck
200
+ `);
@@ -0,0 +1,427 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Create subcategories within each main agent category
5
+ * Provides finer-grained organization for easier browsing
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const AGENTS_DIR = path.join(__dirname, '../agents');
12
+
13
+ // Subcategory definitions for each main category
14
+ const SUBCATEGORIES = {
15
+ 'development-engineering': {
16
+ 'backend': {
17
+ keywords: ['backend', 'api', 'rest', 'graphql', 'server', 'node', 'django', 'flask', 'express', 'fastapi'],
18
+ description: 'Backend development, APIs, server-side programming'
19
+ },
20
+ 'frontend': {
21
+ keywords: ['frontend', 'react', 'angular', 'vue', 'ui', 'javascript', 'typescript', 'css', 'html', 'web-ui'],
22
+ description: 'Frontend frameworks, UI development, client-side'
23
+ },
24
+ 'mobile': {
25
+ keywords: ['mobile', 'ios', 'android', 'react-native', 'flutter', 'swift', 'kotlin'],
26
+ description: 'Mobile app development (iOS, Android)'
27
+ },
28
+ 'devops': {
29
+ keywords: ['devops', 'docker', 'kubernetes', 'ci-cd', 'cicd', 'deployment', 'container', 'gitops', 'argocd', 'flux', 'jenkins'],
30
+ description: 'DevOps, CI/CD, containerization, orchestration'
31
+ },
32
+ 'testing': {
33
+ keywords: ['test', 'qa', 'quality', 'acceptance', 'cypress', 'jest', 'playwright', 'e2e', 'integration-test', 'unit-test', 'fuzz'],
34
+ description: 'Testing, QA, quality assurance, test automation'
35
+ },
36
+ 'database': {
37
+ keywords: ['database', 'sql', 'nosql', 'postgres', 'mysql', 'mongodb', 'redis', 'data-model'],
38
+ description: 'Database design, SQL, NoSQL, data modeling'
39
+ },
40
+ 'architecture': {
41
+ keywords: ['architect', 'architecture', 'design-pattern', 'microservices', 'system-design', 'scalability'],
42
+ description: 'Software architecture, system design, patterns'
43
+ },
44
+ 'integration': {
45
+ keywords: ['integration', 'api-integration', 'third-party', 'webhook', 'payment-integration', 'oauth'],
46
+ description: 'API integration, third-party services, webhooks'
47
+ }
48
+ },
49
+
50
+ 'industry-specific': {
51
+ 'healthcare': {
52
+ keywords: ['health', 'medical', 'clinical', 'patient', 'doctor', 'hospital', 'telemedicine', 'pharmaceutical'],
53
+ description: 'Healthcare, medical, clinical systems'
54
+ },
55
+ 'finance': {
56
+ keywords: ['finance', 'banking', 'fintech', 'trading', 'investment', 'accounting', 'ledger', 'financial'],
57
+ description: 'Finance, banking, fintech, trading'
58
+ },
59
+ 'legal': {
60
+ keywords: ['legal', 'law', 'attorney', 'court', 'litigation', 'contract', 'compliance-legal'],
61
+ description: 'Legal services, law firms, compliance'
62
+ },
63
+ 'education': {
64
+ keywords: ['education', 'learning', 'student', 'teacher', 'academic', 'e-learning', 'training', 'course'],
65
+ description: 'Education, e-learning, academic systems'
66
+ },
67
+ 'retail': {
68
+ keywords: ['retail', 'e-commerce', 'shop', 'store', 'pos', 'inventory', 'product', 'catalog'],
69
+ description: 'Retail, e-commerce, point-of-sale'
70
+ },
71
+ 'manufacturing': {
72
+ keywords: ['manufactur', 'production', 'factory', 'supply-chain', 'logistics', 'warehouse', 'industrial'],
73
+ description: 'Manufacturing, production, supply chain'
74
+ },
75
+ 'entertainment': {
76
+ keywords: ['entertainment', 'media', 'gaming', 'sports', 'music', 'video', 'streaming', 'content'],
77
+ description: 'Entertainment, media, gaming, sports'
78
+ },
79
+ 'other': {
80
+ keywords: ['real-estate', 'hospitality', 'tourism', 'energy', 'utilities', 'telecom', 'insurance', 'nonprofit'],
81
+ description: 'Other industries (real estate, hospitality, etc.)'
82
+ }
83
+ },
84
+
85
+ 'ai-ml-automation': {
86
+ 'machine-learning': {
87
+ keywords: ['machine-learning', 'ml', 'supervised', 'unsupervised', 'classification', 'regression', 'scikit'],
88
+ description: 'Traditional machine learning, classification, regression'
89
+ },
90
+ 'deep-learning': {
91
+ keywords: ['deep-learning', 'neural', 'tensorflow', 'pytorch', 'keras', 'cnn', 'rnn', 'transformer'],
92
+ description: 'Deep learning, neural networks, frameworks'
93
+ },
94
+ 'nlp': {
95
+ keywords: ['nlp', 'natural-language', 'text', 'sentiment', 'chatbot', 'language-model', 'tokeniz'],
96
+ description: 'Natural language processing, text analysis'
97
+ },
98
+ 'computer-vision': {
99
+ keywords: ['vision', 'image', 'video', 'object-detection', 'facial', 'ocr', 'recognition'],
100
+ description: 'Computer vision, image processing, object detection'
101
+ },
102
+ 'mlops': {
103
+ keywords: ['mlops', 'model-deployment', 'training-pipeline', 'experiment-tracking', 'model-serving'],
104
+ description: 'MLOps, model deployment, training pipelines'
105
+ },
106
+ 'automation': {
107
+ keywords: ['automation', 'intelligent-automation', 'workflow', 'orchestration', 'agent-based'],
108
+ description: 'Intelligent automation, workflow automation'
109
+ }
110
+ },
111
+
112
+ 'business-operations': {
113
+ 'strategy': {
114
+ keywords: ['strategy', 'strategic', 'planning', 'competitive', 'positioning', 'vision'],
115
+ description: 'Business strategy, strategic planning'
116
+ },
117
+ 'growth': {
118
+ keywords: ['growth', 'scaling', 'expansion', 'market-expansion', 'growth-hacking'],
119
+ description: 'Business growth, scaling, expansion'
120
+ },
121
+ 'revenue': {
122
+ keywords: ['revenue', 'sales', 'monetization', 'pricing', 'billing', 'subscription'],
123
+ description: 'Revenue optimization, sales, monetization'
124
+ },
125
+ 'customer': {
126
+ keywords: ['customer', 'client', 'user-experience', 'crm', 'support', 'journey', 'satisfaction'],
127
+ description: 'Customer experience, CRM, support'
128
+ },
129
+ 'operations': {
130
+ keywords: ['operations', 'operational', 'process', 'workflow', 'efficiency', 'optimization'],
131
+ description: 'Operations management, process optimization'
132
+ },
133
+ 'leadership': {
134
+ keywords: ['leadership', 'management', 'executive', 'team-building', 'organizational'],
135
+ description: 'Leadership, management, organizational development'
136
+ }
137
+ },
138
+
139
+ 'data-analytics': {
140
+ 'business-intelligence': {
141
+ keywords: ['business-intelligence', 'bi', 'dashboard', 'reporting', 'kpi', 'metrics'],
142
+ description: 'Business intelligence, dashboards, reporting'
143
+ },
144
+ 'data-engineering': {
145
+ keywords: ['etl', 'elt', 'pipeline', 'data-pipeline', 'warehouse', 'lake', 'ingestion'],
146
+ description: 'Data engineering, ETL/ELT, data pipelines'
147
+ },
148
+ 'analytics': {
149
+ keywords: ['analytics', 'analysis', 'insights', 'statistical', 'predictive', 'prescriptive'],
150
+ description: 'Data analytics, statistical analysis, insights'
151
+ },
152
+ 'forecasting': {
153
+ keywords: ['forecast', 'prediction', 'time-series', 'trend', 'anomaly-detection'],
154
+ description: 'Forecasting, time-series analysis, predictions'
155
+ },
156
+ 'visualization': {
157
+ keywords: ['visualization', 'chart', 'graph', 'tableau', 'power-bi', 'data-viz'],
158
+ description: 'Data visualization, charts, dashboards'
159
+ }
160
+ },
161
+
162
+ 'personal-professional': {
163
+ 'career': {
164
+ keywords: ['career', 'job', 'interview', 'resume', 'job-search', 'promotion', 'transition'],
165
+ description: 'Career development, job search, interviews'
166
+ },
167
+ 'leadership': {
168
+ keywords: ['leadership', 'leader', 'management', 'executive', 'mentoring', 'coaching'],
169
+ description: 'Leadership development, coaching, mentoring'
170
+ },
171
+ 'productivity': {
172
+ keywords: ['productivity', 'time-management', 'efficiency', 'goal', 'planning', 'organization'],
173
+ description: 'Productivity, time management, goal setting'
174
+ },
175
+ 'communication': {
176
+ keywords: ['communication', 'presentation', 'public-speaking', 'writing', 'listening', 'feedback'],
177
+ description: 'Communication skills, presentations, feedback'
178
+ },
179
+ 'wellness': {
180
+ keywords: ['wellness', 'stress', 'work-life', 'balance', 'mindfulness', 'mental-health', 'emotional'],
181
+ description: 'Wellness, work-life balance, mental health'
182
+ }
183
+ },
184
+
185
+ 'security-compliance': {
186
+ 'cybersecurity': {
187
+ keywords: ['cybersecurity', 'security', 'threat', 'vulnerability', 'penetration', 'firewall', 'encryption'],
188
+ description: 'Cybersecurity, threat analysis, penetration testing'
189
+ },
190
+ 'compliance': {
191
+ keywords: ['compliance', 'regulatory', 'audit', 'gdpr', 'hipaa', 'sox', 'pci', 'iso'],
192
+ description: 'Compliance, regulatory requirements, auditing'
193
+ },
194
+ 'privacy': {
195
+ keywords: ['privacy', 'data-privacy', 'gdpr', 'personal-data', 'consent', 'anonymization'],
196
+ description: 'Data privacy, GDPR, personal data protection'
197
+ },
198
+ 'access-control': {
199
+ keywords: ['access-control', 'authentication', 'authorization', 'identity', 'zero-trust', 'iam'],
200
+ description: 'Access control, authentication, identity management'
201
+ }
202
+ },
203
+
204
+ 'payment-financial': {
205
+ 'payment-gateways': {
206
+ keywords: ['stripe', 'paypal', 'square', 'braintree', 'checkout', 'payment-gateway', 'merchant'],
207
+ description: 'Payment gateways (Stripe, PayPal, Square, etc.)'
208
+ },
209
+ 'bnpl': {
210
+ keywords: ['bnpl', 'afterpay', 'klarna', 'affirm', 'installment', 'buy-now-pay-later'],
211
+ description: 'Buy-now-pay-later, installment payments'
212
+ },
213
+ 'cryptocurrency': {
214
+ keywords: ['crypto', 'bitcoin', 'ethereum', 'blockchain', 'wallet', 'web3'],
215
+ description: 'Cryptocurrency, blockchain, Web3 payments'
216
+ },
217
+ 'billing': {
218
+ keywords: ['billing', 'invoice', 'subscription', 'recurring', 'pricing'],
219
+ description: 'Billing systems, invoicing, subscriptions'
220
+ }
221
+ }
222
+ };
223
+
224
+ /**
225
+ * Extract YAML frontmatter from markdown file
226
+ */
227
+ function extractFrontmatter(content) {
228
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
229
+ if (!match) return null;
230
+
231
+ const frontmatter = {};
232
+ const lines = match[1].split('\n');
233
+
234
+ for (const line of lines) {
235
+ const colonIndex = line.indexOf(':');
236
+ if (colonIndex === -1) continue;
237
+
238
+ const key = line.substring(0, colonIndex).trim();
239
+ const value = line.substring(colonIndex + 1).trim();
240
+ frontmatter[key] = value;
241
+ }
242
+
243
+ return frontmatter;
244
+ }
245
+
246
+ /**
247
+ * Categorize agent into subcategory
248
+ */
249
+ function subcategorizeAgent(filename, content, mainCategory) {
250
+ const subcategories = SUBCATEGORIES[mainCategory];
251
+ if (!subcategories) return null;
252
+
253
+ const frontmatter = extractFrontmatter(content);
254
+ const searchText = (filename + ' ' + (frontmatter?.name || '') + ' ' + (frontmatter?.description || '')).toLowerCase();
255
+
256
+ let bestSubcategory = null;
257
+ let bestScore = 0;
258
+
259
+ for (const [subcategory, config] of Object.entries(subcategories)) {
260
+ let score = 0;
261
+ for (const keyword of config.keywords) {
262
+ if (searchText.includes(keyword.toLowerCase())) {
263
+ score++;
264
+ }
265
+ }
266
+
267
+ if (score > bestScore) {
268
+ bestScore = score;
269
+ bestSubcategory = subcategory;
270
+ }
271
+ }
272
+
273
+ // Default to first subcategory or 'other' if no match
274
+ if (!bestSubcategory) {
275
+ bestSubcategory = subcategories.other ? 'other' : Object.keys(subcategories)[0];
276
+ }
277
+
278
+ return bestSubcategory;
279
+ }
280
+
281
+ /**
282
+ * Process a single main category
283
+ */
284
+ function processCategory(mainCategory) {
285
+ const categoryDir = path.join(AGENTS_DIR, mainCategory);
286
+ if (!fs.existsSync(categoryDir)) {
287
+ console.log(`⏭️ Skipping ${mainCategory} (not found)`);
288
+ return null;
289
+ }
290
+
291
+ console.log(`\n📂 Processing ${mainCategory}...`);
292
+
293
+ // Read agent files
294
+ const files = fs.readdirSync(categoryDir)
295
+ .filter(f => f.endsWith('.md') && f !== 'INDEX.md');
296
+
297
+ if (files.length === 0) {
298
+ console.log(` No agents found in ${mainCategory}`);
299
+ return null;
300
+ }
301
+
302
+ console.log(` Found ${files.length} agents`);
303
+
304
+ // Categorize into subcategories
305
+ const subcategorization = {};
306
+ const subcategoryConfigs = SUBCATEGORIES[mainCategory];
307
+
308
+ for (const subcategory of Object.keys(subcategoryConfigs)) {
309
+ subcategorization[subcategory] = [];
310
+ }
311
+
312
+ for (const file of files) {
313
+ const filePath = path.join(categoryDir, file);
314
+ const content = fs.readFileSync(filePath, 'utf-8');
315
+ const subcategory = subcategorizeAgent(file, content, mainCategory);
316
+
317
+ if (subcategory && subcategorization[subcategory]) {
318
+ subcategorization[subcategory].push(file);
319
+ }
320
+ }
321
+
322
+ // Display subcategorization
323
+ console.log(`\n Subcategories:`);
324
+ for (const [subcategory, files] of Object.entries(subcategorization)) {
325
+ if (files.length > 0) {
326
+ console.log(` ${subcategory}: ${files.length} agents`);
327
+ }
328
+ }
329
+
330
+ // Create subdirectories and move files
331
+ for (const [subcategory, config] of Object.entries(subcategoryConfigs)) {
332
+ const subcategoryDir = path.join(categoryDir, subcategory);
333
+ const filesToMove = subcategorization[subcategory];
334
+
335
+ if (filesToMove.length === 0) continue;
336
+
337
+ // Create directory
338
+ if (!fs.existsSync(subcategoryDir)) {
339
+ fs.mkdirSync(subcategoryDir, { recursive: true });
340
+ }
341
+
342
+ // Move files
343
+ for (const file of filesToMove) {
344
+ const src = path.join(categoryDir, file);
345
+ const dest = path.join(subcategoryDir, file);
346
+ fs.renameSync(src, dest);
347
+ }
348
+
349
+ // Create subcategory index
350
+ const indexContent = `# ${subcategory.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}
351
+
352
+ **Description:** ${config.description}
353
+ **Agent Count:** ${filesToMove.length}
354
+
355
+ ## Available Agents
356
+
357
+ ${filesToMove.sort().map(f => `- [${f.replace('.md', '')}](./${f})`).join('\n')}
358
+ `;
359
+
360
+ fs.writeFileSync(path.join(subcategoryDir, 'INDEX.md'), indexContent);
361
+ }
362
+
363
+ // Update main category index
364
+ const mainIndexContent = `# ${mainCategory.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')}
365
+
366
+ **Total Agents:** ${files.length}
367
+
368
+ ## Subcategories
369
+
370
+ ${Object.entries(subcategorization)
371
+ .filter(([_, files]) => files.length > 0)
372
+ .sort((a, b) => b[1].length - a[1].length)
373
+ .map(([subcat, files]) => {
374
+ const config = subcategoryConfigs[subcat];
375
+ return `### [${subcat}](${subcat}/INDEX.md) (${files.length} agents)
376
+
377
+ ${config.description}
378
+ `;
379
+ }).join('\n')}
380
+
381
+ ## Quick Navigation
382
+
383
+ ${Object.entries(subcategorization)
384
+ .filter(([_, files]) => files.length > 0)
385
+ .map(([subcat, files]) => `- [${subcat}](${subcat}/INDEX.md) - ${files.length} agents`)
386
+ .join('\n')}
387
+ `;
388
+
389
+ fs.writeFileSync(path.join(categoryDir, 'INDEX.md'), mainIndexContent);
390
+
391
+ return {
392
+ category: mainCategory,
393
+ totalAgents: files.length,
394
+ subcategories: Object.fromEntries(
395
+ Object.entries(subcategorization).filter(([_, files]) => files.length > 0)
396
+ )
397
+ };
398
+ }
399
+
400
+ /**
401
+ * Main subcategorization process
402
+ */
403
+ async function subcategorizeAgents() {
404
+ console.log('🔍 Subcategorizing agents within each main category...\n');
405
+
406
+ const results = {};
407
+
408
+ for (const mainCategory of Object.keys(SUBCATEGORIES)) {
409
+ const result = processCategory(mainCategory);
410
+ if (result) {
411
+ results[mainCategory] = result;
412
+ }
413
+ }
414
+
415
+ console.log('\n\n✅ Subcategorization complete!\n');
416
+
417
+ // Generate summary
418
+ console.log('📊 Summary by Main Category:\n');
419
+ for (const [category, data] of Object.entries(results)) {
420
+ console.log(`${category}: ${data.totalAgents} agents in ${Object.keys(data.subcategories).length} subcategories`);
421
+ }
422
+
423
+ console.log('\n✨ Done!\n');
424
+ }
425
+
426
+ // Run
427
+ subcategorizeAgents().catch(console.error);
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Sync agents, commands, and hooks from npm package to local project
4
+ * Usage: npx claude-flow-novice sync [--force] [--backup] [--agents] [--commands] [--hooks]
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { execSync } = require('child_process');
10
+
11
+ const args = process.argv.slice(2);
12
+ const flags = {
13
+ force: args.includes('--force'),
14
+ backup: args.includes('--backup'),
15
+ agents: args.includes('--agents') || args.length === 0,
16
+ commands: args.includes('--commands') || args.length === 0,
17
+ hooks: args.includes('--hooks') || args.length === 0,
18
+ help: args.includes('--help') || args.includes('-h')
19
+ };
20
+
21
+ if (flags.help) {
22
+ console.log(`
23
+ Claude Flow Novice - Sync Script
24
+
25
+ Syncs agents, commands, and hooks from npm package to your local project.
26
+
27
+ Usage:
28
+ npx claude-flow-novice sync [options]
29
+
30
+ Options:
31
+ --agents Sync .claude/agents/ only
32
+ --commands Sync .claude/commands/ only
33
+ --hooks Sync config/hooks/ only
34
+ --force Overwrite existing files without prompting
35
+ --backup Create backup before syncing (recommended)
36
+ --help, -h Show this help message
37
+
38
+ Examples:
39
+ npx claude-flow-novice sync # Sync everything
40
+ npx claude-flow-novice sync --agents --backup # Sync agents with backup
41
+ npx claude-flow-novice sync --force --backup # Force sync all with backup
42
+ `);
43
+ process.exit(0);
44
+ }
45
+
46
+ // Find package location
47
+ const packagePath = path.join(__dirname, '..');
48
+ const projectRoot = process.cwd();
49
+
50
+ console.log('🚀 Claude Flow Novice - Sync Script\n');
51
+ console.log(`📦 Package: ${packagePath}`);
52
+ console.log(`📁 Project: ${projectRoot}\n`);
53
+
54
+ const syncItems = [
55
+ {
56
+ name: 'agents',
57
+ enabled: flags.agents,
58
+ source: path.join(packagePath, '.claude', 'agents'),
59
+ dest: path.join(projectRoot, '.claude', 'agents'),
60
+ description: 'Agent definitions'
61
+ },
62
+ {
63
+ name: 'commands',
64
+ enabled: flags.commands,
65
+ source: path.join(packagePath, '.claude', 'commands'),
66
+ dest: path.join(projectRoot, '.claude', 'commands'),
67
+ description: 'Slash commands'
68
+ },
69
+ {
70
+ name: 'hooks',
71
+ enabled: flags.hooks,
72
+ source: path.join(packagePath, 'config', 'hooks'),
73
+ dest: path.join(projectRoot, 'config', 'hooks'),
74
+ description: 'Validation hooks'
75
+ }
76
+ ];
77
+
78
+ // Backup function
79
+ function createBackup(destPath) {
80
+ if (!fs.existsSync(destPath)) return null;
81
+
82
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];
83
+ const backupPath = `${destPath}.backup-${timestamp}`;
84
+
85
+ console.log(` 📋 Creating backup: ${path.basename(backupPath)}`);
86
+ execSync(`cp -r "${destPath}" "${backupPath}"`);
87
+ return backupPath;
88
+ }
89
+
90
+ // Copy directory recursively
91
+ function copyDir(src, dest) {
92
+ if (!fs.existsSync(src)) {
93
+ console.error(` ❌ Source not found: ${src}`);
94
+ return false;
95
+ }
96
+
97
+ // Create destination directory
98
+ if (!fs.existsSync(dest)) {
99
+ fs.mkdirSync(dest, { recursive: true });
100
+ }
101
+
102
+ const entries = fs.readdirSync(src, { withFileTypes: true });
103
+ let fileCount = 0;
104
+
105
+ for (const entry of entries) {
106
+ const srcPath = path.join(src, entry.name);
107
+ const destPath = path.join(dest, entry.name);
108
+
109
+ if (entry.isDirectory()) {
110
+ copyDir(srcPath, destPath);
111
+ } else {
112
+ fs.copyFileSync(srcPath, destPath);
113
+ fileCount++;
114
+ }
115
+ }
116
+
117
+ return fileCount;
118
+ }
119
+
120
+ // Count files in directory
121
+ function countFiles(dir) {
122
+ if (!fs.existsSync(dir)) return 0;
123
+
124
+ let count = 0;
125
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
126
+
127
+ for (const entry of entries) {
128
+ if (entry.isDirectory()) {
129
+ count += countFiles(path.join(dir, entry.name));
130
+ } else {
131
+ count++;
132
+ }
133
+ }
134
+
135
+ return count;
136
+ }
137
+
138
+ // Main sync process
139
+ let totalSynced = 0;
140
+
141
+ for (const item of syncItems) {
142
+ if (!item.enabled) continue;
143
+
144
+ console.log(`\n📂 Syncing ${item.description}...`);
145
+ console.log(` Source: ${item.source}`);
146
+ console.log(` Dest: ${item.dest}`);
147
+
148
+ // Check if source exists
149
+ if (!fs.existsSync(item.source)) {
150
+ console.log(` ⚠️ Source directory not found, skipping`);
151
+ continue;
152
+ }
153
+
154
+ // Backup if requested
155
+ if (flags.backup) {
156
+ createBackup(item.dest);
157
+ }
158
+
159
+ // Check if destination exists and not forcing
160
+ if (fs.existsSync(item.dest) && !flags.force) {
161
+ const beforeCount = countFiles(item.dest);
162
+ console.log(` ⚠️ Destination exists with ${beforeCount} files`);
163
+ console.log(` 💡 Use --force to overwrite or --backup to create backup first`);
164
+ continue;
165
+ }
166
+
167
+ // Perform sync
168
+ const fileCount = copyDir(item.source, item.dest);
169
+ console.log(` ✅ Synced ${fileCount} files`);
170
+ totalSynced += fileCount;
171
+ }
172
+
173
+ console.log(`\n✨ Sync complete! ${totalSynced} files synced.\n`);
174
+
175
+ if (totalSynced > 0) {
176
+ console.log('Next steps:');
177
+ console.log(' 1. Review synced files');
178
+ console.log(' 2. Customize as needed for your project');
179
+ console.log(' 3. Commit changes to version control\n');
180
+ }
@@ -923,7 +923,8 @@ Execute the task using available tools. Report confidence score (0.0-1.0) at the
923
923
  const MAX_TOOL_ITERATIONS = 1000; // Increased from 25 to allow comprehensive optimization tasks
924
924
  let content = '';
925
925
 
926
- // Tool use loop
926
+ // Tool use loop with context window management
927
+ const MAX_CONTEXT_MESSAGES = 20; // Keep only last 20 messages
927
928
  while (toolUseCount < MAX_TOOL_ITERATIONS) {
928
929
  const response = await this.anthropic.createMessage({
929
930
  model: this.model,
@@ -979,6 +980,12 @@ Execute the task using available tools. Report confidence score (0.0-1.0) at the
979
980
  });
980
981
 
981
982
  toolUseCount++;
983
+
984
+ // Trim context window to prevent memory leak
985
+ if (messages.length > MAX_CONTEXT_MESSAGES) {
986
+ // Keep first message (initial task) + last N messages
987
+ messages = [messages[0], ...messages.slice(-MAX_CONTEXT_MESSAGES + 1)];
988
+ }
982
989
  }
983
990
 
984
991
  if (toolUseCount >= MAX_TOOL_ITERATIONS) {
@@ -1103,7 +1110,7 @@ Execute the task using available tools. Report confidence score (0.0-1.0) at the
1103
1110
  }
1104
1111
 
1105
1112
  /**
1106
- * Recursively scan directory for .md files
1113
+ * Recursively scan directory for .md files (excludes node_modules)
1107
1114
  */
1108
1115
  async scanAgentFiles(dirPath, basePath) {
1109
1116
  const { promises: fs } = await import('fs');
@@ -1115,6 +1122,11 @@ Execute the task using available tools. Report confidence score (0.0-1.0) at the
1115
1122
  const entries = await fs.readdir(dirPath, { withFileTypes: true });
1116
1123
 
1117
1124
  for (const entry of entries) {
1125
+ // Skip node_modules to prevent memory leak
1126
+ if (entry.name === 'node_modules') {
1127
+ continue;
1128
+ }
1129
+
1118
1130
  const fullPath = path.join(dirPath, entry.name);
1119
1131
 
1120
1132
  if (entry.isDirectory()) {
package/src/index.ts CHANGED
@@ -27,10 +27,10 @@ export const AgentType = {
27
27
  API_DOCS: 'api-docs',
28
28
  BACKEND_DEV: 'backend-dev',
29
29
  FRONTEND_DEV: 'frontend-dev',
30
- MOBILE_DEV: 'mobile-dev'
30
+ MOBILE_DEV: 'mobile-dev',
31
31
  } as const;
32
32
 
33
- export type AgentType = typeof AgentType[keyof typeof AgentType];
33
+ export type AgentType = (typeof AgentType)[keyof typeof AgentType];
34
34
 
35
35
  // Version
36
36
  export const VERSION = '2.0.4';
@@ -41,6 +41,6 @@ export const defaultConfig = {
41
41
  strategy: 'development',
42
42
  mode: 'mesh',
43
43
  persistence: true,
44
- consensusThreshold: 0.90,
45
- gateThreshold: 0.75
44
+ consensusThreshold: 0.9,
45
+ gateThreshold: 0.75,
46
46
  };