@c-d-cc/reap 0.15.12 → 0.15.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RELEASE_NOTICE.md +12 -0
- package/dist/cli.js +758 -1863
- package/dist/templates/hooks/opencode-session-start.js +25 -4
- package/dist/templates/hooks/session-start.cjs +27 -5
- package/package.json +4 -2
|
@@ -5,6 +5,17 @@ const { execSync } = require("child_process");
|
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
7
7
|
|
|
8
|
+
// Inline semver comparison (no external deps): returns true if a >= b
|
|
9
|
+
function semverGte(a, b) {
|
|
10
|
+
const pa = a.split(".").map(Number);
|
|
11
|
+
const pb = b.split(".").map(Number);
|
|
12
|
+
for (let i = 0; i < 3; i++) {
|
|
13
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return true;
|
|
14
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
8
19
|
module.exports = async (ctx) => {
|
|
9
20
|
return {
|
|
10
21
|
"session.start": async ({ trigger }) => {
|
|
@@ -50,9 +61,15 @@ module.exports = async (ctx) => {
|
|
|
50
61
|
const installed = gl.exec("reap --version 2>/dev/null", execOpts);
|
|
51
62
|
const latest = gl.exec("npm view @c-d-cc/reap version 2>/dev/null", execOpts);
|
|
52
63
|
if (installed && latest && installed !== latest) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
64
|
+
// Auto-update guard: check autoUpdateMinVersion
|
|
65
|
+
const minVersion = gl.exec("npm view @c-d-cc/reap reap.autoUpdateMinVersion 2>/dev/null", execOpts);
|
|
66
|
+
if (minVersion && !semverGte(installed, minVersion)) {
|
|
67
|
+
autoUpdateMessage = `[BREAKING] Auto-update blocked: v${installed} -> v${latest} contains breaking changes. Inform the user about this breaking change and ask if they want to update via '/reap.update'. Release notes: https://reap.cc/docs/release-notes`;
|
|
68
|
+
} else {
|
|
69
|
+
execSync("npm update -g @c-d-cc/reap >/dev/null 2>&1", { ...execOpts, stdio: "ignore" });
|
|
70
|
+
execSync("reap update >/dev/null 2>&1", { ...execOpts, stdio: "ignore" });
|
|
71
|
+
autoUpdateMessage = `REAP auto-updated: v${installed} → v${latest}`;
|
|
72
|
+
}
|
|
56
73
|
}
|
|
57
74
|
} catch { /* update check failed, skip */ }
|
|
58
75
|
}
|
|
@@ -109,7 +126,11 @@ module.exports = async (ctx) => {
|
|
|
109
126
|
// Build auto-update section
|
|
110
127
|
let updateSection = "";
|
|
111
128
|
if (autoUpdateMessage) {
|
|
112
|
-
|
|
129
|
+
if (autoUpdateMessage.startsWith("[BREAKING]")) {
|
|
130
|
+
updateSection = `\n\n## Auto-Update (Breaking Change Detected)\n${autoUpdateMessage}\n\nIMPORTANT: On your first response, explain to the user that a new REAP version is available but contains breaking changes. Show them the release notes link and ask for explicit confirmation before they run the manual update command. Do NOT silently skip this.`;
|
|
131
|
+
} else {
|
|
132
|
+
updateSection = `\n\n## Auto-Update\n${autoUpdateMessage}. Tell the user: "${autoUpdateMessage}"`;
|
|
133
|
+
}
|
|
113
134
|
}
|
|
114
135
|
|
|
115
136
|
const context = `<REAP_WORKFLOW>\n${reapGuide}\n\n---\n\n## Genome (Project Knowledge)\n${genomeContent}\n\n---\n\n## Current State\n${generationContext}${staleSection}${strictSection}${updateSection}${langSection}\n\n## Rules\n1. ALL development work MUST follow the REAP lifecycle.\n2. Before writing any code, check if a Generation is active and what stage it is in.\n3. If a Generation is active, use \`${nextCmd}\` to proceed with the current stage.\n4. If no Generation is active, use \`/reap.start\` to start a new one.\n5. Do NOT implement features outside of the REAP lifecycle unless explicitly asked.\n6. Genome is the authoritative knowledge source.\n</REAP_WORKFLOW>`;
|
|
@@ -117,6 +117,17 @@ if (gl.dirExists(userReapCommands)) {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
// Inline semver comparison (no external deps): returns true if a >= b
|
|
121
|
+
function semverGte(a, b) {
|
|
122
|
+
const pa = a.split('.').map(Number);
|
|
123
|
+
const pb = b.split('.').map(Number);
|
|
124
|
+
for (let i = 0; i < 3; i++) {
|
|
125
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return true;
|
|
126
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return false;
|
|
127
|
+
}
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
|
|
120
131
|
// Step 1: Version check + Auto-update
|
|
121
132
|
log('Checking for updates...');
|
|
122
133
|
let autoUpdateMessage = '';
|
|
@@ -129,10 +140,17 @@ if (installed && installed.includes('+dev')) {
|
|
|
129
140
|
} else if (installed && latest && installed !== latest) {
|
|
130
141
|
const autoUpdate = configContent ? /^autoUpdate:\s*true/m.test(configContent) : false;
|
|
131
142
|
if (autoUpdate) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
143
|
+
// Auto-update guard: check autoUpdateMinVersion before upgrading
|
|
144
|
+
const minVersion = gl.exec('npm view @c-d-cc/reap reap.autoUpdateMinVersion');
|
|
145
|
+
if (minVersion && !semverGte(installed, minVersion)) {
|
|
146
|
+
// Breaking change detected — block auto-update
|
|
147
|
+
autoUpdateMessage = `[BREAKING] Auto-update blocked: v${installed} → v${latest} contains breaking changes. Inform the user about this breaking change and ask if they want to update via '/reap.update'. Release notes: https://reap.cc/docs/release-notes`;
|
|
148
|
+
} else {
|
|
149
|
+
const updated = gl.exec('npm update -g @c-d-cc/reap');
|
|
150
|
+
if (updated !== null) {
|
|
151
|
+
gl.exec('reap update');
|
|
152
|
+
autoUpdateMessage = `REAP auto-updated: v${installed} → v${latest}`;
|
|
153
|
+
}
|
|
136
154
|
}
|
|
137
155
|
} else {
|
|
138
156
|
updateAvailableMessage = `update available: v${installed} → v${latest}`;
|
|
@@ -178,7 +196,11 @@ if (genomeStaleWarning) {
|
|
|
178
196
|
// Build auto-update section
|
|
179
197
|
let updateSection = '';
|
|
180
198
|
if (autoUpdateMessage) {
|
|
181
|
-
|
|
199
|
+
if (autoUpdateMessage.startsWith('[BREAKING]')) {
|
|
200
|
+
updateSection = `\n\n## Auto-Update (Breaking Change Detected)\n${autoUpdateMessage}\n\nIMPORTANT: On your first response, explain to the user that a new REAP version is available but contains breaking changes. Show them the release notes link and ask for explicit confirmation before they run the manual update command. Do NOT silently skip this.`;
|
|
201
|
+
} else {
|
|
202
|
+
updateSection = `\n\n## Auto-Update\n${autoUpdateMessage}. Tell the user: "${autoUpdateMessage}"`;
|
|
203
|
+
}
|
|
182
204
|
}
|
|
183
205
|
|
|
184
206
|
// Build session init display
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c-d-cc/reap",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.14",
|
|
4
4
|
"description": "Recursive Evolutionary Autonomous Pipeline — AI and humans evolve software across generations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,9 @@
|
|
|
45
45
|
"typescript": "^5.0.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"commander": "^12.0.0",
|
|
49
48
|
"yaml": "^2.0.0"
|
|
49
|
+
},
|
|
50
|
+
"reap": {
|
|
51
|
+
"autoUpdateMinVersion": "0.15.0"
|
|
50
52
|
}
|
|
51
53
|
}
|