meto-cli 0.6.0 → 0.7.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/CHANGELOG.md +31 -0
- package/README.md +47 -19
- package/dist/cli/doctor-checks.d.ts +52 -0
- package/dist/cli/doctor-checks.d.ts.map +1 -0
- package/dist/cli/doctor-checks.js +331 -0
- package/dist/cli/doctor-checks.js.map +1 -0
- package/dist/cli/doctor.d.ts +19 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +87 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.js +17 -22
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/prompts.d.ts.map +1 -1
- package/dist/cli/prompts.js +19 -20
- package/dist/cli/prompts.js.map +1 -1
- package/package.json +1 -1
- package/templates/.claude/agent-memory/lom-developer/MEMORY.md +11 -11
- package/templates/.claude/agent-memory/lom-pm/MEMORY.md +9 -14
- package/templates/.claude/agent-memory/lom-tester/MEMORY.md +9 -10
- package/templates/.claude/agents/developer-agent.md +6 -0
- package/templates/.claude/agents/pm-agent.md +6 -0
- package/templates/.claude/agents/tester-agent.md +6 -0
- package/templates/CLAUDE.md +10 -0
- package/templates/ai/workflows/session-checkpoint.md +49 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,37 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [0.7.0] - 2026-03-05
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Doctor command (`meto-cli doctor`) that checks methodology health of a Meto-scaffolded project
|
|
13
|
+
- 7 health checks: required files, context content, board format, epics content, agent definitions, WIP limit, orphan tasks
|
|
14
|
+
- Project root detection by walking up from current directory looking for `ai/tasks/`
|
|
15
|
+
- Scannable report with pass/warn/fail per check and summary line
|
|
16
|
+
- Exit code 1 when any check fails (0 for pass or warnings only)
|
|
17
|
+
|
|
18
|
+
## [0.6.0] - 2026-03-05
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- 4 new stack presets: Python (FastAPI), Go, Vite + React, Flutter
|
|
23
|
+
- Each preset includes tailored tech-stack description, definition of done, and starter epics
|
|
24
|
+
|
|
25
|
+
## [0.4.0] - 2026-03-05
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- AI-powered init: when Claude Code is detected, generates product vision, epics, and sliced backlog automatically
|
|
30
|
+
- User answers 5 questions instead of 10 when AI is available
|
|
31
|
+
- `--no-ai` flag to force static prompts even when Claude Code is installed
|
|
32
|
+
- AI generation with 90-second timeout and progress spinner
|
|
33
|
+
- Fallback to static prompts when AI generation fails (timeout, parse error, subprocess crash)
|
|
34
|
+
- Section-delimited AI output parsing with validation
|
|
35
|
+
- AI generation summary note showing what was generated
|
|
36
|
+
- Agent memory files scaffolded for PM, developer, and tester agents
|
|
37
|
+
- Agent Teams support with `.claude/settings.json` and file ownership boundaries
|
|
38
|
+
|
|
8
39
|
## [0.1.0] - 2026-03-04
|
|
9
40
|
|
|
10
41
|
### Added
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Lovable gives you an app. Meto gives you a project -- built the right way, your way.
|
|
4
4
|
|
|
5
|
-
Meto scaffolds structured software projects with built-in methodology. You describe what you want to build, and Meto bootstraps a project with a
|
|
5
|
+
Meto scaffolds structured software projects with built-in methodology. You describe what you want to build, and Meto bootstraps a project with AI-generated epics, a sliced backlog, agent definitions, product context, and coding conventions -- ready for your first Claude Code session.
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
@@ -14,23 +14,45 @@ Meto scaffolds structured software projects with built-in methodology. You descr
|
|
|
14
14
|
npx meto-cli init
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Answer a few questions
|
|
17
|
+
Answer a few questions, and Meto generates a fully structured repository in seconds -- with AI-powered content if Claude Code is installed.
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## How It Works
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Meto detects whether Claude Code is installed on your machine and offers two paths:
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
**With Claude Code (AI-powered):**
|
|
26
|
+
1. You answer 5 questions -- project name, description, target users, tech stack, output directory
|
|
27
|
+
2. Claude Code generates your product vision, problem statement, epics, and a sliced backlog with acceptance criteria
|
|
28
|
+
3. Meto renders everything into a structured project ready for your first sprint
|
|
29
|
+
|
|
30
|
+
**Without Claude Code (static):**
|
|
31
|
+
1. You answer 10 questions -- the 5 above plus problem statement, success criteria, value proposition, out of scope, and code conventions
|
|
32
|
+
2. Meto renders your answers into the same structured project with sensible defaults
|
|
33
|
+
|
|
34
|
+
Both paths produce the same project structure. The AI path just fills in more content so you spend less time on setup and more time building.
|
|
35
|
+
|
|
36
|
+
Use `--no-ai` to force the static path even when Claude Code is available.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Stack Presets
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
Choose from 7 built-in tech stacks, each with a tailored description, definition of done, and starter epics:
|
|
43
|
+
|
|
44
|
+
| Stack | What you get |
|
|
45
|
+
|---|---|
|
|
46
|
+
| **Next.js + Supabase** | Full-stack web app with auth, database, and edge functions |
|
|
47
|
+
| **React Native** | Cross-platform mobile app |
|
|
48
|
+
| **Node.js CLI** | Command-line tool distributed via npm |
|
|
49
|
+
| **Python (FastAPI)** | REST API with async support, auto-generated docs |
|
|
50
|
+
| **Go** | Compiled backend service or CLI tool |
|
|
51
|
+
| **Vite + React** | Client-side SPA with fast dev server |
|
|
52
|
+
| **Flutter** | Cross-platform mobile and web app with Dart |
|
|
53
|
+
| **Custom** | Describe your own stack |
|
|
54
|
+
|
|
55
|
+
Each preset populates your tech-stack description, definition of done (with stack-specific checks), and starter epics so your backlog has real structure from day one.
|
|
34
56
|
|
|
35
57
|
---
|
|
36
58
|
|
|
@@ -70,6 +92,15 @@ your-project/
|
|
|
70
92
|
└── CLAUDE.md
|
|
71
93
|
```
|
|
72
94
|
|
|
95
|
+
**What's inside:**
|
|
96
|
+
- **CLAUDE.md** -- project instructions that Claude Code reads every session, pre-filled with your vision, stack, and conventions
|
|
97
|
+
- **Kanban board** -- task pipeline (backlog, todo, in-progress, testing, done) ready for your first sprint
|
|
98
|
+
- **Agent definitions** -- PM, developer, and tester agents configured to follow your methodology from day one
|
|
99
|
+
- **Agent memory** -- persistent memory files so agents retain context across sessions
|
|
100
|
+
- **Product context** -- vision, tech stack, and decisions captured in structured files
|
|
101
|
+
- **Epics and workflows** -- definition of done, commit conventions, and an epic backlog to plan against
|
|
102
|
+
- **Agent Teams ready** -- three agents configured to work in parallel with file ownership boundaries
|
|
103
|
+
|
|
73
104
|
---
|
|
74
105
|
|
|
75
106
|
## Agent Teams
|
|
@@ -86,10 +117,6 @@ Meto scaffolds projects ready for Agent Teams out of the box:
|
|
|
86
117
|
|
|
87
118
|
> "Create an agent team with @meto-pm for planning, @meto-developer for building, @meto-tester for validation"
|
|
88
119
|
|
|
89
|
-
**Display modes:** use Shift+Down to cycle between agents in-process, or run each agent in its own split pane (tmux/iTerm2).
|
|
90
|
-
|
|
91
|
-
This feature is experimental and enabled via `.claude/settings.json` in the scaffold.
|
|
92
|
-
|
|
93
120
|
---
|
|
94
121
|
|
|
95
122
|
## Next Steps
|
|
@@ -107,8 +134,8 @@ This feature is experimental and enabled via `.claude/settings.json` in the scaf
|
|
|
107
134
|
| Requirement | Version | Notes |
|
|
108
135
|
|---|---|---|
|
|
109
136
|
| Node.js | >= 18 | Required to run the CLI |
|
|
110
|
-
| git | any | Recommended -- Meto
|
|
111
|
-
| Claude Code | latest |
|
|
137
|
+
| git | any | Recommended -- Meto initializes a repository if git is available |
|
|
138
|
+
| Claude Code | latest | Optional -- enables AI-powered generation. Without it, Meto uses static prompts |
|
|
112
139
|
|
|
113
140
|
---
|
|
114
141
|
|
|
@@ -116,7 +143,8 @@ This feature is experimental and enabled via `.claude/settings.json` in the scaf
|
|
|
116
143
|
|
|
117
144
|
| Command | Description |
|
|
118
145
|
|---|---|
|
|
119
|
-
| `meto-cli init` | Scaffold a new structured project |
|
|
146
|
+
| `meto-cli init` | Scaffold a new structured project (AI-powered if Claude Code is detected) |
|
|
147
|
+
| `meto-cli init --no-ai` | Scaffold using static prompts only, skip AI generation |
|
|
120
148
|
| `meto-cli init --dry-run` | Preview the generated file tree without writing to disk |
|
|
121
149
|
| `meto-cli --help` | Show available commands and options |
|
|
122
150
|
| `meto-cli --version` | Show the installed version |
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of a single health check performed by the doctor command.
|
|
3
|
+
*/
|
|
4
|
+
export interface HealthCheckResult {
|
|
5
|
+
/** Human-readable name of the check */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Whether the check passed, produced a warning, or failed */
|
|
8
|
+
status: "pass" | "warn" | "fail";
|
|
9
|
+
/** Descriptive message explaining the result */
|
|
10
|
+
message: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Extracts all task slice identifiers (e.g. "slice-001") from a markdown file's
|
|
14
|
+
* ## [slice-NNN] headings.
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractSliceIds(content: string): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Check 1: Required files exist.
|
|
19
|
+
* Each required file that is missing produces a "fail" result.
|
|
20
|
+
*/
|
|
21
|
+
export declare function checkRequiredFiles(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Check 2: Context files are not empty.
|
|
24
|
+
* Files with 2 or fewer lines of content produce a "warn" result.
|
|
25
|
+
*/
|
|
26
|
+
export declare function checkContextFilesNotEmpty(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Check 3: Board files start with a # heading.
|
|
29
|
+
*/
|
|
30
|
+
export declare function checkBoardFileFormat(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Check 4: Epics file has content (at least one ## E heading).
|
|
33
|
+
*/
|
|
34
|
+
export declare function checkEpicsFileHasContent(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Check 5: Agent definitions exist in .claude/agents/.
|
|
37
|
+
*/
|
|
38
|
+
export declare function checkAgentDefinitions(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Check 6: In-progress limit (max 1 task in tasks-in-progress.md).
|
|
41
|
+
*/
|
|
42
|
+
export declare function checkInProgressLimit(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Check 7: No orphan tasks (tasks in in-progress or in-testing must exist in backlog).
|
|
45
|
+
*/
|
|
46
|
+
export declare function checkNoOrphanTasks(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Runs all methodology health checks against the given project root.
|
|
49
|
+
* Returns an array of check results -- one per individual check.
|
|
50
|
+
*/
|
|
51
|
+
export declare function runHealthChecks(projectRoot: string): Promise<HealthCheckResult[]>;
|
|
52
|
+
//# sourceMappingURL=doctor-checks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-checks.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-checks.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAsED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CASzD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAqB9B;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA2B9B;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA2B9B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAyB9B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAoC9B;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA4B9B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA+D9B;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAmB9B"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { readFile, readdir, access } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Files that must exist in every Meto-scaffolded project.
|
|
5
|
+
*/
|
|
6
|
+
const REQUIRED_FILES = [
|
|
7
|
+
"CLAUDE.md",
|
|
8
|
+
"ai/context/product-vision.md",
|
|
9
|
+
"ai/context/tech-stack.md",
|
|
10
|
+
"ai/context/decisions.md",
|
|
11
|
+
"ai/backlog/epics.md",
|
|
12
|
+
"ai/tasks/tasks-backlog.md",
|
|
13
|
+
"ai/tasks/tasks-todo.md",
|
|
14
|
+
"ai/tasks/tasks-in-progress.md",
|
|
15
|
+
"ai/tasks/tasks-in-testing.md",
|
|
16
|
+
"ai/tasks/tasks-done.md",
|
|
17
|
+
"ai/workflows/definition-of-done.md",
|
|
18
|
+
];
|
|
19
|
+
/**
|
|
20
|
+
* Context files that should have meaningful content (more than 2 lines).
|
|
21
|
+
*/
|
|
22
|
+
const CONTEXT_FILES = [
|
|
23
|
+
"ai/context/product-vision.md",
|
|
24
|
+
"ai/context/tech-stack.md",
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* Board files that should start with a # heading.
|
|
28
|
+
*/
|
|
29
|
+
const BOARD_FILES = [
|
|
30
|
+
"ai/tasks/tasks-backlog.md",
|
|
31
|
+
"ai/tasks/tasks-todo.md",
|
|
32
|
+
"ai/tasks/tasks-in-progress.md",
|
|
33
|
+
"ai/tasks/tasks-in-testing.md",
|
|
34
|
+
"ai/tasks/tasks-done.md",
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Agent definition files that must exist in .claude/agents/.
|
|
38
|
+
*/
|
|
39
|
+
const REQUIRED_AGENTS = [
|
|
40
|
+
"pm-agent.md",
|
|
41
|
+
"developer-agent.md",
|
|
42
|
+
"tester-agent.md",
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Checks whether a file exists at the given path.
|
|
46
|
+
*/
|
|
47
|
+
async function fileExists(filePath) {
|
|
48
|
+
try {
|
|
49
|
+
await access(filePath);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Safely reads a file, returning undefined if the file does not exist.
|
|
58
|
+
*/
|
|
59
|
+
async function safeReadFile(filePath) {
|
|
60
|
+
try {
|
|
61
|
+
return await readFile(filePath, "utf-8");
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extracts all task slice identifiers (e.g. "slice-001") from a markdown file's
|
|
69
|
+
* ## [slice-NNN] headings.
|
|
70
|
+
*/
|
|
71
|
+
export function extractSliceIds(content) {
|
|
72
|
+
const matches = content.match(/## \[slice-\d+\]/g);
|
|
73
|
+
if (matches === null) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
return matches.map((m) => {
|
|
77
|
+
const idMatch = /\[slice-\d+\]/.exec(m);
|
|
78
|
+
return idMatch ? idMatch[0] : "";
|
|
79
|
+
}).filter((id) => id.length > 0);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check 1: Required files exist.
|
|
83
|
+
* Each required file that is missing produces a "fail" result.
|
|
84
|
+
*/
|
|
85
|
+
export async function checkRequiredFiles(projectRoot) {
|
|
86
|
+
const results = [];
|
|
87
|
+
for (const file of REQUIRED_FILES) {
|
|
88
|
+
const exists = await fileExists(join(projectRoot, file));
|
|
89
|
+
if (exists) {
|
|
90
|
+
results.push({
|
|
91
|
+
name: `Required file: ${file}`,
|
|
92
|
+
status: "pass",
|
|
93
|
+
message: "File exists",
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
results.push({
|
|
98
|
+
name: `Required file: ${file}`,
|
|
99
|
+
status: "fail",
|
|
100
|
+
message: `Missing required file: ${file}`,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return results;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Check 2: Context files are not empty.
|
|
108
|
+
* Files with 2 or fewer lines of content produce a "warn" result.
|
|
109
|
+
*/
|
|
110
|
+
export async function checkContextFilesNotEmpty(projectRoot) {
|
|
111
|
+
const results = [];
|
|
112
|
+
for (const file of CONTEXT_FILES) {
|
|
113
|
+
const content = await safeReadFile(join(projectRoot, file));
|
|
114
|
+
if (content === undefined) {
|
|
115
|
+
// File missing is caught by checkRequiredFiles; skip here
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
119
|
+
if (lines.length > 2) {
|
|
120
|
+
results.push({
|
|
121
|
+
name: `Content check: ${file}`,
|
|
122
|
+
status: "pass",
|
|
123
|
+
message: "File has meaningful content",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
results.push({
|
|
128
|
+
name: `Content check: ${file}`,
|
|
129
|
+
status: "warn",
|
|
130
|
+
message: `${file} has ${lines.length} non-empty lines -- expected more than 2`,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return results;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check 3: Board files start with a # heading.
|
|
138
|
+
*/
|
|
139
|
+
export async function checkBoardFileFormat(projectRoot) {
|
|
140
|
+
const results = [];
|
|
141
|
+
for (const file of BOARD_FILES) {
|
|
142
|
+
const content = await safeReadFile(join(projectRoot, file));
|
|
143
|
+
if (content === undefined) {
|
|
144
|
+
// File missing is caught by checkRequiredFiles; skip here
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const firstLine = content.trimStart().split("\n")[0];
|
|
148
|
+
if (firstLine.startsWith("# ")) {
|
|
149
|
+
results.push({
|
|
150
|
+
name: `Board format: ${file}`,
|
|
151
|
+
status: "pass",
|
|
152
|
+
message: "File starts with a heading",
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
results.push({
|
|
157
|
+
name: `Board format: ${file}`,
|
|
158
|
+
status: "warn",
|
|
159
|
+
message: `${file} does not start with a # heading`,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return results;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Check 4: Epics file has content (at least one ## E heading).
|
|
167
|
+
*/
|
|
168
|
+
export async function checkEpicsFileHasContent(projectRoot) {
|
|
169
|
+
const content = await safeReadFile(join(projectRoot, "ai/backlog/epics.md"));
|
|
170
|
+
if (content === undefined) {
|
|
171
|
+
// File missing is caught by checkRequiredFiles; skip here
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
const hasEpicHeading = /## E/.test(content);
|
|
175
|
+
if (hasEpicHeading) {
|
|
176
|
+
return [
|
|
177
|
+
{
|
|
178
|
+
name: "Epics file content",
|
|
179
|
+
status: "pass",
|
|
180
|
+
message: "Epics file contains at least one epic",
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
return [
|
|
185
|
+
{
|
|
186
|
+
name: "Epics file content",
|
|
187
|
+
status: "warn",
|
|
188
|
+
message: "epics.md does not contain any ## E headings",
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Check 5: Agent definitions exist in .claude/agents/.
|
|
194
|
+
*/
|
|
195
|
+
export async function checkAgentDefinitions(projectRoot) {
|
|
196
|
+
const results = [];
|
|
197
|
+
const agentsDir = join(projectRoot, ".claude", "agents");
|
|
198
|
+
let agentFiles;
|
|
199
|
+
try {
|
|
200
|
+
agentFiles = await readdir(agentsDir);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// Directory doesn't exist -- all agents are missing
|
|
204
|
+
for (const agent of REQUIRED_AGENTS) {
|
|
205
|
+
results.push({
|
|
206
|
+
name: `Agent definition: ${agent}`,
|
|
207
|
+
status: "fail",
|
|
208
|
+
message: `Missing agent definition: .claude/agents/${agent}`,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
return results;
|
|
212
|
+
}
|
|
213
|
+
for (const agent of REQUIRED_AGENTS) {
|
|
214
|
+
if (agentFiles.includes(agent)) {
|
|
215
|
+
results.push({
|
|
216
|
+
name: `Agent definition: ${agent}`,
|
|
217
|
+
status: "pass",
|
|
218
|
+
message: "Agent definition exists",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
results.push({
|
|
223
|
+
name: `Agent definition: ${agent}`,
|
|
224
|
+
status: "fail",
|
|
225
|
+
message: `Missing agent definition: .claude/agents/${agent}`,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return results;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Check 6: In-progress limit (max 1 task in tasks-in-progress.md).
|
|
233
|
+
*/
|
|
234
|
+
export async function checkInProgressLimit(projectRoot) {
|
|
235
|
+
const content = await safeReadFile(join(projectRoot, "ai/tasks/tasks-in-progress.md"));
|
|
236
|
+
if (content === undefined) {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
const sliceIds = extractSliceIds(content);
|
|
240
|
+
const count = sliceIds.length;
|
|
241
|
+
if (count <= 1) {
|
|
242
|
+
return [
|
|
243
|
+
{
|
|
244
|
+
name: "WIP limit",
|
|
245
|
+
status: "pass",
|
|
246
|
+
message: `${count} task(s) in progress`,
|
|
247
|
+
},
|
|
248
|
+
];
|
|
249
|
+
}
|
|
250
|
+
return [
|
|
251
|
+
{
|
|
252
|
+
name: "WIP limit",
|
|
253
|
+
status: "warn",
|
|
254
|
+
message: `WIP limit exceeded: ${count} tasks in progress, expected max 1.`,
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Check 7: No orphan tasks (tasks in in-progress or in-testing must exist in backlog).
|
|
260
|
+
*/
|
|
261
|
+
export async function checkNoOrphanTasks(projectRoot) {
|
|
262
|
+
const backlogContent = await safeReadFile(join(projectRoot, "ai/tasks/tasks-backlog.md"));
|
|
263
|
+
const inProgressContent = await safeReadFile(join(projectRoot, "ai/tasks/tasks-in-progress.md"));
|
|
264
|
+
const inTestingContent = await safeReadFile(join(projectRoot, "ai/tasks/tasks-in-testing.md"));
|
|
265
|
+
if (backlogContent === undefined) {
|
|
266
|
+
return [];
|
|
267
|
+
}
|
|
268
|
+
const backlogIds = extractSliceIds(backlogContent);
|
|
269
|
+
const activeTasks = [];
|
|
270
|
+
if (inProgressContent !== undefined) {
|
|
271
|
+
for (const id of extractSliceIds(inProgressContent)) {
|
|
272
|
+
activeTasks.push({ id, source: "tasks-in-progress.md" });
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (inTestingContent !== undefined) {
|
|
276
|
+
for (const id of extractSliceIds(inTestingContent)) {
|
|
277
|
+
activeTasks.push({ id, source: "tasks-in-testing.md" });
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (activeTasks.length === 0) {
|
|
281
|
+
return [
|
|
282
|
+
{
|
|
283
|
+
name: "Orphan tasks",
|
|
284
|
+
status: "pass",
|
|
285
|
+
message: "No active tasks to check",
|
|
286
|
+
},
|
|
287
|
+
];
|
|
288
|
+
}
|
|
289
|
+
const results = [];
|
|
290
|
+
let hasOrphan = false;
|
|
291
|
+
for (const task of activeTasks) {
|
|
292
|
+
if (!backlogIds.includes(task.id)) {
|
|
293
|
+
hasOrphan = true;
|
|
294
|
+
results.push({
|
|
295
|
+
name: `Orphan task: ${task.id}`,
|
|
296
|
+
status: "warn",
|
|
297
|
+
message: `${task.id} in ${task.source} has no matching entry in tasks-backlog.md`,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (!hasOrphan) {
|
|
302
|
+
results.push({
|
|
303
|
+
name: "Orphan tasks",
|
|
304
|
+
status: "pass",
|
|
305
|
+
message: "All active tasks have backlog entries",
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
return results;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Runs all methodology health checks against the given project root.
|
|
312
|
+
* Returns an array of check results -- one per individual check.
|
|
313
|
+
*/
|
|
314
|
+
export async function runHealthChecks(projectRoot) {
|
|
315
|
+
const allResults = [];
|
|
316
|
+
const checkFunctions = [
|
|
317
|
+
checkRequiredFiles,
|
|
318
|
+
checkContextFilesNotEmpty,
|
|
319
|
+
checkBoardFileFormat,
|
|
320
|
+
checkEpicsFileHasContent,
|
|
321
|
+
checkAgentDefinitions,
|
|
322
|
+
checkInProgressLimit,
|
|
323
|
+
checkNoOrphanTasks,
|
|
324
|
+
];
|
|
325
|
+
for (const checkFn of checkFunctions) {
|
|
326
|
+
const results = await checkFn(projectRoot);
|
|
327
|
+
allResults.push(...results);
|
|
328
|
+
}
|
|
329
|
+
return allResults;
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=doctor-checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-checks.js","sourceRoot":"","sources":["../../src/cli/doctor-checks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HealthCheckResult } from "./doctor-checks.js";
|
|
2
|
+
/**
|
|
3
|
+
* Searches upward from the given starting directory for a Meto project root.
|
|
4
|
+
* A Meto project root is identified by the presence of an `ai/tasks/` directory.
|
|
5
|
+
*
|
|
6
|
+
* Returns the absolute path to the project root, or undefined if not found.
|
|
7
|
+
*/
|
|
8
|
+
export declare function findProjectRoot(startDir: string): Promise<string | undefined>;
|
|
9
|
+
/**
|
|
10
|
+
* Determines the exit code based on health check results.
|
|
11
|
+
* Returns 0 if no failures (warnings are OK), 1 if any check failed.
|
|
12
|
+
*/
|
|
13
|
+
export declare function determineExitCode(results: HealthCheckResult[]): number;
|
|
14
|
+
/**
|
|
15
|
+
* Entry point for the `meto-cli doctor` command.
|
|
16
|
+
* Detects the project root, runs health checks, and displays a report.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runDoctor(): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoB7B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAGtE;AA2BD;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CA6B/C"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { join, dirname, resolve } from "node:path";
|
|
3
|
+
import * as p from "@clack/prompts";
|
|
4
|
+
import { runHealthChecks } from "./doctor-checks.js";
|
|
5
|
+
/**
|
|
6
|
+
* Searches upward from the given starting directory for a Meto project root.
|
|
7
|
+
* A Meto project root is identified by the presence of an `ai/tasks/` directory.
|
|
8
|
+
*
|
|
9
|
+
* Returns the absolute path to the project root, or undefined if not found.
|
|
10
|
+
*/
|
|
11
|
+
export async function findProjectRoot(startDir) {
|
|
12
|
+
let current = resolve(startDir);
|
|
13
|
+
// eslint-disable-next-line no-constant-condition
|
|
14
|
+
while (true) {
|
|
15
|
+
const candidate = join(current, "ai", "tasks");
|
|
16
|
+
try {
|
|
17
|
+
await access(candidate);
|
|
18
|
+
return current;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// ai/tasks/ not found at this level, move up
|
|
22
|
+
}
|
|
23
|
+
const parent = dirname(current);
|
|
24
|
+
if (parent === current) {
|
|
25
|
+
// Reached filesystem root without finding a project
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
current = parent;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Determines the exit code based on health check results.
|
|
33
|
+
* Returns 0 if no failures (warnings are OK), 1 if any check failed.
|
|
34
|
+
*/
|
|
35
|
+
export function determineExitCode(results) {
|
|
36
|
+
const hasFail = results.some((r) => r.status === "fail");
|
|
37
|
+
return hasFail ? 1 : 0;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Formats and displays health check results using clack output functions.
|
|
41
|
+
*/
|
|
42
|
+
function displayResults(results) {
|
|
43
|
+
for (const result of results) {
|
|
44
|
+
switch (result.status) {
|
|
45
|
+
case "pass":
|
|
46
|
+
p.log.success(result.name);
|
|
47
|
+
break;
|
|
48
|
+
case "warn":
|
|
49
|
+
p.log.warning(`${result.name}: ${result.message}`);
|
|
50
|
+
break;
|
|
51
|
+
case "fail":
|
|
52
|
+
p.log.error(`${result.name}: ${result.message}`);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const passed = results.filter((r) => r.status === "pass").length;
|
|
57
|
+
const warnings = results.filter((r) => r.status === "warn").length;
|
|
58
|
+
const failed = results.filter((r) => r.status === "fail").length;
|
|
59
|
+
p.note(`${passed} passed, ${warnings} warnings, ${failed} failed`, "Summary");
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Entry point for the `meto-cli doctor` command.
|
|
63
|
+
* Detects the project root, runs health checks, and displays a report.
|
|
64
|
+
*/
|
|
65
|
+
export async function runDoctor() {
|
|
66
|
+
p.intro("meto-cli doctor");
|
|
67
|
+
const projectRoot = await findProjectRoot(process.cwd());
|
|
68
|
+
if (projectRoot === undefined) {
|
|
69
|
+
p.log.error("No Meto project found. Run this command from within a Meto-scaffolded project.");
|
|
70
|
+
p.outro("");
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
p.log.info(`Meto project detected at ${projectRoot}`);
|
|
74
|
+
const results = await runHealthChecks(projectRoot);
|
|
75
|
+
displayResults(results);
|
|
76
|
+
const exitCode = determineExitCode(results);
|
|
77
|
+
if (exitCode === 0) {
|
|
78
|
+
p.outro("All checks passed.");
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
p.outro("Some checks failed. Review the issues above.");
|
|
82
|
+
}
|
|
83
|
+
if (exitCode !== 0) {
|
|
84
|
+
process.exit(exitCode);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -5,12 +5,11 @@ import * as p from "@clack/prompts";
|
|
|
5
5
|
import { collectDeepContent, collectProjectBrief } from "./prompts.js";
|
|
6
6
|
import { InterruptionHandler } from "./interruption.js";
|
|
7
7
|
import { buildTokenMap, renderTemplates, resolveTemplatesDir, } from "./renderer.js";
|
|
8
|
-
import { runGitHubFlow } from "./github.js";
|
|
9
8
|
import { initGitRepo } from "./git.js";
|
|
10
|
-
import { runSupabaseFlow } from "./supabase.js";
|
|
11
9
|
import { checkWritePermission, PreflightError, runPreflightChecks, } from "./preflight.js";
|
|
12
10
|
import { DirectoryNotEmptyError, writeScaffold } from "./scaffold.js";
|
|
13
11
|
import { formatFileTree } from "./tree.js";
|
|
12
|
+
import { runDoctor } from "./doctor.js";
|
|
14
13
|
import { generateWithAI, AIGenerationTimeoutError } from "./ai-generator.js";
|
|
15
14
|
import { parseAIOutput, validateAIContent } from "./ai-parser.js";
|
|
16
15
|
/**
|
|
@@ -49,6 +48,7 @@ function printHelp() {
|
|
|
49
48
|
" init Scaffold a new structured project",
|
|
50
49
|
" init --dry-run Preview files without writing to disk",
|
|
51
50
|
" init --no-ai Skip AI generation, use standard prompts",
|
|
51
|
+
" doctor Check methodology health of the current project",
|
|
52
52
|
"",
|
|
53
53
|
"Options:",
|
|
54
54
|
" --help, -h Show this help message",
|
|
@@ -229,28 +229,19 @@ async function main() {
|
|
|
229
229
|
gitSpinner.stop("Git initialization failed -- skipping.");
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
|
-
const githubResult = await runGitHubFlow(brief.projectName, brief.outputDirectory, gitInitSucceeded);
|
|
233
|
-
const supabaseResult = await runSupabaseFlow(brief.techStack, brief.outputDirectory);
|
|
234
232
|
const nextSteps = [
|
|
235
|
-
`
|
|
236
|
-
"
|
|
237
|
-
"
|
|
238
|
-
|
|
239
|
-
"
|
|
233
|
+
`Your project is ready at ${brief.outputDirectory}`,
|
|
234
|
+
"",
|
|
235
|
+
"1. Open it in your editor",
|
|
236
|
+
` code ${brief.outputDirectory}`,
|
|
237
|
+
"",
|
|
238
|
+
"2. Start Claude Code in the project folder",
|
|
239
|
+
` cd ${brief.outputDirectory} && claude`,
|
|
240
|
+
"",
|
|
241
|
+
'3. Tell Claude: "Read CLAUDE.md and set up the backlog"',
|
|
242
|
+
" This kicks off the PM agent to create your first tasks.",
|
|
240
243
|
];
|
|
241
|
-
|
|
242
|
-
nextSteps.push(`GitHub repo: ${githubResult.repoUrl}`);
|
|
243
|
-
}
|
|
244
|
-
if (brief.techStack === "nextjs-supabase") {
|
|
245
|
-
if (supabaseResult.initialized) {
|
|
246
|
-
nextSteps.push("Run `supabase start` to launch the local development stack");
|
|
247
|
-
}
|
|
248
|
-
nextSteps.push("Copy the local credentials from `supabase status` into `.env.local`");
|
|
249
|
-
}
|
|
250
|
-
if (!preflight.gitAvailable) {
|
|
251
|
-
nextSteps.push("Run `git init` when git is available");
|
|
252
|
-
}
|
|
253
|
-
p.note(nextSteps.join("\n"), "Next Steps");
|
|
244
|
+
p.note(nextSteps.join("\n"), "What's Next");
|
|
254
245
|
p.outro("Done. Happy building!");
|
|
255
246
|
}
|
|
256
247
|
catch (error) {
|
|
@@ -271,6 +262,10 @@ async function main() {
|
|
|
271
262
|
interruption.uninstall();
|
|
272
263
|
return;
|
|
273
264
|
}
|
|
265
|
+
if (arg === "doctor") {
|
|
266
|
+
await runDoctor();
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
274
269
|
p.intro("meto-cli -- methodology-first project scaffolding");
|
|
275
270
|
p.log.error(`Unknown command: ${arg}`);
|
|
276
271
|
p.log.info("Run 'meto-cli --help' to see available commands.");
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,aAAa,EACb,eAAe,EACf,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,YAAY,CAAC;AAoC1D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CA2CrE;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,YAAY,CAAC;AAoC1D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CA2CrE;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,YAAY,CAAC,CAsHvB"}
|
package/dist/cli/prompts.js
CHANGED
|
@@ -30,7 +30,7 @@ function handleCancel(value) {
|
|
|
30
30
|
process.exit(0);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
const DEFAULT_DEFERRED = "To be
|
|
33
|
+
const DEFAULT_DEFERRED = "To be filled in later";
|
|
34
34
|
const DEFAULT_CONVENTIONS = "TypeScript strict mode, no any types, no console.log in production code";
|
|
35
35
|
/**
|
|
36
36
|
* Collects the deep content prompts (problem statement, success criteria,
|
|
@@ -39,32 +39,32 @@ const DEFAULT_CONVENTIONS = "TypeScript strict mode, no any types, no console.lo
|
|
|
39
39
|
*/
|
|
40
40
|
export async function collectDeepContent() {
|
|
41
41
|
const problemInput = await p.text({
|
|
42
|
-
message: "What
|
|
43
|
-
placeholder: "
|
|
42
|
+
message: "What pain point does this solve for your users?",
|
|
43
|
+
placeholder: "Managing tasks across multiple tools is chaotic",
|
|
44
44
|
defaultValue: DEFAULT_DEFERRED,
|
|
45
45
|
});
|
|
46
46
|
handleCancel(problemInput);
|
|
47
47
|
const criteriaInput = await p.text({
|
|
48
|
-
message: "
|
|
49
|
-
placeholder: "
|
|
48
|
+
message: "What does success look like for your users?",
|
|
49
|
+
placeholder: "They can manage a full sprint in under 10 minutes a day",
|
|
50
50
|
defaultValue: DEFAULT_DEFERRED,
|
|
51
51
|
});
|
|
52
52
|
handleCancel(criteriaInput);
|
|
53
53
|
const valueInput = await p.text({
|
|
54
|
-
message: "
|
|
55
|
-
placeholder: "
|
|
54
|
+
message: "Why would someone use this over alternatives?",
|
|
55
|
+
placeholder: "Simpler than Jira, more structured than a spreadsheet",
|
|
56
56
|
defaultValue: DEFAULT_DEFERRED,
|
|
57
57
|
});
|
|
58
58
|
handleCancel(valueInput);
|
|
59
59
|
const scopeInput = await p.text({
|
|
60
|
-
message: "What
|
|
61
|
-
placeholder: "
|
|
60
|
+
message: "What are you NOT building in the first version?",
|
|
61
|
+
placeholder: "Mobile app, billing, admin dashboard",
|
|
62
62
|
defaultValue: DEFAULT_DEFERRED,
|
|
63
63
|
});
|
|
64
64
|
handleCancel(scopeInput);
|
|
65
65
|
const conventionsInput = await p.text({
|
|
66
|
-
message: "Any
|
|
67
|
-
placeholder: "TypeScript strict, ESLint, Prettier
|
|
66
|
+
message: "Any coding rules you want enforced?",
|
|
67
|
+
placeholder: "TypeScript strict, ESLint, Prettier",
|
|
68
68
|
defaultValue: DEFAULT_CONVENTIONS,
|
|
69
69
|
});
|
|
70
70
|
handleCancel(conventionsInput);
|
|
@@ -85,25 +85,25 @@ export async function collectDeepContent() {
|
|
|
85
85
|
*/
|
|
86
86
|
export async function collectProjectBrief(options = {}) {
|
|
87
87
|
const projectName = await p.text({
|
|
88
|
-
message: "
|
|
89
|
-
placeholder: "my-
|
|
88
|
+
message: "Name your project",
|
|
89
|
+
placeholder: "my-saas-app",
|
|
90
90
|
validate: validateProjectName,
|
|
91
91
|
});
|
|
92
92
|
handleCancel(projectName);
|
|
93
93
|
const description = await p.text({
|
|
94
|
-
message: "
|
|
95
|
-
placeholder: "A
|
|
94
|
+
message: "What are you building? (one line)",
|
|
95
|
+
placeholder: "A project management tool for remote teams",
|
|
96
96
|
validate: requireNonEmpty,
|
|
97
97
|
});
|
|
98
98
|
handleCancel(description);
|
|
99
99
|
const targetUsers = await p.text({
|
|
100
|
-
message: "Who
|
|
100
|
+
message: "Who is this for?",
|
|
101
101
|
placeholder: "Developers, small teams, freelancers",
|
|
102
102
|
validate: requireNonEmpty,
|
|
103
103
|
});
|
|
104
104
|
handleCancel(targetUsers);
|
|
105
105
|
const techStack = await p.select({
|
|
106
|
-
message: "
|
|
106
|
+
message: "Pick your tech stack",
|
|
107
107
|
options: [
|
|
108
108
|
{
|
|
109
109
|
value: "nextjs-supabase",
|
|
@@ -154,7 +154,7 @@ export async function collectProjectBrief(options = {}) {
|
|
|
154
154
|
let customStack;
|
|
155
155
|
if (techStack === "custom") {
|
|
156
156
|
const customStackInput = await p.text({
|
|
157
|
-
message: "
|
|
157
|
+
message: "What tools and frameworks are you using?",
|
|
158
158
|
placeholder: "Django + PostgreSQL + React frontend",
|
|
159
159
|
validate: requireNonEmpty,
|
|
160
160
|
});
|
|
@@ -175,10 +175,9 @@ export async function collectProjectBrief(options = {}) {
|
|
|
175
175
|
codeConventions = deep.codeConventions;
|
|
176
176
|
}
|
|
177
177
|
const outputDirectory = await p.text({
|
|
178
|
-
message: "
|
|
178
|
+
message: "Project folder",
|
|
179
179
|
defaultValue: `./${projectName}`,
|
|
180
180
|
placeholder: `./${projectName}`,
|
|
181
|
-
validate: requireNonEmpty,
|
|
182
181
|
});
|
|
183
182
|
handleCancel(outputDirectory);
|
|
184
183
|
return {
|
package/dist/cli/prompts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAGpC;;GAEG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,yBAAyB,CAAC;IACnC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,2BAA2B,CAAC;IACrC,CAAC;IACD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,OAAO,qEAAqE,CAAC;IAC/E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,CAAC,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAqBD,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/cli/prompts.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# Developer Agent Memory — {{PROJECT_NAME}}
|
|
2
2
|
|
|
3
|
-
*Read at session start. Update at session end
|
|
3
|
+
*Read at session start. Update at session end.*
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
7
|
+
## Active Decisions
|
|
8
|
+
<!-- Architecture or implementation decisions in progress -->
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
10
|
+
## Codebase Map
|
|
11
|
+
<!-- Key files and where things live — build this incrementally as you work -->
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
|
|
13
|
+
## Patterns Found
|
|
14
|
+
<!-- Naming conventions, component patterns, API patterns established here -->
|
|
15
15
|
|
|
16
|
-
## Watch Out
|
|
17
|
-
|
|
16
|
+
## Watch Out
|
|
17
|
+
<!-- Bugs caused, gotchas, things that break easily in this codebase -->
|
|
18
18
|
|
|
19
|
-
##
|
|
20
|
-
|
|
19
|
+
## Session Log
|
|
20
|
+
<!-- Reverse-chronological: date, slices worked on, files changed, state left in -->
|
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
# PM Agent Memory — {{PROJECT_NAME}}
|
|
2
2
|
|
|
3
|
-
*Read at session start. Update at session end
|
|
3
|
+
*Read at session start. Update at session end.*
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
7
|
+
## Active Decisions
|
|
8
|
+
<!-- Decisions in progress — move to decisions.md once finalized -->
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
- Last slice added: —
|
|
13
|
-
- Current epic focus: —
|
|
10
|
+
## Patterns Found
|
|
11
|
+
<!-- How the user likes tasks sliced, naming preferences, detail level that works -->
|
|
14
12
|
|
|
15
|
-
##
|
|
16
|
-
|
|
13
|
+
## Watch Out
|
|
14
|
+
<!-- Things that caused problems, edge cases, constraints discovered -->
|
|
17
15
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## Watch Out For
|
|
22
|
-
[Things that caused problems, edge cases to keep in mind]
|
|
16
|
+
## Session Log
|
|
17
|
+
<!-- Reverse-chronological: date, what was done, what was left incomplete, key decisions -->
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# Tester Agent Memory — {{PROJECT_NAME}}
|
|
2
2
|
|
|
3
|
-
*Read at session start. Update at session end
|
|
3
|
+
*Read at session start. Update at session end.*
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
7
|
+
## Active Decisions
|
|
8
|
+
<!-- Testing approach decisions in progress -->
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
10
|
+
## Patterns Found
|
|
11
|
+
<!-- Recurring check patterns, project-specific DoD quirks -->
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
- Total failed: 0
|
|
13
|
+
## Watch Out
|
|
14
|
+
<!-- Checks that keep failing, things developers keep getting wrong -->
|
|
16
15
|
|
|
17
|
-
##
|
|
18
|
-
|
|
16
|
+
## Session Log
|
|
17
|
+
<!-- Reverse-chronological: date, slices validated, pass/fail results, issues found -->
|
|
@@ -35,6 +35,12 @@ Only write files listed under "What I Own".
|
|
|
35
35
|
When a task is ready for testing, message @meto-tester directly (e.g., "tell @meto-tester slice-X is in testing").
|
|
36
36
|
Never write to `/ai/backlog/`, `/ai/context/`, `tasks-backlog.md`, `tasks-todo.md`, or `tasks-done.md`.
|
|
37
37
|
|
|
38
|
+
## Context Budget
|
|
39
|
+
- Grep before reading — only open files you need
|
|
40
|
+
- Use targeted line ranges for long files
|
|
41
|
+
- Max 3 files open before acting — note key info in memory
|
|
42
|
+
- Check Codebase Map in your memory file before reading files — it may already have what you need
|
|
43
|
+
|
|
38
44
|
## Task Pickup Protocol
|
|
39
45
|
1. Read `tasks-todo.md` — take TOP item
|
|
40
46
|
2. Copy full task block to `tasks-in-progress.md`, add `Started: [date]`
|
|
@@ -44,6 +44,12 @@ Only write files listed under "What I Own".
|
|
|
44
44
|
If you need developer or tester action, message them directly (e.g., "tell @meto-developer the backlog is ready").
|
|
45
45
|
Never write to `/src/`, `tasks-in-progress.md`, `tasks-in-testing.md`, or `tasks-done.md`.
|
|
46
46
|
|
|
47
|
+
## Context Budget
|
|
48
|
+
- Grep before reading — only open files you need
|
|
49
|
+
- Use targeted line ranges for long files
|
|
50
|
+
- Max 3 files open before acting — note key info in memory
|
|
51
|
+
- Read each epic once, then work from memory — don't re-read `/ai/backlog/epics.md` every task
|
|
52
|
+
|
|
47
53
|
## Task Definition Format
|
|
48
54
|
|
|
49
55
|
```markdown
|
|
@@ -35,6 +35,12 @@ When validation is complete, message the lead or @meto-developer directly with t
|
|
|
35
35
|
Never write to `/src/`, `/ai/backlog/`, `/ai/context/`, `tasks-backlog.md`, or `tasks-in-progress.md`.
|
|
36
36
|
Process items sequentially even when other agents run in parallel.
|
|
37
37
|
|
|
38
|
+
## Context Budget
|
|
39
|
+
- Grep before reading — only open files you need
|
|
40
|
+
- Use targeted line ranges for long files
|
|
41
|
+
- Max 3 files open before acting — note key info in memory
|
|
42
|
+
- Only read files listed in "Files changed" on the task block — don't explore the whole codebase
|
|
43
|
+
|
|
38
44
|
## Validation Protocol
|
|
39
45
|
ONE item at a time — parallel writes corrupt the board. Always sequential.
|
|
40
46
|
|
package/templates/CLAUDE.md
CHANGED
|
@@ -64,6 +64,16 @@ Teammates do NOT inherit the lead's conversation history. Each teammate reads CL
|
|
|
64
64
|
|
|
65
65
|
---
|
|
66
66
|
|
|
67
|
+
## Context Management
|
|
68
|
+
|
|
69
|
+
- **Session cadence:** Start a new session every 3-5 slices or when context feels sluggish
|
|
70
|
+
- **Session start:** Read CLAUDE.md, your agent memory file, and the board — then act
|
|
71
|
+
- **Session end:** Update your memory file with decisions, patterns, and what to pick up next
|
|
72
|
+
- **Context budget:** Grep before reading full files; read targeted line ranges; max 3 files open before acting
|
|
73
|
+
- **Red flag:** If you re-read a file you already read this session, note key info in memory instead
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
67
77
|
## Commit Format
|
|
68
78
|
|
|
69
79
|
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Session Checkpoint
|
|
2
|
+
|
|
3
|
+
Write this at session end. Paste it into the next session's first message.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Checkpoint Template
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
## Session Checkpoint — [date]
|
|
11
|
+
|
|
12
|
+
### Completed
|
|
13
|
+
- [slice-XXX] — description — PASS/IN-TESTING
|
|
14
|
+
|
|
15
|
+
### In Progress
|
|
16
|
+
- [slice-XXX] — description — what's left
|
|
17
|
+
|
|
18
|
+
### Decisions Made
|
|
19
|
+
- [decision] — rationale (move to decisions.md if permanent)
|
|
20
|
+
|
|
21
|
+
### Files Changed
|
|
22
|
+
- `path/to/file` — what changed
|
|
23
|
+
|
|
24
|
+
### Blocked On
|
|
25
|
+
- [blocker] — who/what can unblock
|
|
26
|
+
|
|
27
|
+
### Next Session Should
|
|
28
|
+
1. [first action]
|
|
29
|
+
2. [second action]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Session Resume Protocol
|
|
35
|
+
|
|
36
|
+
1. Paste the checkpoint into your first message
|
|
37
|
+
2. Read CLAUDE.md and your agent memory file
|
|
38
|
+
3. Read the board (`tasks-todo.md`, `tasks-in-progress.md`, `tasks-in-testing.md`)
|
|
39
|
+
4. Pick up where the checkpoint says — don't re-read files already summarized
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## When to Force a New Session
|
|
44
|
+
|
|
45
|
+
- Context feels sluggish (repeating yourself, forgetting earlier decisions)
|
|
46
|
+
- 3-5 slices completed since last fresh session
|
|
47
|
+
- Switching between agents (PM → Developer → Tester)
|
|
48
|
+
- After a major refactor or architecture change
|
|
49
|
+
- When the checkpoint itself exceeds 30 lines
|