@c-d-cc/reap 0.7.4 → 0.7.6

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/dist/cli.js CHANGED
@@ -9830,18 +9830,6 @@ async function initProject(projectRoot, projectName, entryMode, preset, onProgre
9830
9830
  const dest = join5(mergeTemplatesDir, file);
9831
9831
  await writeTextFile(dest, await readTextFileOrThrow(src));
9832
9832
  }
9833
- log("Installing brainstorm server...");
9834
- const brainstormSourceDir = join5(ReapPaths.packageTemplatesDir, "brainstorm");
9835
- const brainstormDestDir = join5(paths.root, "brainstorm");
9836
- await mkdir3(brainstormDestDir, { recursive: true });
9837
- const brainstormFiles = ["server.cjs", "frame.html", "start-server.sh"];
9838
- for (const file of brainstormFiles) {
9839
- const src = join5(brainstormSourceDir, file);
9840
- const dest = join5(brainstormDestDir, file);
9841
- await writeTextFile(dest, await readTextFileOrThrow(src));
9842
- if (file.endsWith(".sh"))
9843
- await chmod(dest, 493);
9844
- }
9845
9833
  log("Installing hook conditions...");
9846
9834
  const conditionsSourceDir = join5(ReapPaths.packageTemplatesDir, "conditions");
9847
9835
  const conditionsDestDir = join5(paths.hooks, "conditions");
@@ -9871,7 +9859,7 @@ async function initProject(projectRoot, projectName, entryMode, preset, onProgre
9871
9859
  }
9872
9860
 
9873
9861
  // src/cli/commands/update.ts
9874
- import { readdir as readdir9, unlink as unlink3, rm as rm2, mkdir as mkdir6, chmod as chmod2 } from "fs/promises";
9862
+ import { readdir as readdir9, unlink as unlink3, rm as rm2, mkdir as mkdir6 } from "fs/promises";
9875
9863
  import { join as join10 } from "path";
9876
9864
 
9877
9865
  // src/core/hooks.ts
@@ -10661,11 +10649,8 @@ async function migrateLineage(paths) {
10661
10649
  // src/cli/commands/update.ts
10662
10650
  async function updateProject(projectRoot, dryRun = false) {
10663
10651
  const paths = new ReapPaths(projectRoot);
10664
- if (!await paths.isReapProject()) {
10665
- throw new Error("Not a REAP project. Run 'reap init' first.");
10666
- }
10667
10652
  const result = { updated: [], skipped: [], removed: [] };
10668
- const config = await ConfigManager.read(paths);
10653
+ const config = await paths.isReapProject() ? await ConfigManager.read(paths) : null;
10669
10654
  const adapters = await AgentRegistry.getActiveAdapters(config ?? undefined);
10670
10655
  const commandsDir = ReapPaths.packageCommandsDir;
10671
10656
  const commandFiles = await readdir9(commandsDir);
@@ -10742,26 +10727,6 @@ async function updateProject(projectRoot, dryRun = false) {
10742
10727
  result.updated.push(`~/.reap/templates/merge/${file}`);
10743
10728
  }
10744
10729
  }
10745
- const brainstormSourceDir = join10(ReapPaths.packageTemplatesDir, "brainstorm");
10746
- const brainstormDestDir = join10(paths.root, "brainstorm");
10747
- await mkdir6(brainstormDestDir, { recursive: true });
10748
- const brainstormFiles = ["server.cjs", "frame.html", "start-server.sh"];
10749
- for (const file of brainstormFiles) {
10750
- const src = await readTextFileOrThrow(join10(brainstormSourceDir, file));
10751
- const dest = join10(brainstormDestDir, file);
10752
- const existing = await readTextFile(dest);
10753
- if (existing !== null && existing === src) {
10754
- result.skipped.push(`.reap/brainstorm/${file}`);
10755
- } else {
10756
- if (!dryRun) {
10757
- await writeTextFile(dest, src);
10758
- if (file.endsWith(".sh")) {
10759
- await chmod2(dest, 493);
10760
- }
10761
- }
10762
- result.updated.push(`.reap/brainstorm/${file}`);
10763
- }
10764
- }
10765
10730
  const migrations = await migrateHooks(dryRun);
10766
10731
  for (const m of migrations.results) {
10767
10732
  if (m.action === "migrated") {
@@ -10776,18 +10741,20 @@ async function updateProject(projectRoot, dryRun = false) {
10776
10741
  result.skipped.push(`[${adapter.displayName}] session hook`);
10777
10742
  }
10778
10743
  }
10779
- await migrateLegacyFiles(paths, dryRun, result);
10780
- if (await needsMigration(paths)) {
10781
- if (!dryRun) {
10782
- const migrationResult = await migrateLineage(paths);
10783
- for (const m of migrationResult.migrated) {
10784
- result.updated.push(`[lineage] ${m}`);
10785
- }
10786
- for (const e of migrationResult.errors) {
10787
- result.removed.push(`[lineage error] ${e}`);
10744
+ if (await paths.isReapProject()) {
10745
+ await migrateLegacyFiles(paths, dryRun, result);
10746
+ if (await needsMigration(paths)) {
10747
+ if (!dryRun) {
10748
+ const migrationResult = await migrateLineage(paths);
10749
+ for (const m of migrationResult.migrated) {
10750
+ result.updated.push(`[lineage] ${m}`);
10751
+ }
10752
+ for (const e of migrationResult.errors) {
10753
+ result.removed.push(`[lineage error] ${e}`);
10754
+ }
10755
+ } else {
10756
+ result.updated.push("[lineage] DAG migration pending (dry-run)");
10788
10757
  }
10789
- } else {
10790
- result.updated.push("[lineage] DAG migration pending (dry-run)");
10791
10758
  }
10792
10759
  }
10793
10760
  return result;
@@ -10939,7 +10906,7 @@ async function fixProject(projectRoot) {
10939
10906
  // src/cli/index.ts
10940
10907
  init_fs();
10941
10908
  import { join as join11 } from "path";
10942
- program.name("reap").description("REAP — Recursive Evolutionary Autonomous Pipeline").version("0.7.4");
10909
+ program.name("reap").description("REAP — Recursive Evolutionary Autonomous Pipeline").version("0.7.6");
10943
10910
  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) => {
10944
10911
  try {
10945
10912
  const cwd = process.cwd();
@@ -45,15 +45,17 @@ UI 관련 질문이라도 자동으로 비주얼은 아니다.
45
45
 
46
46
  ## 서버 기동
47
47
 
48
+ 서버 파일은 REAP 패키지에 포함되어 있으므로 프로젝트에 복사할 필요 없음.
49
+
48
50
  ```bash
49
- # 프로젝트 루트에서 실행
50
- bash .reap/brainstorm/start-server.sh
51
- # 또는 직접
52
- node .reap/brainstorm/server.cjs
51
+ # npm 글로벌 패키지 경로에서 실행
52
+ node "$(npm root -g)/@c-d-cc/reap/dist/templates/brainstorm/server.cjs"
53
+ # 또는 start-server.sh 사용
54
+ bash "$(npm root -g)/@c-d-cc/reap/dist/templates/brainstorm/start-server.sh"
53
55
  ```
54
56
 
55
57
  - `BRAINSTORM_PORT` 환경 변수로 포트 변경 (기본: 3210)
56
- - `BRAINSTORM_DIR` 환경 변수로 스크린 디렉토리 변경 (기본: `.reap/brainstorm/`)
58
+ - `BRAINSTORM_DIR` 환경 변수로 스크린 디렉토리 변경 (기본: `.reap/brainstorm/` — HTML 파일만 저장)
57
59
 
58
60
  ## 서버 상태 확인
59
61
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c-d-cc/reap",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Recursive Evolutionary Autonomous Pipeline — AI and humans evolve software across generations",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,56 +1,51 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * postinstall — install REAP slash commands to detected AI agents.
3
+ * postinstall — install REAP slash commands to ~/.reap/commands/.
4
4
  * Runs after `npm install -g @c-d-cc/reap`.
5
+ * Project-level symlinks are created by session-start.cjs at session time.
5
6
  * Graceful: never fails npm install (always exits 0).
6
7
  */
7
- const { execSync } = require("child_process");
8
- const { readdirSync, readFileSync, writeFileSync, mkdirSync, existsSync } = require("fs");
8
+ const { readdirSync, readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } = require("fs");
9
9
  const { join, dirname } = require("path");
10
10
  const { homedir } = require("os");
11
11
 
12
- const AGENTS = [
13
- { name: "Claude Code", bin: "claude", commandsDir: join(homedir(), ".claude", "commands") },
14
- { name: "OpenCode", bin: "opencode", commandsDir: join(homedir(), ".config", "opencode", "commands") },
15
- ];
16
-
17
- function isInstalled(bin) {
18
- try {
19
- execSync(`which ${bin}`, { stdio: "ignore" });
20
- return true;
21
- } catch {
22
- return false;
23
- }
24
- }
25
-
26
12
  try {
27
13
  // Resolve commands source: dist/templates/commands/ relative to this script
28
14
  const commandsSource = join(dirname(__dirname), "dist", "templates", "commands");
29
15
  if (!existsSync(commandsSource)) {
30
- // During development or if dist not built yet, skip silently
31
16
  process.exit(0);
32
17
  }
33
18
 
34
19
  const commandFiles = readdirSync(commandsSource).filter(f => f.endsWith(".md"));
35
20
  if (commandFiles.length === 0) process.exit(0);
36
21
 
37
- let installed = 0;
38
- for (const agent of AGENTS) {
39
- if (!isInstalled(agent.bin)) continue;
40
-
41
- mkdirSync(agent.commandsDir, { recursive: true });
42
- for (const file of commandFiles) {
43
- const src = readFileSync(join(commandsSource, file), "utf-8");
44
- writeFileSync(join(agent.commandsDir, file), src);
45
- }
46
- installed++;
47
- console.log(` reap: ${agent.name} — ${commandFiles.length} slash commands installed`);
22
+ // Install originals to ~/.reap/commands/
23
+ const reapCommandsDir = join(homedir(), ".reap", "commands");
24
+ mkdirSync(reapCommandsDir, { recursive: true });
25
+ for (const file of commandFiles) {
26
+ const src = readFileSync(join(commandsSource, file), "utf-8");
27
+ writeFileSync(join(reapCommandsDir, file), src);
48
28
  }
29
+ console.log(` reap: ${commandFiles.length} slash commands installed to ~/.reap/commands/`);
49
30
 
50
- if (installed === 0) {
51
- console.log(" reap: no supported AI agents detected (claude, opencode). Run 'reap update' after installing one.");
31
+ // Phase 2 cleanup: remove redirect stubs from agent user-level dirs
32
+ const agentDirs = [
33
+ join(homedir(), ".claude", "commands"),
34
+ join(homedir(), ".config", "opencode", "commands"),
35
+ ];
36
+ for (const agentDir of agentDirs) {
37
+ if (!existsSync(agentDir)) continue;
38
+ try {
39
+ const files = readdirSync(agentDir).filter(f => f.startsWith("reap.") && f.endsWith(".md"));
40
+ for (const file of files) {
41
+ const filePath = join(agentDir, file);
42
+ const content = readFileSync(filePath, "utf-8");
43
+ if (content.includes("redirected to ~/.reap/commands/")) {
44
+ unlinkSync(filePath);
45
+ }
46
+ }
47
+ } catch { /* best effort */ }
52
48
  }
53
49
  } catch (err) {
54
- // Graceful failure — never break npm install
55
50
  console.warn(" reap: postinstall warning —", err.message);
56
51
  }