guild-agents 0.2.9 → 0.3.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 +68 -102
- package/bin/guild.js +1 -1
- package/package.json +12 -10
- package/src/commands/doctor.js +6 -0
- package/src/commands/init.js +21 -16
- package/src/commands/list.js +3 -18
- package/src/commands/new-agent.js +3 -0
- package/src/commands/status.js +2 -3
- package/src/templates/skills/build-feature/SKILL.md +166 -10
- package/src/templates/skills/council/SKILL.md +30 -0
- package/src/templates/skills/create-pr/SKILL.md +100 -0
- package/src/templates/specs/SPEC_TEMPLATE.md +46 -0
- package/src/utils/files.js +71 -13
- package/src/utils/generators.js +70 -4
package/README.md
CHANGED
|
@@ -5,37 +5,25 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
|
|
8
|
-
Claude Code
|
|
8
|
+
**Guild makes Claude Code think before it builds.**
|
|
9
9
|
|
|
10
|
-
Guild is
|
|
10
|
+
Guild is a spec-driven development CLI for Claude Code. It installs structured design and development workflows as `.claude/` markdown files in any project. Before code is written, features are evaluated, debated by independent AI perspectives, and specified in a design doc. Everything is markdown, tracked by git, works offline, zero infrastructure.
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## The Problem
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
- **Agents = WHO, Skills = HOW.** Agents are flat `.md` files with identity and expertise. Skills are workflow definitions invoked as slash commands. Clean separation, no magic.
|
|
16
|
-
- **State that persists.** Context lives in `CLAUDE.md`, `PROJECT.md`, and `SESSION.md` -- tracked by git, readable by humans, never lost between sessions.
|
|
17
|
-
- **Zero infrastructure.** No servers, no APIs, no config files. Just markdown files that Claude Code reads natively.
|
|
14
|
+
Without structure, Claude Code:
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
- Writes code before understanding the problem
|
|
17
|
+
- Has no design phase and no review gate
|
|
18
|
+
- Loses decisions between sessions
|
|
19
|
+
- Produces results that vary with every conversation
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
You ──> /build-feature "Add JWT auth"
|
|
23
|
-
│
|
|
24
|
-
▼
|
|
25
|
-
┌─────────┐ ┌───────────────┐ ┌───────────────┐
|
|
26
|
-
│ Advisor │────>│ Tech Lead │────>│ Developer │
|
|
27
|
-
│ evaluate │ │ plan │ │ implement │
|
|
28
|
-
└─────────┘ └───────────────┘ └───────┬───────┘
|
|
29
|
-
│
|
|
30
|
-
┌─────────────┼─────────────┐
|
|
31
|
-
▼ ▼ ▼
|
|
32
|
-
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
33
|
-
│ Reviewer │ │ QA │ │ Bugfix │
|
|
34
|
-
│ review │ │ test │ │ fix │
|
|
35
|
-
└──────────┘ └──────────┘ └──────────┘
|
|
36
|
-
```
|
|
21
|
+
## How Guild Solves It
|
|
37
22
|
|
|
38
|
-
|
|
23
|
+
- **Spec before code**: every feature starts with a design doc
|
|
24
|
+
- **Structured deliberation**: `/council` runs parallel independent analysis -- multiple perspectives evaluate independently, then synthesize
|
|
25
|
+
- **Decisions that persist**: design docs, session state, and project context live in git-tracked markdown
|
|
26
|
+
- **Zero infrastructure**: no servers, no APIs, just markdown files and Claude Code
|
|
39
27
|
|
|
40
28
|
## Quick Start
|
|
41
29
|
|
|
@@ -44,28 +32,68 @@ npm install -g guild-agents
|
|
|
44
32
|
guild init
|
|
45
33
|
```
|
|
46
34
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
Next, let Guild learn your codebase:
|
|
35
|
+
Then use skills as slash commands in Claude Code:
|
|
50
36
|
|
|
37
|
+
```text
|
|
38
|
+
/guild-specialize # Learn your codebase, enrich CLAUDE.md
|
|
39
|
+
/council "Add JWT auth" # Spec a feature through structured deliberation
|
|
40
|
+
/build-feature # Implement from spec through the full pipeline
|
|
51
41
|
```
|
|
52
|
-
|
|
42
|
+
|
|
43
|
+
## The Pipeline
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
You ──> /council "Add JWT auth"
|
|
47
|
+
│
|
|
48
|
+
▼
|
|
49
|
+
┌──────────┐ ┌──────────────┐ ┌──────────┐
|
|
50
|
+
│ Evaluate │────>│ Design Doc │────>│ Build │
|
|
51
|
+
│ debate │ │ spec │ │ implement│
|
|
52
|
+
└──────────┘ └──────────────┘ └────┬─────┘
|
|
53
|
+
│
|
|
54
|
+
┌─────┴─────┐
|
|
55
|
+
▼ ▼
|
|
56
|
+
┌──────────┐┌──────────┐
|
|
57
|
+
│ Review ││ QA │
|
|
58
|
+
└──────────┘└──────────┘
|
|
53
59
|
```
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
Six phases: **evaluate**, **specify**, **plan**, **implement**, **review**, **validate**. Phases 1-3 happen before any code is written.
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
## Skills Reference
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
All 11 skills, grouped by function:
|
|
66
|
+
|
|
67
|
+
| Skill | Group | Description |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| `/build-feature` | Pipeline | Full pipeline: evaluate, spec, implement, review, QA |
|
|
70
|
+
| `/new-feature` | Pipeline | Create branch and scaffold for a new feature |
|
|
71
|
+
| `/create-pr` | Pipeline | Create a structured pull request from current branch |
|
|
72
|
+
| `/council` | Decision | Multi-perspective deliberation on a decision or feature |
|
|
73
|
+
| `/review` | Quality | Code review on the current diff |
|
|
74
|
+
| `/qa-cycle` | Quality | QA and bugfix loop until clean |
|
|
75
|
+
| `/guild-specialize` | Context | Explore codebase, enrich CLAUDE.md with real conventions |
|
|
76
|
+
| `/session-start` | Context | Load context and resume work |
|
|
77
|
+
| `/session-end` | Context | Save state to SESSION.md |
|
|
78
|
+
| `/status` | Context | Project and session state overview |
|
|
79
|
+
| `/dev-flow` | Context | Show current pipeline phase and next step |
|
|
80
|
+
|
|
81
|
+
## CLI Commands
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
guild init # Interactive project onboarding
|
|
85
|
+
guild new-agent <name> # Create a custom agent
|
|
86
|
+
guild status # Show project status
|
|
87
|
+
guild doctor # Diagnose setup
|
|
88
|
+
guild list # List agents and skills
|
|
61
89
|
```
|
|
62
90
|
|
|
63
|
-
|
|
91
|
+
## Under the Hood
|
|
64
92
|
|
|
65
|
-
|
|
93
|
+
Guild coordinates 9 specialized agents through the pipeline. Each agent handles one phase.
|
|
66
94
|
|
|
67
95
|
| Agent | Role |
|
|
68
|
-
|
|
96
|
+
| --- | --- |
|
|
69
97
|
| advisor | Evaluates ideas and provides strategic direction |
|
|
70
98
|
| product-owner | Turns approved ideas into concrete tasks |
|
|
71
99
|
| tech-lead | Defines technical approach and architecture |
|
|
@@ -74,70 +102,13 @@ This runs the full pipeline -- advisor evaluation, tech lead planning, developer
|
|
|
74
102
|
| qa | Testing, edge cases, regression validation |
|
|
75
103
|
| bugfix | Bug diagnosis and resolution |
|
|
76
104
|
| db-migration | Schema changes and safe migrations |
|
|
77
|
-
| platform-expert | Diagnoses
|
|
78
|
-
|
|
79
|
-
## Skills
|
|
80
|
-
|
|
81
|
-
| Skill | Description |
|
|
82
|
-
|---|---|
|
|
83
|
-
| `/guild-specialize` | Explores codebase, enriches CLAUDE.md with real stack and conventions |
|
|
84
|
-
| `/build-feature` | Full pipeline: evaluation, spec, implementation, review, QA |
|
|
85
|
-
| `/new-feature` | Creates branch and scaffold for a new feature |
|
|
86
|
-
| `/council` | Convenes multiple agents to debate a decision |
|
|
87
|
-
| `/qa-cycle` | QA and bugfix loop until clean |
|
|
88
|
-
| `/review` | Code review on the current diff |
|
|
89
|
-
| `/dev-flow` | Shows current pipeline phase and next step |
|
|
90
|
-
| `/status` | Project and session state overview |
|
|
91
|
-
| `/session-start` | Loads context and resumes work |
|
|
92
|
-
| `/session-end` | Saves state to SESSION.md |
|
|
93
|
-
|
|
94
|
-
## CLI Commands
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
guild init # Interactive project onboarding
|
|
98
|
-
guild new-agent <name> # Create a custom agent
|
|
99
|
-
guild status # Show project status
|
|
100
|
-
guild doctor # Diagnose installation state
|
|
101
|
-
guild list # List installed agents and skills
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Generated Structure
|
|
105
|
+
| platform-expert | Diagnoses Claude Code integration issues |
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
CLAUDE.md
|
|
110
|
-
PROJECT.md
|
|
111
|
-
SESSION.md
|
|
112
|
-
.claude/
|
|
113
|
-
agents/
|
|
114
|
-
advisor.md
|
|
115
|
-
product-owner.md
|
|
116
|
-
tech-lead.md
|
|
117
|
-
developer.md
|
|
118
|
-
code-reviewer.md
|
|
119
|
-
qa.md
|
|
120
|
-
bugfix.md
|
|
121
|
-
db-migration.md
|
|
122
|
-
platform-expert.md
|
|
123
|
-
skills/
|
|
124
|
-
guild-specialize/SKILL.md
|
|
125
|
-
build-feature/SKILL.md
|
|
126
|
-
new-feature/SKILL.md
|
|
127
|
-
council/SKILL.md
|
|
128
|
-
qa-cycle/SKILL.md
|
|
129
|
-
review/SKILL.md
|
|
130
|
-
dev-flow/SKILL.md
|
|
131
|
-
status/SKILL.md
|
|
132
|
-
session-start/SKILL.md
|
|
133
|
-
session-end/SKILL.md
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
All files are markdown, tracked by git, and work fully offline.
|
|
107
|
+
Agents are flat `.md` files with identity and expertise. Skills orchestrate agents through structured pipelines. Everything lives in `.claude/`, readable by humans, tracked by git.
|
|
137
108
|
|
|
138
109
|
## Guild Builds Itself
|
|
139
110
|
|
|
140
|
-
|
|
111
|
+
Every feature in Guild goes through the same spec-first pipeline that Guild installs in your project. Guild's own design decisions live in `docs/specs/`.
|
|
141
112
|
|
|
142
113
|
## Requirements
|
|
143
114
|
|
|
@@ -147,12 +118,7 @@ This project uses its own agents and skills to develop itself. Every feature, re
|
|
|
147
118
|
|
|
148
119
|
## Contributing
|
|
149
120
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
- **Agent and skill templates** (`src/templates/`) -- improve agent definitions or skill workflows.
|
|
153
|
-
- **CLI code** (`src/`, `bin/`) -- bug fixes, new commands, onboarding improvements.
|
|
154
|
-
|
|
155
|
-
See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for details.
|
|
121
|
+
See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for setup, branching, and contribution guidelines.
|
|
156
122
|
|
|
157
123
|
## License
|
|
158
124
|
|
package/bin/guild.js
CHANGED
|
@@ -20,7 +20,7 @@ const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'))
|
|
|
20
20
|
|
|
21
21
|
program
|
|
22
22
|
.name('guild')
|
|
23
|
-
.description('
|
|
23
|
+
.description('Specification-driven development CLI for Claude Code')
|
|
24
24
|
.version(pkg.version);
|
|
25
25
|
|
|
26
26
|
// guild init
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guild-agents",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "Specification-driven development CLI for Claude Code — think before you build",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"bin/",
|
|
@@ -26,15 +26,16 @@
|
|
|
26
26
|
"keywords": [
|
|
27
27
|
"claude",
|
|
28
28
|
"claude-code",
|
|
29
|
+
"anthropic",
|
|
30
|
+
"specification-driven",
|
|
31
|
+
"spec-driven",
|
|
32
|
+
"spec-first",
|
|
33
|
+
"design-docs",
|
|
34
|
+
"developer-tools",
|
|
35
|
+
"cli",
|
|
29
36
|
"agents",
|
|
30
37
|
"ai",
|
|
31
38
|
"workflow",
|
|
32
|
-
"multi-agent",
|
|
33
|
-
"developer-tools",
|
|
34
|
-
"cli",
|
|
35
|
-
"framework",
|
|
36
|
-
"anthropic",
|
|
37
|
-
"ai-agents",
|
|
38
39
|
"automation",
|
|
39
40
|
"code-review",
|
|
40
41
|
"nodejs"
|
|
@@ -45,14 +46,15 @@
|
|
|
45
46
|
"type": "git",
|
|
46
47
|
"url": "git+https://github.com/guild-agents/guild.git"
|
|
47
48
|
},
|
|
48
|
-
"homepage": "https://
|
|
49
|
+
"homepage": "https://guildagents.dev",
|
|
49
50
|
"bugs": {
|
|
50
51
|
"url": "https://github.com/guild-agents/guild/issues"
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
54
|
"@clack/prompts": "^1.0.1",
|
|
54
55
|
"chalk": "^5.3.0",
|
|
55
|
-
"commander": "^14.0.3"
|
|
56
|
+
"commander": "^14.0.3",
|
|
57
|
+
"guild-agents": "^0.3.0"
|
|
56
58
|
},
|
|
57
59
|
"engines": {
|
|
58
60
|
"node": ">=20.0.0"
|
package/src/commands/doctor.js
CHANGED
|
@@ -6,8 +6,14 @@ import * as p from '@clack/prompts';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { existsSync, readdirSync } from 'fs';
|
|
8
8
|
import { join } from 'path';
|
|
9
|
+
import { resolveProjectRoot } from '../utils/files.js';
|
|
9
10
|
|
|
10
11
|
export async function runDoctor() {
|
|
12
|
+
const root = resolveProjectRoot();
|
|
13
|
+
if (root) {
|
|
14
|
+
process.chdir(root);
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
p.intro(chalk.bold.cyan('Guild — Doctor'));
|
|
12
18
|
|
|
13
19
|
const checks = [];
|
package/src/commands/init.js
CHANGED
|
@@ -13,7 +13,7 @@ import * as p from '@clack/prompts';
|
|
|
13
13
|
import chalk from 'chalk';
|
|
14
14
|
import { existsSync } from 'fs';
|
|
15
15
|
import { generateProjectMd, generateSessionMd, generateClaudeMd } from '../utils/generators.js';
|
|
16
|
-
import { copyTemplates, getAgentNames } from '../utils/files.js';
|
|
16
|
+
import { copyTemplates, getAgentNames, getSkillNames } from '../utils/files.js';
|
|
17
17
|
|
|
18
18
|
export async function runInit() {
|
|
19
19
|
console.log('');
|
|
@@ -122,19 +122,24 @@ export async function runInit() {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
// ─── Summary ──────────────────────────────────────────────────────────────
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
p.log.success(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
'
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
125
|
+
const agentCount = getAgentNames().length;
|
|
126
|
+
const skillCount = getSkillNames().length;
|
|
127
|
+
p.log.success(`Created: CLAUDE.md, PROJECT.md, SESSION.md, ${agentCount} agents, ${skillCount} skills`);
|
|
128
|
+
|
|
129
|
+
const relevantSkills = projectData.hasExistingCode
|
|
130
|
+
? ['/guild-specialize', '/council', '/build-feature']
|
|
131
|
+
: ['/council', '/build-feature', '/new-feature'];
|
|
132
|
+
p.log.info(`Start with: ${relevantSkills.join(' ')}`);
|
|
133
|
+
|
|
134
|
+
const quickStart = projectData.hasExistingCode
|
|
135
|
+
? '1. Run /guild-specialize to analyze your codebase\n' +
|
|
136
|
+
'2. Run /council to spec your first feature\n' +
|
|
137
|
+
'3. Build it with /build-feature'
|
|
138
|
+
: '1. Run /council to spec your first feature\n' +
|
|
139
|
+
'2. Build it with /build-feature\n' +
|
|
140
|
+
'3. Run /guild-specialize once you have code';
|
|
141
|
+
|
|
142
|
+
p.note(quickStart, 'Quick start');
|
|
143
|
+
|
|
144
|
+
p.outro(chalk.bold.cyan('Guild ready — spec before you build.'));
|
|
140
145
|
}
|
package/src/commands/list.js
CHANGED
|
@@ -6,26 +6,11 @@ import * as p from '@clack/prompts';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
8
8
|
import { join } from 'path';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Parses YAML frontmatter from a markdown file content.
|
|
12
|
-
* Returns an object with key-value pairs from the frontmatter.
|
|
13
|
-
*/
|
|
14
|
-
function parseFrontmatter(content) {
|
|
15
|
-
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
16
|
-
if (!match) return {};
|
|
17
|
-
const fm = {};
|
|
18
|
-
for (const line of match[1].split('\n')) {
|
|
19
|
-
const colonIndex = line.indexOf(':');
|
|
20
|
-
if (colonIndex === -1) continue;
|
|
21
|
-
const key = line.slice(0, colonIndex).trim();
|
|
22
|
-
const value = line.slice(colonIndex + 1).trim().replace(/^["']|["']$/g, '');
|
|
23
|
-
if (key && value) fm[key] = value;
|
|
24
|
-
}
|
|
25
|
-
return fm;
|
|
26
|
-
}
|
|
9
|
+
import { ensureProjectRoot, parseFrontmatter } from '../utils/files.js';
|
|
27
10
|
|
|
28
11
|
export async function runList() {
|
|
12
|
+
ensureProjectRoot();
|
|
13
|
+
|
|
29
14
|
p.intro(chalk.bold.cyan('Guild — Agents & Skills'));
|
|
30
15
|
|
|
31
16
|
// List agents
|
|
@@ -13,10 +13,13 @@ import * as p from '@clack/prompts';
|
|
|
13
13
|
import chalk from 'chalk';
|
|
14
14
|
import { existsSync, writeFileSync } from 'fs';
|
|
15
15
|
import { join } from 'path';
|
|
16
|
+
import { ensureProjectRoot } from '../utils/files.js';
|
|
16
17
|
|
|
17
18
|
const AGENTS_DIR = join('.claude', 'agents');
|
|
18
19
|
|
|
19
20
|
export async function runNewAgent(agentName) {
|
|
21
|
+
ensureProjectRoot();
|
|
22
|
+
|
|
20
23
|
p.intro(chalk.bold.cyan('Guild — New agent'));
|
|
21
24
|
|
|
22
25
|
// Validate name
|
package/src/commands/status.js
CHANGED
|
@@ -6,11 +6,10 @@ import * as p from '@clack/prompts';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
8
8
|
import { join } from 'path';
|
|
9
|
+
import { ensureProjectRoot } from '../utils/files.js';
|
|
9
10
|
|
|
10
11
|
export async function runStatus() {
|
|
11
|
-
|
|
12
|
-
throw new Error('Guild is not installed. Run: guild init');
|
|
13
|
-
}
|
|
12
|
+
ensureProjectRoot();
|
|
14
13
|
|
|
15
14
|
const projectMd = readFileSync('PROJECT.md', 'utf8');
|
|
16
15
|
const nameMatch = projectMd.match(/\*\*Name:\*\*\s*(.+)/);
|
|
@@ -35,8 +35,31 @@ When running a single build-feature, a simple `git checkout -b` is sufficient.
|
|
|
35
35
|
|
|
36
36
|
## 6-Phase Pipeline
|
|
37
37
|
|
|
38
|
+
### Progress Display
|
|
39
|
+
|
|
40
|
+
At the start of each phase, display a progress indicator to the user before any agent output:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
[1/6] Advisor — Evaluating feature...
|
|
44
|
+
[2/6] Product Owner — Defining spec...
|
|
45
|
+
[3/6] Tech Lead — Defining technical approach...
|
|
46
|
+
[4/6] Developer — Implementing...
|
|
47
|
+
[5/6] Code Reviewer — Reviewing changes...
|
|
48
|
+
[6/6] QA — Validating acceptance criteria...
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
When a phase loops (review-fix or QA-review cycles), show the iteration:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
[5/6 · round 2] Code Reviewer — Re-reviewing after fixes...
|
|
55
|
+
[4/6 · round 2] Developer — Fixing review blockers...
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This indicator MUST be displayed before spawning the agent for that phase.
|
|
59
|
+
|
|
38
60
|
### Phase 1 — Evaluation (Advisor)
|
|
39
61
|
|
|
62
|
+
**Progress:** `[1/6] Advisor — Evaluating feature...`
|
|
40
63
|
**Agent:** Reads `.claude/agents/advisor.md` via Task tool
|
|
41
64
|
**Input:** The feature description provided by the user
|
|
42
65
|
**Process:**
|
|
@@ -46,10 +69,12 @@ When running a single build-feature, a simple `git checkout -b` is sufficient.
|
|
|
46
69
|
3. Issues evaluation: Approved / Rejected / Requires adjustments
|
|
47
70
|
|
|
48
71
|
**Output:** Evaluation with reasoning and identified risks
|
|
72
|
+
**Trace data:** Verdict (Approved/Rejected/Approved with conditions), risks identified, conditions if any
|
|
49
73
|
**Exit condition:** If the Advisor rejects the feature, the pipeline stops here. Inform the user of the reason and suggest adjustments if any.
|
|
50
74
|
|
|
51
75
|
### Phase 2 — Specification (Product Owner)
|
|
52
76
|
|
|
77
|
+
**Progress:** `[2/6] Product Owner — Defining spec...`
|
|
53
78
|
**Agent:** Reads `.claude/agents/product-owner.md` via Task tool
|
|
54
79
|
**Input:** The feature approved by the Advisor + their observations
|
|
55
80
|
**Process:**
|
|
@@ -59,9 +84,11 @@ When running a single build-feature, a simple `git checkout -b` is sufficient.
|
|
|
59
84
|
3. Estimates effort and suggests implementation order
|
|
60
85
|
|
|
61
86
|
**Output:** Task list with acceptance criteria, estimation, and order
|
|
87
|
+
**Trace data:** Tasks defined count, acceptance criteria count, estimated effort
|
|
62
88
|
|
|
63
89
|
### Phase 3 — Technical Approach (Tech Lead)
|
|
64
90
|
|
|
91
|
+
**Progress:** `[3/6] Tech Lead — Defining technical approach...`
|
|
65
92
|
**Agent:** Reads `.claude/agents/tech-lead.md` via Task tool
|
|
66
93
|
**Input:** Product Owner tasks + acceptance criteria
|
|
67
94
|
**Process:**
|
|
@@ -71,9 +98,11 @@ When running a single build-feature, a simple `git checkout -b` is sufficient.
|
|
|
71
98
|
3. Anticipates technical risks and proposes mitigations
|
|
72
99
|
|
|
73
100
|
**Output:** Technical plan with files, patterns, interfaces, and risks
|
|
101
|
+
**Trace data:** Key patterns identified, files to modify, technical risks
|
|
74
102
|
|
|
75
103
|
### Phase 4 — Implementation (Developer)
|
|
76
104
|
|
|
105
|
+
**Progress:** `[4/6] Developer — Implementing...`
|
|
77
106
|
**Agent:** Reads `.claude/agents/developer.md` via Task tool
|
|
78
107
|
**Input:** Tech Lead technical plan + PO acceptance criteria
|
|
79
108
|
**Process:**
|
|
@@ -84,6 +113,7 @@ When running a single build-feature, a simple `git checkout -b` is sufficient.
|
|
|
84
113
|
4. Verifies that tests pass
|
|
85
114
|
|
|
86
115
|
**Output:** Implemented code + tests + commits made
|
|
116
|
+
**Trace data:** Files created/modified, tests added, commits made
|
|
87
117
|
|
|
88
118
|
### Pre-Review Gate (mandatory)
|
|
89
119
|
|
|
@@ -95,8 +125,11 @@ Before advancing to Phase 5, run automated verification:
|
|
|
95
125
|
|
|
96
126
|
This gate CANNOT be skipped, even if the user requested phase skipping. The specific commands are in the "CLI commands" section of CLAUDE.md.
|
|
97
127
|
|
|
128
|
+
**Trace data:** Tests pass/fail, lint pass/fail
|
|
129
|
+
|
|
98
130
|
### Phase 5 — Review (Code Reviewer)
|
|
99
131
|
|
|
132
|
+
**Progress:** `[5/6] Code Reviewer — Reviewing changes...`
|
|
100
133
|
**Agent:** Reads `.claude/agents/code-reviewer.md` via Task tool
|
|
101
134
|
**Input:** The implemented changes (git diff)
|
|
102
135
|
**Process:**
|
|
@@ -105,10 +138,13 @@ This gate CANNOT be skipped, even if the user requested phase skipping. The spec
|
|
|
105
138
|
2. Classifies findings as Blocker, Warning, or Suggestion
|
|
106
139
|
|
|
107
140
|
**Output:** Review report with classified findings
|
|
141
|
+
**Trace data:** Blockers count, warnings count, suggestions count, review-fix loops
|
|
108
142
|
**Loop condition:** If there are Blocker findings, return to **Phase 4** for the Developer to fix them. Maximum 2 review-fix iterations.
|
|
109
143
|
|
|
110
144
|
### Phase 6 — QA (delegates to /qa-cycle)
|
|
111
145
|
|
|
146
|
+
**Progress:** `[6/6] QA — Validating acceptance criteria...`
|
|
147
|
+
|
|
112
148
|
Runs the `/qa-cycle` skill passing the PO acceptance criteria as context. The qa-cycle handles:
|
|
113
149
|
|
|
114
150
|
1. Running project tests and lint
|
|
@@ -116,6 +152,7 @@ Runs the `/qa-cycle` skill passing the PO acceptance criteria as context. The qa
|
|
|
116
152
|
3. Testing edge cases and error scenarios
|
|
117
153
|
4. Bugfix cycle if issues arise (maximum 3 cycles)
|
|
118
154
|
|
|
155
|
+
**Trace data:** Acceptance criteria verified count, bugs found, QA cycles
|
|
119
156
|
**Additional loop condition:** If the qa-cycle bugfix introduces significant changes, return to **Phase 5** (Review) for verification. Maximum 2 review-QA cycles.
|
|
120
157
|
|
|
121
158
|
## Checkpoint Commits
|
|
@@ -132,7 +169,7 @@ Pattern for each phase:
|
|
|
132
169
|
- After Phase 1: `wip: [feature] phase 1 — advisor approved`
|
|
133
170
|
- After Phase 2: `wip: [feature] phase 2 — PO spec ready`
|
|
134
171
|
- After Phase 3: `wip: [feature] phase 3 — tech approach defined`
|
|
135
|
-
- After Phase 4: `wip: [feature] phase 4 — implementation done`
|
|
172
|
+
- After Phase 4: `wip: [feature] phase 4 — implementation done` -- also write partial trace (phases 1-4) to spec and update status to `implementing`
|
|
136
173
|
- After Phase 5: `wip: [feature] phase 5 — review passed`
|
|
137
174
|
- After Phase 6: `wip: [feature] phase 6 — QA passed`
|
|
138
175
|
|
|
@@ -142,6 +179,110 @@ Also update SESSION.md at each phase transition:
|
|
|
142
179
|
- [timestamp] | build-feature | Phase N ([phase-name]) complete for [feature]
|
|
143
180
|
```
|
|
144
181
|
|
|
182
|
+
## Pipeline Trace
|
|
183
|
+
|
|
184
|
+
After pipeline completion, append a `## Pipeline Trace` section to the feature's spec file in `docs/specs/`. This provides a structured record of what happened in each phase.
|
|
185
|
+
|
|
186
|
+
### Spec file discovery
|
|
187
|
+
|
|
188
|
+
1. Search `docs/specs/` for a file whose `spec-id` frontmatter matches the feature name (kebab-case)
|
|
189
|
+
2. If no matching spec exists, auto-create a minimal spec file at `docs/specs/[feature-name].md`
|
|
190
|
+
|
|
191
|
+
### Auto-created spec format
|
|
192
|
+
|
|
193
|
+
When no prior council spec exists, create a minimal spec:
|
|
194
|
+
|
|
195
|
+
````markdown
|
|
196
|
+
---
|
|
197
|
+
spec-id: [feature-name]
|
|
198
|
+
status: implementing
|
|
199
|
+
date: [YYYY-MM-DD]
|
|
200
|
+
council-type: none (pipeline-generated)
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
# Spec: [Feature Name]
|
|
204
|
+
|
|
205
|
+
## Context
|
|
206
|
+
|
|
207
|
+
Spec auto-generated by /build-feature pipeline. No prior council session.
|
|
208
|
+
|
|
209
|
+
## Pipeline Trace
|
|
210
|
+
|
|
211
|
+
[trace content appended here]
|
|
212
|
+
````
|
|
213
|
+
|
|
214
|
+
### Status field updates
|
|
215
|
+
|
|
216
|
+
- At Phase 4 checkpoint: set `status: implementing`
|
|
217
|
+
- At pipeline completion: set `status: implemented`
|
|
218
|
+
|
|
219
|
+
### Trace section format
|
|
220
|
+
|
|
221
|
+
Append this section to the spec file:
|
|
222
|
+
|
|
223
|
+
````markdown
|
|
224
|
+
## Pipeline Trace
|
|
225
|
+
|
|
226
|
+
pipeline-start: [YYYY-MM-DD]
|
|
227
|
+
pipeline-end: [YYYY-MM-DD]
|
|
228
|
+
phases-completed: [N]/6
|
|
229
|
+
review-fix-loops: [N]
|
|
230
|
+
qa-cycles: [N]
|
|
231
|
+
final-gate: pass | fail
|
|
232
|
+
|
|
233
|
+
### Phase 1 — Evaluation
|
|
234
|
+
|
|
235
|
+
- **Verdict**: [Approved/Rejected/Approved with conditions]
|
|
236
|
+
- **Risks identified**: [list or "None"]
|
|
237
|
+
|
|
238
|
+
### Phase 2 — Specification
|
|
239
|
+
|
|
240
|
+
- **Tasks defined**: [N]
|
|
241
|
+
- **Acceptance criteria**: [N]
|
|
242
|
+
- **Estimated effort**: [summary]
|
|
243
|
+
|
|
244
|
+
### Phase 3 — Technical Approach
|
|
245
|
+
|
|
246
|
+
- **Key patterns**: [list]
|
|
247
|
+
- **Files to modify**: [list]
|
|
248
|
+
- **Technical risks**: [list or "None"]
|
|
249
|
+
|
|
250
|
+
### Phase 4 — Implementation
|
|
251
|
+
|
|
252
|
+
- **Files created/modified**: [list]
|
|
253
|
+
- **Tests added**: [N]
|
|
254
|
+
- **Commits**: [list of commit summaries]
|
|
255
|
+
|
|
256
|
+
### Pre-Review Gate
|
|
257
|
+
|
|
258
|
+
- **Tests**: pass | fail
|
|
259
|
+
- **Lint**: pass | fail
|
|
260
|
+
|
|
261
|
+
### Phase 5 — Review
|
|
262
|
+
|
|
263
|
+
- **Blockers**: [N]
|
|
264
|
+
- **Warnings**: [N]
|
|
265
|
+
- **Suggestions**: [N]
|
|
266
|
+
- **Review-fix loops**: [N]
|
|
267
|
+
|
|
268
|
+
### Phase 6 — QA
|
|
269
|
+
|
|
270
|
+
- **Acceptance criteria verified**: [N]/[total]
|
|
271
|
+
- **Bugs found**: [N]
|
|
272
|
+
- **QA cycles**: [N]
|
|
273
|
+
|
|
274
|
+
### Final Gate
|
|
275
|
+
|
|
276
|
+
- **Tests**: pass | fail
|
|
277
|
+
- **Lint**: pass | fail
|
|
278
|
+
- **Result**: pass | fail
|
|
279
|
+
````
|
|
280
|
+
|
|
281
|
+
### When to write the trace
|
|
282
|
+
|
|
283
|
+
- **Phase 4 checkpoint:** Write a partial trace covering phases 1-4 to the spec file. Set status to `implementing`. Include the spec file in the checkpoint commit.
|
|
284
|
+
- **Pipeline completion:** Write the complete trace (all phases) to the spec file. Set status to `implemented`. Include the spec file in the final checkpoint commit.
|
|
285
|
+
|
|
145
286
|
## Final Gate (mandatory before Completion)
|
|
146
287
|
|
|
147
288
|
Before declaring the pipeline as complete, run final verification:
|
|
@@ -152,23 +293,27 @@ Before declaring the pipeline as complete, run final verification:
|
|
|
152
293
|
|
|
153
294
|
This gate is the last safety net. It CANNOT be skipped under any circumstances.
|
|
154
295
|
|
|
296
|
+
**Trace data:** Tests pass/fail, lint pass/fail, result (pass/fail)
|
|
297
|
+
|
|
155
298
|
## Completion
|
|
156
299
|
|
|
157
300
|
Upon successfully completing all phases and the final gate:
|
|
158
301
|
|
|
159
|
-
1.
|
|
302
|
+
1. Write the complete Pipeline Trace to the spec file (see "Pipeline Trace" section above). Update the spec status to `implemented`. Include the spec file in the final checkpoint commit.
|
|
303
|
+
|
|
304
|
+
2. Present pipeline summary:
|
|
160
305
|
- Feature implemented
|
|
161
306
|
- Files modified/created
|
|
162
307
|
- Tests run and result
|
|
163
308
|
- Review issues resolved
|
|
164
309
|
- Final QA result
|
|
165
310
|
|
|
166
|
-
|
|
311
|
+
3. Update `SESSION.md` with:
|
|
167
312
|
- Feature completed
|
|
168
313
|
- Decisions made during the pipeline
|
|
169
314
|
- Next steps if any
|
|
170
315
|
|
|
171
|
-
|
|
316
|
+
4. Close the GitHub Issue (if applicable):
|
|
172
317
|
- Do NOT use `Closes #N` in PR description (only works when merging to default branch)
|
|
173
318
|
- After the PR is merged, run: `gh issue close N --comment "Resolved in PR #X"`
|
|
174
319
|
|
|
@@ -197,12 +342,23 @@ Task tool with:
|
|
|
197
342
|
```text
|
|
198
343
|
User: /build-feature add dark mode toggle to settings page
|
|
199
344
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
345
|
+
[1/6] Advisor — Evaluating feature...
|
|
346
|
+
Approved. Low risk, aligns with UX roadmap.
|
|
347
|
+
|
|
348
|
+
[2/6] Product Owner — Defining spec...
|
|
349
|
+
3 tasks defined with acceptance criteria.
|
|
350
|
+
|
|
351
|
+
[3/6] Tech Lead — Defining technical approach...
|
|
352
|
+
Use CSS variables + context provider pattern.
|
|
353
|
+
|
|
354
|
+
[4/6] Developer — Implementing...
|
|
355
|
+
Implemented ThemeContext, toggle component, CSS vars.
|
|
356
|
+
|
|
357
|
+
[5/6] Code Reviewer — Reviewing changes...
|
|
358
|
+
Passed. 1 suggestion (memoize context value).
|
|
359
|
+
|
|
360
|
+
[6/6] QA — Validating acceptance criteria...
|
|
361
|
+
All 3 acceptance criteria verified. 0 bugs.
|
|
206
362
|
|
|
207
363
|
Feature complete. PR ready for merge.
|
|
208
364
|
```
|
|
@@ -111,6 +111,33 @@ Present clear options to the user based on the debate:
|
|
|
111
111
|
|
|
112
112
|
Ask the user to decide. If the user decides, document the decision in SESSION.md.
|
|
113
113
|
|
|
114
|
+
### Step 5 — Write Spec Document
|
|
115
|
+
|
|
116
|
+
After the user makes their decision in Step 4, offer to write a spec document to `docs/specs/`.
|
|
117
|
+
|
|
118
|
+
1. **Suggest filename**: Derive a kebab-case filename (3-5 words) from the council question. Present the suggested filename to the user for confirmation. Example: `docs/specs/graphql-migration-strategy.md`
|
|
119
|
+
2. **Create directory**: Create `docs/specs/` if it does not already exist.
|
|
120
|
+
3. **Read the spec template**: Read `src/templates/specs/SPEC_TEMPLATE.md` (or the project's local copy) to use as the structural guide.
|
|
121
|
+
4. **Assemble spec content**: Map the council debate to the template format:
|
|
122
|
+
- **Title**: From the council question
|
|
123
|
+
- **spec-id**: Matches the filename (without `.md`)
|
|
124
|
+
- **status**: Always `draft`
|
|
125
|
+
- **date**: Current date in `YYYY-MM-DD` format
|
|
126
|
+
- **council-type**: From Step 1 (architecture, feature-scope, or tech-debt)
|
|
127
|
+
- **Context**: From the council question and background provided by the user
|
|
128
|
+
- **Decision**: The user's chosen option from Step 4
|
|
129
|
+
- **Constraints**: Extracted from agent arguments during the debate
|
|
130
|
+
- **Acceptance Criteria**: Derived from the decision, as checkboxes (`- [ ]`)
|
|
131
|
+
- **Technical Approach**: Synthesis of implementation details from agents
|
|
132
|
+
- **Trade-offs Considered**: Options A/B/C from Step 4 with their pros and cons
|
|
133
|
+
- **Unresolved Questions**: Open risks and unknowns identified during debate
|
|
134
|
+
- **Test Strategy**: How to verify the implementation meets the acceptance criteria
|
|
135
|
+
- **Council Perspectives**: Summary of each agent's independent position
|
|
136
|
+
- **Points of Dissent**: Where agents disagreed and how it was resolved, or "None — consensus reached"
|
|
137
|
+
5. **Write the file**: Use the Write tool to create the spec at `docs/specs/<filename>.md`.
|
|
138
|
+
6. **Report**: Tell the user the file path of the written spec.
|
|
139
|
+
7. **Trivial decisions**: For trivial or low-impact decisions, offer SESSION.md-only logging instead of a full spec document.
|
|
140
|
+
|
|
114
141
|
## Subagent Configuration
|
|
115
142
|
|
|
116
143
|
When spawning council agents via the Task tool, always use `subagent_type: "general-purpose"`. Guild agent role names (advisor, developer, tech-lead, etc.) are NOT valid Claude Code subagent_types.
|
|
@@ -143,3 +170,6 @@ Consensus: Incremental adoption. New endpoints in GraphQL, existing stay REST.
|
|
|
143
170
|
- Each perspective must be independent — not "responding" to another agent
|
|
144
171
|
- The synthesis is done by you (the skill), not by the agents
|
|
145
172
|
- If all 3 agents agree, indicate consensus and suggest taking action
|
|
173
|
+
- After the user decides, always offer to write the spec to `docs/specs/`
|
|
174
|
+
- The spec document is the primary output of `/council` — it captures the debate, decision, and rationale
|
|
175
|
+
- If the user declines the spec, log the decision to SESSION.md as before
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-pr
|
|
3
|
+
description: "Create a pull request from the current branch with structured summary"
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Create PR
|
|
8
|
+
|
|
9
|
+
Creates a pull request from the current feature branch with a structured summary, test results, and change description. Closes the pipeline loop: init -> build-feature -> create-pr.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
|
|
13
|
+
- After completing a feature with `/build-feature`
|
|
14
|
+
- When you have changes on a feature branch ready for review
|
|
15
|
+
- To create a well-structured PR without manual formatting
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
`/create-pr`
|
|
20
|
+
|
|
21
|
+
## Process
|
|
22
|
+
|
|
23
|
+
### Step 1 -- Verify branch state
|
|
24
|
+
|
|
25
|
+
1. Confirm you are NOT on `main` or `develop` -- refuse to create PR from default branches
|
|
26
|
+
2. Run `git status` to check for uncommitted changes -- if any, warn the user and ask whether to commit first
|
|
27
|
+
3. Run `git log main..HEAD --oneline` to get the list of commits that will be in the PR
|
|
28
|
+
4. If there are no commits ahead of main, report that there is nothing to PR
|
|
29
|
+
|
|
30
|
+
### Step 2 -- Gather context
|
|
31
|
+
|
|
32
|
+
Collect the information needed for the PR description:
|
|
33
|
+
|
|
34
|
+
1. **Commits**: `git log main..HEAD --oneline` -- list of all commits on this branch
|
|
35
|
+
2. **Diff summary**: `git diff main..HEAD --stat` -- files changed with line counts
|
|
36
|
+
3. **Test results**: Run project tests (e.g., `npm test`) and capture pass/fail
|
|
37
|
+
4. **Lint results**: Run project lint (e.g., `npm run lint`) and capture pass/fail
|
|
38
|
+
5. **Branch name**: Extract feature name from the branch (e.g., `feature/dark-mode` -> `dark-mode`)
|
|
39
|
+
|
|
40
|
+
If tests or lint fail, warn the user but allow them to proceed (some PRs are draft/WIP).
|
|
41
|
+
|
|
42
|
+
### Step 3 -- Generate PR description
|
|
43
|
+
|
|
44
|
+
Build a structured PR description:
|
|
45
|
+
|
|
46
|
+
```markdown
|
|
47
|
+
## Summary
|
|
48
|
+
[2-4 bullet points describing what this PR does, derived from commit messages]
|
|
49
|
+
|
|
50
|
+
## Changes
|
|
51
|
+
[File-level summary from git diff --stat]
|
|
52
|
+
|
|
53
|
+
## Test plan
|
|
54
|
+
- [x] Tests: [pass/fail] ([count] tests)
|
|
55
|
+
- [x] Lint: [pass/fail]
|
|
56
|
+
- [ ] [Any manual verification steps if applicable]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Step 4 -- Create the PR
|
|
60
|
+
|
|
61
|
+
1. Push the branch to origin: `git push -u origin [branch-name]`
|
|
62
|
+
2. Create the PR using `gh pr create`:
|
|
63
|
+
- Title: derived from branch name or first commit message (max 70 chars)
|
|
64
|
+
- Body: the generated description from Step 3
|
|
65
|
+
- Base: `main` (or the project's default branch)
|
|
66
|
+
3. Report the PR URL to the user
|
|
67
|
+
|
|
68
|
+
### Step 5 -- Post-creation
|
|
69
|
+
|
|
70
|
+
1. Display the PR URL
|
|
71
|
+
2. Suggest next steps:
|
|
72
|
+
- "Request review from a teammate"
|
|
73
|
+
- "Run `/review` for an AI code review"
|
|
74
|
+
- "Merge when ready with `gh pr merge [number]`"
|
|
75
|
+
|
|
76
|
+
## Example Session
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
User: /create-pr
|
|
80
|
+
|
|
81
|
+
Checking branch state...
|
|
82
|
+
Branch: feature/dark-mode (4 commits ahead of main)
|
|
83
|
+
Tests: 82 passed, 0 failed
|
|
84
|
+
Lint: 0 errors
|
|
85
|
+
|
|
86
|
+
Creating PR...
|
|
87
|
+
PR #42: "feat: add dark mode toggle to settings"
|
|
88
|
+
https://github.com/org/repo/pull/42
|
|
89
|
+
|
|
90
|
+
Next steps:
|
|
91
|
+
- Request review from a teammate
|
|
92
|
+
- Run /review for AI code review
|
|
93
|
+
- Merge when ready
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Notes
|
|
97
|
+
|
|
98
|
+
- The PR title should be concise (under 70 characters) and follow conventional commits format when the project uses it
|
|
99
|
+
- If the branch has `wip:` commits from build-feature checkpoints, consider squashing them before creating the PR
|
|
100
|
+
- This skill does NOT merge the PR -- that is a manual step or a separate command
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Spec: [Feature Name]
|
|
2
|
+
|
|
3
|
+
spec-id: [kebab-case-identifier]
|
|
4
|
+
status: draft
|
|
5
|
+
date: [YYYY-MM-DD]
|
|
6
|
+
council-type: [architecture | feature-scope | tech-debt]
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
[Why this spec exists. What problem or opportunity triggered it. Include relevant background, current state, and what happens if we do nothing.]
|
|
11
|
+
|
|
12
|
+
## Decision
|
|
13
|
+
|
|
14
|
+
[What we decided to do. The core design choice and key sub-decisions. Written in present tense: "Create X that does Y."]
|
|
15
|
+
|
|
16
|
+
## Constraints
|
|
17
|
+
|
|
18
|
+
[Hard boundaries: compatibility, performance, dependencies, timeline, and non-negotiable requirements.]
|
|
19
|
+
|
|
20
|
+
## Acceptance Criteria
|
|
21
|
+
|
|
22
|
+
[Checkboxes. Each criterion is independently verifiable. These are the contract between spec and implementation.]
|
|
23
|
+
|
|
24
|
+
## Technical Approach
|
|
25
|
+
|
|
26
|
+
[How to implement the decision. Files involved, patterns to follow, integration points. Enough detail for a developer to start working without ambiguity about direction.]
|
|
27
|
+
|
|
28
|
+
## Trade-offs Considered
|
|
29
|
+
|
|
30
|
+
[Options evaluated and rejected, with reasoning. Table format preferred: Option | Pros | Cons | Decision.]
|
|
31
|
+
|
|
32
|
+
## Unresolved Questions
|
|
33
|
+
|
|
34
|
+
[Open items that need answers before or during implementation. Include recommendations where possible.]
|
|
35
|
+
|
|
36
|
+
## Test Strategy
|
|
37
|
+
|
|
38
|
+
[How to verify the implementation meets acceptance criteria. Automated tests, manual checks, linting, integration tests.]
|
|
39
|
+
|
|
40
|
+
## Council Perspectives
|
|
41
|
+
|
|
42
|
+
[Summary of each agent's independent analysis. One subsection per agent with their key arguments and position.]
|
|
43
|
+
|
|
44
|
+
## Points of Dissent
|
|
45
|
+
|
|
46
|
+
[Where agents disagreed and how the disagreement was resolved. If consensus was unanimous, state that explicitly.]
|
package/src/utils/files.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* files.js — File system utilities for Guild v1
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { mkdirSync, copyFileSync, existsSync, readdirSync, readFileSync } from 'fs';
|
|
5
|
+
import { mkdirSync, copyFileSync, existsSync, readdirSync, readFileSync, writeFileSync } from 'fs';
|
|
6
6
|
import { join, dirname, resolve } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
|
|
@@ -12,20 +12,56 @@ const AGENTS_DIR = join('.claude', 'agents');
|
|
|
12
12
|
const SKILLS_DIR = join('.claude', 'skills');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Returns the names of the
|
|
15
|
+
* Returns the names of the v1 agents by reading the templates directory.
|
|
16
|
+
* Adding a new .md file to src/templates/agents/ automatically includes it.
|
|
16
17
|
*/
|
|
17
18
|
export function getAgentNames() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
const agentsDir = join(TEMPLATES_DIR, 'agents');
|
|
20
|
+
if (!existsSync(agentsDir)) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
return readdirSync(agentsDir)
|
|
24
|
+
.filter(f => f.endsWith('.md'))
|
|
25
|
+
.map(f => f.replace('.md', ''))
|
|
26
|
+
.sort();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the names of the v1 skills by reading the templates directory.
|
|
31
|
+
* Adding a new directory to src/templates/skills/ automatically includes it.
|
|
32
|
+
*/
|
|
33
|
+
export function getSkillNames() {
|
|
34
|
+
const skillsDir = join(TEMPLATES_DIR, 'skills');
|
|
35
|
+
if (!existsSync(skillsDir)) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
return readdirSync(skillsDir, { withFileTypes: true })
|
|
39
|
+
.filter(d => d.isDirectory())
|
|
40
|
+
.map(d => d.name)
|
|
41
|
+
.sort();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parses YAML frontmatter from markdown content.
|
|
46
|
+
* Returns an object with { name, description, ...other fields } or empty object if no frontmatter.
|
|
47
|
+
*/
|
|
48
|
+
export function parseFrontmatter(content) {
|
|
49
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
50
|
+
if (!match) return {};
|
|
51
|
+
|
|
52
|
+
const frontmatter = {};
|
|
53
|
+
for (const line of match[1].split('\n')) {
|
|
54
|
+
const colonIndex = line.indexOf(':');
|
|
55
|
+
if (colonIndex === -1) continue;
|
|
56
|
+
const key = line.slice(0, colonIndex).trim();
|
|
57
|
+
let value = line.slice(colonIndex + 1).trim();
|
|
58
|
+
// Remove surrounding quotes
|
|
59
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
60
|
+
value = value.slice(1, -1);
|
|
61
|
+
}
|
|
62
|
+
if (key) frontmatter[key] = value;
|
|
63
|
+
}
|
|
64
|
+
return frontmatter;
|
|
29
65
|
}
|
|
30
66
|
|
|
31
67
|
/**
|
|
@@ -44,6 +80,14 @@ export async function copyTemplates() {
|
|
|
44
80
|
}
|
|
45
81
|
}
|
|
46
82
|
|
|
83
|
+
// Create docs/specs/ directory with .gitkeep
|
|
84
|
+
const specsDir = join('docs', 'specs');
|
|
85
|
+
mkdirSync(specsDir, { recursive: true });
|
|
86
|
+
const gitkeep = join(specsDir, '.gitkeep');
|
|
87
|
+
if (!existsSync(gitkeep)) {
|
|
88
|
+
writeFileSync(gitkeep, '', 'utf8');
|
|
89
|
+
}
|
|
90
|
+
|
|
47
91
|
// Copy skill directories with SKILL.md
|
|
48
92
|
const skillsTemplate = join(TEMPLATES_DIR, 'skills');
|
|
49
93
|
if (existsSync(skillsTemplate)) {
|
|
@@ -101,3 +145,17 @@ export function resolveProjectRoot(startDir = process.cwd()) {
|
|
|
101
145
|
dir = parent;
|
|
102
146
|
}
|
|
103
147
|
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Resolves the Guild project root and changes the working directory to it.
|
|
151
|
+
* Throws if no Guild project is found.
|
|
152
|
+
* Returns the absolute path to the project root.
|
|
153
|
+
*/
|
|
154
|
+
export function ensureProjectRoot() {
|
|
155
|
+
const root = resolveProjectRoot();
|
|
156
|
+
if (!root) {
|
|
157
|
+
throw new Error('Guild project not found. Run `guild init` to initialize.');
|
|
158
|
+
}
|
|
159
|
+
process.chdir(root);
|
|
160
|
+
return root;
|
|
161
|
+
}
|
package/src/utils/generators.js
CHANGED
|
@@ -31,6 +31,67 @@ export async function generateProjectMd(data) {
|
|
|
31
31
|
writeFileSync('PROJECT.md', content, 'utf8');
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Infers code conventions based on project type and stack.
|
|
36
|
+
* Rules accumulate (not exclusive). Deduplicates lines.
|
|
37
|
+
*/
|
|
38
|
+
export function inferCodeConventions(type, stack) {
|
|
39
|
+
const s = (stack || '').toLowerCase();
|
|
40
|
+
const rules = [];
|
|
41
|
+
|
|
42
|
+
// Stack-specific rules
|
|
43
|
+
if (s.includes('next') || s.includes('react')) {
|
|
44
|
+
rules.push('- Components in PascalCase', '- CSS Modules or Tailwind utility classes');
|
|
45
|
+
}
|
|
46
|
+
if (s.includes('express') || (s.includes('node') && type === 'api')) {
|
|
47
|
+
rules.push('- Controllers/routes pattern', '- Async/await error handling');
|
|
48
|
+
}
|
|
49
|
+
if (s.includes('typescript') || /\bts\b/.test(s)) {
|
|
50
|
+
rules.push('- Strict TypeScript', '- Interfaces over types where possible');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Type-specific fallbacks (only if no stack rules matched)
|
|
54
|
+
if (rules.length === 0) {
|
|
55
|
+
if (type === 'cli') {
|
|
56
|
+
rules.push('- Commander.js command pattern', '- ESModules throughout');
|
|
57
|
+
} else if (type === 'api') {
|
|
58
|
+
rules.push('- REST or GraphQL endpoint conventions', '- Input validation on all endpoints');
|
|
59
|
+
} else {
|
|
60
|
+
rules.push('- Consistent naming conventions', '- ESModules throughout');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Deduplicate
|
|
65
|
+
return [...new Set(rules)].join('\n');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Infers likely environment variables based on project type and stack.
|
|
70
|
+
* Rules accumulate. Deduplicates lines.
|
|
71
|
+
*/
|
|
72
|
+
export function inferEnvVars(type, stack) {
|
|
73
|
+
const s = (stack || '').toLowerCase();
|
|
74
|
+
const vars = [];
|
|
75
|
+
|
|
76
|
+
// Stack-specific
|
|
77
|
+
if (s.includes('supabase')) vars.push('- `SUPABASE_URL`', '- `SUPABASE_ANON_KEY`');
|
|
78
|
+
if (s.includes('firebase')) vars.push('- `FIREBASE_API_KEY`', '- `FIREBASE_PROJECT_ID`');
|
|
79
|
+
if (s.includes('postgres')) vars.push('- `DATABASE_URL`');
|
|
80
|
+
if (s.includes('redis')) vars.push('- `REDIS_URL`');
|
|
81
|
+
if (s.includes('stripe')) vars.push('- `STRIPE_SECRET_KEY`', '- `STRIPE_WEBHOOK_SECRET`');
|
|
82
|
+
if (s.includes('vercel')) vars.push('- `VERCEL_URL`');
|
|
83
|
+
if (/\baws\b/.test(s)) vars.push('- `AWS_ACCESS_KEY_ID`', '- `AWS_SECRET_ACCESS_KEY`', '- `AWS_REGION`');
|
|
84
|
+
|
|
85
|
+
// Type-specific fallbacks
|
|
86
|
+
if (vars.length === 0) {
|
|
87
|
+
if (type === 'webapp') vars.push('- `NODE_ENV`', '- `API_URL`');
|
|
88
|
+
else if (type === 'api') vars.push('- `NODE_ENV`', '- `PORT`', '- `DATABASE_URL`');
|
|
89
|
+
else vars.push('- `NODE_ENV`');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return [...new Set(vars)].join('\n');
|
|
93
|
+
}
|
|
94
|
+
|
|
34
95
|
/**
|
|
35
96
|
* Generates CLAUDE.md — central document with placeholders for guild-specialize.
|
|
36
97
|
*/
|
|
@@ -46,14 +107,17 @@ ${data.stack}
|
|
|
46
107
|
## Project structure
|
|
47
108
|
[PENDING: guild-specialize]
|
|
48
109
|
|
|
110
|
+
docs/
|
|
111
|
+
specs/ # Design documents (SDD specs)
|
|
112
|
+
|
|
49
113
|
## Code conventions
|
|
50
|
-
|
|
114
|
+
${inferCodeConventions(data.type, data.stack)}
|
|
51
115
|
|
|
52
116
|
## Architecture patterns
|
|
53
117
|
[PENDING: guild-specialize]
|
|
54
118
|
|
|
55
119
|
## Environment variables
|
|
56
|
-
|
|
120
|
+
${inferEnvVars(data.type, data.stack)}
|
|
57
121
|
|
|
58
122
|
## Global rules
|
|
59
123
|
- Do not implement without an approved plan
|
|
@@ -72,6 +136,7 @@ ${data.stack}
|
|
|
72
136
|
- /guild-specialize — enrich CLAUDE.md by exploring the actual project
|
|
73
137
|
- /build-feature — full development pipeline
|
|
74
138
|
- /new-feature — create branch and scaffold for a feature
|
|
139
|
+
- /create-pr — create a structured pull request from current branch
|
|
75
140
|
- /council — debate decisions with multiple agents
|
|
76
141
|
- /review — code review on the current diff
|
|
77
142
|
- /qa-cycle — QA + bugfix cycle
|
|
@@ -103,8 +168,9 @@ export async function generateSessionMd() {
|
|
|
103
168
|
- CLAUDE.md has placeholders — run /guild-specialize to enrich.
|
|
104
169
|
|
|
105
170
|
## Next steps
|
|
106
|
-
1.
|
|
107
|
-
2.
|
|
171
|
+
1. Run /guild-specialize to analyze your codebase
|
|
172
|
+
2. Spec your first feature with /council
|
|
173
|
+
3. Build it with /build-feature
|
|
108
174
|
`;
|
|
109
175
|
|
|
110
176
|
writeFileSync('SESSION.md', content, 'utf8');
|