farmwork 1.0.1 → 1.0.2
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 +24 -26
- package/package.json +2 -2
- package/src/init.js +263 -229
package/README.md
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
<img src="/init.png" alt="Farmwork - Developer Methodology" width="500" />
|
|
2
2
|
|
|
3
|
-
# FARMWORK
|
|
4
|
-
|
|
5
3
|
> A workflow framework for Claude Code by Wynter Jones
|
|
6
4
|
|
|
7
|
-
...because building software should feel like tending a well-organized farm.
|
|
8
|
-
|
|
9
5
|
## Quick Start
|
|
10
6
|
|
|
11
7
|
```bash
|
|
@@ -34,20 +30,19 @@ npx farmwork init
|
|
|
34
30
|
1. **FARMHOUSE.md** - Central command for tracking framework metrics
|
|
35
31
|
2. **Phrase Commands** - Natural language triggers for workflows
|
|
36
32
|
3. **Agents** - Specialized AI subagents for specific tasks
|
|
37
|
-
4. **
|
|
38
|
-
5. **
|
|
39
|
-
6. **
|
|
33
|
+
4. **Autonomously Issue Tracking** - Using beads (`bd`) for full visibility
|
|
34
|
+
5. **Living Audits** - Documents that track ongoing concerns
|
|
35
|
+
6. **Plan & Implement** - You describe the outcome, the rest is handled, tracked and audited
|
|
40
36
|
|
|
41
37
|
### Phrase Commands
|
|
42
38
|
|
|
43
39
|
**Farmwork Phrases** (Development Workflow):
|
|
44
40
|
| Phrase | Action |
|
|
45
41
|
|--------|--------|
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `go to market` | i18n translation check |
|
|
49
|
-
| `
|
|
50
|
-
| `open the farm` | Full audit cycle, then ask to proceed |
|
|
42
|
+
| `open the farm` | Audit systems, update FARMHOUSE.md metrics |
|
|
43
|
+
| `count the herd` | Full inspection + dry run (code review, performance, security, quality, accessibility) |
|
|
44
|
+
| `go to market` | i18n translation check + accessibility audit |
|
|
45
|
+
| `close the farm` | Full push workflow (lint, test, build, commit, push) |
|
|
51
46
|
|
|
52
47
|
**Plan Phrases**:
|
|
53
48
|
| Phrase | Action |
|
|
@@ -59,12 +54,11 @@ npx farmwork init
|
|
|
59
54
|
|
|
60
55
|
| Command | Description |
|
|
61
56
|
|---------|-------------|
|
|
62
|
-
| `/push` |
|
|
63
|
-
| `/open-the-farm` | Full audit cycle with summary report |
|
|
57
|
+
| `/push` | Clean, stage, lint, test, build, commit, push, update metrics (11 steps) |
|
|
64
58
|
|
|
65
59
|
### Agents
|
|
66
60
|
|
|
67
|
-
|
|
61
|
+
10 specialized agents included:
|
|
68
62
|
|
|
69
63
|
| Agent | Purpose |
|
|
70
64
|
|-------|---------|
|
|
@@ -73,6 +67,7 @@ npx farmwork init
|
|
|
73
67
|
| `security-auditor` | OWASP vulnerability scanning |
|
|
74
68
|
| `performance-auditor` | Memory leaks, re-renders, anti-patterns |
|
|
75
69
|
| `code-smell-auditor` | DRY violations, complexity, naming |
|
|
70
|
+
| `accessibility-auditor` | WCAG 2.1 compliance, alt text, contrast |
|
|
76
71
|
| `unused-code-cleaner` | Detect and remove dead code |
|
|
77
72
|
| `code-cleaner` | Remove comments and console.logs |
|
|
78
73
|
| `i18n-locale-translator` | Translate UI text to locales |
|
|
@@ -80,11 +75,13 @@ npx farmwork init
|
|
|
80
75
|
|
|
81
76
|
### Recommended Workflow
|
|
82
77
|
|
|
83
|
-
1. **Start Session**: Run `
|
|
78
|
+
1. **Start Session**: Run `open the farm` to audit current state
|
|
84
79
|
2. **Plan Work**: Use `make a plan for...` for new features
|
|
85
80
|
3. **Implement**: Use `let's implement...` to execute with tracking
|
|
86
|
-
4. **Quality Check**: Run `
|
|
87
|
-
5. **Ship**: Run `
|
|
81
|
+
4. **Quality Check**: Run `count the herd` for full audit + dry run
|
|
82
|
+
5. **Ship**: Run `close the farm` or `/push` to push changes
|
|
83
|
+
|
|
84
|
+
You can `go to market` when you have a production-ready app with international users.
|
|
88
85
|
|
|
89
86
|
## Directory Structure
|
|
90
87
|
|
|
@@ -92,23 +89,24 @@ npx farmwork init
|
|
|
92
89
|
your-project/
|
|
93
90
|
├── CLAUDE.md # Main instructions & phrase commands
|
|
94
91
|
├── .claude/ # Claude Code configuration
|
|
95
|
-
│ ├── agents/ #
|
|
92
|
+
│ ├── agents/ # 10 specialized subagents
|
|
96
93
|
│ │ ├── the-farmer.md
|
|
97
94
|
│ │ ├── code-reviewer.md
|
|
98
95
|
│ │ ├── security-auditor.md
|
|
99
96
|
│ │ ├── performance-auditor.md
|
|
100
97
|
│ │ ├── code-smell-auditor.md
|
|
98
|
+
│ │ ├── accessibility-auditor.md
|
|
101
99
|
│ │ ├── unused-code-cleaner.md
|
|
102
100
|
│ │ ├── code-cleaner.md
|
|
103
101
|
│ │ ├── i18n-locale-translator.md
|
|
104
102
|
│ │ └── storybook-maintainer.md
|
|
105
103
|
│ └── commands/ # User-invocable skills
|
|
106
|
-
│
|
|
107
|
-
│ └── open-the-farm.md
|
|
104
|
+
│ └── push.md
|
|
108
105
|
├── _AUDIT/ # Living audit documents
|
|
109
106
|
│ ├── FARMHOUSE.md # Framework command center
|
|
110
107
|
│ ├── SECURITY.md # Security posture
|
|
111
108
|
│ ├── PERFORMANCE.md # Performance metrics
|
|
109
|
+
│ ├── ACCESSIBILITY.md # WCAG 2.1 compliance
|
|
112
110
|
│ ├── CODE_QUALITY.md # Code quality tracking
|
|
113
111
|
│ └── TESTS.md # Test coverage
|
|
114
112
|
├── _PLANS/ # Implementation plans
|
|
@@ -142,13 +140,13 @@ If you enable Storybook (for React/Vue projects), the wizard will also ask for:
|
|
|
142
140
|
**Creates:**
|
|
143
141
|
- `CLAUDE.md` - Main instructions and phrase commands
|
|
144
142
|
- `.claude/` - Claude Code configuration directory
|
|
145
|
-
- `
|
|
146
|
-
- `
|
|
147
|
-
- `commands/` - 2 user-invocable skills
|
|
143
|
+
- `agents/` - 10 specialized subagents
|
|
144
|
+
- `commands/` - 1 user-invocable skill (/push)
|
|
148
145
|
- `_AUDIT/` - Living audit documents
|
|
149
146
|
- `FARMHOUSE.md` - Framework command center
|
|
150
147
|
- `SECURITY.md` - Security posture tracking
|
|
151
148
|
- `PERFORMANCE.md` - Performance metrics
|
|
149
|
+
- `ACCESSIBILITY.md` - WCAG 2.1 compliance
|
|
152
150
|
- `CODE_QUALITY.md` - Code quality tracking
|
|
153
151
|
- `TESTS.md` - Test coverage tracking
|
|
154
152
|
- `_PLANS/` - Implementation plans directory
|
|
@@ -204,5 +202,5 @@ MIT
|
|
|
204
202
|
|
|
205
203
|
## Links
|
|
206
204
|
|
|
207
|
-
- [Farmwork
|
|
208
|
-
- [
|
|
205
|
+
- [Farmwork Website](https://farmwork.dev)
|
|
206
|
+
- [Wynter Jones](https://wynter.ai)
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "farmwork",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Farmwork -
|
|
5
|
+
"description": "Farmwork - A workflow framework for Claude Code by Wynter Jones",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"farmwork": "./bin/farmwork.js"
|
package/src/init.js
CHANGED
|
@@ -126,7 +126,8 @@ export async function init(options) {
|
|
|
126
126
|
const farmworkConfig = path.join(cwd, ".farmwork.json");
|
|
127
127
|
const claudeMd = path.join(cwd, "CLAUDE.md");
|
|
128
128
|
|
|
129
|
-
const isAlreadyInstalled =
|
|
129
|
+
const isAlreadyInstalled =
|
|
130
|
+
fs.existsSync(claudeDir) &&
|
|
130
131
|
(fs.existsSync(farmworkConfig) || fs.existsSync(claudeMd));
|
|
131
132
|
|
|
132
133
|
if (isAlreadyInstalled && !options.force) {
|
|
@@ -146,12 +147,15 @@ export async function init(options) {
|
|
|
146
147
|
name: "continueInit",
|
|
147
148
|
message: "What would you like to do?",
|
|
148
149
|
choices: [
|
|
149
|
-
{
|
|
150
|
+
{
|
|
151
|
+
name: "🐴 Re-initialize (will backup existing files)",
|
|
152
|
+
value: "reinit",
|
|
153
|
+
},
|
|
150
154
|
{ name: "🐮 Run doctor instead (check health)", value: "doctor" },
|
|
151
155
|
{ name: "🌾 Run status instead (view metrics)", value: "status" },
|
|
152
|
-
{ name: "🐔 Exit", value: "exit" }
|
|
153
|
-
]
|
|
154
|
-
}
|
|
156
|
+
{ name: "🐔 Exit", value: "exit" },
|
|
157
|
+
],
|
|
158
|
+
},
|
|
155
159
|
]);
|
|
156
160
|
|
|
157
161
|
if (continueInit === "exit") {
|
|
@@ -179,7 +183,9 @@ export async function init(options) {
|
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
farmTerm.header("FARMWORK INITIALIZATION", "primary");
|
|
182
|
-
farmTerm.info(
|
|
186
|
+
farmTerm.info(
|
|
187
|
+
"Let's set up your farm! Answer a few questions to get started.\n",
|
|
188
|
+
);
|
|
183
189
|
|
|
184
190
|
const answers = await inquirer.prompt(QUESTIONS);
|
|
185
191
|
|
|
@@ -187,8 +193,12 @@ export async function init(options) {
|
|
|
187
193
|
if (answers.includeStorybook) {
|
|
188
194
|
farmTerm.nl();
|
|
189
195
|
farmTerm.section("Storybook Deployment", "🐄");
|
|
190
|
-
farmTerm.gray(
|
|
191
|
-
|
|
196
|
+
farmTerm.gray(
|
|
197
|
+
" We recommend deploying Storybook to Netlify with password protection.\n",
|
|
198
|
+
);
|
|
199
|
+
farmTerm.gray(
|
|
200
|
+
" This keeps your component docs private but accessible to your team.\n\n",
|
|
201
|
+
);
|
|
192
202
|
|
|
193
203
|
const storybookAnswers = await inquirer.prompt(STORYBOOK_QUESTIONS);
|
|
194
204
|
Object.assign(answers, storybookAnswers);
|
|
@@ -203,12 +213,39 @@ export async function init(options) {
|
|
|
203
213
|
// Check for existing files
|
|
204
214
|
const existingFiles = [];
|
|
205
215
|
const filesToCheck = [
|
|
206
|
-
{
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
{
|
|
216
|
+
{
|
|
217
|
+
path: path.join(cwd, "CLAUDE.md"),
|
|
218
|
+
name: "CLAUDE.md",
|
|
219
|
+
backup: "OLD_CLAUDE.md",
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
path: path.join(cwd, "justfile"),
|
|
223
|
+
name: "justfile",
|
|
224
|
+
backup: "OLD_justfile",
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
path: path.join(cwd, ".farmwork.json"),
|
|
228
|
+
name: ".farmwork.json",
|
|
229
|
+
backup: null,
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
path: path.join(cwd, ".claude", "commands"),
|
|
233
|
+
name: ".claude/commands/",
|
|
234
|
+
backup: null,
|
|
235
|
+
isDir: true,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
path: path.join(cwd, ".claude", "agents"),
|
|
239
|
+
name: ".claude/agents/",
|
|
240
|
+
backup: null,
|
|
241
|
+
isDir: true,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
path: path.join(cwd, "_AUDIT"),
|
|
245
|
+
name: "_AUDIT/",
|
|
246
|
+
backup: null,
|
|
247
|
+
isDir: true,
|
|
248
|
+
},
|
|
212
249
|
];
|
|
213
250
|
|
|
214
251
|
for (const file of filesToCheck) {
|
|
@@ -244,7 +281,10 @@ export async function init(options) {
|
|
|
244
281
|
name: "overwriteChoice",
|
|
245
282
|
message: "How would you like to proceed?",
|
|
246
283
|
choices: [
|
|
247
|
-
{
|
|
284
|
+
{
|
|
285
|
+
name: "🌱 Continue (backup files, add to existing folders)",
|
|
286
|
+
value: "overwrite",
|
|
287
|
+
},
|
|
248
288
|
{ name: "🐔 Cancel installation", value: "cancel" },
|
|
249
289
|
],
|
|
250
290
|
},
|
|
@@ -279,20 +319,32 @@ export async function init(options) {
|
|
|
279
319
|
try {
|
|
280
320
|
// Create folder structure with animations
|
|
281
321
|
const steps = [
|
|
282
|
-
{
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
322
|
+
{
|
|
323
|
+
name: "Creating directories",
|
|
324
|
+
fn: async () => {
|
|
325
|
+
await fs.ensureDir(path.join(cwd, "_AUDIT"));
|
|
326
|
+
await fs.ensureDir(path.join(cwd, "_PLANS"));
|
|
327
|
+
await fs.ensureDir(path.join(cwd, ".claude", "commands"));
|
|
328
|
+
await fs.ensureDir(path.join(cwd, ".claude", "agents"));
|
|
329
|
+
},
|
|
330
|
+
},
|
|
288
331
|
{ name: "Planting CLAUDE.md", fn: () => createClaudeMd(cwd, answers) },
|
|
289
|
-
{
|
|
290
|
-
|
|
332
|
+
{
|
|
333
|
+
name: "Building FARMHOUSE.md",
|
|
334
|
+
fn: () => createFarmhouseMd(cwd, answers),
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
name: "Creating audit documents",
|
|
338
|
+
fn: () => createAuditDocs(cwd, answers),
|
|
339
|
+
},
|
|
291
340
|
{ name: "Laying out justfile", fn: () => createJustfile(cwd, answers) },
|
|
292
341
|
{ name: "Training agents", fn: () => createAgents(cwd, answers) },
|
|
293
342
|
{ name: "Setting up commands", fn: () => createCommands(cwd, answers) },
|
|
294
343
|
{ name: "Configuring settings", fn: () => createSettings(cwd, answers) },
|
|
295
|
-
{
|
|
344
|
+
{
|
|
345
|
+
name: "Writing .farmwork.json",
|
|
346
|
+
fn: () => createProduceConfig(cwd, answers),
|
|
347
|
+
},
|
|
296
348
|
];
|
|
297
349
|
|
|
298
350
|
for (const step of steps) {
|
|
@@ -376,15 +428,18 @@ export async function init(options) {
|
|
|
376
428
|
|
|
377
429
|
// Show created structure
|
|
378
430
|
farmTerm.section("Created Structure", emojis.corn);
|
|
379
|
-
await farmTerm.planting(
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
431
|
+
await farmTerm.planting(
|
|
432
|
+
[
|
|
433
|
+
"_AUDIT/",
|
|
434
|
+
"_PLANS/",
|
|
435
|
+
".claude/commands/",
|
|
436
|
+
".claude/agents/",
|
|
437
|
+
"CLAUDE.md",
|
|
438
|
+
"justfile",
|
|
439
|
+
".farmwork.json",
|
|
440
|
+
],
|
|
441
|
+
"Files planted",
|
|
442
|
+
);
|
|
388
443
|
|
|
389
444
|
// Next steps
|
|
390
445
|
farmTerm.section("Next Steps", emojis.carrot);
|
|
@@ -393,7 +448,7 @@ export async function init(options) {
|
|
|
393
448
|
farmTerm.yellow("just --list");
|
|
394
449
|
farmTerm.gray(" → See available commands\n");
|
|
395
450
|
farmTerm.white(" 2. ");
|
|
396
|
-
farmTerm.yellow('"
|
|
451
|
+
farmTerm.yellow('"open the farm"');
|
|
397
452
|
farmTerm.gray(" → Audit your setup\n");
|
|
398
453
|
farmTerm.white(" 3. ");
|
|
399
454
|
farmTerm.yellow('"make a plan for <feature>"');
|
|
@@ -404,35 +459,44 @@ export async function init(options) {
|
|
|
404
459
|
farmTerm.section("Get Claude Comfortable", emojis.wheat);
|
|
405
460
|
farmTerm.gray(" Copy and paste this prompt to Claude Code:\n\n");
|
|
406
461
|
|
|
407
|
-
farmTerm.box(
|
|
408
|
-
"
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
462
|
+
farmTerm.box(
|
|
463
|
+
"Prompt for Claude",
|
|
464
|
+
[
|
|
465
|
+
"Hey Claude, I am using the Farmwork framework,",
|
|
466
|
+
"please go through the justfile and create",
|
|
467
|
+
"project-specific commands, and go through my",
|
|
468
|
+
"app and suggest project-specific subagents",
|
|
469
|
+
"that would work well.",
|
|
470
|
+
],
|
|
471
|
+
"secondary",
|
|
472
|
+
);
|
|
414
473
|
|
|
415
474
|
// Show merge prompt if we backed up CLAUDE.md
|
|
416
475
|
if (answers._didBackupClaudeMd) {
|
|
417
476
|
farmTerm.nl();
|
|
418
477
|
farmTerm.section("Merge Your Old Instructions", "🥬");
|
|
419
|
-
farmTerm.gray(
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
"
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
478
|
+
farmTerm.gray(
|
|
479
|
+
" Your old CLAUDE.md was backed up. Use this prompt to merge:\n\n",
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
farmTerm.box(
|
|
483
|
+
"Merge Prompt",
|
|
484
|
+
[
|
|
485
|
+
"Hey Claude, look at my CLAUDE.md file and",
|
|
486
|
+
"merge the project-specific instructions from",
|
|
487
|
+
"OLD_CLAUDE.md into it, so I have one file",
|
|
488
|
+
"with all the Farmwork instructions plus my",
|
|
489
|
+
"original project setup. Then delete the OLD",
|
|
490
|
+
"files when done.",
|
|
491
|
+
],
|
|
492
|
+
"accent",
|
|
493
|
+
);
|
|
429
494
|
}
|
|
430
495
|
|
|
431
496
|
// Final tractor drive
|
|
432
497
|
farmTerm.nl();
|
|
433
498
|
await farmTerm.tractorAnimation("Your farm is ready!", 1500);
|
|
434
499
|
farmTerm.nl();
|
|
435
|
-
|
|
436
500
|
} catch (error) {
|
|
437
501
|
farmTerm.error("Failed to initialize Farmwork");
|
|
438
502
|
console.error(error);
|
|
@@ -476,11 +540,10 @@ Run these in order for a complete development cycle:
|
|
|
476
540
|
|
|
477
541
|
| Phrase | Action |
|
|
478
542
|
|--------|--------|
|
|
479
|
-
| **
|
|
480
|
-
| **
|
|
481
|
-
| **go to market** | i18n scan +
|
|
482
|
-
| **
|
|
483
|
-
| **open the farm** | Full audit cycle (everything except push), then ask to proceed |
|
|
543
|
+
| **open the farm** | Audit systems, update \`_AUDIT/FARMHOUSE.md\` with current metrics |
|
|
544
|
+
| **count the herd** | Full inspection + dry run: code review, cleanup, performance, security, code quality, accessibility |
|
|
545
|
+
| **go to market** | i18n scan + accessibility audit for missing translations and a11y issues |
|
|
546
|
+
| **close the farm** | Execute \`/push\` (lint, test, build, commit, push) |
|
|
484
547
|
|
|
485
548
|
---
|
|
486
549
|
|
|
@@ -495,28 +558,30 @@ Run these in order for a complete development cycle:
|
|
|
495
558
|
|
|
496
559
|
### Farmwork Phrase Details
|
|
497
560
|
|
|
498
|
-
**
|
|
561
|
+
**open the farm**
|
|
499
562
|
1. Launch \`the-farmer\` agent to audit all systems
|
|
500
563
|
2. Run \`bd list --status closed | wc -l\` to get total completed issues
|
|
501
564
|
3. Updates \`_AUDIT/FARMHOUSE.md\` with current metrics
|
|
502
565
|
|
|
503
|
-
**
|
|
504
|
-
Runs all inspection agents in parallel
|
|
566
|
+
**count the herd** (Full Audit Cycle)
|
|
567
|
+
Runs all inspection agents in parallel, then dry run quality gates. No push.
|
|
568
|
+
|
|
505
569
|
1. **Code Review & Cleanup** - \`code-reviewer\` + \`unused-code-cleaner\`
|
|
506
|
-
2. **Performance Audit** -
|
|
570
|
+
2. **Performance Audit** - \`performance-auditor\`, updates \`_AUDIT/PERFORMANCE.md\`
|
|
507
571
|
3. **Security Audit** - \`security-auditor\` for OWASP Top 10, updates \`_AUDIT/SECURITY.md\`
|
|
508
572
|
4. **Code Quality** - \`code-smell-auditor\` for DRY violations, updates \`_AUDIT/CODE_QUALITY.md\`
|
|
509
|
-
5. **
|
|
573
|
+
5. **Accessibility** - \`accessibility-auditor\` for WCAG 2.1, updates \`_AUDIT/ACCESSIBILITY.md\`
|
|
574
|
+
6. **Dry Run** - lint, tests, build (but NOT commit/push)
|
|
575
|
+
7. **Summary Report** - Consolidate findings, ask user next steps
|
|
510
576
|
|
|
511
|
-
**
|
|
512
|
-
|
|
577
|
+
**go to market**
|
|
578
|
+
1. Scan for hardcoded text not using i18n
|
|
579
|
+
2. Launch \`i18n-locale-translator\` agent
|
|
580
|
+
3. Launch \`accessibility-auditor\` for WCAG 2.1 compliance
|
|
581
|
+
4. Updates \`_AUDIT/ACCESSIBILITY.md\`
|
|
513
582
|
|
|
514
|
-
**
|
|
515
|
-
|
|
516
|
-
2. **Inspect the Farm** - Full inspection (code review, cleanup, performance, security, code quality)
|
|
517
|
-
3. **Dry Run Harvest** - Run lint, tests, build (but NOT commit/push)
|
|
518
|
-
4. **Summary Report** - Present consolidated findings
|
|
519
|
-
5. **Ask User** - Ready to harvest (push)?
|
|
583
|
+
**close the farm**
|
|
584
|
+
- Invoke the \`push\` skill immediately
|
|
520
585
|
|
|
521
586
|
---
|
|
522
587
|
|
|
@@ -573,7 +638,7 @@ async function createFarmhouseMd(cwd, answers) {
|
|
|
573
638
|
const content = `# Farmwork Farmhouse
|
|
574
639
|
|
|
575
640
|
> Central command for the Farmwork agentic harness.
|
|
576
|
-
> Updated automatically by \`the-farmer\` agent during \`/push\` or via "
|
|
641
|
+
> Updated automatically by \`the-farmer\` agent during \`/push\` or via "open the farm" phrase.
|
|
577
642
|
|
|
578
643
|
**Last Updated:** ${today}
|
|
579
644
|
**Score:** 5.0/10
|
|
@@ -585,8 +650,8 @@ async function createFarmhouseMd(cwd, answers) {
|
|
|
585
650
|
|
|
586
651
|
| Metric | Count |
|
|
587
652
|
|--------|-------|
|
|
588
|
-
| Commands |
|
|
589
|
-
| Agents |
|
|
653
|
+
| Commands | 1 |
|
|
654
|
+
| Agents | 10 |
|
|
590
655
|
| Justfile Recipes | 10 |
|
|
591
656
|
| Unit Tests | 0 |
|
|
592
657
|
| E2E Tests | 0 |
|
|
@@ -604,8 +669,7 @@ All Claude Code commands and agents are documented, phrase triggers are tested a
|
|
|
604
669
|
|
|
605
670
|
| Command | Description |
|
|
606
671
|
|---------|-------------|
|
|
607
|
-
| \`/push\` | Clean, lint, test, build, commit, push |
|
|
608
|
-
| \`/open-the-farm\` | Full audit cycle, then ask user next steps |
|
|
672
|
+
| \`/push\` | Clean, lint, test, build, commit, push, update metrics |
|
|
609
673
|
|
|
610
674
|
---
|
|
611
675
|
|
|
@@ -618,6 +682,7 @@ All Claude Code commands and agents are documented, phrase triggers are tested a
|
|
|
618
682
|
| \`security-auditor\` | OWASP vulnerability scanning |
|
|
619
683
|
| \`performance-auditor\` | Performance anti-patterns |
|
|
620
684
|
| \`code-smell-auditor\` | DRY violations, complexity, naming |
|
|
685
|
+
| \`accessibility-auditor\` | WCAG 2.1 compliance, alt text, contrast |
|
|
621
686
|
| \`unused-code-cleaner\` | Detect and remove dead code |
|
|
622
687
|
| \`code-cleaner\` | Remove comments and console.logs |
|
|
623
688
|
| \`i18n-locale-translator\` | Translate UI text to locales |
|
|
@@ -631,11 +696,10 @@ All Claude Code commands and agents are documented, phrase triggers are tested a
|
|
|
631
696
|
|
|
632
697
|
| Phrase | Action |
|
|
633
698
|
|--------|--------|
|
|
634
|
-
| \`
|
|
635
|
-
| \`
|
|
636
|
-
| \`go to market\` | i18n scan +
|
|
637
|
-
| \`
|
|
638
|
-
| \`open the farm\` | Full audit cycle |
|
|
699
|
+
| \`open the farm\` | Audit systems, update FARMHOUSE.md |
|
|
700
|
+
| \`count the herd\` | Full inspection + dry run (no push) |
|
|
701
|
+
| \`go to market\` | i18n scan + accessibility audit |
|
|
702
|
+
| \`close the farm\` | Execute /push |
|
|
639
703
|
|
|
640
704
|
### Plan Phrases
|
|
641
705
|
|
|
@@ -679,10 +743,31 @@ async function createAuditDocs(cwd, answers) {
|
|
|
679
743
|
const today = new Date().toISOString().split("T")[0];
|
|
680
744
|
|
|
681
745
|
const audits = [
|
|
682
|
-
{
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
746
|
+
{
|
|
747
|
+
name: "SECURITY.md",
|
|
748
|
+
title: "Security Audit",
|
|
749
|
+
description: "Security posture and vulnerability tracking",
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
name: "PERFORMANCE.md",
|
|
753
|
+
title: "Performance Audit",
|
|
754
|
+
description: "Performance metrics and optimization tracking",
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
name: "ACCESSIBILITY.md",
|
|
758
|
+
title: "Accessibility Audit",
|
|
759
|
+
description: "WCAG 2.1 Level AA compliance tracking",
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
name: "CODE_QUALITY.md",
|
|
763
|
+
title: "Code Quality Audit",
|
|
764
|
+
description: "Code quality and standards tracking",
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
name: "TESTS.md",
|
|
768
|
+
title: "Test Coverage Audit",
|
|
769
|
+
description: "Test coverage and gaps tracking",
|
|
770
|
+
},
|
|
686
771
|
];
|
|
687
772
|
|
|
688
773
|
for (const audit of audits) {
|
|
@@ -919,6 +1004,26 @@ Scans for code quality issues:
|
|
|
919
1004
|
|
|
920
1005
|
Reports code health as GOOD / FAIR / NEEDS ATTENTION.
|
|
921
1006
|
Updates \`_AUDIT/CODE_QUALITY.md\` with results.
|
|
1007
|
+
`,
|
|
1008
|
+
"accessibility-auditor.md": `---
|
|
1009
|
+
name: accessibility-auditor
|
|
1010
|
+
description: WCAG 2.1 accessibility auditing for React/Next.js applications
|
|
1011
|
+
tools: Read, Grep, Glob, Edit
|
|
1012
|
+
model: haiku
|
|
1013
|
+
---
|
|
1014
|
+
|
|
1015
|
+
# Accessibility Auditor Agent
|
|
1016
|
+
|
|
1017
|
+
Scans for WCAG 2.1 Level AA compliance issues:
|
|
1018
|
+
- Missing or inadequate alt text on images
|
|
1019
|
+
- Color contrast issues
|
|
1020
|
+
- Keyboard navigation problems
|
|
1021
|
+
- Missing ARIA labels and roles
|
|
1022
|
+
- Form accessibility (labels, error messages)
|
|
1023
|
+
- Focus management issues
|
|
1024
|
+
|
|
1025
|
+
Reports findings by severity (CRITICAL, HIGH, MEDIUM, LOW).
|
|
1026
|
+
Updates \`_AUDIT/ACCESSIBILITY.md\` with results.
|
|
922
1027
|
`,
|
|
923
1028
|
"unused-code-cleaner.md": `---
|
|
924
1029
|
name: unused-code-cleaner
|
|
@@ -1006,201 +1111,130 @@ async function createCommands(cwd, answers) {
|
|
|
1006
1111
|
const storybookSteps = answers.includeStorybook
|
|
1007
1112
|
? `
|
|
1008
1113
|
|
|
1009
|
-
### Step
|
|
1114
|
+
### Step 9: Deploy Storybook to Netlify
|
|
1010
1115
|
|
|
1011
|
-
|
|
1012
|
-
\`\`\`bash
|
|
1013
|
-
${pm} run build-storybook
|
|
1014
|
-
\`\`\`
|
|
1015
|
-
|
|
1016
|
-
Deploy to Netlify (requires NETLIFY_AUTH_TOKEN and NETLIFY_STORYBOOK_SITE_ID in .claude/settings.local.json):
|
|
1116
|
+
Deploy the Storybook documentation site:
|
|
1017
1117
|
\`\`\`bash
|
|
1018
1118
|
npx netlify deploy --dir=storybook-static --site=$NETLIFY_STORYBOOK_SITE_ID --prod
|
|
1019
1119
|
\`\`\`
|
|
1020
1120
|
|
|
1121
|
+
Note: Requires \`NETLIFY_AUTH_TOKEN\` and \`NETLIFY_STORYBOOK_SITE_ID\` in \`.claude/settings.local.json\`.
|
|
1122
|
+
If not configured, skip this step and inform the user to add the env vars.
|
|
1123
|
+
|
|
1021
1124
|
Storybook URL: https://${answers.storybookUrl || "storybook.example.com"}
|
|
1022
1125
|
${answers.passwordProtect ? "**Note:** This Storybook is password protected." : ""}
|
|
1023
1126
|
`
|
|
1024
1127
|
: "";
|
|
1025
1128
|
|
|
1026
|
-
const finalStep = answers.includeStorybook
|
|
1027
|
-
? "### Step 7: Report Success"
|
|
1028
|
-
: "### Step 6: Report Success";
|
|
1029
|
-
const reportContent = answers.includeStorybook
|
|
1030
|
-
? `
|
|
1031
|
-
Show summary:
|
|
1032
|
-
- Files changed
|
|
1033
|
-
- Commit hash
|
|
1034
|
-
- Push status
|
|
1035
|
-
- Storybook deploy status
|
|
1036
|
-
`
|
|
1037
|
-
: `
|
|
1038
|
-
Show summary:
|
|
1039
|
-
- Files changed
|
|
1040
|
-
- Commit hash
|
|
1041
|
-
- Push status
|
|
1042
|
-
`;
|
|
1043
|
-
|
|
1044
1129
|
const pushCommand = `---
|
|
1045
|
-
description: Clean, lint, test, build, commit,
|
|
1046
|
-
|
|
1130
|
+
description: Clean, stage, lint, test, build, commit, push, and update metrics
|
|
1131
|
+
argument-hint: [optional: commit message override]
|
|
1132
|
+
allowed-tools: Bash(find:*), Bash(git:*), Bash(${pm}:*), Bash(npx:*)${answers.includeStorybook ? ", Bash(npx netlify:*)" : ""}, Task
|
|
1047
1133
|
---
|
|
1048
1134
|
|
|
1049
1135
|
# Push Command
|
|
1050
1136
|
|
|
1051
|
-
Run quality gates, commit changes, and push to remote
|
|
1137
|
+
Run code cleanup, all quality gates, commit changes, and push to remote.
|
|
1052
1138
|
|
|
1053
1139
|
## Workflow
|
|
1054
1140
|
|
|
1055
1141
|
Execute these steps in order. **Stop immediately if any step fails.**
|
|
1056
1142
|
|
|
1057
|
-
### Step 1:
|
|
1143
|
+
### Step 1: Clean Up System Files
|
|
1144
|
+
Remove any .DS_Store files from the repository:
|
|
1058
1145
|
\`\`\`bash
|
|
1059
|
-
|
|
1146
|
+
find . -name '.DS_Store' -type f -delete
|
|
1060
1147
|
\`\`\`
|
|
1061
1148
|
|
|
1062
|
-
### Step 2:
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
1. **Lint**: \`${answers.lintCommand}\`
|
|
1068
|
-
2. **Tests**: \`${answers.testCommand}\`
|
|
1069
|
-
3. **Build**: \`${answers.buildCommand}\`
|
|
1070
|
-
|
|
1071
|
-
### Step 4: Generate Commit Message
|
|
1072
|
-
|
|
1073
|
-
Analyze staged changes and generate a concise commit message:
|
|
1074
|
-
- Starts with a type (feat, fix, refactor, docs, style, test, chore)
|
|
1075
|
-
- Summarizes the "why" not the "what"
|
|
1076
|
-
- 1-2 sentences maximum
|
|
1077
|
-
|
|
1078
|
-
### Step 5: Commit and Push
|
|
1079
|
-
|
|
1080
|
-
Create the commit with footer:
|
|
1081
|
-
|
|
1082
|
-
\`\`\`
|
|
1083
|
-
🌽 Generated with [Claude Code](https://claude.com/claude-code)
|
|
1084
|
-
|
|
1085
|
-
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
1149
|
+
### Step 2: Sync Packages
|
|
1150
|
+
Clean and reinstall node_modules to ensure package-lock.json stays in sync:
|
|
1151
|
+
\`\`\`bash
|
|
1152
|
+
rm -rf node_modules && ${pm} install
|
|
1086
1153
|
\`\`\`
|
|
1154
|
+
This prevents \`${pm} ci\` failures in CI/CD due to lock file drift.
|
|
1087
1155
|
|
|
1088
|
-
|
|
1089
|
-
${storybookSteps}
|
|
1090
|
-
${finalStep}
|
|
1091
|
-
${reportContent}`;
|
|
1092
|
-
|
|
1093
|
-
await fs.writeFile(
|
|
1094
|
-
path.join(cwd, ".claude", "commands", "push.md"),
|
|
1095
|
-
pushCommand,
|
|
1096
|
-
);
|
|
1097
|
-
|
|
1098
|
-
// Create open-the-farm command
|
|
1099
|
-
const openTheFarmCommand = `---
|
|
1100
|
-
description: Full audit cycle - till, inspect, dry run harvest, then ask user next steps
|
|
1101
|
-
allowed-tools: Bash(${pm}:*), Bash(just:*), Task
|
|
1102
|
-
---
|
|
1103
|
-
|
|
1104
|
-
# Open the Farm Command
|
|
1105
|
-
|
|
1106
|
-
Complete development audit workflow. Runs all audits and quality checks without committing, then asks the user what to do next.
|
|
1107
|
-
|
|
1108
|
-
Trigger phrase: "open the farm"
|
|
1109
|
-
|
|
1110
|
-
## Workflow
|
|
1111
|
-
|
|
1112
|
-
Execute these steps in order. Track findings from each step for the final summary.
|
|
1113
|
-
|
|
1114
|
-
### Step 1: Till the Land
|
|
1156
|
+
If package-lock.json was modified, it will be staged in the next step.
|
|
1115
1157
|
|
|
1116
|
-
|
|
1158
|
+
### Step 3: Stage All Changes
|
|
1159
|
+
\`\`\`bash
|
|
1160
|
+
git add -A
|
|
1161
|
+
\`\`\`
|
|
1117
1162
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
- Test counts
|
|
1121
|
-
- Completed issues count
|
|
1163
|
+
### Step 4: Check for Changes
|
|
1164
|
+
Run \`git status\` to verify there are staged changes. If nothing to commit, inform the user and stop.
|
|
1122
1165
|
|
|
1123
|
-
|
|
1166
|
+
### Step 5: Clean Code
|
|
1124
1167
|
|
|
1125
|
-
|
|
1168
|
+
Run the code-cleaner agent on staged TypeScript files to remove comments and console.logs.
|
|
1126
1169
|
|
|
1127
|
-
|
|
1170
|
+
This removes:
|
|
1171
|
+
- Line comments (\`//\`) and block comments (\`/* */\`)
|
|
1172
|
+
- \`console.log\` statements
|
|
1128
1173
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
- \`
|
|
1132
|
-
- \`unused-code-cleaner\` to detect dead code, unused imports
|
|
1174
|
+
It preserves:
|
|
1175
|
+
- JSDoc comments (\`/** */\`)
|
|
1176
|
+
- \`console.error\`, \`console.warn\`, \`console.info\`
|
|
1133
1177
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1178
|
+
After cleaning, re-stage the modified files:
|
|
1179
|
+
\`\`\`bash
|
|
1180
|
+
git add -A
|
|
1181
|
+
\`\`\`
|
|
1136
1182
|
|
|
1137
|
-
|
|
1138
|
-
- Launch \`security-auditor\` agent for OWASP Top 10 vulnerabilities
|
|
1139
|
-
- Note findings by severity (CRITICAL, HIGH, MEDIUM, LOW)
|
|
1183
|
+
### Step 6: Run Quality Gates (in order)
|
|
1140
1184
|
|
|
1141
|
-
|
|
1142
|
-
- Launch \`code-smell-auditor\` agent for DRY violations, complexity, naming issues
|
|
1143
|
-
- Note code health rating (GOOD / FAIR / NEEDS ATTENTION)
|
|
1185
|
+
Run each check. If any fails, stop and report which check failed:
|
|
1144
1186
|
|
|
1145
|
-
|
|
1187
|
+
1. **Lint**: \`${answers.lintCommand}\`${answers.includeStorybook ? `\n2. **Storybook**: \`${pm} run build-storybook\`` : ""}
|
|
1188
|
+
${answers.includeStorybook ? "3" : "2"}. **Unit Tests**: \`${answers.testCommand}\`
|
|
1189
|
+
${answers.includeStorybook ? "4" : "3"}. **Build**: \`${answers.buildCommand}\`
|
|
1146
1190
|
|
|
1147
|
-
|
|
1191
|
+
### Step 7: Generate Commit Message
|
|
1148
1192
|
|
|
1149
|
-
|
|
1150
|
-
2. **Tests**: \`${answers.testCommand}\`
|
|
1151
|
-
3. **Build**: \`${answers.buildCommand}\`
|
|
1193
|
+
If \`$ARGUMENTS\` is provided, use it as the commit message.
|
|
1152
1194
|
|
|
1153
|
-
|
|
1195
|
+
Otherwise, analyze the staged changes:
|
|
1196
|
+
1. Run \`git diff --cached --stat\` to see changed files
|
|
1197
|
+
2. Run \`git diff --cached\` to see actual changes
|
|
1198
|
+
3. Run \`git log -5 --oneline\` to match the repository's commit style
|
|
1199
|
+
4. Generate a concise, descriptive commit message that:
|
|
1200
|
+
- Starts with a type (feat, fix, refactor, docs, style, test, chore)
|
|
1201
|
+
- Summarizes the "why" not the "what"
|
|
1202
|
+
- Is 1-2 sentences maximum
|
|
1154
1203
|
|
|
1155
|
-
### Step
|
|
1204
|
+
### Step 8: Commit and Push
|
|
1156
1205
|
|
|
1157
|
-
|
|
1206
|
+
Create the commit with the message, including the standard footer:
|
|
1158
1207
|
|
|
1159
1208
|
\`\`\`
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
### Harness Status
|
|
1163
|
-
- Farmhouse Score: X/10
|
|
1164
|
-
- Commands: X | Agents: X | Tests: X
|
|
1165
|
-
|
|
1166
|
-
### Code Quality
|
|
1167
|
-
- Security: X issues (Y critical, Z high)
|
|
1168
|
-
- Performance: X issues
|
|
1169
|
-
- Code Smells: [GOOD/FAIR/NEEDS ATTENTION]
|
|
1170
|
-
- Unused Code: X items flagged
|
|
1171
|
-
|
|
1172
|
-
### Quality Gates
|
|
1173
|
-
- Lint: ✅/❌
|
|
1174
|
-
- Tests: ✅/❌ (X passed, Y failed)
|
|
1175
|
-
- Build: ✅/❌
|
|
1176
|
-
|
|
1177
|
-
### Open Items
|
|
1178
|
-
[List top 3-5 issues that should be addressed]
|
|
1209
|
+
🌽 Generated with FARMWORK
|
|
1179
1210
|
\`\`\`
|
|
1180
1211
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1212
|
+
Then push to remote:
|
|
1213
|
+
\`\`\`bash
|
|
1214
|
+
git push
|
|
1215
|
+
\`\`\`
|
|
1216
|
+
${storybookSteps}
|
|
1217
|
+
### Step 10: Update Farmhouse Metrics
|
|
1184
1218
|
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
> - **review audits** - Show detailed findings from a specific audit
|
|
1190
|
-
> - **fix issues first** - Address the open items before pushing
|
|
1219
|
+
Run the-farmer agent to update \`_AUDIT/FARMHOUSE.md\` with current metrics:
|
|
1220
|
+
- Commands and agents inventory
|
|
1221
|
+
- Test counts (unit, e2e)
|
|
1222
|
+
- Completed issues count
|
|
1191
1223
|
|
|
1192
|
-
|
|
1224
|
+
This keeps the harness documentation in sync with the codebase.
|
|
1193
1225
|
|
|
1194
|
-
|
|
1226
|
+
### Step 11: Report Success
|
|
1195
1227
|
|
|
1196
|
-
|
|
1197
|
-
-
|
|
1198
|
-
-
|
|
1228
|
+
Show a summary:
|
|
1229
|
+
- Files changed
|
|
1230
|
+
- Commit hash
|
|
1231
|
+
- Push status${answers.includeStorybook ? "\n- Storybook deploy status (if deployed)" : ""}
|
|
1232
|
+
- Harness metrics updated
|
|
1199
1233
|
`;
|
|
1200
1234
|
|
|
1201
1235
|
await fs.writeFile(
|
|
1202
|
-
path.join(cwd, ".claude", "commands", "
|
|
1203
|
-
|
|
1236
|
+
path.join(cwd, ".claude", "commands", "push.md"),
|
|
1237
|
+
pushCommand,
|
|
1204
1238
|
);
|
|
1205
1239
|
}
|
|
1206
1240
|
|
|
@@ -1257,7 +1291,7 @@ async function createProduceConfig(cwd, answers) {
|
|
|
1257
1291
|
storybook: answers.includeStorybook || false,
|
|
1258
1292
|
i18n: answers.includeI18n || false,
|
|
1259
1293
|
},
|
|
1260
|
-
audits: ["FARMHOUSE", "SECURITY", "PERFORMANCE", "CODE_QUALITY", "TESTS"],
|
|
1294
|
+
audits: ["FARMHOUSE", "SECURITY", "PERFORMANCE", "ACCESSIBILITY", "CODE_QUALITY", "TESTS"],
|
|
1261
1295
|
};
|
|
1262
1296
|
|
|
1263
1297
|
if (answers.includeStorybook) {
|