@walwal-harness/cli 6.0.4 → 6.1.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/CHANGELOG.md CHANGED
@@ -29,6 +29,69 @@ docmeta:
29
29
 
30
30
  # Changelog
31
31
 
32
+ ## 6.1.0 — document-driven company loop + task-session isolation (2026-05-08)
33
+
34
+ ### Why
35
+ v6.0.x 는 회사형 조직 비유와 Cxx 라우팅을 문서로는 설명했지만, 실제 런타임은 여전히 얕았다. 특히 다음 두 결함이 컸다.
36
+
37
+ - 회의 결과가 `누가 다음 owner 인가` 를 구조적으로 기록하지 않음
38
+ - `goal_adherence` 하락 시 원인 분류 없이 Planner로 보내는 경향이 있음
39
+
40
+ 또한 agent 간 자기강화 편향을 줄이기 위한 문서 중심 task session 분리도 충분히 강제되지 않았다.
41
+
42
+ ### Changes
43
+ - **document-driven meeting decision**
44
+ - `meeting-manager` 가 `notice.md`, `prep-*.md`, `meeting-<id>.md` skeleton 을 자동 생성
45
+ - 회의 기록에 `decision.owner`, `action_type`, `rationale`, `evidence`, `drift_classification` JSON 블록 추가
46
+ - `conductor-tick` 은 더 이상 `meeting_reason` 문자열만 보지 않고 회의 decision 문서를 우선 읽어 다음 owner 를 결정
47
+ - **goal drift classification**
48
+ - `implementation_drift | planning_drift | ops_drift | goal_drift` 분류 추가
49
+ - 분류별 기본 라우팅:
50
+ - `implementation_drift -> cto`
51
+ - `planning_drift -> planner`
52
+ - `ops_drift -> service-ops`
53
+ - `goal_drift -> dispatcher`
54
+ - **task-session isolation**
55
+ - `harness-next` 가 다음 agent 마다 `.harness/actions/task-sessions/<agent>/<id>.md` 생성
56
+ - `handoff.json` 에 `task_session_path` 추가
57
+ - `UserPromptSubmit` 가 running agent 와 다른 `/harness-*` 호출을 경고가 아니라 **hard block**
58
+ - **direct invocation policy**
59
+ - 모든 harness skill 의 `disable-model-invocation` 을 `false` 로 통일
60
+ - orchestration/control-plane 과 worker/evaluator 모두 직접 호출 가능 상태로 정리
61
+ - **archive reset hardening**
62
+ - archive 시 `workflow`, `meetings.decision`, `service_ops.drift_classification`, `task_sessions.current` 초기화
63
+
64
+ ### Validation
65
+ - `bash -n` 으로 주요 스크립트 문법 검증
66
+ - `jq empty` 로 `config.json`, `progress.json` 검증
67
+ - `/private/tmp` 샌드박스에서:
68
+ - `dispatcher -> meeting-manager` 시 회의 문서 자동 생성 확인
69
+ - 회의 decision 편집 후 `dispatcher / planner / cto` 로 문서 기반 재라우팅 확인
70
+ - `goal_adherence` 하락 시 drift classification 반영 확인
71
+ - context isolation hard block 확인
72
+ - `task_session_path` 생성 확인
73
+
74
+ ## 6.0.5 — migrate 가 gotcha entry / bundle version 까지 sync (2026-05-07)
75
+
76
+ ### Why
77
+ Owner 보고 — `npm install @walwal-harness/cli@latest && npx walwal-harness migrate` 가 "이미 최신 버전입니다" 로 종료. 그러나 v6.0.4 에서 새로 추가된 `gotchas/conductor.md` 의 [G-005], [G-006], `gotchas/service-ops.md`, `gotchas/generator-frontend.md [G-001]` 가 사용자 프로젝트에 merge 되지 않음. **존재 여부 (3 항목 — progress v4 / config.mode_selection / M-NEXUS-P3) 만 확인하고 콘텐츠는 비교 안 함** → 본질적 버그.
78
+
79
+ ### Changes
80
+ - **bin/init.js `detectMigrationNeeded`** — 두 신규 시그널 추가:
81
+ - `gotchaMissingEntries`: `gotchas/*.md` 별로 패키지 → 사용자 [G-NNN] entry 차이 산출 (memory.md 패턴과 동일)
82
+ - `bundleVersionStale`: `.harness/.bundle-version` 스탬프와 패키지 버전 비교
83
+ - **bin/init.js `runMigrate`** — gotcha entry append + bundle stamp 갱신 단계 추가. 사용자가 직접 추가한 [G-NNN] entry 는 절대 건드리지 않으며, 패키지의 신규 시스템 entry 만 끝에 추가.
84
+ - **bin/init.js `extractGotchaEntryBlock` / `extractEntryBlock`** — JS 정규식 `\Z` 미지원 fix. 마지막 entry 가 추출 누락되던 버그 동시 해결 (v6.0.2 부터 잠재).
85
+ - **bin/init.js main flow** — 콘텐츠 드리프트 없이 stamp 만 누락된 경우 init 종료 시 자동 갱신. stamp 만으로 매번 migrate 권유 알림이 뜨는 것 방지.
86
+
87
+ ### Migration
88
+ ```bash
89
+ npm install @walwal-harness/cli@latest
90
+ npx walwal-harness migrate # gotchas/conductor.md G-005/G-006, gotchas/service-ops.md, gotchas/generator-frontend.md G-001 자동 append + stamp 갱신
91
+ npx walwal-harness verify
92
+ ```
93
+ 사용자 [G-NNN] entry 는 보존되고 시스템 entry 만 끝에 append. 변경 전 `.harness/archive/migration-<ts>/gotchas-<file>` 백업.
94
+
32
95
  ## 6.0.4 — Sub-skill 협업 + Service-Ops 상시 + Team 병렬 spawn (2026-05-07)
33
96
 
34
97
  ### Why
package/bin/init.js CHANGED
@@ -988,7 +988,41 @@ function detectMigrationNeeded() {
988
988
  progressV3toV4: false,
989
989
  configMissingModeSelection: false,
990
990
  memoryMissingSystemEntries: [],
991
+ gotchaMissingEntries: {}, // { "<filename>": [G-IDs...] }
992
+ bundleVersionStale: null, // { current, installed }
991
993
  };
994
+
995
+ // Gotcha entry-level diff: for each bundled gotcha file, compare entry IDs.
996
+ // 사용자가 직접 추가한 [G-NNN] 은 절대 건드리지 않으며, 패키지에서 새로
997
+ // 도입된 시스템 entry 만 append 대상.
998
+ const gotchasSrc = path.join(PKG_ROOT, 'gotchas');
999
+ const gotchasDest = path.join(HARNESS_DIR, 'gotchas');
1000
+ if (fs.existsSync(gotchasSrc) && fs.existsSync(gotchasDest)) {
1001
+ const files = fs.readdirSync(gotchasSrc).filter((f) => f.endsWith('.md') && f !== 'README.md');
1002
+ for (const file of files) {
1003
+ const srcPath = path.join(gotchasSrc, file);
1004
+ const destPath = path.join(gotchasDest, file);
1005
+ if (!fs.existsSync(destPath)) continue; // installSkills/init 이 처리
1006
+ try {
1007
+ const srcIds = extractGotchaEntryIds(fs.readFileSync(srcPath, 'utf8'));
1008
+ const dstIds = new Set(extractGotchaEntryIds(fs.readFileSync(destPath, 'utf8')));
1009
+ const missing = srcIds.filter((id) => !dstIds.has(id));
1010
+ if (missing.length) flags.gotchaMissingEntries[file] = missing;
1011
+ } catch {}
1012
+ }
1013
+ }
1014
+
1015
+ // Bundle version stamp: detects fresh package vs. last-applied bundle.
1016
+ // Even if the 3 schema flags pass, a newer bundle may have introduced new
1017
+ // gotcha/SKILL/template content the user hasn't seen yet.
1018
+ try {
1019
+ const pkg = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8'));
1020
+ const stampPath = path.join(HARNESS_DIR, '.bundle-version');
1021
+ const installed = fs.existsSync(stampPath) ? fs.readFileSync(stampPath, 'utf8').trim() : null;
1022
+ if (installed !== pkg.version) {
1023
+ flags.bundleVersionStale = { current: pkg.version, installed };
1024
+ }
1025
+ } catch {}
992
1026
  if (fs.existsSync(progressPath)) {
993
1027
  try {
994
1028
  const p = JSON.parse(fs.readFileSync(progressPath, 'utf8'));
@@ -1025,7 +1059,29 @@ function extractEntryIds(md) {
1025
1059
  // Extracts a single entry block (heading + body until next ### or EOF) from the template.
1026
1060
  function extractEntryBlock(md, id) {
1027
1061
  const escId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1028
- const re = new RegExp(`(^### \\[${escId}\\][\\s\\S]*?)(?=^### \\[|\\Z)`, 'm');
1062
+ const re = new RegExp(`(^### \\[${escId}\\][\\s\\S]*?)(?=^### \\[|$(?![\\s\\S]))`, 'm');
1063
+ const m = md.match(re);
1064
+ return m ? m[1].trimEnd() : null;
1065
+ }
1066
+
1067
+ // Returns gotcha entry IDs ("[G-001]", "[G-NEXUS-P3]" etc.) found in a markdown body.
1068
+ // Supports both `### [G-NNN]` and `## [G-NNN] ...` heading levels.
1069
+ function extractGotchaEntryIds(md) {
1070
+ const re = /^#{2,3}\s+\[(G-[A-Z0-9_-]+)\]/gm;
1071
+ const ids = [];
1072
+ let m;
1073
+ while ((m = re.exec(md)) !== null) ids.push(m[1]);
1074
+ return ids;
1075
+ }
1076
+
1077
+ // Extracts a single gotcha entry block from a markdown body.
1078
+ function extractGotchaEntryBlock(md, id) {
1079
+ const escId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1080
+ // JS lacks \Z; emulate end-of-string via (?![\s\S]) negative lookahead.
1081
+ const re = new RegExp(
1082
+ `(^#{2,3}\\s+\\[${escId}\\][\\s\\S]*?)(?=^#{2,3}\\s+\\[G-|$(?![\\s\\S]))`,
1083
+ 'm',
1084
+ );
1029
1085
  const m = md.match(re);
1030
1086
  return m ? m[1].trimEnd() : null;
1031
1087
  }
@@ -1048,6 +1104,17 @@ function showMigrationProposal(flags) {
1048
1104
  console.log(' [' + flags.memoryMissingSystemEntries.join(', ') + ']');
1049
1105
  console.log(' 사용자 [M-NNN] entry 는 보존, 시스템 entry 만 끝에 추가.');
1050
1106
  }
1107
+ const gotchaSummary = Object.entries(flags.gotchaMissingEntries || {});
1108
+ if (gotchaSummary.length) {
1109
+ console.log(' • gotchas/: 시스템 entry 누락 — entry-level append 가능 (사용자 [G-NNN] 보존)');
1110
+ for (const [file, ids] of gotchaSummary) {
1111
+ console.log(` ${file}: [${ids.join(', ')}]`);
1112
+ }
1113
+ }
1114
+ if (flags.bundleVersionStale) {
1115
+ const { current, installed } = flags.bundleVersionStale;
1116
+ console.log(` • bundle: ${installed ?? '(없음)'} → ${current} 스탬프 갱신 필요`);
1117
+ }
1051
1118
  console.log('');
1052
1119
  console.log(' 적용: npx walwal-harness migrate');
1053
1120
  console.log(' 미리보기: npx walwal-harness migrate --dry-run');
@@ -1060,13 +1127,18 @@ function showMigrationProposal(flags) {
1060
1127
  function runMigrate(opts = {}) {
1061
1128
  const dryRun = opts.dryRun || false;
1062
1129
  const flags = detectMigrationNeeded();
1130
+ const gotchaMissingTotal = Object.values(flags.gotchaMissingEntries || {}).reduce((n, a) => n + a.length, 0);
1063
1131
  if (
1064
1132
  !flags.progressV3toV4 &&
1065
1133
  !flags.configMissingModeSelection &&
1066
- (!flags.memoryMissingSystemEntries || flags.memoryMissingSystemEntries.length === 0)
1134
+ (!flags.memoryMissingSystemEntries || flags.memoryMissingSystemEntries.length === 0) &&
1135
+ gotchaMissingTotal === 0 &&
1136
+ !flags.bundleVersionStale
1067
1137
  ) {
1068
1138
  console.log('');
1069
- log('이미 최신 버전입니다 (progress v' + TARGET_PROGRESS_VERSION + ' + config.mode_selection + memory 시스템 entry 모두 존재).');
1139
+ let pkgVer = 'unknown';
1140
+ try { pkgVer = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8')).version; } catch {}
1141
+ log(`이미 최신 — bundle v${pkgVer} 일치, progress v${TARGET_PROGRESS_VERSION}, config.mode_selection, memory 시스템 entry, gotcha entry 모두 sync.`);
1070
1142
  return;
1071
1143
  }
1072
1144
 
@@ -1141,6 +1213,39 @@ function runMigrate(opts = {}) {
1141
1213
  }
1142
1214
  }
1143
1215
 
1216
+ // 4. gotcha entry merge — for each bundled gotcha file, append missing
1217
+ // [G-NNN] entries while preserving everything the user already has.
1218
+ const gotchaMissing = flags.gotchaMissingEntries || {};
1219
+ for (const [file, missingIds] of Object.entries(gotchaMissing)) {
1220
+ if (!missingIds.length) continue;
1221
+ const srcPath = path.join(PKG_ROOT, 'gotchas', file);
1222
+ const destPath = path.join(HARNESS_DIR, 'gotchas', file);
1223
+ if (!fs.existsSync(srcPath) || !fs.existsSync(destPath)) continue;
1224
+ const original = fs.readFileSync(destPath, 'utf8');
1225
+ const tpl = fs.readFileSync(srcPath, 'utf8');
1226
+ const blocks = [];
1227
+ for (const id of missingIds) {
1228
+ const block = extractGotchaEntryBlock(tpl, id);
1229
+ if (block) blocks.push(block);
1230
+ }
1231
+ if (!blocks.length) continue;
1232
+ log(` gotchas/${file}: 시스템 entry ${blocks.length}개 append (${missingIds.join(', ')})`);
1233
+ if (!dryRun) {
1234
+ fs.writeFileSync(path.join(backupDir, `gotchas-${file}`), original);
1235
+ const sep = original.endsWith('\n') ? '\n' : '\n\n';
1236
+ fs.writeFileSync(destPath, original + sep + blocks.join('\n\n') + '\n');
1237
+ }
1238
+ }
1239
+
1240
+ // 5. Bundle version stamp — record which package version was last applied.
1241
+ if (flags.bundleVersionStale) {
1242
+ const { current, installed } = flags.bundleVersionStale;
1243
+ log(` .bundle-version: ${installed ?? '(none)'} → ${current}`);
1244
+ if (!dryRun) {
1245
+ fs.writeFileSync(path.join(HARNESS_DIR, '.bundle-version'), current + '\n');
1246
+ }
1247
+ }
1248
+
1144
1249
  console.log('');
1145
1250
  if (dryRun) {
1146
1251
  log('Dry-run 완료 — 실제 변경 적용하려면 `npx walwal-harness migrate` 실행');
@@ -1320,8 +1425,20 @@ function main() {
1320
1425
 
1321
1426
  // v6.0 — propose migration if existing project is on v3
1322
1427
  const migFlags = detectMigrationNeeded();
1323
- if (migFlags.progressV3toV4 || migFlags.configMissingModeSelection) {
1428
+ const gotchaMissing = Object.keys(migFlags.gotchaMissingEntries || {}).length > 0;
1429
+ const hasContentDrift =
1430
+ migFlags.progressV3toV4 ||
1431
+ migFlags.configMissingModeSelection ||
1432
+ (migFlags.memoryMissingSystemEntries && migFlags.memoryMissingSystemEntries.length) ||
1433
+ gotchaMissing;
1434
+ if (hasContentDrift) {
1324
1435
  showMigrationProposal(migFlags);
1436
+ } else if (migFlags.bundleVersionStale) {
1437
+ // 콘텐츠 드리프트 없이 stamp 만 누락/오래됨 → 정합성 차원에서 직접 갱신.
1438
+ try {
1439
+ const pkg = JSON.parse(fs.readFileSync(path.join(PKG_ROOT, 'package.json'), 'utf8'));
1440
+ fs.writeFileSync(path.join(HARNESS_DIR, '.bundle-version'), pkg.version + '\n');
1441
+ } catch {}
1325
1442
  }
1326
1443
 
1327
1444
  // v6.0 — Brick Office dashboard one-liner
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  docmeta:
3
3
  id: harness-solo
4
- title: /harness-solo — Solo Mode 시작/전환
4
+ title: /harness-solo — 비상용 Single-Agent Fallback
5
5
  type: input
6
6
  createdAt: 2026-04-20T00:00:00Z
7
7
  updatedAt: 2026-05-07T00:00:00Z
@@ -24,14 +24,14 @@ docmeta:
24
24
  tags: [harness, solo-mode, command, override, v6]
25
25
  ---
26
26
 
27
- # /harness-solo — Solo Mode 사용자 Override (v6.0+)
27
+ # /harness-solo — 비상용 Single-Agent Fallback (v6.0+)
28
28
 
29
- > v6.0 부터 모드 결정은 **Conductor 가 자동**으로 합니다 (config.json `mode_selection.rules`). 본 명령은 Conductor 의 자동 결정을 사용자가 강제로 덮어쓰는 **override** 입니다.
29
+ > v6.0 의 정상 경로는 회사형 자동 루프입니다. 본 명령은 그 루프를 일시적으로 벗어나는 **비상용 override** 입니다.
30
30
  >
31
31
  > **효과**: `progress.json.mode = "solo"` 강제 + `mode_decision.user_override = "solo"` 기록. 현재 sprint 끝까지 유지. 다음 sprint 진입 시 Conductor 가 재자동결정. **Auto 복귀**: 사용자 발화 "auto 로 돌려" 또는 "Conductor 결정으로".
32
32
 
33
- 프롬프트 기반으로 하네스 파이프라인을 순차 진행합니다.
34
- Team 모드에서 전환 시, 진행 중이던 피처의 상태를 보존하고 Solo로 이어갑니다.
33
+ 디버깅, 스크립트 장애, 수동 hotfix 같은 예외 상황에서만 사용합니다.
34
+ 회사 루프에서 전환 시, 진행 중이던 피처의 상태를 보존하고 단일 에이전트 fallback 으로 이어갑니다.
35
35
 
36
36
  ## 실행 절차
37
37
 
@@ -49,12 +49,12 @@ echo "현재 모드: $MODE"
49
49
  bash scripts/harness-queue-manager.sh recover .
50
50
 
51
51
  # mode를 solo로 설정
52
- jq '.mode = "solo" | .team_state.active_teams = 0 | .team_state.paused_at = (now | todate)' .harness/progress.json > /tmp/progress_tmp.json && mv /tmp/progress_tmp.json .harness/progress.json
52
+ jq '.mode = "solo" | .mode_decision.user_override = "solo" | .team_state.active_teams = 0 | .team_state.paused_at = (now | todate)' .harness/progress.json > /tmp/progress_tmp.json && mv /tmp/progress_tmp.json .harness/progress.json
53
53
  ```
54
54
 
55
55
  **paused → solo 전환 시:**
56
56
  ```bash
57
- jq '.mode = "solo"' .harness/progress.json > /tmp/progress_tmp.json && mv /tmp/progress_tmp.json .harness/progress.json
57
+ jq '.mode = "solo" | .mode_decision.user_override = "solo"' .harness/progress.json > /tmp/progress_tmp.json && mv /tmp/progress_tmp.json .harness/progress.json
58
58
  ```
59
59
 
60
60
  ### Step 2: 현재 진행 상태 표시
@@ -75,29 +75,29 @@ fi
75
75
  progress.json의 `next_agent` 필드를 확인하여 다음 단계를 안내합니다:
76
76
 
77
77
  - **next_agent = "dispatcher"** → "프롬프트로 요구사항을 입력하면 자동으로 dispatcher가 분석합니다."
78
- - **next_agent = "planner"** → "/harness-planner 를 호출하거나, 계획을 요청하세요."
79
- - **next_agent = "generator-backend"** → "/harness-generator-backend 를 호출하세요."
80
- - **next_agent = "generator-frontend"** → "/harness-generator-frontend 를 호출하세요."
81
- - **next_agent = "evaluator-functional"** → "/harness-evaluator-functional 를 호출하세요."
82
- - **next_agent = "evaluator-visual"** → "/harness-evaluator-visual 를 호출하세요."
78
+ - **next_agent = "planner"** → Planner 단계가 다음입니다. SessionStart / 내부 handoff가 연결돼 있으면 자동 진입, 아니면 해당 스킬을 수동 호출합니다.
79
+ - **next_agent = "generator-backend"** → Backend generator 단계가 다음입니다.
80
+ - **next_agent = "generator-frontend"** → Frontend generator 단계가 다음입니다.
81
+ - **next_agent = "evaluator-functional"** → Functional evaluator 단계가 다음입니다.
82
+ - **next_agent = "evaluator-visual"** → Visual evaluator 단계가 다음입니다.
83
83
 
84
84
  ### Step 4: Solo 모드 진행
85
85
 
86
- 각 에이전트는 완료 즉시 **`/harness-next` 슬래시 명령을 자동 호출** 하여 다음 에이전트로 핸드오프합니다 (사용자가 매번 bash 명령을 칠 필요 없음).
86
+ 각 에이전트는 완료 즉시 **내부 handoff(`harness-next.sh` 또는 SessionStart hook)** 로 다음 에이전트에 넘겨집니다. Owner가 `/harness-next` 를 직접 다룬다는 전제는 6.0 회사 모델과 맞지 않습니다.
87
87
 
88
88
  **예외 — 사용자 승인 게이트가 있는 단계:**
89
- - **Brainstorming**: brainstorm-spec.md 완성 후 사용자 승인 대기 → 승인 시 자동 `/harness-next`
90
- - **Planner**: plan.md / api-contract.json 완성 후 사용자 승인 대기 → 승인 시 자동 `/harness-next`
89
+ - **Brainstorming**: brainstorm-spec.md 완성 후 사용자 승인 대기 → 승인 시 내부 handoff
90
+ - **Planner**: plan.md / api-contract.json 완성 후 사용자 승인 대기 → 승인 시 내부 handoff
91
91
 
92
- 흐름이 멈췄거나 수동으로 다음 단계를 트리거하고 싶으면 사용자가 직접 `/harness-next` 입력 가능.
92
+ 흐름이 멈췄다면 원인은 보통 내부 handoff 스크립트/훅 미설치 또는 `next_agent` 불일치입니다. 이 경우 상태 파일과 hook 설치 상태를 먼저 점검합니다.
93
93
 
94
94
  feature-queue.json이 존재하는 경우:
95
95
  - 피처 완료(evaluator PASS) 시 `bash scripts/harness-queue-manager.sh pass {FEATURE_ID} .`를 호출하여 공유 상태 업데이트
96
96
  - Team 모드로 전환해도 이미 완료된 피처는 skip됨
97
97
 
98
- ## Solo 모드에서 가능한 작업
98
+ ## 사용 권장 상황
99
99
 
100
100
  - 프롬프트로 각 에이전트 순차 실행
101
- - 코드 직접 수정 및 디버깅
102
- - 피처 단위 작업 선택
103
- - Team 모드로 언제든 전환: `/harness-team`
101
+ - 내부 handoff 스크립트 장애 시 응급 복구
102
+ - 아주 짧은 수동 hotfix / 상태 수선
103
+ - 정상 회사 루프로 복귀: `/harness-team`
@@ -54,7 +54,7 @@ Planner가 완료한 feature-list.json의 피처들을 최대 3개 팀이 병렬
54
54
 
55
55
  ```bash
56
56
  # progress.json에 mode=team 설정
57
- jq '.mode = "team" | .team_state.active_teams = 3 | .team_state.paused_at = null' .harness/progress.json > /tmp/progress_tmp.json && mv /tmp/progress_tmp.json .harness/progress.json
57
+ jq '.mode = "team" | .mode_decision.user_override = "team" | .team_state.active_teams = 3 | .team_state.paused_at = null' .harness/progress.json > /tmp/progress_tmp.json && mv /tmp/progress_tmp.json .harness/progress.json
58
58
 
59
59
  # Queue 초기화 또는 복구
60
60
  if [ ! -f .harness/actions/feature-queue.json ]; then
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@walwal-harness/cli",
3
- "version": "6.0.4",
3
+ "version": "6.1.0",
4
4
  "description": "Production harness for AI agent engineering — NEXUS-adapted company metaphor (Dispatcher/CEO + Conductor + Meeting-Manager + COO/Planner + CTO + CQO + Service-Ops). Solo/Team mode, Brainstormer, Planner, Generator(BE/FE/Designer/DevOps), Evaluator chain (Code-Quality → Functional → Visual + Architecture/Security). Supports React, Next.js, and Flutter FE stacks.",
5
5
  "bin": {
6
6
  "walwal-harness": "bin/init.js"