@c-d-cc/reap 0.16.6 → 0.17.0
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 +6 -0
- package/dist/cli/index.js +518 -444
- package/dist/templates/agents/reap-evaluate.md +21 -0
- package/dist/templates/agents/reap-evolve.md +49 -0
- package/dist/templates/reap-guide.md +78 -0
- 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 join4 } from "path";
|
|
7071
7071
|
import { homedir } from "os";
|
|
7072
7072
|
async function detectV15(paths) {
|
|
7073
|
-
return fileExists(
|
|
7073
|
+
return fileExists(join4(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 = join4(homedir(), ".reap", "reap-guide.md");
|
|
7125
|
+
const guideLocal = join4(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 = join4(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 = join4(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 = join4(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(join4(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 = join4(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(join4(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(join4(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(join4(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(join4(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(join4(home, ".claude", "skills"), /^reap\./, "~/.claude/skills/", "user-level reap skill found (should only be project-level)", errors);
|
|
7435
|
+
await checkGlobPattern(join4(home, ".claude", "commands"), /^reap\./, "~/.claude/commands/", "legacy reap command at user level (Phase 2 remnant)", warnings);
|
|
7436
|
+
await checkGlobPattern(join4(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 = join4(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(join4(commandsDir, entry), { force: true });
|
|
7460
7460
|
deleted.push(`.claude/commands/${entry}`);
|
|
7461
7461
|
}
|
|
7462
7462
|
}
|
|
7463
7463
|
} catch {}
|
|
7464
|
-
const skillsDir =
|
|
7464
|
+
const skillsDir = join4(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 = join4(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
|
+
join4(projectRoot, ".claude", "settings.json"),
|
|
7486
|
+
join4(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
|
|
7546
|
+
import { join as join5, dirname as dirname3 } from "path";
|
|
7547
7547
|
import { fileURLToPath } 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
7551
|
const __dirname2 = dirname3(fileURLToPath(import.meta.url));
|
|
7552
|
-
return
|
|
7552
|
+
return join5(__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 = join5(root, "CLAUDE.md");
|
|
7666
|
+
const dotClaudePath = join5(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 = join5(templateDir, "conditions");
|
|
7735
|
+
const conditionsDir = join5(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 = join5(conditionsDir, file);
|
|
7741
7741
|
if (!await fileExists(dest)) {
|
|
7742
|
-
await copyFile(
|
|
7742
|
+
await copyFile(join5(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 = join5(hooksDir, file);
|
|
7753
7753
|
if (!await fileExists(dest)) {
|
|
7754
|
-
await copyFile(
|
|
7754
|
+
await copyFile(join5(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 join12 } 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 join12(__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 = join12(homedir3(), ".reap", "daemon");
|
|
7859
|
+
PID_PATH = join12(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,10 +7885,13 @@ 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();
|
|
@@ -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 join8 } from "path";
|
|
8580
8595
|
|
|
8581
8596
|
// src/core/paths.ts
|
|
8582
8597
|
import { join } from "path";
|
|
@@ -8623,9 +8638,9 @@ function createPaths(root) {
|
|
|
8623
8638
|
init_fs();
|
|
8624
8639
|
|
|
8625
8640
|
// src/core/dump-state-sync.ts
|
|
8626
|
-
var
|
|
8641
|
+
var import_yaml2 = __toESM(require_dist(), 1);
|
|
8627
8642
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
8628
|
-
import { join as
|
|
8643
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
8629
8644
|
|
|
8630
8645
|
// src/core/prompt.ts
|
|
8631
8646
|
init_fs();
|
|
@@ -8979,6 +8994,21 @@ function buildBasePrompt(knowledge, paths, state, cruiseCount, clarityResult, co
|
|
|
8979
8994
|
lines.push("");
|
|
8980
8995
|
}
|
|
8981
8996
|
}
|
|
8997
|
+
if (config?.daemon === true) {
|
|
8998
|
+
lines.push("## Code Intelligence (Daemon)");
|
|
8999
|
+
lines.push("");
|
|
9000
|
+
lines.push("REAP daemon is enabled. Prefer daemon queries over full-text search when possible.");
|
|
9001
|
+
lines.push("");
|
|
9002
|
+
lines.push("- Health: `curl -sf http://127.0.0.1:17224/health` — if it fails, daemon is down; skip silently.");
|
|
9003
|
+
lines.push("- Project ID lookup: `curl -s http://127.0.0.1:17224/projects | jq '.data[] | select(.path==\"<cwd>\")'`.");
|
|
9004
|
+
lines.push("- Symbol search: `GET /projects/{id}/symbols?q=<query>` — find function/class/type definitions.");
|
|
9005
|
+
lines.push("- Callers: `GET /projects/{id}/symbols/{symbolId}/callers` — who calls this symbol?");
|
|
9006
|
+
lines.push("- Impact: `GET /projects/{id}/impact?file=<path>` — blast radius of changes to a file.");
|
|
9007
|
+
lines.push("- Staleness: `GET /projects/{id}/status` includes `lastIndexedCommit`. Compare against `git rev-parse HEAD`; if different, the index is stale.");
|
|
9008
|
+
lines.push("");
|
|
9009
|
+
lines.push("See `~/.reap/reap-guide.md` § Code Intelligence (Daemon) for the full protocol.");
|
|
9010
|
+
lines.push("");
|
|
9011
|
+
}
|
|
8982
9012
|
lines.push("## Project");
|
|
8983
9013
|
lines.push(`Path: ${paths.root}`);
|
|
8984
9014
|
return lines.join(`
|
|
@@ -9095,6 +9125,96 @@ function buildEvaluatorPrompt(knowledge, paths, state, opts) {
|
|
|
9095
9125
|
`);
|
|
9096
9126
|
}
|
|
9097
9127
|
|
|
9128
|
+
// src/cli/commands/load-context.ts
|
|
9129
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
9130
|
+
import { join as join2 } from "path";
|
|
9131
|
+
init_fs();
|
|
9132
|
+
async function buildKnowledgeContext(cwd) {
|
|
9133
|
+
const configPath = join2(cwd, ".reap", "config.yml");
|
|
9134
|
+
if (!await fileExists(configPath)) {
|
|
9135
|
+
return null;
|
|
9136
|
+
}
|
|
9137
|
+
const paths = createPaths(cwd);
|
|
9138
|
+
const [configContent, currentContent] = await Promise.all([
|
|
9139
|
+
readTextFile(paths.config),
|
|
9140
|
+
readTextFile(paths.current)
|
|
9141
|
+
]);
|
|
9142
|
+
let config = null;
|
|
9143
|
+
if (configContent) {
|
|
9144
|
+
try {
|
|
9145
|
+
config = import_yaml.default.parse(configContent);
|
|
9146
|
+
} catch {}
|
|
9147
|
+
}
|
|
9148
|
+
let state = null;
|
|
9149
|
+
if (currentContent) {
|
|
9150
|
+
try {
|
|
9151
|
+
state = import_yaml.default.parse(currentContent);
|
|
9152
|
+
} catch {}
|
|
9153
|
+
}
|
|
9154
|
+
const sections = [];
|
|
9155
|
+
sections.push("# Current State");
|
|
9156
|
+
if (state) {
|
|
9157
|
+
const stateLines = [];
|
|
9158
|
+
stateLines.push(`- Generation: ${state.id}`);
|
|
9159
|
+
stateLines.push(`- Type: ${state.type}`);
|
|
9160
|
+
stateLines.push(`- Goal: ${state.goal}`);
|
|
9161
|
+
stateLines.push(`- Stage: ${state.stage}`);
|
|
9162
|
+
if (state.phase)
|
|
9163
|
+
stateLines.push(`- Phase: ${state.phase}`);
|
|
9164
|
+
if (state.type === "merge" && state.parents?.length) {
|
|
9165
|
+
stateLines.push(`- Parents: ${state.parents.join(", ")}`);
|
|
9166
|
+
}
|
|
9167
|
+
sections.push(stateLines.join(`
|
|
9168
|
+
`));
|
|
9169
|
+
} else {
|
|
9170
|
+
sections.push("No active generation.");
|
|
9171
|
+
}
|
|
9172
|
+
if (config) {
|
|
9173
|
+
const strictStage = state ? state.stage : "none";
|
|
9174
|
+
const strictSection = buildStrictSection(config.strictEdit ?? false, config.strictMerge ?? false, strictStage, state?.type);
|
|
9175
|
+
if (strictSection) {
|
|
9176
|
+
sections.push(strictSection.trimStart());
|
|
9177
|
+
}
|
|
9178
|
+
}
|
|
9179
|
+
if (config?.language) {
|
|
9180
|
+
sections.push(`# Language
|
|
9181
|
+
Always respond in ${config.language}. Use ${config.language} for all explanations, comments, and communications. Technical terms and code identifiers remain in their original form.`);
|
|
9182
|
+
}
|
|
9183
|
+
if (config?.daemon === true) {
|
|
9184
|
+
sections.push(buildDaemonStaticSection());
|
|
9185
|
+
}
|
|
9186
|
+
return sections.join(`
|
|
9187
|
+
|
|
9188
|
+
---
|
|
9189
|
+
|
|
9190
|
+
`);
|
|
9191
|
+
}
|
|
9192
|
+
function buildDaemonStaticSection() {
|
|
9193
|
+
return [
|
|
9194
|
+
"# Code Intelligence (Daemon)",
|
|
9195
|
+
"",
|
|
9196
|
+
"- Enabled: true",
|
|
9197
|
+
"- Base URL: http://127.0.0.1:17224",
|
|
9198
|
+
"- See `~/.reap/reap-guide.md` § Code Intelligence (Daemon) for query examples and protocol."
|
|
9199
|
+
].join(`
|
|
9200
|
+
`);
|
|
9201
|
+
}
|
|
9202
|
+
async function execute() {
|
|
9203
|
+
const context = await buildKnowledgeContext(process.cwd());
|
|
9204
|
+
if (!context) {
|
|
9205
|
+
process.exit(0);
|
|
9206
|
+
}
|
|
9207
|
+
const output = {
|
|
9208
|
+
hookSpecificOutput: {
|
|
9209
|
+
hookEventName: "SessionStart",
|
|
9210
|
+
additionalContext: context
|
|
9211
|
+
}
|
|
9212
|
+
};
|
|
9213
|
+
process.stdout.write(JSON.stringify(output) + `
|
|
9214
|
+
`);
|
|
9215
|
+
process.exit(0);
|
|
9216
|
+
}
|
|
9217
|
+
|
|
9098
9218
|
// src/core/dump-state-sync.ts
|
|
9099
9219
|
var DUMP_COMMANDS = new Set([
|
|
9100
9220
|
"start",
|
|
@@ -9117,7 +9237,7 @@ var DUMP_COMMANDS = new Set([
|
|
|
9117
9237
|
"init"
|
|
9118
9238
|
]);
|
|
9119
9239
|
function buildKnowledgeContextSync(cwd) {
|
|
9120
|
-
const configPath =
|
|
9240
|
+
const configPath = join3(cwd, ".reap", "config.yml");
|
|
9121
9241
|
if (!existsSync(configPath))
|
|
9122
9242
|
return null;
|
|
9123
9243
|
const paths = createPaths(cwd);
|
|
@@ -9132,13 +9252,13 @@ function buildKnowledgeContextSync(cwd) {
|
|
|
9132
9252
|
let config = null;
|
|
9133
9253
|
if (configContent) {
|
|
9134
9254
|
try {
|
|
9135
|
-
config =
|
|
9255
|
+
config = import_yaml2.default.parse(configContent);
|
|
9136
9256
|
} catch {}
|
|
9137
9257
|
}
|
|
9138
9258
|
let state = null;
|
|
9139
9259
|
if (currentContent) {
|
|
9140
9260
|
try {
|
|
9141
|
-
state =
|
|
9261
|
+
state = import_yaml2.default.parse(currentContent);
|
|
9142
9262
|
} catch {}
|
|
9143
9263
|
}
|
|
9144
9264
|
const sections = [];
|
|
@@ -9170,6 +9290,9 @@ function buildKnowledgeContextSync(cwd) {
|
|
|
9170
9290
|
sections.push(`# Language
|
|
9171
9291
|
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
9292
|
}
|
|
9293
|
+
if (config?.daemon === true) {
|
|
9294
|
+
sections.push(buildDaemonStaticSection());
|
|
9295
|
+
}
|
|
9173
9296
|
return sections.join(`
|
|
9174
9297
|
|
|
9175
9298
|
---
|
|
@@ -9297,7 +9420,7 @@ ${claudeMdSection}
|
|
|
9297
9420
|
6. If confirmed: \`reap run start --type embryo --goal "<goal>"\`
|
|
9298
9421
|
`;
|
|
9299
9422
|
}
|
|
9300
|
-
async function
|
|
9423
|
+
async function execute2(paths, projectName) {
|
|
9301
9424
|
const config = await initCommon(paths, projectName);
|
|
9302
9425
|
await writeTextFile(paths.application, DEFAULT_APPLICATION);
|
|
9303
9426
|
await writeTextFile(paths.environmentSummary, `# ${config.project} Environment
|
|
@@ -9327,10 +9450,10 @@ init_common();
|
|
|
9327
9450
|
// src/core/scanner.ts
|
|
9328
9451
|
init_fs();
|
|
9329
9452
|
import { readdir as readdir3, stat as stat2 } from "fs/promises";
|
|
9330
|
-
import { join as
|
|
9453
|
+
import { join as join6, relative } from "path";
|
|
9331
9454
|
async function scanCodebase(root) {
|
|
9332
9455
|
let packageJson = null;
|
|
9333
|
-
const pkgContent = await readTextFile(
|
|
9456
|
+
const pkgContent = await readTextFile(join6(root, "package.json"));
|
|
9334
9457
|
if (pkgContent) {
|
|
9335
9458
|
try {
|
|
9336
9459
|
packageJson = JSON.parse(pkgContent);
|
|
@@ -9339,7 +9462,7 @@ async function scanCodebase(root) {
|
|
|
9339
9462
|
const deps = Object.keys(packageJson?.dependencies ?? {});
|
|
9340
9463
|
const devDeps = Object.keys(packageJson?.devDependencies ?? {});
|
|
9341
9464
|
const scripts = packageJson?.scripts ?? {};
|
|
9342
|
-
const hasTypeScript = !!await readTextFile(
|
|
9465
|
+
const hasTypeScript = !!await readTextFile(join6(root, "tsconfig.json")) || devDeps.includes("typescript");
|
|
9343
9466
|
const testFrameworks = ["jest", "vitest", "mocha", "@jest/core", "bun:test"];
|
|
9344
9467
|
const testFramework = [...deps, ...devDeps].find((d) => testFrameworks.includes(d)) ?? null;
|
|
9345
9468
|
const hasTests = !!testFramework || scripts.test !== undefined;
|
|
@@ -9347,7 +9470,7 @@ async function scanCodebase(root) {
|
|
|
9347
9470
|
const buildTool = [...deps, ...devDeps].find((d) => buildTools.includes(d)) ?? null;
|
|
9348
9471
|
const tree = await buildTree(root, root, 2);
|
|
9349
9472
|
let readmeExcerpt = null;
|
|
9350
|
-
const readme = await readTextFile(
|
|
9473
|
+
const readme = await readTextFile(join6(root, "README.md"));
|
|
9351
9474
|
if (readme) {
|
|
9352
9475
|
readmeExcerpt = readme.slice(0, 500);
|
|
9353
9476
|
}
|
|
@@ -9381,7 +9504,7 @@ async function buildTree(root, dir, depth) {
|
|
|
9381
9504
|
continue;
|
|
9382
9505
|
if (SKIP_DIRS.has(entry))
|
|
9383
9506
|
continue;
|
|
9384
|
-
const fullPath =
|
|
9507
|
+
const fullPath = join6(dir, entry);
|
|
9385
9508
|
const relPath = relative(root, fullPath);
|
|
9386
9509
|
const s = await stat2(fullPath).catch(() => null);
|
|
9387
9510
|
if (!s)
|
|
@@ -9603,7 +9726,7 @@ ${claudeMdSection}
|
|
|
9603
9726
|
7. If confirmed: \`reap run start --type embryo --goal "<goal>"\`
|
|
9604
9727
|
`;
|
|
9605
9728
|
}
|
|
9606
|
-
async function
|
|
9729
|
+
async function execute3(paths, projectName) {
|
|
9607
9730
|
const scan = await scanCodebase(paths.root);
|
|
9608
9731
|
const name = projectName ?? scan.projectName;
|
|
9609
9732
|
const config = await initCommon(paths, name);
|
|
@@ -9675,14 +9798,14 @@ async function execute2(paths, projectName) {
|
|
|
9675
9798
|
|
|
9676
9799
|
// src/cli/commands/init/repair.ts
|
|
9677
9800
|
init_fs();
|
|
9678
|
-
var
|
|
9801
|
+
var import_yaml5 = __toESM(require_dist(), 1);
|
|
9679
9802
|
init_common();
|
|
9680
|
-
async function
|
|
9803
|
+
async function execute4(paths) {
|
|
9681
9804
|
const configContent = await readTextFile(paths.config);
|
|
9682
9805
|
if (!configContent) {
|
|
9683
9806
|
emitError("init", ".reap/config.yml not found. This is not a reap project. Run 'reap init' first.");
|
|
9684
9807
|
}
|
|
9685
|
-
const config =
|
|
9808
|
+
const config = import_yaml5.default.parse(configContent);
|
|
9686
9809
|
const projectName = config.project ?? "my-project";
|
|
9687
9810
|
const claudeMdAction = await ensureClaudeMd(paths.root, projectName);
|
|
9688
9811
|
const repaired = [];
|
|
@@ -9708,9 +9831,9 @@ async function execute3(paths) {
|
|
|
9708
9831
|
|
|
9709
9832
|
// src/cli/commands/migrate.ts
|
|
9710
9833
|
init_fs();
|
|
9711
|
-
var
|
|
9834
|
+
var import_yaml6 = __toESM(require_dist(), 1);
|
|
9712
9835
|
import { readdir as readdir4, cp, rename, rm as rm2 } from "fs/promises";
|
|
9713
|
-
import { join as
|
|
9836
|
+
import { join as join7, dirname as dirname4 } from "path";
|
|
9714
9837
|
import { execSync as execSync2 } from "child_process";
|
|
9715
9838
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9716
9839
|
import { homedir as homedir2 } from "os";
|
|
@@ -9907,7 +10030,7 @@ init_integrity();
|
|
|
9907
10030
|
init_common();
|
|
9908
10031
|
function distPath2(...segments) {
|
|
9909
10032
|
const __dirname2 = dirname4(fileURLToPath2(import.meta.url));
|
|
9910
|
-
return
|
|
10033
|
+
return join7(__dirname2, "..", "templates", ...segments);
|
|
9911
10034
|
}
|
|
9912
10035
|
function isGitClean(cwd) {
|
|
9913
10036
|
if (!isGitRepo(cwd))
|
|
@@ -9928,14 +10051,14 @@ async function loadMigrationState(paths) {
|
|
|
9928
10051
|
if (!content)
|
|
9929
10052
|
return null;
|
|
9930
10053
|
try {
|
|
9931
|
-
return
|
|
10054
|
+
return import_yaml6.default.parse(content);
|
|
9932
10055
|
} catch {
|
|
9933
10056
|
return null;
|
|
9934
10057
|
}
|
|
9935
10058
|
}
|
|
9936
10059
|
async function saveMigrationState(paths, state) {
|
|
9937
10060
|
state.updatedAt = new Date().toISOString();
|
|
9938
|
-
await writeTextFile(paths.migrationState,
|
|
10061
|
+
await writeTextFile(paths.migrationState, import_yaml6.default.stringify(state));
|
|
9939
10062
|
}
|
|
9940
10063
|
async function clearMigrationState(paths) {
|
|
9941
10064
|
if (await fileExists(paths.migrationState)) {
|
|
@@ -9983,7 +10106,7 @@ function mapHookFilename(filename) {
|
|
|
9983
10106
|
}
|
|
9984
10107
|
async function scanV15Structure(paths) {
|
|
9985
10108
|
const genomeFiles = [];
|
|
9986
|
-
const genomeDir =
|
|
10109
|
+
const genomeDir = join7(paths.reap, "v15", "genome");
|
|
9987
10110
|
const currentGenomeDir = paths.genome;
|
|
9988
10111
|
try {
|
|
9989
10112
|
const entries = await readdir4(currentGenomeDir);
|
|
@@ -9993,7 +10116,7 @@ async function scanV15Structure(paths) {
|
|
|
9993
10116
|
}
|
|
9994
10117
|
} catch {}
|
|
9995
10118
|
const domainFiles = [];
|
|
9996
|
-
const domainDir =
|
|
10119
|
+
const domainDir = join7(currentGenomeDir, "domain");
|
|
9997
10120
|
try {
|
|
9998
10121
|
const entries = await readdir4(domainDir);
|
|
9999
10122
|
for (const e of entries) {
|
|
@@ -10063,14 +10186,14 @@ async function executePreCheck(paths) {
|
|
|
10063
10186
|
if (currentContent && currentContent.trim()) {
|
|
10064
10187
|
emitError("migrate", "Active generation exists. Run '/reap.abort' first, then retry migration.");
|
|
10065
10188
|
}
|
|
10066
|
-
if (await fileExists(
|
|
10189
|
+
if (await fileExists(join7(paths.reap, "v15"))) {
|
|
10067
10190
|
emitError("migrate", "Previous migration backup (.reap/v15/) already exists. Remove it first if you want to re-migrate.");
|
|
10068
10191
|
}
|
|
10069
10192
|
const configContent = await readTextFile(paths.config);
|
|
10070
10193
|
let config = {};
|
|
10071
10194
|
if (configContent) {
|
|
10072
10195
|
try {
|
|
10073
|
-
config =
|
|
10196
|
+
config = import_yaml6.default.parse(configContent) ?? {};
|
|
10074
10197
|
} catch {
|
|
10075
10198
|
emitError("migrate", "config.yml is not valid YAML.");
|
|
10076
10199
|
}
|
|
@@ -10155,7 +10278,7 @@ async function executeMain(paths) {
|
|
|
10155
10278
|
let state = await loadMigrationState(paths);
|
|
10156
10279
|
if (!state) {
|
|
10157
10280
|
if (!await detectV15(paths)) {
|
|
10158
|
-
if (!await fileExists(
|
|
10281
|
+
if (!await fileExists(join7(paths.reap, "v15"))) {
|
|
10159
10282
|
emitError("migrate", "v0.15 structure not found. Cannot proceed.");
|
|
10160
10283
|
}
|
|
10161
10284
|
}
|
|
@@ -10163,7 +10286,7 @@ async function executeMain(paths) {
|
|
|
10163
10286
|
await saveMigrationState(paths, state);
|
|
10164
10287
|
}
|
|
10165
10288
|
const done = new Set(state.completedSteps);
|
|
10166
|
-
const v15Dir =
|
|
10289
|
+
const v15Dir = join7(paths.reap, "v15");
|
|
10167
10290
|
async function step(name, fn) {
|
|
10168
10291
|
if (done.has(name))
|
|
10169
10292
|
return;
|
|
@@ -10174,12 +10297,12 @@ async function executeMain(paths) {
|
|
|
10174
10297
|
await step("backup", async () => {
|
|
10175
10298
|
await ensureDir(v15Dir);
|
|
10176
10299
|
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:
|
|
10300
|
+
{ src: paths.genome, dest: join7(v15Dir, "genome") },
|
|
10301
|
+
{ src: paths.environment, dest: join7(v15Dir, "environment") },
|
|
10302
|
+
{ src: paths.life, dest: join7(v15Dir, "life") },
|
|
10303
|
+
{ src: paths.lineage, dest: join7(v15Dir, "lineage") },
|
|
10304
|
+
{ src: paths.hooks, dest: join7(v15Dir, "hooks") },
|
|
10305
|
+
{ src: paths.config, dest: join7(v15Dir, "config.yml") }
|
|
10183
10306
|
];
|
|
10184
10307
|
for (const item of backupItems) {
|
|
10185
10308
|
if (await fileExists(item.src)) {
|
|
@@ -10189,7 +10312,7 @@ async function executeMain(paths) {
|
|
|
10189
10312
|
});
|
|
10190
10313
|
await step("create-dirs", async () => {
|
|
10191
10314
|
await ensureDir(paths.genome);
|
|
10192
|
-
await ensureDir(
|
|
10315
|
+
await ensureDir(join7(paths.environment, "domain"));
|
|
10193
10316
|
await ensureDir(paths.environmentResources);
|
|
10194
10317
|
await ensureDir(paths.environmentDocs);
|
|
10195
10318
|
await ensureDir(paths.life);
|
|
@@ -10197,7 +10320,7 @@ async function executeMain(paths) {
|
|
|
10197
10320
|
await ensureDir(paths.lineage);
|
|
10198
10321
|
await ensureDir(paths.vision);
|
|
10199
10322
|
await ensureDir(paths.visionDesign);
|
|
10200
|
-
await ensureDir(
|
|
10323
|
+
await ensureDir(join7(paths.vision, "memory"));
|
|
10201
10324
|
await ensureDir(paths.hooks);
|
|
10202
10325
|
});
|
|
10203
10326
|
let v16Config = {
|
|
@@ -10211,10 +10334,10 @@ async function executeMain(paths) {
|
|
|
10211
10334
|
autoIssueReport: true
|
|
10212
10335
|
};
|
|
10213
10336
|
await step("config-migrate", async () => {
|
|
10214
|
-
const v15ConfigContent = await readTextFile(
|
|
10337
|
+
const v15ConfigContent = await readTextFile(join7(v15Dir, "config.yml"));
|
|
10215
10338
|
let v15Config = {};
|
|
10216
10339
|
if (v15ConfigContent) {
|
|
10217
|
-
v15Config =
|
|
10340
|
+
v15Config = import_yaml6.default.parse(v15ConfigContent) ?? {};
|
|
10218
10341
|
}
|
|
10219
10342
|
const wasStrict = v15Config.strict ?? false;
|
|
10220
10343
|
v16Config = {
|
|
@@ -10227,55 +10350,55 @@ async function executeMain(paths) {
|
|
|
10227
10350
|
autoUpdate: v15Config.autoUpdate ?? true,
|
|
10228
10351
|
autoIssueReport: v15Config.autoIssueReport ?? true
|
|
10229
10352
|
};
|
|
10230
|
-
await writeTextFile(paths.config,
|
|
10353
|
+
await writeTextFile(paths.config, import_yaml6.default.stringify(v16Config));
|
|
10231
10354
|
});
|
|
10232
10355
|
if (done.has("config-migrate")) {
|
|
10233
10356
|
const existingConfig = await readTextFile(paths.config);
|
|
10234
10357
|
if (existingConfig) {
|
|
10235
|
-
const parsed =
|
|
10358
|
+
const parsed = import_yaml6.default.parse(existingConfig) ?? {};
|
|
10236
10359
|
v16Config = { ...v16Config, ...parsed };
|
|
10237
10360
|
}
|
|
10238
10361
|
}
|
|
10239
|
-
const principles = await readTextFile(
|
|
10240
|
-
const conventions = await readTextFile(
|
|
10241
|
-
const constraints = await readTextFile(
|
|
10242
|
-
const sourceMap = await readTextFile(
|
|
10362
|
+
const principles = await readTextFile(join7(v15Dir, "genome", "principles.md")) ?? "";
|
|
10363
|
+
const conventions = await readTextFile(join7(v15Dir, "genome", "conventions.md")) ?? "";
|
|
10364
|
+
const constraints = await readTextFile(join7(v15Dir, "genome", "constraints.md")) ?? "";
|
|
10365
|
+
const sourceMap = await readTextFile(join7(v15Dir, "genome", "source-map.md")) ?? "";
|
|
10243
10366
|
const evolutionTemplate = await readTextFile(distPath2("evolution.md")) ?? "";
|
|
10244
10367
|
const domainFiles = [];
|
|
10245
|
-
const v15DomainDir =
|
|
10368
|
+
const v15DomainDir = join7(v15Dir, "genome", "domain");
|
|
10246
10369
|
try {
|
|
10247
10370
|
const entries = await readdir4(v15DomainDir);
|
|
10248
10371
|
domainFiles.push(...entries.filter((e) => e.endsWith(".md")));
|
|
10249
10372
|
} catch {}
|
|
10250
10373
|
await step("environment-copy", async () => {
|
|
10251
|
-
const v15EnvSummary =
|
|
10374
|
+
const v15EnvSummary = join7(v15Dir, "environment", "summary.md");
|
|
10252
10375
|
if (await fileExists(v15EnvSummary)) {
|
|
10253
10376
|
await cp(v15EnvSummary, paths.environmentSummary);
|
|
10254
10377
|
}
|
|
10255
|
-
const v15EnvDomain =
|
|
10378
|
+
const v15EnvDomain = join7(v15Dir, "environment", "domain");
|
|
10256
10379
|
if (await fileExists(v15EnvDomain)) {
|
|
10257
10380
|
try {
|
|
10258
10381
|
const entries = await readdir4(v15EnvDomain);
|
|
10259
10382
|
for (const e of entries) {
|
|
10260
|
-
await cp(
|
|
10383
|
+
await cp(join7(v15EnvDomain, e), join7(paths.environmentDomain, e), { recursive: true });
|
|
10261
10384
|
}
|
|
10262
10385
|
} catch {}
|
|
10263
10386
|
}
|
|
10264
|
-
const v15EnvResources =
|
|
10387
|
+
const v15EnvResources = join7(v15Dir, "environment", "resources");
|
|
10265
10388
|
if (await fileExists(v15EnvResources)) {
|
|
10266
10389
|
try {
|
|
10267
10390
|
const entries = await readdir4(v15EnvResources);
|
|
10268
10391
|
for (const e of entries) {
|
|
10269
|
-
await cp(
|
|
10392
|
+
await cp(join7(v15EnvResources, e), join7(paths.environmentResources, e), { recursive: true });
|
|
10270
10393
|
}
|
|
10271
10394
|
} catch {}
|
|
10272
10395
|
}
|
|
10273
|
-
const v15EnvDocs =
|
|
10396
|
+
const v15EnvDocs = join7(v15Dir, "environment", "docs");
|
|
10274
10397
|
if (await fileExists(v15EnvDocs)) {
|
|
10275
10398
|
try {
|
|
10276
10399
|
const entries = await readdir4(v15EnvDocs);
|
|
10277
10400
|
for (const e of entries) {
|
|
10278
|
-
await cp(
|
|
10401
|
+
await cp(join7(v15EnvDocs, e), join7(paths.environmentDocs, e), { recursive: true });
|
|
10279
10402
|
}
|
|
10280
10403
|
} catch {}
|
|
10281
10404
|
}
|
|
@@ -10284,8 +10407,8 @@ async function executeMain(paths) {
|
|
|
10284
10407
|
}
|
|
10285
10408
|
if (domainFiles.length > 0) {
|
|
10286
10409
|
for (const f of domainFiles) {
|
|
10287
|
-
const src =
|
|
10288
|
-
const dest =
|
|
10410
|
+
const src = join7(v15DomainDir, f);
|
|
10411
|
+
const dest = join7(paths.environmentDomain, f);
|
|
10289
10412
|
if (await fileExists(src)) {
|
|
10290
10413
|
await cp(src, dest);
|
|
10291
10414
|
}
|
|
@@ -10293,23 +10416,23 @@ async function executeMain(paths) {
|
|
|
10293
10416
|
}
|
|
10294
10417
|
});
|
|
10295
10418
|
await step("lineage-copy", async () => {
|
|
10296
|
-
const v15Lineage =
|
|
10419
|
+
const v15Lineage = join7(v15Dir, "lineage");
|
|
10297
10420
|
if (await fileExists(v15Lineage)) {
|
|
10298
10421
|
try {
|
|
10299
10422
|
const entries = await readdir4(v15Lineage);
|
|
10300
10423
|
for (const e of entries) {
|
|
10301
|
-
await cp(
|
|
10424
|
+
await cp(join7(v15Lineage, e), join7(paths.lineage, e), { recursive: true });
|
|
10302
10425
|
}
|
|
10303
10426
|
} catch {}
|
|
10304
10427
|
}
|
|
10305
10428
|
});
|
|
10306
10429
|
await step("backlog-copy", async () => {
|
|
10307
|
-
const v15Backlog =
|
|
10430
|
+
const v15Backlog = join7(v15Dir, "life", "backlog");
|
|
10308
10431
|
if (await fileExists(v15Backlog)) {
|
|
10309
10432
|
try {
|
|
10310
10433
|
const entries = await readdir4(v15Backlog);
|
|
10311
10434
|
for (const e of entries) {
|
|
10312
|
-
await cp(
|
|
10435
|
+
await cp(join7(v15Backlog, e), join7(paths.backlog, e), { recursive: true });
|
|
10313
10436
|
}
|
|
10314
10437
|
} catch {}
|
|
10315
10438
|
}
|
|
@@ -10317,20 +10440,20 @@ async function executeMain(paths) {
|
|
|
10317
10440
|
const hooksMapped = [];
|
|
10318
10441
|
const hooksUnmapped = [];
|
|
10319
10442
|
await step("hooks-map", async () => {
|
|
10320
|
-
const v15Hooks =
|
|
10443
|
+
const v15Hooks = join7(v15Dir, "hooks");
|
|
10321
10444
|
if (await fileExists(v15Hooks)) {
|
|
10322
10445
|
try {
|
|
10323
10446
|
const entries = await readdir4(v15Hooks);
|
|
10324
10447
|
for (const e of entries) {
|
|
10325
10448
|
if (e === "conditions") {
|
|
10326
|
-
const condSrc =
|
|
10327
|
-
const condDest =
|
|
10449
|
+
const condSrc = join7(v15Hooks, "conditions");
|
|
10450
|
+
const condDest = join7(paths.hooks, "conditions");
|
|
10328
10451
|
await cp(condSrc, condDest, { recursive: true });
|
|
10329
10452
|
continue;
|
|
10330
10453
|
}
|
|
10331
10454
|
const mapping = mapHookFilename(e);
|
|
10332
10455
|
if (mapping) {
|
|
10333
|
-
await cp(
|
|
10456
|
+
await cp(join7(v15Hooks, e), join7(paths.hooks, mapping.newName));
|
|
10334
10457
|
if (mapping.newName !== e) {
|
|
10335
10458
|
hooksMapped.push(`${e} → ${mapping.newName}`);
|
|
10336
10459
|
}
|
|
@@ -10338,7 +10461,7 @@ async function executeMain(paths) {
|
|
|
10338
10461
|
hooksUnmapped.push(e);
|
|
10339
10462
|
}
|
|
10340
10463
|
} else {
|
|
10341
|
-
await cp(
|
|
10464
|
+
await cp(join7(v15Hooks, e), join7(paths.hooks, e));
|
|
10342
10465
|
}
|
|
10343
10466
|
}
|
|
10344
10467
|
} catch {}
|
|
@@ -10358,20 +10481,20 @@ async function executeMain(paths) {
|
|
|
10358
10481
|
## Goal Items
|
|
10359
10482
|
<!-- Checklist of major milestones -->
|
|
10360
10483
|
`;
|
|
10361
|
-
await writeTextFile(
|
|
10362
|
-
await writeTextFile(
|
|
10484
|
+
await writeTextFile(join7(paths.vision, "goals.md"), goalsContent);
|
|
10485
|
+
await writeTextFile(join7(paths.vision, "memory", "longterm.md"), `# Longterm Memory
|
|
10363
10486
|
`);
|
|
10364
|
-
await writeTextFile(
|
|
10487
|
+
await writeTextFile(join7(paths.vision, "memory", "midterm.md"), `# Midterm Memory
|
|
10365
10488
|
`);
|
|
10366
|
-
await writeTextFile(
|
|
10489
|
+
await writeTextFile(join7(paths.vision, "memory", "shortterm.md"), `# Shortterm Memory
|
|
10367
10490
|
`);
|
|
10368
10491
|
});
|
|
10369
10492
|
await step("reap-guide", async () => {
|
|
10370
10493
|
const guide = await readTextFile(distPath2("reap-guide.md"));
|
|
10371
10494
|
if (guide) {
|
|
10372
|
-
const reapHome =
|
|
10495
|
+
const reapHome = join7(homedir2(), ".reap");
|
|
10373
10496
|
await ensureDir(reapHome);
|
|
10374
|
-
await writeTextFile(
|
|
10497
|
+
await writeTextFile(join7(reapHome, "reap-guide.md"), guide);
|
|
10375
10498
|
}
|
|
10376
10499
|
});
|
|
10377
10500
|
await step("claude-md", async () => {
|
|
@@ -10567,7 +10690,7 @@ async function executeComplete(paths) {
|
|
|
10567
10690
|
message: `Migration complete. Backup preserved at .reap/v15/. Run 'reap status' to verify.`
|
|
10568
10691
|
});
|
|
10569
10692
|
}
|
|
10570
|
-
async function
|
|
10693
|
+
async function execute5(paths, phase) {
|
|
10571
10694
|
switch (phase) {
|
|
10572
10695
|
case undefined:
|
|
10573
10696
|
case "confirm":
|
|
@@ -10611,12 +10734,12 @@ var PROJECT_FILES = [
|
|
|
10611
10734
|
var SOURCE_GLOBS = [".ts", ".js", ".py", ".rs", ".go", ".java", ".rb", ".php", ".swift", ".kt"];
|
|
10612
10735
|
async function detectMode(root) {
|
|
10613
10736
|
for (const file of PROJECT_FILES) {
|
|
10614
|
-
if (await fileExists(
|
|
10737
|
+
if (await fileExists(join8(root, file))) {
|
|
10615
10738
|
return "adoption";
|
|
10616
10739
|
}
|
|
10617
10740
|
}
|
|
10618
10741
|
for (const dir of SOURCE_DIRS) {
|
|
10619
|
-
if (await fileExists(
|
|
10742
|
+
if (await fileExists(join8(root, dir))) {
|
|
10620
10743
|
return "adoption";
|
|
10621
10744
|
}
|
|
10622
10745
|
}
|
|
@@ -10636,18 +10759,18 @@ async function detectMode(root) {
|
|
|
10636
10759
|
}
|
|
10637
10760
|
return "greenfield";
|
|
10638
10761
|
}
|
|
10639
|
-
async function
|
|
10762
|
+
async function execute6(projectName, mode, repair, migrate, phase) {
|
|
10640
10763
|
const root = process.cwd();
|
|
10641
10764
|
const paths = createPaths(root);
|
|
10642
10765
|
if (migrate) {
|
|
10643
|
-
await
|
|
10766
|
+
await execute5(paths, phase);
|
|
10644
10767
|
return;
|
|
10645
10768
|
}
|
|
10646
10769
|
if (repair) {
|
|
10647
10770
|
if (!await fileExists(paths.config)) {
|
|
10648
10771
|
emitError("init", ".reap/ not found. This is not a reap project. Run 'reap init' first.");
|
|
10649
10772
|
}
|
|
10650
|
-
await
|
|
10773
|
+
await execute4(paths);
|
|
10651
10774
|
return;
|
|
10652
10775
|
}
|
|
10653
10776
|
if (await fileExists(paths.config)) {
|
|
@@ -10655,18 +10778,18 @@ async function execute5(projectName, mode, repair, migrate, phase) {
|
|
|
10655
10778
|
}
|
|
10656
10779
|
const resolvedMode = mode ?? await detectMode(root);
|
|
10657
10780
|
if (resolvedMode === "adoption") {
|
|
10658
|
-
await
|
|
10781
|
+
await execute3(paths, projectName);
|
|
10659
10782
|
} else {
|
|
10660
|
-
await
|
|
10783
|
+
await execute2(paths, projectName ?? "my-project");
|
|
10661
10784
|
}
|
|
10662
10785
|
}
|
|
10663
10786
|
|
|
10664
10787
|
// src/cli/commands/status.ts
|
|
10665
|
-
var
|
|
10788
|
+
var import_yaml7 = __toESM(require_dist(), 1);
|
|
10666
10789
|
import { readdir as readdir6 } from "fs/promises";
|
|
10667
10790
|
init_fs();
|
|
10668
10791
|
init_integrity();
|
|
10669
|
-
async function
|
|
10792
|
+
async function execute7() {
|
|
10670
10793
|
const root = process.cwd();
|
|
10671
10794
|
const paths = createPaths(root);
|
|
10672
10795
|
if (!await fileExists(paths.config)) {
|
|
@@ -10676,11 +10799,11 @@ async function execute6() {
|
|
|
10676
10799
|
emitError("status", "This project uses REAP v0.15 structure. Run '/reap.update' to upgrade to v0.16.");
|
|
10677
10800
|
}
|
|
10678
10801
|
const configContent = await readTextFile(paths.config);
|
|
10679
|
-
const config = configContent ?
|
|
10802
|
+
const config = configContent ? import_yaml7.default.parse(configContent) : null;
|
|
10680
10803
|
let generation = null;
|
|
10681
10804
|
const currentContent = await readTextFile(paths.current);
|
|
10682
10805
|
if (currentContent) {
|
|
10683
|
-
generation =
|
|
10806
|
+
generation = import_yaml7.default.parse(currentContent);
|
|
10684
10807
|
}
|
|
10685
10808
|
let completedGenerations = 0;
|
|
10686
10809
|
try {
|
|
@@ -10714,7 +10837,7 @@ async function execute6() {
|
|
|
10714
10837
|
}
|
|
10715
10838
|
|
|
10716
10839
|
// src/cli/commands/run/index.ts
|
|
10717
|
-
var
|
|
10840
|
+
var import_yaml22 = __toESM(require_dist(), 1);
|
|
10718
10841
|
init_fs();
|
|
10719
10842
|
init_integrity();
|
|
10720
10843
|
|
|
@@ -10742,11 +10865,12 @@ function autoReport(command, error, extraLabels) {
|
|
|
10742
10865
|
}
|
|
10743
10866
|
|
|
10744
10867
|
// src/cli/commands/run/start.ts
|
|
10745
|
-
|
|
10868
|
+
var import_yaml12 = __toESM(require_dist(), 1);
|
|
10869
|
+
import { basename, join as join13 } from "path";
|
|
10746
10870
|
|
|
10747
10871
|
// src/core/generation.ts
|
|
10748
10872
|
init_fs();
|
|
10749
|
-
var
|
|
10873
|
+
var import_yaml8 = __toESM(require_dist(), 1);
|
|
10750
10874
|
import { createHash as createHash3 } from "crypto";
|
|
10751
10875
|
import { hostname } from "os";
|
|
10752
10876
|
import { readdir as readdir7 } from "fs/promises";
|
|
@@ -10774,12 +10898,12 @@ class GenerationManager {
|
|
|
10774
10898
|
const content = await readTextFile(this.paths.current);
|
|
10775
10899
|
if (!content)
|
|
10776
10900
|
return null;
|
|
10777
|
-
return
|
|
10901
|
+
return import_yaml8.default.parse(content);
|
|
10778
10902
|
}
|
|
10779
10903
|
async save(state) {
|
|
10780
10904
|
const header = `# REAP MANAGED — Do not modify directly.
|
|
10781
10905
|
`;
|
|
10782
|
-
await writeTextFile(this.paths.current, header +
|
|
10906
|
+
await writeTextFile(this.paths.current, header + import_yaml8.default.stringify(state));
|
|
10783
10907
|
}
|
|
10784
10908
|
async create(goal, type = "embryo") {
|
|
10785
10909
|
await ensureDir(this.paths.life);
|
|
@@ -10858,15 +10982,15 @@ init_fs();
|
|
|
10858
10982
|
|
|
10859
10983
|
// src/core/hooks.ts
|
|
10860
10984
|
init_fs();
|
|
10861
|
-
var
|
|
10985
|
+
var import_yaml9 = __toESM(require_dist(), 1);
|
|
10862
10986
|
import { readdir as readdir8 } from "fs/promises";
|
|
10863
|
-
import { join as
|
|
10987
|
+
import { join as join9 } from "path";
|
|
10864
10988
|
import { execSync as execSync4 } from "child_process";
|
|
10865
10989
|
async function executeHooks(hooksDir, event, projectRoot) {
|
|
10866
10990
|
const hooks = await scanHooks(hooksDir, event);
|
|
10867
10991
|
if (hooks.length === 0)
|
|
10868
10992
|
return [];
|
|
10869
|
-
const conditionsDir =
|
|
10993
|
+
const conditionsDir = join9(hooksDir, "conditions");
|
|
10870
10994
|
const results = [];
|
|
10871
10995
|
for (const hook of hooks) {
|
|
10872
10996
|
const conditionMet = await evaluateCondition(conditionsDir, hook.condition, projectRoot);
|
|
@@ -10901,7 +11025,7 @@ async function scanHooks(hooksDir, event) {
|
|
|
10901
11025
|
const match = filename.match(pattern);
|
|
10902
11026
|
if (!match)
|
|
10903
11027
|
continue;
|
|
10904
|
-
const meta = await parseHookMeta(
|
|
11028
|
+
const meta = await parseHookMeta(join9(hooksDir, filename), match[2]);
|
|
10905
11029
|
hooks.push({
|
|
10906
11030
|
filename,
|
|
10907
11031
|
name: match[1],
|
|
@@ -10922,7 +11046,7 @@ async function parseHookMeta(filePath, ext) {
|
|
|
10922
11046
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
10923
11047
|
if (fmMatch) {
|
|
10924
11048
|
try {
|
|
10925
|
-
const fm =
|
|
11049
|
+
const fm = import_yaml9.default.parse(fmMatch[1]) ?? {};
|
|
10926
11050
|
return {
|
|
10927
11051
|
condition: String(fm.condition ?? "always"),
|
|
10928
11052
|
order: Number(fm.order ?? 50)
|
|
@@ -10948,7 +11072,7 @@ async function parseHookMeta(filePath, ext) {
|
|
|
10948
11072
|
async function evaluateCondition(conditionsDir, conditionName, projectRoot) {
|
|
10949
11073
|
if (conditionName === "always")
|
|
10950
11074
|
return { met: true };
|
|
10951
|
-
const scriptPath =
|
|
11075
|
+
const scriptPath = join9(conditionsDir, `${conditionName}.sh`);
|
|
10952
11076
|
if (!await fileExists(scriptPath)) {
|
|
10953
11077
|
return { met: false, reason: `condition script not found: ${conditionName}.sh` };
|
|
10954
11078
|
}
|
|
@@ -10961,7 +11085,7 @@ async function evaluateCondition(conditionsDir, conditionName, projectRoot) {
|
|
|
10961
11085
|
}
|
|
10962
11086
|
async function executeShHook(hook, event, projectRoot, hooksDir) {
|
|
10963
11087
|
try {
|
|
10964
|
-
const stdout = execSync4(`bash "${
|
|
11088
|
+
const stdout = execSync4(`bash "${join9(hooksDir, hook.filename)}"`, {
|
|
10965
11089
|
cwd: projectRoot,
|
|
10966
11090
|
timeout: 60000,
|
|
10967
11091
|
stdio: "pipe"
|
|
@@ -10987,7 +11111,7 @@ async function executeShHook(hook, event, projectRoot, hooksDir) {
|
|
|
10987
11111
|
}
|
|
10988
11112
|
}
|
|
10989
11113
|
async function executeMdHook(hook, event, hooksDir) {
|
|
10990
|
-
const content = await readTextFile(
|
|
11114
|
+
const content = await readTextFile(join9(hooksDir, hook.filename));
|
|
10991
11115
|
const body = content?.replace(/^---\n[\s\S]*?\n---\n?/, "").trim() ?? "";
|
|
10992
11116
|
return {
|
|
10993
11117
|
name: hook.name,
|
|
@@ -11000,9 +11124,9 @@ async function executeMdHook(hook, event, hooksDir) {
|
|
|
11000
11124
|
|
|
11001
11125
|
// src/core/backlog.ts
|
|
11002
11126
|
init_fs();
|
|
11003
|
-
var
|
|
11127
|
+
var import_yaml10 = __toESM(require_dist(), 1);
|
|
11004
11128
|
import { readdir as readdir9 } from "fs/promises";
|
|
11005
|
-
import { join as
|
|
11129
|
+
import { join as join10 } from "path";
|
|
11006
11130
|
async function scanBacklog(backlogDir) {
|
|
11007
11131
|
let entries;
|
|
11008
11132
|
try {
|
|
@@ -11014,7 +11138,7 @@ async function scanBacklog(backlogDir) {
|
|
|
11014
11138
|
for (const entry of entries) {
|
|
11015
11139
|
if (!entry.endsWith(".md"))
|
|
11016
11140
|
continue;
|
|
11017
|
-
const filePath =
|
|
11141
|
+
const filePath = join10(backlogDir, entry);
|
|
11018
11142
|
const content = await readTextFile(filePath);
|
|
11019
11143
|
if (!content)
|
|
11020
11144
|
continue;
|
|
@@ -11045,7 +11169,7 @@ async function consumeBacklog(filePath, genId) {
|
|
|
11045
11169
|
const fmRaw = fmMatch[1];
|
|
11046
11170
|
let parsed = {};
|
|
11047
11171
|
try {
|
|
11048
|
-
parsed =
|
|
11172
|
+
parsed = import_yaml10.default.parse(fmRaw) ?? {};
|
|
11049
11173
|
} catch {
|
|
11050
11174
|
return { status: "warning", warning: `${filePath}: malformed YAML frontmatter — backlog not marked` };
|
|
11051
11175
|
}
|
|
@@ -11157,7 +11281,7 @@ ${body}
|
|
|
11157
11281
|
`;
|
|
11158
11282
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
11159
11283
|
await mkdir3(backlogDir, { recursive: true });
|
|
11160
|
-
await writeTextFile(
|
|
11284
|
+
await writeTextFile(join10(backlogDir, filename), content);
|
|
11161
11285
|
return filename;
|
|
11162
11286
|
}
|
|
11163
11287
|
async function createDeferredBacklog(backlogDir, input) {
|
|
@@ -11187,7 +11311,7 @@ ${tasksSection}
|
|
|
11187
11311
|
`;
|
|
11188
11312
|
const { mkdir: mkdir3 } = await import("fs/promises");
|
|
11189
11313
|
await mkdir3(backlogDir, { recursive: true });
|
|
11190
|
-
await writeTextFile(
|
|
11314
|
+
await writeTextFile(join10(backlogDir, filename), content);
|
|
11191
11315
|
return filename;
|
|
11192
11316
|
}
|
|
11193
11317
|
function extractUncheckedTasks(artifactContent) {
|
|
@@ -11208,9 +11332,9 @@ function countCheckedTasks(artifactContent) {
|
|
|
11208
11332
|
|
|
11209
11333
|
// src/core/lineage.ts
|
|
11210
11334
|
init_fs();
|
|
11211
|
-
var
|
|
11335
|
+
var import_yaml11 = __toESM(require_dist(), 1);
|
|
11212
11336
|
import { readdir as readdir10, stat as stat3 } from "fs/promises";
|
|
11213
|
-
import { join as
|
|
11337
|
+
import { join as join11 } from "path";
|
|
11214
11338
|
import { execSync as execSync5 } from "child_process";
|
|
11215
11339
|
function gitShow(cwd, ref, path) {
|
|
11216
11340
|
try {
|
|
@@ -11271,7 +11395,7 @@ async function getLastLineageEntry(paths) {
|
|
|
11271
11395
|
if (genEntries.length === 0)
|
|
11272
11396
|
return null;
|
|
11273
11397
|
const last = genEntries[genEntries.length - 1];
|
|
11274
|
-
const lastPath =
|
|
11398
|
+
const lastPath = join11(paths.lineage, last);
|
|
11275
11399
|
try {
|
|
11276
11400
|
const st = await stat3(lastPath);
|
|
11277
11401
|
if (!st.isDirectory())
|
|
@@ -11279,12 +11403,12 @@ async function getLastLineageEntry(paths) {
|
|
|
11279
11403
|
} catch {
|
|
11280
11404
|
return null;
|
|
11281
11405
|
}
|
|
11282
|
-
const metaContent = await readTextFile(
|
|
11406
|
+
const metaContent = await readTextFile(join11(lastPath, "meta.yml"));
|
|
11283
11407
|
if (!metaContent)
|
|
11284
11408
|
return null;
|
|
11285
11409
|
let parsed;
|
|
11286
11410
|
try {
|
|
11287
|
-
parsed =
|
|
11411
|
+
parsed = import_yaml11.default.parse(metaContent) ?? {};
|
|
11288
11412
|
} catch {
|
|
11289
11413
|
return null;
|
|
11290
11414
|
}
|
|
@@ -11308,7 +11432,7 @@ async function getLastLineageEntry(paths) {
|
|
|
11308
11432
|
}
|
|
11309
11433
|
|
|
11310
11434
|
// src/cli/commands/run/start.ts
|
|
11311
|
-
async function
|
|
11435
|
+
async function execute8(phase, goal, type, parents, backlog) {
|
|
11312
11436
|
const paths = createPaths(process.cwd());
|
|
11313
11437
|
if (!await fileExists(paths.config)) {
|
|
11314
11438
|
emitError("start", "Not a reap project. Run 'reap init' first.");
|
|
@@ -11392,7 +11516,6 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11392
11516
|
`),
|
|
11393
11517
|
nextCommand: `reap run start --phase create --goal "${goal}" --backlog <filename>`
|
|
11394
11518
|
});
|
|
11395
|
-
return;
|
|
11396
11519
|
}
|
|
11397
11520
|
}
|
|
11398
11521
|
if (type === "merge") {
|
|
@@ -11423,7 +11546,7 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11423
11546
|
const state = await gm.create(goal, genType);
|
|
11424
11547
|
let consumeWarning;
|
|
11425
11548
|
if (backlogFilename) {
|
|
11426
|
-
const backlogPath =
|
|
11549
|
+
const backlogPath = join13(paths.backlog, backlogFilename);
|
|
11427
11550
|
if (await fileExists(backlogPath)) {
|
|
11428
11551
|
const result = await consumeBacklog(backlogPath, state.id);
|
|
11429
11552
|
if (result.status === "warning" && result.warning) {
|
|
@@ -11436,8 +11559,13 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11436
11559
|
}
|
|
11437
11560
|
}
|
|
11438
11561
|
await executeHooks(paths.hooks, "onLifeStarted", paths.root).catch(() => {});
|
|
11439
|
-
const
|
|
11440
|
-
|
|
11562
|
+
const configContent = await readTextFile(paths.config);
|
|
11563
|
+
const config = configContent ? import_yaml12.default.parse(configContent) : null;
|
|
11564
|
+
if (config?.daemon === true) {
|
|
11565
|
+
const { ensureRegistered: ensureRegistered2, triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
11566
|
+
await ensureRegistered2(paths.root, basename(paths.root));
|
|
11567
|
+
await triggerIndexing2(paths.root);
|
|
11568
|
+
}
|
|
11441
11569
|
const messageLines = [`Generation ${state.id} created. Run: reap run learning`];
|
|
11442
11570
|
if (consumeWarning) {
|
|
11443
11571
|
messageLines.unshift(`[backlog warning] ${consumeWarning}`);
|
|
@@ -11464,8 +11592,9 @@ async function execute7(phase, goal, type, parents, backlog) {
|
|
|
11464
11592
|
|
|
11465
11593
|
// src/cli/commands/run/learning.ts
|
|
11466
11594
|
init_fs();
|
|
11595
|
+
var import_yaml13 = __toESM(require_dist(), 1);
|
|
11467
11596
|
import { readdir as readdir11 } from "fs/promises";
|
|
11468
|
-
import { join as
|
|
11597
|
+
import { basename as basename2, join as join15 } from "path";
|
|
11469
11598
|
|
|
11470
11599
|
// src/core/lifecycle.ts
|
|
11471
11600
|
init_types();
|
|
@@ -11648,7 +11777,7 @@ async function performMergeTransition(state, gm, paths) {
|
|
|
11648
11777
|
|
|
11649
11778
|
// src/core/template.ts
|
|
11650
11779
|
init_fs();
|
|
11651
|
-
import { join as
|
|
11780
|
+
import { join as join14, dirname as dirname5 } from "path";
|
|
11652
11781
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
11653
11782
|
import { copyFile as copyFile2 } from "fs/promises";
|
|
11654
11783
|
var STAGE_ARTIFACTS2 = {
|
|
@@ -11676,7 +11805,7 @@ async function copyArtifactTemplate(stage, artifactPath, isMerge) {
|
|
|
11676
11805
|
return;
|
|
11677
11806
|
const subdir = isMerge ? "merge" : "normal";
|
|
11678
11807
|
const __dirname2 = dirname5(fileURLToPath3(import.meta.url));
|
|
11679
|
-
const templatePath =
|
|
11808
|
+
const templatePath = join14(__dirname2, "..", "templates", "artifacts", subdir, filename);
|
|
11680
11809
|
if (!await fileExists(templatePath))
|
|
11681
11810
|
return;
|
|
11682
11811
|
await ensureDir(dirname5(destPath));
|
|
@@ -11684,7 +11813,7 @@ async function copyArtifactTemplate(stage, artifactPath, isMerge) {
|
|
|
11684
11813
|
}
|
|
11685
11814
|
|
|
11686
11815
|
// src/cli/commands/run/learning.ts
|
|
11687
|
-
async function
|
|
11816
|
+
async function execute9(paths, phase) {
|
|
11688
11817
|
const gm = new GenerationManager(paths);
|
|
11689
11818
|
const state = await gm.current();
|
|
11690
11819
|
if (!state)
|
|
@@ -11701,7 +11830,7 @@ async function execute8(paths, phase) {
|
|
|
11701
11830
|
const envSummary = await readTextFile(paths.environmentSummary);
|
|
11702
11831
|
let sourceBacklogContent = null;
|
|
11703
11832
|
if (s.sourceBacklog) {
|
|
11704
|
-
sourceBacklogContent = await readTextFile(
|
|
11833
|
+
sourceBacklogContent = await readTextFile(join15(paths.backlog, s.sourceBacklog)) ?? await readTextFile(join15(paths.life, "backlog", s.sourceBacklog));
|
|
11705
11834
|
}
|
|
11706
11835
|
const backlogItems = await scanBacklog(paths.backlog);
|
|
11707
11836
|
const pendingBacklog = backlogItems.filter((b) => b.status === "pending");
|
|
@@ -11712,8 +11841,8 @@ async function execute8(paths, phase) {
|
|
|
11712
11841
|
const genDirs = lineageEntries.filter((e) => e.startsWith("gen-")).sort();
|
|
11713
11842
|
if (genDirs.length > 0) {
|
|
11714
11843
|
const lastGen = genDirs[genDirs.length - 1];
|
|
11715
|
-
prevCompletion = await readTextFile(
|
|
11716
|
-
const metaContent = await readTextFile(
|
|
11844
|
+
prevCompletion = await readTextFile(join15(paths.lineage, lastGen, "05-completion.md"));
|
|
11845
|
+
const metaContent = await readTextFile(join15(paths.lineage, lastGen, "meta.yml"));
|
|
11717
11846
|
if (metaContent) {
|
|
11718
11847
|
const fitnessMatch = metaContent.match(/fitnessFeedback:\n\s+text:\s*([\s\S]*?)(?:\n\s+evaluatedAt:|\n[a-z])/);
|
|
11719
11848
|
if (fitnessMatch)
|
|
@@ -11723,6 +11852,16 @@ async function execute8(paths, phase) {
|
|
|
11723
11852
|
} catch {}
|
|
11724
11853
|
setTransitionNonces(s, "learning:entry");
|
|
11725
11854
|
await gm.save(s);
|
|
11855
|
+
const configContent = await readTextFile(paths.config);
|
|
11856
|
+
const config = configContent ? import_yaml13.default.parse(configContent) : null;
|
|
11857
|
+
const daemonEnabled = config?.daemon === true;
|
|
11858
|
+
let daemonReady;
|
|
11859
|
+
if (daemonEnabled) {
|
|
11860
|
+
const { ensureRegistered: ensureRegistered2, triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
11861
|
+
const registered = await ensureRegistered2(paths.root, basename2(paths.root));
|
|
11862
|
+
const indexed = await triggerIndexing2(paths.root);
|
|
11863
|
+
daemonReady = registered && indexed;
|
|
11864
|
+
}
|
|
11726
11865
|
emitOutput({
|
|
11727
11866
|
status: "prompt",
|
|
11728
11867
|
command: "learning",
|
|
@@ -11740,7 +11879,9 @@ async function execute8(paths, phase) {
|
|
|
11740
11879
|
previousFitness: prevFitness,
|
|
11741
11880
|
artifactPath: paths.artifact("01-learning.md"),
|
|
11742
11881
|
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 }))
|
|
11882
|
+
pendingBacklog: pendingBacklog.map((b) => ({ type: b.type, title: b.title, filename: b.filename })),
|
|
11883
|
+
daemonEnabled,
|
|
11884
|
+
...daemonEnabled ? { daemonReady } : {}
|
|
11744
11885
|
},
|
|
11745
11886
|
prompt: [
|
|
11746
11887
|
"## Learning Stage — Explore and Build Context",
|
|
@@ -11798,7 +11939,7 @@ ${pendingBacklog.map((b) => `- [${b.type}] ${b.title} (\`${b.filename}\`)`).join
|
|
|
11798
11939
|
|
|
11799
11940
|
// src/cli/commands/run/planning.ts
|
|
11800
11941
|
init_fs();
|
|
11801
|
-
async function
|
|
11942
|
+
async function execute10(paths, phase) {
|
|
11802
11943
|
const gm = new GenerationManager(paths);
|
|
11803
11944
|
const state = await gm.current();
|
|
11804
11945
|
if (!state)
|
|
@@ -11889,8 +12030,9 @@ async function execute9(paths, phase) {
|
|
|
11889
12030
|
}
|
|
11890
12031
|
|
|
11891
12032
|
// src/cli/commands/run/implementation.ts
|
|
12033
|
+
var import_yaml14 = __toESM(require_dist(), 1);
|
|
11892
12034
|
init_fs();
|
|
11893
|
-
async function
|
|
12035
|
+
async function execute11(paths, phase) {
|
|
11894
12036
|
const gm = new GenerationManager(paths);
|
|
11895
12037
|
const state = await gm.current();
|
|
11896
12038
|
if (!state)
|
|
@@ -11963,6 +12105,12 @@ async function execute10(paths, phase) {
|
|
|
11963
12105
|
prepareStageEntry(s, "validation:entry");
|
|
11964
12106
|
await gm.save(s);
|
|
11965
12107
|
const next = await performTransition(s, gm, paths);
|
|
12108
|
+
const configContent = await readTextFile(paths.config);
|
|
12109
|
+
const config = configContent ? import_yaml14.default.parse(configContent) : null;
|
|
12110
|
+
if (config?.daemon === true) {
|
|
12111
|
+
const { triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
12112
|
+
await triggerIndexing2(paths.root);
|
|
12113
|
+
}
|
|
11966
12114
|
emitOutput({
|
|
11967
12115
|
status: "ok",
|
|
11968
12116
|
command: "implementation",
|
|
@@ -11976,7 +12124,7 @@ async function execute10(paths, phase) {
|
|
|
11976
12124
|
}
|
|
11977
12125
|
|
|
11978
12126
|
// src/cli/commands/run/validation.ts
|
|
11979
|
-
var
|
|
12127
|
+
var import_yaml15 = __toESM(require_dist(), 1);
|
|
11980
12128
|
init_fs();
|
|
11981
12129
|
|
|
11982
12130
|
// src/core/artifact-check.ts
|
|
@@ -12013,7 +12161,7 @@ function isUnfilled(content) {
|
|
|
12013
12161
|
}
|
|
12014
12162
|
|
|
12015
12163
|
// src/cli/commands/run/validation.ts
|
|
12016
|
-
async function
|
|
12164
|
+
async function execute12(paths, phase, extra) {
|
|
12017
12165
|
const gm = new GenerationManager(paths);
|
|
12018
12166
|
const state = await gm.current();
|
|
12019
12167
|
if (!state)
|
|
@@ -12148,7 +12296,7 @@ async function execute11(paths, phase, extra) {
|
|
|
12148
12296
|
"If fail: reap run back to regress"
|
|
12149
12297
|
];
|
|
12150
12298
|
const configContent = await readTextFile(paths.config);
|
|
12151
|
-
const config = configContent ?
|
|
12299
|
+
const config = configContent ? import_yaml15.default.parse(configContent) : null;
|
|
12152
12300
|
const evaluatorEnabled = config?.evaluator === true;
|
|
12153
12301
|
const context = {
|
|
12154
12302
|
id: s.id,
|
|
@@ -12229,15 +12377,15 @@ init_fs();
|
|
|
12229
12377
|
|
|
12230
12378
|
// src/core/archive.ts
|
|
12231
12379
|
init_fs();
|
|
12232
|
-
var
|
|
12233
|
-
import { join as
|
|
12380
|
+
var import_yaml17 = __toESM(require_dist(), 1);
|
|
12381
|
+
import { join as join17 } from "path";
|
|
12234
12382
|
import { readdir as readdir13, rm as rm4, unlink } from "fs/promises";
|
|
12235
12383
|
|
|
12236
12384
|
// src/core/compression.ts
|
|
12237
12385
|
init_fs();
|
|
12238
|
-
var
|
|
12386
|
+
var import_yaml16 = __toESM(require_dist(), 1);
|
|
12239
12387
|
import { readdir as readdir12, rm as rm3 } from "fs/promises";
|
|
12240
|
-
import { join as
|
|
12388
|
+
import { join as join16 } from "path";
|
|
12241
12389
|
var LEVEL1_THRESHOLD = 20;
|
|
12242
12390
|
var PROTECTED_RECENT = 20;
|
|
12243
12391
|
var LEVEL2_THRESHOLD = 100;
|
|
@@ -12254,7 +12402,7 @@ async function compressLineage(lineageDir) {
|
|
|
12254
12402
|
const { stat: stat4 } = await import("fs/promises");
|
|
12255
12403
|
const uncompressed = [];
|
|
12256
12404
|
for (const entry of genDirs) {
|
|
12257
|
-
const s = await stat4(
|
|
12405
|
+
const s = await stat4(join16(lineageDir, entry)).catch(() => null);
|
|
12258
12406
|
if (s?.isDirectory())
|
|
12259
12407
|
uncompressed.push(entry);
|
|
12260
12408
|
}
|
|
@@ -12263,15 +12411,15 @@ async function compressLineage(lineageDir) {
|
|
|
12263
12411
|
return 0;
|
|
12264
12412
|
let compressed = 0;
|
|
12265
12413
|
for (const dirName of toCompress) {
|
|
12266
|
-
const dirPath =
|
|
12267
|
-
const metaContent = await readTextFile(
|
|
12414
|
+
const dirPath = join16(lineageDir, dirName);
|
|
12415
|
+
const metaContent = await readTextFile(join16(dirPath, "meta.yml"));
|
|
12268
12416
|
let meta = { id: dirName, type: "unknown", goal: "", parents: [] };
|
|
12269
12417
|
if (metaContent) {
|
|
12270
12418
|
try {
|
|
12271
|
-
meta =
|
|
12419
|
+
meta = import_yaml16.default.parse(metaContent);
|
|
12272
12420
|
} catch {}
|
|
12273
12421
|
}
|
|
12274
|
-
const completion = await readTextFile(
|
|
12422
|
+
const completion = await readTextFile(join16(dirPath, "05-completion.md")) ?? "";
|
|
12275
12423
|
const summarySection = completion.match(/## Summary\n([\s\S]*?)(?=\n## |\n$)/)?.[1]?.trim() ?? "";
|
|
12276
12424
|
const compressedContent = [
|
|
12277
12425
|
"---",
|
|
@@ -12288,7 +12436,7 @@ async function compressLineage(lineageDir) {
|
|
|
12288
12436
|
""
|
|
12289
12437
|
].filter(Boolean).join(`
|
|
12290
12438
|
`);
|
|
12291
|
-
await writeTextFile(
|
|
12439
|
+
await writeTextFile(join16(lineageDir, `${dirName}.md`), compressedContent);
|
|
12292
12440
|
await rm3(dirPath, { recursive: true, force: true });
|
|
12293
12441
|
compressed++;
|
|
12294
12442
|
}
|
|
@@ -12307,7 +12455,7 @@ async function compressToEpoch(lineageDir) {
|
|
|
12307
12455
|
for (const entry of entries) {
|
|
12308
12456
|
if (!entry.startsWith("gen-") || !entry.endsWith(".md"))
|
|
12309
12457
|
continue;
|
|
12310
|
-
const s = await stat4(
|
|
12458
|
+
const s = await stat4(join16(lineageDir, entry)).catch(() => null);
|
|
12311
12459
|
if (s?.isFile())
|
|
12312
12460
|
level1Files.push(entry);
|
|
12313
12461
|
}
|
|
@@ -12316,14 +12464,14 @@ async function compressToEpoch(lineageDir) {
|
|
|
12316
12464
|
const allParents = new Set;
|
|
12317
12465
|
const fileMetas = [];
|
|
12318
12466
|
for (const file of level1Files.sort()) {
|
|
12319
|
-
const content = await readTextFile(
|
|
12467
|
+
const content = await readTextFile(join16(lineageDir, file));
|
|
12320
12468
|
if (!content)
|
|
12321
12469
|
continue;
|
|
12322
12470
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
12323
12471
|
let meta = { id: file.replace(".md", ""), type: "unknown", goal: "", parents: [] };
|
|
12324
12472
|
if (fmMatch) {
|
|
12325
12473
|
try {
|
|
12326
|
-
const parsed =
|
|
12474
|
+
const parsed = import_yaml16.default.parse(fmMatch[1]);
|
|
12327
12475
|
meta = { ...meta, ...parsed };
|
|
12328
12476
|
} catch {}
|
|
12329
12477
|
}
|
|
@@ -12336,24 +12484,24 @@ async function compressToEpoch(lineageDir) {
|
|
|
12336
12484
|
const dirEntries = entries.filter((e) => e.startsWith("gen-") && !e.endsWith(".md"));
|
|
12337
12485
|
const dirParents = new Set;
|
|
12338
12486
|
for (const dir of dirEntries) {
|
|
12339
|
-
const metaContent = await readTextFile(
|
|
12487
|
+
const metaContent = await readTextFile(join16(lineageDir, dir, "meta.yml"));
|
|
12340
12488
|
if (!metaContent)
|
|
12341
12489
|
continue;
|
|
12342
12490
|
try {
|
|
12343
|
-
const m =
|
|
12491
|
+
const m = import_yaml16.default.parse(metaContent);
|
|
12344
12492
|
if (m.parents)
|
|
12345
12493
|
m.parents.forEach((p) => dirParents.add(p));
|
|
12346
12494
|
} catch {}
|
|
12347
12495
|
}
|
|
12348
12496
|
const epochFiles = entries.filter((e) => e.startsWith("epoch-") && e.endsWith(".md"));
|
|
12349
12497
|
for (const ef of epochFiles) {
|
|
12350
|
-
const content = await readTextFile(
|
|
12498
|
+
const content = await readTextFile(join16(lineageDir, ef));
|
|
12351
12499
|
if (!content)
|
|
12352
12500
|
continue;
|
|
12353
12501
|
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
12354
12502
|
if (fmMatch) {
|
|
12355
12503
|
try {
|
|
12356
|
-
const parsed =
|
|
12504
|
+
const parsed = import_yaml16.default.parse(fmMatch[1]);
|
|
12357
12505
|
const lastId = parsed.lastGeneration;
|
|
12358
12506
|
if (lastId)
|
|
12359
12507
|
dirParents.add(lastId);
|
|
@@ -12391,9 +12539,9 @@ async function compressToEpoch(lineageDir) {
|
|
|
12391
12539
|
""
|
|
12392
12540
|
].join(`
|
|
12393
12541
|
`);
|
|
12394
|
-
await writeTextFile(
|
|
12542
|
+
await writeTextFile(join16(lineageDir, epochName), epochContent);
|
|
12395
12543
|
for (const f of compressible) {
|
|
12396
|
-
await rm3(
|
|
12544
|
+
await rm3(join16(lineageDir, f.filename), { force: true });
|
|
12397
12545
|
}
|
|
12398
12546
|
return compressible.length;
|
|
12399
12547
|
}
|
|
@@ -12401,7 +12549,7 @@ async function compressToEpoch(lineageDir) {
|
|
|
12401
12549
|
// src/core/archive.ts
|
|
12402
12550
|
function buildArchiveDir(lineageRoot, state) {
|
|
12403
12551
|
const goalSlug = state.goal.toLowerCase().replace(/[^a-z0-9가-힣]+/g, "-").slice(0, 40).replace(/-+$/, "");
|
|
12404
|
-
return
|
|
12552
|
+
return join17(lineageRoot, `${state.id}-${goalSlug}`);
|
|
12405
12553
|
}
|
|
12406
12554
|
async function writeArchive(paths, state, archiveDir, extraMeta) {
|
|
12407
12555
|
await ensureDir(archiveDir);
|
|
@@ -12409,20 +12557,20 @@ async function writeArchive(paths, state, archiveDir, extraMeta) {
|
|
|
12409
12557
|
for (const entry of lifeEntries) {
|
|
12410
12558
|
if (entry === "current.yml" || entry === "backlog")
|
|
12411
12559
|
continue;
|
|
12412
|
-
const src =
|
|
12413
|
-
const dest =
|
|
12560
|
+
const src = join17(paths.life, entry);
|
|
12561
|
+
const dest = join17(archiveDir, entry);
|
|
12414
12562
|
const { cp: cp2 } = await import("fs/promises");
|
|
12415
12563
|
await cp2(src, dest, { recursive: true });
|
|
12416
12564
|
}
|
|
12417
12565
|
const backlogItems = await scanBacklog(paths.backlog);
|
|
12418
12566
|
const consumedItems = backlogItems.filter((b) => b.status === "consumed");
|
|
12419
12567
|
if (consumedItems.length > 0) {
|
|
12420
|
-
const archiveBacklogDir =
|
|
12568
|
+
const archiveBacklogDir = join17(archiveDir, "backlog");
|
|
12421
12569
|
await ensureDir(archiveBacklogDir);
|
|
12422
12570
|
for (const item of consumedItems) {
|
|
12423
12571
|
const content = await readTextFile(item.path);
|
|
12424
12572
|
if (content) {
|
|
12425
|
-
await writeTextFile(
|
|
12573
|
+
await writeTextFile(join17(archiveBacklogDir, item.filename), content);
|
|
12426
12574
|
}
|
|
12427
12575
|
await unlink(item.path).catch(() => {});
|
|
12428
12576
|
}
|
|
@@ -12435,11 +12583,11 @@ async function writeArchive(paths, state, archiveDir, extraMeta) {
|
|
|
12435
12583
|
timeline: state.timeline,
|
|
12436
12584
|
...extraMeta
|
|
12437
12585
|
};
|
|
12438
|
-
await writeTextFile(
|
|
12586
|
+
await writeTextFile(join17(archiveDir, "meta.yml"), import_yaml17.default.stringify(meta));
|
|
12439
12587
|
for (const entry of lifeEntries) {
|
|
12440
12588
|
if (entry === "backlog")
|
|
12441
12589
|
continue;
|
|
12442
|
-
await rm4(
|
|
12590
|
+
await rm4(join17(paths.life, entry), { recursive: true, force: true });
|
|
12443
12591
|
}
|
|
12444
12592
|
await compressLineage(paths.lineage).catch(() => {});
|
|
12445
12593
|
}
|
|
@@ -12760,7 +12908,7 @@ function tokenize(text) {
|
|
|
12760
12908
|
|
|
12761
12909
|
// src/core/cruise.ts
|
|
12762
12910
|
init_fs();
|
|
12763
|
-
var
|
|
12911
|
+
var import_yaml18 = __toESM(require_dist(), 1);
|
|
12764
12912
|
function parseCruiseCount(config) {
|
|
12765
12913
|
if (!config.cruiseCount)
|
|
12766
12914
|
return null;
|
|
@@ -12773,39 +12921,39 @@ async function advanceCruise(configPath) {
|
|
|
12773
12921
|
const content = await readTextFile(configPath);
|
|
12774
12922
|
if (!content)
|
|
12775
12923
|
return false;
|
|
12776
|
-
const config =
|
|
12924
|
+
const config = import_yaml18.default.parse(content);
|
|
12777
12925
|
const cruise = parseCruiseCount(config);
|
|
12778
12926
|
if (!cruise)
|
|
12779
12927
|
return false;
|
|
12780
12928
|
if (cruise.current >= cruise.total) {
|
|
12781
12929
|
delete config.cruiseCount;
|
|
12782
|
-
await writeTextFile(configPath,
|
|
12930
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12783
12931
|
return false;
|
|
12784
12932
|
}
|
|
12785
12933
|
config.cruiseCount = `${cruise.current + 1}/${cruise.total}`;
|
|
12786
|
-
await writeTextFile(configPath,
|
|
12934
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12787
12935
|
return true;
|
|
12788
12936
|
}
|
|
12789
12937
|
async function clearCruise(configPath) {
|
|
12790
12938
|
const content = await readTextFile(configPath);
|
|
12791
12939
|
if (!content)
|
|
12792
12940
|
return;
|
|
12793
|
-
const config =
|
|
12941
|
+
const config = import_yaml18.default.parse(content);
|
|
12794
12942
|
delete config.cruiseCount;
|
|
12795
|
-
await writeTextFile(configPath,
|
|
12943
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12796
12944
|
}
|
|
12797
12945
|
async function setCruise(configPath, total) {
|
|
12798
12946
|
const content = await readTextFile(configPath);
|
|
12799
12947
|
if (!content)
|
|
12800
12948
|
return;
|
|
12801
|
-
const config =
|
|
12949
|
+
const config = import_yaml18.default.parse(content);
|
|
12802
12950
|
config.cruiseCount = `1/${total}`;
|
|
12803
|
-
await writeTextFile(configPath,
|
|
12951
|
+
await writeTextFile(configPath, import_yaml18.default.stringify(config));
|
|
12804
12952
|
}
|
|
12805
12953
|
|
|
12806
12954
|
// src/cli/commands/run/completion.ts
|
|
12807
|
-
var
|
|
12808
|
-
async function
|
|
12955
|
+
var import_yaml19 = __toESM(require_dist(), 1);
|
|
12956
|
+
async function execute13(paths, phase, feedback) {
|
|
12809
12957
|
const gm = new GenerationManager(paths);
|
|
12810
12958
|
const state = await gm.current();
|
|
12811
12959
|
if (!state)
|
|
@@ -12893,7 +13041,7 @@ async function execute12(paths, phase, feedback) {
|
|
|
12893
13041
|
} else {
|
|
12894
13042
|
verifyTransition("completion", s, "completion:fitness");
|
|
12895
13043
|
const configContent = await readTextFile(paths.config);
|
|
12896
|
-
const config = configContent ?
|
|
13044
|
+
const config = configContent ? import_yaml19.default.parse(configContent) : null;
|
|
12897
13045
|
const cruise = config ? parseCruiseCount(config) : null;
|
|
12898
13046
|
const evaluatorEnabled = config?.evaluator === true;
|
|
12899
13047
|
setTransitionNonces(s, "completion:fitness");
|
|
@@ -12969,7 +13117,6 @@ async function execute12(paths, phase, feedback) {
|
|
|
12969
13117
|
`),
|
|
12970
13118
|
nextCommand: "reap run completion --phase fitness"
|
|
12971
13119
|
});
|
|
12972
|
-
return;
|
|
12973
13120
|
}
|
|
12974
13121
|
if (cruise) {
|
|
12975
13122
|
const cruisePrompt = [
|
|
@@ -13043,7 +13190,7 @@ async function execute12(paths, phase, feedback) {
|
|
|
13043
13190
|
const fitnessFeedback = s.fitnessFeedback;
|
|
13044
13191
|
const visionGoals = await readTextFile(paths.visionGoals);
|
|
13045
13192
|
const configContent = await readTextFile(paths.config);
|
|
13046
|
-
const config = configContent ?
|
|
13193
|
+
const config = configContent ? import_yaml19.default.parse(configContent) : null;
|
|
13047
13194
|
const maturity = detectMaturity(s.type, config?.cruiseCount);
|
|
13048
13195
|
const generationCount = await gm.countLineage();
|
|
13049
13196
|
setTransitionNonces(s, "completion:adapt");
|
|
@@ -13137,9 +13284,9 @@ async function execute12(paths, phase, feedback) {
|
|
|
13137
13284
|
verifyTransition("completion", s, "completion:commit");
|
|
13138
13285
|
if (feedback) {
|
|
13139
13286
|
const filenames = feedback.split(",").map((f) => f.trim()).filter(Boolean);
|
|
13140
|
-
const { join:
|
|
13287
|
+
const { join: join18 } = await import("path");
|
|
13141
13288
|
for (const filename of filenames) {
|
|
13142
|
-
await consumeBacklog(
|
|
13289
|
+
await consumeBacklog(join18(paths.backlog, filename), s.id);
|
|
13143
13290
|
}
|
|
13144
13291
|
}
|
|
13145
13292
|
const fitnessFeedback = s.fitnessFeedback;
|
|
@@ -13155,8 +13302,12 @@ async function execute12(paths, phase, feedback) {
|
|
|
13155
13302
|
const commitHash = gitCommitAll(paths.root, commitMsg);
|
|
13156
13303
|
const completionEvent = isMerge ? "onMergeCompleted" : "onLifeCompleted";
|
|
13157
13304
|
await executeHooks(paths.hooks, completionEvent, paths.root).catch(() => {});
|
|
13158
|
-
const
|
|
13159
|
-
|
|
13305
|
+
const completionConfigContent = await readTextFile(paths.config);
|
|
13306
|
+
const completionConfig = completionConfigContent ? import_yaml19.default.parse(completionConfigContent) : null;
|
|
13307
|
+
if (completionConfig?.daemon === true) {
|
|
13308
|
+
const { triggerIndexing: triggerIndexing2 } = await Promise.resolve().then(() => (init_lifecycle(), exports_lifecycle));
|
|
13309
|
+
await triggerIndexing2(paths.root);
|
|
13310
|
+
}
|
|
13160
13311
|
const cruiseStillActive = await advanceCruise(paths.config).catch(() => false);
|
|
13161
13312
|
emitOutput({
|
|
13162
13313
|
status: "ok",
|
|
@@ -13176,7 +13327,7 @@ async function execute12(paths, phase, feedback) {
|
|
|
13176
13327
|
}
|
|
13177
13328
|
|
|
13178
13329
|
// src/cli/commands/run/evolve.ts
|
|
13179
|
-
var
|
|
13330
|
+
var import_yaml20 = __toESM(require_dist(), 1);
|
|
13180
13331
|
import { readdir as readdir14 } from "fs/promises";
|
|
13181
13332
|
init_fs();
|
|
13182
13333
|
async function collectClarityInput(paths, generationType) {
|
|
@@ -13209,11 +13360,11 @@ async function collectClarityInput(paths, generationType) {
|
|
|
13209
13360
|
hasMemory
|
|
13210
13361
|
};
|
|
13211
13362
|
}
|
|
13212
|
-
async function
|
|
13363
|
+
async function execute14(paths, _phase) {
|
|
13213
13364
|
const gm = new GenerationManager(paths);
|
|
13214
13365
|
const state = await gm.current();
|
|
13215
13366
|
const configContent = await readTextFile(paths.config);
|
|
13216
|
-
const config = configContent ?
|
|
13367
|
+
const config = configContent ? import_yaml20.default.parse(configContent) : null;
|
|
13217
13368
|
const autoSubagent = config?.autoSubagent ?? true;
|
|
13218
13369
|
const cruise = config ? parseCruiseCount(config) : null;
|
|
13219
13370
|
const generationType = state?.type ?? "normal";
|
|
@@ -13292,7 +13443,7 @@ async function execute13(paths, _phase) {
|
|
|
13292
13443
|
}
|
|
13293
13444
|
|
|
13294
13445
|
// src/cli/commands/run/back.ts
|
|
13295
|
-
async function
|
|
13446
|
+
async function execute15(paths, _phase, reason) {
|
|
13296
13447
|
const gm = new GenerationManager(paths);
|
|
13297
13448
|
const state = await gm.current();
|
|
13298
13449
|
if (!state)
|
|
@@ -13339,7 +13490,7 @@ async function execute14(paths, _phase, reason) {
|
|
|
13339
13490
|
}
|
|
13340
13491
|
|
|
13341
13492
|
// src/cli/commands/run/next.ts
|
|
13342
|
-
async function
|
|
13493
|
+
async function execute16(paths) {
|
|
13343
13494
|
const gm = new GenerationManager(paths);
|
|
13344
13495
|
const state = await gm.current();
|
|
13345
13496
|
if (!state)
|
|
@@ -13361,7 +13512,7 @@ async function execute15(paths) {
|
|
|
13361
13512
|
|
|
13362
13513
|
// src/cli/commands/run/abort.ts
|
|
13363
13514
|
import { readdir as readdir15, rm as rm5 } from "fs/promises";
|
|
13364
|
-
import { join as
|
|
13515
|
+
import { join as join18 } from "path";
|
|
13365
13516
|
init_fs();
|
|
13366
13517
|
function parseExtra(extra) {
|
|
13367
13518
|
if (!extra)
|
|
@@ -13372,7 +13523,7 @@ function parseExtra(extra) {
|
|
|
13372
13523
|
return {};
|
|
13373
13524
|
}
|
|
13374
13525
|
}
|
|
13375
|
-
async function
|
|
13526
|
+
async function execute17(paths, phase, extra) {
|
|
13376
13527
|
const gm = new GenerationManager(paths);
|
|
13377
13528
|
const state = await gm.current();
|
|
13378
13529
|
if (!state)
|
|
@@ -13437,7 +13588,7 @@ createdAt: ${new Date().toISOString()}
|
|
|
13437
13588
|
## Progress
|
|
13438
13589
|
<!-- Progress from the aborted generation can be referenced here -->
|
|
13439
13590
|
`;
|
|
13440
|
-
await writeTextFile(
|
|
13591
|
+
await writeTextFile(join18(paths.backlog, filename), content);
|
|
13441
13592
|
savedBacklogFile = filename;
|
|
13442
13593
|
}
|
|
13443
13594
|
const revertedCount = await revertBacklogConsumed(paths.backlog, id);
|
|
@@ -13445,7 +13596,7 @@ createdAt: ${new Date().toISOString()}
|
|
|
13445
13596
|
for (const entry of lifeEntries) {
|
|
13446
13597
|
if (entry === "backlog")
|
|
13447
13598
|
continue;
|
|
13448
|
-
await rm5(
|
|
13599
|
+
await rm5(join18(paths.life, entry), { recursive: true, force: true });
|
|
13449
13600
|
}
|
|
13450
13601
|
emitOutput({
|
|
13451
13602
|
status: "ok",
|
|
@@ -13466,7 +13617,7 @@ createdAt: ${new Date().toISOString()}
|
|
|
13466
13617
|
}
|
|
13467
13618
|
|
|
13468
13619
|
// src/cli/commands/run/early-close.ts
|
|
13469
|
-
import { join as
|
|
13620
|
+
import { join as join19 } from "path";
|
|
13470
13621
|
init_fs();
|
|
13471
13622
|
function parseExtra2(extra) {
|
|
13472
13623
|
if (!extra)
|
|
@@ -13479,7 +13630,7 @@ function parseExtra2(extra) {
|
|
|
13479
13630
|
}
|
|
13480
13631
|
var ALLOWED_STAGES = new Set(["implementation", "validation"]);
|
|
13481
13632
|
var ALLOWED_SOURCE_ACTIONS = new Set(["hold", "stash", "none"]);
|
|
13482
|
-
async function
|
|
13633
|
+
async function execute18(paths, phase, extra) {
|
|
13483
13634
|
const gm = new GenerationManager(paths);
|
|
13484
13635
|
const state = await gm.current();
|
|
13485
13636
|
if (!state)
|
|
@@ -13605,7 +13756,7 @@ async function execute17(paths, phase, extra) {
|
|
|
13605
13756
|
message: [
|
|
13606
13757
|
`Generation ${s.id} early-closed at stage '${s.stage}' (reason: ${reason}).`,
|
|
13607
13758
|
`Archived: ${archiveDir}`,
|
|
13608
|
-
deferredBacklogFile ? `Deferred backlog: ${
|
|
13759
|
+
deferredBacklogFile ? `Deferred backlog: ${join19(paths.backlog, deferredBacklogFile)} (${deferredTaskCount} task(s))` : `Defer skipped — ${deferredTaskCount} unchecked task(s) found but not carried over.`,
|
|
13609
13760
|
commitHash ? `Commit: ${commitHash}` : "Commit your changes manually."
|
|
13610
13761
|
].join(" ")
|
|
13611
13762
|
});
|
|
@@ -13614,7 +13765,7 @@ async function execute17(paths, phase, extra) {
|
|
|
13614
13765
|
}
|
|
13615
13766
|
|
|
13616
13767
|
// src/cli/commands/run/detect.ts
|
|
13617
|
-
async function
|
|
13768
|
+
async function execute19(paths, phase) {
|
|
13618
13769
|
const gm = new GenerationManager(paths);
|
|
13619
13770
|
const state = await gm.current();
|
|
13620
13771
|
if (!state)
|
|
@@ -13700,7 +13851,7 @@ async function execute18(paths, phase) {
|
|
|
13700
13851
|
|
|
13701
13852
|
// src/cli/commands/run/mate.ts
|
|
13702
13853
|
init_fs();
|
|
13703
|
-
async function
|
|
13854
|
+
async function execute20(paths, phase) {
|
|
13704
13855
|
const gm = new GenerationManager(paths);
|
|
13705
13856
|
const state = await gm.current();
|
|
13706
13857
|
if (!state)
|
|
@@ -13798,7 +13949,7 @@ async function execute19(paths, phase) {
|
|
|
13798
13949
|
|
|
13799
13950
|
// src/cli/commands/run/merge.ts
|
|
13800
13951
|
init_fs();
|
|
13801
|
-
async function
|
|
13952
|
+
async function execute21(paths, phase) {
|
|
13802
13953
|
const gm = new GenerationManager(paths);
|
|
13803
13954
|
const state = await gm.current();
|
|
13804
13955
|
if (!state)
|
|
@@ -13871,7 +14022,7 @@ async function execute20(paths, phase) {
|
|
|
13871
14022
|
|
|
13872
14023
|
// src/cli/commands/run/reconcile.ts
|
|
13873
14024
|
init_fs();
|
|
13874
|
-
async function
|
|
14025
|
+
async function execute22(paths, phase) {
|
|
13875
14026
|
const gm = new GenerationManager(paths);
|
|
13876
14027
|
const state = await gm.current();
|
|
13877
14028
|
if (!state)
|
|
@@ -13955,7 +14106,7 @@ async function execute21(paths, phase) {
|
|
|
13955
14106
|
}
|
|
13956
14107
|
|
|
13957
14108
|
// src/cli/commands/run/push.ts
|
|
13958
|
-
async function
|
|
14109
|
+
async function execute23(paths) {
|
|
13959
14110
|
const gm = new GenerationManager(paths);
|
|
13960
14111
|
const state = await gm.current();
|
|
13961
14112
|
if (state) {
|
|
@@ -13989,7 +14140,7 @@ async function execute22(paths) {
|
|
|
13989
14140
|
}
|
|
13990
14141
|
|
|
13991
14142
|
// src/cli/commands/run/pull.ts
|
|
13992
|
-
async function
|
|
14143
|
+
async function execute24(paths, phase) {
|
|
13993
14144
|
if (!isGitRepo(paths.root)) {
|
|
13994
14145
|
emitError("pull", "Not a git repository.");
|
|
13995
14146
|
}
|
|
@@ -14142,7 +14293,7 @@ Consider using /reap.merge to start a merge lifecycle if needed.` : "No unmerged
|
|
|
14142
14293
|
}
|
|
14143
14294
|
|
|
14144
14295
|
// src/cli/commands/run/knowledge.ts
|
|
14145
|
-
async function
|
|
14296
|
+
async function execute25(paths, _phase, extra) {
|
|
14146
14297
|
const subcommand = extra ?? "";
|
|
14147
14298
|
if (subcommand === "reload") {
|
|
14148
14299
|
emitOutput({
|
|
@@ -14289,19 +14440,19 @@ async function execute24(paths, _phase, extra) {
|
|
|
14289
14440
|
|
|
14290
14441
|
// src/cli/commands/run/report.ts
|
|
14291
14442
|
init_fs();
|
|
14292
|
-
var
|
|
14293
|
-
async function
|
|
14443
|
+
var import_yaml21 = __toESM(require_dist(), 1);
|
|
14444
|
+
async function execute26(paths, _phase) {
|
|
14294
14445
|
let state = null;
|
|
14295
14446
|
try {
|
|
14296
14447
|
const raw = await readTextFile(paths.current);
|
|
14297
14448
|
if (raw)
|
|
14298
|
-
state =
|
|
14449
|
+
state = import_yaml21.default.parse(raw);
|
|
14299
14450
|
} catch {}
|
|
14300
14451
|
let projectName = "unknown";
|
|
14301
14452
|
try {
|
|
14302
14453
|
const raw = await readTextFile(paths.config);
|
|
14303
14454
|
if (raw) {
|
|
14304
|
-
const config =
|
|
14455
|
+
const config = import_yaml21.default.parse(raw);
|
|
14305
14456
|
projectName = config.project ?? "unknown";
|
|
14306
14457
|
}
|
|
14307
14458
|
} catch {}
|
|
@@ -14356,28 +14507,28 @@ async function execute25(paths, _phase) {
|
|
|
14356
14507
|
|
|
14357
14508
|
// src/cli/commands/run/index.ts
|
|
14358
14509
|
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:
|
|
14510
|
+
learning: execute9,
|
|
14511
|
+
planning: execute10,
|
|
14512
|
+
implementation: execute11,
|
|
14513
|
+
validation: execute12,
|
|
14514
|
+
completion: execute13,
|
|
14515
|
+
evolve: execute14,
|
|
14516
|
+
back: execute15,
|
|
14517
|
+
next: execute16,
|
|
14518
|
+
abort: execute17,
|
|
14519
|
+
"early-close": execute18,
|
|
14520
|
+
detect: execute19,
|
|
14521
|
+
mate: execute20,
|
|
14522
|
+
merge: execute21,
|
|
14523
|
+
reconcile: execute22,
|
|
14524
|
+
push: execute23,
|
|
14525
|
+
pull: execute24,
|
|
14526
|
+
knowledge: execute25,
|
|
14527
|
+
report: execute26
|
|
14377
14528
|
};
|
|
14378
|
-
async function
|
|
14529
|
+
async function execute27(stage, options) {
|
|
14379
14530
|
if (stage === "start") {
|
|
14380
|
-
await
|
|
14531
|
+
await execute8(options.phase, options.goal, options.type, options.parents, options.backlog);
|
|
14381
14532
|
return;
|
|
14382
14533
|
}
|
|
14383
14534
|
const paths = createPaths(process.cwd());
|
|
@@ -14407,7 +14558,7 @@ async function execute26(stage, options) {
|
|
|
14407
14558
|
try {
|
|
14408
14559
|
const configContent = await readTextFile(paths.config);
|
|
14409
14560
|
if (configContent) {
|
|
14410
|
-
const config =
|
|
14561
|
+
const config = import_yaml22.default.parse(configContent);
|
|
14411
14562
|
if (config.autoIssueReport !== false) {
|
|
14412
14563
|
const cmd = `reap run ${stage}${options.phase ? ` --phase ${options.phase}` : ""}`;
|
|
14413
14564
|
autoReport(cmd, err);
|
|
@@ -14442,7 +14593,7 @@ async function makeBacklog(paths, options) {
|
|
|
14442
14593
|
}
|
|
14443
14594
|
|
|
14444
14595
|
// src/cli/commands/make/hook.ts
|
|
14445
|
-
import { join as
|
|
14596
|
+
import { join as join20 } from "path";
|
|
14446
14597
|
import { chmod as chmod2 } from "fs/promises";
|
|
14447
14598
|
init_fs();
|
|
14448
14599
|
var VALID_EVENTS = [
|
|
@@ -14480,7 +14631,7 @@ ${VALID_EVENTS.join(`
|
|
|
14480
14631
|
emitError("make", "Invalid --type. Use 'sh' or 'md'.");
|
|
14481
14632
|
}
|
|
14482
14633
|
const filename = `${event}.${name}.${type}`;
|
|
14483
|
-
const filePath =
|
|
14634
|
+
const filePath = join20(paths.hooks, filename);
|
|
14484
14635
|
await ensureDir(paths.hooks);
|
|
14485
14636
|
if (await fileExists(filePath)) {
|
|
14486
14637
|
emitError("make", `Hook already exists: ${filename}`);
|
|
@@ -14515,7 +14666,7 @@ order: ${order}
|
|
|
14515
14666
|
|
|
14516
14667
|
// src/cli/commands/make/index.ts
|
|
14517
14668
|
var RESOURCES = ["backlog", "hook"];
|
|
14518
|
-
async function
|
|
14669
|
+
async function execute28(resource, options) {
|
|
14519
14670
|
const paths = createPaths(process.cwd());
|
|
14520
14671
|
if (await detectV15(paths)) {
|
|
14521
14672
|
emitError("make", "This project uses REAP v0.15 structure. Run '/reap.update' to upgrade to v0.16.");
|
|
@@ -14531,7 +14682,7 @@ async function execute27(resource, options) {
|
|
|
14531
14682
|
|
|
14532
14683
|
// src/cli/commands/cruise.ts
|
|
14533
14684
|
init_integrity();
|
|
14534
|
-
async function
|
|
14685
|
+
async function execute29(count) {
|
|
14535
14686
|
const n = parseInt(count);
|
|
14536
14687
|
if (isNaN(n) || n < 1) {
|
|
14537
14688
|
emitError("cruise", "Count must be a positive integer.");
|
|
@@ -14550,34 +14701,34 @@ async function execute28(count) {
|
|
|
14550
14701
|
}
|
|
14551
14702
|
|
|
14552
14703
|
// src/cli/commands/install-skills.ts
|
|
14553
|
-
var
|
|
14704
|
+
var import_yaml23 = __toESM(require_dist(), 1);
|
|
14554
14705
|
|
|
14555
14706
|
// src/adapters/claude-code/install.ts
|
|
14556
14707
|
init_fs();
|
|
14557
14708
|
import { readdir as readdir16, cp as cp2, unlink as unlink2, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
|
|
14558
|
-
import { join as
|
|
14709
|
+
import { join as join21, dirname as dirname6 } from "path";
|
|
14559
14710
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
14560
14711
|
import { homedir as homedir4 } from "os";
|
|
14561
14712
|
var __dirname2 = dirname6(fileURLToPath4(import.meta.url));
|
|
14562
|
-
var SKILLS_DIR = __dirname2.includes("dist") ?
|
|
14713
|
+
var SKILLS_DIR = __dirname2.includes("dist") ? join21(__dirname2, "..", "adapters", "claude-code", "skills") : join21(__dirname2, "skills");
|
|
14563
14714
|
var SKILL_PATTERN = /^reap\..+\.md$/;
|
|
14564
14715
|
async function cleanupStaleSkills(targetDir) {
|
|
14565
14716
|
const files = await readdir16(targetDir);
|
|
14566
14717
|
const staleFiles = files.filter((f) => SKILL_PATTERN.test(f));
|
|
14567
14718
|
for (const file of staleFiles) {
|
|
14568
|
-
await unlink2(
|
|
14719
|
+
await unlink2(join21(targetDir, file));
|
|
14569
14720
|
}
|
|
14570
14721
|
return staleFiles;
|
|
14571
14722
|
}
|
|
14572
14723
|
async function installSlashCommandsOnly() {
|
|
14573
|
-
const targetDir =
|
|
14724
|
+
const targetDir = join21(homedir4(), ".claude", "commands");
|
|
14574
14725
|
await ensureDir(targetDir);
|
|
14575
14726
|
const cleaned = await cleanupStaleSkills(targetDir);
|
|
14576
14727
|
const files = await readdir16(SKILLS_DIR);
|
|
14577
14728
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
14578
14729
|
let installed = 0;
|
|
14579
14730
|
for (const file of mdFiles) {
|
|
14580
|
-
await cp2(
|
|
14731
|
+
await cp2(join21(SKILLS_DIR, file), join21(targetDir, file));
|
|
14581
14732
|
installed++;
|
|
14582
14733
|
}
|
|
14583
14734
|
return { cleaned, installed, files: mdFiles, targetDir };
|
|
@@ -14602,17 +14753,17 @@ async function installSkills(_projectRoot) {
|
|
|
14602
14753
|
}
|
|
14603
14754
|
var AGENT_PATTERN = /^reap-.+\.md$/;
|
|
14604
14755
|
function agentsTemplateDir() {
|
|
14605
|
-
return __dirname2.includes("dist") ?
|
|
14756
|
+
return __dirname2.includes("dist") ? join21(__dirname2, "..", "templates", "agents") : join21(__dirname2, "..", "..", "templates", "agents");
|
|
14606
14757
|
}
|
|
14607
14758
|
async function installAgents(home = homedir4()) {
|
|
14608
|
-
const targetDir =
|
|
14759
|
+
const targetDir = join21(home, ".claude", "agents");
|
|
14609
14760
|
await ensureDir(targetDir);
|
|
14610
14761
|
let cleaned = [];
|
|
14611
14762
|
try {
|
|
14612
14763
|
const existing = await readdir16(targetDir);
|
|
14613
14764
|
cleaned = existing.filter((f) => AGENT_PATTERN.test(f));
|
|
14614
14765
|
for (const file of cleaned) {
|
|
14615
|
-
await unlink2(
|
|
14766
|
+
await unlink2(join21(targetDir, file));
|
|
14616
14767
|
}
|
|
14617
14768
|
} catch {}
|
|
14618
14769
|
let installed = 0;
|
|
@@ -14623,7 +14774,7 @@ async function installAgents(home = homedir4()) {
|
|
|
14623
14774
|
for (const file of sources) {
|
|
14624
14775
|
if (!file.endsWith(".md"))
|
|
14625
14776
|
continue;
|
|
14626
|
-
await cp2(
|
|
14777
|
+
await cp2(join21(templateDir, file), join21(targetDir, file));
|
|
14627
14778
|
files.push(file);
|
|
14628
14779
|
installed++;
|
|
14629
14780
|
}
|
|
@@ -14631,16 +14782,16 @@ async function installAgents(home = homedir4()) {
|
|
|
14631
14782
|
return { cleaned, installed, files, targetDir };
|
|
14632
14783
|
}
|
|
14633
14784
|
async function installReapGuide() {
|
|
14634
|
-
const reapHome =
|
|
14785
|
+
const reapHome = join21(homedir4(), ".reap");
|
|
14635
14786
|
await ensureDir(reapHome);
|
|
14636
|
-
const templateDir = __dirname2.includes("dist") ?
|
|
14637
|
-
const src =
|
|
14787
|
+
const templateDir = __dirname2.includes("dist") ? join21(__dirname2, "..", "templates") : join21(__dirname2, "..", "..", "templates");
|
|
14788
|
+
const src = join21(templateDir, "reap-guide.md");
|
|
14638
14789
|
if (await fileExists(src)) {
|
|
14639
|
-
await cp2(src,
|
|
14790
|
+
await cp2(src, join21(reapHome, "reap-guide.md"));
|
|
14640
14791
|
}
|
|
14641
14792
|
}
|
|
14642
14793
|
async function registerSessionHooks() {
|
|
14643
|
-
const settingsPath =
|
|
14794
|
+
const settingsPath = join21(homedir4(), ".claude", "settings.json");
|
|
14644
14795
|
const requiredHooks = [
|
|
14645
14796
|
{ command: "reap check-version 2>/dev/null || true", marker: "reap check-version" },
|
|
14646
14797
|
{ command: "reap load-context 2>/dev/null || true", marker: "reap load-context" }
|
|
@@ -14699,13 +14850,13 @@ var claudeCodeAdapter = {
|
|
|
14699
14850
|
// src/adapters/opencode/install.ts
|
|
14700
14851
|
init_fs();
|
|
14701
14852
|
import { cp as cp3, readFile as readFile4, writeFile as writeFile4, readdir as readdir17, unlink as unlink3 } from "fs/promises";
|
|
14702
|
-
import { join as
|
|
14853
|
+
import { join as join22, dirname as dirname7 } from "path";
|
|
14703
14854
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
14704
14855
|
import { homedir as homedir5 } from "os";
|
|
14705
14856
|
import { createHash as createHash4 } from "crypto";
|
|
14706
14857
|
var __dirname3 = dirname7(fileURLToPath5(import.meta.url));
|
|
14707
14858
|
function assetPath(...segments) {
|
|
14708
|
-
return __dirname3.includes("dist") ?
|
|
14859
|
+
return __dirname3.includes("dist") ? join22(__dirname3, "..", "adapters", "opencode", ...segments) : join22(__dirname3, ...segments);
|
|
14709
14860
|
}
|
|
14710
14861
|
var PLUGIN_FILENAME = "reap-plugin.ts";
|
|
14711
14862
|
var PLUGIN_SRC = assetPath("plugin", PLUGIN_FILENAME);
|
|
@@ -14763,7 +14914,7 @@ async function ensureAgentsMd(projectRoot, projectName) {
|
|
|
14763
14914
|
const inner = stripMarkers2(rawTemplate);
|
|
14764
14915
|
const wrapped = wrapWithMarkers2(inner);
|
|
14765
14916
|
const newHash = computeSectionHash2(inner);
|
|
14766
|
-
const agentsPath =
|
|
14917
|
+
const agentsPath = join22(projectRoot, "AGENTS.md");
|
|
14767
14918
|
const existing = await readTextFile(agentsPath);
|
|
14768
14919
|
if (!existing) {
|
|
14769
14920
|
await writeTextFile(agentsPath, `# ${projectName}
|
|
@@ -14810,7 +14961,7 @@ function stripMarkers2(content) {
|
|
|
14810
14961
|
return content.slice(afterStart + 1, endIdx).trimEnd();
|
|
14811
14962
|
}
|
|
14812
14963
|
async function ensureOpencodeJson(projectRoot) {
|
|
14813
|
-
const path =
|
|
14964
|
+
const path = join22(projectRoot, "opencode.json");
|
|
14814
14965
|
const existed = await fileExists(path);
|
|
14815
14966
|
let cfg = {};
|
|
14816
14967
|
if (existed) {
|
|
@@ -14849,27 +15000,27 @@ async function ensureOpencodeJson(projectRoot) {
|
|
|
14849
15000
|
return existed ? "updated" : "created";
|
|
14850
15001
|
}
|
|
14851
15002
|
async function installPluginFile(projectRoot) {
|
|
14852
|
-
const pluginsDir =
|
|
15003
|
+
const pluginsDir = join22(projectRoot, ".opencode", "plugins");
|
|
14853
15004
|
await ensureDir(pluginsDir);
|
|
14854
15005
|
if (await fileExists(PLUGIN_SRC)) {
|
|
14855
|
-
await cp3(PLUGIN_SRC,
|
|
15006
|
+
await cp3(PLUGIN_SRC, join22(pluginsDir, PLUGIN_FILENAME));
|
|
14856
15007
|
}
|
|
14857
15008
|
}
|
|
14858
15009
|
async function installReapGuide2() {
|
|
14859
|
-
const reapHome =
|
|
15010
|
+
const reapHome = join22(homedir5(), ".reap");
|
|
14860
15011
|
await ensureDir(reapHome);
|
|
14861
|
-
const templateDir = __dirname3.includes("dist") ?
|
|
14862
|
-
const src =
|
|
15012
|
+
const templateDir = __dirname3.includes("dist") ? join22(__dirname3, "..", "..", "templates") : join22(__dirname3, "..", "..", "templates");
|
|
15013
|
+
const src = join22(templateDir, "reap-guide.md");
|
|
14863
15014
|
if (await fileExists(src)) {
|
|
14864
|
-
await cp3(src,
|
|
15015
|
+
await cp3(src, join22(reapHome, "reap-guide.md"));
|
|
14865
15016
|
}
|
|
14866
15017
|
}
|
|
14867
15018
|
var SLASH_COMMAND_PATTERN = /^reap\..+\.md$/;
|
|
14868
15019
|
function claudeCodeSkillsDir() {
|
|
14869
|
-
return __dirname3.includes("dist") ?
|
|
15020
|
+
return __dirname3.includes("dist") ? join22(__dirname3, "..", "adapters", "claude-code", "skills") : join22(__dirname3, "..", "claude-code", "skills");
|
|
14870
15021
|
}
|
|
14871
15022
|
function opencodeCommandsDir(home = homedir5()) {
|
|
14872
|
-
return
|
|
15023
|
+
return join22(home, ".config", "opencode", "commands");
|
|
14873
15024
|
}
|
|
14874
15025
|
async function installSlashCommands(home = homedir5()) {
|
|
14875
15026
|
const targetDir = opencodeCommandsDir(home);
|
|
@@ -14879,7 +15030,7 @@ async function installSlashCommands(home = homedir5()) {
|
|
|
14879
15030
|
const existing = await readdir17(targetDir);
|
|
14880
15031
|
for (const file of existing) {
|
|
14881
15032
|
if (SLASH_COMMAND_PATTERN.test(file)) {
|
|
14882
|
-
await unlink3(
|
|
15033
|
+
await unlink3(join22(targetDir, file));
|
|
14883
15034
|
cleaned++;
|
|
14884
15035
|
}
|
|
14885
15036
|
}
|
|
@@ -14891,7 +15042,7 @@ async function installSlashCommands(home = homedir5()) {
|
|
|
14891
15042
|
for (const file of sources) {
|
|
14892
15043
|
if (!file.endsWith(".md"))
|
|
14893
15044
|
continue;
|
|
14894
|
-
await cp3(
|
|
15045
|
+
await cp3(join22(srcDir, file), join22(targetDir, file));
|
|
14895
15046
|
installed++;
|
|
14896
15047
|
}
|
|
14897
15048
|
} catch {}
|
|
@@ -14899,10 +15050,10 @@ async function installSlashCommands(home = homedir5()) {
|
|
|
14899
15050
|
}
|
|
14900
15051
|
var AGENT_PATTERN2 = /^reap-.+\.md$/;
|
|
14901
15052
|
function agentsTemplateDir2() {
|
|
14902
|
-
return __dirname3.includes("dist") ?
|
|
15053
|
+
return __dirname3.includes("dist") ? join22(__dirname3, "..", "templates", "agents") : join22(__dirname3, "..", "..", "templates", "agents");
|
|
14903
15054
|
}
|
|
14904
15055
|
function opencodeAgentsDir(home = homedir5()) {
|
|
14905
|
-
return
|
|
15056
|
+
return join22(home, ".config", "opencode", "agent");
|
|
14906
15057
|
}
|
|
14907
15058
|
async function installAgents2(home = homedir5()) {
|
|
14908
15059
|
const targetDir = opencodeAgentsDir(home);
|
|
@@ -14912,7 +15063,7 @@ async function installAgents2(home = homedir5()) {
|
|
|
14912
15063
|
const existing = await readdir17(targetDir);
|
|
14913
15064
|
for (const file of existing) {
|
|
14914
15065
|
if (AGENT_PATTERN2.test(file)) {
|
|
14915
|
-
await unlink3(
|
|
15066
|
+
await unlink3(join22(targetDir, file));
|
|
14916
15067
|
cleaned++;
|
|
14917
15068
|
}
|
|
14918
15069
|
}
|
|
@@ -14924,7 +15075,7 @@ async function installAgents2(home = homedir5()) {
|
|
|
14924
15075
|
for (const file of sources) {
|
|
14925
15076
|
if (!file.endsWith(".md"))
|
|
14926
15077
|
continue;
|
|
14927
|
-
await cp3(
|
|
15078
|
+
await cp3(join22(srcDir, file), join22(targetDir, file));
|
|
14928
15079
|
installed++;
|
|
14929
15080
|
}
|
|
14930
15081
|
} catch {}
|
|
@@ -14948,7 +15099,7 @@ async function installSkills2(projectRoot) {
|
|
|
14948
15099
|
],
|
|
14949
15100
|
context: {
|
|
14950
15101
|
agentClient: "opencode",
|
|
14951
|
-
pluginPath:
|
|
15102
|
+
pluginPath: join22(projectRoot, ".opencode", "plugins", PLUGIN_FILENAME),
|
|
14952
15103
|
opencodeJson: opencodeJsonAction,
|
|
14953
15104
|
slashCommands: {
|
|
14954
15105
|
cleaned: slashCommands.cleaned,
|
|
@@ -15003,7 +15154,7 @@ function getAdapter(agentClient) {
|
|
|
15003
15154
|
|
|
15004
15155
|
// src/cli/commands/install-skills.ts
|
|
15005
15156
|
init_fs();
|
|
15006
|
-
async function
|
|
15157
|
+
async function execute30() {
|
|
15007
15158
|
const cwd = process.cwd();
|
|
15008
15159
|
const paths = createPaths(cwd);
|
|
15009
15160
|
let agentClient;
|
|
@@ -15011,7 +15162,7 @@ async function execute29() {
|
|
|
15011
15162
|
const raw = await readTextFile(paths.config);
|
|
15012
15163
|
if (raw) {
|
|
15013
15164
|
try {
|
|
15014
|
-
const cfg =
|
|
15165
|
+
const cfg = import_yaml23.default.parse(raw);
|
|
15015
15166
|
agentClient = cfg.agentClient;
|
|
15016
15167
|
} catch {}
|
|
15017
15168
|
}
|
|
@@ -15021,9 +15172,9 @@ async function execute29() {
|
|
|
15021
15172
|
}
|
|
15022
15173
|
|
|
15023
15174
|
// src/cli/commands/fix.ts
|
|
15024
|
-
var
|
|
15175
|
+
var import_yaml24 = __toESM(require_dist(), 1);
|
|
15025
15176
|
import { mkdir as mkdir3, stat as stat4 } from "fs/promises";
|
|
15026
|
-
import { join as
|
|
15177
|
+
import { join as join23, dirname as dirname8 } from "path";
|
|
15027
15178
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
15028
15179
|
import { homedir as homedir6 } from "os";
|
|
15029
15180
|
init_fs();
|
|
@@ -15073,7 +15224,7 @@ async function fixProject(projectRoot) {
|
|
|
15073
15224
|
if (currentContent !== null) {
|
|
15074
15225
|
if (currentContent.trim()) {
|
|
15075
15226
|
try {
|
|
15076
|
-
const state =
|
|
15227
|
+
const state = import_yaml24.default.parse(currentContent);
|
|
15077
15228
|
const allStages = [
|
|
15078
15229
|
...LIFECYCLE_STAGES,
|
|
15079
15230
|
...MERGE_STAGES
|
|
@@ -15105,13 +15256,13 @@ async function fixProject(projectRoot) {
|
|
|
15105
15256
|
issues.push(`genome/${gf.name} is missing. Run 'reap init --repair' to restore.`);
|
|
15106
15257
|
}
|
|
15107
15258
|
}
|
|
15108
|
-
const guidePath =
|
|
15259
|
+
const guidePath = join23(homedir6(), ".reap", "reap-guide.md");
|
|
15109
15260
|
if (!await fileExists(guidePath)) {
|
|
15110
15261
|
const __dir = dirname8(fileURLToPath6(import.meta.url));
|
|
15111
|
-
const srcGuide = await readTextFile(
|
|
15262
|
+
const srcGuide = await readTextFile(join23(__dir, "..", "templates", "reap-guide.md"));
|
|
15112
15263
|
if (srcGuide) {
|
|
15113
15264
|
const { ensureDir: ensDir } = await Promise.resolve().then(() => (init_fs(), exports_fs));
|
|
15114
|
-
await ensDir(
|
|
15265
|
+
await ensDir(join23(homedir6(), ".reap"));
|
|
15115
15266
|
await writeTextFile(guidePath, srcGuide);
|
|
15116
15267
|
fixed.push("Restored missing ~/.reap/reap-guide.md");
|
|
15117
15268
|
} else {
|
|
@@ -15140,7 +15291,7 @@ async function fixProject(projectRoot) {
|
|
|
15140
15291
|
{
|
|
15141
15292
|
const { ensureClaudeMd: ensureClaudeMd2 } = await Promise.resolve().then(() => (init_common(), exports_common));
|
|
15142
15293
|
const configContent = await readTextFile(paths.config);
|
|
15143
|
-
const projectName = configContent ?
|
|
15294
|
+
const projectName = configContent ? import_yaml24.default.parse(configContent)?.project ?? "my-project" : "my-project";
|
|
15144
15295
|
const action = await ensureClaudeMd2(paths.root, projectName);
|
|
15145
15296
|
if (action !== "skipped") {
|
|
15146
15297
|
fixed.push(`CLAUDE.md ${action} with REAP section`);
|
|
@@ -15148,7 +15299,7 @@ async function fixProject(projectRoot) {
|
|
|
15148
15299
|
}
|
|
15149
15300
|
return { issues, fixed };
|
|
15150
15301
|
}
|
|
15151
|
-
async function
|
|
15302
|
+
async function execute31(check) {
|
|
15152
15303
|
const root = process.cwd();
|
|
15153
15304
|
const paths = createPaths(root);
|
|
15154
15305
|
if (await detectV15(paths)) {
|
|
@@ -15189,9 +15340,9 @@ async function execute30(check) {
|
|
|
15189
15340
|
}
|
|
15190
15341
|
|
|
15191
15342
|
// src/cli/commands/destroy.ts
|
|
15192
|
-
var
|
|
15343
|
+
var import_yaml25 = __toESM(require_dist(), 1);
|
|
15193
15344
|
import { rm as rm6 } from "fs/promises";
|
|
15194
|
-
import { join as
|
|
15345
|
+
import { join as join24 } from "path";
|
|
15195
15346
|
init_fs();
|
|
15196
15347
|
init_integrity();
|
|
15197
15348
|
async function getProjectName(projectRoot) {
|
|
@@ -15200,7 +15351,7 @@ async function getProjectName(projectRoot) {
|
|
|
15200
15351
|
const content = await readTextFile(paths.config);
|
|
15201
15352
|
if (!content)
|
|
15202
15353
|
return null;
|
|
15203
|
-
const config =
|
|
15354
|
+
const config = import_yaml25.default.parse(content);
|
|
15204
15355
|
return config.project ?? null;
|
|
15205
15356
|
} catch {
|
|
15206
15357
|
return null;
|
|
@@ -15209,7 +15360,7 @@ async function getProjectName(projectRoot) {
|
|
|
15209
15360
|
async function destroyProject(projectRoot) {
|
|
15210
15361
|
const removed = [];
|
|
15211
15362
|
const skipped = [];
|
|
15212
|
-
const reapDir =
|
|
15363
|
+
const reapDir = join24(projectRoot, ".reap");
|
|
15213
15364
|
if (await fileExists(reapDir)) {
|
|
15214
15365
|
await rm6(reapDir, { recursive: true, force: true });
|
|
15215
15366
|
removed.push(".reap/");
|
|
@@ -15221,7 +15372,7 @@ async function destroyProject(projectRoot) {
|
|
|
15221
15372
|
return { removed, skipped };
|
|
15222
15373
|
}
|
|
15223
15374
|
async function cleanClaudeMd(projectRoot, removed, skipped) {
|
|
15224
|
-
const claudeMdPath =
|
|
15375
|
+
const claudeMdPath = join24(projectRoot, "CLAUDE.md");
|
|
15225
15376
|
const content = await readTextFile(claudeMdPath);
|
|
15226
15377
|
if (content === null) {
|
|
15227
15378
|
skipped.push("CLAUDE.md (not found)");
|
|
@@ -15246,7 +15397,7 @@ async function cleanClaudeMd(projectRoot, removed, skipped) {
|
|
|
15246
15397
|
}
|
|
15247
15398
|
}
|
|
15248
15399
|
async function cleanGitignore(projectRoot, removed, skipped) {
|
|
15249
|
-
const gitignorePath =
|
|
15400
|
+
const gitignorePath = join24(projectRoot, ".gitignore");
|
|
15250
15401
|
const content = await readTextFile(gitignorePath);
|
|
15251
15402
|
if (content === null) {
|
|
15252
15403
|
skipped.push(".gitignore (not found)");
|
|
@@ -15277,7 +15428,7 @@ async function cleanGitignore(projectRoot, removed, skipped) {
|
|
|
15277
15428
|
await writeTextFile(gitignorePath, cleaned);
|
|
15278
15429
|
removed.push(".gitignore (REAP entries removed)");
|
|
15279
15430
|
}
|
|
15280
|
-
async function
|
|
15431
|
+
async function execute32(confirm) {
|
|
15281
15432
|
const root = process.cwd();
|
|
15282
15433
|
const paths = createPaths(root);
|
|
15283
15434
|
if (await detectV15(paths)) {
|
|
@@ -15311,7 +15462,7 @@ async function execute31(confirm) {
|
|
|
15311
15462
|
|
|
15312
15463
|
// src/cli/commands/clean.ts
|
|
15313
15464
|
import { rm as rm7, readdir as readdir18, mkdir as mkdir4 } from "fs/promises";
|
|
15314
|
-
import { join as
|
|
15465
|
+
import { join as join25 } from "path";
|
|
15315
15466
|
init_fs();
|
|
15316
15467
|
init_integrity();
|
|
15317
15468
|
async function cleanProject(projectRoot, options) {
|
|
@@ -15350,7 +15501,7 @@ async function cleanLineage(lineageDir, mode, actions) {
|
|
|
15350
15501
|
}
|
|
15351
15502
|
if (mode === "delete") {
|
|
15352
15503
|
for (const entry of entries) {
|
|
15353
|
-
await rm7(
|
|
15504
|
+
await rm7(join25(lineageDir, entry), { recursive: true, force: true });
|
|
15354
15505
|
}
|
|
15355
15506
|
actions.push(`Lineage: deleted ${entries.length} item(s)`);
|
|
15356
15507
|
} else {
|
|
@@ -15366,9 +15517,9 @@ async function cleanLineage(lineageDir, mode, actions) {
|
|
|
15366
15517
|
].join(`
|
|
15367
15518
|
`);
|
|
15368
15519
|
for (const dir of genDirs) {
|
|
15369
|
-
await rm7(
|
|
15520
|
+
await rm7(join25(lineageDir, dir), { recursive: true, force: true });
|
|
15370
15521
|
}
|
|
15371
|
-
await writeTextFile(
|
|
15522
|
+
await writeTextFile(join25(lineageDir, `${epochId}.md`), summary);
|
|
15372
15523
|
actions.push(`Lineage: compressed ${genDirs.length} generation(s) into ${epochId}`);
|
|
15373
15524
|
}
|
|
15374
15525
|
}
|
|
@@ -15388,7 +15539,7 @@ async function cleanLife(lifeDir, actions) {
|
|
|
15388
15539
|
for (const entry of entries) {
|
|
15389
15540
|
if (entry === "backlog")
|
|
15390
15541
|
continue;
|
|
15391
|
-
await rm7(
|
|
15542
|
+
await rm7(join25(lifeDir, entry), { recursive: true, force: true });
|
|
15392
15543
|
removedCount++;
|
|
15393
15544
|
}
|
|
15394
15545
|
actions.push(`Life: cleaned ${removedCount} file(s)`);
|
|
@@ -15402,7 +15553,7 @@ async function cleanDir(dirPath, label, actions) {
|
|
|
15402
15553
|
await mkdir4(dirPath, { recursive: true });
|
|
15403
15554
|
actions.push(`${label}: reset`);
|
|
15404
15555
|
}
|
|
15405
|
-
async function
|
|
15556
|
+
async function execute33(options) {
|
|
15406
15557
|
const root = process.cwd();
|
|
15407
15558
|
const hasOptions = options.lineage || options.life || options.backlog || options.hooks;
|
|
15408
15559
|
if (!hasOptions) {
|
|
@@ -15448,14 +15599,14 @@ async function execute32(options) {
|
|
|
15448
15599
|
|
|
15449
15600
|
// src/cli/commands/check-version.ts
|
|
15450
15601
|
init_integrity();
|
|
15451
|
-
var
|
|
15602
|
+
var import_yaml26 = __toESM(require_dist(), 1);
|
|
15452
15603
|
import { execSync as execSync7 } from "child_process";
|
|
15453
15604
|
import { readFileSync as readFileSync3 } from "fs";
|
|
15454
|
-
import { join as
|
|
15605
|
+
import { join as join27 } from "path";
|
|
15455
15606
|
|
|
15456
15607
|
// src/core/notice.ts
|
|
15457
15608
|
import { readFileSync as readFileSync2 } from "fs";
|
|
15458
|
-
import { join as
|
|
15609
|
+
import { join as join26, dirname as dirname9 } from "path";
|
|
15459
15610
|
function findPackageRoot() {
|
|
15460
15611
|
try {
|
|
15461
15612
|
const pkgPath = __require.resolve("@c-d-cc/reap/package.json");
|
|
@@ -15476,7 +15627,7 @@ var LANG_MAP = {
|
|
|
15476
15627
|
};
|
|
15477
15628
|
function fetchReleaseNotice(version, language) {
|
|
15478
15629
|
try {
|
|
15479
|
-
const noticePath =
|
|
15630
|
+
const noticePath = join26(findPackageRoot(), "RELEASE_NOTICE.md");
|
|
15480
15631
|
const content = readFileSync2(noticePath, "utf-8");
|
|
15481
15632
|
const versionTag = version.startsWith("v") ? version : `v${version}`;
|
|
15482
15633
|
const versionPattern = new RegExp(`^## ${versionTag.replace(/\./g, "\\.")}\\s*$`, "m");
|
|
@@ -15621,16 +15772,16 @@ function performAutoUpdate(root) {
|
|
|
15621
15772
|
return { action: "skipped", reason: "error" };
|
|
15622
15773
|
}
|
|
15623
15774
|
}
|
|
15624
|
-
async function
|
|
15775
|
+
async function execute34() {
|
|
15625
15776
|
const root = process.cwd();
|
|
15626
15777
|
await cleanupLegacyHooks(root);
|
|
15627
15778
|
await cleanupLegacyProjectSkills(root);
|
|
15628
15779
|
const result = performAutoUpdate(root);
|
|
15629
15780
|
if (result.action === "upgraded" && result.to) {
|
|
15630
15781
|
try {
|
|
15631
|
-
const configPath =
|
|
15782
|
+
const configPath = join27(root, ".reap", "config.yml");
|
|
15632
15783
|
const configContent = readFileSync3(configPath, "utf-8");
|
|
15633
|
-
const config =
|
|
15784
|
+
const config = import_yaml26.default.parse(configContent);
|
|
15634
15785
|
const language = config?.language ?? "english";
|
|
15635
15786
|
const notice = fetchReleaseNotice(result.to, language);
|
|
15636
15787
|
if (notice)
|
|
@@ -15640,10 +15791,10 @@ async function execute33() {
|
|
|
15640
15791
|
}
|
|
15641
15792
|
|
|
15642
15793
|
// src/cli/commands/config.ts
|
|
15643
|
-
var
|
|
15794
|
+
var import_yaml27 = __toESM(require_dist(), 1);
|
|
15644
15795
|
init_fs();
|
|
15645
15796
|
init_integrity();
|
|
15646
|
-
async function
|
|
15797
|
+
async function execute35() {
|
|
15647
15798
|
const root = process.cwd();
|
|
15648
15799
|
const paths = createPaths(root);
|
|
15649
15800
|
if (!await fileExists(paths.config)) {
|
|
@@ -15656,7 +15807,7 @@ async function execute34() {
|
|
|
15656
15807
|
if (!configContent) {
|
|
15657
15808
|
emitError("config", "Config file is empty.");
|
|
15658
15809
|
}
|
|
15659
|
-
const config =
|
|
15810
|
+
const config = import_yaml27.default.parse(configContent);
|
|
15660
15811
|
emitOutput({
|
|
15661
15812
|
status: "ok",
|
|
15662
15813
|
command: "config",
|
|
@@ -15675,16 +15826,16 @@ async function execute34() {
|
|
|
15675
15826
|
}
|
|
15676
15827
|
|
|
15677
15828
|
// src/cli/commands/update.ts
|
|
15678
|
-
var
|
|
15829
|
+
var import_yaml28 = __toESM(require_dist(), 1);
|
|
15679
15830
|
import { readFileSync as readFileSync4 } from "fs";
|
|
15680
|
-
import { join as
|
|
15831
|
+
import { join as join28, dirname as dirname10 } from "path";
|
|
15681
15832
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
15682
15833
|
init_fs();
|
|
15683
15834
|
init_integrity();
|
|
15684
15835
|
function getPackageVersion() {
|
|
15685
15836
|
try {
|
|
15686
15837
|
const __dir = dirname10(fileURLToPath7(import.meta.url));
|
|
15687
|
-
for (const rel of [
|
|
15838
|
+
for (const rel of [join28(__dir, "..", "..", "package.json"), join28(__dir, "..", "package.json")]) {
|
|
15688
15839
|
try {
|
|
15689
15840
|
return JSON.parse(readFileSync4(rel, "utf-8")).version;
|
|
15690
15841
|
} catch {}
|
|
@@ -15734,7 +15885,7 @@ async function backfillConfig(paths) {
|
|
|
15734
15885
|
return { added: [], removed: [] };
|
|
15735
15886
|
let config;
|
|
15736
15887
|
try {
|
|
15737
|
-
config =
|
|
15888
|
+
config = import_yaml28.default.parse(content) ?? {};
|
|
15738
15889
|
} catch {
|
|
15739
15890
|
return { added: [], removed: [] };
|
|
15740
15891
|
}
|
|
@@ -15760,7 +15911,7 @@ async function backfillConfig(paths) {
|
|
|
15760
15911
|
}
|
|
15761
15912
|
}
|
|
15762
15913
|
if (added.length > 0 || removed.length > 0) {
|
|
15763
|
-
await writeTextFile(paths.config,
|
|
15914
|
+
await writeTextFile(paths.config, import_yaml28.default.stringify(config));
|
|
15764
15915
|
}
|
|
15765
15916
|
return { added, removed };
|
|
15766
15917
|
}
|
|
@@ -15775,7 +15926,7 @@ async function ensureDirectories(paths) {
|
|
|
15775
15926
|
}
|
|
15776
15927
|
return created;
|
|
15777
15928
|
}
|
|
15778
|
-
async function
|
|
15929
|
+
async function execute36(phase, postUpgrade) {
|
|
15779
15930
|
const root = process.cwd();
|
|
15780
15931
|
const paths = createPaths(root);
|
|
15781
15932
|
if (!await fileExists(paths.config) && !await detectV15(paths)) {
|
|
@@ -15784,7 +15935,7 @@ async function execute35(phase, postUpgrade) {
|
|
|
15784
15935
|
if (!postUpgrade) {
|
|
15785
15936
|
if (await detectV15(paths)) {
|
|
15786
15937
|
try {
|
|
15787
|
-
await
|
|
15938
|
+
await execute5(paths, phase);
|
|
15788
15939
|
} catch (err) {
|
|
15789
15940
|
try {
|
|
15790
15941
|
autoReport("reap update (migration)", err, ["migration"]);
|
|
@@ -15811,7 +15962,7 @@ async function execute35(phase, postUpgrade) {
|
|
|
15811
15962
|
let agentClient;
|
|
15812
15963
|
if (configContent) {
|
|
15813
15964
|
try {
|
|
15814
|
-
const config =
|
|
15965
|
+
const config = import_yaml28.default.parse(configContent);
|
|
15815
15966
|
projectName = config.project ?? "my-project";
|
|
15816
15967
|
agentClient = config.agentClient;
|
|
15817
15968
|
} catch {}
|
|
@@ -15828,7 +15979,7 @@ async function execute35(phase, postUpgrade) {
|
|
|
15828
15979
|
const raw = configContent ?? "";
|
|
15829
15980
|
if (raw) {
|
|
15830
15981
|
try {
|
|
15831
|
-
const cfg =
|
|
15982
|
+
const cfg = import_yaml28.default.parse(raw);
|
|
15832
15983
|
if (cfg?.language)
|
|
15833
15984
|
language = cfg.language;
|
|
15834
15985
|
} catch {}
|
|
@@ -15858,7 +16009,7 @@ async function execute35(phase, postUpgrade) {
|
|
|
15858
16009
|
}
|
|
15859
16010
|
|
|
15860
16011
|
// src/cli/commands/help.ts
|
|
15861
|
-
import { join as
|
|
16012
|
+
import { join as join29 } from "path";
|
|
15862
16013
|
init_fs();
|
|
15863
16014
|
var SUPPORTED_LANGUAGES = ["en", "ko", "ja", "zh-CN"];
|
|
15864
16015
|
var LANGUAGE_ALIASES = {
|
|
@@ -16025,7 +16176,7 @@ function buildHelpLines(lang, stateDisplay) {
|
|
|
16025
16176
|
CONFIG_LINE[lang]
|
|
16026
16177
|
];
|
|
16027
16178
|
}
|
|
16028
|
-
async function
|
|
16179
|
+
async function execute37(topic) {
|
|
16029
16180
|
const paths = createPaths(process.cwd());
|
|
16030
16181
|
const configContent = await readTextFile(paths.config);
|
|
16031
16182
|
const rawLang = detectLanguage(configContent);
|
|
@@ -16036,7 +16187,7 @@ async function execute36(topic) {
|
|
|
16036
16187
|
const stateDisplay = buildStateDisplay(state, lang);
|
|
16037
16188
|
const lines = buildHelpLines(lang, stateDisplay);
|
|
16038
16189
|
if (topic) {
|
|
16039
|
-
const reapGuidePath =
|
|
16190
|
+
const reapGuidePath = join29(paths.reap, "reap-guide.md");
|
|
16040
16191
|
const reapGuide = await readTextFile(reapGuidePath) ?? "";
|
|
16041
16192
|
emitOutput({
|
|
16042
16193
|
status: "prompt",
|
|
@@ -16081,7 +16232,7 @@ async function execute36(topic) {
|
|
|
16081
16232
|
// src/cli/commands/daemon/index.ts
|
|
16082
16233
|
init_client();
|
|
16083
16234
|
init_fs();
|
|
16084
|
-
async function
|
|
16235
|
+
async function execute38(subcommand, options) {
|
|
16085
16236
|
switch (subcommand) {
|
|
16086
16237
|
case "status":
|
|
16087
16238
|
return statusCmd();
|
|
@@ -16194,83 +16345,6 @@ ${lines.join(`
|
|
|
16194
16345
|
});
|
|
16195
16346
|
}
|
|
16196
16347
|
|
|
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
16348
|
// src/cli/commands/dump-state.ts
|
|
16275
16349
|
init_fs();
|
|
16276
16350
|
async function execute39(opts = {}) {
|
|
@@ -16325,31 +16399,31 @@ function readVersion() {
|
|
|
16325
16399
|
var program2 = new Command;
|
|
16326
16400
|
program2.name("reap").description("Recursive Evolutionary Autonomous Pipeline — Self-Evolving").version(readVersion());
|
|
16327
16401
|
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
|
|
16402
|
+
await execute6(projectName, options.mode, options.repair, options.migrate, options.phase);
|
|
16329
16403
|
});
|
|
16330
16404
|
program2.command("status").description("Show current project status").action(async () => {
|
|
16331
|
-
await
|
|
16405
|
+
await execute7();
|
|
16332
16406
|
});
|
|
16333
16407
|
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
|
|
16408
|
+
await execute27(stage, options);
|
|
16335
16409
|
});
|
|
16336
16410
|
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
|
|
16411
|
+
await execute28(resource, options);
|
|
16338
16412
|
});
|
|
16339
16413
|
program2.command("cruise <count>").description("Enable cruise mode for N generations").action(async (count) => {
|
|
16340
|
-
await
|
|
16414
|
+
await execute29(count);
|
|
16341
16415
|
});
|
|
16342
16416
|
program2.command("install-skills").description("Install Claude Code skill files to .claude/commands/").action(async () => {
|
|
16343
|
-
await
|
|
16417
|
+
await execute30();
|
|
16344
16418
|
});
|
|
16345
16419
|
program2.command("fix").description("Diagnose and repair .reap/ directory structure").option("--check", "Check only — report issues without fixing").action(async (options) => {
|
|
16346
|
-
await
|
|
16420
|
+
await execute31(options.check);
|
|
16347
16421
|
});
|
|
16348
16422
|
program2.command("destroy").description("Completely remove REAP from this project").option("--confirm", "Confirm destruction without prompt").action(async (options) => {
|
|
16349
|
-
await
|
|
16423
|
+
await execute32(options.confirm);
|
|
16350
16424
|
});
|
|
16351
16425
|
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
|
|
16426
|
+
await execute33({
|
|
16353
16427
|
lineage: options.lineage,
|
|
16354
16428
|
life: options.life,
|
|
16355
16429
|
backlog: options.backlog,
|
|
@@ -16357,24 +16431,24 @@ program2.command("clean").description("Selectively reset REAP project state").op
|
|
|
16357
16431
|
});
|
|
16358
16432
|
});
|
|
16359
16433
|
program2.command("check-version").description("Check for v0.15 project and show migration message").action(async () => {
|
|
16360
|
-
await
|
|
16434
|
+
await execute34();
|
|
16361
16435
|
});
|
|
16362
16436
|
program2.command("config").description("Show current REAP project configuration").action(async () => {
|
|
16363
|
-
await
|
|
16437
|
+
await execute35();
|
|
16364
16438
|
});
|
|
16365
16439
|
program2.command("help [topic]").description("Show REAP commands and workflow overview").action(async (topic) => {
|
|
16366
|
-
await
|
|
16440
|
+
await execute37(topic);
|
|
16367
16441
|
});
|
|
16368
16442
|
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
|
|
16443
|
+
await execute36(options.phase, options.postUpgrade);
|
|
16370
16444
|
});
|
|
16371
16445
|
program2.command("load-context").description("Output REAP project knowledge for SessionStart hook injection").action(async () => {
|
|
16372
|
-
await
|
|
16446
|
+
await execute();
|
|
16373
16447
|
});
|
|
16374
16448
|
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
16449
|
await execute39({ stdout: options.stdout, silent: options.silent });
|
|
16376
16450
|
});
|
|
16377
16451
|
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
|
|
16452
|
+
await execute38(subcommand, options);
|
|
16379
16453
|
});
|
|
16380
16454
|
program2.parse();
|