farmwork 1.0.0 → 1.0.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 +116 -88
- package/bin/farmwork.js +0 -6
- package/package.json +8 -2
- package/src/doctor.js +57 -41
- package/src/index.js +0 -1
- package/src/init.js +429 -328
- package/src/status.js +108 -145
- package/src/terminal.js +649 -0
- package/src/add.js +0 -194
package/README.md
CHANGED
|
@@ -1,44 +1,132 @@
|
|
|
1
|
-
|
|
1
|
+
<img src="/init.png" alt="Farmwork - Developer Methodology" width="500" />
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# FARMWORK
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> A workflow framework for Claude Code by Wynter Jones
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
...because building software should feel like tending a well-organized farm.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npm install -g farmwork
|
|
11
13
|
```
|
|
12
14
|
|
|
15
|
+
```bash
|
|
16
|
+
cd your-project
|
|
17
|
+
farmwork init
|
|
18
|
+
farmwork doctor
|
|
19
|
+
farmwork status
|
|
20
|
+
```
|
|
21
|
+
|
|
13
22
|
Or run directly with npx:
|
|
14
23
|
|
|
15
24
|
```bash
|
|
16
25
|
npx farmwork init
|
|
17
26
|
```
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
----
|
|
20
29
|
|
|
21
|
-
|
|
22
|
-
# Initialize in your project
|
|
23
|
-
cd your-project
|
|
24
|
-
farmwork init
|
|
30
|
+
## The Farmwork Method
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
farmwork doctor
|
|
32
|
+
### Core Concepts
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
1. **FARMHOUSE.md** - Central command for tracking framework metrics
|
|
35
|
+
2. **Phrase Commands** - Natural language triggers for workflows
|
|
36
|
+
3. **Agents** - Specialized AI subagents for specific tasks
|
|
37
|
+
4. **Commands** - User-invocable skills (triggered with `/command`)
|
|
38
|
+
5. **Issue Tracking** - Using beads (`bd`) for full visibility
|
|
39
|
+
6. **Living Audits** - Documents that track ongoing concerns
|
|
40
|
+
|
|
41
|
+
### Phrase Commands
|
|
42
|
+
|
|
43
|
+
**Farmwork Phrases** (Development Workflow):
|
|
44
|
+
| Phrase | Action |
|
|
45
|
+
|--------|--------|
|
|
46
|
+
| `till the land` | Audit systems, update FARMHOUSE.md metrics |
|
|
47
|
+
| `inspect the farm` | Full inspection (code review, performance, security, quality) |
|
|
48
|
+
| `go to market` | i18n translation check |
|
|
49
|
+
| `harvest crops` | Full push workflow (lint, test, build, commit, push) |
|
|
50
|
+
| `open the farm` | Full audit cycle, then ask to proceed |
|
|
51
|
+
|
|
52
|
+
**Plan Phrases**:
|
|
53
|
+
| Phrase | Action |
|
|
54
|
+
|--------|--------|
|
|
55
|
+
| `make a plan for...` | Create implementation plan in `_PLANS/` |
|
|
56
|
+
| `let's implement...` | Execute plan with issue tracking |
|
|
57
|
+
|
|
58
|
+
### Slash Commands
|
|
59
|
+
|
|
60
|
+
| Command | Description |
|
|
61
|
+
|---------|-------------|
|
|
62
|
+
| `/push` | Stage, lint, test, build, commit, push |
|
|
63
|
+
| `/open-the-farm` | Full audit cycle with summary report |
|
|
64
|
+
|
|
65
|
+
### Agents
|
|
66
|
+
|
|
67
|
+
9 specialized agents included:
|
|
68
|
+
|
|
69
|
+
| Agent | Purpose |
|
|
70
|
+
|-------|---------|
|
|
71
|
+
| `the-farmer` | Audit and update FARMHOUSE.md metrics |
|
|
72
|
+
| `code-reviewer` | Quality & security code review |
|
|
73
|
+
| `security-auditor` | OWASP vulnerability scanning |
|
|
74
|
+
| `performance-auditor` | Memory leaks, re-renders, anti-patterns |
|
|
75
|
+
| `code-smell-auditor` | DRY violations, complexity, naming |
|
|
76
|
+
| `unused-code-cleaner` | Detect and remove dead code |
|
|
77
|
+
| `code-cleaner` | Remove comments and console.logs |
|
|
78
|
+
| `i18n-locale-translator` | Translate UI text to locales |
|
|
79
|
+
| `storybook-maintainer` | Create/update Storybook stories |
|
|
80
|
+
|
|
81
|
+
### Recommended Workflow
|
|
82
|
+
|
|
83
|
+
1. **Start Session**: Run `till the land` to audit current state
|
|
84
|
+
2. **Plan Work**: Use `make a plan for...` for new features
|
|
85
|
+
3. **Implement**: Use `let's implement...` to execute with tracking
|
|
86
|
+
4. **Quality Check**: Run `inspect the farm` or `/open-the-farm`
|
|
87
|
+
5. **Ship**: Run `harvest crops` or `/push` to push changes
|
|
88
|
+
|
|
89
|
+
## Directory Structure
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
your-project/
|
|
93
|
+
├── CLAUDE.md # Main instructions & phrase commands
|
|
94
|
+
├── .claude/ # Claude Code configuration
|
|
95
|
+
│ ├── agents/ # 9 specialized subagents
|
|
96
|
+
│ │ ├── the-farmer.md
|
|
97
|
+
│ │ ├── code-reviewer.md
|
|
98
|
+
│ │ ├── security-auditor.md
|
|
99
|
+
│ │ ├── performance-auditor.md
|
|
100
|
+
│ │ ├── code-smell-auditor.md
|
|
101
|
+
│ │ ├── unused-code-cleaner.md
|
|
102
|
+
│ │ ├── code-cleaner.md
|
|
103
|
+
│ │ ├── i18n-locale-translator.md
|
|
104
|
+
│ │ └── storybook-maintainer.md
|
|
105
|
+
│ └── commands/ # User-invocable skills
|
|
106
|
+
│ ├── push.md
|
|
107
|
+
│ └── open-the-farm.md
|
|
108
|
+
├── _AUDIT/ # Living audit documents
|
|
109
|
+
│ ├── FARMHOUSE.md # Framework command center
|
|
110
|
+
│ ├── SECURITY.md # Security posture
|
|
111
|
+
│ ├── PERFORMANCE.md # Performance metrics
|
|
112
|
+
│ ├── CODE_QUALITY.md # Code quality tracking
|
|
113
|
+
│ └── TESTS.md # Test coverage
|
|
114
|
+
├── _PLANS/ # Implementation plans
|
|
115
|
+
│ └── FEATURE_NAME.md
|
|
116
|
+
├── .beads/ # Issue tracking
|
|
117
|
+
└── justfile # Navigation commands
|
|
31
118
|
```
|
|
32
119
|
|
|
120
|
+
<img src="/logo.png" alt="Farmwork - Developer Methodology" width="300" />
|
|
121
|
+
|
|
33
122
|
## Commands
|
|
34
123
|
|
|
35
124
|
### `farmwork init`
|
|
36
125
|
|
|
37
|
-
|
|
126
|
+
Start setting up the new digital farm:
|
|
38
127
|
|
|
39
128
|
```bash
|
|
40
129
|
farmwork init # Interactive setup wizard
|
|
41
|
-
farmwork init -f # Force overwrite existing files
|
|
42
130
|
```
|
|
43
131
|
|
|
44
132
|
**Options:**
|
|
@@ -55,30 +143,21 @@ If you enable Storybook (for React/Vue projects), the wizard will also ask for:
|
|
|
55
143
|
- `CLAUDE.md` - Main instructions and phrase commands
|
|
56
144
|
- `.claude/` - Claude Code configuration directory
|
|
57
145
|
- `settings.json` - Project settings
|
|
58
|
-
- `agents/` -
|
|
59
|
-
- `commands/` -
|
|
146
|
+
- `agents/` - 9 specialized subagents
|
|
147
|
+
- `commands/` - 2 user-invocable skills
|
|
60
148
|
- `_AUDIT/` - Living audit documents
|
|
61
149
|
- `FARMHOUSE.md` - Framework command center
|
|
150
|
+
- `SECURITY.md` - Security posture tracking
|
|
151
|
+
- `PERFORMANCE.md` - Performance metrics
|
|
152
|
+
- `CODE_QUALITY.md` - Code quality tracking
|
|
153
|
+
- `TESTS.md` - Test coverage tracking
|
|
62
154
|
- `_PLANS/` - Implementation plans directory
|
|
63
155
|
- `justfile` - Navigation and task commands
|
|
64
156
|
|
|
65
|
-
### `farmwork add <type> <name>`
|
|
66
|
-
|
|
67
|
-
Add a new component to your Farmwork setup.
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
farmwork add agent code-reviewer # Add a new agent
|
|
71
|
-
farmwork add command deploy # Add a new command
|
|
72
|
-
farmwork add audit performance # Add a new audit document
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**Types:**
|
|
76
|
-
- `agent` - Creates `.claude/agents/<name>.md`
|
|
77
|
-
- `command` - Creates `.claude/commands/<name>.md`
|
|
78
|
-
- `audit` - Creates `_AUDIT/<NAME>.md`
|
|
79
|
-
|
|
80
157
|
### `farmwork status`
|
|
81
158
|
|
|
159
|
+
<img src="/status.png" alt="Farmwork Status" width="500" />
|
|
160
|
+
|
|
82
161
|
Display Farmwork status and metrics.
|
|
83
162
|
|
|
84
163
|
```bash
|
|
@@ -92,8 +171,12 @@ farmwork status
|
|
|
92
171
|
- Configuration file status
|
|
93
172
|
- Project metrics (tests, stories)
|
|
94
173
|
|
|
174
|
+
<img src="/status2.png" alt="Farmwork Status Details" width="500" />
|
|
175
|
+
|
|
95
176
|
### `farmwork doctor`
|
|
96
177
|
|
|
178
|
+
<img src="/doctor.png" alt="Farmwork Doctor" width="500" />
|
|
179
|
+
|
|
97
180
|
Check your Farmwork setup and diagnose issues.
|
|
98
181
|
|
|
99
182
|
```bash
|
|
@@ -108,67 +191,12 @@ farmwork doctor
|
|
|
108
191
|
- Issue tracking (beads)
|
|
109
192
|
- Security (.gitignore settings)
|
|
110
193
|
|
|
111
|
-
## The Farmwork Method
|
|
112
|
-
|
|
113
|
-
### Core Concepts
|
|
114
|
-
|
|
115
|
-
1. **FARMHOUSE.md** - Central command for tracking framework metrics
|
|
116
|
-
2. **Phrase Commands** - Natural language triggers for workflows
|
|
117
|
-
3. **Agents** - Specialized AI subagents for specific tasks
|
|
118
|
-
4. **Commands** - User-invocable skills (triggered with `/command`)
|
|
119
|
-
5. **Issue Tracking** - Using beads (`bd`) for full visibility
|
|
120
|
-
6. **Living Audits** - Documents that track ongoing concerns
|
|
121
|
-
|
|
122
|
-
### Phrase Commands
|
|
123
|
-
|
|
124
|
-
**Farmwork Phrases** (Development Workflow):
|
|
125
|
-
- `till the land` - Audit systems, update metrics
|
|
126
|
-
- `inspect the farm` - Full inspection (code review, performance, security, quality)
|
|
127
|
-
- `go to market` - i18n translation check
|
|
128
|
-
- `harvest crops` - Full push workflow
|
|
129
|
-
|
|
130
|
-
**Plan Phrases**:
|
|
131
|
-
- `make a plan for...` - Create implementation plan
|
|
132
|
-
- `let's implement...` - Execute plan with issue tracking
|
|
133
|
-
|
|
134
|
-
### Recommended Workflow
|
|
135
|
-
|
|
136
|
-
1. **Start Session**: Run `till the land` to audit current state
|
|
137
|
-
2. **Plan Work**: Use `make a plan for...` for new features
|
|
138
|
-
3. **Implement**: Use `let's implement...` to execute with tracking
|
|
139
|
-
4. **Quality Check**: Run `inspect the farm`
|
|
140
|
-
5. **Ship**: Run `harvest crops` to push changes
|
|
141
|
-
|
|
142
|
-
## Directory Structure
|
|
143
|
-
|
|
144
|
-
```
|
|
145
|
-
your-project/
|
|
146
|
-
├── CLAUDE.md # Main instructions & phrase commands
|
|
147
|
-
├── .claude/ # Claude Code configuration
|
|
148
|
-
│ ├── settings.json # Project settings
|
|
149
|
-
│ ├── agents/ # Specialized subagents
|
|
150
|
-
│ │ ├── code-reviewer.md
|
|
151
|
-
│ │ ├── security-auditor.md
|
|
152
|
-
│ │ └── ...
|
|
153
|
-
│ └── commands/ # User-invocable skills
|
|
154
|
-
│ ├── push.md
|
|
155
|
-
│ └── ...
|
|
156
|
-
├── _AUDIT/ # Living audit documents
|
|
157
|
-
│ ├── FARMHOUSE.md # Framework command center
|
|
158
|
-
│ ├── SECURITY.md
|
|
159
|
-
│ ├── PERFORMANCE.md
|
|
160
|
-
│ └── ...
|
|
161
|
-
├── _PLANS/ # Implementation plans
|
|
162
|
-
│ └── FEATURE_NAME.md
|
|
163
|
-
├── .beads/ # Issue tracking (optional)
|
|
164
|
-
└── justfile # Navigation commands
|
|
165
|
-
```
|
|
166
194
|
|
|
167
195
|
## Requirements
|
|
168
196
|
|
|
169
197
|
- Node.js 18+
|
|
170
198
|
- [just](https://github.com/casey/just) (recommended for navigation)
|
|
171
|
-
- [beads](https://github.com/steveyegge/beads) (
|
|
199
|
+
- [beads](https://github.com/steveyegge/beads) (for issue tracking)
|
|
172
200
|
|
|
173
201
|
## License
|
|
174
202
|
|
package/bin/farmwork.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import { program } from 'commander';
|
|
4
4
|
import { init } from '../src/init.js';
|
|
5
|
-
import { add } from '../src/add.js';
|
|
6
5
|
import { status } from '../src/status.js';
|
|
7
6
|
import { doctor } from '../src/doctor.js';
|
|
8
7
|
import chalk from 'chalk';
|
|
@@ -26,11 +25,6 @@ program
|
|
|
26
25
|
.option('-f, --force', 'Overwrite existing files')
|
|
27
26
|
.action(init);
|
|
28
27
|
|
|
29
|
-
program
|
|
30
|
-
.command('add <type> <name>')
|
|
31
|
-
.description('Add a component (agent, command, audit)')
|
|
32
|
-
.action(add);
|
|
33
|
-
|
|
34
28
|
program
|
|
35
29
|
.command('status')
|
|
36
30
|
.description('Show Farmwork status and metrics')
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "farmwork",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Farmwork - Agentic development harness for AI-assisted projects",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"farmwork": "./bin/farmwork.js"
|
|
9
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"bin",
|
|
13
|
+
"templates"
|
|
14
|
+
],
|
|
10
15
|
"scripts": {
|
|
11
16
|
"test": "node --test",
|
|
12
17
|
"lint": "eslint src/"
|
|
@@ -25,9 +30,10 @@
|
|
|
25
30
|
"dependencies": {
|
|
26
31
|
"chalk": "^5.3.0",
|
|
27
32
|
"commander": "^12.1.0",
|
|
33
|
+
"fs-extra": "^11.2.0",
|
|
28
34
|
"inquirer": "^9.2.12",
|
|
29
35
|
"ora": "^8.0.1",
|
|
30
|
-
"
|
|
36
|
+
"terminal-kit": "^3.1.1"
|
|
31
37
|
},
|
|
32
38
|
"engines": {
|
|
33
39
|
"node": ">=18.0.0"
|
package/src/doctor.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import chalk from "chalk";
|
|
4
3
|
import { execSync } from "child_process";
|
|
4
|
+
import { farmTerm, emojis } from "./terminal.js";
|
|
5
5
|
|
|
6
6
|
function checkExists(filePath, description) {
|
|
7
7
|
const exists = fs.existsSync(filePath);
|
|
@@ -54,8 +54,7 @@ function checkClaudeMdSections(claudeMdPath) {
|
|
|
54
54
|
const content = fs.readFileSync(claudeMdPath, "utf8");
|
|
55
55
|
const requiredSections = [
|
|
56
56
|
"Phrase Commands",
|
|
57
|
-
"Issue
|
|
58
|
-
"Claude Code Commands",
|
|
57
|
+
"Issue-First Workflow",
|
|
59
58
|
];
|
|
60
59
|
|
|
61
60
|
const missing = requiredSections.filter(
|
|
@@ -115,27 +114,24 @@ function checkGitignore(cwd) {
|
|
|
115
114
|
export async function doctor() {
|
|
116
115
|
const cwd = process.cwd();
|
|
117
116
|
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
farmTerm.logo();
|
|
118
|
+
farmTerm.header("FARMWORK DOCTOR", "accent");
|
|
119
|
+
await farmTerm.analyzing("Diagnosing project health", 1200);
|
|
120
120
|
|
|
121
121
|
const checks = [];
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
// Core Files
|
|
124
|
+
checks.push({ category: "Core Files", emoji: "🌾", items: [] });
|
|
124
125
|
checks[0].items.push(
|
|
125
126
|
checkExists(path.join(cwd, "CLAUDE.md"), "CLAUDE.md exists"),
|
|
126
127
|
);
|
|
127
128
|
checks[0].items.push(
|
|
128
129
|
checkExists(path.join(cwd, ".claude"), ".claude/ directory exists"),
|
|
129
130
|
);
|
|
130
|
-
checks[0].items.push(
|
|
131
|
-
checkExists(
|
|
132
|
-
path.join(cwd, ".claude", "settings.json"),
|
|
133
|
-
"settings.json exists",
|
|
134
|
-
),
|
|
135
|
-
);
|
|
136
131
|
checks[0].items.push(checkClaudeMdSections(path.join(cwd, "CLAUDE.md")));
|
|
137
132
|
|
|
138
|
-
|
|
133
|
+
// Agents & Commands
|
|
134
|
+
checks.push({ category: "Agents & Commands", emoji: "🐴", items: [] });
|
|
139
135
|
checks[1].items.push(
|
|
140
136
|
checkDirectoryNotEmpty(
|
|
141
137
|
path.join(cwd, ".claude", "agents"),
|
|
@@ -149,7 +145,8 @@ export async function doctor() {
|
|
|
149
145
|
),
|
|
150
146
|
);
|
|
151
147
|
|
|
152
|
-
|
|
148
|
+
// Audit System
|
|
149
|
+
checks.push({ category: "Audit System", emoji: "🦉", items: [] });
|
|
153
150
|
checks[2].items.push(
|
|
154
151
|
checkExists(path.join(cwd, "_AUDIT"), "_AUDIT/ directory exists"),
|
|
155
152
|
);
|
|
@@ -166,56 +163,67 @@ export async function doctor() {
|
|
|
166
163
|
checkExists(path.join(cwd, "_PLANS"), "_PLANS/ directory exists"),
|
|
167
164
|
);
|
|
168
165
|
|
|
169
|
-
|
|
166
|
+
// Navigation
|
|
167
|
+
checks.push({ category: "Navigation", emoji: "🐓", items: [] });
|
|
170
168
|
checks[3].items.push(
|
|
171
169
|
checkExists(path.join(cwd, "justfile"), "justfile exists"),
|
|
172
170
|
);
|
|
173
171
|
checks[3].items.push(checkCommand("just", "just command available"));
|
|
174
172
|
|
|
175
|
-
|
|
173
|
+
// Issue Tracking
|
|
174
|
+
checks.push({ category: "Issue Tracking", emoji: "🐷", items: [] });
|
|
176
175
|
checks[4].items.push(
|
|
177
176
|
checkExists(path.join(cwd, ".beads"), ".beads/ directory exists"),
|
|
178
177
|
);
|
|
179
178
|
checks[4].items.push(checkCommand("bd", "bd (beads) command available"));
|
|
180
179
|
|
|
181
|
-
|
|
180
|
+
// Security
|
|
181
|
+
checks.push({ category: "Security", emoji: "🐕", items: [] });
|
|
182
182
|
checks[5].items.push(checkGitignore(cwd));
|
|
183
183
|
|
|
184
184
|
let totalPassed = 0;
|
|
185
185
|
let totalFailed = 0;
|
|
186
186
|
let totalWarnings = 0;
|
|
187
187
|
|
|
188
|
+
// Run checks with animation
|
|
188
189
|
for (const category of checks) {
|
|
189
|
-
|
|
190
|
+
farmTerm.section(category.category, category.emoji);
|
|
190
191
|
|
|
191
192
|
for (const check of category.items) {
|
|
193
|
+
// Small delay for visual effect
|
|
194
|
+
await new Promise(r => setTimeout(r, 80));
|
|
195
|
+
|
|
192
196
|
if (check.passed) {
|
|
193
|
-
|
|
197
|
+
farmTerm.status(check.message, "pass");
|
|
194
198
|
totalPassed++;
|
|
195
199
|
} else {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
200
|
+
// Beads-related items are optional (warnings)
|
|
201
|
+
const isOptional = check.message.includes("beads") || check.message.includes("bd ");
|
|
202
|
+
if (isOptional) {
|
|
203
|
+
farmTerm.status(check.message, "warn", check.details || "(optional)");
|
|
199
204
|
totalWarnings++;
|
|
200
205
|
} else {
|
|
201
|
-
|
|
202
|
-
if (check.details) console.log(chalk.gray(` ${check.details}`));
|
|
206
|
+
farmTerm.status(check.message, "fail", check.details || "");
|
|
203
207
|
totalFailed++;
|
|
204
208
|
}
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
|
-
console.log();
|
|
208
211
|
}
|
|
209
212
|
|
|
210
|
-
|
|
211
|
-
|
|
213
|
+
// Summary
|
|
214
|
+
farmTerm.nl();
|
|
215
|
+
farmTerm.divider("═", 50);
|
|
216
|
+
farmTerm.section("Diagnosis Summary", "🐮");
|
|
217
|
+
|
|
218
|
+
farmTerm.metric("Passed", totalPassed, emojis.seedling);
|
|
212
219
|
if (totalWarnings > 0) {
|
|
213
|
-
|
|
220
|
+
farmTerm.metric("Warnings", totalWarnings, emojis.leaf);
|
|
214
221
|
}
|
|
215
222
|
if (totalFailed > 0) {
|
|
216
|
-
|
|
223
|
+
farmTerm.metric("Failed", totalFailed, "🍂");
|
|
217
224
|
}
|
|
218
225
|
|
|
226
|
+
// Health Assessment
|
|
219
227
|
const health =
|
|
220
228
|
totalFailed === 0
|
|
221
229
|
? totalWarnings === 0
|
|
@@ -225,20 +233,28 @@ export async function doctor() {
|
|
|
225
233
|
? "Needs Attention"
|
|
226
234
|
: "Critical";
|
|
227
235
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
farmTerm.nl();
|
|
237
|
+
farmTerm.divider();
|
|
238
|
+
|
|
239
|
+
if (health === "Excellent") {
|
|
240
|
+
farmTerm.success(`Health: ${health} - Your farm is thriving! 🌳`);
|
|
241
|
+
} else if (health === "Good") {
|
|
242
|
+
farmTerm.info(`Health: ${health} - Growing nicely! 🌿`);
|
|
243
|
+
} else if (health === "Needs Attention") {
|
|
244
|
+
farmTerm.warn(`Health: ${health} - Some areas need work 🌱`);
|
|
245
|
+
} else {
|
|
246
|
+
farmTerm.error(`Health: ${health} - Urgent care needed! 🥀`);
|
|
247
|
+
}
|
|
238
248
|
|
|
239
249
|
if (totalFailed > 0) {
|
|
240
|
-
|
|
250
|
+
farmTerm.nl();
|
|
251
|
+
farmTerm.info("Run `farmwork init` to fix missing components.");
|
|
241
252
|
}
|
|
242
253
|
|
|
243
|
-
|
|
254
|
+
// Health bar visualization
|
|
255
|
+
const healthPercent = Math.round((totalPassed / (totalPassed + totalFailed + totalWarnings)) * 100);
|
|
256
|
+
farmTerm.nl();
|
|
257
|
+
farmTerm.score("Overall Health", healthPercent, 100);
|
|
258
|
+
|
|
259
|
+
farmTerm.nl();
|
|
244
260
|
}
|
package/src/index.js
CHANGED