@c-d-cc/reap 0.16.6 → 0.17.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.de.md +48 -0
- package/README.ja.md +48 -0
- package/README.ko.md +50 -0
- package/README.md +28 -0
- package/README.zh-CN.md +50 -0
- package/RELEASE_NOTICE.md +12 -0
- package/dist/cli/index.js +722 -496
- package/dist/templates/agents/reap-evaluate.md +21 -0
- package/dist/templates/agents/reap-evolve.md +49 -0
- package/dist/templates/migration/v0.17.1.md +56 -0
- package/dist/templates/reap-guide.md +170 -37
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -7067,10 +7067,10 @@ var init_types = __esm(() => {
|
|
|
7067
7067
|
|
|
7068
7068
|
// src/core/integrity.ts
|
|
7069
7069
|
import { readdir, stat, rm, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
7070
|
-
import { join as
|
|
7070
|
+
import { join as join5 } from "path";
|
|
7071
7071
|
import { homedir } from "os";
|
|
7072
7072
|
async function detectV15(paths) {
|
|
7073
|
-
return fileExists(
|
|
7073
|
+
return fileExists(join5(paths.genome, "principles.md"));
|
|
7074
7074
|
}
|
|
7075
7075
|
async function checkIntegrity(paths) {
|
|
7076
7076
|
const errors = [];
|
|
@@ -7121,8 +7121,8 @@ async function checkDirectoryStructure(paths, errors) {
|
|
|
7121
7121
|
}
|
|
7122
7122
|
}
|
|
7123
7123
|
async function checkRequiredFiles(paths, errors, warnings) {
|
|
7124
|
-
const guideGlobal =
|
|
7125
|
-
const guideLocal =
|
|
7124
|
+
const guideGlobal = join5(homedir(), ".reap", "reap-guide.md");
|
|
7125
|
+
const guideLocal = join5(paths.reap, "reap-guide.md");
|
|
7126
7126
|
if (!await fileExists(guideGlobal) && !await fileExists(guideLocal)) {
|
|
7127
7127
|
errors.push("reap-guide.md missing — run 'npm install -g @c-d-cc/reap' to reinstall");
|
|
7128
7128
|
}
|
|
@@ -7139,7 +7139,7 @@ async function checkRequiredFiles(paths, errors, warnings) {
|
|
|
7139
7139
|
if (!await fileExists(paths.visionGoals)) {
|
|
7140
7140
|
warnings.push("vision/goals.md missing");
|
|
7141
7141
|
}
|
|
7142
|
-
const claudeMdPath =
|
|
7142
|
+
const claudeMdPath = join5(paths.root, "CLAUDE.md");
|
|
7143
7143
|
const claudeMd = await readTextFile(claudeMdPath);
|
|
7144
7144
|
if (!claudeMd) {
|
|
7145
7145
|
warnings.push("CLAUDE.md missing — run 'reap init --repair'");
|
|
@@ -7155,7 +7155,7 @@ async function checkConfig(paths, errors, warnings) {
|
|
|
7155
7155
|
}
|
|
7156
7156
|
let config;
|
|
7157
7157
|
try {
|
|
7158
|
-
config =
|
|
7158
|
+
config = import_yaml3.default.parse(content) ?? {};
|
|
7159
7159
|
} catch {
|
|
7160
7160
|
errors.push("config.yml is not valid YAML");
|
|
7161
7161
|
return;
|
|
@@ -7199,7 +7199,7 @@ async function checkCurrentYml(paths, errors, _warnings) {
|
|
|
7199
7199
|
}
|
|
7200
7200
|
let state;
|
|
7201
7201
|
try {
|
|
7202
|
-
state =
|
|
7202
|
+
state = import_yaml3.default.parse(content) ?? {};
|
|
7203
7203
|
} catch {
|
|
7204
7204
|
errors.push("current.yml is not valid YAML");
|
|
7205
7205
|
return null;
|
|
@@ -7247,7 +7247,7 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7247
7247
|
for (const name of items) {
|
|
7248
7248
|
if (!name.startsWith("gen-"))
|
|
7249
7249
|
continue;
|
|
7250
|
-
const itemPath =
|
|
7250
|
+
const itemPath = join5(paths.lineage, name);
|
|
7251
7251
|
let itemStat;
|
|
7252
7252
|
try {
|
|
7253
7253
|
itemStat = await stat(itemPath);
|
|
@@ -7255,7 +7255,7 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7255
7255
|
continue;
|
|
7256
7256
|
}
|
|
7257
7257
|
if (itemStat.isDirectory()) {
|
|
7258
|
-
const metaPath =
|
|
7258
|
+
const metaPath = join5(paths.lineage, name, "meta.yml");
|
|
7259
7259
|
const metaContent = await readTextFile(metaPath);
|
|
7260
7260
|
if (metaContent === null) {
|
|
7261
7261
|
errors.push(`lineage/${name}: missing meta.yml`);
|
|
@@ -7263,7 +7263,7 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7263
7263
|
}
|
|
7264
7264
|
let meta;
|
|
7265
7265
|
try {
|
|
7266
|
-
meta =
|
|
7266
|
+
meta = import_yaml3.default.parse(metaContent) ?? {};
|
|
7267
7267
|
} catch {
|
|
7268
7268
|
errors.push(`lineage/${name}/meta.yml: invalid YAML`);
|
|
7269
7269
|
continue;
|
|
@@ -7272,7 +7272,7 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7272
7272
|
if (meta.id)
|
|
7273
7273
|
allMetaIds.add(meta.id);
|
|
7274
7274
|
} else if (itemStat.isFile() && name.endsWith(".md")) {
|
|
7275
|
-
const content = await readTextFile(
|
|
7275
|
+
const content = await readTextFile(join5(paths.lineage, name));
|
|
7276
7276
|
if (!content)
|
|
7277
7277
|
continue;
|
|
7278
7278
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -7282,7 +7282,7 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7282
7282
|
}
|
|
7283
7283
|
let meta;
|
|
7284
7284
|
try {
|
|
7285
|
-
meta =
|
|
7285
|
+
meta = import_yaml3.default.parse(fmMatch[1]) ?? {};
|
|
7286
7286
|
} catch {
|
|
7287
7287
|
errors.push(`lineage/${name}: invalid frontmatter YAML`);
|
|
7288
7288
|
continue;
|
|
@@ -7295,7 +7295,7 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7295
7295
|
for (const name of items) {
|
|
7296
7296
|
if (!name.startsWith("gen-"))
|
|
7297
7297
|
continue;
|
|
7298
|
-
const itemPath =
|
|
7298
|
+
const itemPath = join5(paths.lineage, name);
|
|
7299
7299
|
let parents = [];
|
|
7300
7300
|
let itemStat;
|
|
7301
7301
|
try {
|
|
@@ -7304,20 +7304,20 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7304
7304
|
continue;
|
|
7305
7305
|
}
|
|
7306
7306
|
if (itemStat.isDirectory()) {
|
|
7307
|
-
const metaContent = await readTextFile(
|
|
7307
|
+
const metaContent = await readTextFile(join5(paths.lineage, name, "meta.yml"));
|
|
7308
7308
|
if (metaContent) {
|
|
7309
7309
|
try {
|
|
7310
|
-
const meta =
|
|
7310
|
+
const meta = import_yaml3.default.parse(metaContent);
|
|
7311
7311
|
parents = meta?.parents ?? [];
|
|
7312
7312
|
} catch {}
|
|
7313
7313
|
}
|
|
7314
7314
|
} else if (itemStat.isFile() && name.endsWith(".md")) {
|
|
7315
|
-
const content = await readTextFile(
|
|
7315
|
+
const content = await readTextFile(join5(paths.lineage, name));
|
|
7316
7316
|
if (content) {
|
|
7317
7317
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
7318
7318
|
if (fmMatch) {
|
|
7319
7319
|
try {
|
|
7320
|
-
const meta =
|
|
7320
|
+
const meta = import_yaml3.default.parse(fmMatch[1]);
|
|
7321
7321
|
parents = meta?.parents ?? [];
|
|
7322
7322
|
} catch {}
|
|
7323
7323
|
}
|
|
@@ -7325,7 +7325,7 @@ async function checkLineage(paths, errors, warnings) {
|
|
|
7325
7325
|
}
|
|
7326
7326
|
for (const parent of parents) {
|
|
7327
7327
|
if (parent && !allMetaIds.has(parent)) {
|
|
7328
|
-
const epochContent = await readTextFile(
|
|
7328
|
+
const epochContent = await readTextFile(join5(paths.lineage, "epoch.md"));
|
|
7329
7329
|
let inEpoch = false;
|
|
7330
7330
|
if (epochContent) {
|
|
7331
7331
|
inEpoch = epochContent.includes(parent);
|
|
@@ -7397,7 +7397,7 @@ async function checkBacklog(paths, errors, _warnings) {
|
|
|
7397
7397
|
for (const filename of entries) {
|
|
7398
7398
|
if (!filename.endsWith(".md"))
|
|
7399
7399
|
continue;
|
|
7400
|
-
const content = await readTextFile(
|
|
7400
|
+
const content = await readTextFile(join5(paths.backlog, filename));
|
|
7401
7401
|
if (!content)
|
|
7402
7402
|
continue;
|
|
7403
7403
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -7407,7 +7407,7 @@ async function checkBacklog(paths, errors, _warnings) {
|
|
|
7407
7407
|
}
|
|
7408
7408
|
let fm;
|
|
7409
7409
|
try {
|
|
7410
|
-
fm =
|
|
7410
|
+
fm = import_yaml3.default.parse(fmMatch[1]) ?? {};
|
|
7411
7411
|
} catch {
|
|
7412
7412
|
errors.push(`backlog/${filename}: invalid frontmatter YAML`);
|
|
7413
7413
|
continue;
|
|
@@ -7431,9 +7431,9 @@ async function checkUserLevelArtifacts(projectRoot) {
|
|
|
7431
7431
|
const errors = [];
|
|
7432
7432
|
const warnings = [];
|
|
7433
7433
|
const home = homedir();
|
|
7434
|
-
await checkGlobPattern(
|
|
7435
|
-
await checkGlobPattern(
|
|
7436
|
-
await checkGlobPattern(
|
|
7434
|
+
await checkGlobPattern(join5(home, ".claude", "skills"), /^reap\./, "~/.claude/skills/", "user-level reap skill found (should only be project-level)", errors);
|
|
7435
|
+
await checkGlobPattern(join5(home, ".claude", "commands"), /^reap\./, "~/.claude/commands/", "legacy reap command at user level (Phase 2 remnant)", warnings);
|
|
7436
|
+
await checkGlobPattern(join5(projectRoot, ".claude", "commands"), /^reap\./, ".claude/commands/", "legacy project-level reap command (should be migrated to skills/)", warnings);
|
|
7437
7437
|
return { errors, warnings };
|
|
7438
7438
|
}
|
|
7439
7439
|
async function checkGlobPattern(dir, pattern, displayDir, message, target) {
|
|
@@ -7451,22 +7451,22 @@ async function checkGlobPattern(dir, pattern, displayDir, message, target) {
|
|
|
7451
7451
|
}
|
|
7452
7452
|
async function cleanupLegacyProjectSkills(projectRoot) {
|
|
7453
7453
|
const deleted = [];
|
|
7454
|
-
const commandsDir =
|
|
7454
|
+
const commandsDir = join5(projectRoot, ".claude", "commands");
|
|
7455
7455
|
try {
|
|
7456
7456
|
const entries = await readdir(commandsDir);
|
|
7457
7457
|
for (const entry of entries) {
|
|
7458
7458
|
if (LEGACY_COMMAND_PATTERN.test(entry)) {
|
|
7459
|
-
await rm(
|
|
7459
|
+
await rm(join5(commandsDir, entry), { force: true });
|
|
7460
7460
|
deleted.push(`.claude/commands/${entry}`);
|
|
7461
7461
|
}
|
|
7462
7462
|
}
|
|
7463
7463
|
} catch {}
|
|
7464
|
-
const skillsDir =
|
|
7464
|
+
const skillsDir = join5(projectRoot, ".claude", "skills");
|
|
7465
7465
|
try {
|
|
7466
7466
|
const entries = await readdir(skillsDir);
|
|
7467
7467
|
for (const entry of entries) {
|
|
7468
7468
|
if (LEGACY_SKILL_PATTERN.test(entry)) {
|
|
7469
|
-
const entryPath =
|
|
7469
|
+
const entryPath = join5(skillsDir, entry);
|
|
7470
7470
|
try {
|
|
7471
7471
|
const s = await stat(entryPath);
|
|
7472
7472
|
if (s.isDirectory()) {
|
|
@@ -7482,8 +7482,8 @@ async function cleanupLegacyProjectSkills(projectRoot) {
|
|
|
7482
7482
|
async function cleanupLegacyHooks(projectRoot) {
|
|
7483
7483
|
const modified = [];
|
|
7484
7484
|
const settingsPaths = [
|
|
7485
|
-
|
|
7486
|
-
|
|
7485
|
+
join5(projectRoot, ".claude", "settings.json"),
|
|
7486
|
+
join5(homedir(), ".claude", "settings.json")
|
|
7487
7487
|
];
|
|
7488
7488
|
for (const settingsPath of settingsPaths) {
|
|
7489
7489
|
try {
|
|
@@ -7518,11 +7518,11 @@ async function cleanupLegacyHooks(projectRoot) {
|
|
|
7518
7518
|
}
|
|
7519
7519
|
return modified;
|
|
7520
7520
|
}
|
|
7521
|
-
var
|
|
7521
|
+
var import_yaml3, VALID_BACKLOG_TYPES, VALID_BACKLOG_STATUSES, VALID_GENERATION_TYPES, GENOME_LINE_WARNING_THRESHOLD = 100, LEGACY_COMMAND_PATTERN, LEGACY_SKILL_PATTERN;
|
|
7522
7522
|
var init_integrity = __esm(() => {
|
|
7523
7523
|
init_fs();
|
|
7524
7524
|
init_types();
|
|
7525
|
-
|
|
7525
|
+
import_yaml3 = __toESM(require_dist(), 1);
|
|
7526
7526
|
VALID_BACKLOG_TYPES = ["genome-change", "environment-change", "task"];
|
|
7527
7527
|
VALID_BACKLOG_STATUSES = ["pending", "consumed"];
|
|
7528
7528
|
VALID_GENERATION_TYPES = ["embryo", "normal", "merge"];
|
|
@@ -7543,13 +7543,13 @@ __export(exports_common, {
|
|
|
7543
7543
|
buildPromptPreamble: () => buildPromptPreamble,
|
|
7544
7544
|
buildHardGateBlock: () => buildHardGateBlock
|
|
7545
7545
|
});
|
|
7546
|
-
import { join as
|
|
7547
|
-
import { fileURLToPath } from "url";
|
|
7546
|
+
import { join as join6, dirname as dirname5 } from "path";
|
|
7547
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
7548
7548
|
import { createHash } from "crypto";
|
|
7549
7549
|
import { readdir as readdir2, copyFile, chmod } from "fs/promises";
|
|
7550
7550
|
function distPath(...segments) {
|
|
7551
|
-
const __dirname2 =
|
|
7552
|
-
return
|
|
7551
|
+
const __dirname2 = dirname5(fileURLToPath4(import.meta.url));
|
|
7552
|
+
return join6(__dirname2, "..", "templates", ...segments);
|
|
7553
7553
|
}
|
|
7554
7554
|
async function initCommon(paths, projectName) {
|
|
7555
7555
|
await cleanupLegacyProjectSkills(paths.root);
|
|
@@ -7576,7 +7576,7 @@ async function initCommon(paths, projectName) {
|
|
|
7576
7576
|
autoUpdate: true,
|
|
7577
7577
|
autoIssueReport: true
|
|
7578
7578
|
};
|
|
7579
|
-
await writeTextFile(paths.config,
|
|
7579
|
+
await writeTextFile(paths.config, import_yaml4.default.stringify(config));
|
|
7580
7580
|
const evolution = await readTextFile(distPath("evolution.md"));
|
|
7581
7581
|
await writeTextFile(paths.evolution, evolution ?? `# Evolution
|
|
7582
7582
|
`);
|
|
@@ -7662,8 +7662,8 @@ async function ensureClaudeMd(root, projectName) {
|
|
|
7662
7662
|
const templateContent = stripMarkers(rawTemplate);
|
|
7663
7663
|
const wrappedSection = wrapWithMarkers(templateContent);
|
|
7664
7664
|
const newHash = computeSectionHash(templateContent);
|
|
7665
|
-
const rootPath =
|
|
7666
|
-
const dotClaudePath =
|
|
7665
|
+
const rootPath = join6(root, "CLAUDE.md");
|
|
7666
|
+
const dotClaudePath = join6(root, ".claude", "CLAUDE.md");
|
|
7667
7667
|
const rootContent = await readTextFile(rootPath);
|
|
7668
7668
|
const dotClaudeContent = await readTextFile(dotClaudePath);
|
|
7669
7669
|
const result = await updateClaudeMdFile(rootPath, rootContent, newHash, wrappedSection);
|
|
@@ -7731,15 +7731,15 @@ async function updateClaudeMdFile(filePath, content, newHash, wrappedSection) {
|
|
|
7731
7731
|
}
|
|
7732
7732
|
async function installHookTemplates(hooksDir) {
|
|
7733
7733
|
const templateDir = distPath("hooks");
|
|
7734
|
-
const conditionsTemplateDir =
|
|
7735
|
-
const conditionsDir =
|
|
7734
|
+
const conditionsTemplateDir = join6(templateDir, "conditions");
|
|
7735
|
+
const conditionsDir = join6(hooksDir, "conditions");
|
|
7736
7736
|
await ensureDir(conditionsDir);
|
|
7737
7737
|
try {
|
|
7738
7738
|
const conditionFiles = await readdir2(conditionsTemplateDir);
|
|
7739
7739
|
for (const file of conditionFiles) {
|
|
7740
|
-
const dest =
|
|
7740
|
+
const dest = join6(conditionsDir, file);
|
|
7741
7741
|
if (!await fileExists(dest)) {
|
|
7742
|
-
await copyFile(
|
|
7742
|
+
await copyFile(join6(conditionsTemplateDir, file), dest);
|
|
7743
7743
|
await chmod(dest, 493);
|
|
7744
7744
|
}
|
|
7745
7745
|
}
|
|
@@ -7749,14 +7749,14 @@ async function installHookTemplates(hooksDir) {
|
|
|
7749
7749
|
for (const file of hookFiles) {
|
|
7750
7750
|
if (!file.endsWith(".example"))
|
|
7751
7751
|
continue;
|
|
7752
|
-
const dest =
|
|
7752
|
+
const dest = join6(hooksDir, file);
|
|
7753
7753
|
if (!await fileExists(dest)) {
|
|
7754
|
-
await copyFile(
|
|
7754
|
+
await copyFile(join6(templateDir, file), dest);
|
|
7755
7755
|
}
|
|
7756
7756
|
}
|
|
7757
7757
|
} catch {}
|
|
7758
7758
|
}
|
|
7759
|
-
var
|
|
7759
|
+
var import_yaml4, DEFAULT_INVARIANTS = `# Invariants
|
|
7760
7760
|
|
|
7761
7761
|
> Absolute constraints. Human-only modification.
|
|
7762
7762
|
|
|
@@ -7774,17 +7774,27 @@ var import_yaml3, DEFAULT_INVARIANTS = `# Invariants
|
|
|
7774
7774
|
var init_common = __esm(() => {
|
|
7775
7775
|
init_fs();
|
|
7776
7776
|
init_integrity();
|
|
7777
|
-
|
|
7777
|
+
import_yaml4 = __toESM(require_dist(), 1);
|
|
7778
7778
|
REAP_START_RE = /<!-- reap:start ([a-f0-9]+) -->/;
|
|
7779
7779
|
});
|
|
7780
7780
|
|
|
7781
7781
|
// src/cli/commands/daemon/client.ts
|
|
7782
7782
|
import { spawn, execSync as execSync6 } from "child_process";
|
|
7783
|
-
import { join as
|
|
7783
|
+
import { join as join13 } from "path";
|
|
7784
7784
|
import { homedir as homedir3 } from "os";
|
|
7785
|
+
function resolvePort() {
|
|
7786
|
+
const raw = process.env.REAP_DAEMON_PORT;
|
|
7787
|
+
if (!raw)
|
|
7788
|
+
return DEFAULT_PORT;
|
|
7789
|
+
const n = Number(raw);
|
|
7790
|
+
return Number.isFinite(n) && n > 0 ? n : DEFAULT_PORT;
|
|
7791
|
+
}
|
|
7792
|
+
function getBaseUrl() {
|
|
7793
|
+
return `http://127.0.0.1:${resolvePort()}`;
|
|
7794
|
+
}
|
|
7785
7795
|
async function daemonRequest(method, path, body) {
|
|
7786
7796
|
await ensureDaemon();
|
|
7787
|
-
const res = await fetch(`${
|
|
7797
|
+
const res = await fetch(`${getBaseUrl()}${path}`, {
|
|
7788
7798
|
method,
|
|
7789
7799
|
headers: body ? { "Content-Type": "application/json" } : undefined,
|
|
7790
7800
|
body: body ? JSON.stringify(body) : undefined
|
|
@@ -7811,7 +7821,7 @@ async function ensureDaemon() {
|
|
|
7811
7821
|
}
|
|
7812
7822
|
async function isDaemonRunning() {
|
|
7813
7823
|
try {
|
|
7814
|
-
const res = await fetch(`${
|
|
7824
|
+
const res = await fetch(`${getBaseUrl()}/health`, { signal: AbortSignal.timeout(500) });
|
|
7815
7825
|
return res.ok;
|
|
7816
7826
|
} catch {
|
|
7817
7827
|
return false;
|
|
@@ -7821,7 +7831,7 @@ function resolveDaemonBin() {
|
|
|
7821
7831
|
try {
|
|
7822
7832
|
return __require.resolve("@c-d-cc/reap-daemon/dist/index.js");
|
|
7823
7833
|
} catch {
|
|
7824
|
-
return
|
|
7834
|
+
return join13(__dirname, "..", "..", "..", "daemon", "dist", "index.js");
|
|
7825
7835
|
}
|
|
7826
7836
|
}
|
|
7827
7837
|
function detectRuntime() {
|
|
@@ -7843,11 +7853,10 @@ async function findProjectId(projectRoot) {
|
|
|
7843
7853
|
return null;
|
|
7844
7854
|
}
|
|
7845
7855
|
}
|
|
7846
|
-
var __dirname = "/home/runner/work/reap/reap/src/cli/commands/daemon", DAEMON_ROOT, PID_PATH, DEFAULT_PORT = 17224
|
|
7856
|
+
var __dirname = "/home/runner/work/reap/reap/src/cli/commands/daemon", DAEMON_ROOT, PID_PATH, DEFAULT_PORT = 17224;
|
|
7847
7857
|
var init_client = __esm(() => {
|
|
7848
|
-
DAEMON_ROOT =
|
|
7849
|
-
PID_PATH =
|
|
7850
|
-
BASE_URL = `http://127.0.0.1:${DEFAULT_PORT}`;
|
|
7858
|
+
DAEMON_ROOT = join13(homedir3(), ".reap", "daemon");
|
|
7859
|
+
PID_PATH = join13(DAEMON_ROOT, "daemon.pid");
|
|
7851
7860
|
});
|
|
7852
7861
|
|
|
7853
7862
|
// src/cli/commands/daemon/lifecycle.ts
|
|
@@ -7860,12 +7869,15 @@ async function triggerIndexing(projectRoot) {
|
|
|
7860
7869
|
try {
|
|
7861
7870
|
const result = await daemonRequest("GET", "/projects");
|
|
7862
7871
|
if (result.status !== "ok" || !result.data)
|
|
7863
|
-
return;
|
|
7872
|
+
return false;
|
|
7864
7873
|
const project = result.data.find((p) => p.path === projectRoot);
|
|
7865
7874
|
if (!project)
|
|
7866
|
-
return;
|
|
7867
|
-
await daemonRequest("POST", `/projects/${project.id}/index`);
|
|
7868
|
-
|
|
7875
|
+
return false;
|
|
7876
|
+
const indexResult = await daemonRequest("POST", `/projects/${project.id}/index`);
|
|
7877
|
+
return indexResult.status === "ok";
|
|
7878
|
+
} catch {
|
|
7879
|
+
return false;
|
|
7880
|
+
}
|
|
7869
7881
|
}
|
|
7870
7882
|
async function ensureRegistered(projectRoot, name) {
|
|
7871
7883
|
try {
|
|
@@ -7873,19 +7885,22 @@ async function ensureRegistered(projectRoot, name) {
|
|
|
7873
7885
|
if (result.status === "ok" && result.data) {
|
|
7874
7886
|
const existing = result.data.find((p) => p.path === projectRoot);
|
|
7875
7887
|
if (existing)
|
|
7876
|
-
return;
|
|
7888
|
+
return true;
|
|
7877
7889
|
}
|
|
7878
|
-
await daemonRequest("POST", "/projects/register", { path: projectRoot, name });
|
|
7879
|
-
|
|
7890
|
+
const regResult = await daemonRequest("POST", "/projects/register", { path: projectRoot, name });
|
|
7891
|
+
return regResult.status === "ok";
|
|
7892
|
+
} catch {
|
|
7893
|
+
return false;
|
|
7894
|
+
}
|
|
7880
7895
|
}
|
|
7881
7896
|
var init_lifecycle = __esm(() => {
|
|
7882
7897
|
init_client();
|
|
7883
7898
|
});
|
|
7884
7899
|
|
|
7885
7900
|
// src/cli/index.ts
|
|
7886
|
-
import { readFileSync as
|
|
7887
|
-
import { join as
|
|
7888
|
-
import { fileURLToPath as
|
|
7901
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
7902
|
+
import { join as join31, dirname as dirname13 } from "path";
|
|
7903
|
+
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
7889
7904
|
|
|
7890
7905
|
// src/libs/cli.ts
|
|
7891
7906
|
function parseOptionFlags(flags) {
|
|
@@ -8576,7 +8591,7 @@ var program = new Command;
|
|
|
8576
8591
|
|
|
8577
8592
|
// src/cli/commands/init/index.ts
|
|
8578
8593
|
import { readdir as readdir5 } from "fs/promises";
|
|
8579
|
-
import { join as
|
|
8594
|
+
import { join as join9 } from "path";
|
|
8580
8595
|
|
|
8581
8596
|
// src/core/paths.ts
|
|
8582
8597
|
import { join } from "path";
|
|
@@ -8623,9 +8638,10 @@ function createPaths(root) {
|
|
|
8623
8638
|
init_fs();
|
|
8624
8639
|
|
|
8625
8640
|
// src/core/dump-state-sync.ts
|
|
8626
|
-
var
|
|
8627
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
8628
|
-
import { join as
|
|
8641
|
+
var import_yaml2 = __toESM(require_dist(), 1);
|
|
8642
|
+
import { readFileSync as readFileSync3, writeFileSync, mkdirSync, existsSync as existsSync2 } from "fs";
|
|
8643
|
+
import { join as join4, dirname as dirname4 } from "path";
|
|
8644
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
8629
8645
|
|
|
8630
8646
|
// src/core/prompt.ts
|
|
8631
8647
|
init_fs();
|
|
@@ -8979,6 +8995,21 @@ function buildBasePrompt(knowledge, paths, state, cruiseCount, clarityResult, co
|
|
|
8979
8995
|
lines.push("");
|
|
8980
8996
|
}
|
|
8981
8997
|
}
|
|
8998
|
+
if (config?.daemon === true) {
|
|
8999
|
+
lines.push("## Code Intelligence (Daemon)");
|
|
9000
|
+
lines.push("");
|
|
9001
|
+
lines.push("REAP daemon is enabled. Prefer daemon queries over full-text search when possible.");
|
|
9002
|
+
lines.push("");
|
|
9003
|
+
lines.push("- Health: `curl -sf http://127.0.0.1:17224/health` — if it fails, daemon is down; skip silently.");
|
|
9004
|
+
lines.push("- Project ID lookup: `curl -s http://127.0.0.1:17224/projects | jq '.data[] | select(.path==\"<cwd>\")'`.");
|
|
9005
|
+
lines.push("- Symbol search: `GET /projects/{id}/symbols?q=<query>` — find function/class/type definitions.");
|
|
9006
|
+
lines.push("- Callers: `GET /projects/{id}/symbols/{symbolId}/callers` — who calls this symbol?");
|
|
9007
|
+
lines.push("- Impact: `GET /projects/{id}/impact?file=<path>` — blast radius of changes to a file.");
|
|
9008
|
+
lines.push("- Staleness: `GET /projects/{id}/status` includes `lastIndexedCommit`. Compare against `git rev-parse HEAD`; if different, the index is stale.");
|
|
9009
|
+
lines.push("");
|
|
9010
|
+
lines.push("See `~/.reap/reap-guide.md` § Code Intelligence (Daemon) for the full protocol.");
|
|
9011
|
+
lines.push("");
|
|
9012
|
+
}
|
|
8982
9013
|
lines.push("## Project");
|
|
8983
9014
|
lines.push(`Path: ${paths.root}`);
|
|
8984
9015
|
return lines.join(`
|
|
@@ -9095,7 +9126,202 @@ function buildEvaluatorPrompt(knowledge, paths, state, opts) {
|
|
|
9095
9126
|
`);
|
|
9096
9127
|
}
|
|
9097
9128
|
|
|
9129
|
+
// src/cli/commands/load-context.ts
|
|
9130
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
9131
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
9132
|
+
import { join as join3, dirname as dirname3 } from "path";
|
|
9133
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9134
|
+
init_fs();
|
|
9135
|
+
|
|
9136
|
+
// src/core/migration.ts
|
|
9137
|
+
import { readdirSync, readFileSync, existsSync } from "fs";
|
|
9138
|
+
import { join as join2, dirname as dirname2 } from "path";
|
|
9139
|
+
import { fileURLToPath } from "url";
|
|
9140
|
+
var MIGRATION_FILENAME_RE = /^v(\d+\.\d+\.\d+)\.md$/;
|
|
9141
|
+
function parseVersionFromFilename(name) {
|
|
9142
|
+
const m = MIGRATION_FILENAME_RE.exec(name);
|
|
9143
|
+
return m ? m[1] : null;
|
|
9144
|
+
}
|
|
9145
|
+
function semverGt(a, b) {
|
|
9146
|
+
const pa = a.split(".").map((s) => Number.parseInt(s, 10) || 0);
|
|
9147
|
+
const pb = b.split(".").map((s) => Number.parseInt(s, 10) || 0);
|
|
9148
|
+
for (let i = 0;i < 3; i++) {
|
|
9149
|
+
const av = pa[i] ?? 0;
|
|
9150
|
+
const bv = pb[i] ?? 0;
|
|
9151
|
+
if (av > bv)
|
|
9152
|
+
return true;
|
|
9153
|
+
if (av < bv)
|
|
9154
|
+
return false;
|
|
9155
|
+
}
|
|
9156
|
+
return false;
|
|
9157
|
+
}
|
|
9158
|
+
function migrationTemplatesDir() {
|
|
9159
|
+
const here = dirname2(fileURLToPath(import.meta.url));
|
|
9160
|
+
return here.includes("dist") ? join2(here, "..", "templates", "migration") : join2(here, "..", "templates", "migration");
|
|
9161
|
+
}
|
|
9162
|
+
function detectPendingMigrations(config, currentVersion, templatesDir) {
|
|
9163
|
+
if (!currentVersion || currentVersion === "0.0.0")
|
|
9164
|
+
return [];
|
|
9165
|
+
const lastMigrated = config?.lastMigratedVersion ?? "0.0.0";
|
|
9166
|
+
const dir = templatesDir ?? migrationTemplatesDir();
|
|
9167
|
+
let entries;
|
|
9168
|
+
try {
|
|
9169
|
+
if (!existsSync(dir))
|
|
9170
|
+
return [];
|
|
9171
|
+
entries = readdirSync(dir);
|
|
9172
|
+
} catch {
|
|
9173
|
+
return [];
|
|
9174
|
+
}
|
|
9175
|
+
const pending = [];
|
|
9176
|
+
for (const name of entries) {
|
|
9177
|
+
const version = parseVersionFromFilename(name);
|
|
9178
|
+
if (!version)
|
|
9179
|
+
continue;
|
|
9180
|
+
if (!semverGt(version, lastMigrated))
|
|
9181
|
+
continue;
|
|
9182
|
+
if (semverGt(version, currentVersion))
|
|
9183
|
+
continue;
|
|
9184
|
+
try {
|
|
9185
|
+
const body = readFileSync(join2(dir, name), "utf-8");
|
|
9186
|
+
pending.push({ version, instructions: body });
|
|
9187
|
+
} catch {}
|
|
9188
|
+
}
|
|
9189
|
+
pending.sort((a, b) => semverGt(a.version, b.version) ? 1 : -1);
|
|
9190
|
+
return pending;
|
|
9191
|
+
}
|
|
9192
|
+
function buildPendingMigrationsSection(config, currentVersion, templatesDir) {
|
|
9193
|
+
const pending = detectPendingMigrations(config, currentVersion, templatesDir);
|
|
9194
|
+
if (pending.length === 0)
|
|
9195
|
+
return null;
|
|
9196
|
+
const lines = [];
|
|
9197
|
+
lines.push("# Pending Migrations");
|
|
9198
|
+
lines.push("");
|
|
9199
|
+
lines.push(`This project has not yet been migrated for ${pending.length} REAP version${pending.length === 1 ? "" : "s"}. ` + `Follow the instructions below to bring existing artifacts/memory in line with the current REAP version, ` + `then run \`reap update --mark-migrated\` to record completion.`);
|
|
9200
|
+
for (const m of pending) {
|
|
9201
|
+
lines.push("");
|
|
9202
|
+
lines.push(`## v${m.version}`);
|
|
9203
|
+
lines.push("");
|
|
9204
|
+
lines.push(m.instructions.trim());
|
|
9205
|
+
}
|
|
9206
|
+
return lines.join(`
|
|
9207
|
+
`);
|
|
9208
|
+
}
|
|
9209
|
+
|
|
9210
|
+
// src/cli/commands/load-context.ts
|
|
9211
|
+
function getPackageVersion() {
|
|
9212
|
+
try {
|
|
9213
|
+
const __dir = dirname3(fileURLToPath2(import.meta.url));
|
|
9214
|
+
for (const rel of [join3(__dir, "..", "..", "..", "package.json"), join3(__dir, "..", "..", "package.json"), join3(__dir, "..", "package.json")]) {
|
|
9215
|
+
try {
|
|
9216
|
+
return JSON.parse(readFileSync2(rel, "utf-8")).version;
|
|
9217
|
+
} catch {}
|
|
9218
|
+
}
|
|
9219
|
+
} catch {}
|
|
9220
|
+
return "0.0.0";
|
|
9221
|
+
}
|
|
9222
|
+
async function buildKnowledgeContext(cwd) {
|
|
9223
|
+
const configPath = join3(cwd, ".reap", "config.yml");
|
|
9224
|
+
if (!await fileExists(configPath)) {
|
|
9225
|
+
return null;
|
|
9226
|
+
}
|
|
9227
|
+
const paths = createPaths(cwd);
|
|
9228
|
+
const [configContent, currentContent] = await Promise.all([
|
|
9229
|
+
readTextFile(paths.config),
|
|
9230
|
+
readTextFile(paths.current)
|
|
9231
|
+
]);
|
|
9232
|
+
let config = null;
|
|
9233
|
+
if (configContent) {
|
|
9234
|
+
try {
|
|
9235
|
+
config = import_yaml.default.parse(configContent);
|
|
9236
|
+
} catch {}
|
|
9237
|
+
}
|
|
9238
|
+
let state = null;
|
|
9239
|
+
if (currentContent) {
|
|
9240
|
+
try {
|
|
9241
|
+
state = import_yaml.default.parse(currentContent);
|
|
9242
|
+
} catch {}
|
|
9243
|
+
}
|
|
9244
|
+
const sections = [];
|
|
9245
|
+
sections.push("# Current State");
|
|
9246
|
+
if (state) {
|
|
9247
|
+
const stateLines = [];
|
|
9248
|
+
stateLines.push(`- Generation: ${state.id}`);
|
|
9249
|
+
stateLines.push(`- Type: ${state.type}`);
|
|
9250
|
+
stateLines.push(`- Goal: ${state.goal}`);
|
|
9251
|
+
stateLines.push(`- Stage: ${state.stage}`);
|
|
9252
|
+
if (state.phase)
|
|
9253
|
+
stateLines.push(`- Phase: ${state.phase}`);
|
|
9254
|
+
if (state.type === "merge" && state.parents?.length) {
|
|
9255
|
+
stateLines.push(`- Parents: ${state.parents.join(", ")}`);
|
|
9256
|
+
}
|
|
9257
|
+
sections.push(stateLines.join(`
|
|
9258
|
+
`));
|
|
9259
|
+
} else {
|
|
9260
|
+
sections.push("No active generation.");
|
|
9261
|
+
}
|
|
9262
|
+
if (config) {
|
|
9263
|
+
const strictStage = state ? state.stage : "none";
|
|
9264
|
+
const strictSection = buildStrictSection(config.strictEdit ?? false, config.strictMerge ?? false, strictStage, state?.type);
|
|
9265
|
+
if (strictSection) {
|
|
9266
|
+
sections.push(strictSection.trimStart());
|
|
9267
|
+
}
|
|
9268
|
+
}
|
|
9269
|
+
if (config?.language) {
|
|
9270
|
+
sections.push(`# Language
|
|
9271
|
+
Always respond in ${config.language}. Use ${config.language} for all explanations, comments, and communications. Technical terms and code identifiers remain in their original form.`);
|
|
9272
|
+
}
|
|
9273
|
+
if (config?.daemon === true) {
|
|
9274
|
+
sections.push(buildDaemonStaticSection());
|
|
9275
|
+
}
|
|
9276
|
+
try {
|
|
9277
|
+
const migrationsSection = buildPendingMigrationsSection(config, getPackageVersion());
|
|
9278
|
+
if (migrationsSection)
|
|
9279
|
+
sections.push(migrationsSection);
|
|
9280
|
+
} catch {}
|
|
9281
|
+
return sections.join(`
|
|
9282
|
+
|
|
9283
|
+
---
|
|
9284
|
+
|
|
9285
|
+
`);
|
|
9286
|
+
}
|
|
9287
|
+
function buildDaemonStaticSection() {
|
|
9288
|
+
return [
|
|
9289
|
+
"# Code Intelligence (Daemon)",
|
|
9290
|
+
"",
|
|
9291
|
+
"- Enabled: true",
|
|
9292
|
+
"- Base URL: http://127.0.0.1:17224",
|
|
9293
|
+
"- See `~/.reap/reap-guide.md` § Code Intelligence (Daemon) for query examples and protocol."
|
|
9294
|
+
].join(`
|
|
9295
|
+
`);
|
|
9296
|
+
}
|
|
9297
|
+
async function execute() {
|
|
9298
|
+
const context = await buildKnowledgeContext(process.cwd());
|
|
9299
|
+
if (!context) {
|
|
9300
|
+
process.exit(0);
|
|
9301
|
+
}
|
|
9302
|
+
const output = {
|
|
9303
|
+
hookSpecificOutput: {
|
|
9304
|
+
hookEventName: "SessionStart",
|
|
9305
|
+
additionalContext: context
|
|
9306
|
+
}
|
|
9307
|
+
};
|
|
9308
|
+
process.stdout.write(JSON.stringify(output) + `
|
|
9309
|
+
`);
|
|
9310
|
+
process.exit(0);
|
|
9311
|
+
}
|
|
9312
|
+
|
|
9098
9313
|
// src/core/dump-state-sync.ts
|
|
9314
|
+
function getPackageVersion2() {
|
|
9315
|
+
try {
|
|
9316
|
+
const __dir = dirname4(fileURLToPath3(import.meta.url));
|
|
9317
|
+
for (const rel of [join4(__dir, "..", "..", "package.json"), join4(__dir, "..", "package.json")]) {
|
|
9318
|
+
try {
|
|
9319
|
+
return JSON.parse(readFileSync3(rel, "utf-8")).version;
|
|
9320
|
+
} catch {}
|
|
9321
|
+
}
|
|
9322
|
+
} catch {}
|
|
9323
|
+
return "0.0.0";
|
|
9324
|
+
}
|
|
9099
9325
|
var DUMP_COMMANDS = new Set([
|
|
9100
9326
|
"start",
|
|
9101
9327
|
"learning",
|
|
@@ -9117,28 +9343,28 @@ var DUMP_COMMANDS = new Set([
|
|
|
9117
9343
|
"init"
|
|
9118
9344
|
]);
|
|
9119
9345
|
function buildKnowledgeContextSync(cwd) {
|
|
9120
|
-
const configPath =
|
|
9121
|
-
if (!
|
|
9346
|
+
const configPath = join4(cwd, ".reap", "config.yml");
|
|
9347
|
+
if (!existsSync2(configPath))
|
|
9122
9348
|
return null;
|
|
9123
9349
|
const paths = createPaths(cwd);
|
|
9124
9350
|
let configContent = "";
|
|
9125
9351
|
let currentContent = "";
|
|
9126
9352
|
try {
|
|
9127
|
-
configContent =
|
|
9353
|
+
configContent = readFileSync3(paths.config, "utf-8");
|
|
9128
9354
|
} catch {}
|
|
9129
9355
|
try {
|
|
9130
|
-
currentContent =
|
|
9356
|
+
currentContent = readFileSync3(paths.current, "utf-8");
|
|
9131
9357
|
} catch {}
|
|
9132
9358
|
let config = null;
|
|
9133
9359
|
if (configContent) {
|
|
9134
9360
|
try {
|
|
9135
|
-
config =
|
|
9361
|
+
config = import_yaml2.default.parse(configContent);
|
|
9136
9362
|
} catch {}
|
|
9137
9363
|
}
|
|
9138
9364
|
let state = null;
|
|
9139
9365
|
if (currentContent) {
|
|
9140
9366
|
try {
|
|
9141
|
-
state =
|
|
9367
|
+
state = import_yaml2.default.parse(currentContent);
|
|
9142
9368
|
} catch {}
|
|
9143
9369
|
}
|
|
9144
9370
|
const sections = [];
|
|
@@ -9170,6 +9396,14 @@ function buildKnowledgeContextSync(cwd) {
|
|
|
9170
9396
|
sections.push(`# Language
|
|
9171
9397
|
Always respond in ${config.language}. Use ${config.language} for all explanations, comments, and communications. Technical terms and code identifiers remain in their original form.`);
|
|
9172
9398
|
}
|
|
9399
|
+
if (config?.daemon === true) {
|
|
9400
|
+
sections.push(buildDaemonStaticSection());
|
|
9401
|
+
}
|
|
9402
|
+
try {
|
|
9403
|
+
const migrationsSection = buildPendingMigrationsSection(config, getPackageVersion2());
|
|
9404
|
+
if (migrationsSection)
|
|
9405
|
+
sections.push(migrationsSection);
|
|
9406
|
+
} catch {}
|
|
9173
9407
|
return sections.join(`
|
|
9174
9408
|
|
|
9175
9409
|
---
|
|
@@ -9181,7 +9415,7 @@ function dumpStateSync(cwd) {
|
|
|
9181
9415
|
if (!ctx)
|
|
9182
9416
|
return;
|
|
9183
9417
|
const paths = createPaths(cwd);
|
|
9184
|
-
mkdirSync(
|
|
9418
|
+
mkdirSync(dirname4(paths.sessionState), { recursive: true });
|
|
9185
9419
|
writeFileSync(paths.sessionState, ctx + `
|
|
9186
9420
|
`, "utf-8");
|
|
9187
9421
|
}
|
|
@@ -9297,7 +9531,7 @@ ${claudeMdSection}
|
|
|
9297
9531
|
6. If confirmed: \`reap run start --type embryo --goal "<goal>"\`
|
|
9298
9532
|
`;
|
|
9299
9533
|
}
|
|
9300
|
-
async function
|
|
9534
|
+
async function execute2(paths, projectName) {
|
|
9301
9535
|
const config = await initCommon(paths, projectName);
|
|
9302
9536
|
await writeTextFile(paths.application, DEFAULT_APPLICATION);
|
|
9303
9537
|
await writeTextFile(paths.environmentSummary, `# ${config.project} Environment
|
|
@@ -9327,10 +9561,10 @@ init_common();
|
|
|
9327
9561
|
// src/core/scanner.ts
|
|
9328
9562
|
init_fs();
|
|
9329
9563
|
import { readdir as readdir3, stat as stat2 } from "fs/promises";
|
|
9330
|
-
import { join as
|
|
9564
|
+
import { join as join7, relative } from "path";
|
|
9331
9565
|
async function scanCodebase(root) {
|
|
9332
9566
|
let packageJson = null;
|
|
9333
|
-
const pkgContent = await readTextFile(
|
|
9567
|
+
const pkgContent = await readTextFile(join7(root, "package.json"));
|
|
9334
9568
|
if (pkgContent) {
|
|
9335
9569
|
try {
|
|
9336
9570
|
packageJson = JSON.parse(pkgContent);
|
|
@@ -9339,7 +9573,7 @@ async function scanCodebase(root) {
|
|
|
9339
9573
|
const deps = Object.keys(packageJson?.dependencies ?? {});
|
|
9340
9574
|
const devDeps = Object.keys(packageJson?.devDependencies ?? {});
|
|
9341
9575
|
const scripts = packageJson?.scripts ?? {};
|
|
9342
|
-
const hasTypeScript = !!await readTextFile(
|
|
9576
|
+
const hasTypeScript = !!await readTextFile(join7(root, "tsconfig.json")) || devDeps.includes("typescript");
|
|
9343
9577
|
const testFrameworks = ["jest", "vitest", "mocha", "@jest/core", "bun:test"];
|
|
9344
9578
|
const testFramework = [...deps, ...devDeps].find((d) => testFrameworks.includes(d)) ?? null;
|
|
9345
9579
|
const hasTests = !!testFramework || scripts.test !== undefined;
|
|
@@ -9347,7 +9581,7 @@ async function scanCodebase(root) {
|
|
|
9347
9581
|
const buildTool = [...deps, ...devDeps].find((d) => buildTools.includes(d)) ?? null;
|
|
9348
9582
|
const tree = await buildTree(root, root, 2);
|
|
9349
9583
|
let readmeExcerpt = null;
|
|
9350
|
-
const readme = await readTextFile(
|
|
9584
|
+
const readme = await readTextFile(join7(root, "README.md"));
|
|
9351
9585
|
if (readme) {
|
|
9352
9586
|
readmeExcerpt = readme.slice(0, 500);
|
|
9353
9587
|
}
|
|
@@ -9381,7 +9615,7 @@ async function buildTree(root, dir, depth) {
|
|
|
9381
9615
|
continue;
|
|
9382
9616
|
if (SKIP_DIRS.has(entry))
|
|
9383
9617
|
continue;
|
|
9384
|
-
const fullPath =
|
|
9618
|
+
const fullPath = join7(dir, entry);
|
|
9385
9619
|
const relPath = relative(root, fullPath);
|
|
9386
9620
|
const s = await stat2(fullPath).catch(() => null);
|
|
9387
9621
|
if (!s)
|
|
@@ -9603,7 +9837,7 @@ ${claudeMdSection}
|
|
|
9603
9837
|
7. If confirmed: \`reap run start --type embryo --goal "<goal>"\`
|
|
9604
9838
|
`;
|
|
9605
9839
|
}
|
|
9606
|
-
async function
|
|
9840
|
+
async function execute3(paths, projectName) {
|
|
9607
9841
|
const scan = await scanCodebase(paths.root);
|
|
9608
9842
|
const name = projectName ?? scan.projectName;
|
|
9609
9843
|
const config = await initCommon(paths, name);
|
|
@@ -9675,14 +9909,14 @@ async function execute2(paths, projectName) {
|
|
|
9675
9909
|
|
|
9676
9910
|
// src/cli/commands/init/repair.ts
|
|
9677
9911
|
init_fs();
|
|
9678
|
-
var
|
|
9912
|
+
var import_yaml5 = __toESM(require_dist(), 1);
|
|
9679
9913
|
init_common();
|
|
9680
|
-
async function
|
|
9914
|
+
async function execute4(paths) {
|
|
9681
9915
|
const configContent = await readTextFile(paths.config);
|
|
9682
9916
|
if (!configContent) {
|
|
9683
9917
|
emitError("init", ".reap/config.yml not found. This is not a reap project. Run 'reap init' first.");
|
|
9684
9918
|
}
|
|
9685
|
-
const config =
|
|
9919
|
+
const config = import_yaml5.default.parse(configContent);
|
|
9686
9920
|
const projectName = config.project ?? "my-project";
|
|
9687
9921
|
const claudeMdAction = await ensureClaudeMd(paths.root, projectName);
|
|
9688
9922
|
const repaired = [];
|
|
@@ -9708,11 +9942,11 @@ async function execute3(paths) {
|
|
|
9708
9942
|
|
|
9709
9943
|
// src/cli/commands/migrate.ts
|
|
9710
9944
|
init_fs();
|
|
9711
|
-
var
|
|
9945
|
+
var import_yaml6 = __toESM(require_dist(), 1);
|
|
9712
9946
|
import { readdir as readdir4, cp, rename, rm as rm2 } from "fs/promises";
|
|
9713
|
-
import { join as
|
|
9947
|
+
import { join as join8, dirname as dirname6 } from "path";
|
|
9714
9948
|
import { execSync as execSync2 } from "child_process";
|
|
9715
|
-
import { fileURLToPath as
|
|
9949
|
+
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
9716
9950
|
import { homedir as homedir2 } from "os";
|
|
9717
9951
|
|
|
9718
9952
|
// src/core/git.ts
|
|
@@ -9906,8 +10140,8 @@ function pushSubmodules(cwd) {
|
|
|
9906
10140
|
init_integrity();
|
|
9907
10141
|
init_common();
|
|
9908
10142
|
function distPath2(...segments) {
|
|
9909
|
-
const __dirname2 =
|
|
9910
|
-
return
|
|
10143
|
+
const __dirname2 = dirname6(fileURLToPath5(import.meta.url));
|
|
10144
|
+
return join8(__dirname2, "..", "templates", ...segments);
|
|
9911
10145
|
}
|
|
9912
10146
|
function isGitClean(cwd) {
|
|
9913
10147
|
if (!isGitRepo(cwd))
|
|
@@ -9928,14 +10162,14 @@ async function loadMigrationState(paths) {
|
|
|
9928
10162
|
if (!content)
|
|
9929
10163
|
return null;
|
|
9930
10164
|
try {
|
|
9931
|
-
return
|
|
10165
|
+
return import_yaml6.default.parse(content);
|
|
9932
10166
|
} catch {
|
|
9933
10167
|
return null;
|
|
9934
10168
|
}
|
|
9935
10169
|
}
|
|
9936
10170
|
async function saveMigrationState(paths, state) {
|
|
9937
10171
|
state.updatedAt = new Date().toISOString();
|
|
9938
|
-
await writeTextFile(paths.migrationState,
|
|
10172
|
+
await writeTextFile(paths.migrationState, import_yaml6.default.stringify(state));
|
|
9939
10173
|
}
|
|
9940
10174
|
async function clearMigrationState(paths) {
|
|
9941
10175
|
if (await fileExists(paths.migrationState)) {
|
|
@@ -9983,7 +10217,7 @@ function mapHookFilename(filename) {
|
|
|
9983
10217
|
}
|
|
9984
10218
|
async function scanV15Structure(paths) {
|
|
9985
10219
|
const genomeFiles = [];
|
|
9986
|
-
const genomeDir =
|
|
10220
|
+
const genomeDir = join8(paths.reap, "v15", "genome");
|
|
9987
10221
|
const currentGenomeDir = paths.genome;
|
|
9988
10222
|
try {
|
|
9989
10223
|
const entries = await readdir4(currentGenomeDir);
|
|
@@ -9993,7 +10227,7 @@ async function scanV15Structure(paths) {
|
|
|
9993
10227
|
}
|
|
9994
10228
|
} catch {}
|
|
9995
10229
|
const domainFiles = [];
|
|
9996
|
-
const domainDir =
|
|
10230
|
+
const domainDir = join8(currentGenomeDir, "domain");
|
|
9997
10231
|
try {
|
|
9998
10232
|
const entries = await readdir4(domainDir);
|
|
9999
10233
|
for (const e of entries) {
|
|
@@ -10063,14 +10297,14 @@ async function executePreCheck(paths) {
|
|
|
10063
10297
|
if (currentContent && currentContent.trim()) {
|
|
10064
10298
|
emitError("migrate", "Active generation exists. Run '/reap.abort' first, then retry migration.");
|
|
10065
10299
|
}
|
|
10066
|
-
if (await fileExists(
|
|
10300
|
+
if (await fileExists(join8(paths.reap, "v15"))) {
|
|
10067
10301
|
emitError("migrate", "Previous migration backup (.reap/v15/) already exists. Remove it first if you want to re-migrate.");
|
|
10068
10302
|
}
|
|
10069
10303
|
const configContent = await readTextFile(paths.config);
|
|
10070
10304
|
let config = {};
|
|
10071
10305
|
if (configContent) {
|
|
10072
10306
|
try {
|
|
10073
|
-
config =
|
|
10307
|
+
config = import_yaml6.default.parse(configContent) ?? {};
|
|
10074
10308
|
} catch {
|
|
10075
10309
|
emitError("migrate", "config.yml is not valid YAML.");
|
|
10076
10310
|
}
|
|
@@ -10155,7 +10389,7 @@ async function executeMain(paths) {
|
|
|
10155
10389
|
let state = await loadMigrationState(paths);
|
|
10156
10390
|
if (!state) {
|
|
10157
10391
|
if (!await detectV15(paths)) {
|
|
10158
|
-
if (!await fileExists(
|
|
10392
|
+
if (!await fileExists(join8(paths.reap, "v15"))) {
|
|
10159
10393
|
emitError("migrate", "v0.15 structure not found. Cannot proceed.");
|
|
10160
10394
|
}
|
|
10161
10395
|
}
|
|
@@ -10163,7 +10397,7 @@ async function executeMain(paths) {
|
|
|
10163
10397
|
await saveMigrationState(paths, state);
|
|
10164
10398
|
}
|
|
10165
10399
|
const done = new Set(state.completedSteps);
|
|
10166
|
-
const v15Dir =
|
|
10400
|
+
const v15Dir = join8(paths.reap, "v15");
|
|
10167
10401
|
async function step(name, fn) {
|
|
10168
10402
|
if (done.has(name))
|
|
10169
10403
|
return;
|
|
@@ -10174,12 +10408,12 @@ async function executeMain(paths) {
|
|
|
10174
10408
|
await step("backup", async () => {
|
|
10175
10409
|
await ensureDir(v15Dir);
|
|
10176
10410
|
const backupItems = [
|
|
10177
|
-
{ src: paths.genome, dest:
|
|
10178
|
-
{ src: paths.environment, dest:
|
|
10179
|
-
{ src: paths.life, dest:
|
|
10180
|
-
{ src: paths.lineage, dest:
|
|
10181
|
-
{ src: paths.hooks, dest:
|
|
10182
|
-
{ src: paths.config, dest:
|
|
10411
|
+
{ src: paths.genome, dest: join8(v15Dir, "genome") },
|
|
10412
|
+
{ src: paths.environment, dest: join8(v15Dir, "environment") },
|
|
10413
|
+
{ src: paths.life, dest: join8(v15Dir, "life") },
|
|
10414
|
+
{ src: paths.lineage, dest: join8(v15Dir, "lineage") },
|
|
10415
|
+
{ src: paths.hooks, dest: join8(v15Dir, "hooks") },
|
|
10416
|
+
{ src: paths.config, dest: join8(v15Dir, "config.yml") }
|
|
10183
10417
|
];
|
|
10184
10418
|
for (const item of backupItems) {
|
|
10185
10419
|
if (await fileExists(item.src)) {
|
|
@@ -10189,7 +10423,7 @@ async function executeMain(paths) {
|
|
|
10189
10423
|
});
|
|
10190
10424
|
await step("create-dirs", async () => {
|
|
10191
10425
|
await ensureDir(paths.genome);
|
|
10192
|
-
await ensureDir(
|
|
10426
|
+
await ensureDir(join8(paths.environment, "domain"));
|
|
10193
10427
|
await ensureDir(paths.environmentResources);
|
|
10194
10428
|
await ensureDir(paths.environmentDocs);
|
|
10195
10429
|
await ensureDir(paths.life);
|
|
@@ -10197,7 +10431,7 @@ async function executeMain(paths) {
|
|
|
10197
10431
|
await ensureDir(paths.lineage);
|
|
10198
10432
|
await ensureDir(paths.vision);
|
|
10199
10433
|
await ensureDir(paths.visionDesign);
|
|
10200
|
-
await ensureDir(
|
|
10434
|
+
await ensureDir(join8(paths.vision, "memory"));
|
|
10201
10435
|
await ensureDir(paths.hooks);
|
|
10202
10436
|
});
|
|
10203
10437
|
let v16Config = {
|
|
@@ -10211,10 +10445,10 @@ async function executeMain(paths) {
|
|
|
10211
10445
|
autoIssueReport: true
|
|
10212
10446
|
};
|
|
10213
10447
|
await step("config-migrate", async () => {
|
|
10214
|
-
const v15ConfigContent = await readTextFile(
|
|
10448
|
+
const v15ConfigContent = await readTextFile(join8(v15Dir, "config.yml"));
|
|
10215
10449
|
let v15Config = {};
|
|
10216
10450
|
if (v15ConfigContent) {
|
|
10217
|
-
v15Config =
|
|
10451
|
+
v15Config = import_yaml6.default.parse(v15ConfigContent) ?? {};
|
|
10218
10452
|
}
|
|
10219
10453
|
const wasStrict = v15Config.strict ?? false;
|
|
10220
10454
|
v16Config = {
|
|
@@ -10227,55 +10461,55 @@ async function executeMain(paths) {
|
|
|
10227
10461
|
autoUpdate: v15Config.autoUpdate ?? true,
|
|
10228
10462
|
autoIssueReport: v15Config.autoIssueReport ?? true
|
|
10229
10463
|
};
|
|
10230
|
-
await writeTextFile(paths.config,
|
|
10464
|
+
await writeTextFile(paths.config, import_yaml6.default.stringify(v16Config));
|
|
10231
10465
|
});
|
|
10232
10466
|
if (done.has("config-migrate")) {
|
|
10233
10467
|
const existingConfig = await readTextFile(paths.config);
|
|
10234
10468
|
if (existingConfig) {
|
|
10235
|
-
const parsed =
|
|
10469
|
+
const parsed = import_yaml6.default.parse(existingConfig) ?? {};
|
|
10236
10470
|
v16Config = { ...v16Config, ...parsed };
|
|
10237
10471
|
}
|
|
10238
10472
|
}
|
|
10239
|
-
const principles = await readTextFile(
|
|
10240
|
-
const conventions = await readTextFile(
|
|
10241
|
-
const constraints = await readTextFile(
|
|
10242
|
-
const sourceMap = await readTextFile(
|
|
10473
|
+
const principles = await readTextFile(join8(v15Dir, "genome", "principles.md")) ?? "";
|
|
10474
|
+
const conventions = await readTextFile(join8(v15Dir, "genome", "conventions.md")) ?? "";
|
|
10475
|
+
const constraints = await readTextFile(join8(v15Dir, "genome", "constraints.md")) ?? "";
|
|
10476
|
+
const sourceMap = await readTextFile(join8(v15Dir, "genome", "source-map.md")) ?? "";
|
|
10243
10477
|
const evolutionTemplate = await readTextFile(distPath2("evolution.md")) ?? "";
|
|
10244
10478
|
const domainFiles = [];
|
|
10245
|
-
const v15DomainDir =
|
|
10479
|
+
const v15DomainDir = join8(v15Dir, "genome", "domain");
|
|
10246
10480
|
try {
|
|
10247
10481
|
const entries = await readdir4(v15DomainDir);
|
|
10248
10482
|
domainFiles.push(...entries.filter((e) => e.endsWith(".md")));
|
|
10249
10483
|
} catch {}
|
|
10250
10484
|
await step("environment-copy", async () => {
|
|
10251
|
-
const v15EnvSummary =
|
|
10485
|
+
const v15EnvSummary = join8(v15Dir, "environment", "summary.md");
|
|
10252
10486
|
if (await fileExists(v15EnvSummary)) {
|
|
10253
10487
|
await cp(v15EnvSummary, paths.environmentSummary);
|
|
10254
10488
|
}
|
|
10255
|
-
const v15EnvDomain =
|
|
10489
|
+
const v15EnvDomain = join8(v15Dir, "environment", "domain");
|
|
10256
10490
|
if (await fileExists(v15EnvDomain)) {
|
|
10257
10491
|
try {
|
|
10258
10492
|
const entries = await readdir4(v15EnvDomain);
|
|
10259
10493
|
for (const e of entries) {
|
|
10260
|
-
await cp(
|
|
10494
|
+
await cp(join8(v15EnvDomain, e), join8(paths.environmentDomain, e), { recursive: true });
|
|
10261
10495
|
}
|
|
10262
10496
|
} catch {}
|
|
10263
10497
|
}
|
|
10264
|
-
const v15EnvResources =
|
|
10498
|
+
const v15EnvResources = join8(v15Dir, "environment", "resources");
|
|
10265
10499
|
if (await fileExists(v15EnvResources)) {
|
|
10266
10500
|
try {
|
|
10267
10501
|
const entries = await readdir4(v15EnvResources);
|
|
10268
10502
|
for (const e of entries) {
|
|
10269
|
-
await cp(
|
|
10503
|
+
await cp(join8(v15EnvResources, e), join8(paths.environmentResources, e), { recursive: true });
|
|
10270
10504
|
}
|
|
10271
10505
|
} catch {}
|
|
10272
10506
|
}
|
|
10273
|
-
const v15EnvDocs =
|
|
10507
|
+
const v15EnvDocs = join8(v15Dir, "environment", "docs");
|
|
10274
10508
|
if (await fileExists(v15EnvDocs)) {
|
|
10275
10509
|
try {
|
|
10276
10510
|
const entries = await readdir4(v15EnvDocs);
|
|
10277
10511
|
for (const e of entries) {
|
|
10278
|
-
await cp(
|
|
10512
|
+
await cp(join8(v15EnvDocs, e), join8(paths.environmentDocs, e), { recursive: true });
|
|
10279
10513
|
}
|
|
10280
10514
|
} catch {}
|
|
10281
10515
|
}
|
|
@@ -10284,8 +10518,8 @@ async function executeMain(paths) {
|
|
|
10284
10518
|
}
|
|
10285
10519
|
if (domainFiles.length > 0) {
|
|
10286
10520
|
for (const f of domainFiles) {
|
|
10287
|
-
const src =
|
|
10288
|
-
const dest =
|
|
10521
|
+
const src = join8(v15DomainDir, f);
|
|
10522
|
+
const dest = join8(paths.environmentDomain, f);
|
|
10289
10523
|
if (await fileExists(src)) {
|
|
10290
10524
|
await cp(src, dest);
|
|
10291
10525
|
}
|
|
@@ -10293,23 +10527,23 @@ async function executeMain(paths) {
|
|
|
10293
10527
|
}
|
|
10294
10528
|
});
|
|
10295
10529
|
await step("lineage-copy", async () => {
|
|
10296
|
-
const v15Lineage =
|
|
10530
|
+
const v15Lineage = join8(v15Dir, "lineage");
|
|
10297
10531
|
if (await fileExists(v15Lineage)) {
|
|
10298
10532
|
try {
|
|
10299
10533
|
const entries = await readdir4(v15Lineage);
|
|
10300
10534
|
for (const e of entries) {
|
|
10301
|
-
await cp(
|
|
10535
|
+
await cp(join8(v15Lineage, e), join8(paths.lineage, e), { recursive: true });
|
|
10302
10536
|
}
|
|
10303
10537
|
} catch {}
|
|
10304
10538
|
}
|
|
10305
10539
|
});
|
|
10306
10540
|
await step("backlog-copy", async () => {
|
|
10307
|
-
const v15Backlog =
|
|
10541
|
+
const v15Backlog = join8(v15Dir, "life", "backlog");
|
|
10308
10542
|
if (await fileExists(v15Backlog)) {
|
|
10309
10543
|
try {
|
|
10310
10544
|
const entries = await readdir4(v15Backlog);
|
|
10311
10545
|
for (const e of entries) {
|
|
10312
|
-
await cp(
|
|
10546
|
+
await cp(join8(v15Backlog, e), join8(paths.backlog, e), { recursive: true });
|
|
10313
10547
|
}
|
|
10314
10548
|
} catch {}
|
|
10315
10549
|
}
|
|
@@ -10317,20 +10551,20 @@ async function executeMain(paths) {
|
|
|
10317
10551
|
const hooksMapped = [];
|
|
10318
10552
|
const hooksUnmapped = [];
|
|
10319
10553
|
await step("hooks-map", async () => {
|
|
10320
|
-
const v15Hooks =
|
|
10554
|
+
const v15Hooks = join8(v15Dir, "hooks");
|
|
10321
10555
|
if (await fileExists(v15Hooks)) {
|
|
10322
10556
|
try {
|
|
10323
10557
|
const entries = await readdir4(v15Hooks);
|
|
10324
10558
|
for (const e of entries) {
|
|
10325
10559
|
if (e === "conditions") {
|
|
10326
|
-
const condSrc =
|
|
10327
|
-
const condDest =
|
|
10560
|
+
const condSrc = join8(v15Hooks, "conditions");
|
|
10561
|
+
const condDest = join8(paths.hooks, "conditions");
|
|
10328
10562
|
await cp(condSrc, condDest, { recursive: true });
|
|
10329
10563
|
continue;
|
|
10330
10564
|
}
|
|
10331
10565
|
const mapping = mapHookFilename(e);
|
|
10332
10566
|
if (mapping) {
|
|
10333
|
-
await cp(
|
|
10567
|
+
await cp(join8(v15Hooks, e), join8(paths.hooks, mapping.newName));
|
|
10334
10568
|
if (mapping.newName !== e) {
|
|
10335
10569
|
hooksMapped.push(`${e} → ${mapping.newName}`);
|
|
10336
10570
|
}
|
|
@@ -10338,7 +10572,7 @@ async function executeMain(paths) {
|
|
|
10338
10572
|
hooksUnmapped.push(e);
|
|
10339
10573
|
}
|
|
10340
10574
|
} else {
|
|
10341
|
-
await cp(
|
|
10575
|
+
await cp(join8(v15Hooks, e), join8(paths.hooks, e));
|
|
10342
10576
|
}
|
|
10343
10577
|
}
|
|
10344
10578
|
} catch {}
|
|
@@ -10358,20 +10592,20 @@ async function executeMain(paths) {
|
|
|
10358
10592
|
## Goal Items
|
|
10359
10593
|
<!-- Checklist of major milestones -->
|
|
10360
10594
|
`;
|
|
10361
|
-
await writeTextFile(
|
|
10362
|
-
await writeTextFile(
|
|
10595
|
+
await writeTextFile(join8(paths.vision, "goals.md"), goalsContent);
|
|
10596
|
+
await writeTextFile(join8(paths.vision, "memory", "longterm.md"), `# Longterm Memory
|
|
10363
10597
|
`);
|
|
10364
|
-
await writeTextFile(
|
|
10598
|
+
await writeTextFile(join8(paths.vision, "memory", "midterm.md"), `# Midterm Memory
|
|
10365
10599
|
`);
|
|
10366
|
-
await writeTextFile(
|
|
10600
|
+
await writeTextFile(join8(paths.vision, "memory", "shortterm.md"), `# Shortterm Memory
|
|
10367
10601
|
`);
|
|
10368
10602
|
});
|
|
10369
10603
|
await step("reap-guide", async () => {
|
|
10370
10604
|
const guide = await readTextFile(distPath2("reap-guide.md"));
|
|
10371
10605
|
if (guide) {
|
|
10372
|
-
const reapHome =
|
|
10606
|
+
const reapHome = join8(homedir2(), ".reap");
|
|
10373
10607
|
await ensureDir(reapHome);
|
|
10374
|
-
await writeTextFile(
|
|
10608
|
+
await writeTextFile(join8(reapHome, "reap-guide.md"), guide);
|
|
10375
10609
|
}
|
|
10376
10610
|
});
|
|
10377
10611
|
await step("claude-md", async () => {
|
|
@@ -10567,7 +10801,7 @@ async function executeComplete(paths) {
|
|
|
10567
10801
|
message: `Migration complete. Backup preserved at .reap/v15/. Run 'reap status' to verify.`
|
|
10568
10802
|
});
|
|
10569
10803
|
}
|
|
10570
|
-
async function
|
|
10804
|
+
async function execute5(paths, phase) {
|
|
10571
10805
|
switch (phase) {
|
|
10572
10806
|
case undefined:
|
|
10573
10807
|
case "confirm":
|
|
@@ -10611,12 +10845,12 @@ var PROJECT_FILES = [
|
|
|
10611
10845
|
var SOURCE_GLOBS = [".ts", ".js", ".py", ".rs", ".go", ".java", ".rb", ".php", ".swift", ".kt"];
|
|
10612
10846
|
async function detectMode(root) {
|
|
10613
10847
|
for (const file of PROJECT_FILES) {
|
|
10614
|
-
if (await fileExists(
|
|
10848
|
+
if (await fileExists(join9(root, file))) {
|
|
10615
10849
|
return "adoption";
|
|
10616
10850
|
}
|
|
10617
10851
|
}
|
|
10618
10852
|
for (const dir of SOURCE_DIRS) {
|
|
10619
|
-
if (await fileExists(
|
|
10853
|
+
if (await fileExists(join9(root, dir))) {
|
|
10620
10854
|
return "adoption";
|
|
10621
10855
|
}
|
|
10622
10856
|
}
|
|
@@ -10636,18 +10870,18 @@ async function detectMode(root) {
|
|
|
10636
10870
|
}
|
|
10637
10871
|
return "greenfield";
|
|
10638
10872
|
}
|
|
10639
|
-
async function
|
|
10873
|
+
async function execute6(projectName, mode, repair, migrate, phase) {
|
|
10640
10874
|
const root = process.cwd();
|
|
10641
10875
|
const paths = createPaths(root);
|
|
10642
10876
|
if (migrate) {
|
|
10643
|
-
await
|
|
10877
|
+
await execute5(paths, phase);
|
|
10644
10878
|
return;
|
|
10645
10879
|
}
|
|
10646
10880
|
if (repair) {
|
|
10647
10881
|
if (!await fileExists(paths.config)) {
|
|
10648
10882
|
emitError("init", ".reap/ not found. This is not a reap project. Run 'reap init' first.");
|
|
10649
10883
|
}
|
|
10650
|
-
await
|
|
10884
|
+
await execute4(paths);
|
|
10651
10885
|
return;
|
|
10652
10886
|
}
|
|
10653
10887
|
if (await fileExists(paths.config)) {
|
|
@@ -10655,18 +10889,18 @@ async function execute5(projectName, mode, repair, migrate, phase) {
|
|
|
10655
10889
|
}
|
|
10656
10890
|
const resolvedMode = mode ?? await detectMode(root);
|
|
10657
10891
|
if (resolvedMode === "adoption") {
|
|
10658
|
-
await
|
|
10892
|
+
await execute3(paths, projectName);
|
|
10659
10893
|
} else {
|
|
10660
|
-
await
|
|
10894
|
+
await execute2(paths, projectName ?? "my-project");
|
|
10661
10895
|
}
|
|
10662
10896
|
}
|
|
10663
10897
|
|
|
10664
10898
|
// src/cli/commands/status.ts
|
|
10665
|
-
var
|
|
10899
|
+
var import_yaml7 = __toESM(require_dist(), 1);
|
|
10666
10900
|
import { readdir as readdir6 } from "fs/promises";
|
|
10667
10901
|
init_fs();
|
|
10668
10902
|
init_integrity();
|
|
10669
|
-
async function
|
|
10903
|
+
async function execute7() {
|
|
10670
10904
|
const root = process.cwd();
|
|
10671
10905
|
const paths = createPaths(root);
|
|
10672
10906
|
if (!await fileExists(paths.config)) {
|
|
@@ -10676,11 +10910,11 @@ async function execute6() {
|
|
|
10676
10910
|
emitError("status", "This project uses REAP v0.15 structure. Run '/reap.update' to upgrade to v0.16.");
|
|
10677
10911
|
}
|
|
10678
10912
|
const configContent = await readTextFile(paths.config);
|
|
10679
|
-
const config = configContent ?
|
|
10913
|
+
const config = configContent ? import_yaml7.default.parse(configContent) : null;
|
|
10680
10914
|
let generation = null;
|
|
10681
10915
|
const currentContent = await readTextFile(paths.current);
|
|
10682
10916
|
if (currentContent) {
|
|
10683
|
-
generation =
|
|
10917
|
+
generation = import_yaml7.default.parse(currentContent);
|
|
10684
10918
|
}
|
|
10685
10919
|
let completedGenerations = 0;
|
|
10686
10920
|
try {
|
|
@@ -10714,7 +10948,7 @@ async function execute6() {
|
|
|
10714
10948
|
}
|
|
10715
10949
|
|
|
10716
10950
|
// src/cli/commands/run/index.ts
|
|
10717
|
-
var
|
|
10951
|
+
var import_yaml22 = __toESM(require_dist(), 1);
|
|
10718
10952
|
init_fs();
|
|
10719
10953
|
init_integrity();
|
|
10720
10954
|
|
|
@@ -10742,11 +10976,12 @@ function autoReport(command, error, extraLabels) {
|
|
|
10742
10976
|
}
|
|
10743
10977
|
|
|
10744
10978
|
// src/cli/commands/run/start.ts
|
|
10745
|
-
|
|
10979
|
+
var import_yaml12 = __toESM(require_dist(), 1);
|
|
10980
|
+
import { basename, join as join14 } from "path";
|
|
10746
10981
|
|
|
10747
10982
|
// src/core/generation.ts
|
|
10748
10983
|
init_fs();
|
|
10749
|
-
var
|
|
10984
|
+
var import_yaml8 = __toESM(require_dist(), 1);
|
|
10750
10985
|
import { createHash as createHash3 } from "crypto";
|
|
10751
10986
|
import { hostname } from "os";
|
|
10752
10987
|
import { readdir as readdir7 } from "fs/promises";
|
|
@@ -10774,12 +11009,12 @@ class GenerationManager {
|
|
|
10774
11009
|
const content = await readTextFile(this.paths.current);
|
|
10775
11010
|
if (!content)
|
|
10776
11011
|
return null;
|
|
10777
|
-
return
|
|
11012
|
+
return import_yaml8.default.parse(content);
|
|
10778
11013
|
}
|
|
10779
11014
|
async save(state) {
|
|
10780
11015
|
const header = `# REAP MANAGED — Do not modify directly.
|
|
10781
11016
|
`;
|
|
10782
|
-
await writeTextFile(this.paths.current, header +
|
|
11017
|
+
await writeTextFile(this.paths.current, header + import_yaml8.default.stringify(state));
|
|
10783
11018
|
}
|
|
10784
11019
|
async create(goal, type = "embryo") {
|
|
10785
11020
|
await ensureDir(this.paths.life);
|
|
@@ -10858,15 +11093,15 @@ init_fs();
|
|
|
10858
11093
|
|
|
10859
11094
|
// src/core/hooks.ts
|
|
10860
11095
|
init_fs();
|
|
10861
|
-
var
|
|
11096
|
+
var import_yaml9 = __toESM(require_dist(), 1);
|
|
10862
11097
|
import { readdir as readdir8 } from "fs/promises";
|
|
10863
|
-
import { join as
|
|
11098
|
+
import { join as join10 } from "path";
|
|
10864
11099
|
import { execSync as execSync4 } from "child_process";
|
|
10865
11100
|
async function executeHooks(hooksDir, event, projectRoot) {
|
|
10866
11101
|
const hooks = await scanHooks(hooksDir, event);
|
|
10867
11102
|
if (hooks.length === 0)
|
|
10868
11103
|
return [];
|
|
10869
|
-
const conditionsDir =
|
|
11104
|
+
const conditionsDir = join10(hooksDir, "conditions");
|
|
10870
11105
|
const results = [];
|
|
10871
11106
|
for (const hook of hooks) {
|
|
10872
11107
|
const conditionMet = await evaluateCondition(conditionsDir, hook.condition, projectRoot);
|
|
@@ -10901,7 +11136,7 @@ async function scanHooks(hooksDir, event) {
|
|
|
10901
11136
|
const match = filename.match(pattern);
|
|
10902
11137
|
if (!match)
|
|
10903
11138
|
continue;
|
|
10904
|
-
const meta = await parseHookMeta(
|
|
11139
|
+
const meta = await parseHookMeta(join10(hooksDir, filename), match[2]);
|
|
10905
11140
|
hooks.push({
|
|
10906
11141
|
filename,
|
|
10907
11142
|
name: match[1],
|
|
@@ -10922,7 +11157,7 @@ async function parseHookMeta(filePath, ext) {
|
|
|
10922
11157
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
10923
11158
|
if (fmMatch) {
|
|
10924
11159
|
try {
|
|
10925
|
-
const fm =
|
|
11160
|
+
const fm = import_yaml9.default.parse(fmMatch[1]) ?? {};
|
|
10926
11161
|
return {
|
|
10927
11162
|
condition: String(fm.condition ?? "always"),
|
|
10928
11163
|
order: Number(fm.order ?? 50)
|
|
@@ -10948,7 +11183,7 @@ async function parseHookMeta(filePath, ext) {
|
|
|
10948
11183
|
async function evaluateCondition(conditionsDir, conditionName, projectRoot) {
|
|
10949
11184
|
if (conditionName === "always")
|
|
10950
11185
|
return { met: true };
|
|
10951
|
-
const scriptPath =
|
|
11186
|
+
const scriptPath = join10(conditionsDir, `${conditionName}.sh`);
|
|
10952
11187
|
if (!await fileExists(scriptPath)) {
|
|
10953
11188
|
return { met: false, reason: `condition script not found: ${conditionName}.sh` };
|
|
10954
11189
|
}
|
|
@@ -10961,7 +11196,7 @@ async function evaluateCondition(conditionsDir, conditionName, projectRoot) {
|
|
|
10961
11196
|
}
|
|
10962
11197
|
async function executeShHook(hook, event, projectRoot, hooksDir) {
|
|
10963
11198
|
try {
|
|
10964
|
-
const stdout = execSync4(`bash "${
|
|
11199
|
+
const stdout = execSync4(`bash "${join10(hooksDir, hook.filename)}"`, {
|
|
10965
11200
|
cwd: projectRoot,
|
|
10966
11201
|
timeout: 60000,
|
|
10967
11202
|
stdio: "pipe"
|
|
@@ -10987,7 +11222,7 @@ async function executeShHook(hook, event, projectRoot, hooksDir) {
|
|
|
10987
11222
|
}
|
|
10988
11223
|
}
|
|
10989
11224
|
async function executeMdHook(hook, event, hooksDir) {
|
|
10990
|
-
const content = await readTextFile(
|
|
11225
|
+
const content = await readTextFile(join10(hooksDir, hook.filename));
|
|
10991
11226
|
const body = content?.replace(/^---\n[\s\S]*?\n---\n?/, "").trim() ?? "";
|
|
10992
11227
|
return {
|
|
10993
11228
|
name: hook.name,
|
|
@@ -11000,9 +11235,9 @@ async function executeMdHook(hook, event, hooksDir) {
|
|
|
11000
11235
|
|
|
11001
11236
|
// src/core/backlog.ts
|
|
11002
11237
|
init_fs();
|
|
11003
|
-
var
|
|
11238
|
+
var import_yaml10 = __toESM(require_dist(), 1);
|
|
11004
11239
|
import { readdir as readdir9 } from "fs/promises";
|
|
11005
|
-
import { join as
|
|
11240
|
+
import { join as join11 } from "path";
|
|
11006
11241
|
async function scanBacklog(backlogDir) {
|
|
11007
11242
|
let entries;
|
|
11008
11243
|
try {
|
|
@@ -11014,7 +11249,7 @@ async function scanBacklog(backlogDir) {
|
|
|
11014
11249
|
for (const entry of entries) {
|
|
11015
11250
|
if (!entry.endsWith(".md"))
|
|
11016
11251
|
continue;
|
|
11017
|
-
const filePath =
|
|
11252
|
+
const filePath = join11(backlogDir, entry);
|
|
11018
11253
|
const content = await readTextFile(filePath);
|
|
11019
11254
|
if (!content)
|
|
11020
11255
|
continue;
|
|
@@ -11045,7 +11280,7 @@ async function consumeBacklog(filePath, genId) {
|
|
|
11045
11280
|
const fmRaw = fmMatch[1];
|
|
11046
11281
|
let parsed = {};
|
|
11047
11282
|
try {
|
|
11048
|
-
parsed =
|
|
11283
|
+
parsed = import_yaml10.default.parse(fmRaw) ?? {};
|
|
11049
11284
|
} catch {
|
|
11050
11285
|
return { status: "warning", warning: `${filePath}: malformed YAML frontmatter — backlog not marked` };
|
|
11051
11286
|
}
|
|
@@ -11157,7 +11392,7 @@ ${body}
|
|
|
11157
11392
|
`;
|
|
11158
11393
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
11159
11394
|
await mkdir3(backlogDir, { recursive: true });
|
|
11160
|
-
await writeTextFile(
|
|
11395
|
+
await writeTextFile(join11(backlogDir, filename), content);
|
|
11161
11396
|
return filename;
|
|
11162
11397
|
}
|
|
11163
11398
|
async function createDeferredBacklog(backlogDir, input) {
|
|
@@ -11187,7 +11422,7 @@ ${tasksSection}
|
|
|
11187
11422
|
`;
|
|
11188
11423
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
11189
11424
|
await mkdir3(backlogDir, { recursive: true });
|
|
11190
|
-
await writeTextFile(
|
|
11425
|
+
await writeTextFile(join11(backlogDir, filename), content);
|
|
11191
11426
|
return filename;
|
|
11192
11427
|
}
|
|
11193
11428
|
function extractUncheckedTasks(artifactContent) {
|
|
@@ -11208,9 +11443,9 @@ function countCheckedTasks(artifactContent) {
|
|
|
11208
11443
|
|
|
11209
11444
|
// src/core/lineage.ts
|
|
11210
11445
|
init_fs();
|
|
11211
|
-
var
|
|
11446
|
+
var import_yaml11 = __toESM(require_dist(), 1);
|
|
11212
11447
|
import { readdir as readdir10, stat as stat3 } from "fs/promises";
|
|
11213
|
-
import { join as
|
|
11448
|
+
import { join as join12 } from "path";
|
|
11214
11449
|
import { execSync as execSync5 } from "child_process";
|
|
11215
11450
|
function gitShow(cwd, ref, path) {
|
|
11216
11451
|
try {
|
|
@@ -11271,7 +11506,7 @@ async function getLastLineageEntry(paths) {
|
|
|
11271
11506
|
if (genEntries.length === 0)
|
|
11272
11507
|
return null;
|
|
11273
11508
|
const last = genEntries[genEntries.length - 1];
|
|
11274
|
-
const lastPath =
|
|
11509
|
+
const lastPath = join12(paths.lineage, last);
|
|
11275
11510
|
try {
|
|
11276
11511
|
const st = await stat3(lastPath);
|
|
11277
11512
|
if (!st.isDirectory())
|
|
@@ -11279,12 +11514,12 @@ async function getLastLineageEntry(paths) {
|
|
|
11279
11514
|
} catch {
|
|
11280
11515
|
return null;
|
|
11281
11516
|
}
|
|
11282
|
-
const metaContent = await readTextFile(
|
|
11517
|
+
const metaContent = await readTextFile(join12(lastPath, "meta.yml"));
|
|
11283
11518
|
if (!metaContent)
|
|
11284
11519
|
return null;
|
|
11285
11520
|
let parsed;
|
|
11286
11521
|
try {
|
|
11287
|
-
parsed =
|
|
11522
|
+
parsed = import_yaml11.default.parse(metaContent) ?? {};
|
|
11288
11523
|
} catch {
|
|
11289
11524
|
return null;
|
|
11290
11525
|
}
|
|
@@ -11308,7 +11543,7 @@ async function getLastLineageEntry(paths) {
|
|
|
11308
11543
|
}
|
|
11309
11544
|
|
|
11310
11545
|
// src/cli/commands/run/start.ts
|
|
11311
|
-
async function
|
|
11546
|
+
async function execute8(phase, goal, type, parents, backlog) {
|
|
11312
11547
|
const paths = createPaths(process.cwd());
|
|
11313
11548
|
if (!await fileExists(paths.config)) {
|
|
11314
11549
|
emitError("start", "Not a reap project. Run 'reap init' first.");
|
|
@@ -11392,7 +11627,6 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11392
11627
|
`),
|
|
11393
11628
|
nextCommand: `reap run start --phase create --goal "${goal}" --backlog <filename>`
|
|
11394
11629
|
});
|
|
11395
|
-
return;
|
|
11396
11630
|
}
|
|
11397
11631
|
}
|
|
11398
11632
|
if (type === "merge") {
|
|
@@ -11423,7 +11657,7 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11423
11657
|
const state = await gm.create(goal, genType);
|
|
11424
11658
|
let consumeWarning;
|
|
11425
11659
|
if (backlogFilename) {
|
|
11426
|
-
const backlogPath =
|
|
11660
|
+
const backlogPath = join14(paths.backlog, backlogFilename);
|
|
11427
11661
|
if (await fileExists(backlogPath)) {
|
|
11428
11662
|
const result = await consumeBacklog(backlogPath, state.id);
|
|
11429
11663
|
if (result.status === "warning" && result.warning) {
|
|
@@ -11436,8 +11670,13 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11436
11670
|
}
|
|
11437
11671
|
}
|
|
11438
11672
|
await executeHooks(paths.hooks, "onLifeStarted", paths.root).catch(() => {});
|
|
11439
|
-
const
|
|
11440
|
-
|
|
11673
|
+
const configContent = await readTextFile(paths.config);
|
|
11674
|
+
const config = configContent ? import_yaml12.default.parse(configContent) : null;
|
|
11675
|
+
if (config?.daemon === true) {
|
|
11676
|
+
const { ensureRegistered: ensureRegistered2, triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
11677
|
+
await ensureRegistered2(paths.root, basename(paths.root));
|
|
11678
|
+
await triggerIndexing2(paths.root);
|
|
11679
|
+
}
|
|
11441
11680
|
const messageLines = [`Generation ${state.id} created. Run: reap run learning`];
|
|
11442
11681
|
if (consumeWarning) {
|
|
11443
11682
|
messageLines.unshift(`[backlog warning] ${consumeWarning}`);
|
|
@@ -11464,8 +11703,9 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11464
11703
|
|
|
11465
11704
|
// src/cli/commands/run/learning.ts
|
|
11466
11705
|
init_fs();
|
|
11706
|
+
var import_yaml13 = __toESM(require_dist(), 1);
|
|
11467
11707
|
import { readdir as readdir11 } from "fs/promises";
|
|
11468
|
-
import { join as
|
|
11708
|
+
import { basename as basename2, join as join16 } from "path";
|
|
11469
11709
|
|
|
11470
11710
|
// src/core/lifecycle.ts
|
|
11471
11711
|
init_types();
|
|
@@ -11648,8 +11888,8 @@ async function performMergeTransition(state, gm, paths) {
|
|
|
11648
11888
|
|
|
11649
11889
|
// src/core/template.ts
|
|
11650
11890
|
init_fs();
|
|
11651
|
-
import { join as
|
|
11652
|
-
import { fileURLToPath as
|
|
11891
|
+
import { join as join15, dirname as dirname7 } from "path";
|
|
11892
|
+
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
11653
11893
|
import { copyFile as copyFile2 } from "fs/promises";
|
|
11654
11894
|
var STAGE_ARTIFACTS2 = {
|
|
11655
11895
|
learning: "01-learning.md",
|
|
@@ -11675,16 +11915,16 @@ async function copyArtifactTemplate(stage, artifactPath, isMerge) {
|
|
|
11675
11915
|
if (await fileExists(destPath))
|
|
11676
11916
|
return;
|
|
11677
11917
|
const subdir = isMerge ? "merge" : "normal";
|
|
11678
|
-
const __dirname2 =
|
|
11679
|
-
const templatePath =
|
|
11918
|
+
const __dirname2 = dirname7(fileURLToPath6(import.meta.url));
|
|
11919
|
+
const templatePath = join15(__dirname2, "..", "templates", "artifacts", subdir, filename);
|
|
11680
11920
|
if (!await fileExists(templatePath))
|
|
11681
11921
|
return;
|
|
11682
|
-
await ensureDir(
|
|
11922
|
+
await ensureDir(dirname7(destPath));
|
|
11683
11923
|
await copyFile2(templatePath, destPath);
|
|
11684
11924
|
}
|
|
11685
11925
|
|
|
11686
11926
|
// src/cli/commands/run/learning.ts
|
|
11687
|
-
async function
|
|
11927
|
+
async function execute9(paths, phase) {
|
|
11688
11928
|
const gm = new GenerationManager(paths);
|
|
11689
11929
|
const state = await gm.current();
|
|
11690
11930
|
if (!state)
|
|
@@ -11701,7 +11941,7 @@ async function execute8(paths, phase) {
|
|
|
11701
11941
|
const envSummary = await readTextFile(paths.environmentSummary);
|
|
11702
11942
|
let sourceBacklogContent = null;
|
|
11703
11943
|
if (s.sourceBacklog) {
|
|
11704
|
-
sourceBacklogContent = await readTextFile(
|
|
11944
|
+
sourceBacklogContent = await readTextFile(join16(paths.backlog, s.sourceBacklog)) ?? await readTextFile(join16(paths.life, "backlog", s.sourceBacklog));
|
|
11705
11945
|
}
|
|
11706
11946
|
const backlogItems = await scanBacklog(paths.backlog);
|
|
11707
11947
|
const pendingBacklog = backlogItems.filter((b) => b.status === "pending");
|
|
@@ -11712,8 +11952,8 @@ async function execute8(paths, phase) {
|
|
|
11712
11952
|
const genDirs = lineageEntries.filter((e) => e.startsWith("gen-")).sort();
|
|
11713
11953
|
if (genDirs.length > 0) {
|
|
11714
11954
|
const lastGen = genDirs[genDirs.length - 1];
|
|
11715
|
-
prevCompletion = await readTextFile(
|
|
11716
|
-
const metaContent = await readTextFile(
|
|
11955
|
+
prevCompletion = await readTextFile(join16(paths.lineage, lastGen, "05-completion.md"));
|
|
11956
|
+
const metaContent = await readTextFile(join16(paths.lineage, lastGen, "meta.yml"));
|
|
11717
11957
|
if (metaContent) {
|
|
11718
11958
|
const fitnessMatch = metaContent.match(/fitnessFeedback:\n\s+text:\s*([\s\S]*?)(?:\n\s+evaluatedAt:|\n[a-z])/);
|
|
11719
11959
|
if (fitnessMatch)
|
|
@@ -11723,6 +11963,16 @@ async function execute8(paths, phase) {
|
|
|
11723
11963
|
} catch {}
|
|
11724
11964
|
setTransitionNonces(s, "learning:entry");
|
|
11725
11965
|
await gm.save(s);
|
|
11966
|
+
const configContent = await readTextFile(paths.config);
|
|
11967
|
+
const config = configContent ? import_yaml13.default.parse(configContent) : null;
|
|
11968
|
+
const daemonEnabled = config?.daemon === true;
|
|
11969
|
+
let daemonReady;
|
|
11970
|
+
if (daemonEnabled) {
|
|
11971
|
+
const { ensureRegistered: ensureRegistered2, triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
11972
|
+
const registered = await ensureRegistered2(paths.root, basename2(paths.root));
|
|
11973
|
+
const indexed = await triggerIndexing2(paths.root);
|
|
11974
|
+
daemonReady = registered && indexed;
|
|
11975
|
+
}
|
|
11726
11976
|
emitOutput({
|
|
11727
11977
|
status: "prompt",
|
|
11728
11978
|
command: "learning",
|
|
@@ -11740,7 +11990,9 @@ async function execute8(paths, phase) {
|
|
|
11740
11990
|
previousFitness: prevFitness,
|
|
11741
11991
|
artifactPath: paths.artifact("01-learning.md"),
|
|
11742
11992
|
sourceBacklog: s.sourceBacklog ? { filename: s.sourceBacklog, content: sourceBacklogContent?.slice(0, 2000) } : null,
|
|
11743
|
-
pendingBacklog: pendingBacklog.map((b) => ({ type: b.type, title: b.title, filename: b.filename }))
|
|
11993
|
+
pendingBacklog: pendingBacklog.map((b) => ({ type: b.type, title: b.title, filename: b.filename })),
|
|
11994
|
+
daemonEnabled,
|
|
11995
|
+
...daemonEnabled ? { daemonReady } : {}
|
|
11744
11996
|
},
|
|
11745
11997
|
prompt: [
|
|
11746
11998
|
"## Learning Stage — Explore and Build Context",
|
|
@@ -11798,7 +12050,7 @@ ${pendingBacklog.map((b) => `- [${b.type}] ${b.title} (\`${b.filename}\`)`).join
|
|
|
11798
12050
|
|
|
11799
12051
|
// src/cli/commands/run/planning.ts
|
|
11800
12052
|
init_fs();
|
|
11801
|
-
async function
|
|
12053
|
+
async function execute10(paths, phase) {
|
|
11802
12054
|
const gm = new GenerationManager(paths);
|
|
11803
12055
|
const state = await gm.current();
|
|
11804
12056
|
if (!state)
|
|
@@ -11889,8 +12141,9 @@ async function execute9(paths, phase) {
|
|
|
11889
12141
|
}
|
|
11890
12142
|
|
|
11891
12143
|
// src/cli/commands/run/implementation.ts
|
|
12144
|
+
var import_yaml14 = __toESM(require_dist(), 1);
|
|
11892
12145
|
init_fs();
|
|
11893
|
-
async function
|
|
12146
|
+
async function execute11(paths, phase) {
|
|
11894
12147
|
const gm = new GenerationManager(paths);
|
|
11895
12148
|
const state = await gm.current();
|
|
11896
12149
|
if (!state)
|
|
@@ -11963,6 +12216,12 @@ async function execute10(paths, phase) {
|
|
|
11963
12216
|
prepareStageEntry(s, "validation:entry");
|
|
11964
12217
|
await gm.save(s);
|
|
11965
12218
|
const next = await performTransition(s, gm, paths);
|
|
12219
|
+
const configContent = await readTextFile(paths.config);
|
|
12220
|
+
const config = configContent ? import_yaml14.default.parse(configContent) : null;
|
|
12221
|
+
if (config?.daemon === true) {
|
|
12222
|
+
const { triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
12223
|
+
await triggerIndexing2(paths.root);
|
|
12224
|
+
}
|
|
11966
12225
|
emitOutput({
|
|
11967
12226
|
status: "ok",
|
|
11968
12227
|
command: "implementation",
|
|
@@ -11976,7 +12235,7 @@ async function execute10(paths, phase) {
|
|
|
11976
12235
|
}
|
|
11977
12236
|
|
|
11978
12237
|
// src/cli/commands/run/validation.ts
|
|
11979
|
-
var
|
|
12238
|
+
var import_yaml15 = __toESM(require_dist(), 1);
|
|
11980
12239
|
init_fs();
|
|
11981
12240
|
|
|
11982
12241
|
// src/core/artifact-check.ts
|
|
@@ -12013,7 +12272,7 @@ function isUnfilled(content) {
|
|
|
12013
12272
|
}
|
|
12014
12273
|
|
|
12015
12274
|
// src/cli/commands/run/validation.ts
|
|
12016
|
-
async function
|
|
12275
|
+
async function execute12(paths, phase, extra) {
|
|
12017
12276
|
const gm = new GenerationManager(paths);
|
|
12018
12277
|
const state = await gm.current();
|
|
12019
12278
|
if (!state)
|
|
@@ -12148,7 +12407,7 @@ async function execute11(paths, phase, extra) {
|
|
|
12148
12407
|
"If fail: reap run back to regress"
|
|
12149
12408
|
];
|
|
12150
12409
|
const configContent = await readTextFile(paths.config);
|
|
12151
|
-
const config = configContent ?
|
|
12410
|
+
const config = configContent ? import_yaml15.default.parse(configContent) : null;
|
|
12152
12411
|
const evaluatorEnabled = config?.evaluator === true;
|
|
12153
12412
|
const context = {
|
|
12154
12413
|
id: s.id,
|
|
@@ -12229,15 +12488,15 @@ init_fs();
|
|
|
12229
12488
|
|
|
12230
12489
|
// src/core/archive.ts
|
|
12231
12490
|
init_fs();
|
|
12232
|
-
var
|
|
12233
|
-
import { join as
|
|
12491
|
+
var import_yaml17 = __toESM(require_dist(), 1);
|
|
12492
|
+
import { join as join18 } from "path";
|
|
12234
12493
|
import { readdir as readdir13, rm as rm4, unlink } from "fs/promises";
|
|
12235
12494
|
|
|
12236
12495
|
// src/core/compression.ts
|
|
12237
12496
|
init_fs();
|
|
12238
|
-
var
|
|
12497
|
+
var import_yaml16 = __toESM(require_dist(), 1);
|
|
12239
12498
|
import { readdir as readdir12, rm as rm3 } from "fs/promises";
|
|
12240
|
-
import { join as
|
|
12499
|
+
import { join as join17 } from "path";
|
|
12241
12500
|
var LEVEL1_THRESHOLD = 20;
|
|
12242
12501
|
var PROTECTED_RECENT = 20;
|
|
12243
12502
|
var LEVEL2_THRESHOLD = 100;
|
|
@@ -12254,7 +12513,7 @@ async function compressLineage(lineageDir) {
|
|
|
12254
12513
|
const { stat: stat4 } = await import("fs/promises");
|
|
12255
12514
|
const uncompressed = [];
|
|
12256
12515
|
for (const entry of genDirs) {
|
|
12257
|
-
const s = await stat4(
|
|
12516
|
+
const s = await stat4(join17(lineageDir, entry)).catch(() => null);
|
|
12258
12517
|
if (s?.isDirectory())
|
|
12259
12518
|
uncompressed.push(entry);
|
|
12260
12519
|
}
|
|
@@ -12263,15 +12522,15 @@ async function compressLineage(lineageDir) {
|
|
|
12263
12522
|
return 0;
|
|
12264
12523
|
let compressed = 0;
|
|
12265
12524
|
for (const dirName of toCompress) {
|
|
12266
|
-
const dirPath =
|
|
12267
|
-
const metaContent = await readTextFile(
|
|
12525
|
+
const dirPath = join17(lineageDir, dirName);
|
|
12526
|
+
const metaContent = await readTextFile(join17(dirPath, "meta.yml"));
|
|
12268
12527
|
let meta = { id: dirName, type: "unknown", goal: "", parents: [] };
|
|
12269
12528
|
if (metaContent) {
|
|
12270
12529
|
try {
|
|
12271
|
-
meta =
|
|
12530
|
+
meta = import_yaml16.default.parse(metaContent);
|
|
12272
12531
|
} catch {}
|
|
12273
12532
|
}
|
|
12274
|
-
const completion = await readTextFile(
|
|
12533
|
+
const completion = await readTextFile(join17(dirPath, "05-completion.md")) ?? "";
|
|
12275
12534
|
const summarySection = completion.match(/## Summary\n([\s\S]*?)(?=\n## |\n$)/)?.[1]?.trim() ?? "";
|
|
12276
12535
|
const compressedContent = [
|
|
12277
12536
|
"---",
|
|
@@ -12288,7 +12547,7 @@ async function compressLineage(lineageDir) {
|
|
|
12288
12547
|
""
|
|
12289
12548
|
].filter(Boolean).join(`
|
|
12290
12549
|
`);
|
|
12291
|
-
await writeTextFile(
|
|
12550
|
+
await writeTextFile(join17(lineageDir, `${dirName}.md`), compressedContent);
|
|
12292
12551
|
await rm3(dirPath, { recursive: true, force: true });
|
|
12293
12552
|
compressed++;
|
|
12294
12553
|
}
|
|
@@ -12307,7 +12566,7 @@ async function compressToEpoch(lineageDir) {
|
|
|
12307
12566
|
for (const entry of entries) {
|
|
12308
12567
|
if (!entry.startsWith("gen-") || !entry.endsWith(".md"))
|
|
12309
12568
|
continue;
|
|
12310
|
-
const s = await stat4(
|
|
12569
|
+
const s = await stat4(join17(lineageDir, entry)).catch(() => null);
|
|
12311
12570
|
if (s?.isFile())
|
|
12312
12571
|
level1Files.push(entry);
|
|
12313
12572
|
}
|
|
@@ -12316,14 +12575,14 @@ async function compressToEpoch(lineageDir) {
|
|
|
12316
12575
|
const allParents = new Set;
|
|
12317
12576
|
const fileMetas = [];
|
|
12318
12577
|
for (const file of level1Files.sort()) {
|
|
12319
|
-
const content = await readTextFile(
|
|
12578
|
+
const content = await readTextFile(join17(lineageDir, file));
|
|
12320
12579
|
if (!content)
|
|
12321
12580
|
continue;
|
|
12322
12581
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
12323
12582
|
let meta = { id: file.replace(".md", ""), type: "unknown", goal: "", parents: [] };
|
|
12324
12583
|
if (fmMatch) {
|
|
12325
12584
|
try {
|
|
12326
|
-
const parsed =
|
|
12585
|
+
const parsed = import_yaml16.default.parse(fmMatch[1]);
|
|
12327
12586
|
meta = { ...meta, ...parsed };
|
|
12328
12587
|
} catch {}
|
|
12329
12588
|
}
|
|
@@ -12336,24 +12595,24 @@ async function compressToEpoch(lineageDir) {
|
|
|
12336
12595
|
const dirEntries = entries.filter((e) => e.startsWith("gen-") && !e.endsWith(".md"));
|
|
12337
12596
|
const dirParents = new Set;
|
|
12338
12597
|
for (const dir of dirEntries) {
|
|
12339
|
-
const metaContent = await readTextFile(
|
|
12598
|
+
const metaContent = await readTextFile(join17(lineageDir, dir, "meta.yml"));
|
|
12340
12599
|
if (!metaContent)
|
|
12341
12600
|
continue;
|
|
12342
12601
|
try {
|
|
12343
|
-
const m =
|
|
12602
|
+
const m = import_yaml16.default.parse(metaContent);
|
|
12344
12603
|
if (m.parents)
|
|
12345
12604
|
m.parents.forEach((p) => dirParents.add(p));
|
|
12346
12605
|
} catch {}
|
|
12347
12606
|
}
|
|
12348
12607
|
const epochFiles = entries.filter((e) => e.startsWith("epoch-") && e.endsWith(".md"));
|
|
12349
12608
|
for (const ef of epochFiles) {
|
|
12350
|
-
const content = await readTextFile(
|
|
12609
|
+
const content = await readTextFile(join17(lineageDir, ef));
|
|
12351
12610
|
if (!content)
|
|
12352
12611
|
continue;
|
|
12353
12612
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
12354
12613
|
if (fmMatch) {
|
|
12355
12614
|
try {
|
|
12356
|
-
const parsed =
|
|
12615
|
+
const parsed = import_yaml16.default.parse(fmMatch[1]);
|
|
12357
12616
|
const lastId = parsed.lastGeneration;
|
|
12358
12617
|
if (lastId)
|
|
12359
12618
|
dirParents.add(lastId);
|
|
@@ -12391,9 +12650,9 @@ async function compressToEpoch(lineageDir) {
|
|
|
12391
12650
|
""
|
|
12392
12651
|
].join(`
|
|
12393
12652
|
`);
|
|
12394
|
-
await writeTextFile(
|
|
12653
|
+
await writeTextFile(join17(lineageDir, epochName), epochContent);
|
|
12395
12654
|
for (const f of compressible) {
|
|
12396
|
-
await rm3(
|
|
12655
|
+
await rm3(join17(lineageDir, f.filename), { force: true });
|
|
12397
12656
|
}
|
|
12398
12657
|
return compressible.length;
|
|
12399
12658
|
}
|
|
@@ -12401,7 +12660,7 @@ async function compressToEpoch(lineageDir) {
|
|
|
12401
12660
|
// src/core/archive.ts
|
|
12402
12661
|
function buildArchiveDir(lineageRoot, state) {
|
|
12403
12662
|
const goalSlug = state.goal.toLowerCase().replace(/[^a-z0-9가-힣]+/g, "-").slice(0, 40).replace(/-+$/, "");
|
|
12404
|
-
return
|
|
12663
|
+
return join18(lineageRoot, `${state.id}-${goalSlug}`);
|
|
12405
12664
|
}
|
|
12406
12665
|
async function writeArchive(paths, state, archiveDir, extraMeta) {
|
|
12407
12666
|
await ensureDir(archiveDir);
|
|
@@ -12409,20 +12668,20 @@ async function writeArchive(paths, state, archiveDir, extraMeta) {
|
|
|
12409
12668
|
for (const entry of lifeEntries) {
|
|
12410
12669
|
if (entry === "current.yml" || entry === "backlog")
|
|
12411
12670
|
continue;
|
|
12412
|
-
const src =
|
|
12413
|
-
const dest =
|
|
12671
|
+
const src = join18(paths.life, entry);
|
|
12672
|
+
const dest = join18(archiveDir, entry);
|
|
12414
12673
|
const { cp: cp2 } = await import("fs/promises");
|
|
12415
12674
|
await cp2(src, dest, { recursive: true });
|
|
12416
12675
|
}
|
|
12417
12676
|
const backlogItems = await scanBacklog(paths.backlog);
|
|
12418
12677
|
const consumedItems = backlogItems.filter((b) => b.status === "consumed");
|
|
12419
12678
|
if (consumedItems.length > 0) {
|
|
12420
|
-
const archiveBacklogDir =
|
|
12679
|
+
const archiveBacklogDir = join18(archiveDir, "backlog");
|
|
12421
12680
|
await ensureDir(archiveBacklogDir);
|
|
12422
12681
|
for (const item of consumedItems) {
|
|
12423
12682
|
const content = await readTextFile(item.path);
|
|
12424
12683
|
if (content) {
|
|
12425
|
-
await writeTextFile(
|
|
12684
|
+
await writeTextFile(join18(archiveBacklogDir, item.filename), content);
|
|
12426
12685
|
}
|
|
12427
12686
|
await unlink(item.path).catch(() => {});
|
|
12428
12687
|
}
|
|
@@ -12435,11 +12694,11 @@ async function writeArchive(paths, state, archiveDir, extraMeta) {
|
|
|
12435
12694
|
timeline: state.timeline,
|
|
12436
12695
|
...extraMeta
|
|
12437
12696
|
};
|
|
12438
|
-
await writeTextFile(
|
|
12697
|
+
await writeTextFile(join18(archiveDir, "meta.yml"), import_yaml17.default.stringify(meta));
|
|
12439
12698
|
for (const entry of lifeEntries) {
|
|
12440
12699
|
if (entry === "backlog")
|
|
12441
12700
|
continue;
|
|
12442
|
-
await rm4(
|
|
12701
|
+
await rm4(join18(paths.life, entry), { recursive: true, force: true });
|
|
12443
12702
|
}
|
|
12444
12703
|
await compressLineage(paths.lineage).catch(() => {});
|
|
12445
12704
|
}
|
|
@@ -12760,7 +13019,7 @@ function tokenize(text) {
|
|
|
12760
13019
|
|
|
12761
13020
|
// src/core/cruise.ts
|
|
12762
13021
|
init_fs();
|
|
12763
|
-
var
|
|
13022
|
+
var import_yaml18 = __toESM(require_dist(), 1);
|
|
12764
13023
|
function parseCruiseCount(config) {
|
|
12765
13024
|
if (!config.cruiseCount)
|
|
12766
13025
|
return null;
|
|
@@ -12773,39 +13032,39 @@ async function advanceCruise(configPath) {
|
|
|
12773
13032
|
const content = await readTextFile(configPath);
|
|
12774
13033
|
if (!content)
|
|
12775
13034
|
return false;
|
|
12776
|
-
const config =
|
|
13035
|
+
const config = import_yaml18.default.parse(content);
|
|
12777
13036
|
const cruise = parseCruiseCount(config);
|
|
12778
13037
|
if (!cruise)
|
|
12779
13038
|
return false;
|
|
12780
13039
|
if (cruise.current >= cruise.total) {
|
|
12781
13040
|
delete config.cruiseCount;
|
|
12782
|
-
await writeTextFile(configPath,
|
|
13041
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12783
13042
|
return false;
|
|
12784
13043
|
}
|
|
12785
13044
|
config.cruiseCount = `${cruise.current + 1}/${cruise.total}`;
|
|
12786
|
-
await writeTextFile(configPath,
|
|
13045
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12787
13046
|
return true;
|
|
12788
13047
|
}
|
|
12789
13048
|
async function clearCruise(configPath) {
|
|
12790
13049
|
const content = await readTextFile(configPath);
|
|
12791
13050
|
if (!content)
|
|
12792
13051
|
return;
|
|
12793
|
-
const config =
|
|
13052
|
+
const config = import_yaml18.default.parse(content);
|
|
12794
13053
|
delete config.cruiseCount;
|
|
12795
|
-
await writeTextFile(configPath,
|
|
13054
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12796
13055
|
}
|
|
12797
13056
|
async function setCruise(configPath, total) {
|
|
12798
13057
|
const content = await readTextFile(configPath);
|
|
12799
13058
|
if (!content)
|
|
12800
13059
|
return;
|
|
12801
|
-
const config =
|
|
13060
|
+
const config = import_yaml18.default.parse(content);
|
|
12802
13061
|
config.cruiseCount = `1/${total}`;
|
|
12803
|
-
await writeTextFile(configPath,
|
|
13062
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12804
13063
|
}
|
|
12805
13064
|
|
|
12806
13065
|
// src/cli/commands/run/completion.ts
|
|
12807
|
-
var
|
|
12808
|
-
async function
|
|
13066
|
+
var import_yaml19 = __toESM(require_dist(), 1);
|
|
13067
|
+
async function execute13(paths, phase, feedback) {
|
|
12809
13068
|
const gm = new GenerationManager(paths);
|
|
12810
13069
|
const state = await gm.current();
|
|
12811
13070
|
if (!state)
|
|
@@ -12893,7 +13152,7 @@ async function execute12(paths, phase, feedback) {
|
|
|
12893
13152
|
} else {
|
|
12894
13153
|
verifyTransition("completion", s, "completion:fitness");
|
|
12895
13154
|
const configContent = await readTextFile(paths.config);
|
|
12896
|
-
const config = configContent ?
|
|
13155
|
+
const config = configContent ? import_yaml19.default.parse(configContent) : null;
|
|
12897
13156
|
const cruise = config ? parseCruiseCount(config) : null;
|
|
12898
13157
|
const evaluatorEnabled = config?.evaluator === true;
|
|
12899
13158
|
setTransitionNonces(s, "completion:fitness");
|
|
@@ -12969,7 +13228,6 @@ async function execute12(paths, phase, feedback) {
|
|
|
12969
13228
|
`),
|
|
12970
13229
|
nextCommand: "reap run completion --phase fitness"
|
|
12971
13230
|
});
|
|
12972
|
-
return;
|
|
12973
13231
|
}
|
|
12974
13232
|
if (cruise) {
|
|
12975
13233
|
const cruisePrompt = [
|
|
@@ -13043,7 +13301,7 @@ async function execute12(paths, phase, feedback) {
|
|
|
13043
13301
|
const fitnessFeedback = s.fitnessFeedback;
|
|
13044
13302
|
const visionGoals = await readTextFile(paths.visionGoals);
|
|
13045
13303
|
const configContent = await readTextFile(paths.config);
|
|
13046
|
-
const config = configContent ?
|
|
13304
|
+
const config = configContent ? import_yaml19.default.parse(configContent) : null;
|
|
13047
13305
|
const maturity = detectMaturity(s.type, config?.cruiseCount);
|
|
13048
13306
|
const generationCount = await gm.countLineage();
|
|
13049
13307
|
setTransitionNonces(s, "completion:adapt");
|
|
@@ -13137,9 +13395,9 @@ async function execute12(paths, phase, feedback) {
|
|
|
13137
13395
|
verifyTransition("completion", s, "completion:commit");
|
|
13138
13396
|
if (feedback) {
|
|
13139
13397
|
const filenames = feedback.split(",").map((f) => f.trim()).filter(Boolean);
|
|
13140
|
-
const { join:
|
|
13398
|
+
const { join: join19 } = await import("path");
|
|
13141
13399
|
for (const filename of filenames) {
|
|
13142
|
-
await consumeBacklog(
|
|
13400
|
+
await consumeBacklog(join19(paths.backlog, filename), s.id);
|
|
13143
13401
|
}
|
|
13144
13402
|
}
|
|
13145
13403
|
const fitnessFeedback = s.fitnessFeedback;
|
|
@@ -13155,8 +13413,12 @@ async function execute12(paths, phase, feedback) {
|
|
|
13155
13413
|
const commitHash = gitCommitAll(paths.root, commitMsg);
|
|
13156
13414
|
const completionEvent = isMerge ? "onMergeCompleted" : "onLifeCompleted";
|
|
13157
13415
|
await executeHooks(paths.hooks, completionEvent, paths.root).catch(() => {});
|
|
13158
|
-
const
|
|
13159
|
-
|
|
13416
|
+
const completionConfigContent = await readTextFile(paths.config);
|
|
13417
|
+
const completionConfig = completionConfigContent ? import_yaml19.default.parse(completionConfigContent) : null;
|
|
13418
|
+
if (completionConfig?.daemon === true) {
|
|
13419
|
+
const { triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
13420
|
+
await triggerIndexing2(paths.root);
|
|
13421
|
+
}
|
|
13160
13422
|
const cruiseStillActive = await advanceCruise(paths.config).catch(() => false);
|
|
13161
13423
|
emitOutput({
|
|
13162
13424
|
status: "ok",
|
|
@@ -13176,7 +13438,7 @@ async function execute12(paths, phase, feedback) {
|
|
|
13176
13438
|
}
|
|
13177
13439
|
|
|
13178
13440
|
// src/cli/commands/run/evolve.ts
|
|
13179
|
-
var
|
|
13441
|
+
var import_yaml20 = __toESM(require_dist(), 1);
|
|
13180
13442
|
import { readdir as readdir14 } from "fs/promises";
|
|
13181
13443
|
init_fs();
|
|
13182
13444
|
async function collectClarityInput(paths, generationType) {
|
|
@@ -13209,11 +13471,11 @@ async function collectClarityInput(paths, generationType) {
|
|
|
13209
13471
|
hasMemory
|
|
13210
13472
|
};
|
|
13211
13473
|
}
|
|
13212
|
-
async function
|
|
13474
|
+
async function execute14(paths, _phase) {
|
|
13213
13475
|
const gm = new GenerationManager(paths);
|
|
13214
13476
|
const state = await gm.current();
|
|
13215
13477
|
const configContent = await readTextFile(paths.config);
|
|
13216
|
-
const config = configContent ?
|
|
13478
|
+
const config = configContent ? import_yaml20.default.parse(configContent) : null;
|
|
13217
13479
|
const autoSubagent = config?.autoSubagent ?? true;
|
|
13218
13480
|
const cruise = config ? parseCruiseCount(config) : null;
|
|
13219
13481
|
const generationType = state?.type ?? "normal";
|
|
@@ -13292,7 +13554,7 @@ async function execute13(paths, _phase) {
|
|
|
13292
13554
|
}
|
|
13293
13555
|
|
|
13294
13556
|
// src/cli/commands/run/back.ts
|
|
13295
|
-
async function
|
|
13557
|
+
async function execute15(paths, _phase, reason) {
|
|
13296
13558
|
const gm = new GenerationManager(paths);
|
|
13297
13559
|
const state = await gm.current();
|
|
13298
13560
|
if (!state)
|
|
@@ -13339,7 +13601,7 @@ async function execute14(paths, _phase, reason) {
|
|
|
13339
13601
|
}
|
|
13340
13602
|
|
|
13341
13603
|
// src/cli/commands/run/next.ts
|
|
13342
|
-
async function
|
|
13604
|
+
async function execute16(paths) {
|
|
13343
13605
|
const gm = new GenerationManager(paths);
|
|
13344
13606
|
const state = await gm.current();
|
|
13345
13607
|
if (!state)
|
|
@@ -13361,7 +13623,7 @@ async function execute15(paths) {
|
|
|
13361
13623
|
|
|
13362
13624
|
// src/cli/commands/run/abort.ts
|
|
13363
13625
|
import { readdir as readdir15, rm as rm5 } from "fs/promises";
|
|
13364
|
-
import { join as
|
|
13626
|
+
import { join as join19 } from "path";
|
|
13365
13627
|
init_fs();
|
|
13366
13628
|
function parseExtra(extra) {
|
|
13367
13629
|
if (!extra)
|
|
@@ -13372,7 +13634,7 @@ function parseExtra(extra) {
|
|
|
13372
13634
|
return {};
|
|
13373
13635
|
}
|
|
13374
13636
|
}
|
|
13375
|
-
async function
|
|
13637
|
+
async function execute17(paths, phase, extra) {
|
|
13376
13638
|
const gm = new GenerationManager(paths);
|
|
13377
13639
|
const state = await gm.current();
|
|
13378
13640
|
if (!state)
|
|
@@ -13437,7 +13699,7 @@ createdAt: ${new Date().toISOString()}
|
|
|
13437
13699
|
## Progress
|
|
13438
13700
|
<!-- Progress from the aborted generation can be referenced here -->
|
|
13439
13701
|
`;
|
|
13440
|
-
await writeTextFile(
|
|
13702
|
+
await writeTextFile(join19(paths.backlog, filename), content);
|
|
13441
13703
|
savedBacklogFile = filename;
|
|
13442
13704
|
}
|
|
13443
13705
|
const revertedCount = await revertBacklogConsumed(paths.backlog, id);
|
|
@@ -13445,7 +13707,7 @@ createdAt: ${new Date().toISOString()}
|
|
|
13445
13707
|
for (const entry of lifeEntries) {
|
|
13446
13708
|
if (entry === "backlog")
|
|
13447
13709
|
continue;
|
|
13448
|
-
await rm5(
|
|
13710
|
+
await rm5(join19(paths.life, entry), { recursive: true, force: true });
|
|
13449
13711
|
}
|
|
13450
13712
|
emitOutput({
|
|
13451
13713
|
status: "ok",
|
|
@@ -13466,7 +13728,7 @@ createdAt: ${new Date().toISOString()}
|
|
|
13466
13728
|
}
|
|
13467
13729
|
|
|
13468
13730
|
// src/cli/commands/run/early-close.ts
|
|
13469
|
-
import { join as
|
|
13731
|
+
import { join as join20 } from "path";
|
|
13470
13732
|
init_fs();
|
|
13471
13733
|
function parseExtra2(extra) {
|
|
13472
13734
|
if (!extra)
|
|
@@ -13479,7 +13741,7 @@ function parseExtra2(extra) {
|
|
|
13479
13741
|
}
|
|
13480
13742
|
var ALLOWED_STAGES = new Set(["implementation", "validation"]);
|
|
13481
13743
|
var ALLOWED_SOURCE_ACTIONS = new Set(["hold", "stash", "none"]);
|
|
13482
|
-
async function
|
|
13744
|
+
async function execute18(paths, phase, extra) {
|
|
13483
13745
|
const gm = new GenerationManager(paths);
|
|
13484
13746
|
const state = await gm.current();
|
|
13485
13747
|
if (!state)
|
|
@@ -13605,7 +13867,7 @@ async function execute17(paths, phase, extra) {
|
|
|
13605
13867
|
message: [
|
|
13606
13868
|
`Generation ${s.id} early-closed at stage '${s.stage}' (reason: ${reason}).`,
|
|
13607
13869
|
`Archived: ${archiveDir}`,
|
|
13608
|
-
deferredBacklogFile ? `Deferred backlog: ${
|
|
13870
|
+
deferredBacklogFile ? `Deferred backlog: ${join20(paths.backlog, deferredBacklogFile)} (${deferredTaskCount} task(s))` : `Defer skipped — ${deferredTaskCount} unchecked task(s) found but not carried over.`,
|
|
13609
13871
|
commitHash ? `Commit: ${commitHash}` : "Commit your changes manually."
|
|
13610
13872
|
].join(" ")
|
|
13611
13873
|
});
|
|
@@ -13614,7 +13876,7 @@ async function execute17(paths, phase, extra) {
|
|
|
13614
13876
|
}
|
|
13615
13877
|
|
|
13616
13878
|
// src/cli/commands/run/detect.ts
|
|
13617
|
-
async function
|
|
13879
|
+
async function execute19(paths, phase) {
|
|
13618
13880
|
const gm = new GenerationManager(paths);
|
|
13619
13881
|
const state = await gm.current();
|
|
13620
13882
|
if (!state)
|
|
@@ -13700,7 +13962,7 @@ async function execute18(paths, phase) {
|
|
|
13700
13962
|
|
|
13701
13963
|
// src/cli/commands/run/mate.ts
|
|
13702
13964
|
init_fs();
|
|
13703
|
-
async function
|
|
13965
|
+
async function execute20(paths, phase) {
|
|
13704
13966
|
const gm = new GenerationManager(paths);
|
|
13705
13967
|
const state = await gm.current();
|
|
13706
13968
|
if (!state)
|
|
@@ -13798,7 +14060,7 @@ async function execute19(paths, phase) {
|
|
|
13798
14060
|
|
|
13799
14061
|
// src/cli/commands/run/merge.ts
|
|
13800
14062
|
init_fs();
|
|
13801
|
-
async function
|
|
14063
|
+
async function execute21(paths, phase) {
|
|
13802
14064
|
const gm = new GenerationManager(paths);
|
|
13803
14065
|
const state = await gm.current();
|
|
13804
14066
|
if (!state)
|
|
@@ -13871,7 +14133,7 @@ async function execute20(paths, phase) {
|
|
|
13871
14133
|
|
|
13872
14134
|
// src/cli/commands/run/reconcile.ts
|
|
13873
14135
|
init_fs();
|
|
13874
|
-
async function
|
|
14136
|
+
async function execute22(paths, phase) {
|
|
13875
14137
|
const gm = new GenerationManager(paths);
|
|
13876
14138
|
const state = await gm.current();
|
|
13877
14139
|
if (!state)
|
|
@@ -13955,7 +14217,7 @@ async function execute21(paths, phase) {
|
|
|
13955
14217
|
}
|
|
13956
14218
|
|
|
13957
14219
|
// src/cli/commands/run/push.ts
|
|
13958
|
-
async function
|
|
14220
|
+
async function execute23(paths) {
|
|
13959
14221
|
const gm = new GenerationManager(paths);
|
|
13960
14222
|
const state = await gm.current();
|
|
13961
14223
|
if (state) {
|
|
@@ -13989,7 +14251,7 @@ async function execute22(paths) {
|
|
|
13989
14251
|
}
|
|
13990
14252
|
|
|
13991
14253
|
// src/cli/commands/run/pull.ts
|
|
13992
|
-
async function
|
|
14254
|
+
async function execute24(paths, phase) {
|
|
13993
14255
|
if (!isGitRepo(paths.root)) {
|
|
13994
14256
|
emitError("pull", "Not a git repository.");
|
|
13995
14257
|
}
|
|
@@ -14142,7 +14404,7 @@ Consider using /reap.merge to start a merge lifecycle if needed.` : "No unmerged
|
|
|
14142
14404
|
}
|
|
14143
14405
|
|
|
14144
14406
|
// src/cli/commands/run/knowledge.ts
|
|
14145
|
-
async function
|
|
14407
|
+
async function execute25(paths, _phase, extra) {
|
|
14146
14408
|
const subcommand = extra ?? "";
|
|
14147
14409
|
if (subcommand === "reload") {
|
|
14148
14410
|
emitOutput({
|
|
@@ -14289,19 +14551,19 @@ async function execute24(paths, _phase, extra) {
|
|
|
14289
14551
|
|
|
14290
14552
|
// src/cli/commands/run/report.ts
|
|
14291
14553
|
init_fs();
|
|
14292
|
-
var
|
|
14293
|
-
async function
|
|
14554
|
+
var import_yaml21 = __toESM(require_dist(), 1);
|
|
14555
|
+
async function execute26(paths, _phase) {
|
|
14294
14556
|
let state = null;
|
|
14295
14557
|
try {
|
|
14296
14558
|
const raw = await readTextFile(paths.current);
|
|
14297
14559
|
if (raw)
|
|
14298
|
-
state =
|
|
14560
|
+
state = import_yaml21.default.parse(raw);
|
|
14299
14561
|
} catch {}
|
|
14300
14562
|
let projectName = "unknown";
|
|
14301
14563
|
try {
|
|
14302
14564
|
const raw = await readTextFile(paths.config);
|
|
14303
14565
|
if (raw) {
|
|
14304
|
-
const config =
|
|
14566
|
+
const config = import_yaml21.default.parse(raw);
|
|
14305
14567
|
projectName = config.project ?? "unknown";
|
|
14306
14568
|
}
|
|
14307
14569
|
} catch {}
|
|
@@ -14356,28 +14618,28 @@ async function execute25(paths, _phase) {
|
|
|
14356
14618
|
|
|
14357
14619
|
// src/cli/commands/run/index.ts
|
|
14358
14620
|
var STAGE_HANDLERS = {
|
|
14359
|
-
learning:
|
|
14360
|
-
planning:
|
|
14361
|
-
implementation:
|
|
14362
|
-
validation:
|
|
14363
|
-
completion:
|
|
14364
|
-
evolve:
|
|
14365
|
-
back:
|
|
14366
|
-
next:
|
|
14367
|
-
abort:
|
|
14368
|
-
"early-close":
|
|
14369
|
-
detect:
|
|
14370
|
-
mate:
|
|
14371
|
-
merge:
|
|
14372
|
-
reconcile:
|
|
14373
|
-
push:
|
|
14374
|
-
pull:
|
|
14375
|
-
knowledge:
|
|
14376
|
-
report:
|
|
14621
|
+
learning: execute9,
|
|
14622
|
+
planning: execute10,
|
|
14623
|
+
implementation: execute11,
|
|
14624
|
+
validation: execute12,
|
|
14625
|
+
completion: execute13,
|
|
14626
|
+
evolve: execute14,
|
|
14627
|
+
back: execute15,
|
|
14628
|
+
next: execute16,
|
|
14629
|
+
abort: execute17,
|
|
14630
|
+
"early-close": execute18,
|
|
14631
|
+
detect: execute19,
|
|
14632
|
+
mate: execute20,
|
|
14633
|
+
merge: execute21,
|
|
14634
|
+
reconcile: execute22,
|
|
14635
|
+
push: execute23,
|
|
14636
|
+
pull: execute24,
|
|
14637
|
+
knowledge: execute25,
|
|
14638
|
+
report: execute26
|
|
14377
14639
|
};
|
|
14378
|
-
async function
|
|
14640
|
+
async function execute27(stage, options) {
|
|
14379
14641
|
if (stage === "start") {
|
|
14380
|
-
await
|
|
14642
|
+
await execute8(options.phase, options.goal, options.type, options.parents, options.backlog);
|
|
14381
14643
|
return;
|
|
14382
14644
|
}
|
|
14383
14645
|
const paths = createPaths(process.cwd());
|
|
@@ -14407,7 +14669,7 @@ async function execute26(stage, options) {
|
|
|
14407
14669
|
try {
|
|
14408
14670
|
const configContent = await readTextFile(paths.config);
|
|
14409
14671
|
if (configContent) {
|
|
14410
|
-
const config =
|
|
14672
|
+
const config = import_yaml22.default.parse(configContent);
|
|
14411
14673
|
if (config.autoIssueReport !== false) {
|
|
14412
14674
|
const cmd = `reap run ${stage}${options.phase ? ` --phase ${options.phase}` : ""}`;
|
|
14413
14675
|
autoReport(cmd, err);
|
|
@@ -14442,7 +14704,7 @@ async function makeBacklog(paths, options) {
|
|
|
14442
14704
|
}
|
|
14443
14705
|
|
|
14444
14706
|
// src/cli/commands/make/hook.ts
|
|
14445
|
-
import { join as
|
|
14707
|
+
import { join as join21 } from "path";
|
|
14446
14708
|
import { chmod as chmod2 } from "fs/promises";
|
|
14447
14709
|
init_fs();
|
|
14448
14710
|
var VALID_EVENTS = [
|
|
@@ -14480,7 +14742,7 @@ ${VALID_EVENTS.join(`
|
|
|
14480
14742
|
emitError("make", "Invalid --type. Use 'sh' or 'md'.");
|
|
14481
14743
|
}
|
|
14482
14744
|
const filename = `${event}.${name}.${type}`;
|
|
14483
|
-
const filePath =
|
|
14745
|
+
const filePath = join21(paths.hooks, filename);
|
|
14484
14746
|
await ensureDir(paths.hooks);
|
|
14485
14747
|
if (await fileExists(filePath)) {
|
|
14486
14748
|
emitError("make", `Hook already exists: ${filename}`);
|
|
@@ -14515,7 +14777,7 @@ order: ${order}
|
|
|
14515
14777
|
|
|
14516
14778
|
// src/cli/commands/make/index.ts
|
|
14517
14779
|
var RESOURCES = ["backlog", "hook"];
|
|
14518
|
-
async function
|
|
14780
|
+
async function execute28(resource, options) {
|
|
14519
14781
|
const paths = createPaths(process.cwd());
|
|
14520
14782
|
if (await detectV15(paths)) {
|
|
14521
14783
|
emitError("make", "This project uses REAP v0.15 structure. Run '/reap.update' to upgrade to v0.16.");
|
|
@@ -14531,7 +14793,7 @@ async function execute27(resource, options) {
|
|
|
14531
14793
|
|
|
14532
14794
|
// src/cli/commands/cruise.ts
|
|
14533
14795
|
init_integrity();
|
|
14534
|
-
async function
|
|
14796
|
+
async function execute29(count) {
|
|
14535
14797
|
const n = parseInt(count);
|
|
14536
14798
|
if (isNaN(n) || n < 1) {
|
|
14537
14799
|
emitError("cruise", "Count must be a positive integer.");
|
|
@@ -14550,34 +14812,34 @@ async function execute28(count) {
|
|
|
14550
14812
|
}
|
|
14551
14813
|
|
|
14552
14814
|
// src/cli/commands/install-skills.ts
|
|
14553
|
-
var
|
|
14815
|
+
var import_yaml23 = __toESM(require_dist(), 1);
|
|
14554
14816
|
|
|
14555
14817
|
// src/adapters/claude-code/install.ts
|
|
14556
14818
|
init_fs();
|
|
14557
14819
|
import { readdir as readdir16, cp as cp2, unlink as unlink2, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
14558
|
-
import { join as
|
|
14559
|
-
import { fileURLToPath as
|
|
14820
|
+
import { join as join22, dirname as dirname8 } from "path";
|
|
14821
|
+
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
14560
14822
|
import { homedir as homedir4 } from "os";
|
|
14561
|
-
var __dirname2 =
|
|
14562
|
-
var SKILLS_DIR = __dirname2.includes("dist") ?
|
|
14823
|
+
var __dirname2 = dirname8(fileURLToPath7(import.meta.url));
|
|
14824
|
+
var SKILLS_DIR = __dirname2.includes("dist") ? join22(__dirname2, "..", "adapters", "claude-code", "skills") : join22(__dirname2, "skills");
|
|
14563
14825
|
var SKILL_PATTERN = /^reap\..+\.md$/;
|
|
14564
14826
|
async function cleanupStaleSkills(targetDir) {
|
|
14565
14827
|
const files = await readdir16(targetDir);
|
|
14566
14828
|
const staleFiles = files.filter((f) => SKILL_PATTERN.test(f));
|
|
14567
14829
|
for (const file of staleFiles) {
|
|
14568
|
-
await unlink2(
|
|
14830
|
+
await unlink2(join22(targetDir, file));
|
|
14569
14831
|
}
|
|
14570
14832
|
return staleFiles;
|
|
14571
14833
|
}
|
|
14572
14834
|
async function installSlashCommandsOnly() {
|
|
14573
|
-
const targetDir =
|
|
14835
|
+
const targetDir = join22(homedir4(), ".claude", "commands");
|
|
14574
14836
|
await ensureDir(targetDir);
|
|
14575
14837
|
const cleaned = await cleanupStaleSkills(targetDir);
|
|
14576
14838
|
const files = await readdir16(SKILLS_DIR);
|
|
14577
14839
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
14578
14840
|
let installed = 0;
|
|
14579
14841
|
for (const file of mdFiles) {
|
|
14580
|
-
await cp2(
|
|
14842
|
+
await cp2(join22(SKILLS_DIR, file), join22(targetDir, file));
|
|
14581
14843
|
installed++;
|
|
14582
14844
|
}
|
|
14583
14845
|
return { cleaned, installed, files: mdFiles, targetDir };
|
|
@@ -14602,17 +14864,17 @@ async function installSkills(_projectRoot) {
|
|
|
14602
14864
|
}
|
|
14603
14865
|
var AGENT_PATTERN = /^reap-.+\.md$/;
|
|
14604
14866
|
function agentsTemplateDir() {
|
|
14605
|
-
return __dirname2.includes("dist") ?
|
|
14867
|
+
return __dirname2.includes("dist") ? join22(__dirname2, "..", "templates", "agents") : join22(__dirname2, "..", "..", "templates", "agents");
|
|
14606
14868
|
}
|
|
14607
14869
|
async function installAgents(home = homedir4()) {
|
|
14608
|
-
const targetDir =
|
|
14870
|
+
const targetDir = join22(home, ".claude", "agents");
|
|
14609
14871
|
await ensureDir(targetDir);
|
|
14610
14872
|
let cleaned = [];
|
|
14611
14873
|
try {
|
|
14612
14874
|
const existing = await readdir16(targetDir);
|
|
14613
14875
|
cleaned = existing.filter((f) => AGENT_PATTERN.test(f));
|
|
14614
14876
|
for (const file of cleaned) {
|
|
14615
|
-
await unlink2(
|
|
14877
|
+
await unlink2(join22(targetDir, file));
|
|
14616
14878
|
}
|
|
14617
14879
|
} catch {}
|
|
14618
14880
|
let installed = 0;
|
|
@@ -14623,7 +14885,7 @@ async function installAgents(home = homedir4()) {
|
|
|
14623
14885
|
for (const file of sources) {
|
|
14624
14886
|
if (!file.endsWith(".md"))
|
|
14625
14887
|
continue;
|
|
14626
|
-
await cp2(
|
|
14888
|
+
await cp2(join22(templateDir, file), join22(targetDir, file));
|
|
14627
14889
|
files.push(file);
|
|
14628
14890
|
installed++;
|
|
14629
14891
|
}
|
|
@@ -14631,16 +14893,16 @@ async function installAgents(home = homedir4()) {
|
|
|
14631
14893
|
return { cleaned, installed, files, targetDir };
|
|
14632
14894
|
}
|
|
14633
14895
|
async function installReapGuide() {
|
|
14634
|
-
const reapHome =
|
|
14896
|
+
const reapHome = join22(homedir4(), ".reap");
|
|
14635
14897
|
await ensureDir(reapHome);
|
|
14636
|
-
const templateDir = __dirname2.includes("dist") ?
|
|
14637
|
-
const src =
|
|
14898
|
+
const templateDir = __dirname2.includes("dist") ? join22(__dirname2, "..", "templates") : join22(__dirname2, "..", "..", "templates");
|
|
14899
|
+
const src = join22(templateDir, "reap-guide.md");
|
|
14638
14900
|
if (await fileExists(src)) {
|
|
14639
|
-
await cp2(src,
|
|
14901
|
+
await cp2(src, join22(reapHome, "reap-guide.md"));
|
|
14640
14902
|
}
|
|
14641
14903
|
}
|
|
14642
14904
|
async function registerSessionHooks() {
|
|
14643
|
-
const settingsPath =
|
|
14905
|
+
const settingsPath = join22(homedir4(), ".claude", "settings.json");
|
|
14644
14906
|
const requiredHooks = [
|
|
14645
14907
|
{ command: "reap check-version 2>/dev/null || true", marker: "reap check-version" },
|
|
14646
14908
|
{ command: "reap load-context 2>/dev/null || true", marker: "reap load-context" }
|
|
@@ -14699,13 +14961,13 @@ var claudeCodeAdapter = {
|
|
|
14699
14961
|
// src/adapters/opencode/install.ts
|
|
14700
14962
|
init_fs();
|
|
14701
14963
|
import { cp as cp3, readFile as readFile4, writeFile as writeFile4, readdir as readdir17, unlink as unlink3 } from "fs/promises";
|
|
14702
|
-
import { join as
|
|
14703
|
-
import { fileURLToPath as
|
|
14964
|
+
import { join as join23, dirname as dirname9 } from "path";
|
|
14965
|
+
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
14704
14966
|
import { homedir as homedir5 } from "os";
|
|
14705
14967
|
import { createHash as createHash4 } from "crypto";
|
|
14706
|
-
var __dirname3 =
|
|
14968
|
+
var __dirname3 = dirname9(fileURLToPath8(import.meta.url));
|
|
14707
14969
|
function assetPath(...segments) {
|
|
14708
|
-
return __dirname3.includes("dist") ?
|
|
14970
|
+
return __dirname3.includes("dist") ? join23(__dirname3, "..", "adapters", "opencode", ...segments) : join23(__dirname3, ...segments);
|
|
14709
14971
|
}
|
|
14710
14972
|
var PLUGIN_FILENAME = "reap-plugin.ts";
|
|
14711
14973
|
var PLUGIN_SRC = assetPath("plugin", PLUGIN_FILENAME);
|
|
@@ -14763,7 +15025,7 @@ async function ensureAgentsMd(projectRoot, projectName) {
|
|
|
14763
15025
|
const inner = stripMarkers2(rawTemplate);
|
|
14764
15026
|
const wrapped = wrapWithMarkers2(inner);
|
|
14765
15027
|
const newHash = computeSectionHash2(inner);
|
|
14766
|
-
const agentsPath =
|
|
15028
|
+
const agentsPath = join23(projectRoot, "AGENTS.md");
|
|
14767
15029
|
const existing = await readTextFile(agentsPath);
|
|
14768
15030
|
if (!existing) {
|
|
14769
15031
|
await writeTextFile(agentsPath, `# ${projectName}
|
|
@@ -14810,7 +15072,7 @@ function stripMarkers2(content) {
|
|
|
14810
15072
|
return content.slice(afterStart + 1, endIdx).trimEnd();
|
|
14811
15073
|
}
|
|
14812
15074
|
async function ensureOpencodeJson(projectRoot) {
|
|
14813
|
-
const path =
|
|
15075
|
+
const path = join23(projectRoot, "opencode.json");
|
|
14814
15076
|
const existed = await fileExists(path);
|
|
14815
15077
|
let cfg = {};
|
|
14816
15078
|
if (existed) {
|
|
@@ -14849,27 +15111,27 @@ async function ensureOpencodeJson(projectRoot) {
|
|
|
14849
15111
|
return existed ? "updated" : "created";
|
|
14850
15112
|
}
|
|
14851
15113
|
async function installPluginFile(projectRoot) {
|
|
14852
|
-
const pluginsDir =
|
|
15114
|
+
const pluginsDir = join23(projectRoot, ".opencode", "plugins");
|
|
14853
15115
|
await ensureDir(pluginsDir);
|
|
14854
15116
|
if (await fileExists(PLUGIN_SRC)) {
|
|
14855
|
-
await cp3(PLUGIN_SRC,
|
|
15117
|
+
await cp3(PLUGIN_SRC, join23(pluginsDir, PLUGIN_FILENAME));
|
|
14856
15118
|
}
|
|
14857
15119
|
}
|
|
14858
15120
|
async function installReapGuide2() {
|
|
14859
|
-
const reapHome =
|
|
15121
|
+
const reapHome = join23(homedir5(), ".reap");
|
|
14860
15122
|
await ensureDir(reapHome);
|
|
14861
|
-
const templateDir = __dirname3.includes("dist") ?
|
|
14862
|
-
const src =
|
|
15123
|
+
const templateDir = __dirname3.includes("dist") ? join23(__dirname3, "..", "..", "templates") : join23(__dirname3, "..", "..", "templates");
|
|
15124
|
+
const src = join23(templateDir, "reap-guide.md");
|
|
14863
15125
|
if (await fileExists(src)) {
|
|
14864
|
-
await cp3(src,
|
|
15126
|
+
await cp3(src, join23(reapHome, "reap-guide.md"));
|
|
14865
15127
|
}
|
|
14866
15128
|
}
|
|
14867
15129
|
var SLASH_COMMAND_PATTERN = /^reap\..+\.md$/;
|
|
14868
15130
|
function claudeCodeSkillsDir() {
|
|
14869
|
-
return __dirname3.includes("dist") ?
|
|
15131
|
+
return __dirname3.includes("dist") ? join23(__dirname3, "..", "adapters", "claude-code", "skills") : join23(__dirname3, "..", "claude-code", "skills");
|
|
14870
15132
|
}
|
|
14871
15133
|
function opencodeCommandsDir(home = homedir5()) {
|
|
14872
|
-
return
|
|
15134
|
+
return join23(home, ".config", "opencode", "commands");
|
|
14873
15135
|
}
|
|
14874
15136
|
async function installSlashCommands(home = homedir5()) {
|
|
14875
15137
|
const targetDir = opencodeCommandsDir(home);
|
|
@@ -14879,7 +15141,7 @@ async function installSlashCommands(home = homedir5()) {
|
|
|
14879
15141
|
const existing = await readdir17(targetDir);
|
|
14880
15142
|
for (const file of existing) {
|
|
14881
15143
|
if (SLASH_COMMAND_PATTERN.test(file)) {
|
|
14882
|
-
await unlink3(
|
|
15144
|
+
await unlink3(join23(targetDir, file));
|
|
14883
15145
|
cleaned++;
|
|
14884
15146
|
}
|
|
14885
15147
|
}
|
|
@@ -14891,7 +15153,7 @@ async function installSlashCommands(home = homedir5()) {
|
|
|
14891
15153
|
for (const file of sources) {
|
|
14892
15154
|
if (!file.endsWith(".md"))
|
|
14893
15155
|
continue;
|
|
14894
|
-
await cp3(
|
|
15156
|
+
await cp3(join23(srcDir, file), join23(targetDir, file));
|
|
14895
15157
|
installed++;
|
|
14896
15158
|
}
|
|
14897
15159
|
} catch {}
|
|
@@ -14899,10 +15161,10 @@ async function installSlashCommands(home = homedir5()) {
|
|
|
14899
15161
|
}
|
|
14900
15162
|
var AGENT_PATTERN2 = /^reap-.+\.md$/;
|
|
14901
15163
|
function agentsTemplateDir2() {
|
|
14902
|
-
return __dirname3.includes("dist") ?
|
|
15164
|
+
return __dirname3.includes("dist") ? join23(__dirname3, "..", "templates", "agents") : join23(__dirname3, "..", "..", "templates", "agents");
|
|
14903
15165
|
}
|
|
14904
15166
|
function opencodeAgentsDir(home = homedir5()) {
|
|
14905
|
-
return
|
|
15167
|
+
return join23(home, ".config", "opencode", "agent");
|
|
14906
15168
|
}
|
|
14907
15169
|
async function installAgents2(home = homedir5()) {
|
|
14908
15170
|
const targetDir = opencodeAgentsDir(home);
|
|
@@ -14912,7 +15174,7 @@ async function installAgents2(home = homedir5()) {
|
|
|
14912
15174
|
const existing = await readdir17(targetDir);
|
|
14913
15175
|
for (const file of existing) {
|
|
14914
15176
|
if (AGENT_PATTERN2.test(file)) {
|
|
14915
|
-
await unlink3(
|
|
15177
|
+
await unlink3(join23(targetDir, file));
|
|
14916
15178
|
cleaned++;
|
|
14917
15179
|
}
|
|
14918
15180
|
}
|
|
@@ -14924,7 +15186,7 @@ async function installAgents2(home = homedir5()) {
|
|
|
14924
15186
|
for (const file of sources) {
|
|
14925
15187
|
if (!file.endsWith(".md"))
|
|
14926
15188
|
continue;
|
|
14927
|
-
await cp3(
|
|
15189
|
+
await cp3(join23(srcDir, file), join23(targetDir, file));
|
|
14928
15190
|
installed++;
|
|
14929
15191
|
}
|
|
14930
15192
|
} catch {}
|
|
@@ -14948,7 +15210,7 @@ async function installSkills2(projectRoot) {
|
|
|
14948
15210
|
],
|
|
14949
15211
|
context: {
|
|
14950
15212
|
agentClient: "opencode",
|
|
14951
|
-
pluginPath:
|
|
15213
|
+
pluginPath: join23(projectRoot, ".opencode", "plugins", PLUGIN_FILENAME),
|
|
14952
15214
|
opencodeJson: opencodeJsonAction,
|
|
14953
15215
|
slashCommands: {
|
|
14954
15216
|
cleaned: slashCommands.cleaned,
|
|
@@ -15003,7 +15265,7 @@ function getAdapter(agentClient) {
|
|
|
15003
15265
|
|
|
15004
15266
|
// src/cli/commands/install-skills.ts
|
|
15005
15267
|
init_fs();
|
|
15006
|
-
async function
|
|
15268
|
+
async function execute30() {
|
|
15007
15269
|
const cwd = process.cwd();
|
|
15008
15270
|
const paths = createPaths(cwd);
|
|
15009
15271
|
let agentClient;
|
|
@@ -15011,7 +15273,7 @@ async function execute29() {
|
|
|
15011
15273
|
const raw = await readTextFile(paths.config);
|
|
15012
15274
|
if (raw) {
|
|
15013
15275
|
try {
|
|
15014
|
-
const cfg =
|
|
15276
|
+
const cfg = import_yaml23.default.parse(raw);
|
|
15015
15277
|
agentClient = cfg.agentClient;
|
|
15016
15278
|
} catch {}
|
|
15017
15279
|
}
|
|
@@ -15021,10 +15283,10 @@ async function execute29() {
|
|
|
15021
15283
|
}
|
|
15022
15284
|
|
|
15023
15285
|
// src/cli/commands/fix.ts
|
|
15024
|
-
var
|
|
15286
|
+
var import_yaml24 = __toESM(require_dist(), 1);
|
|
15025
15287
|
import { mkdir as mkdir3, stat as stat4 } from "fs/promises";
|
|
15026
|
-
import { join as
|
|
15027
|
-
import { fileURLToPath as
|
|
15288
|
+
import { join as join24, dirname as dirname10 } from "path";
|
|
15289
|
+
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
15028
15290
|
import { homedir as homedir6 } from "os";
|
|
15029
15291
|
init_fs();
|
|
15030
15292
|
init_integrity();
|
|
@@ -15073,7 +15335,7 @@ async function fixProject(projectRoot) {
|
|
|
15073
15335
|
if (currentContent !== null) {
|
|
15074
15336
|
if (currentContent.trim()) {
|
|
15075
15337
|
try {
|
|
15076
|
-
const state =
|
|
15338
|
+
const state = import_yaml24.default.parse(currentContent);
|
|
15077
15339
|
const allStages = [
|
|
15078
15340
|
...LIFECYCLE_STAGES,
|
|
15079
15341
|
...MERGE_STAGES
|
|
@@ -15105,13 +15367,13 @@ async function fixProject(projectRoot) {
|
|
|
15105
15367
|
issues.push(`genome/${gf.name} is missing. Run 'reap init --repair' to restore.`);
|
|
15106
15368
|
}
|
|
15107
15369
|
}
|
|
15108
|
-
const guidePath =
|
|
15370
|
+
const guidePath = join24(homedir6(), ".reap", "reap-guide.md");
|
|
15109
15371
|
if (!await fileExists(guidePath)) {
|
|
15110
|
-
const __dir =
|
|
15111
|
-
const srcGuide = await readTextFile(
|
|
15372
|
+
const __dir = dirname10(fileURLToPath9(import.meta.url));
|
|
15373
|
+
const srcGuide = await readTextFile(join24(__dir, "..", "templates", "reap-guide.md"));
|
|
15112
15374
|
if (srcGuide) {
|
|
15113
15375
|
const { ensureDir: ensDir } = await Promise.resolve().then(() => (init_fs(), exports_fs));
|
|
15114
|
-
await ensDir(
|
|
15376
|
+
await ensDir(join24(homedir6(), ".reap"));
|
|
15115
15377
|
await writeTextFile(guidePath, srcGuide);
|
|
15116
15378
|
fixed.push("Restored missing ~/.reap/reap-guide.md");
|
|
15117
15379
|
} else {
|
|
@@ -15140,7 +15402,7 @@ async function fixProject(projectRoot) {
|
|
|
15140
15402
|
{
|
|
15141
15403
|
const { ensureClaudeMd: ensureClaudeMd2 } = await Promise.resolve().then(() => (init_common(), exports_common));
|
|
15142
15404
|
const configContent = await readTextFile(paths.config);
|
|
15143
|
-
const projectName = configContent ?
|
|
15405
|
+
const projectName = configContent ? import_yaml24.default.parse(configContent)?.project ?? "my-project" : "my-project";
|
|
15144
15406
|
const action = await ensureClaudeMd2(paths.root, projectName);
|
|
15145
15407
|
if (action !== "skipped") {
|
|
15146
15408
|
fixed.push(`CLAUDE.md ${action} with REAP section`);
|
|
@@ -15148,7 +15410,7 @@ async function fixProject(projectRoot) {
|
|
|
15148
15410
|
}
|
|
15149
15411
|
return { issues, fixed };
|
|
15150
15412
|
}
|
|
15151
|
-
async function
|
|
15413
|
+
async function execute31(check) {
|
|
15152
15414
|
const root = process.cwd();
|
|
15153
15415
|
const paths = createPaths(root);
|
|
15154
15416
|
if (await detectV15(paths)) {
|
|
@@ -15189,9 +15451,9 @@ async function execute30(check) {
|
|
|
15189
15451
|
}
|
|
15190
15452
|
|
|
15191
15453
|
// src/cli/commands/destroy.ts
|
|
15192
|
-
var
|
|
15454
|
+
var import_yaml25 = __toESM(require_dist(), 1);
|
|
15193
15455
|
import { rm as rm6 } from "fs/promises";
|
|
15194
|
-
import { join as
|
|
15456
|
+
import { join as join25 } from "path";
|
|
15195
15457
|
init_fs();
|
|
15196
15458
|
init_integrity();
|
|
15197
15459
|
async function getProjectName(projectRoot) {
|
|
@@ -15200,7 +15462,7 @@ async function getProjectName(projectRoot) {
|
|
|
15200
15462
|
const content = await readTextFile(paths.config);
|
|
15201
15463
|
if (!content)
|
|
15202
15464
|
return null;
|
|
15203
|
-
const config =
|
|
15465
|
+
const config = import_yaml25.default.parse(content);
|
|
15204
15466
|
return config.project ?? null;
|
|
15205
15467
|
} catch {
|
|
15206
15468
|
return null;
|
|
@@ -15209,7 +15471,7 @@ async function getProjectName(projectRoot) {
|
|
|
15209
15471
|
async function destroyProject(projectRoot) {
|
|
15210
15472
|
const removed = [];
|
|
15211
15473
|
const skipped = [];
|
|
15212
|
-
const reapDir =
|
|
15474
|
+
const reapDir = join25(projectRoot, ".reap");
|
|
15213
15475
|
if (await fileExists(reapDir)) {
|
|
15214
15476
|
await rm6(reapDir, { recursive: true, force: true });
|
|
15215
15477
|
removed.push(".reap/");
|
|
@@ -15221,7 +15483,7 @@ async function destroyProject(projectRoot) {
|
|
|
15221
15483
|
return { removed, skipped };
|
|
15222
15484
|
}
|
|
15223
15485
|
async function cleanClaudeMd(projectRoot, removed, skipped) {
|
|
15224
|
-
const claudeMdPath =
|
|
15486
|
+
const claudeMdPath = join25(projectRoot, "CLAUDE.md");
|
|
15225
15487
|
const content = await readTextFile(claudeMdPath);
|
|
15226
15488
|
if (content === null) {
|
|
15227
15489
|
skipped.push("CLAUDE.md (not found)");
|
|
@@ -15246,7 +15508,7 @@ async function cleanClaudeMd(projectRoot, removed, skipped) {
|
|
|
15246
15508
|
}
|
|
15247
15509
|
}
|
|
15248
15510
|
async function cleanGitignore(projectRoot, removed, skipped) {
|
|
15249
|
-
const gitignorePath =
|
|
15511
|
+
const gitignorePath = join25(projectRoot, ".gitignore");
|
|
15250
15512
|
const content = await readTextFile(gitignorePath);
|
|
15251
15513
|
if (content === null) {
|
|
15252
15514
|
skipped.push(".gitignore (not found)");
|
|
@@ -15277,7 +15539,7 @@ async function cleanGitignore(projectRoot, removed, skipped) {
|
|
|
15277
15539
|
await writeTextFile(gitignorePath, cleaned);
|
|
15278
15540
|
removed.push(".gitignore (REAP entries removed)");
|
|
15279
15541
|
}
|
|
15280
|
-
async function
|
|
15542
|
+
async function execute32(confirm) {
|
|
15281
15543
|
const root = process.cwd();
|
|
15282
15544
|
const paths = createPaths(root);
|
|
15283
15545
|
if (await detectV15(paths)) {
|
|
@@ -15311,7 +15573,7 @@ async function execute31(confirm) {
|
|
|
15311
15573
|
|
|
15312
15574
|
// src/cli/commands/clean.ts
|
|
15313
15575
|
import { rm as rm7, readdir as readdir18, mkdir as mkdir4 } from "fs/promises";
|
|
15314
|
-
import { join as
|
|
15576
|
+
import { join as join26 } from "path";
|
|
15315
15577
|
init_fs();
|
|
15316
15578
|
init_integrity();
|
|
15317
15579
|
async function cleanProject(projectRoot, options) {
|
|
@@ -15350,7 +15612,7 @@ async function cleanLineage(lineageDir, mode, actions) {
|
|
|
15350
15612
|
}
|
|
15351
15613
|
if (mode === "delete") {
|
|
15352
15614
|
for (const entry of entries) {
|
|
15353
|
-
await rm7(
|
|
15615
|
+
await rm7(join26(lineageDir, entry), { recursive: true, force: true });
|
|
15354
15616
|
}
|
|
15355
15617
|
actions.push(`Lineage: deleted ${entries.length} item(s)`);
|
|
15356
15618
|
} else {
|
|
@@ -15366,9 +15628,9 @@ async function cleanLineage(lineageDir, mode, actions) {
|
|
|
15366
15628
|
].join(`
|
|
15367
15629
|
`);
|
|
15368
15630
|
for (const dir of genDirs) {
|
|
15369
|
-
await rm7(
|
|
15631
|
+
await rm7(join26(lineageDir, dir), { recursive: true, force: true });
|
|
15370
15632
|
}
|
|
15371
|
-
await writeTextFile(
|
|
15633
|
+
await writeTextFile(join26(lineageDir, `${epochId}.md`), summary);
|
|
15372
15634
|
actions.push(`Lineage: compressed ${genDirs.length} generation(s) into ${epochId}`);
|
|
15373
15635
|
}
|
|
15374
15636
|
}
|
|
@@ -15388,7 +15650,7 @@ async function cleanLife(lifeDir, actions) {
|
|
|
15388
15650
|
for (const entry of entries) {
|
|
15389
15651
|
if (entry === "backlog")
|
|
15390
15652
|
continue;
|
|
15391
|
-
await rm7(
|
|
15653
|
+
await rm7(join26(lifeDir, entry), { recursive: true, force: true });
|
|
15392
15654
|
removedCount++;
|
|
15393
15655
|
}
|
|
15394
15656
|
actions.push(`Life: cleaned ${removedCount} file(s)`);
|
|
@@ -15402,7 +15664,7 @@ async function cleanDir(dirPath, label, actions) {
|
|
|
15402
15664
|
await mkdir4(dirPath, { recursive: true });
|
|
15403
15665
|
actions.push(`${label}: reset`);
|
|
15404
15666
|
}
|
|
15405
|
-
async function
|
|
15667
|
+
async function execute33(options) {
|
|
15406
15668
|
const root = process.cwd();
|
|
15407
15669
|
const hasOptions = options.lineage || options.life || options.backlog || options.hooks;
|
|
15408
15670
|
if (!hasOptions) {
|
|
@@ -15448,18 +15710,18 @@ async function execute32(options) {
|
|
|
15448
15710
|
|
|
15449
15711
|
// src/cli/commands/check-version.ts
|
|
15450
15712
|
init_integrity();
|
|
15451
|
-
var
|
|
15713
|
+
var import_yaml26 = __toESM(require_dist(), 1);
|
|
15452
15714
|
import { execSync as execSync7 } from "child_process";
|
|
15453
|
-
import { readFileSync as
|
|
15454
|
-
import { join as
|
|
15715
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
15716
|
+
import { join as join28 } from "path";
|
|
15455
15717
|
|
|
15456
15718
|
// src/core/notice.ts
|
|
15457
|
-
import { readFileSync as
|
|
15458
|
-
import { join as
|
|
15719
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
15720
|
+
import { join as join27, dirname as dirname11 } from "path";
|
|
15459
15721
|
function findPackageRoot() {
|
|
15460
15722
|
try {
|
|
15461
15723
|
const pkgPath = __require.resolve("@c-d-cc/reap/package.json");
|
|
15462
|
-
return
|
|
15724
|
+
return dirname11(pkgPath);
|
|
15463
15725
|
} catch {
|
|
15464
15726
|
return process.cwd();
|
|
15465
15727
|
}
|
|
@@ -15476,8 +15738,8 @@ var LANG_MAP = {
|
|
|
15476
15738
|
};
|
|
15477
15739
|
function fetchReleaseNotice(version, language) {
|
|
15478
15740
|
try {
|
|
15479
|
-
const noticePath =
|
|
15480
|
-
const content =
|
|
15741
|
+
const noticePath = join27(findPackageRoot(), "RELEASE_NOTICE.md");
|
|
15742
|
+
const content = readFileSync4(noticePath, "utf-8");
|
|
15481
15743
|
const versionTag = version.startsWith("v") ? version : `v${version}`;
|
|
15482
15744
|
const versionPattern = new RegExp(`^## ${versionTag.replace(/\./g, "\\.")}\\s*$`, "m");
|
|
15483
15745
|
const versionMatch = versionPattern.exec(content);
|
|
@@ -15621,16 +15883,16 @@ function performAutoUpdate(root) {
|
|
|
15621
15883
|
return { action: "skipped", reason: "error" };
|
|
15622
15884
|
}
|
|
15623
15885
|
}
|
|
15624
|
-
async function
|
|
15886
|
+
async function execute34() {
|
|
15625
15887
|
const root = process.cwd();
|
|
15626
15888
|
await cleanupLegacyHooks(root);
|
|
15627
15889
|
await cleanupLegacyProjectSkills(root);
|
|
15628
15890
|
const result = performAutoUpdate(root);
|
|
15629
15891
|
if (result.action === "upgraded" && result.to) {
|
|
15630
15892
|
try {
|
|
15631
|
-
const configPath =
|
|
15632
|
-
const configContent =
|
|
15633
|
-
const config =
|
|
15893
|
+
const configPath = join28(root, ".reap", "config.yml");
|
|
15894
|
+
const configContent = readFileSync5(configPath, "utf-8");
|
|
15895
|
+
const config = import_yaml26.default.parse(configContent);
|
|
15634
15896
|
const language = config?.language ?? "english";
|
|
15635
15897
|
const notice = fetchReleaseNotice(result.to, language);
|
|
15636
15898
|
if (notice)
|
|
@@ -15640,10 +15902,10 @@ async function execute33() {
|
|
|
15640
15902
|
}
|
|
15641
15903
|
|
|
15642
15904
|
// src/cli/commands/config.ts
|
|
15643
|
-
var
|
|
15905
|
+
var import_yaml27 = __toESM(require_dist(), 1);
|
|
15644
15906
|
init_fs();
|
|
15645
15907
|
init_integrity();
|
|
15646
|
-
async function
|
|
15908
|
+
async function execute35() {
|
|
15647
15909
|
const root = process.cwd();
|
|
15648
15910
|
const paths = createPaths(root);
|
|
15649
15911
|
if (!await fileExists(paths.config)) {
|
|
@@ -15656,7 +15918,7 @@ async function execute34() {
|
|
|
15656
15918
|
if (!configContent) {
|
|
15657
15919
|
emitError("config", "Config file is empty.");
|
|
15658
15920
|
}
|
|
15659
|
-
const config =
|
|
15921
|
+
const config = import_yaml27.default.parse(configContent);
|
|
15660
15922
|
emitOutput({
|
|
15661
15923
|
status: "ok",
|
|
15662
15924
|
command: "config",
|
|
@@ -15675,18 +15937,18 @@ async function execute34() {
|
|
|
15675
15937
|
}
|
|
15676
15938
|
|
|
15677
15939
|
// src/cli/commands/update.ts
|
|
15678
|
-
var
|
|
15679
|
-
import { readFileSync as
|
|
15680
|
-
import { join as
|
|
15681
|
-
import { fileURLToPath as
|
|
15940
|
+
var import_yaml28 = __toESM(require_dist(), 1);
|
|
15941
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
15942
|
+
import { join as join29, dirname as dirname12 } from "path";
|
|
15943
|
+
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
15682
15944
|
init_fs();
|
|
15683
15945
|
init_integrity();
|
|
15684
|
-
function
|
|
15946
|
+
function getPackageVersion3() {
|
|
15685
15947
|
try {
|
|
15686
|
-
const __dir =
|
|
15687
|
-
for (const rel of [
|
|
15948
|
+
const __dir = dirname12(fileURLToPath10(import.meta.url));
|
|
15949
|
+
for (const rel of [join29(__dir, "..", "..", "package.json"), join29(__dir, "..", "package.json")]) {
|
|
15688
15950
|
try {
|
|
15689
|
-
return JSON.parse(
|
|
15951
|
+
return JSON.parse(readFileSync6(rel, "utf-8")).version;
|
|
15690
15952
|
} catch {}
|
|
15691
15953
|
}
|
|
15692
15954
|
} catch {}
|
|
@@ -15701,7 +15963,10 @@ var VALID_CONFIG_FIELDS = new Set([
|
|
|
15701
15963
|
"agentClient",
|
|
15702
15964
|
"autoUpdate",
|
|
15703
15965
|
"autoIssueReport",
|
|
15704
|
-
"cruiseCount"
|
|
15966
|
+
"cruiseCount",
|
|
15967
|
+
"evaluator",
|
|
15968
|
+
"daemon",
|
|
15969
|
+
"lastMigratedVersion"
|
|
15705
15970
|
]);
|
|
15706
15971
|
var CONFIG_DEFAULTS = {
|
|
15707
15972
|
language: "english",
|
|
@@ -15734,7 +15999,7 @@ async function backfillConfig(paths) {
|
|
|
15734
15999
|
return { added: [], removed: [] };
|
|
15735
16000
|
let config;
|
|
15736
16001
|
try {
|
|
15737
|
-
config =
|
|
16002
|
+
config = import_yaml28.default.parse(content) ?? {};
|
|
15738
16003
|
} catch {
|
|
15739
16004
|
return { added: [], removed: [] };
|
|
15740
16005
|
}
|
|
@@ -15760,10 +16025,21 @@ async function backfillConfig(paths) {
|
|
|
15760
16025
|
}
|
|
15761
16026
|
}
|
|
15762
16027
|
if (added.length > 0 || removed.length > 0) {
|
|
15763
|
-
await writeTextFile(paths.config,
|
|
16028
|
+
await writeTextFile(paths.config, import_yaml28.default.stringify(config));
|
|
15764
16029
|
}
|
|
15765
16030
|
return { added, removed };
|
|
15766
16031
|
}
|
|
16032
|
+
async function markMigratedNow(paths, version) {
|
|
16033
|
+
const content = await readTextFile(paths.config) ?? "";
|
|
16034
|
+
let config = {};
|
|
16035
|
+
try {
|
|
16036
|
+
config = import_yaml28.default.parse(content) ?? {};
|
|
16037
|
+
} catch {}
|
|
16038
|
+
const previous = config.lastMigratedVersion ?? "0.0.0";
|
|
16039
|
+
config.lastMigratedVersion = version;
|
|
16040
|
+
await writeTextFile(paths.config, import_yaml28.default.stringify(config));
|
|
16041
|
+
return previous;
|
|
16042
|
+
}
|
|
15767
16043
|
async function ensureDirectories(paths) {
|
|
15768
16044
|
const created = [];
|
|
15769
16045
|
for (const dir of getRequiredDirs(paths)) {
|
|
@@ -15775,16 +16051,31 @@ async function ensureDirectories(paths) {
|
|
|
15775
16051
|
}
|
|
15776
16052
|
return created;
|
|
15777
16053
|
}
|
|
15778
|
-
async function
|
|
16054
|
+
async function execute36(phase, postUpgrade, markMigrated) {
|
|
15779
16055
|
const root = process.cwd();
|
|
15780
16056
|
const paths = createPaths(root);
|
|
15781
16057
|
if (!await fileExists(paths.config) && !await detectV15(paths)) {
|
|
15782
16058
|
emitError("update", "No REAP project detected. Run 'reap init' first.");
|
|
15783
16059
|
}
|
|
16060
|
+
if (markMigrated) {
|
|
16061
|
+
await backfillConfig(paths);
|
|
16062
|
+
const version = getPackageVersion3();
|
|
16063
|
+
const previous = await markMigratedNow(paths, version);
|
|
16064
|
+
emitOutput({
|
|
16065
|
+
status: "ok",
|
|
16066
|
+
command: "update",
|
|
16067
|
+
context: {
|
|
16068
|
+
markMigrated: true,
|
|
16069
|
+
lastMigratedVersion: version,
|
|
16070
|
+
previous
|
|
16071
|
+
},
|
|
16072
|
+
message: previous === version ? `Already marked as migrated for v${version}.` : `Marked project as migrated for v${version} (was ${previous}).`
|
|
16073
|
+
});
|
|
16074
|
+
}
|
|
15784
16075
|
if (!postUpgrade) {
|
|
15785
16076
|
if (await detectV15(paths)) {
|
|
15786
16077
|
try {
|
|
15787
|
-
await
|
|
16078
|
+
await execute5(paths, phase);
|
|
15788
16079
|
} catch (err) {
|
|
15789
16080
|
try {
|
|
15790
16081
|
autoReport("reap update (migration)", err, ["migration"]);
|
|
@@ -15811,7 +16102,7 @@ async function execute35(phase, postUpgrade) {
|
|
|
15811
16102
|
let agentClient;
|
|
15812
16103
|
if (configContent) {
|
|
15813
16104
|
try {
|
|
15814
|
-
const config =
|
|
16105
|
+
const config = import_yaml28.default.parse(configContent);
|
|
15815
16106
|
projectName = config.project ?? "my-project";
|
|
15816
16107
|
agentClient = config.agentClient;
|
|
15817
16108
|
} catch {}
|
|
@@ -15828,37 +16119,49 @@ async function execute35(phase, postUpgrade) {
|
|
|
15828
16119
|
const raw = configContent ?? "";
|
|
15829
16120
|
if (raw) {
|
|
15830
16121
|
try {
|
|
15831
|
-
const cfg =
|
|
16122
|
+
const cfg = import_yaml28.default.parse(raw);
|
|
15832
16123
|
if (cfg?.language)
|
|
15833
16124
|
language = cfg.language;
|
|
15834
16125
|
} catch {}
|
|
15835
16126
|
}
|
|
15836
|
-
const version =
|
|
16127
|
+
const version = getPackageVersion3();
|
|
15837
16128
|
if (version !== "0.0.0") {
|
|
15838
16129
|
const notice = fetchReleaseNotice(version, language);
|
|
15839
16130
|
if (notice)
|
|
15840
16131
|
console.error(notice);
|
|
15841
16132
|
}
|
|
15842
16133
|
} catch {}
|
|
15843
|
-
|
|
15844
|
-
|
|
15845
|
-
|
|
15846
|
-
|
|
15847
|
-
|
|
15848
|
-
|
|
15849
|
-
});
|
|
15850
|
-
} else {
|
|
15851
|
-
emitOutput({
|
|
15852
|
-
status: "ok",
|
|
15853
|
-
command: "update",
|
|
15854
|
-
context: { changes: updated },
|
|
15855
|
-
message: `Updated: ${updated.join("; ")}`
|
|
15856
|
-
});
|
|
16134
|
+
const refreshedRaw = await readTextFile(paths.config);
|
|
16135
|
+
let refreshedConfig = null;
|
|
16136
|
+
if (refreshedRaw) {
|
|
16137
|
+
try {
|
|
16138
|
+
refreshedConfig = import_yaml28.default.parse(refreshedRaw);
|
|
16139
|
+
} catch {}
|
|
15857
16140
|
}
|
|
16141
|
+
const pkgVersion = getPackageVersion3();
|
|
16142
|
+
let pendingMigrations = [];
|
|
16143
|
+
try {
|
|
16144
|
+
pendingMigrations = detectPendingMigrations(refreshedConfig, pkgVersion);
|
|
16145
|
+
} catch {
|
|
16146
|
+
pendingMigrations = [];
|
|
16147
|
+
}
|
|
16148
|
+
const baseMessage = updated.length === 0 ? "Project is up to date. Nothing to update." : `Updated: ${updated.join("; ")}`;
|
|
16149
|
+
const migrationMessage = pendingMigrations.length === 0 ? "" : ` ${pendingMigrations.length} pending migration${pendingMigrations.length === 1 ? "" : "s"} ` + `(${pendingMigrations.map((m) => "v" + m.version).join(", ")}) — see context.pendingMigrations. ` + `Run \`reap update --mark-migrated\` after applying them.`;
|
|
16150
|
+
emitOutput({
|
|
16151
|
+
status: "ok",
|
|
16152
|
+
command: "update",
|
|
16153
|
+
context: {
|
|
16154
|
+
changes: updated,
|
|
16155
|
+
pendingMigrations,
|
|
16156
|
+
packageVersion: pkgVersion,
|
|
16157
|
+
lastMigratedVersion: refreshedConfig?.lastMigratedVersion ?? "0.0.0"
|
|
16158
|
+
},
|
|
16159
|
+
message: baseMessage + migrationMessage
|
|
16160
|
+
});
|
|
15858
16161
|
}
|
|
15859
16162
|
|
|
15860
16163
|
// src/cli/commands/help.ts
|
|
15861
|
-
import { join as
|
|
16164
|
+
import { join as join30 } from "path";
|
|
15862
16165
|
init_fs();
|
|
15863
16166
|
var SUPPORTED_LANGUAGES = ["en", "ko", "ja", "zh-CN"];
|
|
15864
16167
|
var LANGUAGE_ALIASES = {
|
|
@@ -16025,7 +16328,7 @@ function buildHelpLines(lang, stateDisplay) {
|
|
|
16025
16328
|
CONFIG_LINE[lang]
|
|
16026
16329
|
];
|
|
16027
16330
|
}
|
|
16028
|
-
async function
|
|
16331
|
+
async function execute37(topic) {
|
|
16029
16332
|
const paths = createPaths(process.cwd());
|
|
16030
16333
|
const configContent = await readTextFile(paths.config);
|
|
16031
16334
|
const rawLang = detectLanguage(configContent);
|
|
@@ -16036,7 +16339,7 @@ async function execute36(topic) {
|
|
|
16036
16339
|
const stateDisplay = buildStateDisplay(state, lang);
|
|
16037
16340
|
const lines = buildHelpLines(lang, stateDisplay);
|
|
16038
16341
|
if (topic) {
|
|
16039
|
-
const reapGuidePath =
|
|
16342
|
+
const reapGuidePath = join30(paths.reap, "reap-guide.md");
|
|
16040
16343
|
const reapGuide = await readTextFile(reapGuidePath) ?? "";
|
|
16041
16344
|
emitOutput({
|
|
16042
16345
|
status: "prompt",
|
|
@@ -16081,7 +16384,7 @@ async function execute36(topic) {
|
|
|
16081
16384
|
// src/cli/commands/daemon/index.ts
|
|
16082
16385
|
init_client();
|
|
16083
16386
|
init_fs();
|
|
16084
|
-
async function
|
|
16387
|
+
async function execute38(subcommand, options) {
|
|
16085
16388
|
switch (subcommand) {
|
|
16086
16389
|
case "status":
|
|
16087
16390
|
return statusCmd();
|
|
@@ -16194,83 +16497,6 @@ ${lines.join(`
|
|
|
16194
16497
|
});
|
|
16195
16498
|
}
|
|
16196
16499
|
|
|
16197
|
-
// src/cli/commands/load-context.ts
|
|
16198
|
-
var import_yaml25 = __toESM(require_dist(), 1);
|
|
16199
|
-
import { join as join29 } from "path";
|
|
16200
|
-
init_fs();
|
|
16201
|
-
async function buildKnowledgeContext(cwd) {
|
|
16202
|
-
const configPath = join29(cwd, ".reap", "config.yml");
|
|
16203
|
-
if (!await fileExists(configPath)) {
|
|
16204
|
-
return null;
|
|
16205
|
-
}
|
|
16206
|
-
const paths = createPaths(cwd);
|
|
16207
|
-
const [configContent, currentContent] = await Promise.all([
|
|
16208
|
-
readTextFile(paths.config),
|
|
16209
|
-
readTextFile(paths.current)
|
|
16210
|
-
]);
|
|
16211
|
-
let config = null;
|
|
16212
|
-
if (configContent) {
|
|
16213
|
-
try {
|
|
16214
|
-
config = import_yaml25.default.parse(configContent);
|
|
16215
|
-
} catch {}
|
|
16216
|
-
}
|
|
16217
|
-
let state = null;
|
|
16218
|
-
if (currentContent) {
|
|
16219
|
-
try {
|
|
16220
|
-
state = import_yaml25.default.parse(currentContent);
|
|
16221
|
-
} catch {}
|
|
16222
|
-
}
|
|
16223
|
-
const sections = [];
|
|
16224
|
-
sections.push("# Current State");
|
|
16225
|
-
if (state) {
|
|
16226
|
-
const stateLines = [];
|
|
16227
|
-
stateLines.push(`- Generation: ${state.id}`);
|
|
16228
|
-
stateLines.push(`- Type: ${state.type}`);
|
|
16229
|
-
stateLines.push(`- Goal: ${state.goal}`);
|
|
16230
|
-
stateLines.push(`- Stage: ${state.stage}`);
|
|
16231
|
-
if (state.phase)
|
|
16232
|
-
stateLines.push(`- Phase: ${state.phase}`);
|
|
16233
|
-
if (state.type === "merge" && state.parents?.length) {
|
|
16234
|
-
stateLines.push(`- Parents: ${state.parents.join(", ")}`);
|
|
16235
|
-
}
|
|
16236
|
-
sections.push(stateLines.join(`
|
|
16237
|
-
`));
|
|
16238
|
-
} else {
|
|
16239
|
-
sections.push("No active generation.");
|
|
16240
|
-
}
|
|
16241
|
-
if (config) {
|
|
16242
|
-
const strictStage = state ? state.stage : "none";
|
|
16243
|
-
const strictSection = buildStrictSection(config.strictEdit ?? false, config.strictMerge ?? false, strictStage, state?.type);
|
|
16244
|
-
if (strictSection) {
|
|
16245
|
-
sections.push(strictSection.trimStart());
|
|
16246
|
-
}
|
|
16247
|
-
}
|
|
16248
|
-
if (config?.language) {
|
|
16249
|
-
sections.push(`# Language
|
|
16250
|
-
Always respond in ${config.language}. Use ${config.language} for all explanations, comments, and communications. Technical terms and code identifiers remain in their original form.`);
|
|
16251
|
-
}
|
|
16252
|
-
return sections.join(`
|
|
16253
|
-
|
|
16254
|
-
---
|
|
16255
|
-
|
|
16256
|
-
`);
|
|
16257
|
-
}
|
|
16258
|
-
async function execute38() {
|
|
16259
|
-
const context = await buildKnowledgeContext(process.cwd());
|
|
16260
|
-
if (!context) {
|
|
16261
|
-
process.exit(0);
|
|
16262
|
-
}
|
|
16263
|
-
const output = {
|
|
16264
|
-
hookSpecificOutput: {
|
|
16265
|
-
hookEventName: "SessionStart",
|
|
16266
|
-
additionalContext: context
|
|
16267
|
-
}
|
|
16268
|
-
};
|
|
16269
|
-
process.stdout.write(JSON.stringify(output) + `
|
|
16270
|
-
`);
|
|
16271
|
-
process.exit(0);
|
|
16272
|
-
}
|
|
16273
|
-
|
|
16274
16500
|
// src/cli/commands/dump-state.ts
|
|
16275
16501
|
init_fs();
|
|
16276
16502
|
async function execute39(opts = {}) {
|
|
@@ -16307,16 +16533,16 @@ async function execute39(opts = {}) {
|
|
|
16307
16533
|
|
|
16308
16534
|
// src/cli/index.ts
|
|
16309
16535
|
function readVersion() {
|
|
16310
|
-
const __dir =
|
|
16536
|
+
const __dir = dirname13(fileURLToPath11(import.meta.url));
|
|
16311
16537
|
let version = "0.0.0";
|
|
16312
|
-
for (const rel of [
|
|
16538
|
+
for (const rel of [join31(__dir, "..", "..", "package.json"), join31(__dir, "..", "package.json")]) {
|
|
16313
16539
|
try {
|
|
16314
|
-
version = JSON.parse(
|
|
16540
|
+
version = JSON.parse(readFileSync7(rel, "utf-8")).version;
|
|
16315
16541
|
break;
|
|
16316
16542
|
} catch {}
|
|
16317
16543
|
}
|
|
16318
16544
|
try {
|
|
16319
|
-
const hash =
|
|
16545
|
+
const hash = readFileSync7(join31(__dir, "..", ".dev-build"), "utf-8").trim();
|
|
16320
16546
|
if (hash)
|
|
16321
16547
|
version += `+dev.${hash}`;
|
|
16322
16548
|
} catch {}
|
|
@@ -16325,31 +16551,31 @@ function readVersion() {
|
|
|
16325
16551
|
var program2 = new Command;
|
|
16326
16552
|
program2.name("reap").description("Recursive Evolutionary Autonomous Pipeline — Self-Evolving").version(readVersion());
|
|
16327
16553
|
program2.command("init [project-name]").description("Initialize a new reap project").option("--mode <mode>", "Override auto-detected mode (greenfield or adoption)").option("--repair", "Repair an existing project — supplement missing files (e.g., CLAUDE.md)").option("--migrate", "Migrate from v0.15 to v0.16 structure").option("--phase <phase>", "Migration phase (confirm, execute, vision, complete)").action(async (projectName, options) => {
|
|
16328
|
-
await
|
|
16554
|
+
await execute6(projectName, options.mode, options.repair, options.migrate, options.phase);
|
|
16329
16555
|
});
|
|
16330
16556
|
program2.command("status").description("Show current project status").action(async () => {
|
|
16331
|
-
await
|
|
16557
|
+
await execute7();
|
|
16332
16558
|
});
|
|
16333
16559
|
program2.command("run <stage>").description("Run a lifecycle stage (start, learning, planning, ...)").option("--phase <phase>", "Stage phase (work, complete, reflect, fitness, adapt, commit)").option("--goal <goal>", "Goal for start command").option("--type <type>", "Generation type (embryo, normal, merge)").option("--parents <parents>", "Parent generation IDs for merge (comma-separated)").option("--feedback <feedback>", "Fitness feedback text").option("--reason <reason>", "Reason for back regression or abort").option("--backlog <backlog>", "Backlog filename to consume for this generation (use --no-backlog to explicitly declare no relevant backlog)").option("--no-backlog", "Explicitly declare no backlog item is relevant to this generation (suppresses pending-backlog prompt). Negates --backlog.").option("--source-action <sourceAction>", "Source action for abort/early-close (rollback, stash, hold, none — rollback only for abort)").option("--save-backlog", "Save progress to backlog on abort").option("--defer-tasks <value>", "For early-close: auto-defer unchecked tasks to new backlog (true|false, default true)").option("--severity <severity>", "For validation --phase report-evaluator: evaluator concern severity (high|low|none — none is a no-op)").option("--summary <summary>", "For validation --phase report-evaluator: one-line evaluator concern summary").action(async (stage, options) => {
|
|
16334
|
-
await
|
|
16560
|
+
await execute27(stage, options);
|
|
16335
16561
|
});
|
|
16336
16562
|
program2.command("make <resource>").description("Create a resource from template (backlog, hook)").option("--type <type>", "Resource type (backlog: genome-change/environment-change/task, hook: sh/md)").option("--title <title>", "Resource title").option("--body <body>", "Optional description body").option("--priority <priority>", "Priority (high, medium, low)").option("--event <event>", "Hook event (e.g. onLifeCompleted)").option("--name <name>", "Hook name").option("--condition <condition>", "Hook condition (default: always)").option("--order <order>", "Hook execution order (default: 50)").action(async (resource, options) => {
|
|
16337
|
-
await
|
|
16563
|
+
await execute28(resource, options);
|
|
16338
16564
|
});
|
|
16339
16565
|
program2.command("cruise <count>").description("Enable cruise mode for N generations").action(async (count) => {
|
|
16340
|
-
await
|
|
16566
|
+
await execute29(count);
|
|
16341
16567
|
});
|
|
16342
16568
|
program2.command("install-skills").description("Install Claude Code skill files to .claude/commands/").action(async () => {
|
|
16343
|
-
await
|
|
16569
|
+
await execute30();
|
|
16344
16570
|
});
|
|
16345
16571
|
program2.command("fix").description("Diagnose and repair .reap/ directory structure").option("--check", "Check only — report issues without fixing").action(async (options) => {
|
|
16346
|
-
await
|
|
16572
|
+
await execute31(options.check);
|
|
16347
16573
|
});
|
|
16348
16574
|
program2.command("destroy").description("Completely remove REAP from this project").option("--confirm", "Confirm destruction without prompt").action(async (options) => {
|
|
16349
|
-
await
|
|
16575
|
+
await execute32(options.confirm);
|
|
16350
16576
|
});
|
|
16351
16577
|
program2.command("clean").description("Selectively reset REAP project state").option("--lineage <mode>", "Lineage action (compress or delete)").option("--life", "Clear current generation and artifacts").option("--backlog", "Delete all backlog items").option("--hooks <mode>", "Hooks action (reset)").action(async (options) => {
|
|
16352
|
-
await
|
|
16578
|
+
await execute33({
|
|
16353
16579
|
lineage: options.lineage,
|
|
16354
16580
|
life: options.life,
|
|
16355
16581
|
backlog: options.backlog,
|
|
@@ -16357,24 +16583,24 @@ program2.command("clean").description("Selectively reset REAP project state").op
|
|
|
16357
16583
|
});
|
|
16358
16584
|
});
|
|
16359
16585
|
program2.command("check-version").description("Check for v0.15 project and show migration message").action(async () => {
|
|
16360
|
-
await
|
|
16586
|
+
await execute34();
|
|
16361
16587
|
});
|
|
16362
16588
|
program2.command("config").description("Show current REAP project configuration").action(async () => {
|
|
16363
|
-
await
|
|
16589
|
+
await execute35();
|
|
16364
16590
|
});
|
|
16365
16591
|
program2.command("help [topic]").description("Show REAP commands and workflow overview").action(async (topic) => {
|
|
16366
|
-
await
|
|
16592
|
+
await execute37(topic);
|
|
16367
16593
|
});
|
|
16368
|
-
program2.command("update").description("Update project structure to match current REAP version").option("--phase <phase>", "Migration phase for v0.15 projects (confirm, execute, vision, complete)").option("--post-upgrade", "Run project sync only (called by previous binary after self-upgrade)").action(async (options) => {
|
|
16369
|
-
await
|
|
16594
|
+
program2.command("update").description("Update project structure to match current REAP version").option("--phase <phase>", "Migration phase for v0.15 projects (confirm, execute, vision, complete)").option("--post-upgrade", "Run project sync only (called by previous binary after self-upgrade)").option("--mark-migrated", "Mark this project as migrated for the current REAP version (gen-071 migration layer)").action(async (options) => {
|
|
16595
|
+
await execute36(options.phase, options.postUpgrade, options.markMigrated);
|
|
16370
16596
|
});
|
|
16371
16597
|
program2.command("load-context").description("Output REAP project knowledge for SessionStart hook injection").action(async () => {
|
|
16372
|
-
await
|
|
16598
|
+
await execute();
|
|
16373
16599
|
});
|
|
16374
16600
|
program2.command("dump-state").description("Dump dynamic REAP context to .reap/.session-state.md (for OpenCode and external tools)").option("--stdout", "Write to stdout instead of the file").option("--silent", "Exit 0 silently on any error / non-REAP project").action(async (options) => {
|
|
16375
16601
|
await execute39({ stdout: options.stdout, silent: options.silent });
|
|
16376
16602
|
});
|
|
16377
16603
|
program2.command("daemon <subcommand>").description("Manage the REAP daemon (status, stop, index, query)").option("--query <query>", "Search query for daemon query subcommand").action(async (subcommand, options) => {
|
|
16378
|
-
await
|
|
16604
|
+
await execute38(subcommand, options);
|
|
16379
16605
|
});
|
|
16380
16606
|
program2.parse();
|