@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 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
- // Copy subdirectories (e.g., lib/)
225
- if (!fileExists(destPath) || isForce) {
226
- copyDir(srcPath, destPath);
227
- // Make scripts in subdirs executable
228
- try {
229
- const subFiles = fs.readdirSync(destPath);
230
- for (const f of subFiles) {
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
- } catch (e) {}
236
- }
245
+ }
246
+ } catch (e) {}
237
247
  } else {
238
- if (!fileExists(destPath) || isForce) {
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.0",
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"
@@ -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
- if [ "$current_agent" = "generator-frontend" ] || [ "$current_agent" = "generator-frontend-flutter" ]; then
103
- location="frontend"
104
- checks_key="frontend_checks"
105
- fi
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)