hool-cli 0.1.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/README.md +219 -0
- package/dist/adapters/claude-code.d.ts +8 -0
- package/dist/adapters/claude-code.js +119 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/cursor.d.ts +8 -0
- package/dist/adapters/cursor.js +76 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/generic.d.ts +8 -0
- package/dist/adapters/generic.js +63 -0
- package/dist/adapters/generic.js.map +1 -0
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.js +11 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/types.d.ts +24 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/core/scaffold.d.ts +6 -0
- package/dist/core/scaffold.js +156 -0
- package/dist/core/scaffold.js.map +1 -0
- package/dist/core/templates.d.ts +2 -0
- package/dist/core/templates.js +19 -0
- package/dist/core/templates.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +195 -0
- package/dist/index.js.map +1 -0
- package/dist/mcps/installer.d.ts +7 -0
- package/dist/mcps/installer.js +25 -0
- package/dist/mcps/installer.js.map +1 -0
- package/dist/mcps/registry.d.ts +4 -0
- package/dist/mcps/registry.js +44 -0
- package/dist/mcps/registry.js.map +1 -0
- package/package.json +37 -0
- package/prompts/agents/05-fe-tech-lead.md +177 -0
- package/prompts/agents/06-be-tech-lead.md +198 -0
- package/prompts/agents/08-be-dev.md +132 -0
- package/prompts/agents/08-fe-dev.md +122 -0
- package/prompts/agents/10-qa.md +238 -0
- package/prompts/agents/11-forensic.md +134 -0
- package/prompts/orchestrator.md +561 -0
- package/prompts/skills/01-brainstorm.md +96 -0
- package/prompts/skills/02-spec.md +151 -0
- package/prompts/skills/03-design.md +146 -0
- package/prompts/skills/04-architecture.md +298 -0
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# HOOL CLI
|
|
2
|
+
|
|
3
|
+
One command to install the entire agent-driven SDLC framework into any project.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx hool init
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
That's it. Everything else is automatic.
|
|
12
|
+
|
|
13
|
+
## What `hool init` does
|
|
14
|
+
|
|
15
|
+
### Step 1: Ask project type
|
|
16
|
+
```
|
|
17
|
+
What are you building?
|
|
18
|
+
1. Web application
|
|
19
|
+
2. Browser game
|
|
20
|
+
3. Mobile app (React Native)
|
|
21
|
+
4. Animation / motion
|
|
22
|
+
5. CLI tool
|
|
23
|
+
6. API / backend only
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Step 2: Create project structure
|
|
27
|
+
Based on selection, creates:
|
|
28
|
+
```
|
|
29
|
+
your-project/
|
|
30
|
+
phases/
|
|
31
|
+
00-init/
|
|
32
|
+
project-profile.md
|
|
33
|
+
01-brainstorm/
|
|
34
|
+
brainstorm.md
|
|
35
|
+
02-spec/
|
|
36
|
+
spec.md
|
|
37
|
+
03-design/
|
|
38
|
+
design.md
|
|
39
|
+
cards/
|
|
40
|
+
04-architecture/
|
|
41
|
+
architecture.md
|
|
42
|
+
contracts.md
|
|
43
|
+
schema.md
|
|
44
|
+
flows.md
|
|
45
|
+
fe/
|
|
46
|
+
be/
|
|
47
|
+
05-fe-scaffold/
|
|
48
|
+
fe-lld.md
|
|
49
|
+
06-be-scaffold/
|
|
50
|
+
be-lld.md
|
|
51
|
+
07-test-plan/
|
|
52
|
+
test-plan.md
|
|
53
|
+
operations/
|
|
54
|
+
current-phase.md
|
|
55
|
+
task-board.md
|
|
56
|
+
bugs.md
|
|
57
|
+
issues.md
|
|
58
|
+
inconsistencies.md
|
|
59
|
+
needs-human-review.md
|
|
60
|
+
memory/
|
|
61
|
+
product-lead/
|
|
62
|
+
hot.md, cold.md, best-practices.md, issues.md
|
|
63
|
+
fe-tech-lead/
|
|
64
|
+
hot.md, cold.md, best-practices.md, issues.md
|
|
65
|
+
be-tech-lead/
|
|
66
|
+
hot.md, cold.md, best-practices.md, issues.md
|
|
67
|
+
fe-dev/
|
|
68
|
+
hot.md, cold.md, best-practices.md, issues.md
|
|
69
|
+
be-dev/
|
|
70
|
+
hot.md, cold.md, best-practices.md, issues.md
|
|
71
|
+
qa/
|
|
72
|
+
hot.md, cold.md, best-practices.md, issues.md
|
|
73
|
+
forensic/
|
|
74
|
+
hot.md, cold.md, best-practices.md, issues.md
|
|
75
|
+
logs/
|
|
76
|
+
fe.log
|
|
77
|
+
be.log
|
|
78
|
+
src/
|
|
79
|
+
frontend/
|
|
80
|
+
backend/
|
|
81
|
+
tests/
|
|
82
|
+
unit/
|
|
83
|
+
integration/
|
|
84
|
+
e2e/
|
|
85
|
+
.hool/
|
|
86
|
+
mcps.json
|
|
87
|
+
prompts/ <- agent prompts (copied from hool-mini templates)
|
|
88
|
+
CLAUDE.md <- injected with HOOL product-lead instructions
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Step 3: Check & Install MCPs (global)
|
|
92
|
+
MCPs are installed GLOBALLY (once per machine, not per project).
|
|
93
|
+
|
|
94
|
+
On first run:
|
|
95
|
+
```
|
|
96
|
+
Checking global MCPs...
|
|
97
|
+
ok context7 -- already installed
|
|
98
|
+
!! playwright -- not found
|
|
99
|
+
|
|
100
|
+
Install missing MCPs globally? (y/n)
|
|
101
|
+
Installing playwright -> ~/.claude/mcp_servers.json ok
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Required MCPs by project type:
|
|
105
|
+
```
|
|
106
|
+
ALL projects: context7
|
|
107
|
+
Web app: + playwright
|
|
108
|
+
Browser game: + playwright
|
|
109
|
+
Mobile app: + adb MCP (warn if adb CLI not on PATH)
|
|
110
|
+
Animation: + playwright
|
|
111
|
+
CLI / API only: (no additional)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Writes to `~/.claude/mcp_servers.json` (global, shared across all projects).
|
|
115
|
+
|
|
116
|
+
### Step 4: Set up Claude Code integration
|
|
117
|
+
Injects HOOL product-lead instructions into project CLAUDE.md so that when you open Claude Code in this project, it knows:
|
|
118
|
+
- The phase structure
|
|
119
|
+
- Which agent prompts to load
|
|
120
|
+
- Where state files live
|
|
121
|
+
- Which MCPs are available
|
|
122
|
+
|
|
123
|
+
### Step 5: Initialize status files
|
|
124
|
+
Creates all status files with empty templates:
|
|
125
|
+
- `operations/current-phase.md` -> Phase 0, awaiting start
|
|
126
|
+
- `operations/task-board.md` -> empty
|
|
127
|
+
- `operations/bugs.md`, `operations/issues.md`, `operations/inconsistencies.md`, `operations/needs-human-review.md` -> empty
|
|
128
|
+
- All agent memory files (`memory/<agent-name>/hot.md`, `cold.md`, `best-practices.md`, `issues.md`) -> initialized with headers
|
|
129
|
+
|
|
130
|
+
### Step 6: Write project MCP manifest
|
|
131
|
+
Creates `.hool/mcps.json` -- a READ-ONLY manifest declaring which global MCPs this project uses. Not an installer, just a reference.
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"required": ["context7", "playwright"],
|
|
135
|
+
"optional": ["hool-context-mcp"],
|
|
136
|
+
"domain": "web-app"
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Step 7: Done
|
|
141
|
+
```
|
|
142
|
+
HOOL initialized for: Web Application
|
|
143
|
+
|
|
144
|
+
Start building:
|
|
145
|
+
$ claude
|
|
146
|
+
> /hool start
|
|
147
|
+
|
|
148
|
+
Or manually:
|
|
149
|
+
> Read .hool/prompts/product-lead.md and begin Phase 1: Brainstorm
|
|
150
|
+
|
|
151
|
+
Global MCPs verified: context7, playwright
|
|
152
|
+
Project profile: web-app
|
|
153
|
+
Status: ready for Phase 1 -- Brainstorm
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Other commands
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx hool init # bootstrap everything
|
|
160
|
+
npx hool status # show current phase + task board summary
|
|
161
|
+
npx hool add-mcp <name> # install an additional MCP
|
|
162
|
+
npx hool reset # reset status files (keep phases/)
|
|
163
|
+
npx hool upgrade # update prompts/agents to latest version
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## How it ships
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
npm package: hool
|
|
170
|
+
bin: hool
|
|
171
|
+
contains:
|
|
172
|
+
- CLI (Node.js)
|
|
173
|
+
- Prompt templates (markdown)
|
|
174
|
+
- MCP installer logic
|
|
175
|
+
- CLAUDE.md generator
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Install globally or use npx:
|
|
179
|
+
```bash
|
|
180
|
+
npm install -g hool # global
|
|
181
|
+
npx hool init # one-shot
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## MCP Installation Strategy
|
|
185
|
+
|
|
186
|
+
MCPs install GLOBALLY -- one install per machine, shared across all projects.
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
npm-based MCPs (context7, playwright):
|
|
190
|
+
-> writes to ~/.claude/mcp_servers.json (global)
|
|
191
|
+
|
|
192
|
+
Python-based MCPs:
|
|
193
|
+
-> pip/uvx install, writes to ~/.claude/mcp_servers.json (global)
|
|
194
|
+
|
|
195
|
+
Custom MCPs (hool-context-mcp):
|
|
196
|
+
-> installed globally, reads per-project config from .hool/context-config.json
|
|
197
|
+
|
|
198
|
+
System tools (adb):
|
|
199
|
+
-> Check if installed on PATH, warn if not, provide install instructions
|
|
200
|
+
-> Don't auto-install system-level tools
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Global vs Project-Level
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
GLOBAL (~/.claude/mcp_servers.json):
|
|
207
|
+
- MCP server binaries and configs
|
|
208
|
+
- Installed once, available to all projects
|
|
209
|
+
- `hool init` checks and installs missing ones
|
|
210
|
+
|
|
211
|
+
PROJECT-LEVEL (.hool/mcps.json):
|
|
212
|
+
- Read-only manifest: which MCPs this project uses
|
|
213
|
+
- NOT an installer -- just a reference
|
|
214
|
+
- Helps `hool init` know what to check globally
|
|
215
|
+
|
|
216
|
+
PROJECT-LEVEL (.hool/context-config.json):
|
|
217
|
+
- hool-context-mcp reads this for per-project indexing config
|
|
218
|
+
- Which dirs to watch, chunking rules, ignore patterns
|
|
219
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Adapter, AdapterConfig, McpDefinition, AgentPlatform } from './types.js';
|
|
2
|
+
export declare class ClaudeCodeAdapter implements Adapter {
|
|
3
|
+
readonly platform: AgentPlatform;
|
|
4
|
+
injectInstructions(config: AdapterConfig): Promise<void>;
|
|
5
|
+
installMcp(mcp: McpDefinition): Promise<void>;
|
|
6
|
+
isMcpInstalled(mcpName: string): Promise<boolean>;
|
|
7
|
+
getCompletionMessage(config: AdapterConfig): string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const CLAUDE_MCP_CONFIG_PATH = path.join(os.homedir(), '.claude', 'mcp_servers.json');
|
|
5
|
+
function getMcpSection(projectType) {
|
|
6
|
+
const mcps = ['- **context7**: Use `mcp__context7__resolve-library-id` and `mcp__context7__query-docs` for up-to-date library documentation'];
|
|
7
|
+
if (['web-app', 'browser-game', 'animation'].includes(projectType)) {
|
|
8
|
+
mcps.push('- **playwright**: Use for E2E testing, screenshots, visual comparison, and browser automation');
|
|
9
|
+
}
|
|
10
|
+
if (projectType === 'mobile-android') {
|
|
11
|
+
mcps.push('- **adb**: Use for Android device/emulator interaction (must be installed on PATH)');
|
|
12
|
+
}
|
|
13
|
+
return mcps.join('\n');
|
|
14
|
+
}
|
|
15
|
+
function generateClaudeMd(config) {
|
|
16
|
+
return `# HOOL — Agent-Driven SDLC
|
|
17
|
+
|
|
18
|
+
This project uses the HOOL framework. The Product Lead is the sole user-facing agent.
|
|
19
|
+
All other agents are internal — dispatched by the Product Lead as subagents.
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
You are the Product Lead. On every invocation:
|
|
24
|
+
1. Read \`.hool/prompts/orchestrator.md\` — your full process and rules
|
|
25
|
+
2. Read \`operations/current-phase.md\` to know where you are
|
|
26
|
+
3. Read \`operations/task-board.md\` to know what's in flight
|
|
27
|
+
4. Read your memory files (\`memory/product-lead/hot.md\`, \`best-practices.md\`, \`issues.md\`)
|
|
28
|
+
5. Continue from where you left off (see Autonomous Execution Loop in orchestrator.md)
|
|
29
|
+
|
|
30
|
+
## How to Dispatch Subagents
|
|
31
|
+
|
|
32
|
+
When you need to dispatch an agent (Phases 5-12), use the **Agent tool**:
|
|
33
|
+
|
|
34
|
+
1. Read the agent's prompt from \`.hool/prompts/agents/\`
|
|
35
|
+
2. Read the agent's memory files (\`memory/<agent>/hot.md\`, \`best-practices.md\`, \`issues.md\`)
|
|
36
|
+
3. Call the Agent tool with:
|
|
37
|
+
- \`prompt\`: The task description + relevant context file paths
|
|
38
|
+
- The subagent reads its own prompt, memory, and the files you specify
|
|
39
|
+
4. When the subagent returns, check its output and continue the dispatch loop
|
|
40
|
+
|
|
41
|
+
### Agent Registry
|
|
42
|
+
All agents are defined in \`.hool/agents.json\` — read it for the full list of agents, their prompts, memory paths, and which phases they participate in.
|
|
43
|
+
|
|
44
|
+
## MCP Tools Available
|
|
45
|
+
|
|
46
|
+
MCP server configs are in \`.hool/mcps.json\` and installed to your platform's MCP config.
|
|
47
|
+
|
|
48
|
+
${getMcpSection(config.projectType)}
|
|
49
|
+
|
|
50
|
+
## Key Rules
|
|
51
|
+
|
|
52
|
+
- You are the **sole user-facing agent** — the user only talks to you
|
|
53
|
+
- After Phase 4 sign-off, the human is OUT — you run autonomously
|
|
54
|
+
- All state lives in files: \`phases/\`, \`operations/\`, \`memory/\`
|
|
55
|
+
- Agents never modify their own prompts — escalate to \`operations/needs-human-review.md\`
|
|
56
|
+
- Read your full orchestrator prompt at \`.hool/prompts/orchestrator.md\` for the complete process
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
export class ClaudeCodeAdapter {
|
|
60
|
+
platform = 'claude-code';
|
|
61
|
+
async injectInstructions(config) {
|
|
62
|
+
const claudeMdPath = path.join(config.projectDir, 'CLAUDE.md');
|
|
63
|
+
const content = generateClaudeMd(config);
|
|
64
|
+
// Append to existing CLAUDE.md or create new
|
|
65
|
+
try {
|
|
66
|
+
const existing = await fs.readFile(claudeMdPath, 'utf-8');
|
|
67
|
+
if (existing.includes('HOOL')) {
|
|
68
|
+
// Already has HOOL instructions, replace
|
|
69
|
+
const marker = '# HOOL — Agent-Driven SDLC';
|
|
70
|
+
const idx = existing.indexOf(marker);
|
|
71
|
+
if (idx >= 0) {
|
|
72
|
+
await fs.writeFile(claudeMdPath, existing.slice(0, idx) + content, 'utf-8');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
await fs.writeFile(claudeMdPath, existing + '\n\n' + content, 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
await fs.writeFile(claudeMdPath, content, 'utf-8');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async installMcp(mcp) {
|
|
84
|
+
const configDir = path.dirname(CLAUDE_MCP_CONFIG_PATH);
|
|
85
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
86
|
+
let config = {};
|
|
87
|
+
try {
|
|
88
|
+
const raw = await fs.readFile(CLAUDE_MCP_CONFIG_PATH, 'utf-8');
|
|
89
|
+
config = JSON.parse(raw);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// File doesn't exist or is invalid — start fresh
|
|
93
|
+
}
|
|
94
|
+
config[mcp.name] = mcp.configEntry;
|
|
95
|
+
await fs.writeFile(CLAUDE_MCP_CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
96
|
+
}
|
|
97
|
+
async isMcpInstalled(mcpName) {
|
|
98
|
+
try {
|
|
99
|
+
const raw = await fs.readFile(CLAUDE_MCP_CONFIG_PATH, 'utf-8');
|
|
100
|
+
const config = JSON.parse(raw);
|
|
101
|
+
return mcpName in config;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
getCompletionMessage(config) {
|
|
108
|
+
return [
|
|
109
|
+
'',
|
|
110
|
+
' Start building:',
|
|
111
|
+
' $ claude',
|
|
112
|
+
' > Read .hool/prompts/orchestrator.md and begin Phase 1: Brainstorm',
|
|
113
|
+
'',
|
|
114
|
+
' Or if you have the /hool skill registered:',
|
|
115
|
+
' > /hool start',
|
|
116
|
+
].join('\n');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Adapter, AdapterConfig, McpDefinition, AgentPlatform } from './types.js';
|
|
2
|
+
export declare class CursorAdapter implements Adapter {
|
|
3
|
+
readonly platform: AgentPlatform;
|
|
4
|
+
injectInstructions(config: AdapterConfig): Promise<void>;
|
|
5
|
+
installMcp(mcp: McpDefinition): Promise<void>;
|
|
6
|
+
isMcpInstalled(mcpName: string): Promise<boolean>;
|
|
7
|
+
getCompletionMessage(config: AdapterConfig): string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const CURSOR_MCP_CONFIG_PATH = path.join(os.homedir(), '.cursor', 'mcp.json');
|
|
5
|
+
function generateCursorRules(config) {
|
|
6
|
+
return `# HOOL — Agent-Driven SDLC
|
|
7
|
+
|
|
8
|
+
This project uses the HOOL framework. You are the Product Lead — the sole user-facing agent.
|
|
9
|
+
|
|
10
|
+
## On Every Message
|
|
11
|
+
|
|
12
|
+
1. Read \`operations/current-phase.md\` to know where you are
|
|
13
|
+
2. Read \`operations/task-board.md\` to know what's in flight
|
|
14
|
+
3. Read your memory: \`memory/product-lead/hot.md\`, \`best-practices.md\`, \`issues.md\`
|
|
15
|
+
4. Follow the full process in \`.hool/prompts/orchestrator.md\`
|
|
16
|
+
|
|
17
|
+
## Agent Dispatch
|
|
18
|
+
|
|
19
|
+
When you need to dispatch an agent, read the agent's prompt from \`.hool/prompts/agents/\` and follow its instructions directly. In Cursor, agents are not spawned as subprocesses — you switch roles by loading the relevant prompt and executing its process.
|
|
20
|
+
|
|
21
|
+
After completing the agent's task, switch back to Product Lead role and continue the dispatch loop.
|
|
22
|
+
|
|
23
|
+
## Key Rules
|
|
24
|
+
|
|
25
|
+
- You are the **sole user-facing agent** — the user only talks to you
|
|
26
|
+
- After Phase 4 sign-off, the human is OUT — you run autonomously
|
|
27
|
+
- All state lives in files: \`phases/\`, \`operations/\`, \`memory/\`
|
|
28
|
+
- Agents never modify their own prompts — escalate to \`operations/needs-human-review.md\`
|
|
29
|
+
`;
|
|
30
|
+
}
|
|
31
|
+
export class CursorAdapter {
|
|
32
|
+
platform = 'cursor';
|
|
33
|
+
async injectInstructions(config) {
|
|
34
|
+
const rulesDir = path.join(config.projectDir, '.cursor', 'rules');
|
|
35
|
+
await fs.mkdir(rulesDir, { recursive: true });
|
|
36
|
+
const rulesPath = path.join(rulesDir, 'hool.mdc');
|
|
37
|
+
const content = generateCursorRules(config);
|
|
38
|
+
await fs.writeFile(rulesPath, content, 'utf-8');
|
|
39
|
+
}
|
|
40
|
+
async installMcp(mcp) {
|
|
41
|
+
const configDir = path.dirname(CURSOR_MCP_CONFIG_PATH);
|
|
42
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
43
|
+
let config = {};
|
|
44
|
+
try {
|
|
45
|
+
const raw = await fs.readFile(CURSOR_MCP_CONFIG_PATH, 'utf-8');
|
|
46
|
+
config = JSON.parse(raw);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Fresh config
|
|
50
|
+
}
|
|
51
|
+
if (!config.mcpServers)
|
|
52
|
+
config.mcpServers = {};
|
|
53
|
+
config.mcpServers[mcp.name] = mcp.configEntry;
|
|
54
|
+
await fs.writeFile(CURSOR_MCP_CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
55
|
+
}
|
|
56
|
+
async isMcpInstalled(mcpName) {
|
|
57
|
+
try {
|
|
58
|
+
const raw = await fs.readFile(CURSOR_MCP_CONFIG_PATH, 'utf-8');
|
|
59
|
+
const config = JSON.parse(raw);
|
|
60
|
+
return mcpName in (config.mcpServers || {});
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
getCompletionMessage(config) {
|
|
67
|
+
return [
|
|
68
|
+
'',
|
|
69
|
+
' Start building:',
|
|
70
|
+
' 1. Open this project in Cursor',
|
|
71
|
+
' 2. The .cursor/rules/hool.mdc will load automatically',
|
|
72
|
+
' 3. Tell the agent: "Read .hool/prompts/orchestrator.md and begin Phase 1: Brainstorm"',
|
|
73
|
+
].join('\n');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/adapters/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAE9E,SAAS,mBAAmB,CAAC,MAAqB;IAChD,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAuBR,CAAC;AACF,CAAC;AAED,MAAM,OAAO,aAAa;IACf,QAAQ,GAAkB,QAAQ,CAAC;IAE5C,KAAK,CAAC,kBAAkB,CAAC,MAAqB;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAClE,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAkB;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/C,IAAI,MAAM,GAA6C,EAAE,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;YAC/D,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QAC/C,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;QAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,sBAAsB,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9F,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAe;QAClC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,OAAO,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,oBAAoB,CAAC,MAAqB;QACxC,OAAO;YACL,EAAE;YACF,mBAAmB;YACnB,oCAAoC;YACpC,2DAA2D;YAC3D,2FAA2F;SAC5F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Adapter, AdapterConfig, McpDefinition, AgentPlatform } from './types.js';
|
|
2
|
+
export declare class GenericAdapter implements Adapter {
|
|
3
|
+
readonly platform: AgentPlatform;
|
|
4
|
+
injectInstructions(config: AdapterConfig): Promise<void>;
|
|
5
|
+
installMcp(_mcp: McpDefinition): Promise<void>;
|
|
6
|
+
isMcpInstalled(_mcpName: string): Promise<boolean>;
|
|
7
|
+
getCompletionMessage(config: AdapterConfig): string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
function generateInstructions(config) {
|
|
4
|
+
return `# HOOL — Agent-Driven SDLC
|
|
5
|
+
|
|
6
|
+
This project uses the HOOL framework for agent-driven development.
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
Your AI agent needs to act as the Product Lead. Load the orchestrator prompt:
|
|
11
|
+
|
|
12
|
+
.hool/prompts/orchestrator.md
|
|
13
|
+
|
|
14
|
+
This prompt tells the agent:
|
|
15
|
+
- How to manage phases (0-12)
|
|
16
|
+
- How to dispatch internal agents (by loading their prompts from .hool/prompts/agents/)
|
|
17
|
+
- How to use the memory system (memory/<agent>/)
|
|
18
|
+
- How to manage operations files (operations/)
|
|
19
|
+
|
|
20
|
+
## On Every Session
|
|
21
|
+
|
|
22
|
+
1. Read \`operations/current-phase.md\` — know where you are
|
|
23
|
+
2. Read \`operations/task-board.md\` — know what's in flight
|
|
24
|
+
3. Read \`memory/product-lead/hot.md\` — your recent context
|
|
25
|
+
4. Follow the process in \`.hool/prompts/orchestrator.md\`
|
|
26
|
+
|
|
27
|
+
## MCP Servers
|
|
28
|
+
|
|
29
|
+
This project uses the following MCPs (install them for your platform):
|
|
30
|
+
${config.projectType === 'web-app' || config.projectType === 'browser-game' || config.projectType === 'animation'
|
|
31
|
+
? '- context7: npx -y @context7/mcp\n- playwright: npx @anthropic/mcp-playwright'
|
|
32
|
+
: '- context7: npx -y @context7/mcp'}
|
|
33
|
+
|
|
34
|
+
See .hool/mcps.json for the full manifest.
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
37
|
+
export class GenericAdapter {
|
|
38
|
+
platform = 'generic';
|
|
39
|
+
async injectInstructions(config) {
|
|
40
|
+
const instructionsPath = path.join(config.projectDir, 'HOOL-INSTRUCTIONS.md');
|
|
41
|
+
await fs.writeFile(instructionsPath, generateInstructions(config), 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
async installMcp(_mcp) {
|
|
44
|
+
// Generic adapter can't install MCPs — the user's platform handles it
|
|
45
|
+
// Just log what needs to be installed
|
|
46
|
+
}
|
|
47
|
+
async isMcpInstalled(_mcpName) {
|
|
48
|
+
// Can't check — assume not installed, instructions will list them
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
getCompletionMessage(config) {
|
|
52
|
+
return [
|
|
53
|
+
'',
|
|
54
|
+
' Start building:',
|
|
55
|
+
' 1. Open this project in your AI coding tool',
|
|
56
|
+
' 2. Load the instructions from HOOL-INSTRUCTIONS.md',
|
|
57
|
+
' 3. Tell the agent: "Read .hool/prompts/orchestrator.md and begin Phase 1: Brainstorm"',
|
|
58
|
+
'',
|
|
59
|
+
' Note: Install the MCPs listed in .hool/mcps.json for your platform manually.',
|
|
60
|
+
].join('\n');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=generic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/adapters/generic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,SAAS,oBAAoB,CAAC,MAAqB;IACjD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BP,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,KAAK,cAAc,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW;QAC7G,CAAC,CAAC,+EAA+E;QACjF,CAAC,CAAC,kCACJ;;;CAGD,CAAC;AACF,CAAC;AAED,MAAM,OAAO,cAAc;IAChB,QAAQ,GAAkB,SAAS,CAAC;IAE7C,KAAK,CAAC,kBAAkB,CAAC,MAAqB;QAC5C,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;QAC9E,MAAM,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAmB;QAClC,sEAAsE;QACtE,sCAAsC;IACxC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,kEAAkE;QAClE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB,CAAC,MAAqB;QACxC,OAAO;YACL,EAAE;YACF,mBAAmB;YACnB,iDAAiD;YACjD,wDAAwD;YACxD,2FAA2F;YAC3F,EAAE;YACF,gFAAgF;SACjF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ClaudeCodeAdapter } from './claude-code.js';
|
|
2
|
+
import { CursorAdapter } from './cursor.js';
|
|
3
|
+
import { GenericAdapter } from './generic.js';
|
|
4
|
+
export function createAdapter(platform) {
|
|
5
|
+
switch (platform) {
|
|
6
|
+
case 'claude-code': return new ClaudeCodeAdapter();
|
|
7
|
+
case 'cursor': return new CursorAdapter();
|
|
8
|
+
case 'generic': return new GenericAdapter();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,UAAU,aAAa,CAAC,QAAuB;IACnD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa,CAAC,CAAC,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACnD,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,aAAa,EAAE,CAAC;QAC1C,KAAK,SAAS,CAAC,CAAC,OAAO,IAAI,cAAc,EAAE,CAAC;IAC9C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type ProjectType = 'web-app' | 'browser-game' | 'mobile-android' | 'animation' | 'cli-tool' | 'api-only' | 'desktop' | 'other';
|
|
2
|
+
export type AgentPlatform = 'claude-code' | 'cursor' | 'generic';
|
|
3
|
+
export interface McpDefinition {
|
|
4
|
+
name: string;
|
|
5
|
+
installCommand: string;
|
|
6
|
+
configEntry: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface AdapterConfig {
|
|
9
|
+
platform: AgentPlatform;
|
|
10
|
+
projectType: ProjectType;
|
|
11
|
+
projectDir: string;
|
|
12
|
+
promptsDir: string;
|
|
13
|
+
}
|
|
14
|
+
export interface Adapter {
|
|
15
|
+
readonly platform: AgentPlatform;
|
|
16
|
+
/** Inject agent instructions into the platform's config (CLAUDE.md, .cursor/rules/, etc.) */
|
|
17
|
+
injectInstructions(config: AdapterConfig): Promise<void>;
|
|
18
|
+
/** Install an MCP into the platform's global config */
|
|
19
|
+
installMcp(mcp: McpDefinition): Promise<void>;
|
|
20
|
+
/** Check if an MCP is already installed */
|
|
21
|
+
isMcpInstalled(mcpName: string): Promise<boolean>;
|
|
22
|
+
/** Get platform-specific completion message */
|
|
23
|
+
getCompletionMessage(config: AdapterConfig): string;
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ProjectType } from '../adapters/types.js';
|
|
2
|
+
export type ExecutionMode = 'interactive' | 'full-hool';
|
|
3
|
+
export declare function scaffoldProject(projectDir: string, projectType: ProjectType, mode?: ExecutionMode): Promise<void>;
|
|
4
|
+
export declare function copyPrompts(projectDir: string, promptsSourceDir: string): Promise<void>;
|
|
5
|
+
export declare function writeMcpManifest(projectDir: string, projectType: ProjectType, requiredMcps: string[]): Promise<void>;
|
|
6
|
+
export declare function writeAgentManifest(projectDir: string): Promise<void>;
|