@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.
Files changed (94) hide show
  1. package/README.md +139 -10
  2. package/bin/cli.js +1032 -48
  3. package/bin/hooks/README.md +338 -82
  4. package/bin/hooks/analyze-trigger.js +69 -0
  5. package/bin/hooks/block-random-docs.js +77 -0
  6. package/bin/hooks/health-check.js +153 -0
  7. package/bin/hooks/post-agent.js +101 -0
  8. package/bin/hooks/post-feature.js +227 -0
  9. package/bin/hooks/pre-agent.js +118 -0
  10. package/bin/hooks/pre-feature.js +138 -0
  11. package/lib/VALIDATION_README.md +455 -0
  12. package/lib/atomic.js +350 -0
  13. package/lib/ci/claude-action-integration.js +641 -0
  14. package/lib/ci/index.js +10 -0
  15. package/lib/core/CLAUDE_EXECUTOR.md +371 -0
  16. package/lib/core/README.md +321 -0
  17. package/lib/core/analyzer.js +497 -0
  18. package/lib/core/claude-executor.example.js +210 -0
  19. package/lib/core/claude-executor.js +1046 -0
  20. package/lib/core/cli.js +141 -0
  21. package/lib/core/detectors/conventions.js +342 -0
  22. package/lib/core/detectors/framework.js +276 -0
  23. package/lib/core/detectors/index.js +15 -0
  24. package/lib/core/detectors/language.js +199 -0
  25. package/lib/core/detectors/patterns.js +356 -0
  26. package/lib/core/generator.js +626 -0
  27. package/lib/core/index.js +9 -0
  28. package/lib/core/output-parser.example.js +250 -0
  29. package/lib/core/output-parser.js +458 -0
  30. package/lib/core/storage.js +515 -0
  31. package/lib/core/templates.js +556 -0
  32. package/lib/index.js +32 -0
  33. package/lib/init.js +497 -25
  34. package/lib/pipeline/cli.js +423 -0
  35. package/lib/pipeline/engine.js +928 -0
  36. package/lib/pipeline/executor.js +440 -0
  37. package/lib/pipeline/index.js +33 -0
  38. package/lib/pipeline/integrations.js +559 -0
  39. package/lib/pipeline/schemas.js +288 -0
  40. package/lib/presets.js +207 -0
  41. package/lib/remote/client.js +361 -0
  42. package/lib/server/auth.js +286 -0
  43. package/lib/server/client-example.js +190 -0
  44. package/lib/server/executor.js +426 -0
  45. package/lib/server/index.js +469 -0
  46. package/lib/update-helpers.js +505 -0
  47. package/lib/validation.js +460 -0
  48. package/package.json +19 -2
  49. package/template/.claude/agents/architect.md +260 -0
  50. package/template/.claude/agents/backend.md +203 -0
  51. package/template/.claude/agents/fixer.md +244 -0
  52. package/template/.claude/agents/frontend.md +232 -0
  53. package/template/.claude/agents/orchestrator.md +528 -0
  54. package/template/.claude/agents/product-analyzer.md +1130 -0
  55. package/template/.claude/agents/reviewer.md +229 -0
  56. package/template/.claude/agents/tester.md +242 -0
  57. package/{.claude → template/.claude}/commands/agentful-analyze.md +151 -43
  58. package/template/.claude/commands/agentful-decide.md +470 -0
  59. package/{.claude → template/.claude}/commands/agentful-product.md +92 -8
  60. package/template/.claude/commands/agentful-start.md +432 -0
  61. package/{.claude → template/.claude}/commands/agentful-status.md +88 -3
  62. package/template/.claude/commands/agentful-update.md +402 -0
  63. package/template/.claude/commands/agentful-validate.md +369 -0
  64. package/{.claude → template/.claude}/commands/agentful.md +111 -195
  65. package/template/.claude/product/EXAMPLES.md +167 -0
  66. package/{.claude → template/.claude}/settings.json +9 -13
  67. package/{.claude → template/.claude}/skills/conversation/SKILL.md +13 -7
  68. package/template/.claude/skills/deployment/SKILL.md +116 -0
  69. package/template/.claude/skills/product-planning/SKILL.md +463 -0
  70. package/{.claude → template/.claude}/skills/product-tracking/SKILL.md +10 -21
  71. package/template/.claude/skills/testing/SKILL.md +228 -0
  72. package/template/.claude/skills/validation/SKILL.md +650 -0
  73. package/template/CLAUDE.md +84 -16
  74. package/template/bin/hooks/block-random-docs.js +121 -0
  75. package/version.json +1 -1
  76. package/.claude/agents/architect.md +0 -524
  77. package/.claude/agents/backend.md +0 -315
  78. package/.claude/agents/fixer.md +0 -263
  79. package/.claude/agents/frontend.md +0 -274
  80. package/.claude/agents/orchestrator.md +0 -283
  81. package/.claude/agents/product-analyzer.md +0 -799
  82. package/.claude/agents/reviewer.md +0 -332
  83. package/.claude/agents/tester.md +0 -410
  84. package/.claude/commands/agentful-decide.md +0 -214
  85. package/.claude/commands/agentful-start.md +0 -182
  86. package/.claude/commands/agentful-validate.md +0 -127
  87. package/.claude/product/EXAMPLES.md +0 -610
  88. package/.claude/product/README.md +0 -344
  89. package/.claude/skills/validation/SKILL.md +0 -271
  90. package/bin/hooks/analyze-trigger.sh +0 -57
  91. package/bin/hooks/health-check.sh +0 -36
  92. package/template/PRODUCT.md +0 -584
  93. /package/{.claude → template/.claude}/commands/agentful-generate.md +0 -0
  94. /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. Check architecture.json
76
+ // 1. Validate and check architecture.json
44
77
  const archPath = ".agentful/architecture.json";
45
- if (!exists(archPath)) {
46
- issues.push({ type: "critical", msg: "Missing architecture.json - run /agentful-start" });
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 = JSON.parse(Read(archPath));
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. Check state files
88
- const stateFiles = [".agentful/state.json", ".agentful/completion.json"];
89
- for (const file of stateFiles) {
90
- if (exists(file)) {
91
- try {
92
- JSON.parse(Read(file));
93
- } catch {
94
- issues.push({ type: "error", msg: `Corrupted state file: ${file}`, fix: `reset_state:${file}` });
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 (6/6)
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 version of /agentful-agents)
170
- const domains = await Task("domain-explorer-lightweight", {
171
- mode: "fast",
172
- confidence_threshold: 0.75
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 => !["backend", "frontend", "tester", "reviewer", "fixer", "orchestrator"].includes(extractName(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.confidence}%) but no agent exists`,
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 validation = await Task("skill-validator", { path: skillPath });
205
- if (validation.status !== "valid") {
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 '${extractSkillName(skillPath)}' has issues: ${validation.issues.join(", ")}`,
209
- fix: `regenerate_skill:${extractSkillName(skillPath)}`
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 (parallel)
424
+ // Skills (delegate to architect)
343
425
  if (fixGroups.skills.length > 0) {
344
426
  console.log("\n🔧 Fixing skills...");
345
- fixTasks.push(...fixGroups.skills.map(issue =>
346
- Task("fix-applier", { fix: issue.fix, msg: issue.msg })
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 (parallel)
436
+ // Agents (delegate to architect)
351
437
  if (fixGroups.agents.length > 0) {
352
438
  console.log("\n🔧 Fixing agents...");
353
- fixTasks.push(...fixGroups.agents.map(issue =>
354
- Task("fix-applier", { fix: issue.fix, msg: issue.msg })
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 (6/6)
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
- await Task("skill-generator", { skill_name: params[0] });
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
- await Task("skill-regenerator", { skill_name: params[0] });
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
- await Task("agent-generator", { domain: params[0] });
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
- Task("agentful-analyzer", { mode: "quick", context: "package.json changed" });
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
- Task("agentful-analyzer", { mode: "quick", context: "architecture updated" });
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 applied using existing sub-agents (skill-generator, agent-generator, etc.)
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