@walwal-harness/cli 6.0.1 → 6.0.2
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 +21 -0
- package/bin/init.js +73 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -29,6 +29,27 @@ docmeta:
|
|
|
29
29
|
|
|
30
30
|
# Changelog
|
|
31
31
|
|
|
32
|
+
## 6.0.2 — `migrate` 가 memory 시스템 entry 까지 자동 처리 (2026-05-07)
|
|
33
|
+
|
|
34
|
+
v6.0.1 patch 적용을 위해 사용자가 memory.md 의 [M-NEXUS-P3] 를 수동 추가해야 했던 불편을 제거. `npx walwal-harness migrate` 한 줄로 모두 처리됩니다.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- `bin/init.js` 의 `detectMigrationNeeded()` 가 memory.md 의 시스템 entry (M-NEXUS-*, M-SYS-*) 누락도 감지.
|
|
38
|
+
- `runMigrate()` 가 누락된 시스템 entry 를 template 에서 발췌해 사용자 memory.md 끝에 append. **사용자 [M-NNN] entry 는 무손상**.
|
|
39
|
+
- postinstall 안내 banner 가 누락된 memory entry 목록도 함께 표시.
|
|
40
|
+
|
|
41
|
+
### Migration (one-liner)
|
|
42
|
+
```bash
|
|
43
|
+
npm install @walwal-harness/cli@latest
|
|
44
|
+
npx walwal-harness migrate # progress + config + memory 한 번에
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`migrate` 가 처리하는 것:
|
|
48
|
+
- progress.json v3 → v4 (mode → "auto" + mode_decision)
|
|
49
|
+
- config.json mode_selection 자동 주입
|
|
50
|
+
- **(신규)** memory.md 시스템 entry append (M-NEXUS-P3 등)
|
|
51
|
+
- 변경 전 .harness/archive/migration-<ts>/ 에 progress / config / memory 자동 백업.
|
|
52
|
+
|
|
32
53
|
## 6.0.1 — Owner ↔ CEO 정체성 + 자율 실행 룰 강화 (2026-05-07)
|
|
33
54
|
|
|
34
55
|
v6.0.0 publish 직후 Owner 의 명시적 교정으로 발견된 두 가지 inviolable 룰 위반 패턴을 패키지에 정식 등재한 patch.
|
package/bin/init.js
CHANGED
|
@@ -973,10 +973,22 @@ function runTeamStudio() {
|
|
|
973
973
|
// ─────────────────────────────────────────
|
|
974
974
|
const TARGET_PROGRESS_VERSION = 4;
|
|
975
975
|
|
|
976
|
+
// System memory entries that must exist in every install. ID prefix convention:
|
|
977
|
+
// M-NEXUS-* : Foundational NEXUS doctrine rules
|
|
978
|
+
// M-SYS-* : Cross-agent system-level rules
|
|
979
|
+
// User-added [M-NNN] entries are NEVER touched.
|
|
980
|
+
const SYSTEM_MEMORY_ENTRY_PATTERN = /^### \[M-(NEXUS|SYS)-[A-Z0-9_-]+\]/m;
|
|
981
|
+
|
|
976
982
|
function detectMigrationNeeded() {
|
|
977
983
|
const progressPath = path.join(HARNESS_DIR, 'progress.json');
|
|
978
984
|
const configPath = path.join(HARNESS_DIR, 'config.json');
|
|
979
|
-
const
|
|
985
|
+
const memoryPath = path.join(HARNESS_DIR, 'memory.md');
|
|
986
|
+
const memoryTplPath = path.join(PKG_ROOT, 'assets', 'templates', 'memory.md');
|
|
987
|
+
const flags = {
|
|
988
|
+
progressV3toV4: false,
|
|
989
|
+
configMissingModeSelection: false,
|
|
990
|
+
memoryMissingSystemEntries: [],
|
|
991
|
+
};
|
|
980
992
|
if (fs.existsSync(progressPath)) {
|
|
981
993
|
try {
|
|
982
994
|
const p = JSON.parse(fs.readFileSync(progressPath, 'utf8'));
|
|
@@ -989,9 +1001,35 @@ function detectMigrationNeeded() {
|
|
|
989
1001
|
if (!c.mode_selection) flags.configMissingModeSelection = true;
|
|
990
1002
|
} catch {}
|
|
991
1003
|
}
|
|
1004
|
+
if (fs.existsSync(memoryPath) && fs.existsSync(memoryTplPath)) {
|
|
1005
|
+
try {
|
|
1006
|
+
const userMem = fs.readFileSync(memoryPath, 'utf8');
|
|
1007
|
+
const tplMem = fs.readFileSync(memoryTplPath, 'utf8');
|
|
1008
|
+
const tplEntryIds = extractEntryIds(tplMem).filter((id) => /^M-(NEXUS|SYS)-/.test(id));
|
|
1009
|
+
const userEntryIds = new Set(extractEntryIds(userMem));
|
|
1010
|
+
flags.memoryMissingSystemEntries = tplEntryIds.filter((id) => !userEntryIds.has(id));
|
|
1011
|
+
} catch {}
|
|
1012
|
+
}
|
|
992
1013
|
return flags;
|
|
993
1014
|
}
|
|
994
1015
|
|
|
1016
|
+
// Returns the list of memory entry IDs found in the markdown body, e.g. ["M-001", "M-NEXUS-P3"].
|
|
1017
|
+
function extractEntryIds(md) {
|
|
1018
|
+
const re = /^### \[(M-[A-Z0-9_-]+)\]/gm;
|
|
1019
|
+
const ids = [];
|
|
1020
|
+
let m;
|
|
1021
|
+
while ((m = re.exec(md)) !== null) ids.push(m[1]);
|
|
1022
|
+
return ids;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// Extracts a single entry block (heading + body until next ### or EOF) from the template.
|
|
1026
|
+
function extractEntryBlock(md, id) {
|
|
1027
|
+
const escId = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1028
|
+
const re = new RegExp(`(^### \\[${escId}\\][\\s\\S]*?)(?=^### \\[|\\Z)`, 'm');
|
|
1029
|
+
const m = md.match(re);
|
|
1030
|
+
return m ? m[1].trimEnd() : null;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
995
1033
|
function showMigrationProposal(flags) {
|
|
996
1034
|
console.log('');
|
|
997
1035
|
console.log('╔══════════════════════════════════════════════════════════╗');
|
|
@@ -1005,6 +1043,11 @@ function showMigrationProposal(flags) {
|
|
|
1005
1043
|
console.log(' • config.json: mode_selection 섹션 누락 — 자동 주입 가능');
|
|
1006
1044
|
console.log(' Conductor 가 ready≥3 + features≥6 + depth≤2 로 자동 모드 결정.');
|
|
1007
1045
|
}
|
|
1046
|
+
if (flags.memoryMissingSystemEntries && flags.memoryMissingSystemEntries.length) {
|
|
1047
|
+
console.log(' • memory.md: 시스템 entry 누락 — append 가능');
|
|
1048
|
+
console.log(' [' + flags.memoryMissingSystemEntries.join(', ') + ']');
|
|
1049
|
+
console.log(' 사용자 [M-NNN] entry 는 보존, 시스템 entry 만 끝에 추가.');
|
|
1050
|
+
}
|
|
1008
1051
|
console.log('');
|
|
1009
1052
|
console.log(' 적용: npx walwal-harness migrate');
|
|
1010
1053
|
console.log(' 미리보기: npx walwal-harness migrate --dry-run');
|
|
@@ -1017,9 +1060,13 @@ function showMigrationProposal(flags) {
|
|
|
1017
1060
|
function runMigrate(opts = {}) {
|
|
1018
1061
|
const dryRun = opts.dryRun || false;
|
|
1019
1062
|
const flags = detectMigrationNeeded();
|
|
1020
|
-
if (
|
|
1063
|
+
if (
|
|
1064
|
+
!flags.progressV3toV4 &&
|
|
1065
|
+
!flags.configMissingModeSelection &&
|
|
1066
|
+
(!flags.memoryMissingSystemEntries || flags.memoryMissingSystemEntries.length === 0)
|
|
1067
|
+
) {
|
|
1021
1068
|
console.log('');
|
|
1022
|
-
log('이미 최신 버전입니다 (progress
|
|
1069
|
+
log('이미 최신 버전입니다 (progress v' + TARGET_PROGRESS_VERSION + ' + config.mode_selection + memory 시스템 entry 모두 존재).');
|
|
1023
1070
|
return;
|
|
1024
1071
|
}
|
|
1025
1072
|
|
|
@@ -1071,6 +1118,29 @@ function runMigrate(opts = {}) {
|
|
|
1071
1118
|
}
|
|
1072
1119
|
}
|
|
1073
1120
|
|
|
1121
|
+
// 3. memory.md — append missing system entries (M-NEXUS-*, M-SYS-*) only.
|
|
1122
|
+
// User-added [M-NNN] entries are NEVER touched.
|
|
1123
|
+
const memoryPath = path.join(HARNESS_DIR, 'memory.md');
|
|
1124
|
+
const memoryTplPath = path.join(PKG_ROOT, 'assets', 'templates', 'memory.md');
|
|
1125
|
+
const missingMemEntries = flags.memoryMissingSystemEntries || [];
|
|
1126
|
+
if (missingMemEntries.length && fs.existsSync(memoryPath) && fs.existsSync(memoryTplPath)) {
|
|
1127
|
+
const original = fs.readFileSync(memoryPath, 'utf8');
|
|
1128
|
+
const tpl = fs.readFileSync(memoryTplPath, 'utf8');
|
|
1129
|
+
const blocks = [];
|
|
1130
|
+
for (const id of missingMemEntries) {
|
|
1131
|
+
const block = extractEntryBlock(tpl, id);
|
|
1132
|
+
if (block) blocks.push(block);
|
|
1133
|
+
}
|
|
1134
|
+
if (blocks.length) {
|
|
1135
|
+
log(` memory.md: 시스템 entry ${blocks.length}개 append (${missingMemEntries.join(', ')})`);
|
|
1136
|
+
if (!dryRun) {
|
|
1137
|
+
fs.writeFileSync(path.join(backupDir, 'memory.md'), original);
|
|
1138
|
+
const sep = original.endsWith('\n') ? '\n' : '\n\n';
|
|
1139
|
+
fs.writeFileSync(memoryPath, original + sep + blocks.join('\n\n') + '\n');
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1074
1144
|
console.log('');
|
|
1075
1145
|
if (dryRun) {
|
|
1076
1146
|
log('Dry-run 완료 — 실제 변경 적용하려면 `npx walwal-harness migrate` 실행');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.2",
|
|
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"
|