@itz4blitz/agentful 0.2.1 → 0.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/.claude/agents/orchestrator.md +121 -610
- package/.claude/agents/product-analyzer.md +3 -10
- package/.claude/commands/agentful-generate.md +206 -0
- package/.claude/commands/agentful-product.md +3 -3
- package/.claude/commands/agentful.md +1 -12
- package/.claude/product/EXAMPLES.md +2 -2
- package/.claude/product/README.md +9 -27
- package/.claude/skills/conversation/SKILL.md +152 -975
- package/.claude/skills/product-tracking/SKILL.md +10 -21
- package/README.md +6 -5
- package/bin/cli.js +108 -583
- package/bin/hooks/health-check.sh +16 -16
- package/lib/index.js +6 -36
- package/lib/init.js +411 -0
- package/package.json +1 -2
- package/template/CLAUDE.md +11 -11
- package/version.json +1 -1
- package/.claude/commands/agentful-agents.md +0 -668
- package/.claude/commands/agentful-skills.md +0 -635
- package/.claude/product/CHANGES.md +0 -276
- package/lib/agent-generator.js +0 -778
- package/lib/domain-detector.js +0 -468
- package/lib/domain-structure-generator.js +0 -770
- package/lib/project-analyzer.js +0 -701
- package/lib/tech-stack-detector.js +0 -1091
- package/lib/template-engine.js +0 -240
- package/template/PRODUCT.md +0 -584
- package/templates/agents/domain-agent.template.md +0 -208
- package/templates/agents/tech-agent.template.md +0 -124
|
@@ -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
|
|
11
|
+
echo "Agentful not initialized. Run: npx @itz4blitz/agentful init"
|
|
12
12
|
exit 0
|
|
13
13
|
fi
|
|
14
14
|
|
|
15
|
-
# Check
|
|
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
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
5
|
-
* Smart project analysis for autonomous development
|
|
2
|
+
* agentful - Lightweight project initialization
|
|
6
3
|
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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,411 @@
|
|
|
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
|
+
* @returns {Promise<{success: boolean, files: string[]}>}
|
|
13
|
+
*/
|
|
14
|
+
export async function initProject(targetDir) {
|
|
15
|
+
const createdFiles = [];
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Ensure target directory exists
|
|
19
|
+
await fs.access(targetDir);
|
|
20
|
+
|
|
21
|
+
// 1. Copy .claude/ directory (agents, skills, commands)
|
|
22
|
+
const claudeTargetDir = path.join(targetDir, '.claude');
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
await fs.access(CLAUDE_DIR);
|
|
26
|
+
await copyDirectory(CLAUDE_DIR, claudeTargetDir);
|
|
27
|
+
createdFiles.push('.claude/');
|
|
28
|
+
} catch (err) {
|
|
29
|
+
// .claude directory doesn't exist in package, skip
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 2. Copy CLAUDE.md template
|
|
33
|
+
const claudeMdSource = path.join(TEMPLATE_DIR, 'CLAUDE.md');
|
|
34
|
+
const claudeMdTarget = path.join(targetDir, 'CLAUDE.md');
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
await fs.access(claudeMdSource);
|
|
38
|
+
await fs.copyFile(claudeMdSource, claudeMdTarget);
|
|
39
|
+
createdFiles.push('CLAUDE.md');
|
|
40
|
+
} catch (err) {
|
|
41
|
+
// CLAUDE.md template doesn't exist, skip
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 3. Create .agentful/ directory with state files
|
|
45
|
+
const agentfulDir = path.join(targetDir, '.agentful');
|
|
46
|
+
await fs.mkdir(agentfulDir, { recursive: true });
|
|
47
|
+
createdFiles.push('.agentful/');
|
|
48
|
+
|
|
49
|
+
// Create state.json
|
|
50
|
+
const stateFile = path.join(agentfulDir, 'state.json');
|
|
51
|
+
const initialState = {
|
|
52
|
+
initialized: new Date().toISOString(),
|
|
53
|
+
version: '1.0.0',
|
|
54
|
+
agents: [],
|
|
55
|
+
skills: []
|
|
56
|
+
};
|
|
57
|
+
await fs.writeFile(stateFile, JSON.stringify(initialState, null, 2));
|
|
58
|
+
createdFiles.push('.agentful/state.json');
|
|
59
|
+
|
|
60
|
+
// Create completion.json
|
|
61
|
+
const completionFile = path.join(agentfulDir, 'completion.json');
|
|
62
|
+
const initialCompletion = {
|
|
63
|
+
agents: {},
|
|
64
|
+
skills: {},
|
|
65
|
+
lastUpdated: new Date().toISOString()
|
|
66
|
+
};
|
|
67
|
+
await fs.writeFile(completionFile, JSON.stringify(initialCompletion, null, 2));
|
|
68
|
+
createdFiles.push('.agentful/completion.json');
|
|
69
|
+
|
|
70
|
+
// Create decisions.json
|
|
71
|
+
const decisionsFile = path.join(agentfulDir, 'decisions.json');
|
|
72
|
+
const initialDecisions = {
|
|
73
|
+
decisions: [],
|
|
74
|
+
lastUpdated: new Date().toISOString()
|
|
75
|
+
};
|
|
76
|
+
await fs.writeFile(decisionsFile, JSON.stringify(initialDecisions, null, 2));
|
|
77
|
+
createdFiles.push('.agentful/decisions.json');
|
|
78
|
+
|
|
79
|
+
// 4. Create .claude/product/ hierarchical structure
|
|
80
|
+
const productDir = path.join(targetDir, '.claude', 'product');
|
|
81
|
+
await fs.mkdir(productDir, { recursive: true });
|
|
82
|
+
|
|
83
|
+
// Create basic index.md template
|
|
84
|
+
const indexMdContent = `# Product Specification
|
|
85
|
+
|
|
86
|
+
## Overview
|
|
87
|
+
|
|
88
|
+
[Describe what you're building in 2-3 sentences]
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
> A task management application that helps teams collaborate on projects. Users can create projects, add tasks with deadlines, assign team members, and track progress with real-time updates.
|
|
92
|
+
|
|
93
|
+
## Goals
|
|
94
|
+
|
|
95
|
+
- [ ] [Primary goal 1]
|
|
96
|
+
- [ ] [Primary goal 2]
|
|
97
|
+
- [ ] [Primary goal 3]
|
|
98
|
+
|
|
99
|
+
## Tech Stack
|
|
100
|
+
|
|
101
|
+
### Frontend
|
|
102
|
+
- **Framework**: [Next.js 14 / React + Vite / Vue + Nuxt / SvelteKit]
|
|
103
|
+
- **Language**: [TypeScript / JavaScript]
|
|
104
|
+
- **Styling**: [Tailwind CSS / CSS Modules / styled-components / shadcn/ui]
|
|
105
|
+
- **State Management**: [Zustand / Context API / Redux / Jotai]
|
|
106
|
+
|
|
107
|
+
### Backend
|
|
108
|
+
- **Runtime**: [Node.js / Bun / Deno]
|
|
109
|
+
- **Framework**: [Next.js API Routes / Express / Fastify / NestJS / Hono]
|
|
110
|
+
- **Language**: [TypeScript / JavaScript]
|
|
111
|
+
|
|
112
|
+
### Database
|
|
113
|
+
- **Database**: [PostgreSQL / MySQL / SQLite / MongoDB / PlanetScale]
|
|
114
|
+
- **ORM**: [Prisma / Drizzle / TypeORM / Mongoose]
|
|
115
|
+
|
|
116
|
+
### Authentication
|
|
117
|
+
- **Method**: [JWT / NextAuth / Clerk / Auth0 / Lucia]
|
|
118
|
+
|
|
119
|
+
### Testing
|
|
120
|
+
- **Unit**: [Vitest / Jest]
|
|
121
|
+
- **E2E**: [Playwright / Cypress]
|
|
122
|
+
|
|
123
|
+
### Deployment
|
|
124
|
+
- **Hosting**: [Vercel / Netlify / Railway / Fly.io]
|
|
125
|
+
|
|
126
|
+
## Domains
|
|
127
|
+
|
|
128
|
+
Create domain-specific subdirectories under \`.claude/product/domains/\` to organize your features:
|
|
129
|
+
|
|
130
|
+
\`\`\`
|
|
131
|
+
.claude/product/
|
|
132
|
+
├── index.md (this file)
|
|
133
|
+
├── README.md
|
|
134
|
+
└── domains/
|
|
135
|
+
├── authentication/
|
|
136
|
+
│ ├── index.md
|
|
137
|
+
│ └── features/
|
|
138
|
+
│ ├── login.md
|
|
139
|
+
│ └── register.md
|
|
140
|
+
└── user-management/
|
|
141
|
+
├── index.md
|
|
142
|
+
└── features/
|
|
143
|
+
└── profile.md
|
|
144
|
+
\`\`\`
|
|
145
|
+
|
|
146
|
+
See \`.claude/product/README.md\` for detailed structure guidance.
|
|
147
|
+
|
|
148
|
+
## Architecture Notes
|
|
149
|
+
|
|
150
|
+
### Design Patterns
|
|
151
|
+
|
|
152
|
+
- [Any specific patterns to use]
|
|
153
|
+
- [Any patterns to avoid]
|
|
154
|
+
|
|
155
|
+
### Constraints
|
|
156
|
+
|
|
157
|
+
- [Performance requirements]
|
|
158
|
+
- [Accessibility requirements]
|
|
159
|
+
- [Browser support requirements]
|
|
160
|
+
|
|
161
|
+
## Third-Party Integrations (Optional)
|
|
162
|
+
|
|
163
|
+
- [API 1]: [Purpose]
|
|
164
|
+
- [API 2]: [Purpose]
|
|
165
|
+
|
|
166
|
+
## Out of Scope (for MVP)
|
|
167
|
+
|
|
168
|
+
List what you're explicitly NOT building:
|
|
169
|
+
|
|
170
|
+
- [Feature X] - Will add in v2
|
|
171
|
+
- [Feature Y] - Out of scope
|
|
172
|
+
- [Feature Z] - Not needed
|
|
173
|
+
|
|
174
|
+
## Success Criteria
|
|
175
|
+
|
|
176
|
+
The product is complete when:
|
|
177
|
+
|
|
178
|
+
1. [All critical features implemented and tested]
|
|
179
|
+
2. [All tests passing with 80%+ coverage]
|
|
180
|
+
3. [No TypeScript errors]
|
|
181
|
+
4. [No security vulnerabilities]
|
|
182
|
+
5. [Deployed to production]
|
|
183
|
+
|
|
184
|
+
## Notes
|
|
185
|
+
|
|
186
|
+
[Any additional context, links, or documentation]
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
**Tip**: The more detailed your product specification, the better agentful can understand what to build. Include:
|
|
191
|
+
- Clear acceptance criteria
|
|
192
|
+
- User stories for context
|
|
193
|
+
- Technical constraints
|
|
194
|
+
- Examples when helpful
|
|
195
|
+
`;
|
|
196
|
+
|
|
197
|
+
const indexMdPath = path.join(productDir, 'index.md');
|
|
198
|
+
await fs.writeFile(indexMdPath, indexMdContent);
|
|
199
|
+
createdFiles.push('.claude/product/index.md');
|
|
200
|
+
|
|
201
|
+
// Create README.md explaining the structure
|
|
202
|
+
const readmeMdContent = `# Product Structure Guide
|
|
203
|
+
|
|
204
|
+
agentful uses a hierarchical product structure to organize features by domain.
|
|
205
|
+
|
|
206
|
+
## Structure
|
|
207
|
+
|
|
208
|
+
\`\`\`
|
|
209
|
+
.claude/product/
|
|
210
|
+
├── index.md # Product overview (name, description, tech stack)
|
|
211
|
+
├── README.md # This file - documentation about the structure
|
|
212
|
+
└── domains/ # Business domains (create as needed)
|
|
213
|
+
├── authentication/
|
|
214
|
+
│ ├── index.md # Domain overview
|
|
215
|
+
│ └── features/
|
|
216
|
+
│ ├── login.md
|
|
217
|
+
│ └── register.md
|
|
218
|
+
└── user-management/
|
|
219
|
+
├── index.md
|
|
220
|
+
└── features/
|
|
221
|
+
└── profile.md
|
|
222
|
+
\`\`\`
|
|
223
|
+
|
|
224
|
+
## Files Explained
|
|
225
|
+
|
|
226
|
+
### \`index.md\` (Product Level)
|
|
227
|
+
- Product name and description
|
|
228
|
+
- Tech stack
|
|
229
|
+
- High-level goals
|
|
230
|
+
- List of domains
|
|
231
|
+
- Architecture notes
|
|
232
|
+
- Success criteria
|
|
233
|
+
|
|
234
|
+
### \`domains/{domain-name}/index.md\` (Domain Level)
|
|
235
|
+
- Domain description and purpose
|
|
236
|
+
- List of features in this domain
|
|
237
|
+
- Domain-specific constraints
|
|
238
|
+
- Dependencies on other domains
|
|
239
|
+
|
|
240
|
+
### \`domains/{domain-name}/features/{feature-name}.md\` (Feature Level)
|
|
241
|
+
- Feature description
|
|
242
|
+
- Priority (CRITICAL, HIGH, MEDIUM, LOW)
|
|
243
|
+
- Acceptance criteria (checkboxes)
|
|
244
|
+
- User stories
|
|
245
|
+
- Technical notes
|
|
246
|
+
- Subtasks breakdown
|
|
247
|
+
|
|
248
|
+
## When to Create a Domain
|
|
249
|
+
|
|
250
|
+
Create a new domain when you have:
|
|
251
|
+
- A distinct business area (e.g., authentication, billing, analytics)
|
|
252
|
+
- Multiple related features (e.g., login, register, password reset)
|
|
253
|
+
- Shared logic or data models
|
|
254
|
+
- Clear boundaries from other domains
|
|
255
|
+
|
|
256
|
+
**Example domains:**
|
|
257
|
+
- \`authentication\` - Login, registration, password reset
|
|
258
|
+
- \`user-management\` - Profile, settings, preferences
|
|
259
|
+
- \`purchasing\` - Cart, checkout, orders, payments
|
|
260
|
+
- \`analytics\` - Dashboards, reports, metrics
|
|
261
|
+
- \`content\` - Posts, comments, media uploads
|
|
262
|
+
|
|
263
|
+
## Example Feature File
|
|
264
|
+
|
|
265
|
+
\`\`\`markdown
|
|
266
|
+
<!-- .claude/product/domains/authentication/features/login.md -->
|
|
267
|
+
|
|
268
|
+
# Feature: User Login
|
|
269
|
+
|
|
270
|
+
**Priority**: CRITICAL
|
|
271
|
+
|
|
272
|
+
**Description**: Allow existing users to authenticate with email and password.
|
|
273
|
+
|
|
274
|
+
## Acceptance Criteria
|
|
275
|
+
|
|
276
|
+
- [ ] Login form with email and password fields
|
|
277
|
+
- [ ] Client-side validation before submission
|
|
278
|
+
- [ ] API endpoint POST /api/auth/login
|
|
279
|
+
- [ ] Returns JWT token on success
|
|
280
|
+
- [ ] Sets httpOnly cookie with token
|
|
281
|
+
- [ ] Returns 401 for invalid credentials
|
|
282
|
+
- [ ] Rate limited to 10 requests per minute
|
|
283
|
+
- [ ] Account lockout after 5 failed attempts
|
|
284
|
+
|
|
285
|
+
## User Stories
|
|
286
|
+
|
|
287
|
+
- As a returning user, I want to log in with my credentials so that I can access my account
|
|
288
|
+
|
|
289
|
+
## Subtasks
|
|
290
|
+
|
|
291
|
+
### 1. Create login form UI
|
|
292
|
+
**Status**: pending
|
|
293
|
+
|
|
294
|
+
- [ ] Email and password input fields
|
|
295
|
+
- [ ] "Remember me" checkbox
|
|
296
|
+
- [ ] "Forgot password" link
|
|
297
|
+
- [ ] Loading state during authentication
|
|
298
|
+
- [ ] Error message display
|
|
299
|
+
|
|
300
|
+
### 2. Implement login API endpoint
|
|
301
|
+
**Status**: pending
|
|
302
|
+
|
|
303
|
+
- [ ] Verify email exists in database
|
|
304
|
+
- [ ] Compare hashed password using bcrypt
|
|
305
|
+
- [ ] Generate JWT token with 7-day expiration
|
|
306
|
+
- [ ] Set secure httpOnly cookie
|
|
307
|
+
- [ ] Implement rate limiting
|
|
308
|
+
- [ ] Track failed login attempts
|
|
309
|
+
|
|
310
|
+
## Technical Notes
|
|
311
|
+
|
|
312
|
+
- Use jose or jsonwebtoken for JWT
|
|
313
|
+
- Store failed attempts in Redis
|
|
314
|
+
- Set cookie flags: httpOnly, secure, sameSite=strict
|
|
315
|
+
\`\`\`
|
|
316
|
+
|
|
317
|
+
## Priority Levels
|
|
318
|
+
|
|
319
|
+
- **CRITICAL** - Must have for MVP, blocks other features
|
|
320
|
+
- **HIGH** - Important for MVP, should include
|
|
321
|
+
- **MEDIUM** - Nice to have if time permits
|
|
322
|
+
- **LOW** - Future enhancement, not for MVP
|
|
323
|
+
|
|
324
|
+
## Status Tracking
|
|
325
|
+
|
|
326
|
+
- \`pending\` - Not started
|
|
327
|
+
- \`in-progress\` - Currently being worked on
|
|
328
|
+
- \`complete\` - Done and tested
|
|
329
|
+
- \`blocked\` - Waiting for decision or dependency
|
|
330
|
+
|
|
331
|
+
## Getting Started
|
|
332
|
+
|
|
333
|
+
1. Edit \`index.md\` to describe your product
|
|
334
|
+
2. Create domains under \`domains/\` for major functional areas
|
|
335
|
+
3. Add features under each domain's \`features/\` directory
|
|
336
|
+
4. Run \`/agentful-start\` in Claude Code to begin development
|
|
337
|
+
|
|
338
|
+
For more information, see the agentful documentation.
|
|
339
|
+
`;
|
|
340
|
+
|
|
341
|
+
const readmeMdPath = path.join(productDir, 'README.md');
|
|
342
|
+
await fs.writeFile(readmeMdPath, readmeMdContent);
|
|
343
|
+
createdFiles.push('.claude/product/README.md');
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
success: true,
|
|
347
|
+
files: createdFiles
|
|
348
|
+
};
|
|
349
|
+
} catch (error) {
|
|
350
|
+
throw new Error(`Failed to initialize project: ${error.message}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Recursively copy a directory
|
|
356
|
+
* @param {string} src - Source directory
|
|
357
|
+
* @param {string} dest - Destination directory
|
|
358
|
+
*/
|
|
359
|
+
export async function copyDirectory(src, dest) {
|
|
360
|
+
// Create destination directory
|
|
361
|
+
await fs.mkdir(dest, { recursive: true });
|
|
362
|
+
|
|
363
|
+
// Read source directory
|
|
364
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
365
|
+
|
|
366
|
+
for (const entry of entries) {
|
|
367
|
+
const srcPath = path.join(src, entry.name);
|
|
368
|
+
const destPath = path.join(dest, entry.name);
|
|
369
|
+
|
|
370
|
+
if (entry.isDirectory()) {
|
|
371
|
+
// Recursively copy subdirectory
|
|
372
|
+
await copyDirectory(srcPath, destPath);
|
|
373
|
+
} else {
|
|
374
|
+
// Copy file
|
|
375
|
+
await fs.copyFile(srcPath, destPath);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Check if project is already initialized
|
|
382
|
+
* @param {string} targetDir - Target project directory
|
|
383
|
+
* @returns {Promise<boolean>}
|
|
384
|
+
*/
|
|
385
|
+
export async function isInitialized(targetDir) {
|
|
386
|
+
const agentfulDir = path.join(targetDir, '.agentful');
|
|
387
|
+
const stateFile = path.join(agentfulDir, 'state.json');
|
|
388
|
+
|
|
389
|
+
try {
|
|
390
|
+
await fs.access(stateFile);
|
|
391
|
+
return true;
|
|
392
|
+
} catch {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Get current state from .agentful/state.json
|
|
399
|
+
* @param {string} targetDir - Target project directory
|
|
400
|
+
* @returns {Promise<Object|null>}
|
|
401
|
+
*/
|
|
402
|
+
export async function getState(targetDir) {
|
|
403
|
+
const stateFile = path.join(targetDir, '.agentful', 'state.json');
|
|
404
|
+
|
|
405
|
+
try {
|
|
406
|
+
const content = await fs.readFile(stateFile, 'utf-8');
|
|
407
|
+
return JSON.parse(content);
|
|
408
|
+
} catch {
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itz4blitz/agentful",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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/template/CLAUDE.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
7
|
-
1. Edit
|
|
7
|
+
1. Edit `.claude/product/index.md` to define your product requirements
|
|
8
8
|
2. Run: `claude`
|
|
9
9
|
3. Type: `/agentful-start`
|
|
10
10
|
|
|
@@ -28,7 +28,7 @@ claude --dangerously-skip-permissions
|
|
|
28
28
|
## When to Use What
|
|
29
29
|
|
|
30
30
|
**Starting fresh?**
|
|
31
|
-
→ Run `/agentful-product` to analyze your
|
|
31
|
+
→ Run `/agentful-product` to analyze your product spec, then `/agentful-start`
|
|
32
32
|
|
|
33
33
|
**Existing project?**
|
|
34
34
|
→ Run `/agentful-start` directly (auto-detects tech stack)
|
|
@@ -43,16 +43,16 @@ claude --dangerously-skip-permissions
|
|
|
43
43
|
→ Check `.agentful/decisions.json` or run `/agentful-decide`
|
|
44
44
|
|
|
45
45
|
**Unclear requirements?**
|
|
46
|
-
→ Run `/agentful-product` in reverse-engineering mode or improve
|
|
46
|
+
→ Run `/agentful-product` in reverse-engineering mode or improve `.claude/product/index.md`
|
|
47
47
|
|
|
48
48
|
**Want to add features?**
|
|
49
|
-
→ Edit
|
|
49
|
+
→ Edit `.claude/product/index.md`, then run `/agentful-start` (picks up changes automatically)
|
|
50
50
|
|
|
51
51
|
## File Structure
|
|
52
52
|
|
|
53
53
|
**Product Specification** (you edit these):
|
|
54
|
-
-
|
|
55
|
-
- `.claude/product/` - Hierarchical structure (
|
|
54
|
+
- `.claude/product/index.md` - Flat structure (all features in one file)
|
|
55
|
+
- `.claude/product/domains/` - Hierarchical structure (organized by domain)
|
|
56
56
|
|
|
57
57
|
**Runtime State** (managed by agentful, gitignored):
|
|
58
58
|
- `.agentful/state.json` - Current work phase and progress
|
|
@@ -81,22 +81,22 @@ The `reviewer` agent runs these checks automatically. The `fixer` agent resolves
|
|
|
81
81
|
## Troubleshooting
|
|
82
82
|
|
|
83
83
|
**"agentful keeps asking me unclear questions"**
|
|
84
|
-
→ Your
|
|
84
|
+
→ Your product spec needs more detail. Run `/agentful-product` to analyze and improve it.
|
|
85
85
|
|
|
86
86
|
**"Validation keeps failing"**
|
|
87
87
|
→ Check `.agentful/last-validation.json` for details. The `fixer` agent should auto-resolve, but you can run `/agentful-validate` manually.
|
|
88
88
|
|
|
89
89
|
**"Agent isn't working on the right feature"**
|
|
90
|
-
→ Check priority in
|
|
90
|
+
→ Check priority in `.claude/product/index.md`. CRITICAL > HIGH > MEDIUM > LOW. Run `/agentful-status` to see current focus.
|
|
91
91
|
|
|
92
92
|
**"State seems stuck or corrupted"**
|
|
93
93
|
→ Delete `.agentful/state.json` and run `/agentful-start` to reset. Completion progress is preserved.
|
|
94
94
|
|
|
95
95
|
**"Tech stack not detected correctly"**
|
|
96
|
-
→ Add explicit tech stack section to
|
|
96
|
+
→ Add explicit tech stack section to `.claude/product/index.md` or check `.agentful/architecture.json` for what was detected.
|
|
97
97
|
|
|
98
|
-
**"How do I
|
|
99
|
-
→
|
|
98
|
+
**"How do I expand to hierarchical product structure?"**
|
|
99
|
+
→ Create `.claude/product/domains/` directories and organize features by domain. Auto-detected.
|
|
100
100
|
|
|
101
101
|
**"Agent generated wrong type of code"**
|
|
102
102
|
→ Check that the right specialized agent was generated. Run `/agents` to list all agents.
|
package/version.json
CHANGED