@c-d-cc/reap 0.15.15 → 0.15.16

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/RELEASE_NOTICE.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Release Notices
2
2
 
3
+ ## v0.15.16
4
+ ### en
5
+ Upgrade hand-off: `reap update` now delegates to the new binary after self-upgrade, ensuring seamless v0.16.0 migration. Config now tracks `lastCliVersion`.
6
+ ### ko
7
+ 업그레이드 hand-off: `reap update`가 self-upgrade 후 새 바이너리에 위임하여 v0.16.0 마이그레이션을 원활하게 처리. config에 `lastCliVersion` 기록 시작.
8
+
3
9
  ## v0.15.15
4
10
  ### en
5
11
  Added v0.16 breaking change pre-announcement to README.
package/dist/cli.js CHANGED
@@ -7165,6 +7165,38 @@ async function fileExists(path) {
7165
7165
  }
7166
7166
  var init_fs = () => {};
7167
7167
 
7168
+ // src/core/version.ts
7169
+ import { execSync } from "child_process";
7170
+ function checkLatestVersion() {
7171
+ try {
7172
+ const result = execSync("npm view @c-d-cc/reap version", {
7173
+ timeout: 2000,
7174
+ encoding: "utf-8",
7175
+ stdio: ["pipe", "pipe", "pipe"]
7176
+ });
7177
+ return result.trim() || null;
7178
+ } catch {
7179
+ return null;
7180
+ }
7181
+ }
7182
+ function getCurrentVersion() {
7183
+ return "0.15.16";
7184
+ }
7185
+ function formatVersionLine(current, skipCheck) {
7186
+ if (skipCheck) {
7187
+ return `REAP v${current}`;
7188
+ }
7189
+ const latest = checkLatestVersion();
7190
+ if (!latest) {
7191
+ return `REAP v${current}`;
7192
+ }
7193
+ if (latest === current) {
7194
+ return `REAP v${current} (latest)`;
7195
+ }
7196
+ return `REAP v${current} (update available: ${latest})`;
7197
+ }
7198
+ var init_version = () => {};
7199
+
7168
7200
  // src/core/config.ts
7169
7201
  class ConfigManager {
7170
7202
  static async read(paths) {
@@ -7206,6 +7238,11 @@ class ConfigManager {
7206
7238
  delete config.lastSyncedCommit;
7207
7239
  added.push("lastSyncedCommit(removed)");
7208
7240
  }
7241
+ const currentVersion = getCurrentVersion();
7242
+ if (config.lastCliVersion !== currentVersion) {
7243
+ config.lastCliVersion = currentVersion;
7244
+ added.push("lastCliVersion");
7245
+ }
7209
7246
  if (added.length > 0) {
7210
7247
  await ConfigManager.write(paths, config);
7211
7248
  }
@@ -7227,6 +7264,7 @@ class ConfigManager {
7227
7264
  var import_yaml;
7228
7265
  var init_config = __esm(() => {
7229
7266
  init_fs();
7267
+ init_version();
7230
7268
  import_yaml = __toESM(require_dist(), 1);
7231
7269
  });
7232
7270
 
@@ -7592,17 +7630,17 @@ var init_lifecycle = __esm(() => {
7592
7630
  });
7593
7631
 
7594
7632
  // src/core/git.ts
7595
- import { execSync } from "child_process";
7633
+ import { execSync as execSync2 } from "child_process";
7596
7634
  function gitShow(ref, path, cwd) {
7597
7635
  try {
7598
- return execSync(`git show ${ref}:${path}`, { cwd, encoding: "utf-8", timeout: 1e4 });
7636
+ return execSync2(`git show ${ref}:${path}`, { cwd, encoding: "utf-8", timeout: 1e4 });
7599
7637
  } catch {
7600
7638
  return null;
7601
7639
  }
7602
7640
  }
7603
7641
  function gitLsTree(ref, path, cwd) {
7604
7642
  try {
7605
- const output = execSync(`git ls-tree -r --name-only ${ref} -- ${path}`, {
7643
+ const output = execSync2(`git ls-tree -r --name-only ${ref} -- ${path}`, {
7606
7644
  cwd,
7607
7645
  encoding: "utf-8",
7608
7646
  timeout: 1e4
@@ -7615,7 +7653,7 @@ function gitLsTree(ref, path, cwd) {
7615
7653
  }
7616
7654
  function gitRefExists(ref, cwd) {
7617
7655
  try {
7618
- execSync(`git rev-parse --verify ${ref}`, { cwd, encoding: "utf-8", timeout: 5000 });
7656
+ execSync2(`git rev-parse --verify ${ref}`, { cwd, encoding: "utf-8", timeout: 5000 });
7619
7657
  return true;
7620
7658
  } catch {
7621
7659
  return false;
@@ -7623,7 +7661,7 @@ function gitRefExists(ref, cwd) {
7623
7661
  }
7624
7662
  function gitAllBranches(cwd) {
7625
7663
  try {
7626
- const output = execSync("git branch -a --format='%(refname:short)'", {
7664
+ const output = execSync2("git branch -a --format='%(refname:short)'", {
7627
7665
  cwd,
7628
7666
  encoding: "utf-8",
7629
7667
  timeout: 1e4
@@ -7636,7 +7674,7 @@ function gitAllBranches(cwd) {
7636
7674
  }
7637
7675
  function gitCurrentBranch(cwd) {
7638
7676
  try {
7639
- return execSync("git rev-parse --abbrev-ref HEAD", { cwd, encoding: "utf-8", timeout: 5000 }).trim();
7677
+ return execSync2("git rev-parse --abbrev-ref HEAD", { cwd, encoding: "utf-8", timeout: 5000 }).trim();
7640
7678
  } catch {
7641
7679
  return null;
7642
7680
  }
@@ -8376,38 +8414,6 @@ var init_generation = __esm(() => {
8376
8414
  import_yaml4 = __toESM(require_dist(), 1);
8377
8415
  });
8378
8416
 
8379
- // src/core/version.ts
8380
- import { execSync as execSync4 } from "child_process";
8381
- function checkLatestVersion() {
8382
- try {
8383
- const result = execSync4("npm view @c-d-cc/reap version", {
8384
- timeout: 2000,
8385
- encoding: "utf-8",
8386
- stdio: ["pipe", "pipe", "pipe"]
8387
- });
8388
- return result.trim() || null;
8389
- } catch {
8390
- return null;
8391
- }
8392
- }
8393
- function getCurrentVersion() {
8394
- return "0.15.15";
8395
- }
8396
- function formatVersionLine(current, skipCheck) {
8397
- if (skipCheck) {
8398
- return `REAP v${current}`;
8399
- }
8400
- const latest = checkLatestVersion();
8401
- if (!latest) {
8402
- return `REAP v${current}`;
8403
- }
8404
- if (latest === current) {
8405
- return `REAP v${current} (latest)`;
8406
- }
8407
- return `REAP v${current} (update available: ${latest})`;
8408
- }
8409
- var init_version = () => {};
8410
-
8411
8417
  // src/core/run-output.ts
8412
8418
  function emitOutput(output) {
8413
8419
  console.log(JSON.stringify(output, null, 2));
@@ -10604,7 +10610,7 @@ async function execute17(paths) {
10604
10610
  const gm = new GenerationManager(paths);
10605
10611
  const state = await gm.current();
10606
10612
  const configContent = await readTextFile(paths.config);
10607
- const installedVersion = "0.15.15";
10613
+ const installedVersion = "0.15.16";
10608
10614
  const autoUpdate = configContent?.match(/autoUpdate:\s*(true|false)/)?.[1] === "true";
10609
10615
  const versionDisplay = formatVersionLine(installedVersion, !autoUpdate);
10610
10616
  const rawLang = detectLanguage(configContent);
@@ -12332,7 +12338,7 @@ async function execute30(paths) {
12332
12338
  const lines = [
12333
12339
  `REAP Configuration (${paths.config})`,
12334
12340
  "",
12335
- ` version: ${"0.15.15"} (package)`,
12341
+ ` version: ${"0.15.16"} (package)`,
12336
12342
  ` project: ${config.project}`,
12337
12343
  ` entryMode: ${config.entryMode}`,
12338
12344
  ` strict: ${config.strict ?? false}`,
@@ -12638,7 +12644,7 @@ async function runCommand(command, phase, argv = []) {
12638
12644
  try {
12639
12645
  const config = await ConfigManager.read(paths);
12640
12646
  if (config.autoIssueReport) {
12641
- const version = "0.15.15";
12647
+ const version = "0.15.16";
12642
12648
  const errMsg = err instanceof Error ? err.message : String(err);
12643
12649
  const title = `[auto] reap run ${command}: ${errMsg.slice(0, 80)}`;
12644
12650
  const body = [
@@ -13412,8 +13418,8 @@ class ClaudeCodeAdapter {
13412
13418
  }
13413
13419
  async detect() {
13414
13420
  try {
13415
- const { execSync } = await import("child_process");
13416
- execSync("which claude", { stdio: "ignore" });
13421
+ const { execSync: execSync2 } = await import("child_process");
13422
+ execSync2("which claude", { stdio: "ignore" });
13417
13423
  return true;
13418
13424
  } catch {
13419
13425
  return false;
@@ -13716,8 +13722,8 @@ class CodexAdapter {
13716
13722
  }
13717
13723
  async detect() {
13718
13724
  try {
13719
- const { execSync } = await import("child_process");
13720
- execSync("which codex", { stdio: "ignore" });
13725
+ const { execSync: execSync2 } = await import("child_process");
13726
+ execSync2("which codex", { stdio: "ignore" });
13721
13727
  return true;
13722
13728
  } catch {
13723
13729
  return false;
@@ -13921,8 +13927,8 @@ class OpenCodeAdapter {
13921
13927
  }
13922
13928
  async detect() {
13923
13929
  try {
13924
- const { execSync } = await import("child_process");
13925
- execSync("which opencode", { stdio: "ignore" });
13930
+ const { execSync: execSync2 } = await import("child_process");
13931
+ execSync2("which opencode", { stdio: "ignore" });
13926
13932
  return true;
13927
13933
  } catch {
13928
13934
  return false;
@@ -14182,8 +14188,8 @@ async function initProject(projectRoot, projectName, entryMode, preset, onProgre
14182
14188
  log("Writing config.yml...");
14183
14189
  let hasGhCli = false;
14184
14190
  try {
14185
- const { execSync } = await import("child_process");
14186
- execSync("which gh", { stdio: "ignore" });
14191
+ const { execSync: execSync2 } = await import("child_process");
14192
+ execSync2("which gh", { stdio: "ignore" });
14187
14193
  hasGhCli = true;
14188
14194
  } catch {}
14189
14195
  if (!hasGhCli) {
@@ -14292,7 +14298,7 @@ async function initProject(projectRoot, projectName, entryMode, preset, onProgre
14292
14298
  init_paths();
14293
14299
  import { readdir as readdir12, unlink as unlink5, rm as rm3, mkdir as mkdir7 } from "fs/promises";
14294
14300
  import { join as join13 } from "path";
14295
- import { execSync as execSync3 } from "child_process";
14301
+ import { execSync as execSync4 } from "child_process";
14296
14302
 
14297
14303
  // src/core/hooks.ts
14298
14304
  async function migrateHooks(dryRun = false) {
@@ -14317,15 +14323,15 @@ init_generation();
14317
14323
  var import_yaml5 = __toESM(require_dist(), 1);
14318
14324
  import { readdir as readdir10, rename } from "fs/promises";
14319
14325
  import { join as join11 } from "path";
14320
- import { execSync as execSync2 } from "child_process";
14326
+ import { execSync as execSync3 } from "child_process";
14321
14327
  function estimateGenDates(lineagePath, dirName, fallbackDate) {
14322
14328
  const pattern = join11(lineagePath, `${dirName}*`);
14323
14329
  const fallback = fallbackDate ?? new Date().toISOString();
14324
14330
  try {
14325
- const startedRaw = execSync2(`git log --format=%aI --diff-filter=A -- "${pattern}"`, { encoding: "utf-8", timeout: 5000 }).trim();
14331
+ const startedRaw = execSync3(`git log --format=%aI --diff-filter=A -- "${pattern}"`, { encoding: "utf-8", timeout: 5000 }).trim();
14326
14332
  const startedAt = startedRaw.split(`
14327
14333
  `).pop() || fallback;
14328
- const completedRaw = execSync2(`git log -1 --format=%aI -- "${pattern}"`, { encoding: "utf-8", timeout: 5000 }).trim();
14334
+ const completedRaw = execSync3(`git log -1 --format=%aI -- "${pattern}"`, { encoding: "utf-8", timeout: 5000 }).trim();
14329
14335
  const completedAt = completedRaw || startedAt;
14330
14336
  return { startedAt, completedAt };
14331
14337
  } catch {
@@ -14525,7 +14531,7 @@ async function checkDirectoryStructure(paths, errors) {
14525
14531
  { path: paths.environment, name: "environment/" },
14526
14532
  { path: paths.life, name: "life/" },
14527
14533
  { path: paths.lineage, name: "lineage/" },
14528
- { path: paths.backlog, name: "life/backlog/" },
14534
+ { path: paths.backlog, name: "life/backlog/", optional: true },
14529
14535
  { path: paths.hooks, name: "hooks/" },
14530
14536
  { path: paths.hookConditions, name: "hooks/conditions/" }
14531
14537
  ];
@@ -14536,7 +14542,9 @@ async function checkDirectoryStructure(paths, errors) {
14536
14542
  errors.push(`${dir.name} directory missing`);
14537
14543
  }
14538
14544
  } catch {
14539
- errors.push(`${dir.name} directory missing`);
14545
+ if (!(("optional" in dir) && dir.optional)) {
14546
+ errors.push(`${dir.name} directory missing`);
14547
+ }
14540
14548
  }
14541
14549
  }
14542
14550
  }
@@ -14951,11 +14959,11 @@ async function detectMigrationGaps(paths) {
14951
14959
  // src/cli/commands/update.ts
14952
14960
  function selfUpgrade() {
14953
14961
  try {
14954
- const installed = execSync3("reap --version", { encoding: "utf-8", timeout: 5000 }).trim();
14962
+ const installed = execSync4("reap --version", { encoding: "utf-8", timeout: 5000 }).trim();
14955
14963
  if (installed.includes("+dev")) {
14956
14964
  return { upgraded: false };
14957
14965
  }
14958
- const latest = execSync3("npm view @c-d-cc/reap version", { encoding: "utf-8", timeout: 1e4 }).trim();
14966
+ const latest = execSync4("npm view @c-d-cc/reap version", { encoding: "utf-8", timeout: 1e4 }).trim();
14959
14967
  if (installed === latest) {
14960
14968
  return { upgraded: false };
14961
14969
  }
@@ -14969,7 +14977,7 @@ function selfUpgrade() {
14969
14977
  reason: `Breaking change: v${installed} -> v${latest}. Run '/reap.update' to upgrade manually. See https://reap.cc/docs/release-notes`
14970
14978
  };
14971
14979
  }
14972
- execSync3("npm update -g @c-d-cc/reap", { encoding: "utf-8", timeout: 60000, stdio: "pipe" });
14980
+ execSync4("npm update -g @c-d-cc/reap", { encoding: "utf-8", timeout: 60000, stdio: "pipe" });
14973
14981
  return { upgraded: true, from: installed, to: latest };
14974
14982
  } catch {
14975
14983
  return { upgraded: false };
@@ -14988,8 +14996,8 @@ function semverGte(a, b) {
14988
14996
  }
14989
14997
  function forceUpgrade(to) {
14990
14998
  try {
14991
- const installed = execSync3("reap --version", { encoding: "utf-8", timeout: 5000 }).trim();
14992
- execSync3(`npm install -g @c-d-cc/reap@${to}`, { encoding: "utf-8", timeout: 60000, stdio: "pipe" });
14999
+ const installed = execSync4("reap --version", { encoding: "utf-8", timeout: 5000 }).trim();
15000
+ execSync4(`npm install -g @c-d-cc/reap@${to}`, { encoding: "utf-8", timeout: 60000, stdio: "pipe" });
14993
15001
  return { upgraded: true, from: installed, to };
14994
15002
  } catch {
14995
15003
  return { upgraded: false };
@@ -14997,7 +15005,7 @@ function forceUpgrade(to) {
14997
15005
  }
14998
15006
  function queryAutoUpdateMinVersion() {
14999
15007
  try {
15000
- const result = execSync3("npm view @c-d-cc/reap reap.autoUpdateMinVersion", {
15008
+ const result = execSync4("npm view @c-d-cc/reap reap.autoUpdateMinVersion", {
15001
15009
  encoding: "utf-8",
15002
15010
  timeout: 1e4,
15003
15011
  stdio: ["pipe", "pipe", "pipe"]
@@ -15007,6 +15015,17 @@ function queryAutoUpdateMinVersion() {
15007
15015
  return null;
15008
15016
  }
15009
15017
  }
15018
+ function handOffToNewBinary() {
15019
+ try {
15020
+ execSync4("reap update --post-upgrade", {
15021
+ stdio: "inherit",
15022
+ timeout: 120000
15023
+ });
15024
+ return true;
15025
+ } catch {
15026
+ return false;
15027
+ }
15028
+ }
15010
15029
  async function updateProject(projectRoot, dryRun = false) {
15011
15030
  const paths = new ReapPaths(projectRoot);
15012
15031
  const result = { updated: [], skipped: [], removed: [] };
@@ -15165,11 +15184,11 @@ async function updateProject(projectRoot, dryRun = false) {
15165
15184
  }
15166
15185
  if (migrationResult.errors.length > 0 && config?.autoIssueReport) {
15167
15186
  try {
15168
- const { execSync: execSync4 } = await import("child_process");
15187
+ const { execSync: execSync5 } = await import("child_process");
15169
15188
  const errorSummary = migrationResult.errors.join("\\n");
15170
15189
  const title = `Migration failure during update`;
15171
15190
  const body = `## Migration Error\\n\\n### Errors\\n\\n${errorSummary}`;
15172
- execSync4(`gh issue create --repo c-d-cc/reap --title "${title}" --label "auto-reported,migration" --body "${body}"`, { encoding: "utf-8", timeout: 15000, stdio: "pipe" });
15191
+ execSync5(`gh issue create --repo c-d-cc/reap --title "${title}" --label "auto-reported,migration" --body "${body}"`, { encoding: "utf-8", timeout: 15000, stdio: "pipe" });
15173
15192
  } catch {}
15174
15193
  }
15175
15194
  }
@@ -15301,7 +15320,7 @@ async function getStatus(projectRoot) {
15301
15320
  const totalCompleted = await mgr.countAllCompleted();
15302
15321
  const integrityResult = await checkIntegrity(paths);
15303
15322
  return {
15304
- version: "0.15.15",
15323
+ version: "0.15.16",
15305
15324
  project: config.project,
15306
15325
  entryMode: config.entryMode,
15307
15326
  lastSyncedGeneration: config.lastSyncedGeneration,
@@ -15624,7 +15643,7 @@ init_fs();
15624
15643
  init_version();
15625
15644
  init_config();
15626
15645
  import { join as join34 } from "path";
15627
- program.name("reap").description("REAP — Recursive Evolutionary Autonomous Pipeline").version("0.15.15");
15646
+ program.name("reap").description("REAP — Recursive Evolutionary Autonomous Pipeline").version("0.15.16");
15628
15647
  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) => {
15629
15648
  try {
15630
15649
  const cwd = process.cwd();
@@ -15681,7 +15700,7 @@ program.command("status").description("Show current project and Generation statu
15681
15700
  const paths = new ReapPaths(cwd);
15682
15701
  const config = await ConfigManager.read(paths);
15683
15702
  const skipCheck = config.autoUpdate === false;
15684
- const installedVersion = "0.15.15";
15703
+ const installedVersion = "0.15.16";
15685
15704
  const versionLine = formatVersionLine(installedVersion, skipCheck);
15686
15705
  console.log(`${versionLine} | Project: ${status.project} (${status.entryMode})`);
15687
15706
  console.log(`Completed Generations: ${status.totalGenerations}`);
@@ -15751,32 +15770,42 @@ program.command("fix").description("Diagnose and repair .reap/ directory structu
15751
15770
  process.exit(1);
15752
15771
  }
15753
15772
  });
15754
- program.command("update").description("Upgrade REAP package and sync slash commands, templates, and hooks").option("--dry-run", "Show changes without applying them").action(async (options) => {
15773
+ program.command("update").description("Upgrade REAP package and sync slash commands, templates, and hooks").option("--dry-run", "Show changes without applying them").option("--post-upgrade", "Run project sync only (called by previous binary after self-upgrade)").action(async (options) => {
15755
15774
  try {
15756
- let upgrade = !options.dryRun ? selfUpgrade() : { upgraded: false };
15757
- if (upgrade.blocked) {
15758
- console.log(`
15775
+ const isPostUpgrade = options.postUpgrade === true;
15776
+ let upgrade = { upgraded: false };
15777
+ if (!isPostUpgrade) {
15778
+ upgrade = !options.dryRun ? selfUpgrade() : { upgraded: false };
15779
+ if (upgrade.blocked) {
15780
+ console.log(`
15759
15781
  ⚠ Breaking change detected: v${upgrade.from} → v${upgrade.to}`);
15760
- console.log(` This update contains breaking changes that may require manual migration.`);
15761
- console.log(` See release notes: https://reap.cc/docs/release-notes
15782
+ console.log(` This update contains breaking changes that may require manual migration.`);
15783
+ console.log(` See release notes: https://reap.cc/docs/release-notes
15762
15784
  `);
15763
- const rl = createInterface({ input: process.stdin, output: process.stdout });
15764
- const answer = await new Promise((resolve) => {
15765
- rl.question(" Proceed with update? (y/N) ", resolve);
15766
- });
15767
- rl.close();
15768
- if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
15769
- upgrade = forceUpgrade(upgrade.to);
15770
- if (upgrade.upgraded) {
15771
- console.log(`Upgraded: v${upgrade.from} → v${upgrade.to}`);
15785
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
15786
+ const answer = await new Promise((resolve) => {
15787
+ rl.question(" Proceed with update? (y/N) ", resolve);
15788
+ });
15789
+ rl.close();
15790
+ if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
15791
+ upgrade = forceUpgrade(upgrade.to);
15792
+ if (upgrade.upgraded) {
15793
+ console.log(`Upgraded: v${upgrade.from} → v${upgrade.to}`);
15794
+ } else {
15795
+ console.log("Upgrade failed. Try manually: npm install -g @c-d-cc/reap@latest");
15796
+ }
15772
15797
  } else {
15773
- console.log("Upgrade failed. Try manually: npm install -g @c-d-cc/reap@latest");
15798
+ console.log("Update skipped.");
15799
+ }
15800
+ } else if (upgrade.upgraded) {
15801
+ console.log(`Upgraded: v${upgrade.from} → v${upgrade.to}`);
15802
+ }
15803
+ if (upgrade.upgraded) {
15804
+ const handedOff = handOffToNewBinary();
15805
+ if (handedOff) {
15806
+ return;
15774
15807
  }
15775
- } else {
15776
- console.log("Update skipped.");
15777
15808
  }
15778
- } else if (upgrade.upgraded) {
15779
- console.log(`Upgraded: v${upgrade.from} → v${upgrade.to}`);
15780
15809
  }
15781
15810
  const result = await updateProject(process.cwd(), options.dryRun ?? false);
15782
15811
  if (options.dryRun) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c-d-cc/reap",
3
- "version": "0.15.15",
3
+ "version": "0.15.16",
4
4
  "description": "Recursive Evolutionary Autonomous Pipeline — AI and humans evolve software across generations",
5
5
  "type": "module",
6
6
  "license": "MIT",