@walwal-harness/cli 3.7.0 → 3.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/init.js +25 -13
- package/package.json +1 -1
- package/scripts/harness-next.sh +30 -4
package/bin/init.js
CHANGED
|
@@ -214,6 +214,19 @@ function installScripts() {
|
|
|
214
214
|
const scriptsSrc = path.join(PKG_ROOT, 'scripts');
|
|
215
215
|
const scriptsDest = path.join(PROJECT_ROOT, 'scripts');
|
|
216
216
|
|
|
217
|
+
// Core scripts are ALWAYS overwritten on update (not user-editable)
|
|
218
|
+
// These contain harness logic that must stay in sync with the CLI version
|
|
219
|
+
const coreScripts = new Set([
|
|
220
|
+
'harness-next.sh',
|
|
221
|
+
'harness-session-start.sh',
|
|
222
|
+
'harness-statusline.sh',
|
|
223
|
+
'harness-user-prompt-submit.sh',
|
|
224
|
+
'harness-dashboard.sh',
|
|
225
|
+
'harness-monitor.sh',
|
|
226
|
+
'harness-eval-watcher.sh',
|
|
227
|
+
'harness-tmux.sh',
|
|
228
|
+
]);
|
|
229
|
+
|
|
217
230
|
if (fs.existsSync(scriptsSrc)) {
|
|
218
231
|
ensureDir(scriptsDest);
|
|
219
232
|
const entries = fs.readdirSync(scriptsSrc, { withFileTypes: true });
|
|
@@ -221,21 +234,20 @@ function installScripts() {
|
|
|
221
234
|
const srcPath = path.join(scriptsSrc, entry.name);
|
|
222
235
|
const destPath = path.join(scriptsDest, entry.name);
|
|
223
236
|
if (entry.isDirectory()) {
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (f.endsWith('.sh')) {
|
|
232
|
-
fs.chmodSync(path.join(destPath, f), '755');
|
|
233
|
-
}
|
|
237
|
+
// lib/ and other subdirectories — always overwrite
|
|
238
|
+
copyDir(srcPath, destPath);
|
|
239
|
+
try {
|
|
240
|
+
const subFiles = fs.readdirSync(destPath);
|
|
241
|
+
for (const f of subFiles) {
|
|
242
|
+
if (f.endsWith('.sh')) {
|
|
243
|
+
fs.chmodSync(path.join(destPath, f), '755');
|
|
234
244
|
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
245
|
+
}
|
|
246
|
+
} catch (e) {}
|
|
237
247
|
} else {
|
|
238
|
-
if (
|
|
248
|
+
// Core scripts: always overwrite. Others: skip if exists (unless --force)
|
|
249
|
+
const isCore = coreScripts.has(entry.name);
|
|
250
|
+
if (isCore || !fileExists(destPath) || isForce) {
|
|
239
251
|
copyFile(srcPath, destPath);
|
|
240
252
|
try { fs.chmodSync(destPath, '755'); } catch (e) {}
|
|
241
253
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.1",
|
|
4
4
|
"description": "Production harness for AI agent engineering — Planner, Generator(BE/FE), Evaluator(Func/Visual), optional Brainstormer (requirements refinement). Supports React and Flutter FE stacks.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"walwal-harness": "bin/init.js"
|
package/scripts/harness-next.sh
CHANGED
|
@@ -97,12 +97,38 @@ run_pre_eval_gate() {
|
|
|
97
97
|
timeout=$(jq -r '.flow.pre_eval_gate.timeout_seconds // 120' "$CONFIG" 2>/dev/null)
|
|
98
98
|
|
|
99
99
|
# 실패 위치 결정 (backend or frontend)
|
|
100
|
+
# current_agent가 실패로 변경된 경우, completed_agents에서 직전 Generator를 찾는다
|
|
100
101
|
local location="backend"
|
|
101
102
|
local checks_key="backend_checks"
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
local source_agent="$current_agent"
|
|
104
|
+
|
|
105
|
+
# current_agent가 generator가 아닌 경우 (예: dispatcher로 리라우팅된 상태),
|
|
106
|
+
# completed_agents에서 마지막 generator를 찾는다
|
|
107
|
+
case "$source_agent" in
|
|
108
|
+
generator-frontend|generator-frontend-flutter)
|
|
109
|
+
location="frontend"
|
|
110
|
+
checks_key="frontend_checks"
|
|
111
|
+
;;
|
|
112
|
+
generator-backend)
|
|
113
|
+
location="backend"
|
|
114
|
+
checks_key="backend_checks"
|
|
115
|
+
;;
|
|
116
|
+
*)
|
|
117
|
+
# completed_agents에서 마지막 generator를 역순으로 찾기
|
|
118
|
+
local last_gen
|
|
119
|
+
last_gen=$(jq -r '.completed_agents // [] | map(select(startswith("generator-"))) | last // empty' "$PROGRESS" 2>/dev/null)
|
|
120
|
+
case "$last_gen" in
|
|
121
|
+
generator-frontend|generator-frontend-flutter)
|
|
122
|
+
location="frontend"
|
|
123
|
+
checks_key="frontend_checks"
|
|
124
|
+
;;
|
|
125
|
+
generator-backend)
|
|
126
|
+
location="backend"
|
|
127
|
+
checks_key="backend_checks"
|
|
128
|
+
;;
|
|
129
|
+
esac
|
|
130
|
+
;;
|
|
131
|
+
esac
|
|
106
132
|
|
|
107
133
|
local -a checks
|
|
108
134
|
mapfile -t checks < <(jq -r ".flow.pre_eval_gate.${checks_key}[]" "$CONFIG" 2>/dev/null)
|