@c-d-cc/reap 0.5.0 → 0.6.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.ja.md CHANGED
@@ -112,7 +112,7 @@ Objective → Planning → Implementation ⟷ Validation → Completion
112
112
 
113
113
  | ステージ | 内容 | 成果物 |
114
114
  |----------|------|--------|
115
- | **Objective** | 目標 + 要件 + 受入基準の定義 | `01-objective.md` |
115
+ | **Objective** | 構造化ブレインストーミングによる目標・設計定義:明確化質問、アプローチ代案、セクション別設計、ビジュアルコンパニオン、Specレビュー | `01-objective.md` |
116
116
  | **Planning** | タスク分解、実装アプローチ、依存関係 | `02-planning.md` |
117
117
  | **Implementation** | AI+Human協力でコード実装 | `03-implementation.md` |
118
118
  | **Validation** | テスト実行、完了条件の確認 | `04-validation.md` |
package/README.ko.md CHANGED
@@ -112,7 +112,7 @@ Objective → Planning → Implementation ⟷ Validation → Completion
112
112
 
113
113
  | 단계 | 하는 일 | 산출물 |
114
114
  |------|---------|--------|
115
- | **Objective** | 목표 + 요구사항 + 수용기준 정의 | `01-objective.md` |
115
+ | **Objective** | 구조화된 브레인스토밍으로 목표 설계 정의: 명확화 질문, 접근법 대안, 섹션별 설계, 비주얼 컴패니언, Spec 리뷰 | `01-objective.md` |
116
116
  | **Planning** | 태스크 분해, 구현 접근법, 의존관계 | `02-planning.md` |
117
117
  | **Implementation** | AI+Human 협업으로 코드 구현 | `03-implementation.md` |
118
118
  | **Validation** | 테스트 실행, 완료 조건 점검 | `04-validation.md` |
package/README.md CHANGED
@@ -111,7 +111,7 @@ Objective → Planning → Implementation ⟷ Validation → Completion
111
111
 
112
112
  | Stage | What happens | Artifact |
113
113
  |-------|-------------|----------|
114
- | **Objective** | Define goal, requirements, and acceptance criteria | `01-objective.md` |
114
+ | **Objective** | Define goal through structured brainstorming: clarifying questions, 2-3 approach alternatives, sectional design approval, optional visual companion, and spec review loop | `01-objective.md` |
115
115
  | **Planning** | Break down tasks, choose approach, map dependencies | `02-planning.md` |
116
116
  | **Implementation** | Build with AI + human collaboration | `03-implementation.md` |
117
117
  | **Validation** | Run tests, verify completion criteria | `04-validation.md` |
package/README.zh-CN.md CHANGED
@@ -112,7 +112,7 @@ Objective → Planning → Implementation ⟷ Validation → Completion
112
112
 
113
113
  | 阶段 | 内容 | 产出物 |
114
114
  |------|------|--------|
115
- | **Objective** | 定义目标 + 需求 + 验收标准 | `01-objective.md` |
115
+ | **Objective** | 通过结构化头脑风暴定义目标与设计:澄清问题、方案替代、分段设计、视觉伴侣、Spec审查 | `01-objective.md` |
116
116
  | **Planning** | 任务分解、实施方案、依赖关系 | `02-planning.md` |
117
117
  | **Implementation** | AI+人类协作编写代码 | `03-implementation.md` |
118
118
  | **Validation** | 执行测试、检查完成条件 | `04-validation.md` |
package/dist/cli.js CHANGED
@@ -9500,6 +9500,18 @@ async function initProject(projectRoot, projectName, entryMode, preset, onProgre
9500
9500
  const dest = join4(mergeTemplatesDir, file);
9501
9501
  await writeTextFile(dest, await readTextFileOrThrow(src));
9502
9502
  }
9503
+ log("Installing brainstorm server...");
9504
+ const brainstormSourceDir = join4(ReapPaths.packageTemplatesDir, "brainstorm");
9505
+ const brainstormDestDir = join4(paths.root, "brainstorm");
9506
+ await mkdir3(brainstormDestDir, { recursive: true });
9507
+ const brainstormFiles = ["server.cjs", "frame.html", "start-server.sh"];
9508
+ for (const file of brainstormFiles) {
9509
+ const src = join4(brainstormSourceDir, file);
9510
+ const dest = join4(brainstormDestDir, file);
9511
+ await writeTextFile(dest, await readTextFileOrThrow(src));
9512
+ if (file.endsWith(".sh"))
9513
+ await chmod(dest, 493);
9514
+ }
9503
9515
  log("Installing hook conditions...");
9504
9516
  const conditionsSourceDir = join4(ReapPaths.packageTemplatesDir, "conditions");
9505
9517
  const conditionsDestDir = join4(paths.hooks, "conditions");
@@ -9529,7 +9541,7 @@ async function initProject(projectRoot, projectName, entryMode, preset, onProgre
9529
9541
  }
9530
9542
 
9531
9543
  // src/cli/commands/update.ts
9532
- import { readdir as readdir8, unlink as unlink3, rm as rm2, mkdir as mkdir6 } from "fs/promises";
9544
+ import { readdir as readdir8, unlink as unlink3, rm as rm2, mkdir as mkdir6, chmod as chmod2 } from "fs/promises";
9533
9545
  import { join as join9 } from "path";
9534
9546
 
9535
9547
  // src/core/hooks.ts
@@ -10382,6 +10394,26 @@ async function updateProject(projectRoot, dryRun = false) {
10382
10394
  result.updated.push(`~/.reap/templates/merge/${file}`);
10383
10395
  }
10384
10396
  }
10397
+ const brainstormSourceDir = join9(ReapPaths.packageTemplatesDir, "brainstorm");
10398
+ const brainstormDestDir = join9(paths.root, "brainstorm");
10399
+ await mkdir6(brainstormDestDir, { recursive: true });
10400
+ const brainstormFiles = ["server.cjs", "frame.html", "start-server.sh"];
10401
+ for (const file of brainstormFiles) {
10402
+ const src = await readTextFileOrThrow(join9(brainstormSourceDir, file));
10403
+ const dest = join9(brainstormDestDir, file);
10404
+ const existing = await readTextFile(dest);
10405
+ if (existing !== null && existing === src) {
10406
+ result.skipped.push(`.reap/brainstorm/${file}`);
10407
+ } else {
10408
+ if (!dryRun) {
10409
+ await writeTextFile(dest, src);
10410
+ if (file.endsWith(".sh")) {
10411
+ await chmod2(dest, 493);
10412
+ }
10413
+ }
10414
+ result.updated.push(`.reap/brainstorm/${file}`);
10415
+ }
10416
+ }
10385
10417
  const migrations = await migrateHooks(dryRun);
10386
10418
  for (const m of migrations.results) {
10387
10419
  if (m.action === "migrated") {
@@ -10557,7 +10589,7 @@ async function fixProject(projectRoot) {
10557
10589
 
10558
10590
  // src/cli/index.ts
10559
10591
  import { join as join10 } from "path";
10560
- program.name("reap").description("REAP — Recursive Evolutionary Autonomous Pipeline").version("0.5.0");
10592
+ program.name("reap").description("REAP — Recursive Evolutionary Autonomous Pipeline").version("0.6.1");
10561
10593
  program.command("init").description("Initialize a new REAP project (Genesis)").argument("[project-name]", "Project name (defaults to current directory name)").option("-m, --mode <mode>", "Entry mode: greenfield, migration, adoption", "greenfield").option("-p, --preset <preset>", "Bootstrap with a genome preset (e.g., bun-hono-react)").action(async (projectName, options) => {
10562
10594
  try {
10563
10595
  const cwd = process.cwd();
@@ -14,6 +14,23 @@
14
14
  ### Non-Functional Requirements
15
15
 
16
16
 
17
+ ## Design
18
+
19
+ ### Approaches Considered
20
+
21
+ | Aspect | Approach A | Approach B |
22
+ |--------|-----------|-----------|
23
+ | Summary | | |
24
+ | Pros | | |
25
+ | Cons | | |
26
+ | Recommendation | | |
27
+
28
+ ### Selected Design
29
+
30
+
31
+ ### Design Approval History
32
+
33
+
17
34
  ## Scope
18
35
  - **Related Genome Areas**:
19
36
  - **Expected Change Scope**:
@@ -0,0 +1,125 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>REAP Brainstorm</title>
7
+ <style>
8
+ :root {
9
+ --bg: #0f1117;
10
+ --surface: #1a1d27;
11
+ --border: #2a2d3a;
12
+ --text: #e1e4ed;
13
+ --text-muted: #8b8fa3;
14
+ --accent: #6c8cff;
15
+ --accent-soft: rgba(108,140,255,0.12);
16
+ --success: #4ade80;
17
+ --warning: #fbbf24;
18
+ --radius: 8px;
19
+ }
20
+
21
+ * { margin: 0; padding: 0; box-sizing: border-box; }
22
+
23
+ body {
24
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
25
+ background: var(--bg);
26
+ color: var(--text);
27
+ line-height: 1.6;
28
+ padding: 2rem;
29
+ max-width: 960px;
30
+ margin: 0 auto;
31
+ }
32
+
33
+ h2 { font-size: 1.25rem; font-weight: 600; margin-bottom: 1rem; color: var(--text); }
34
+ h3 { font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: var(--text-muted); }
35
+ .subtitle { color: var(--text-muted); font-size: 0.95rem; }
36
+ .section { margin-bottom: 2rem; }
37
+ .label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-bottom: 0.5rem; }
38
+
39
+ /* Options: single/multi select */
40
+ .options { display: flex; flex-direction: column; gap: 0.5rem; }
41
+ .option {
42
+ padding: 1rem 1.25rem;
43
+ border: 1px solid var(--border);
44
+ border-radius: var(--radius);
45
+ cursor: pointer;
46
+ transition: all 0.15s;
47
+ background: var(--surface);
48
+ }
49
+ .option:hover { border-color: var(--accent); background: var(--accent-soft); }
50
+ .option.selected { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 1px var(--accent); }
51
+
52
+ /* Cards: visual design cards */
53
+ .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; }
54
+ .card {
55
+ padding: 1.25rem;
56
+ border: 1px solid var(--border);
57
+ border-radius: var(--radius);
58
+ cursor: pointer;
59
+ transition: all 0.15s;
60
+ background: var(--surface);
61
+ }
62
+ .card:hover { border-color: var(--accent); transform: translateY(-2px); }
63
+ .card.selected { border-color: var(--accent); background: var(--accent-soft); }
64
+ .card h3 { margin-bottom: 0.5rem; }
65
+
66
+ /* Mockup containers */
67
+ .mockup {
68
+ border: 1px solid var(--border);
69
+ border-radius: var(--radius);
70
+ overflow: hidden;
71
+ background: var(--surface);
72
+ }
73
+ .mockup-header {
74
+ padding: 0.5rem 1rem;
75
+ background: var(--border);
76
+ display: flex;
77
+ align-items: center;
78
+ gap: 0.5rem;
79
+ }
80
+ .mockup-header::before {
81
+ content: '';
82
+ display: inline-flex;
83
+ gap: 4px;
84
+ width: 48px;
85
+ height: 12px;
86
+ background: radial-gradient(circle at 6px 6px, #ff5f56 5px, transparent 5px),
87
+ radial-gradient(circle at 22px 6px, #ffbd2e 5px, transparent 5px),
88
+ radial-gradient(circle at 38px 6px, #27c93f 5px, transparent 5px);
89
+ }
90
+ .mockup-body { padding: 1.25rem; }
91
+
92
+ /* Split comparison */
93
+ .split { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
94
+ @media (max-width: 600px) { .split { grid-template-columns: 1fr; } }
95
+
96
+ /* Pros and cons */
97
+ .pros-cons { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
98
+ .pros-cons .pros { color: var(--success); }
99
+ .pros-cons .cons { color: var(--warning); }
100
+ .pros-cons ul { list-style: none; padding: 0; }
101
+ .pros-cons li { padding: 0.25rem 0; }
102
+ .pros-cons .pros li::before { content: '+ '; font-weight: bold; }
103
+ .pros-cons .cons li::before { content: '- '; font-weight: bold; }
104
+
105
+ /* Mock UI elements */
106
+ .mock-nav { height: 48px; background: var(--border); border-radius: var(--radius) var(--radius) 0 0; display: flex; align-items: center; padding: 0 1rem; }
107
+ .mock-sidebar { background: var(--surface); border-right: 1px solid var(--border); padding: 1rem; min-height: 200px; }
108
+ .mock-content { padding: 1rem; flex: 1; }
109
+ .mock-button { display: inline-block; padding: 0.5rem 1rem; background: var(--accent); border-radius: var(--radius); color: white; font-size: 0.85rem; cursor: pointer; }
110
+ .mock-input { display: block; width: 100%; padding: 0.5rem 0.75rem; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); font-size: 0.9rem; }
111
+ .placeholder { background: var(--border); border-radius: 4px; height: 1em; margin: 0.25rem 0; }
112
+
113
+ /* Table for trade-offs */
114
+ table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
115
+ th, td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--border); }
116
+ th { color: var(--text-muted); font-weight: 500; font-size: 0.85rem; }
117
+ </style>
118
+ </head>
119
+ <body>
120
+ {{CONTENT}}
121
+ <script>
122
+ {{WS_SCRIPT}}
123
+ </script>
124
+ </body>
125
+ </html>
@@ -0,0 +1,306 @@
1
+ #!/usr/bin/env node
2
+ // REAP Visual Companion Server
3
+ // Zero-dependency HTTP + WebSocket server using Node.js built-in modules only.
4
+ // Serves HTML fragments from a screen directory, auto-wraps in frame template,
5
+ // watches for file changes and pushes updates via WebSocket.
6
+
7
+ const http = require('http');
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const crypto = require('crypto');
11
+ const url = require('url');
12
+
13
+ // --- Configuration ---
14
+ const PORT = parseInt(process.env.BRAINSTORM_PORT || '3210', 10);
15
+ const HOST = process.env.BRAINSTORM_HOST || '127.0.0.1';
16
+ const URL_HOST = process.env.BRAINSTORM_URL_HOST || `http://${HOST}:${PORT}`;
17
+ const IDLE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
18
+
19
+ // Screen directory: where HTML fragments are written by the AI agent
20
+ const SCREEN_DIR = process.env.BRAINSTORM_DIR || path.join(process.cwd(), '.reap', 'brainstorm');
21
+ const SERVER_INFO_FILE = path.join(SCREEN_DIR, '.server-info');
22
+ const SERVER_STOPPED_FILE = path.join(SCREEN_DIR, '.server-stopped');
23
+ const EVENTS_FILE = path.join(SCREEN_DIR, '.events');
24
+
25
+ // Frame template path (same directory as this script)
26
+ const FRAME_TEMPLATE_PATH = path.join(__dirname, 'frame.html');
27
+
28
+ // --- State ---
29
+ let idleTimer = null;
30
+ const wsClients = new Set();
31
+
32
+ // --- Helpers ---
33
+
34
+ function ensureDir(dir) {
35
+ if (!fs.existsSync(dir)) {
36
+ fs.mkdirSync(dir, { recursive: true });
37
+ }
38
+ }
39
+
40
+ function resetIdleTimer() {
41
+ if (idleTimer) clearTimeout(idleTimer);
42
+ idleTimer = setTimeout(() => {
43
+ console.log('[brainstorm] Idle timeout reached. Shutting down.');
44
+ shutdown();
45
+ }, IDLE_TIMEOUT_MS);
46
+ }
47
+
48
+ function shutdown() {
49
+ try {
50
+ fs.writeFileSync(SERVER_STOPPED_FILE, new Date().toISOString());
51
+ if (fs.existsSync(SERVER_INFO_FILE)) fs.unlinkSync(SERVER_INFO_FILE);
52
+ } catch (_) { /* best effort */ }
53
+ process.exit(0);
54
+ }
55
+
56
+ function getNewestHtmlFile() {
57
+ ensureDir(SCREEN_DIR);
58
+ const files = fs.readdirSync(SCREEN_DIR)
59
+ .filter(f => f.endsWith('.html') && !f.startsWith('.'))
60
+ .map(f => ({ name: f, mtime: fs.statSync(path.join(SCREEN_DIR, f)).mtimeMs }))
61
+ .sort((a, b) => b.mtime - a.mtime);
62
+ return files.length > 0 ? files[0].name : null;
63
+ }
64
+
65
+ function loadFrame() {
66
+ if (fs.existsSync(FRAME_TEMPLATE_PATH)) {
67
+ return fs.readFileSync(FRAME_TEMPLATE_PATH, 'utf-8');
68
+ }
69
+ return '<!DOCTYPE html><html><head><meta charset="utf-8"><title>REAP Brainstorm</title></head><body>{{CONTENT}}<script>{{WS_SCRIPT}}</script></body></html>';
70
+ }
71
+
72
+ function wrapInFrame(content) {
73
+ const frame = loadFrame();
74
+ const wsScript = `
75
+ (function() {
76
+ var ws = new WebSocket('ws://' + location.host + '/ws');
77
+ ws.onmessage = function(e) {
78
+ var data = JSON.parse(e.data);
79
+ if (data.type === 'reload') location.reload();
80
+ };
81
+ ws.onclose = function() { setTimeout(function() { location.reload(); }, 2000); };
82
+
83
+ document.addEventListener('click', function(e) {
84
+ var el = e.target.closest('[data-choice]');
85
+ if (!el) return;
86
+ var container = el.closest('.options, .cards');
87
+ var isMulti = container && container.hasAttribute('data-multiselect');
88
+ if (!isMulti) {
89
+ container.querySelectorAll('[data-choice]').forEach(function(s) { s.classList.remove('selected'); });
90
+ }
91
+ el.classList.toggle('selected');
92
+ var event = {
93
+ type: 'click',
94
+ choice: el.getAttribute('data-choice'),
95
+ text: el.textContent.trim().substring(0, 200),
96
+ timestamp: Math.floor(Date.now() / 1000)
97
+ };
98
+ ws.send(JSON.stringify(event));
99
+ });
100
+ })();`;
101
+
102
+ // Check if content is a full HTML document
103
+ if (content.trim().startsWith('<!DOCTYPE') || content.trim().startsWith('<html')) {
104
+ return content;
105
+ }
106
+ return frame.replace('{{CONTENT}}', content).replace('{{WS_SCRIPT}}', wsScript);
107
+ }
108
+
109
+ // --- WebSocket (RFC 6455 minimal implementation) ---
110
+
111
+ function parseWsFrame(buffer) {
112
+ if (buffer.length < 2) return null;
113
+ const secondByte = buffer[1];
114
+ const masked = (secondByte & 0x80) !== 0;
115
+ let payloadLen = secondByte & 0x7f;
116
+ let offset = 2;
117
+
118
+ if (payloadLen === 126) {
119
+ if (buffer.length < 4) return null;
120
+ payloadLen = buffer.readUInt16BE(2);
121
+ offset = 4;
122
+ } else if (payloadLen === 127) {
123
+ if (buffer.length < 10) return null;
124
+ payloadLen = Number(buffer.readBigUInt64BE(2));
125
+ offset = 10;
126
+ }
127
+
128
+ let maskKey = null;
129
+ if (masked) {
130
+ if (buffer.length < offset + 4) return null;
131
+ maskKey = buffer.slice(offset, offset + 4);
132
+ offset += 4;
133
+ }
134
+
135
+ if (buffer.length < offset + payloadLen) return null;
136
+
137
+ let payload = buffer.slice(offset, offset + payloadLen);
138
+ if (masked && maskKey) {
139
+ for (let i = 0; i < payload.length; i++) {
140
+ payload[i] ^= maskKey[i & 3];
141
+ }
142
+ }
143
+
144
+ const opcode = buffer[0] & 0x0f;
145
+ return { opcode, payload, totalLength: offset + payloadLen };
146
+ }
147
+
148
+ function createWsFrame(data) {
149
+ const payload = Buffer.from(data, 'utf-8');
150
+ const len = payload.length;
151
+ let header;
152
+ if (len < 126) {
153
+ header = Buffer.alloc(2);
154
+ header[0] = 0x81; // FIN + text
155
+ header[1] = len;
156
+ } else if (len < 65536) {
157
+ header = Buffer.alloc(4);
158
+ header[0] = 0x81;
159
+ header[1] = 126;
160
+ header.writeUInt16BE(len, 2);
161
+ } else {
162
+ header = Buffer.alloc(10);
163
+ header[0] = 0x81;
164
+ header[1] = 127;
165
+ header.writeBigUInt64BE(BigInt(len), 2);
166
+ }
167
+ return Buffer.concat([header, payload]);
168
+ }
169
+
170
+ function broadcastWs(message) {
171
+ const frame = createWsFrame(JSON.stringify(message));
172
+ for (const client of wsClients) {
173
+ try { client.write(frame); } catch (_) { wsClients.delete(client); }
174
+ }
175
+ }
176
+
177
+ // --- HTTP Server ---
178
+
179
+ const server = http.createServer((req, res) => {
180
+ resetIdleTimer();
181
+ const parsed = url.parse(req.url, true);
182
+ const pathname = parsed.pathname;
183
+
184
+ // Serve newest HTML file
185
+ if (pathname === '/') {
186
+ const newest = getNewestHtmlFile();
187
+ if (!newest) {
188
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
189
+ res.end(wrapInFrame('<div style="display:flex;align-items:center;justify-content:center;min-height:60vh"><p style="color:#888;font-size:1.2em;">Waiting for content...</p></div>'));
190
+ return;
191
+ }
192
+ const content = fs.readFileSync(path.join(SCREEN_DIR, newest), 'utf-8');
193
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
194
+ res.end(wrapInFrame(content));
195
+ return;
196
+ }
197
+
198
+ // Serve specific files from screen directory
199
+ if (pathname.startsWith('/files/')) {
200
+ const filename = path.basename(pathname);
201
+ const filePath = path.join(SCREEN_DIR, filename);
202
+ if (fs.existsSync(filePath)) {
203
+ const ext = path.extname(filename).toLowerCase();
204
+ const mimeTypes = { '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript', '.png': 'image/png', '.jpg': 'image/jpeg', '.svg': 'image/svg+xml' };
205
+ res.writeHead(200, { 'Content-Type': (mimeTypes[ext] || 'application/octet-stream') + '; charset=utf-8' });
206
+ res.end(fs.readFileSync(filePath));
207
+ return;
208
+ }
209
+ }
210
+
211
+ res.writeHead(404);
212
+ res.end('Not Found');
213
+ });
214
+
215
+ // WebSocket upgrade
216
+ server.on('upgrade', (req, socket) => {
217
+ if (req.url !== '/ws') { socket.destroy(); return; }
218
+
219
+ const key = req.headers['sec-websocket-key'];
220
+ const accept = crypto.createHash('sha1')
221
+ .update(key + '258EAFA5-E914-47DA-95CA-5AB5DC085B11')
222
+ .digest('base64');
223
+
224
+ socket.write(
225
+ 'HTTP/1.1 101 Switching Protocols\r\n' +
226
+ 'Upgrade: websocket\r\n' +
227
+ 'Connection: Upgrade\r\n' +
228
+ `Sec-WebSocket-Accept: ${accept}\r\n\r\n`
229
+ );
230
+
231
+ wsClients.add(socket);
232
+ let buffer = Buffer.alloc(0);
233
+
234
+ socket.on('data', (data) => {
235
+ resetIdleTimer();
236
+ buffer = Buffer.concat([buffer, data]);
237
+ while (true) {
238
+ const frame = parseWsFrame(buffer);
239
+ if (!frame) break;
240
+ buffer = buffer.slice(frame.totalLength);
241
+
242
+ if (frame.opcode === 0x08) { // close
243
+ wsClients.delete(socket);
244
+ socket.end();
245
+ return;
246
+ }
247
+ if (frame.opcode === 0x09) { // ping
248
+ const pong = Buffer.alloc(2);
249
+ pong[0] = 0x8a; pong[1] = 0;
250
+ socket.write(pong);
251
+ continue;
252
+ }
253
+ if (frame.opcode === 0x01) { // text
254
+ try {
255
+ const event = frame.payload.toString('utf-8');
256
+ fs.appendFileSync(EVENTS_FILE, event + '\n');
257
+ } catch (_) { /* best effort */ }
258
+ }
259
+ }
260
+ });
261
+
262
+ socket.on('close', () => wsClients.delete(socket));
263
+ socket.on('error', () => wsClients.delete(socket));
264
+ });
265
+
266
+ // --- File Watcher ---
267
+
268
+ function startWatcher() {
269
+ ensureDir(SCREEN_DIR);
270
+ let debounce = null;
271
+ try {
272
+ fs.watch(SCREEN_DIR, (eventType, filename) => {
273
+ if (!filename || filename.startsWith('.') || !filename.endsWith('.html')) return;
274
+ if (debounce) clearTimeout(debounce);
275
+ debounce = setTimeout(() => {
276
+ // Clear events file when new HTML is pushed
277
+ try { fs.writeFileSync(EVENTS_FILE, ''); } catch (_) {}
278
+ broadcastWs({ type: 'reload' });
279
+ }, 100);
280
+ });
281
+ } catch (err) {
282
+ console.error('[brainstorm] File watcher error:', err.message);
283
+ }
284
+ }
285
+
286
+ // --- Startup ---
287
+
288
+ ensureDir(SCREEN_DIR);
289
+
290
+ // Remove stale stopped marker
291
+ if (fs.existsSync(SERVER_STOPPED_FILE)) {
292
+ fs.unlinkSync(SERVER_STOPPED_FILE);
293
+ }
294
+
295
+ server.listen(PORT, HOST, () => {
296
+ const info = { url: URL_HOST, port: PORT, pid: process.pid, startedAt: new Date().toISOString() };
297
+ fs.writeFileSync(SERVER_INFO_FILE, JSON.stringify(info, null, 2));
298
+ console.log(`[brainstorm] Visual Companion running at ${URL_HOST}`);
299
+ console.log(`[brainstorm] Screen directory: ${SCREEN_DIR}`);
300
+ console.log(`[brainstorm] Idle timeout: 30 minutes`);
301
+ resetIdleTimer();
302
+ startWatcher();
303
+ });
304
+
305
+ process.on('SIGINT', shutdown);
306
+ process.on('SIGTERM', shutdown);
@@ -0,0 +1,52 @@
1
+ # Spec Document Review
2
+
3
+ You are a spec-document-reviewer subagent. Your job is to review the REAP Objective artifact (`01-objective.md`) for quality issues that would cause problems during planning and implementation.
4
+
5
+ ## What to Check
6
+
7
+ | Category | What to Look For |
8
+ |----------|------------------|
9
+ | Completeness | TODOs, placeholders, "TBD", incomplete sections, missing completion criteria |
10
+ | Consistency | Internal contradictions, conflicting requirements, mismatched scope vs requirements |
11
+ | Clarity | Requirements ambiguous enough to cause someone to build the wrong thing |
12
+ | Scope | Focused enough for a single generation — not covering multiple independent subsystems |
13
+ | YAGNI | Unrequested features, over-engineering, unnecessary complexity |
14
+ | Verifiability | Completion criteria that cannot be objectively verified (vague: "improve", "better") |
15
+
16
+ ## Calibration
17
+
18
+ Only flag issues that would cause **real problems** during planning or implementation.
19
+
20
+ **Flag these:**
21
+ - Missing sections that would block planning
22
+ - Contradictions between requirements
23
+ - Ambiguous requirements with multiple valid interpretations
24
+ - Scope too large for a single generation
25
+
26
+ **Do NOT flag:**
27
+ - Minor wording improvements
28
+ - Stylistic preferences
29
+ - Suggestions for additional nice-to-have features
30
+ - Formatting issues
31
+
32
+ ## Output Format
33
+
34
+ ```
35
+ ## Spec Review
36
+
37
+ **Status:** Approved | Issues Found
38
+
39
+ **Issues (if any):**
40
+ - [Section]: [specific issue] — [why it matters for planning]
41
+
42
+ **Recommendations (advisory, do not block approval):**
43
+ - [suggestions for improvement]
44
+ ```
45
+
46
+ ## Important
47
+
48
+ - Read the full `01-objective.md` before starting the review
49
+ - Cross-reference requirements against completion criteria — every criterion should map to at least one FR
50
+ - Check that exclusions are explicitly stated
51
+ - Verify that FR numbering is consistent (FR-001, FR-002, ...)
52
+ - Maximum 3 review iterations — if issues persist after 3 rounds, escalate to the human
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env bash
2
+ # REAP Visual Companion — Server Start Script
3
+ # Usage: start-server.sh [--project-dir /path/to/project] [--port 3210] [--foreground]
4
+
5
+ set -e
6
+
7
+ PROJECT_DIR="$(pwd)"
8
+ PORT="${BRAINSTORM_PORT:-3210}"
9
+ FOREGROUND=false
10
+
11
+ while [[ $# -gt 0 ]]; do
12
+ case "$1" in
13
+ --project-dir) PROJECT_DIR="$2"; shift 2 ;;
14
+ --port) PORT="$2"; shift 2 ;;
15
+ --foreground) FOREGROUND=true; shift ;;
16
+ *) shift ;;
17
+ esac
18
+ done
19
+
20
+ SCREEN_DIR="${PROJECT_DIR}/.reap/brainstorm"
21
+ SERVER_INFO="${SCREEN_DIR}/.server-info"
22
+ SERVER_STOPPED="${SCREEN_DIR}/.server-stopped"
23
+
24
+ # Find server.cjs relative to this script
25
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
26
+ SERVER_JS="${SCRIPT_DIR}/server.cjs"
27
+
28
+ # Ensure screen directory exists
29
+ mkdir -p "${SCREEN_DIR}"
30
+
31
+ # Remove stale stopped marker
32
+ rm -f "${SERVER_STOPPED}"
33
+
34
+ # Check if already running
35
+ if [ -f "${SERVER_INFO}" ]; then
36
+ PID=$(node -e "try{console.log(JSON.parse(require('fs').readFileSync('${SERVER_INFO}','utf-8')).pid)}catch(e){console.log('')}")
37
+ if [ -n "${PID}" ] && kill -0 "${PID}" 2>/dev/null; then
38
+ echo "[brainstorm] Server already running (PID: ${PID})"
39
+ cat "${SERVER_INFO}"
40
+ exit 0
41
+ fi
42
+ # Stale info file
43
+ rm -f "${SERVER_INFO}"
44
+ fi
45
+
46
+ export BRAINSTORM_PORT="${PORT}"
47
+ export BRAINSTORM_DIR="${SCREEN_DIR}"
48
+
49
+ if [ "${FOREGROUND}" = true ]; then
50
+ exec node "${SERVER_JS}"
51
+ else
52
+ nohup node "${SERVER_JS}" > "${SCREEN_DIR}/.server.log" 2>&1 &
53
+ NOHUP_PID=$!
54
+
55
+ # Wait for server-info to appear (max 5 seconds)
56
+ for i in $(seq 1 50); do
57
+ if [ -f "${SERVER_INFO}" ]; then
58
+ echo "[brainstorm] Server started."
59
+ cat "${SERVER_INFO}"
60
+ exit 0
61
+ fi
62
+ sleep 0.1
63
+ done
64
+
65
+ echo "[brainstorm] Warning: server may have failed to start. Check ${SCREEN_DIR}/.server.log"
66
+ exit 1
67
+ fi
@@ -0,0 +1,120 @@
1
+ # Visual Companion Guide
2
+
3
+ > REAP Objective 단계에서 비주얼 컴패니언을 사용하는 가이드.
4
+ > `reap.objective` 슬래시 커맨드가 이 파일을 참조한다.
5
+
6
+ ## 비주얼 컴패니언이란
7
+
8
+ 로컬 Node.js 서버를 통해 브라우저에 목업, 다이어그램, 비교 카드 등을 표시하여 설계 논의를 시각적으로 보조하는 도구.
9
+ 외부 의존 없이 Node.js 내장 모듈만 사용한다.
10
+
11
+ ## 제안 시점
12
+
13
+ Objective Step 5(Goal + Spec Definition) 진입 시, 시각적 질문이 예상되면 컴패니언을 제안한다.
14
+ 제안 메시지는 **독립 메시지**로 보내야 한다 (다른 질문과 합치지 않는다):
15
+
16
+ > "이번 설계에서 목업이나 다이어그램으로 보여드리면 이해하기 쉬운 부분이 있을 수 있습니다.
17
+ > 브라우저에서 시각 자료를 보여드릴 수 있는 비주얼 컴패니언을 사용할까요?
18
+ > (로컬 서버를 띄워 브라우저에서 확인하는 방식입니다)"
19
+
20
+ 유저가 거부하면 터미널 전용으로 진행한다.
21
+
22
+ ## 브라우저 vs 터미널 판단 규칙
23
+
24
+ 각 질문마다 판단: **유저가 읽는 것보다 보는 것이 이해에 도움이 되는가?**
25
+
26
+ ### 브라우저 사용
27
+ - UI 목업, 와이어프레임, 레이아웃
28
+ - 아키텍처 다이어그램, 시스템 구성도, 데이터 흐름 맵
29
+ - 나란히 비교 (레이아웃, 색상, 디자인 방향)
30
+ - 디자인 폴리시 (느낌, 간격, 비주얼 위계)
31
+ - 공간 관계 (상태 머신, 플로우차트, ERD를 다이어그램으로)
32
+
33
+ ### 터미널 사용
34
+ - 요구사항, 범위 질문 ("X는 무슨 뜻인가요?")
35
+ - 개념적 A/B/C 선택 (텍스트로 설명 가능한 접근법)
36
+ - 트레이드오프 목록, 비교표
37
+ - 기술 결정 (API 설계, 데이터 모델링, 아키텍처 접근)
38
+ - 명확화 질문 (답이 시각적 선호가 아닌 말)
39
+
40
+ ### 핵심 테스트
41
+
42
+ UI 관련 질문이라도 자동으로 비주얼은 아니다.
43
+ - "어떤 종류의 마법사를 원하시나요?" → 개념적 → **터미널**
44
+ - "어떤 마법사 레이아웃이 좋으세요?" → 시각적 → **브라우저**
45
+
46
+ ## 서버 기동
47
+
48
+ ```bash
49
+ # 프로젝트 루트에서 실행
50
+ bash .reap/brainstorm/start-server.sh
51
+ # 또는 직접
52
+ node .reap/brainstorm/server.cjs
53
+ ```
54
+
55
+ - `BRAINSTORM_PORT` 환경 변수로 포트 변경 (기본: 3210)
56
+ - `BRAINSTORM_DIR` 환경 변수로 스크린 디렉토리 변경 (기본: `.reap/brainstorm/`)
57
+
58
+ ## 서버 상태 확인
59
+
60
+ - `.reap/brainstorm/.server-info` — 서버 실행 중이면 JSON 존재 (url, port, pid)
61
+ - `.reap/brainstorm/.server-stopped` — 서버가 종료되면 생성됨
62
+ - 서버가 종료된 상태에서 재기동 필요: `start-server.sh` 재실행
63
+
64
+ ## HTML 작성 규칙
65
+
66
+ 1. `.reap/brainstorm/` 디렉토리에 HTML 파일을 Write 도구로 작성
67
+ 2. 시맨틱 파일명 사용 (`architecture.html`, `layout-options.html`)
68
+ 3. 파일명 재사용 금지 (수정 시 `layout-v2.html` 사용)
69
+ 4. **Content fragment 기본** — `<!DOCTYPE` 없이 본문만 작성하면 프레임 템플릿이 자동 래핑
70
+ 5. 전체 HTML 제어가 필요한 경우만 full document 작성
71
+
72
+ ## 사용 가능한 CSS 클래스
73
+
74
+ | 클래스 | 용도 |
75
+ |--------|------|
76
+ | `.options` + `.option[data-choice]` | A/B/C 단일 선택 |
77
+ | `.options[data-multiselect]` | 다중 선택 |
78
+ | `.cards` + `.card[data-choice]` | 비주얼 디자인 카드 |
79
+ | `.mockup` + `.mockup-header` + `.mockup-body` | 목업 컨테이너 |
80
+ | `.split` | 나란히 비교 |
81
+ | `.pros-cons` + `.pros` + `.cons` | 장단점 |
82
+ | `.mock-nav`, `.mock-sidebar`, `.mock-content` | 목업 UI 요소 |
83
+ | `.mock-button`, `.mock-input` | 목업 인터랙티브 요소 |
84
+ | `.placeholder` | 플레이스홀더 블록 |
85
+ | `table`, `h2`, `h3`, `.subtitle`, `.section`, `.label` | 타이포그래피 |
86
+
87
+ ## 이벤트 읽기
88
+
89
+ 유저가 브라우저에서 `[data-choice]` 요소를 클릭하면 WebSocket을 통해 `.events` 파일에 JSON Lines로 기록된다:
90
+
91
+ ```json
92
+ {"type":"click","choice":"a","text":"Option A","timestamp":1706000101}
93
+ ```
94
+
95
+ - 터미널 메시지가 주 피드백 채널
96
+ - `.events` 파일은 보조 인터랙션 데이터
97
+ - 새 HTML 파일 푸시 시 `.events`는 자동 초기화
98
+
99
+ ## 턴 기반 흐름
100
+
101
+ 1. HTML 파일을 Write 도구로 작성
102
+ 2. 유저에게 URL 안내 + 간략한 텍스트 설명 → **턴 종료**
103
+ 3. 다음 턴에서 `.events` 파일 읽기 (유저 인터랙션 확인)
104
+ 4. 터미널 메시지 + `.events`를 종합하여 다음 단계 진행
105
+ 5. 터미널로 돌아갈 때 대기 화면 푸시:
106
+ ```html
107
+ <div style="display:flex;align-items:center;justify-content:center;min-height:60vh">
108
+ <p class="subtitle">터미널에서 계속 진행 중...</p>
109
+ </div>
110
+ ```
111
+
112
+ ## 조건부 실행
113
+
114
+ 비주얼 컴패니언은 brainstorming이 활성화된 경우에만 제안된다.
115
+ brainstorming 자체가 목표 복잡도에 따라 조건부로 실행되므로, 단순 태스크(bugfix, config, docs-only)에서는 비주얼 컴패니언도 제안되지 않는다.
116
+
117
+ ## evolve 모드에서의 동작
118
+
119
+ `/reap.evolve`의 Autonomous Override가 활성화되어 있어도, brainstorming 진입 시 비주얼 컴패니언 제안은 수행한다.
120
+ 유저가 명시적으로 거부한 경우에만 스킵한다.
@@ -2,11 +2,12 @@
2
2
  description: "REAP Objective — Define the goal and specification for this Generation"
3
3
  ---
4
4
 
5
- # Objective (Goal Definition)
5
+ # Objective (Goal Definition + Brainstorming Design)
6
6
 
7
7
  <HARD-GATE>
8
8
  Do NOT write any code until the artifact (01-objective.md) has been confirmed by the human.
9
9
  If the goal is ambiguous, do NOT guess — STOP and ask the human. This is non-negotiable.
10
+ Brainstorming is triggered based on goal complexity — simple tasks skip it, complex tasks require it. The human can always override the AI's assessment.
10
11
  </HARD-GATE>
11
12
 
12
13
  ## Gate (Preconditions)
@@ -107,13 +108,97 @@ If the goal is ambiguous, do NOT guess — STOP and ask the human. This is non-n
107
108
  - **constraints.md has empty Validation Commands** → flag as "test commands undefined"
108
109
  - Report the genome health status to the human
109
110
 
110
- ### 5. Goal + Spec Definition
111
- - Based on the above information, converse with the human to refine this generation's goal
112
- - If genome enhancement is needed, discuss whether to include it in this generation's goal
113
- - Criteria for a good goal:
114
- - Achievable within a single Generation
115
- - Verifiable completion criteria (no vague wording)
116
- - Relevant genome areas are clearly identified
111
+ ### 5. Goal + Spec Definition (with optional Brainstorming)
112
+
113
+ Before entering brainstorming, evaluate whether the goal requires it.
114
+
115
+ #### Complexity Gate
116
+ Assess the goal's complexity based on these criteria:
117
+
118
+ **Skip brainstorming** (proceed directly to Step 6 with simple goal+spec definition):
119
+ - Simple bugfix with clear cause and fix
120
+ - Configuration change or settings adjustment
121
+ - Documentation-only changes
122
+ - Single-file refactoring with obvious approach
123
+ - Tasks where the "what" and "how" are both already clear
124
+
125
+ **Enter brainstorming** (follow sub-steps 5a–5e):
126
+ - New feature development spanning multiple components
127
+ - Architecture changes or new module design
128
+ - Tasks with multiple valid implementation approaches
129
+ - Requirements that need further exploration or clarification
130
+ - Integration with external systems or complex data flows
131
+
132
+ **Under Autonomous Override**: Assess automatically. If the goal from `current.yml` clearly fits "skip" criteria, skip brainstorming.
133
+ **Human override**: The human can always request brainstorming ("let's brainstorm this") or skip it ("just do it", "skip brainstorming") regardless of the AI's assessment.
134
+
135
+ When skipping brainstorming, converse with the human to refine the goal:
136
+ - Criteria for a good goal: achievable within a single Generation, verifiable completion criteria (no vague wording), relevant genome areas identified
137
+ - Then proceed directly to Step 6 (Genome Gap Analysis)
138
+
139
+ When entering brainstorming, follow the structured brainstorming process below to produce a well-designed objective. Follow the sub-steps in order.
140
+
141
+ #### 5a. Visual Companion Proposal
142
+ - Evaluate whether this generation's goal involves visual questions (UI design, architecture diagrams, layout comparisons, etc.)
143
+ - If visual questions are likely, propose the Visual Companion in a **standalone message** (do NOT combine with other questions):
144
+ > "이번 설계에서 목업이나 다이어그램으로 보여드리면 이해하기 쉬운 부분이 있을 수 있습니다.
145
+ > 브라우저에서 시각 자료를 보여드릴 수 있는 비주얼 컴패니언을 사용할까요?
146
+ > (로컬 서버를 띄워 브라우저에서 확인하는 방식입니다)"
147
+ - If the human accepts: start the brainstorm server (`bash` the start script in `.reap/brainstorm/start-server.sh` or `node` the server directly). Read `src/templates/brainstorm/visual-companion-guide.md` for usage rules.
148
+ - If the human declines: proceed terminal-only. Do NOT offer again.
149
+ - **This step applies even under `/reap.evolve` Autonomous Override** — only skip if the human has explicitly declined.
150
+
151
+ #### 5b. Clarifying Questions (One at a Time)
152
+ - **CRITICAL**: Ask only ONE question per message. Never bundle multiple questions.
153
+ - Prefer **multiple choice** over open-ended questions when possible.
154
+ - Goal: understand purpose, constraints, success criteria, and scope.
155
+ - Continue asking until you have enough information to propose approaches.
156
+ - Good question flow:
157
+ 1. Purpose/motivation: "What problem does this solve?"
158
+ 2. Users/stakeholders: "Who benefits from this?"
159
+ 3. Constraints: "Are there any hard constraints?" (with examples as choices)
160
+ 4. Success criteria: "How will you know this is done?"
161
+ - Under Autonomous Override: Use existing context (genome, backlog, goal from `current.yml`) to answer these questions yourself. Only STOP and ask if genuinely ambiguous.
162
+
163
+ #### 5c. Approach Exploration (2-3 Alternatives)
164
+ - Propose **2-3 approaches** with clear trade-offs.
165
+ - Present as a comparison table:
166
+
167
+ | Aspect | Approach A | Approach B | Approach C |
168
+ |--------|-----------|-----------|-----------|
169
+ | Summary | ... | ... | ... |
170
+ | Pros | ... | ... | ... |
171
+ | Cons | ... | ... | ... |
172
+ | Complexity | ... | ... | ... |
173
+ | Recommendation | ... | ... | ... |
174
+
175
+ - Include a clear recommendation with reasoning.
176
+ - If using Visual Companion: show approaches visually in the browser for comparison.
177
+ - If only one sensible approach exists, state why alternatives were considered but dismissed.
178
+ - Wait for the human to choose (or confirm the recommendation).
179
+ - Under Autonomous Override: choose the recommended approach and proceed.
180
+
181
+ #### 5d. Sectional Design Approval
182
+ - Present the design in sections, scaled to complexity:
183
+ - **Simple** (few sentences per section): small feature, bug fix, config change
184
+ - **Medium** (1-2 paragraphs per section): new module, refactoring, integration
185
+ - **Detailed** (200-300 words per section): new system, major architecture change
186
+ - Sections to cover (skip if not applicable):
187
+ 1. **Architecture** — high-level structure, module relationships
188
+ 2. **Components** — key components and their responsibilities
189
+ 3. **Data Flow** — how data moves through the system
190
+ 4. **Error Handling** — failure modes and recovery strategies
191
+ 5. **Testing Strategy** — what and how to test
192
+ - **After each section**, ask: "Does this look right so far?" (or confirm under Autonomous Override)
193
+ - If using Visual Companion: show architecture/data flow diagrams in the browser.
194
+ - Iterate until the human approves each section.
195
+
196
+ #### 5e. Scope Decomposition Check
197
+ - **Check for multi-subsystem scope**: If the goal describes 2+ independent subsystems (e.g., "build chat + file storage + billing"):
198
+ - Flag immediately: "This goal covers multiple independent subsystems. I recommend splitting into separate Generations."
199
+ - Help decompose into sub-goals, each getting its own Generation.
200
+ - **Check FR count**: If functional requirements exceed 10, warn and suggest splitting.
201
+ - Under Autonomous Override: if scope is clearly single-subsystem, proceed without asking.
117
202
 
118
203
  ### 6. Genome Gap Analysis
119
204
  - Identify information required to achieve the goal that is missing from the genome
@@ -135,6 +220,14 @@ If the goal is ambiguous, do NOT guess — STOP and ask the human. This is non-n
135
220
  - **Limit**: Maximum 7 completion criteria. Each must be verifiable.
136
221
  - Finalize with the human
137
222
 
223
+ ### 8. Spec Review Loop
224
+ - After the artifact is complete, dispatch a **spec-document-reviewer subagent** (using the Agent tool with the prompt from `src/templates/brainstorm/spec-reviewer-prompt.md`):
225
+ - The subagent reads `.reap/life/01-objective.md` and reviews for completeness, consistency, clarity, scope, YAGNI, and verifiability.
226
+ - If **Issues Found**: fix the issues in the artifact and re-dispatch the reviewer.
227
+ - If **Approved**: proceed to human review.
228
+ - **Maximum 3 iterations**. If issues persist after 3 rounds, present remaining issues to the human for decision.
229
+ - Under Autonomous Override: run the review loop automatically. Only escalate if the reviewer flags blocking issues after 3 rounds.
230
+
138
231
  ## Escalation
139
232
  In the following situations, do NOT guess — **STOP and ask the human**:
140
233
  - When the scope of the goal is unclear
@@ -147,6 +240,8 @@ Before saving the artifact, verify:
147
240
  - [ ] Are all completion criteria verifiable? (No vague wording like "improve" or "make better"?)
148
241
  - [ ] Are exclusions explicitly stated in the scope?
149
242
  - [ ] Do functional requirements have FR-XXX numbering?
243
+ - [ ] Does the Design section include the chosen approach with rationale?
244
+ - [ ] Has the spec review loop completed (approved or human-overridden)?
150
245
 
151
246
  ❌ Bad completion criterion: "Stabilize the service"
152
247
  ✅ Good completion criterion: "`npm run lint` reports 0 errors, `npm run build` succeeds"
@@ -159,9 +254,10 @@ Before saving the artifact, verify:
159
254
  - After Previous Generation Reference → update Background section
160
255
  - After Backlog Review → update Background section
161
256
  - After Genome Health Check → update Genome Reference section
162
- - After Goal + Spec Definition → update Goal, Scope sections
257
+ - After Brainstorming Design (5a-5e) → update Goal, Scope, Design sections
163
258
  - After Genome Gap Analysis → update Backlog section
164
259
  - After Requirements Finalization → update Requirements, Completion Criteria sections
260
+ - After Spec Review Loop → update with any review-driven changes
165
261
  - The artifact should reflect the **current state of work at all times**
166
262
  - Do NOT wait until the end to write the artifact
167
263
 
@@ -47,7 +47,7 @@ Objective → Planning → Implementation ⟷ Validation → Completion
47
47
 
48
48
  | Stage | Description | What it does | Artifact |
49
49
  |-------|-------------|--------------|----------|
50
- | **Objective** | Goal definition | Define this generation's goal + requirements. Reference environment, backlog, genome | `01-objective.md` |
50
+ | **Objective** | Goal definition + brainstorming design | Define goal + requirements through structured brainstorming: clarifying questions, 2-3 approach alternatives, sectional design approval, visual companion (optional), and spec review loop. Reference environment, backlog, genome | `01-objective.md` |
51
51
  | **Planning** | Plan formulation | Task decomposition, dependencies, implementation approach | `02-planning.md` |
52
52
  | **Implementation** | Implementation | AI+Human collaboration to write code. Record genome defects in backlog when found | `03-implementation.md` |
53
53
  | **Validation** | Verification | Run tests, check completion criteria. Can regress to Implementation on failure | `04-validation.md` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c-d-cc/reap",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "description": "Recursive Evolutionary Autonomous Pipeline — AI and humans evolve software across generations",
5
5
  "type": "module",
6
6
  "license": "MIT",