@c-d-cc/reap 0.15.14 → 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/README.ja.md +9 -0
- package/README.ko.md +9 -0
- package/README.md +9 -0
- package/README.zh-CN.md +9 -0
- package/RELEASE_NOTICE.md +12 -0
- package/dist/cli.js +115 -86
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -23,6 +23,15 @@
|
|
|
23
23
|
|
|
24
24
|
REAPはアプリケーションの設計知識 — Genome(アーキテクチャ、コンベンション、制約)とEnvironment(外部API、インフラ) — を記録し、各世代で目標を設定して実装します。その過程で発見した欠陥はKnowledge Baseにフィードバックされます。世代を重ねるごとに知識が進化し、Source Code(Civilization)が成長します。
|
|
25
25
|
|
|
26
|
+
> **⚠️ v0.16 Breaking Changes予定**
|
|
27
|
+
>
|
|
28
|
+
> - REAPがSelf Evolving Pipelineへ移行
|
|
29
|
+
> - ライフサイクル変更: learning → planning → implementation → validation → completion(Learning stage新規追加、ObjectiveとPlanningをPlanningに統合)
|
|
30
|
+
> - スラッシュコマンド再編: skillマッチング最適化
|
|
31
|
+
> - CLIコマンドがユーザーインターフェースから削除(内部用途のみ)
|
|
32
|
+
>
|
|
33
|
+
> v0.15.xからv0.16.xへの自動アップデートはブロックされます。[リリースノート](https://reap.cc/docs/release-notes)参照。
|
|
34
|
+
|
|
26
35
|
## 目次
|
|
27
36
|
|
|
28
37
|
- [なぜREAPか?](#なぜreapか)
|
package/README.ko.md
CHANGED
|
@@ -23,6 +23,15 @@
|
|
|
23
23
|
|
|
24
24
|
REAP은 Application의 설계 지식 — Genome(아키텍처, 컨벤션, 제약사항)과 Environment(외부 API, 인프라) — 을 기록하고, 각 세대에서 목표를 설정하여 구현합니다. 그 과정에서 발견한 결함은 Knowledge Base에 반영됩니다. 세대를 거듭하며 지식이 진화하고, Source Code(Civilization)가 성장합니다.
|
|
25
25
|
|
|
26
|
+
> **⚠️ v0.16 Breaking Changes 예정**
|
|
27
|
+
>
|
|
28
|
+
> - REAP이 Self Evolving Pipeline으로 전환됩니다
|
|
29
|
+
> - Lifecycle 변경: learning → planning → implementation → validation → completion (Learning stage 신규 추가, Objective와 Planning을 Planning으로 병합)
|
|
30
|
+
> - Slash command 구조 변경: skill 매칭 최적화
|
|
31
|
+
> - CLI 커맨드가 사용자 인터페이스에서 제거 (내부 용도로만 사용)
|
|
32
|
+
>
|
|
33
|
+
> v0.15.x에서 v0.16.x로의 자동 업데이트가 차단됩니다. [릴리스 노트](https://reap.cc/docs/release-notes) 참조.
|
|
34
|
+
|
|
26
35
|
## 목차
|
|
27
36
|
|
|
28
37
|
- [Why REAP?](#why-reap)
|
package/README.md
CHANGED
|
@@ -23,6 +23,15 @@
|
|
|
23
23
|
|
|
24
24
|
REAP captures an application's design knowledge — the Genome (architecture, conventions, constraints) and Environment (external APIs, infrastructure) — then sets objectives for each generation to implement. Defects discovered along the way feed back into the Knowledge Base. As generations accumulate, knowledge evolves and the Source Code (Civilization) grows.
|
|
25
25
|
|
|
26
|
+
> **⚠️ Breaking Changes in v0.16**
|
|
27
|
+
>
|
|
28
|
+
> - REAP transitions to a Self Evolving Pipeline
|
|
29
|
+
> - Lifecycle changed: learning → planning → implementation → validation → completion (new Learning stage, Objective + Planning merged)
|
|
30
|
+
> - Slash commands restructured for optimal skill matching
|
|
31
|
+
> - CLI commands removed from user-facing interface (internal use only)
|
|
32
|
+
>
|
|
33
|
+
> Automatic updates from v0.15.x → v0.16.x are blocked. See [Release Notes](https://reap.cc/docs/release-notes).
|
|
34
|
+
|
|
26
35
|
## Table of Contents
|
|
27
36
|
|
|
28
37
|
- [Why REAP?](#why-reap)
|
package/README.zh-CN.md
CHANGED
|
@@ -23,6 +23,15 @@
|
|
|
23
23
|
|
|
24
24
|
REAP记录应用程序的设计知识 — Genome(架构、约定、约束)和Environment(外部API、基础设施) — 并在每个世代设定目标进行实现。过程中发现的缺陷反馈到Knowledge Base。随着世代的积累,知识不断进化,Source Code(Civilization)持续成长。
|
|
25
25
|
|
|
26
|
+
> **⚠️ v0.16 Breaking Changes 预告**
|
|
27
|
+
>
|
|
28
|
+
> - REAP转型为Self Evolving Pipeline
|
|
29
|
+
> - 生命周期变更: learning → planning → implementation → validation → completion(新增Learning阶段,Objective和Planning合并为Planning)
|
|
30
|
+
> - 斜杠命令重组: skill匹配优化
|
|
31
|
+
> - CLI命令从用户界面移除(仅供内部使用)
|
|
32
|
+
>
|
|
33
|
+
> v0.15.x到v0.16.x的自动更新将被阻止。参见[发布说明](https://reap.cc/docs/release-notes)。
|
|
34
|
+
|
|
26
35
|
## 目录
|
|
27
36
|
|
|
28
37
|
- [为什么选择REAP?](#为什么选择reap)
|
package/RELEASE_NOTICE.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
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
|
+
|
|
9
|
+
## v0.15.15
|
|
10
|
+
### en
|
|
11
|
+
Added v0.16 breaking change pre-announcement to README.
|
|
12
|
+
### ko
|
|
13
|
+
README에 v0.16 breaking change 사전 고지 추가.
|
|
14
|
+
|
|
3
15
|
## v0.15.14
|
|
4
16
|
### en
|
|
5
17
|
Auto-update guard for breaking changes. New Release Notes docs page with v0.16 pre-announcement.
|
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
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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.14";
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
14992
|
-
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
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
|
-
|
|
15761
|
-
|
|
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
|
-
|
|
15764
|
-
|
|
15765
|
-
|
|
15766
|
-
|
|
15767
|
-
|
|
15768
|
-
|
|
15769
|
-
|
|
15770
|
-
|
|
15771
|
-
|
|
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("
|
|
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) {
|