@itz4blitz/agentful 0.3.0 → 0.5.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/README.md +139 -10
- package/bin/cli.js +1032 -48
- package/bin/hooks/README.md +338 -82
- package/bin/hooks/analyze-trigger.js +69 -0
- package/bin/hooks/block-random-docs.js +77 -0
- package/bin/hooks/health-check.js +153 -0
- package/bin/hooks/post-agent.js +101 -0
- package/bin/hooks/post-feature.js +227 -0
- package/bin/hooks/pre-agent.js +118 -0
- package/bin/hooks/pre-feature.js +138 -0
- package/lib/VALIDATION_README.md +455 -0
- package/lib/atomic.js +350 -0
- package/lib/ci/claude-action-integration.js +641 -0
- package/lib/ci/index.js +10 -0
- package/lib/core/CLAUDE_EXECUTOR.md +371 -0
- package/lib/core/README.md +321 -0
- package/lib/core/analyzer.js +497 -0
- package/lib/core/claude-executor.example.js +210 -0
- package/lib/core/claude-executor.js +1046 -0
- package/lib/core/cli.js +141 -0
- package/lib/core/detectors/conventions.js +342 -0
- package/lib/core/detectors/framework.js +276 -0
- package/lib/core/detectors/index.js +15 -0
- package/lib/core/detectors/language.js +199 -0
- package/lib/core/detectors/patterns.js +356 -0
- package/lib/core/generator.js +626 -0
- package/lib/core/index.js +9 -0
- package/lib/core/output-parser.example.js +250 -0
- package/lib/core/output-parser.js +458 -0
- package/lib/core/storage.js +515 -0
- package/lib/core/templates.js +556 -0
- package/lib/index.js +32 -0
- package/lib/init.js +497 -25
- package/lib/pipeline/cli.js +423 -0
- package/lib/pipeline/engine.js +928 -0
- package/lib/pipeline/executor.js +440 -0
- package/lib/pipeline/index.js +33 -0
- package/lib/pipeline/integrations.js +559 -0
- package/lib/pipeline/schemas.js +288 -0
- package/lib/presets.js +207 -0
- package/lib/remote/client.js +361 -0
- package/lib/server/auth.js +286 -0
- package/lib/server/client-example.js +190 -0
- package/lib/server/executor.js +426 -0
- package/lib/server/index.js +469 -0
- package/lib/update-helpers.js +505 -0
- package/lib/validation.js +460 -0
- package/package.json +19 -2
- package/template/.claude/agents/architect.md +260 -0
- package/template/.claude/agents/backend.md +203 -0
- package/template/.claude/agents/fixer.md +244 -0
- package/template/.claude/agents/frontend.md +232 -0
- package/template/.claude/agents/orchestrator.md +528 -0
- package/template/.claude/agents/product-analyzer.md +1130 -0
- package/template/.claude/agents/reviewer.md +229 -0
- package/template/.claude/agents/tester.md +242 -0
- package/{.claude → template/.claude}/commands/agentful-analyze.md +151 -43
- package/template/.claude/commands/agentful-decide.md +470 -0
- package/{.claude → template/.claude}/commands/agentful-product.md +92 -8
- package/template/.claude/commands/agentful-start.md +432 -0
- package/{.claude → template/.claude}/commands/agentful-status.md +88 -3
- package/template/.claude/commands/agentful-update.md +402 -0
- package/template/.claude/commands/agentful-validate.md +369 -0
- package/{.claude → template/.claude}/commands/agentful.md +111 -195
- package/template/.claude/product/EXAMPLES.md +167 -0
- package/{.claude → template/.claude}/settings.json +9 -13
- package/{.claude → template/.claude}/skills/conversation/SKILL.md +13 -7
- package/template/.claude/skills/deployment/SKILL.md +116 -0
- package/template/.claude/skills/product-planning/SKILL.md +463 -0
- package/{.claude → template/.claude}/skills/product-tracking/SKILL.md +10 -21
- package/template/.claude/skills/testing/SKILL.md +228 -0
- package/template/.claude/skills/validation/SKILL.md +650 -0
- package/template/CLAUDE.md +84 -16
- package/template/bin/hooks/block-random-docs.js +121 -0
- package/version.json +1 -1
- package/.claude/agents/architect.md +0 -524
- package/.claude/agents/backend.md +0 -315
- package/.claude/agents/fixer.md +0 -263
- package/.claude/agents/frontend.md +0 -274
- package/.claude/agents/orchestrator.md +0 -283
- package/.claude/agents/product-analyzer.md +0 -799
- package/.claude/agents/reviewer.md +0 -332
- package/.claude/agents/tester.md +0 -410
- package/.claude/commands/agentful-decide.md +0 -214
- package/.claude/commands/agentful-start.md +0 -182
- package/.claude/commands/agentful-validate.md +0 -127
- package/.claude/product/EXAMPLES.md +0 -610
- package/.claude/product/README.md +0 -344
- package/.claude/skills/validation/SKILL.md +0 -271
- package/bin/hooks/analyze-trigger.sh +0 -57
- package/bin/hooks/health-check.sh +0 -36
- package/template/PRODUCT.md +0 -584
- /package/{.claude → template/.claude}/commands/agentful-generate.md +0 -0
- /package/{.claude → template/.claude}/product/index.md +0 -0
|
@@ -21,12 +21,45 @@ Unified analysis command that detects gaps in skills, agents, and configuration.
|
|
|
21
21
|
|
|
22
22
|
Fast health check (under 10 seconds). No deep codebase scanning.
|
|
23
23
|
|
|
24
|
+
#### State File Validation
|
|
25
|
+
|
|
26
|
+
Before checking anything, validate state files:
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
function validate_state_file(file_path, required_fields) {
|
|
30
|
+
// Check file exists
|
|
31
|
+
if (!exists(file_path)) {
|
|
32
|
+
return { valid: false, error: `File not found: ${file_path}`, action: "not_found" };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Check file is valid JSON
|
|
36
|
+
let content;
|
|
37
|
+
try {
|
|
38
|
+
content = JSON.parse(Read(file_path));
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return { valid: false, error: `Invalid JSON in ${file_path}`, action: "corrupted" };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check required fields exist (if specified)
|
|
44
|
+
if (required_fields) {
|
|
45
|
+
for (const field of required_fields) {
|
|
46
|
+
if (!(field in content)) {
|
|
47
|
+
return { valid: false, error: `Missing field '${field}' in ${file_path}`, action: "incomplete", missing_field: field };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return { valid: true, content };
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
24
56
|
**What it checks:**
|
|
25
57
|
|
|
26
58
|
1. **Core Setup**
|
|
27
59
|
- `.agentful/architecture.json` exists and is valid JSON
|
|
28
60
|
- Core agents exist (backend, frontend, tester, reviewer, fixer, orchestrator)
|
|
29
61
|
- Skills directory structure is valid
|
|
62
|
+
- State files are valid JSON (state.json, completion.json, etc.)
|
|
30
63
|
|
|
31
64
|
2. **Tech Stack Alignment**
|
|
32
65
|
- Read `package.json` or equivalent dependency file
|
|
@@ -40,19 +73,27 @@ Fast health check (under 10 seconds). No deep codebase scanning.
|
|
|
40
73
|
**Process:**
|
|
41
74
|
|
|
42
75
|
```typescript
|
|
43
|
-
// 1.
|
|
76
|
+
// 1. Validate and check architecture.json
|
|
44
77
|
const archPath = ".agentful/architecture.json";
|
|
45
|
-
|
|
46
|
-
|
|
78
|
+
const archValidation = validate_state_file(archPath, ["language", "framework"]);
|
|
79
|
+
|
|
80
|
+
if (!archValidation.valid) {
|
|
81
|
+
if (archValidation.action == "not_found") {
|
|
82
|
+
issues.push({ type: "critical", msg: "Missing architecture.json - run /agentful-start" });
|
|
83
|
+
} else if (archValidation.action == "corrupted") {
|
|
84
|
+
issues.push({ type: "critical", msg: "Corrupted architecture.json - backup and regenerate", fix: "reset_architecture" });
|
|
85
|
+
} else if (archValidation.action == "incomplete") {
|
|
86
|
+
issues.push({ type: "warning", msg: `Incomplete architecture.json - missing field: ${archValidation.missing_field}` });
|
|
87
|
+
}
|
|
47
88
|
} else {
|
|
48
|
-
const arch =
|
|
89
|
+
const arch = archValidation.content;
|
|
49
90
|
if (!arch.language || !arch.framework) {
|
|
50
91
|
issues.push({ type: "warning", msg: "Incomplete architecture analysis" });
|
|
51
92
|
}
|
|
52
93
|
}
|
|
53
94
|
|
|
54
95
|
// 2. Check core agents
|
|
55
|
-
const coreAgents = ["backend", "frontend", "tester", "reviewer", "fixer", "orchestrator"];
|
|
96
|
+
const coreAgents = ["backend", "frontend", "tester", "reviewer", "fixer", "orchestrator", "architect", "product-analyzer"];
|
|
56
97
|
const existingAgents = Glob(".claude/agents/*.md").map(extractName);
|
|
57
98
|
const missingAgents = coreAgents.filter(a => !existingAgents.includes(a));
|
|
58
99
|
if (missingAgents.length > 0) {
|
|
@@ -84,14 +125,25 @@ for (const dep of deps) {
|
|
|
84
125
|
}
|
|
85
126
|
}
|
|
86
127
|
|
|
87
|
-
// 4.
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
128
|
+
// 4. Validate state files with proper validation
|
|
129
|
+
const stateFilesConfig = [
|
|
130
|
+
{ path: ".agentful/state.json", fields: ["current_task", "current_phase", "iterations"] },
|
|
131
|
+
{ path: ".agentful/completion.json", fields: ["features", "gates"] },
|
|
132
|
+
{ path: ".agentful/decisions.json", fields: ["pending"], optional: true }
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
for (const config of stateFilesConfig) {
|
|
136
|
+
if (exists(config.path) || !config.optional) {
|
|
137
|
+
const validation = validate_state_file(config.path, config.fields);
|
|
138
|
+
|
|
139
|
+
if (!validation.valid) {
|
|
140
|
+
if (validation.action == "not_found" && !config.optional) {
|
|
141
|
+
issues.push({ type: "warning", msg: `Missing state file: ${config.path}`, fix: `initialize_state:${config.path}` });
|
|
142
|
+
} else if (validation.action == "corrupted") {
|
|
143
|
+
issues.push({ type: "error", msg: `Corrupted state file: ${config.path}`, fix: `reset_state:${config.path}` });
|
|
144
|
+
} else if (validation.action == "incomplete") {
|
|
145
|
+
issues.push({ type: "warning", msg: `Incomplete state file: ${config.path} (missing: ${validation.missing_field})`, fix: `repair_state:${config.path}` });
|
|
146
|
+
}
|
|
95
147
|
}
|
|
96
148
|
}
|
|
97
149
|
}
|
|
@@ -108,7 +160,7 @@ Status: ⚠️ WARNINGS
|
|
|
108
160
|
|
|
109
161
|
Core Setup:
|
|
110
162
|
✓ architecture.json valid
|
|
111
|
-
✓ All core agents present (
|
|
163
|
+
✓ All core agents present (8/8)
|
|
112
164
|
✓ State files intact
|
|
113
165
|
|
|
114
166
|
Tech Stack Alignment:
|
|
@@ -166,21 +218,33 @@ Comprehensive analysis including codebase scanning.
|
|
|
166
218
|
// Run quick checks first
|
|
167
219
|
await runQuickChecks();
|
|
168
220
|
|
|
169
|
-
// 1. Domain discovery (lightweight
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
221
|
+
// 1. Domain discovery (inline lightweight scan)
|
|
222
|
+
// Scan common domain directories for structure
|
|
223
|
+
const srcDirs = Glob("src/**/").filter(d =>
|
|
224
|
+
!d.includes("node_modules") &&
|
|
225
|
+
!d.includes("test") &&
|
|
226
|
+
!d.includes("__")
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const domains = [];
|
|
230
|
+
for (const dir of srcDirs) {
|
|
231
|
+
const files = Glob(`${dir}/*.{ts,tsx,js,jsx}`);
|
|
232
|
+
if (files.length >= 3) { // At least 3 files suggests a domain
|
|
233
|
+
const domainName = extractDomainName(dir);
|
|
234
|
+
domains.push({ name: domainName, path: dir, fileCount: files.length });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
174
237
|
|
|
238
|
+
const coreAgents = ["backend", "frontend", "tester", "reviewer", "fixer", "orchestrator", "architect", "product-analyzer"];
|
|
175
239
|
const domainAgents = Glob(".claude/agents/*.md")
|
|
176
|
-
.filter(p => !
|
|
240
|
+
.filter(p => !coreAgents.includes(extractName(p)));
|
|
177
241
|
|
|
178
242
|
// Check for missing domain agents
|
|
179
243
|
for (const domain of domains) {
|
|
180
244
|
if (!domainAgents.some(a => extractName(a) === domain.name)) {
|
|
181
245
|
issues.push({
|
|
182
246
|
type: "info",
|
|
183
|
-
msg: `Domain '${domain.name}' detected (${domain.
|
|
247
|
+
msg: `Domain '${domain.name}' detected (${domain.fileCount} files) but no agent exists`,
|
|
184
248
|
fix: `generate_domain_agent:${domain.name}`
|
|
185
249
|
});
|
|
186
250
|
}
|
|
@@ -198,15 +262,33 @@ for (const agent of domainAgents) {
|
|
|
198
262
|
}
|
|
199
263
|
}
|
|
200
264
|
|
|
201
|
-
// 2. Skill content validation
|
|
265
|
+
// 2. Skill content validation (inline basic checks)
|
|
202
266
|
const skills = Glob(".claude/skills/*/SKILL.md");
|
|
203
267
|
for (const skillPath of skills) {
|
|
204
|
-
const
|
|
205
|
-
|
|
268
|
+
const content = Read(skillPath);
|
|
269
|
+
const skillName = extractSkillName(skillPath);
|
|
270
|
+
const validationIssues = [];
|
|
271
|
+
|
|
272
|
+
// Check if skill is just a placeholder
|
|
273
|
+
if (content.length < 500) {
|
|
274
|
+
validationIssues.push("too short (likely placeholder)");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Check if skill has TODO markers
|
|
278
|
+
if (content.includes("TODO") || content.includes("PLACEHOLDER")) {
|
|
279
|
+
validationIssues.push("contains TODOs/placeholders");
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Check if skill has basic structure
|
|
283
|
+
if (!content.includes("## Overview") && !content.includes("## Usage")) {
|
|
284
|
+
validationIssues.push("missing standard sections");
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (validationIssues.length > 0) {
|
|
206
288
|
issues.push({
|
|
207
289
|
type: "warning",
|
|
208
|
-
msg: `Skill '${
|
|
209
|
-
fix: `regenerate_skill:${
|
|
290
|
+
msg: `Skill '${skillName}' has issues: ${validationIssues.join(", ")}`,
|
|
291
|
+
fix: `regenerate_skill:${skillName}`
|
|
210
292
|
});
|
|
211
293
|
}
|
|
212
294
|
}
|
|
@@ -339,24 +421,30 @@ for (const issue of fixGroups.critical) {
|
|
|
339
421
|
await applyFix(issue.fix);
|
|
340
422
|
}
|
|
341
423
|
|
|
342
|
-
// Skills (
|
|
424
|
+
// Skills (delegate to architect)
|
|
343
425
|
if (fixGroups.skills.length > 0) {
|
|
344
426
|
console.log("\n🔧 Fixing skills...");
|
|
345
|
-
|
|
346
|
-
Task("
|
|
347
|
-
|
|
427
|
+
for (const issue of fixGroups.skills) {
|
|
428
|
+
await Task("architect", {
|
|
429
|
+
action: "manage_skills",
|
|
430
|
+
fix: issue.fix,
|
|
431
|
+
msg: issue.msg
|
|
432
|
+
});
|
|
433
|
+
}
|
|
348
434
|
}
|
|
349
435
|
|
|
350
|
-
// Agents (
|
|
436
|
+
// Agents (delegate to architect)
|
|
351
437
|
if (fixGroups.agents.length > 0) {
|
|
352
438
|
console.log("\n🔧 Fixing agents...");
|
|
353
|
-
|
|
354
|
-
Task("
|
|
355
|
-
|
|
439
|
+
for (const issue of fixGroups.agents) {
|
|
440
|
+
await Task("architect", {
|
|
441
|
+
action: "manage_agents",
|
|
442
|
+
fix: issue.fix,
|
|
443
|
+
msg: issue.msg
|
|
444
|
+
});
|
|
445
|
+
}
|
|
356
446
|
}
|
|
357
447
|
|
|
358
|
-
await Promise.all(fixTasks);
|
|
359
|
-
|
|
360
448
|
// Architecture updates (sequential)
|
|
361
449
|
for (const issue of fixGroups.architecture) {
|
|
362
450
|
await applyFix(issue.fix);
|
|
@@ -413,7 +501,7 @@ Status: ✓ HEALTHY
|
|
|
413
501
|
|
|
414
502
|
Core Setup:
|
|
415
503
|
✓ architecture.json valid
|
|
416
|
-
✓ All core agents present (
|
|
504
|
+
✓ All core agents present (8/8)
|
|
417
505
|
✓ State files intact
|
|
418
506
|
|
|
419
507
|
Tech Stack Alignment:
|
|
@@ -438,18 +526,34 @@ async function applyFix(fixString: string): Promise<void> {
|
|
|
438
526
|
|
|
439
527
|
switch (action) {
|
|
440
528
|
case "generate_skill":
|
|
441
|
-
|
|
529
|
+
// Delegate to architect agent
|
|
530
|
+
await Task("architect", {
|
|
531
|
+
action: "generate_skill",
|
|
532
|
+
skill_name: params[0],
|
|
533
|
+
context: "detected missing skill for framework"
|
|
534
|
+
});
|
|
442
535
|
break;
|
|
443
536
|
|
|
444
537
|
case "regenerate_skill":
|
|
445
|
-
|
|
538
|
+
// Delegate to architect agent
|
|
539
|
+
await Task("architect", {
|
|
540
|
+
action: "regenerate_skill",
|
|
541
|
+
skill_name: params[0],
|
|
542
|
+
context: "skill outdated or has quality issues"
|
|
543
|
+
});
|
|
446
544
|
break;
|
|
447
545
|
|
|
448
546
|
case "generate_domain_agent":
|
|
449
|
-
|
|
547
|
+
// Delegate to architect agent
|
|
548
|
+
await Task("architect", {
|
|
549
|
+
action: "generate_agent",
|
|
550
|
+
domain: params[0],
|
|
551
|
+
context: "domain detected in codebase without agent"
|
|
552
|
+
});
|
|
450
553
|
break;
|
|
451
554
|
|
|
452
555
|
case "archive_agent":
|
|
556
|
+
// Inline archival logic
|
|
453
557
|
const agentPath = `.claude/agents/${params[0]}.md`;
|
|
454
558
|
const archivePath = `.claude/agents/archived/${params[0]}.md`;
|
|
455
559
|
const content = Read(agentPath);
|
|
@@ -458,6 +562,7 @@ async function applyFix(fixString: string): Promise<void> {
|
|
|
458
562
|
break;
|
|
459
563
|
|
|
460
564
|
case "update_architecture":
|
|
565
|
+
// Inline architecture update logic
|
|
461
566
|
const arch = JSON.parse(Read(".agentful/architecture.json"));
|
|
462
567
|
if (params[0] === "add") {
|
|
463
568
|
arch.dependencies = arch.dependencies || [];
|
|
@@ -469,6 +574,7 @@ async function applyFix(fixString: string): Promise<void> {
|
|
|
469
574
|
break;
|
|
470
575
|
|
|
471
576
|
case "reset_state":
|
|
577
|
+
// Inline state reset logic
|
|
472
578
|
const statePath = params[0];
|
|
473
579
|
const backup = Read(statePath);
|
|
474
580
|
Write(`${statePath}.backup`, backup);
|
|
@@ -487,7 +593,8 @@ This command can be called from PostToolUse hooks:
|
|
|
487
593
|
```typescript
|
|
488
594
|
// .claude/hooks/post-edit-package-json.ts
|
|
489
595
|
if (file_path.includes("package.json")) {
|
|
490
|
-
|
|
596
|
+
// Trigger quick analysis via /agentful-analyze command
|
|
597
|
+
console.log("Dependency file changed - run /agentful-analyze to check alignment");
|
|
491
598
|
}
|
|
492
599
|
```
|
|
493
600
|
|
|
@@ -496,7 +603,8 @@ if (file_path.includes("package.json")) {
|
|
|
496
603
|
```typescript
|
|
497
604
|
// .claude/hooks/post-architecture-update.ts
|
|
498
605
|
if (file_path === ".agentful/architecture.json") {
|
|
499
|
-
|
|
606
|
+
// Trigger quick analysis via /agentful-analyze command
|
|
607
|
+
console.log("Architecture updated - run /agentful-analyze to validate setup");
|
|
500
608
|
}
|
|
501
609
|
```
|
|
502
610
|
|
|
@@ -541,7 +649,7 @@ npm install next@15
|
|
|
541
649
|
1. **Quick mode** is non-invasive and fast - suitable for hooks
|
|
542
650
|
2. **Full mode** scans codebase - takes longer but thorough
|
|
543
651
|
3. **Fix mode** requires user confirmation before changes
|
|
544
|
-
4. All fixes are
|
|
652
|
+
4. All fixes are delegated to the architect agent or applied inline
|
|
545
653
|
5. State files are backed up before reset
|
|
546
654
|
6. Agents are archived (not deleted) when stale
|
|
547
655
|
|