@itz4blitz/agentful 1.3.0 → 1.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/README.md +20 -68
- package/bin/cli.js +30 -1
- package/bin/hooks/architect-drift-detector.js +242 -0
- package/bin/hooks/context-awareness.js +369 -0
- package/bin/hooks/post-action-suggestions.js +75 -0
- package/bin/hooks/session-start.js +93 -0
- package/lib/context-awareness.js +369 -0
- package/lib/index.js +17 -3
- package/lib/init.js +97 -3
- package/lib/presets.js +55 -1
- package/lib/state-validator.README.md +442 -0
- package/lib/state-validator.example.js +262 -0
- package/lib/state-validator.js +562 -0
- package/package.json +1 -1
- package/template/.claude/commands/agentful-analyze.md +47 -59
- package/template/.claude/commands/agentful-decide.md +73 -95
- package/template/.claude/commands/agentful-product.md +26 -37
- package/template/.claude/commands/agentful-start.md +36 -121
- package/template/.claude/commands/agentful-status.md +51 -68
- package/template/.claude/commands/agentful-validate.md +29 -69
- package/template/.claude/commands/agentful.md +1 -1
- package/template/.claude/settings.json +17 -0
- package/template/CLAUDE.md +222 -28
- package/template/bin/hooks/analyze-trigger.js +69 -0
- package/template/bin/hooks/architect-drift-detector.js +0 -0
- package/template/bin/hooks/block-file-creation.js +271 -0
- package/template/bin/hooks/health-check.js +153 -0
- package/version.json +1 -1
package/README.md
CHANGED
|
@@ -14,22 +14,22 @@
|
|
|
14
14
|
[](https://discord.gg/SMDvJXUe)
|
|
15
15
|
[](https://agentful.app)
|
|
16
16
|
|
|
17
|
-
**
|
|
17
|
+
**Pre-configured development toolkit for Claude Code**
|
|
18
|
+
|
|
19
|
+
Orchestrates specialized agents in parallel with inter-agent communication to build features from product specs.
|
|
18
20
|
|
|
19
21
|
[Quick Start](#quick-start) • [Documentation](https://agentful.app) • [Discord](https://discord.gg/SMDvJXUe)
|
|
20
22
|
|
|
21
23
|
</div>
|
|
22
24
|
|
|
23
|
-
**The Swiss Army Knife of AI Agents** - Works with any LLM (Claude, GLM, DeepSeek, Ollama), any tech stack, any platform. Self-hosted or cloud.
|
|
24
|
-
|
|
25
25
|
## Features
|
|
26
26
|
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
27
|
+
- **Parallel execution** - Multiple agents work simultaneously in git worktrees (frontend + backend + tests running concurrently)
|
|
28
|
+
- **Three-tier architecture** - Core agents (pre-built), domain agents (generated for your stack), ephemeral agents (task-specific)
|
|
29
|
+
- **Shared skills** - Reusable capabilities like validation, testing, and research across all agents
|
|
30
|
+
- **Quality gates** - Automated validation for every change (types, lint, tests, coverage, security, dead code)
|
|
31
|
+
- **Tech stack agnostic** - Works with any language/framework
|
|
32
|
+
- **Human checkpoints** - You decide, agents execute
|
|
33
33
|
|
|
34
34
|
## Quick Start
|
|
35
35
|
|
|
@@ -40,13 +40,12 @@ npx @itz4blitz/agentful init
|
|
|
40
40
|
# 2. Start Claude Code
|
|
41
41
|
claude
|
|
42
42
|
|
|
43
|
-
# 3. Define product spec (
|
|
44
|
-
/agentful-
|
|
45
|
-
|
|
46
|
-
#
|
|
47
|
-
/agentful-generate
|
|
43
|
+
# 3. Define product spec (choose one):
|
|
44
|
+
/agentful-init # Interactive 7-question wizard (recommended for new users)
|
|
45
|
+
# OR
|
|
46
|
+
/agentful-product # Manual spec creation/analysis
|
|
48
47
|
|
|
49
|
-
#
|
|
48
|
+
# 4. Start development (auto-generates agents on first run)
|
|
50
49
|
/agentful-start
|
|
51
50
|
```
|
|
52
51
|
|
|
@@ -70,71 +69,24 @@ https://agentful.app/configure
|
|
|
70
69
|
|
|
71
70
|
| Command | Description |
|
|
72
71
|
|---------|-------------|
|
|
72
|
+
| `/agentful-init` | Interactive onboarding - 7 guided questions |
|
|
73
73
|
| `/agentful-product` | Create and analyze product specifications |
|
|
74
|
+
| `/agentful-generate` | Generate domain-specific agents for your stack |
|
|
74
75
|
| `/agentful-start` | Start autonomous development |
|
|
75
76
|
| `/agentful-status` | View completion % and current work |
|
|
76
77
|
| `/agentful-validate` | Run quality checks |
|
|
77
78
|
| `/agentful-decide` | Answer blocking decisions |
|
|
78
|
-
| `/agentful-analyze` | Generate domain-specific agents |
|
|
79
|
-
|
|
80
|
-
## Self-Hosted Remote Execution
|
|
81
|
-
|
|
82
|
-
Run agents on your infrastructure:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
# Deploy to Oracle Cloud free tier ($0/month)
|
|
86
|
-
agentful serve --auth=tailscale
|
|
87
|
-
|
|
88
|
-
# Or use SSH tunnel for local dev
|
|
89
|
-
ssh -L 3000:localhost:3000 your-server
|
|
90
|
-
agentful serve
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
See [deployment docs](https://agentful.app/remote-execution) for Tailscale, HMAC auth, and Oracle Cloud setup.
|
|
94
|
-
|
|
95
|
-
## MCP Server
|
|
96
|
-
|
|
97
|
-
Use agentful with any MCP-compatible AI tool (Claude Code, Kiro, Aider):
|
|
98
|
-
|
|
99
|
-
```json
|
|
100
|
-
{
|
|
101
|
-
"mcpServers": {
|
|
102
|
-
"agentful": {
|
|
103
|
-
"command": "npx",
|
|
104
|
-
"args": ["-y", "@itz4blitz/agentful-mcp"]
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Features**:
|
|
111
|
-
- Cross-tool compatibility (works with any MCP client)
|
|
112
|
-
- Launch specialized agents via MCP tools
|
|
113
|
-
- Access product specs and state via MCP resources
|
|
114
|
-
- Real-time execution status updates
|
|
115
|
-
|
|
116
|
-
See [MCP Integration Guide](./docs/mcp-integration.md) for setup with different AI tools.
|
|
117
|
-
|
|
118
|
-
## CI/CD Integration
|
|
119
|
-
|
|
120
|
-
Works with any platform via HTTP API or templates:
|
|
121
|
-
|
|
122
|
-
- [GitHub Actions](https://agentful.app/ci-integration#github-actions)
|
|
123
|
-
- [GitLab CI](https://agentful.app/ci-integration#gitlab-ci)
|
|
124
|
-
- [Jenkins](https://agentful.app/ci-integration#jenkins)
|
|
125
|
-
- [HTTP API](https://agentful.app/ci-integration#http-api) (CircleCI, Bitbucket, Travis, etc.)
|
|
126
79
|
|
|
127
80
|
## Documentation
|
|
128
81
|
|
|
129
82
|
- **Full docs**: [agentful.app](https://agentful.app)
|
|
130
|
-
- **
|
|
131
|
-
- **
|
|
132
|
-
- **
|
|
133
|
-
- **Skills**: [Product tracking](https://agentful.app/skills/product-tracking), [Validation](https://agentful.app/skills/validation), etc.
|
|
83
|
+
- **Architecture**: [Three-tier system](https://agentful.app/concepts/architecture) | [Background agents](https://agentful.app/concepts/background-agents)
|
|
84
|
+
- **Agents**: [Orchestrator](https://agentful.app/agents/orchestrator), [Backend](https://agentful.app/agents/backend), [Frontend](https://agentful.app/agents/frontend), [Reviewer](https://agentful.app/agents/reviewer), [Fixer](https://agentful.app/agents/fixer)
|
|
85
|
+
- **Skills**: [Validation](https://agentful.app/skills/validation), [Testing](https://agentful.app/skills/testing), [Research](https://agentful.app/skills/research), [Product Planning](https://agentful.app/skills/product-planning)
|
|
134
86
|
|
|
135
87
|
## Requirements
|
|
136
88
|
|
|
137
|
-
- Claude Code
|
|
89
|
+
- [Claude Code](https://claude.ai/download)
|
|
138
90
|
- Node.js 22+
|
|
139
91
|
- Git
|
|
140
92
|
|
package/bin/cli.js
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
mergePresetWithFlags,
|
|
30
30
|
validateConfiguration
|
|
31
31
|
} from '../lib/presets.js';
|
|
32
|
+
import { detectTeammateTool, enableTeammateTool } from '../lib/parallel-execution.js';
|
|
32
33
|
|
|
33
34
|
const __filename = fileURLToPath(import.meta.url);
|
|
34
35
|
const __dirname = path.dirname(__filename);
|
|
@@ -122,7 +123,7 @@ function showPresets() {
|
|
|
122
123
|
log(colors.cyan, 'DEFAULT (Recommended)');
|
|
123
124
|
log(colors.dim, ' Install all components - agentful works best with everything enabled');
|
|
124
125
|
log(colors.dim, ' Command: agentful init');
|
|
125
|
-
log(colors.dim, ' Includes: 8 agents,
|
|
126
|
+
log(colors.dim, ' Includes: 8 agents, 7 skills, all hooks, all gates');
|
|
126
127
|
console.log('');
|
|
127
128
|
|
|
128
129
|
log(colors.cyan, 'MINIMAL');
|
|
@@ -354,6 +355,34 @@ async function init(args) {
|
|
|
354
355
|
log(colors.green, ` ${file}`);
|
|
355
356
|
});
|
|
356
357
|
console.log('');
|
|
358
|
+
|
|
359
|
+
// Enable parallel execution
|
|
360
|
+
log(colors.dim, 'Checking parallel execution support...');
|
|
361
|
+
const detection = detectTeammateTool();
|
|
362
|
+
|
|
363
|
+
if (detection.available) {
|
|
364
|
+
if (detection.autoEnabled) {
|
|
365
|
+
log(colors.green, '✓ Parallel execution enabled (TeammateTool auto-patched)');
|
|
366
|
+
} else {
|
|
367
|
+
log(colors.green, '✓ Parallel execution available');
|
|
368
|
+
}
|
|
369
|
+
} else if (detection.canEnable) {
|
|
370
|
+
log(colors.yellow, '⚡ Enabling parallel execution...');
|
|
371
|
+
const result = enableTeammateTool();
|
|
372
|
+
if (result.success) {
|
|
373
|
+
log(colors.green, '✓ Parallel execution enabled successfully');
|
|
374
|
+
log(colors.dim, ` Backup created: ${result.backupPath}`);
|
|
375
|
+
} else {
|
|
376
|
+
log(colors.yellow, '⚠ Could not enable parallel execution');
|
|
377
|
+
log(colors.dim, ` Reason: ${result.error}`);
|
|
378
|
+
log(colors.dim, ' Agents will run sequentially (still works, just slower)');
|
|
379
|
+
}
|
|
380
|
+
} else {
|
|
381
|
+
log(colors.yellow, '⚠ Parallel execution not available');
|
|
382
|
+
log(colors.dim, ` Reason: ${detection.reason}`);
|
|
383
|
+
log(colors.dim, ' Agents will run sequentially (still works, just slower)');
|
|
384
|
+
}
|
|
385
|
+
console.log('');
|
|
357
386
|
} catch (error) {
|
|
358
387
|
log(colors.red, `Failed to initialize: ${error.message}`);
|
|
359
388
|
process.exit(1);
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Architect Drift Detector Hook
|
|
5
|
+
*
|
|
6
|
+
* Detects when project changes require architect to re-analyze and update skills/agents.
|
|
7
|
+
*
|
|
8
|
+
* Triggers re-analysis when:
|
|
9
|
+
* - New dependencies added (package.json, requirements.txt, go.mod, etc.)
|
|
10
|
+
* - Tech stack changes (switched frameworks)
|
|
11
|
+
* - New patterns emerge (5+ files violating existing conventions)
|
|
12
|
+
* - Skills are stale (last analysis > 7 days old)
|
|
13
|
+
*
|
|
14
|
+
* Run: After any Write/Edit operation by agents
|
|
15
|
+
* Action: Updates .agentful/architecture.json with needs_reanalysis: true
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import fs from 'fs';
|
|
19
|
+
import path from 'path';
|
|
20
|
+
import crypto from 'crypto';
|
|
21
|
+
|
|
22
|
+
const ARCHITECTURE_FILE = '.agentful/architecture.json';
|
|
23
|
+
const STALE_THRESHOLD_DAYS = 7;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Detect if architect needs to re-run
|
|
27
|
+
*/
|
|
28
|
+
function detectArchitectDrift() {
|
|
29
|
+
try {
|
|
30
|
+
// Load current architecture analysis
|
|
31
|
+
const arch = loadArchitecture();
|
|
32
|
+
|
|
33
|
+
// Check various drift indicators
|
|
34
|
+
const driftReasons = [];
|
|
35
|
+
|
|
36
|
+
// 1. Check if dependency files changed
|
|
37
|
+
if (dependenciesChanged(arch)) {
|
|
38
|
+
driftReasons.push('dependencies_changed');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 2. Check if tech stack files modified
|
|
42
|
+
if (techStackFilesModified(arch)) {
|
|
43
|
+
driftReasons.push('tech_stack_modified');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 3. Check if analysis is stale
|
|
47
|
+
if (analysisIsStale(arch)) {
|
|
48
|
+
driftReasons.push('analysis_stale');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 4. Check if new patterns emerged (heuristic: lots of new files)
|
|
52
|
+
if (newPatternsDetected(arch)) {
|
|
53
|
+
driftReasons.push('new_patterns_detected');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// If drift detected, mark for re-analysis
|
|
57
|
+
if (driftReasons.length > 0) {
|
|
58
|
+
markForReanalysis(arch, driftReasons);
|
|
59
|
+
console.log(`⚠️ Architect drift detected: ${driftReasons.join(', ')}`);
|
|
60
|
+
console.log(' Run /agentful-generate to update skills and agents');
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return false;
|
|
65
|
+
} catch (error) {
|
|
66
|
+
// Fail silently - don't block operations if architecture.json missing
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Load architecture.json
|
|
73
|
+
*/
|
|
74
|
+
function loadArchitecture() {
|
|
75
|
+
if (!fs.existsSync(ARCHITECTURE_FILE)) {
|
|
76
|
+
// First run - architect hasn't analyzed yet
|
|
77
|
+
return {
|
|
78
|
+
last_analysis: null,
|
|
79
|
+
dependency_hashes: {},
|
|
80
|
+
file_count: 0,
|
|
81
|
+
needs_reanalysis: true
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return JSON.parse(fs.readFileSync(ARCHITECTURE_FILE, 'utf8'));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if dependency files changed
|
|
90
|
+
*/
|
|
91
|
+
function dependenciesChanged(arch) {
|
|
92
|
+
const depFiles = [
|
|
93
|
+
'package.json',
|
|
94
|
+
'package-lock.json',
|
|
95
|
+
'requirements.txt',
|
|
96
|
+
'pyproject.toml',
|
|
97
|
+
'Pipfile',
|
|
98
|
+
'go.mod',
|
|
99
|
+
'go.sum',
|
|
100
|
+
'Gemfile',
|
|
101
|
+
'Gemfile.lock',
|
|
102
|
+
'composer.json',
|
|
103
|
+
'pom.xml',
|
|
104
|
+
'build.gradle',
|
|
105
|
+
'Cargo.toml'
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
for (const file of depFiles) {
|
|
109
|
+
if (!fs.existsSync(file)) continue;
|
|
110
|
+
|
|
111
|
+
const currentHash = hashFile(file);
|
|
112
|
+
const previousHash = arch.dependency_hashes?.[file];
|
|
113
|
+
|
|
114
|
+
if (previousHash && currentHash !== previousHash) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Check if tech stack config files modified
|
|
124
|
+
*/
|
|
125
|
+
function techStackFilesModified(arch) {
|
|
126
|
+
const configFiles = [
|
|
127
|
+
'tsconfig.json',
|
|
128
|
+
'next.config.js',
|
|
129
|
+
'vite.config.js',
|
|
130
|
+
'webpack.config.js',
|
|
131
|
+
'django/settings.py',
|
|
132
|
+
'config/application.rb',
|
|
133
|
+
'nest-cli.json'
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
for (const file of configFiles) {
|
|
137
|
+
if (!fs.existsSync(file)) continue;
|
|
138
|
+
|
|
139
|
+
const currentHash = hashFile(file);
|
|
140
|
+
const previousHash = arch.dependency_hashes?.[file];
|
|
141
|
+
|
|
142
|
+
if (previousHash && currentHash !== previousHash) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Check if analysis is stale (>7 days old)
|
|
152
|
+
*/
|
|
153
|
+
function analysisIsStale(arch) {
|
|
154
|
+
if (!arch.last_analysis) return true;
|
|
155
|
+
|
|
156
|
+
const lastAnalysis = new Date(arch.last_analysis);
|
|
157
|
+
const daysSinceAnalysis = (Date.now() - lastAnalysis.getTime()) / (1000 * 60 * 60 * 24);
|
|
158
|
+
|
|
159
|
+
return daysSinceAnalysis > STALE_THRESHOLD_DAYS;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Heuristic: Check if significant new code added (potential new patterns)
|
|
164
|
+
*/
|
|
165
|
+
function newPatternsDetected(arch) {
|
|
166
|
+
// Count current files in src/
|
|
167
|
+
const currentFileCount = countSourceFiles();
|
|
168
|
+
const previousFileCount = arch.file_count || 0;
|
|
169
|
+
|
|
170
|
+
// If 20% more files added, might have new patterns
|
|
171
|
+
const growthRatio = (currentFileCount - previousFileCount) / Math.max(previousFileCount, 1);
|
|
172
|
+
|
|
173
|
+
return growthRatio > 0.2;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Count source files
|
|
178
|
+
*/
|
|
179
|
+
function countSourceFiles() {
|
|
180
|
+
const srcDirs = ['src', 'app', 'lib', 'pages', 'components'];
|
|
181
|
+
let count = 0;
|
|
182
|
+
|
|
183
|
+
for (const dir of srcDirs) {
|
|
184
|
+
if (fs.existsSync(dir)) {
|
|
185
|
+
count += countFilesRecursive(dir);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return count;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Count files recursively
|
|
194
|
+
*/
|
|
195
|
+
function countFilesRecursive(dir) {
|
|
196
|
+
let count = 0;
|
|
197
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
198
|
+
|
|
199
|
+
for (const entry of entries) {
|
|
200
|
+
if (entry.name.startsWith('.')) continue;
|
|
201
|
+
if (entry.name === 'node_modules') continue;
|
|
202
|
+
|
|
203
|
+
const fullPath = path.join(dir, entry.name);
|
|
204
|
+
|
|
205
|
+
if (entry.isDirectory()) {
|
|
206
|
+
count += countFilesRecursive(fullPath);
|
|
207
|
+
} else if (entry.isFile()) {
|
|
208
|
+
count++;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return count;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Hash a file
|
|
217
|
+
*/
|
|
218
|
+
function hashFile(filePath) {
|
|
219
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
220
|
+
return crypto.createHash('md5').update(content).digest('hex');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Mark architecture.json for re-analysis
|
|
225
|
+
*/
|
|
226
|
+
function markForReanalysis(arch, reasons) {
|
|
227
|
+
arch.needs_reanalysis = true;
|
|
228
|
+
arch.drift_reasons = reasons;
|
|
229
|
+
arch.drift_detected_at = new Date().toISOString();
|
|
230
|
+
|
|
231
|
+
// Ensure directory exists
|
|
232
|
+
const dir = path.dirname(ARCHITECTURE_FILE);
|
|
233
|
+
if (!fs.existsSync(dir)) {
|
|
234
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
fs.writeFileSync(ARCHITECTURE_FILE, JSON.stringify(arch, null, 2));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Run detection
|
|
241
|
+
const driftDetected = detectArchitectDrift();
|
|
242
|
+
process.exit(driftDetected ? 1 : 0);
|