@walwal-harness/cli 4.0.0-beta.5 → 4.0.0-beta.6

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.
Files changed (2) hide show
  1. package/bin/init.js +27 -63
  2. package/package.json +1 -1
package/bin/init.js CHANGED
@@ -225,25 +225,24 @@ function installSkills() {
225
225
  return;
226
226
  }
227
227
 
228
+ // harness- 프리픽스 스킬 전체 삭제 후 재복사 — 잔류 방지
229
+ if (fs.existsSync(CLAUDE_SKILLS_DIR)) {
230
+ const existing = fs.readdirSync(CLAUDE_SKILLS_DIR, { withFileTypes: true });
231
+ for (const entry of existing) {
232
+ if (entry.isDirectory() && entry.name.startsWith('harness-')) {
233
+ fs.rmSync(path.join(CLAUDE_SKILLS_DIR, entry.name), { recursive: true, force: true });
234
+ }
235
+ }
236
+ log(' Cleared existing harness-* skills');
237
+ }
238
+
228
239
  const skills = fs.readdirSync(skillsSrc, { withFileTypes: true })
229
240
  .filter(d => d.isDirectory())
230
241
  .map(d => d.name);
231
242
 
232
- // Remove obsolete skills (cleaned up in v4)
233
- const obsoleteSkills = ['harness-generator-frontend-flutter', 'harness-evaluator-functional-flutter', 'harness-team'];
234
- for (const obs of obsoleteSkills) {
235
- const obsPath = path.join(CLAUDE_SKILLS_DIR, obs);
236
- if (fs.existsSync(obsPath)) {
237
- fs.rmSync(obsPath, { recursive: true, force: true });
238
- log(` Removed obsolete: ${obs}`);
239
- }
240
- }
241
-
242
243
  for (const skill of skills) {
243
244
  const src = path.join(skillsSrc, skill);
244
245
  const dest = path.join(CLAUDE_SKILLS_DIR, `harness-${skill}`);
245
-
246
- // Skills are ALWAYS overwritten — they are harness-managed, not user-editable
247
246
  copyDir(src, dest);
248
247
  log(` Installed: harness-${skill}`);
249
248
  }
@@ -260,63 +259,28 @@ function installScripts() {
260
259
  const scriptsSrc = path.join(PKG_ROOT, 'scripts');
261
260
  const scriptsDest = path.join(PROJECT_ROOT, 'scripts');
262
261
 
263
- // Remove obsolete scripts from previous versions
264
- const obsoleteScripts = [
265
- 'harness-studio-v4.sh',
266
- 'harness-control-v4.sh',
267
- 'harness-prompts-v4.sh',
268
- 'harness-team-worker.sh',
269
- ];
270
- for (const obs of obsoleteScripts) {
271
- const obsPath = path.join(scriptsDest, obs);
272
- if (fs.existsSync(obsPath)) {
273
- fs.unlinkSync(obsPath);
274
- log(` Removed obsolete: ${obs}`);
275
- }
262
+ // 전체 삭제 재복사 버전 간 잔류 파일 방지
263
+ if (fs.existsSync(scriptsDest)) {
264
+ fs.rmSync(scriptsDest, { recursive: true, force: true });
265
+ log(' Cleared existing scripts/');
276
266
  }
277
267
 
278
- // Core scripts are ALWAYS overwritten on update (not user-editable)
279
- // These contain harness logic that must stay in sync with the CLI version
280
- const coreScripts = new Set([
281
- 'harness-next.sh',
282
- 'harness-session-start.sh',
283
- 'harness-statusline.sh',
284
- 'harness-user-prompt-submit.sh',
285
- 'harness-dashboard.sh',
286
- 'harness-monitor.sh',
287
- 'harness-eval-watcher.sh',
288
- 'harness-tmux.sh',
289
- 'harness-control.sh',
290
- 'harness-dashboard-v4.sh',
291
- 'harness-queue-manager.sh',
292
- ]);
293
-
294
268
  if (fs.existsSync(scriptsSrc)) {
295
- ensureDir(scriptsDest);
296
- const entries = fs.readdirSync(scriptsSrc, { withFileTypes: true });
297
- for (const entry of entries) {
298
- const srcPath = path.join(scriptsSrc, entry.name);
299
- const destPath = path.join(scriptsDest, entry.name);
300
- if (entry.isDirectory()) {
301
- // lib/ and other subdirectories — always overwrite
302
- copyDir(srcPath, destPath);
303
- try {
304
- const subFiles = fs.readdirSync(destPath);
305
- for (const f of subFiles) {
306
- if (f.endsWith('.sh')) {
307
- fs.chmodSync(path.join(destPath, f), '755');
308
- }
309
- }
310
- } catch (e) {}
311
- } else {
312
- // Core scripts: always overwrite. Others: skip if exists (unless --force)
313
- const isCore = coreScripts.has(entry.name);
314
- if (isCore || !fileExists(destPath) || isForce) {
315
- copyFile(srcPath, destPath);
316
- try { fs.chmodSync(destPath, '755'); } catch (e) {}
269
+ copyDir(scriptsSrc, scriptsDest);
270
+
271
+ // chmod +x for all .sh files (recursive)
272
+ function chmodRecursive(dir) {
273
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
274
+ for (const entry of entries) {
275
+ const full = path.join(dir, entry.name);
276
+ if (entry.isDirectory()) {
277
+ chmodRecursive(full);
278
+ } else if (entry.name.endsWith('.sh')) {
279
+ try { fs.chmodSync(full, '755'); } catch (e) {}
317
280
  }
318
281
  }
319
282
  }
283
+ chmodRecursive(scriptsDest);
320
284
  }
321
285
 
322
286
  log('Scripts installation complete');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@walwal-harness/cli",
3
- "version": "4.0.0-beta.5",
3
+ "version": "4.0.0-beta.6",
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"