@itz4blitz/agentful 0.2.1 → 0.3.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.
@@ -8,29 +8,29 @@ set -e
8
8
 
9
9
  # Check if .agentful directory exists
10
10
  if [ ! -d ".agentful" ]; then
11
- echo "Agentful not initialized. Run /agentful-start to set up."
11
+ echo "Agentful not initialized. Run: npx @itz4blitz/agentful init"
12
12
  exit 0
13
13
  fi
14
14
 
15
- # Check for critical files
16
- WARNINGS=()
17
-
15
+ # Check if this is a fresh init (no architecture.json means analysis hasn't run)
18
16
  if [ ! -f ".agentful/architecture.json" ]; then
19
- WARNINGS+=("Architecture config missing. Run /agentful-analyze to detect tech stack.")
17
+ echo "Agentful initialized but not analyzed."
18
+ echo ""
19
+ echo "Run /agentful-generate to:"
20
+ echo " - Detect your tech stack"
21
+ echo " - Discover business domains"
22
+ echo " - Generate specialized agents and skills"
23
+ exit 0
20
24
  fi
21
25
 
22
- if [ ! -f "package.json" ] && [ ! -f "pyproject.toml" ] && [ ! -f "go.mod" ] && [ ! -f "Cargo.toml" ]; then
23
- WARNINGS+=("No package manager config found. Project structure unclear.")
24
- fi
26
+ # Check for generated agents
27
+ AGENT_COUNT=$(find .claude/agents -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
28
+ SKILL_COUNT=$(find .claude/skills -name "SKILL.md" 2>/dev/null | wc -l | tr -d ' ')
25
29
 
26
- # Output any warnings
27
- if [ ${#WARNINGS[@]} -gt 0 ]; then
28
- echo "Agentful Health Check:"
29
- for warning in "${WARNINGS[@]}"; do
30
- echo " - $warning"
31
- done
32
- else
33
- echo "Agentful ready."
30
+ if [ "$AGENT_COUNT" -lt 3 ] || [ "$SKILL_COUNT" -lt 1 ]; then
31
+ echo "Agentful ready. Consider running /agentful-generate to generate more agents/skills."
32
+ exit 0
34
33
  fi
35
34
 
35
+ echo "Agentful ready."
36
36
  exit 0
package/lib/index.js CHANGED
@@ -1,40 +1,10 @@
1
- #!/usr/bin/env node
2
-
3
1
  /**
4
- * agentful Analysis Engine
5
- * Smart project analysis for autonomous development
2
+ * agentful - Lightweight project initialization
6
3
  *
7
- * @module agentful/analyzer
8
- */
9
-
10
- export { analyzeProject, exportToArchitectureJson } from './project-analyzer.js';
11
- export { detectDomains, getDomainKeywords, getAllDomains, addCustomDomainPattern } from './domain-detector.js';
12
- export { detectTechStack } from './tech-stack-detector.js';
13
-
14
- /**
15
- * Main entry point for project analysis
16
- * @param {string} projectRoot - Root directory of the project to analyze
17
- * @returns {Promise<Object>} Comprehensive project analysis
18
- */
19
- export async function analyze(projectRoot) {
20
- return await analyzeProject(projectRoot);
21
- }
22
-
23
- /**
24
- * Quick tech stack detection
25
- * @param {string} projectRoot - Root directory of the project
26
- * @returns {Promise<Object>} Detected tech stack
4
+ * The heavy analysis is done by Claude via /agentful-agents and /agentful-skills commands.
5
+ * This module just handles template copying and state management.
6
+ *
7
+ * @module agentful
27
8
  */
28
- export async function detectStack(projectRoot) {
29
- return await detectTechStack(projectRoot);
30
- }
31
9
 
32
- /**
33
- * Domain detection
34
- * @param {string} projectRoot - Root directory of the project
35
- * @param {Object} quickScan - Optional quick scan results
36
- * @returns {Promise<Object>} Detected domains with confidence scores
37
- */
38
- export async function detectBusinessDomains(projectRoot, quickScan) {
39
- return await detectDomains(projectRoot, quickScan);
40
- }
10
+ export { initProject, copyDirectory, isInitialized, getState } from './init.js';
package/lib/init.js ADDED
@@ -0,0 +1,162 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ const TEMPLATE_DIR = path.join(__dirname, '..', 'template');
7
+ const CLAUDE_DIR = path.join(__dirname, '..', '.claude');
8
+
9
+ /**
10
+ * Initialize agentful in a target project directory
11
+ * @param {string} targetDir - Target project directory
12
+ * @param {Object} options - Initialization options
13
+ * @param {boolean} options.includeProduct - Whether to include PRODUCT.md template
14
+ * @returns {Promise<{success: boolean, files: string[]}>}
15
+ */
16
+ export async function initProject(targetDir, options = {}) {
17
+ const { includeProduct = false } = options;
18
+ const createdFiles = [];
19
+
20
+ try {
21
+ // Ensure target directory exists
22
+ await fs.access(targetDir);
23
+
24
+ // 1. Copy .claude/ directory (agents, skills, commands)
25
+ const claudeTargetDir = path.join(targetDir, '.claude');
26
+
27
+ try {
28
+ await fs.access(CLAUDE_DIR);
29
+ await copyDirectory(CLAUDE_DIR, claudeTargetDir);
30
+ createdFiles.push('.claude/');
31
+ } catch (err) {
32
+ // .claude directory doesn't exist in package, skip
33
+ }
34
+
35
+ // 2. Copy CLAUDE.md template
36
+ const claudeMdSource = path.join(TEMPLATE_DIR, 'CLAUDE.md');
37
+ const claudeMdTarget = path.join(targetDir, 'CLAUDE.md');
38
+
39
+ try {
40
+ await fs.access(claudeMdSource);
41
+ await fs.copyFile(claudeMdSource, claudeMdTarget);
42
+ createdFiles.push('CLAUDE.md');
43
+ } catch (err) {
44
+ // CLAUDE.md template doesn't exist, skip
45
+ }
46
+
47
+ // 3. Create .agentful/ directory with state files
48
+ const agentfulDir = path.join(targetDir, '.agentful');
49
+ await fs.mkdir(agentfulDir, { recursive: true });
50
+ createdFiles.push('.agentful/');
51
+
52
+ // Create state.json
53
+ const stateFile = path.join(agentfulDir, 'state.json');
54
+ const initialState = {
55
+ initialized: new Date().toISOString(),
56
+ version: '1.0.0',
57
+ agents: [],
58
+ skills: []
59
+ };
60
+ await fs.writeFile(stateFile, JSON.stringify(initialState, null, 2));
61
+ createdFiles.push('.agentful/state.json');
62
+
63
+ // Create completion.json
64
+ const completionFile = path.join(agentfulDir, 'completion.json');
65
+ const initialCompletion = {
66
+ agents: {},
67
+ skills: {},
68
+ lastUpdated: new Date().toISOString()
69
+ };
70
+ await fs.writeFile(completionFile, JSON.stringify(initialCompletion, null, 2));
71
+ createdFiles.push('.agentful/completion.json');
72
+
73
+ // Create decisions.json
74
+ const decisionsFile = path.join(agentfulDir, 'decisions.json');
75
+ const initialDecisions = {
76
+ decisions: [],
77
+ lastUpdated: new Date().toISOString()
78
+ };
79
+ await fs.writeFile(decisionsFile, JSON.stringify(initialDecisions, null, 2));
80
+ createdFiles.push('.agentful/decisions.json');
81
+
82
+ // 4. Optionally copy PRODUCT.md template
83
+ if (includeProduct) {
84
+ const productMdSource = path.join(TEMPLATE_DIR, 'PRODUCT.md');
85
+ const productMdTarget = path.join(targetDir, 'PRODUCT.md');
86
+
87
+ try {
88
+ await fs.access(productMdSource);
89
+ await fs.copyFile(productMdSource, productMdTarget);
90
+ createdFiles.push('PRODUCT.md');
91
+ } catch (err) {
92
+ // PRODUCT.md template doesn't exist, skip
93
+ }
94
+ }
95
+
96
+ return {
97
+ success: true,
98
+ files: createdFiles
99
+ };
100
+ } catch (error) {
101
+ throw new Error(`Failed to initialize project: ${error.message}`);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Recursively copy a directory
107
+ * @param {string} src - Source directory
108
+ * @param {string} dest - Destination directory
109
+ */
110
+ export async function copyDirectory(src, dest) {
111
+ // Create destination directory
112
+ await fs.mkdir(dest, { recursive: true });
113
+
114
+ // Read source directory
115
+ const entries = await fs.readdir(src, { withFileTypes: true });
116
+
117
+ for (const entry of entries) {
118
+ const srcPath = path.join(src, entry.name);
119
+ const destPath = path.join(dest, entry.name);
120
+
121
+ if (entry.isDirectory()) {
122
+ // Recursively copy subdirectory
123
+ await copyDirectory(srcPath, destPath);
124
+ } else {
125
+ // Copy file
126
+ await fs.copyFile(srcPath, destPath);
127
+ }
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Check if project is already initialized
133
+ * @param {string} targetDir - Target project directory
134
+ * @returns {Promise<boolean>}
135
+ */
136
+ export async function isInitialized(targetDir) {
137
+ const agentfulDir = path.join(targetDir, '.agentful');
138
+ const stateFile = path.join(agentfulDir, 'state.json');
139
+
140
+ try {
141
+ await fs.access(stateFile);
142
+ return true;
143
+ } catch {
144
+ return false;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Get current state from .agentful/state.json
150
+ * @param {string} targetDir - Target project directory
151
+ * @returns {Promise<Object|null>}
152
+ */
153
+ export async function getState(targetDir) {
154
+ const stateFile = path.join(targetDir, '.agentful', 'state.json');
155
+
156
+ try {
157
+ const content = await fs.readFile(stateFile, 'utf-8');
158
+ return JSON.parse(content);
159
+ } catch {
160
+ return null;
161
+ }
162
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itz4blitz/agentful",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Human-in-the-loop development kit for Claude Code with smart product analysis and natural conversation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,6 @@
23
23
  "bin/",
24
24
  "lib/",
25
25
  "template/",
26
- "templates/",
27
26
  ".claude/",
28
27
  "version.json",
29
28
  "LICENSE"
package/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.2.0"
2
+ "version": "0.2.1"
3
3
  }