leerness 1.9.241 β 1.9.243
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 +85 -0
- package/README.md +3 -3
- package/bin/harness.js +166 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,90 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.243 β 2026-05-26
|
|
4
|
+
|
|
5
|
+
**π UR-0014 3λ¨κ³: CJK λ€κ΅μ΄ λΆλ₯ (νκ΅μ΄/μΌλ³Έμ΄/μ€κ΅μ΄) + session close --auto-fix-encoding + handoff body --apply μ§μ
μ .**
|
|
6
|
+
|
|
7
|
+
### μ¬μ©μ λͺ
μ (UR-0014) β 3λ¨κ³ λ€κ΅μ΄ λ³΄κ° + λ§κ° μλν
|
|
8
|
+
|
|
9
|
+
1.9.241 (κ°μ§) β 1.9.242 (μλ μμ ) β 1.9.243 (λ€κ΅μ΄ + λ§κ° μλ ν΅ν©):
|
|
10
|
+
|
|
11
|
+
### 1. CJK λΆλ₯ β Korean/Japanese/Chinese μλ μλ³
|
|
12
|
+
- `_scanShellScriptsEncoding()` μ `riskType` νλ μΆκ°
|
|
13
|
+
- UTF-8 byte range λΆλ₯:
|
|
14
|
+
- Korean (Hangul U+AC00-D7AF) β 0xEA-0xED μμ β CP949 μν
|
|
15
|
+
- Japanese (Hiragana/Katakana U+3040-30FF) β 0xE3 μμ β CP932 (Shift-JIS) μν
|
|
16
|
+
- Chinese (CJK Unified U+4E00-9FFF) β 0xE4-0xE9 μμ β CP936 (GBK) μν
|
|
17
|
+
- `atRisk[].cjk`: { korean, japanese, chinese, other } μΈλΆ μΉ΄μ΄νΈ
|
|
18
|
+
- `result.riskTypeCounts`: λΆλ₯λ³ μμ½ ν΅κ³
|
|
19
|
+
- Locale λ³ μ νν μν λ©μμ§ ("Windows νκ΅μ΄/μΌλ³Έμ΄/μ€κ΅μ΄ PowerShell μμ CPxxx λ‘ μ€μΈμ κ°λ₯")
|
|
20
|
+
|
|
21
|
+
### 2. session close --auto-fix-encoding λ§κ° μλ ν볡
|
|
22
|
+
- 1.9.224 (--auto-apply-delivered) + 1.9.237 (--auto-cleanup-branches) ν¨ν΄ νμ₯
|
|
23
|
+
- λ§κ° μ μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μν μλ BOM μΆκ°
|
|
24
|
+
- κΈ°λ³Έ: μλ΄λ§ (`μλ ν볡 κ°λ₯` hint) Β· `--auto-fix-encoding` λͺ
μ μμλ§ λ³κ²½
|
|
25
|
+
- agent-mode stop νλ¦μ μλ chain (`session close --auto-apply-delivered --auto-cleanup-branches --auto-fix-encoding`)
|
|
26
|
+
|
|
27
|
+
### 3. handoff body --apply μ§μ
μ νμ
|
|
28
|
+
- μΈμ½λ© μν λ°κ²¬ μ λ³Έλ¬Έμ μλ μλ΄ 2μ€ μΆκ°:
|
|
29
|
+
- `β μλ ν볡: leerness env encoding --apply (UTF-8 BOM μλ μΆκ°, 1.9.242)`
|
|
30
|
+
- `β λ§κ° μ μλ: session close --auto-fix-encoding (1.9.243)`
|
|
31
|
+
- CJK λΆλ₯ μμ½ νμ: `λΆλ₯: korean=N, japanese=M, chinese=K (1.9.243 CJK)`
|
|
32
|
+
|
|
33
|
+
### 4. λμ νκ· (1.9.207~242) β λͺ¨λ μ μ§
|
|
34
|
+
- MCP 69 λꡬ μ μ§
|
|
35
|
+
- JSON ν΅ν© 10 νλ (envInfo) μ μ§
|
|
36
|
+
- drift check --auto-fix env encoding ν΅ν© μ μ§
|
|
37
|
+
|
|
38
|
+
### 5. stress-v188 β **24/24 PASS Β· 100%**
|
|
39
|
+
- 1.9.243 (8): VERSION + CJK 3μ’
λΆλ₯ μ νλ + riskTypeCounts + atRisk[].cjk + session close μλ/κΈ°λ³Έ λͺ¨λ + handoff body μ§μ
μ + agent-mode stop chain
|
|
40
|
+
- μ±λ₯ (2): cold_start avg 333ms Β· session close --auto-fix 438ms
|
|
41
|
+
- λμ νκ· (14): 1.9.207~242 + 보μ + npm publish
|
|
42
|
+
|
|
43
|
+
### 6. μλ release (105 λΌμ΄λ main-push streak Β· 66 λΌμ΄λ npm publish streak)
|
|
44
|
+
|
|
45
|
+
π **λ€κ΅μ΄ CJK μμ μλν** β Korean/Japanese/Chinese PowerShell μΈμ½λ© μ€μΈμ μ¬μ μ°¨λ¨
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 1.9.242 β 2026-05-26
|
|
50
|
+
|
|
51
|
+
**π UR-0014 2λ¨κ³: env encoding --apply (BOM μλ μΆκ°) + JSON 10 νλ envInfo + drift --auto-fix ν΅ν©.**
|
|
52
|
+
|
|
53
|
+
### μ¬μ©μ λͺ
μ (UR-0014) β 2λ¨κ³ μλ ν볡
|
|
54
|
+
|
|
55
|
+
1.9.241 μμ κ°μ§λ§ μ 곡νλ μνμ 1.9.242 κ° **μ€μ μλ μμ **μΌλ‘ νμ₯:
|
|
56
|
+
|
|
57
|
+
### 1. `leerness env encoding --apply` μλ BOM μΆκ°
|
|
58
|
+
- `.ps1` / `.bat` / `.cmd` / `.sh` μ μν νμΌμ UTF-8 BOM (`EF BB BF`) μλ prepend
|
|
59
|
+
- `--auto-fix-bom` λ³μΉ λμΌ λμ
|
|
60
|
+
- κΈ°λ³Έ dry-run μ μ§ (--apply λͺ
μ μμλ§ λ³κ²½) β μμ μμΉ
|
|
61
|
+
- μ μ© κ²°κ³Ό `result.applied` λ°°μ΄λ‘ λ
ΈμΆ (file/action: utf8-bom-added | failed)
|
|
62
|
+
|
|
63
|
+
### 2. handoff/session close/health --json **10 νλ** envInfo ν΅ν©
|
|
64
|
+
- JSON ν΅ν© λ§€νΈλ¦μ€ 9 β **10 νλ** μ§ν (3 λͺ
λ Ή Γ 10 = 30 ν΅ν© ν¬μΈνΈ)
|
|
65
|
+
- `envInfo`: os / isKoreanWindows / codepage / nodeVersion / shellScriptsScanned / encodingRiskCount / encodingRiskFiles[0..5]
|
|
66
|
+
- μΈλΆ AI κ° νκ²½ 컨ν
μ€νΈ + μΈμ½λ© μνμ λ¨μΌ νΈμΆμμ νμ
|
|
67
|
+
|
|
68
|
+
### 3. drift check --auto-fix env encoding BOM ν΅ν©
|
|
69
|
+
- 1.9.82 보μ ν볡 + 1.9.225 delivered + 1.9.236 release cleanup μλ ν볡 ν¨ν΄ νμ₯
|
|
70
|
+
- `drift check --auto-fix` μ μ
Έ μ€ν¬λ¦½νΈ μν μλ BOM μΆκ°
|
|
71
|
+
- log: `π --auto-fix νμ± (1.9.242) β μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μν N건 BOM μλ μΆκ° μ€...`
|
|
72
|
+
|
|
73
|
+
### 4. λμ νκ· (1.9.207~241) β λͺ¨λ μ μ§
|
|
74
|
+
- MCP 69 λꡬ μ μ§ (1.9.242 λ μ κ· CLI μ΅μ
+ ν΅ν©, λꡬ μ¦κ° X)
|
|
75
|
+
- handoff JSON: userRequestsAudit + preWakeAudit + idempotencyAudit + abnormalShutdown + deliveredRequests + roundHistory + milestones + recentChanges + pyFiles + **envInfo** (10)
|
|
76
|
+
|
|
77
|
+
### 5. stress-v187 β **22/22 PASS Β· 100%**
|
|
78
|
+
- 1.9.242 (8): VERSION + env --apply (격리) + --auto-fix-bom λ³μΉ + handoff/session close/health 10νλ envInfo + drift --auto-fix BOM ν΅ν© + envInfo μ€ν€λ§
|
|
79
|
+
- μ±λ₯ (2): cold_start avg 371ms Β· env --apply 372ms
|
|
80
|
+
- λμ νκ· (12): 1.9.207~241
|
|
81
|
+
|
|
82
|
+
### 6. μλ release (104 λΌμ΄λ main-push streak Β· 65 λΌμ΄λ npm publish streak)
|
|
83
|
+
|
|
84
|
+
π **UR-0014 μμ μλν** β κ°μ§ (1.9.241) β μλ μμ (1.9.242)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
3
88
|
## 1.9.241 β 2026-05-24
|
|
4
89
|
|
|
5
90
|
**π leerness env + νκ΅μ΄ PowerShell μΈμ½λ© μν μ¬μ κ°μ§ (μ¬μ©μ λͺ
μ UR-0014).**
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **AI μ½λ© μμ΄μ νΈμ κ±°μ§ μλ£Β·μ€λ³΅Β·λ§κ°Β·μΆ©λμ λ§μμ£Όλ κ²μΒ·κΈ°μ΅Β·νμ
CLI νλ€μ€.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []() []() []() []() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
β βββ ββββββ ββββββ ββββββββββββββββββββββββ ββββββββ β
|
|
13
13
|
β βββββββββββββββββββββββββββ ββββββ ββββββββββββββββββββββ β
|
|
14
14
|
β βββββββββββββββββββββββββββ ββββββ βββββββββββββββββββββ β
|
|
15
|
-
β v1.9.
|
|
15
|
+
β v1.9.243 AI Agent Reliability Harness + Sandbox β
|
|
16
16
|
β verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β
|
|
17
|
-
β
|
|
17
|
+
β π CJK λΆλ₯ + session close --auto-fix-encoding (UR-0014 3) β
|
|
18
18
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
19
19
|
```
|
|
20
20
|
|
package/bin/harness.js
CHANGED
|
@@ -7,7 +7,7 @@ const cp = require('child_process');
|
|
|
7
7
|
const os = require('os'); // 1.9.178: _publishToNpm μμ os.tmpdir() μ¬μ© (μ μ import)
|
|
8
8
|
const readline = require('readline');
|
|
9
9
|
|
|
10
|
-
const VERSION = '1.9.
|
|
10
|
+
const VERSION = '1.9.243';
|
|
11
11
|
|
|
12
12
|
// 1.9.184: DEP0190 (child_process shell: true) deprecation warning μ΅μ (μ¬μ©μ λͺ
μ).
|
|
13
13
|
// leerness λ cross-platform PATH resolution μ μν΄ shell: true λ₯Ό μλμ μΌλ‘ μ¬μ© (claude.cmd / ollama.cmd λ± Windows .cmd μ²λ¦¬).
|
|
@@ -2308,7 +2308,7 @@ function agentModeCmd(root, sub) {
|
|
|
2308
2308
|
log('');
|
|
2309
2309
|
log(` start μ§μ
(handoff + drift --auto-fix + session-resume --auto-fix)`);
|
|
2310
2310
|
log(` tick λ§€ λΌμ΄λ (pulse + ν΅μ¬ μ νΈ)`);
|
|
2311
|
-
log(` stop λ§κ° (session close --auto-apply-delivered --auto-cleanup-branches)`);
|
|
2311
|
+
log(` stop λ§κ° (session close --auto-apply-delivered --auto-cleanup-branches --auto-fix-encoding)`);
|
|
2312
2312
|
log('');
|
|
2313
2313
|
log(dm(` μ¬μ©μ λͺ
μ UR-0013 (Python + agent-mode ν¨μ¨ν)`));
|
|
2314
2314
|
return;
|
|
@@ -2337,8 +2337,8 @@ function agentModeCmd(root, sub) {
|
|
|
2337
2337
|
}
|
|
2338
2338
|
if (sub === 'stop') {
|
|
2339
2339
|
log(cy(`# leerness agent-mode stop (1.9.239) β ν΅ν© λ§κ°`));
|
|
2340
|
-
log(dm(` β session close --auto-apply-delivered --auto-cleanup-branches`));
|
|
2341
|
-
const r = spawnChild(['session', 'close', root, '--auto-apply-delivered', '--auto-cleanup-branches']);
|
|
2340
|
+
log(dm(` β session close --auto-apply-delivered --auto-cleanup-branches --auto-fix-encoding`));
|
|
2341
|
+
const r = spawnChild(['session', 'close', root, '--auto-apply-delivered', '--auto-cleanup-branches', '--auto-fix-encoding']);
|
|
2342
2342
|
process.stdout.write(r.stdout || '');
|
|
2343
2343
|
return;
|
|
2344
2344
|
}
|
|
@@ -2442,6 +2442,35 @@ function _collectRuntimeEnv() {
|
|
|
2442
2442
|
// μν μκ·Έλ: νκ΅μ΄ (λλ λΉ-ASCII) λ¬Έμ + BOM μμ + Windows νκ²½
|
|
2443
2443
|
function _scanShellScriptsEncoding(root) {
|
|
2444
2444
|
const result = { scanned: 0, atRisk: [], notes: [] };
|
|
2445
|
+
// 1.9.243: CJK λΆλ₯ β Korean/Japanese/Chinese λΉ-ASCII ν¨ν΄ ν΅κ³ (UR-0014 3λ¨κ³)
|
|
2446
|
+
function _classifyCJK(buf, len) {
|
|
2447
|
+
let korean = 0, japanese = 0, chinese = 0, other = 0;
|
|
2448
|
+
for (let i = 0; i < Math.min(buf.length, len); i++) {
|
|
2449
|
+
const b = buf[i];
|
|
2450
|
+
if (b < 0x80) continue;
|
|
2451
|
+
// UTF-8 3-byte μνμ€ μμ λ°μ΄νΈ λΆλ₯
|
|
2452
|
+
// Korean Hangul Syllables U+AC00-D7AF β 3-byte: EA B0 80 ~ ED 9F BF
|
|
2453
|
+
if (b >= 0xEA && b <= 0xED) korean++;
|
|
2454
|
+
// Japanese Hiragana/Katakana U+3040-30FF β 3-byte: E3 81 80 ~ E3 83 BF
|
|
2455
|
+
else if (b === 0xE3) japanese++;
|
|
2456
|
+
// CJK Unified Ideographs U+4E00-9FFF β 3-byte: E4 B8 80 ~ E9 BF BF
|
|
2457
|
+
else if (b >= 0xE4 && b <= 0xE9) chinese++;
|
|
2458
|
+
else other++;
|
|
2459
|
+
}
|
|
2460
|
+
return { korean, japanese, chinese, other };
|
|
2461
|
+
}
|
|
2462
|
+
function _riskLabel(cjk) {
|
|
2463
|
+
if (cjk.korean >= cjk.japanese && cjk.korean >= cjk.chinese && cjk.korean > 0) {
|
|
2464
|
+
return { type: 'korean', risk: 'Windows νκ΅μ΄ PowerShell μμ CP949 λ‘ μ€μΈμ κ°λ₯ (BOM μΆκ° κΆμ₯)' };
|
|
2465
|
+
}
|
|
2466
|
+
if (cjk.japanese > cjk.korean && cjk.japanese >= cjk.chinese) {
|
|
2467
|
+
return { type: 'japanese', risk: 'Windows μΌλ³Έμ΄ PowerShell μμ CP932 (Shift-JIS) λ‘ μ€μΈμ κ°λ₯ (BOM μΆκ° κΆμ₯)' };
|
|
2468
|
+
}
|
|
2469
|
+
if (cjk.chinese > 0) {
|
|
2470
|
+
return { type: 'chinese', risk: 'Windows μ€κ΅μ΄ PowerShell μμ CP936 (GBK) λ‘ μ€μΈμ κ°λ₯ (BOM μΆκ° κΆμ₯)' };
|
|
2471
|
+
}
|
|
2472
|
+
return { type: 'non-ascii', risk: 'Windows λΉ-ASCII μ
Έ μ€ν¬λ¦½νΈ β BOM μλ UTF-8 μΈμ½λ© μ€μΈμ κ°λ₯ (BOM μΆκ° κΆμ₯)' };
|
|
2473
|
+
}
|
|
2445
2474
|
function walk(dir, depth = 0) {
|
|
2446
2475
|
if (depth > 3) return; // λ무 κΉμ΄ λ€μ΄κ°μ§ μμ
|
|
2447
2476
|
let entries;
|
|
@@ -2462,12 +2491,17 @@ function _scanShellScriptsEncoding(root) {
|
|
|
2462
2491
|
if (buf[i] >= 0x80) { nonAscii = true; break; }
|
|
2463
2492
|
}
|
|
2464
2493
|
if (nonAscii && !hasBOM) {
|
|
2494
|
+
// 1.9.243: CJK λΆλ₯ μΆκ°
|
|
2495
|
+
const cjk = _classifyCJK(buf, 4096);
|
|
2496
|
+
const label = _riskLabel(cjk);
|
|
2465
2497
|
result.atRisk.push({
|
|
2466
2498
|
file: path.relative(root, fp),
|
|
2467
2499
|
ext: path.extname(fp),
|
|
2468
2500
|
hasBOM: false,
|
|
2469
2501
|
nonAscii: true,
|
|
2470
|
-
|
|
2502
|
+
riskType: label.type,
|
|
2503
|
+
cjk,
|
|
2504
|
+
risk: label.risk
|
|
2471
2505
|
});
|
|
2472
2506
|
}
|
|
2473
2507
|
} catch {}
|
|
@@ -2478,6 +2512,9 @@ function _scanShellScriptsEncoding(root) {
|
|
|
2478
2512
|
if (result.atRisk.length > 0) {
|
|
2479
2513
|
result.notes.push('ν΄κ²°: νμΌ μμμ UTF-8 BOM μΆκ° (EF BB BF) λλ .ps1 첫 μ€μ $OutputEncoding/[Console]::OutputEncoding μ€μ ');
|
|
2480
2514
|
}
|
|
2515
|
+
// 1.9.243: λΆλ₯λ³ ν΅κ³ μμ½
|
|
2516
|
+
const types = result.atRisk.reduce((m, r) => { m[r.riskType] = (m[r.riskType] || 0) + 1; return m; }, {});
|
|
2517
|
+
result.riskTypeCounts = types;
|
|
2481
2518
|
return result;
|
|
2482
2519
|
}
|
|
2483
2520
|
|
|
@@ -2491,8 +2528,25 @@ function envCmd(root, sub) {
|
|
|
2491
2528
|
const dm = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
2492
2529
|
if (sub === 'encoding-check') {
|
|
2493
2530
|
const result = _scanShellScriptsEncoding(root);
|
|
2531
|
+
// 1.9.242: --apply μ΅μ
β μν νμΌμ UTF-8 BOM μλ μΆκ° (μ¬μ©μ λͺ
μ UR-0014 2λ¨κ³)
|
|
2532
|
+
const apply = has('--apply') || has('--auto-fix-bom');
|
|
2533
|
+
if (apply) result.applied = [];
|
|
2534
|
+
if (apply && result.atRisk.length > 0) {
|
|
2535
|
+
for (const r of result.atRisk) {
|
|
2536
|
+
try {
|
|
2537
|
+
const fullPath = path.join(root, r.file);
|
|
2538
|
+
const orig = fs.readFileSync(fullPath);
|
|
2539
|
+
const bom = Buffer.from([0xEF, 0xBB, 0xBF]);
|
|
2540
|
+
const fixed = Buffer.concat([bom, orig]);
|
|
2541
|
+
fs.writeFileSync(fullPath, fixed);
|
|
2542
|
+
result.applied.push({ file: r.file, action: 'utf8-bom-added' });
|
|
2543
|
+
} catch (e) {
|
|
2544
|
+
result.applied.push({ file: r.file, action: 'failed', error: e.message });
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2494
2548
|
if (has('--json')) { log(JSON.stringify(result, null, 2)); return; }
|
|
2495
|
-
log(cy(`# leerness env encoding-check (1.9.241, UR-0014) β μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μν κ°μ§`));
|
|
2549
|
+
log(cy(`# leerness env encoding-check (1.9.241/242, UR-0014) β μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μν κ°μ§`));
|
|
2496
2550
|
log('');
|
|
2497
2551
|
log(` μ€μΊ: ${gr(String(result.scanned))} νμΌ (.ps1/.bat/.cmd/.sh)`);
|
|
2498
2552
|
if (result.atRisk.length === 0) {
|
|
@@ -2504,7 +2558,14 @@ function envCmd(root, sub) {
|
|
|
2504
2558
|
log(dm(` ${r.risk}`));
|
|
2505
2559
|
});
|
|
2506
2560
|
log('');
|
|
2507
|
-
|
|
2561
|
+
if (apply) {
|
|
2562
|
+
const okCnt = (result.applied || []).filter(a => a.action === 'utf8-bom-added').length;
|
|
2563
|
+
const failCnt = (result.applied || []).filter(a => a.action === 'failed').length;
|
|
2564
|
+
log(gr(` β UTF-8 BOM μΆκ° ${okCnt}건${failCnt > 0 ? ` (μ€ν¨ ${failCnt}건)` : ''} (1.9.242 --apply)`));
|
|
2565
|
+
} else {
|
|
2566
|
+
result.notes.forEach(n => log(yl(` π‘ ${n}`)));
|
|
2567
|
+
log(dm(` β μλ μμ : leerness env encoding --apply (BOM μλ μΆκ°)`));
|
|
2568
|
+
}
|
|
2508
2569
|
}
|
|
2509
2570
|
return;
|
|
2510
2571
|
}
|
|
@@ -6554,6 +6615,20 @@ function handoff(root) {
|
|
|
6554
6615
|
totalClasses: analyses.reduce((s, a) => s + a.classes, 0)
|
|
6555
6616
|
};
|
|
6556
6617
|
} catch {}
|
|
6618
|
+
// 1.9.242: envInfo ν΅ν© (handoff JSON 10λ²μ§Έ ν΅ν© νλ) β νκ²½ + μΈμ½λ© μν (UR-0014 2λ¨κ³)
|
|
6619
|
+
try {
|
|
6620
|
+
const runtimeEnv = _collectRuntimeEnv();
|
|
6621
|
+
const encScan = _scanShellScriptsEncoding(root);
|
|
6622
|
+
result.envInfo = {
|
|
6623
|
+
os: runtimeEnv.os.platform,
|
|
6624
|
+
isKoreanWindows: runtimeEnv.locale.isKoreanWindows || false,
|
|
6625
|
+
codepage: runtimeEnv.locale.codepage || null,
|
|
6626
|
+
nodeVersion: runtimeEnv.node.version,
|
|
6627
|
+
shellScriptsScanned: encScan.scanned,
|
|
6628
|
+
encodingRiskCount: encScan.atRisk.length,
|
|
6629
|
+
encodingRiskFiles: encScan.atRisk.slice(0, 5).map(r => r.file)
|
|
6630
|
+
};
|
|
6631
|
+
} catch {}
|
|
6557
6632
|
} catch {}
|
|
6558
6633
|
try {
|
|
6559
6634
|
const pwState = _loadPreWakeReport(root);
|
|
@@ -6910,8 +6985,13 @@ function handoff(root) {
|
|
|
6910
6985
|
log(dm5(` ${r.risk}`));
|
|
6911
6986
|
});
|
|
6912
6987
|
if (scan.atRisk.length > 3) log(dm5(` ... +${scan.atRisk.length - 3}건 λ`));
|
|
6988
|
+
// 1.9.243: CJK λΆλ₯ μμ½ (UR-0014 3λ¨κ³)
|
|
6989
|
+
const types = scan.riskTypeCounts || {};
|
|
6990
|
+
const tList = Object.entries(types).filter(([_, c]) => c > 0).map(([t, c]) => `${t}=${c}`);
|
|
6991
|
+
if (tList.length > 0) log(dm5(` λΆλ₯: ${tList.join(', ')} (1.9.243 CJK)`));
|
|
6913
6992
|
log(dm5(` β μμΈ: leerness env encoding`));
|
|
6914
|
-
log(dm5(` β
|
|
6993
|
+
log(dm5(` β μλ ν볡: leerness env encoding --apply (UTF-8 BOM μλ μΆκ°, 1.9.242)`));
|
|
6994
|
+
log(dm5(` β λ§κ° μ μλ: session close --auto-fix-encoding (1.9.243)`));
|
|
6915
6995
|
}
|
|
6916
6996
|
} catch {}
|
|
6917
6997
|
|
|
@@ -10777,6 +10857,20 @@ function sessionClose(root, opts = {}) {
|
|
|
10777
10857
|
totalClasses: analyses.reduce((s, a) => s + a.classes, 0)
|
|
10778
10858
|
};
|
|
10779
10859
|
} catch {}
|
|
10860
|
+
// 1.9.242: envInfo ν΅ν© (session close JSON 10λ²μ§Έ ν΅ν© νλ) β UR-0014 2λ¨κ³
|
|
10861
|
+
try {
|
|
10862
|
+
const runtimeEnv = _collectRuntimeEnv();
|
|
10863
|
+
const encScan = _scanShellScriptsEncoding(root);
|
|
10864
|
+
jsonResult.envInfo = {
|
|
10865
|
+
os: runtimeEnv.os.platform,
|
|
10866
|
+
isKoreanWindows: runtimeEnv.locale.isKoreanWindows || false,
|
|
10867
|
+
codepage: runtimeEnv.locale.codepage || null,
|
|
10868
|
+
nodeVersion: runtimeEnv.node.version,
|
|
10869
|
+
shellScriptsScanned: encScan.scanned,
|
|
10870
|
+
encodingRiskCount: encScan.atRisk.length,
|
|
10871
|
+
encodingRiskFiles: encScan.atRisk.slice(0, 5).map(r => r.file)
|
|
10872
|
+
};
|
|
10873
|
+
} catch {}
|
|
10780
10874
|
} catch {}
|
|
10781
10875
|
try {
|
|
10782
10876
|
// 1.9.209: pre-wake-audit μλ μ€ν + μ μ₯ (sleep μ μλ μ κ²)
|
|
@@ -10915,6 +11009,31 @@ function sessionClose(root, opts = {}) {
|
|
|
10915
11009
|
}
|
|
10916
11010
|
}
|
|
10917
11011
|
} catch {}
|
|
11012
|
+
// 1.9.243: session close --auto-fix-encoding β μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μν μλ ν볡 (UR-0014 3λ¨κ³)
|
|
11013
|
+
// 1.9.224 (--auto-apply-delivered) / 1.9.237 (--auto-cleanup-branches) ν¨ν΄ νμ₯
|
|
11014
|
+
// λ§κ° μ νκ΅μ΄/μΌλ³Έμ΄/μ€κ΅μ΄ PowerShell μΈμ½λ© μν μλ BOM μΆκ°
|
|
11015
|
+
try {
|
|
11016
|
+
const encScan = _scanShellScriptsEncoding(root);
|
|
11017
|
+
if (encScan.atRisk && encScan.atRisk.length > 0) {
|
|
11018
|
+
if (has('--auto-fix-encoding')) {
|
|
11019
|
+
let ok = 0;
|
|
11020
|
+
for (const r of encScan.atRisk) {
|
|
11021
|
+
try {
|
|
11022
|
+
const fullPath = path.join(root, r.file);
|
|
11023
|
+
const orig = fs.readFileSync(fullPath);
|
|
11024
|
+
const bom = Buffer.from([0xEF, 0xBB, 0xBF]);
|
|
11025
|
+
const fixed = Buffer.concat([bom, orig]);
|
|
11026
|
+
fs.writeFileSync(fullPath, fixed);
|
|
11027
|
+
ok++;
|
|
11028
|
+
} catch {}
|
|
11029
|
+
}
|
|
11030
|
+
log(grn(` β μΈμ½λ© μν ${ok}/${encScan.atRisk.length}건 UTF-8 BOM μλ μΆκ° (--auto-fix-encoding 1.9.243)`));
|
|
11031
|
+
} else {
|
|
11032
|
+
log(yel(` β μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μν ${encScan.atRisk.length}건 (1.9.241) β μλ ν볡 κ°λ₯`));
|
|
11033
|
+
log(dim(` β leerness env encoding --apply (μλ) λλ session close --auto-fix-encoding (1.9.243 μλ)`));
|
|
11034
|
+
}
|
|
11035
|
+
}
|
|
11036
|
+
} catch {}
|
|
10918
11037
|
// 1.9.232: λ§κ° μ pulse ν μ€ μλ λ
ΈμΆ β λ€μ λΌμ΄λ μ§μ
μ μ¦μ μν μΈμ§
|
|
10919
11038
|
try {
|
|
10920
11039
|
const rh = _computeRoundHistory(root);
|
|
@@ -13868,6 +13987,31 @@ function driftCheckCmd(root, opts = {}) {
|
|
|
13868
13987
|
log(`β auto-fix 보μ ν볡 μ€λ₯: ${e.message}`);
|
|
13869
13988
|
}
|
|
13870
13989
|
}
|
|
13990
|
+
// 1.9.242: drift check --auto-fix μ env encoding BOM μλ μΆκ° ν΅ν© (μ¬μ©μ λͺ
μ UR-0014 2λ¨κ³)
|
|
13991
|
+
// 1.9.82 ν¨ν΄ νμ₯ β drift ν볡 μ μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μνλ μλ ν΄κ²°
|
|
13992
|
+
if (autoFix) {
|
|
13993
|
+
try {
|
|
13994
|
+
const encScan = _scanShellScriptsEncoding(root);
|
|
13995
|
+
if (encScan.atRisk && encScan.atRisk.length > 0) {
|
|
13996
|
+
log('');
|
|
13997
|
+
log(`π --auto-fix νμ± (1.9.242) β μ
Έ μ€ν¬λ¦½νΈ μΈμ½λ© μν ${encScan.atRisk.length}건 BOM μλ μΆκ° μ€...`);
|
|
13998
|
+
let ok = 0;
|
|
13999
|
+
for (const r of encScan.atRisk) {
|
|
14000
|
+
try {
|
|
14001
|
+
const fullPath = path.join(root, r.file);
|
|
14002
|
+
const orig = fs.readFileSync(fullPath);
|
|
14003
|
+
const bom = Buffer.from([0xEF, 0xBB, 0xBF]);
|
|
14004
|
+
const fixed = Buffer.concat([bom, orig]);
|
|
14005
|
+
fs.writeFileSync(fullPath, fixed);
|
|
14006
|
+
ok++;
|
|
14007
|
+
} catch {}
|
|
14008
|
+
}
|
|
14009
|
+
log(`β UTF-8 BOM μΆκ° ${ok}/${encScan.atRisk.length}건 (1.9.242 UR-0014)`);
|
|
14010
|
+
}
|
|
14011
|
+
} catch (e) {
|
|
14012
|
+
log(`β env encoding auto-fix μ€λ₯ (1.9.242): ${e.message}`);
|
|
14013
|
+
}
|
|
14014
|
+
}
|
|
13871
14015
|
// 1.9.225: drift check --auto-fix μ delivered ν¨ν΄ μλ μ μ© ν΅ν© (1.9.223/224 μμ€ν
νμ)
|
|
13872
14016
|
// μ¬μ©μ μμ²μ "ꡬν μλ£" ν¨ν΄μ΄ λμ λλ©΄ κ°μ§ λ―Έλ΅ μ νΈκ° drift score λ₯Ό κ°μ€μν¬ μ μμ β μλ μ 리.
|
|
13873
14017
|
// 1.9.82 audit --fix ν¨ν΄κ³Ό λμΌ: --auto-fix μ μ¦μ μ μ©, μ μ© ν μ¬κ²μ¬.
|
|
@@ -17348,6 +17492,20 @@ function healthCmd(root) {
|
|
|
17348
17492
|
totalClasses: analyses.reduce((s, a) => s + a.classes, 0)
|
|
17349
17493
|
};
|
|
17350
17494
|
} catch { out.pyFiles = { error: 'pyFiles μ κ² μ€ν¨' }; }
|
|
17495
|
+
// 1.9.242: health --json envInfo ν΅ν© (3 λͺ
λ Ή 10 νλ β UR-0014 2λ¨κ³)
|
|
17496
|
+
try {
|
|
17497
|
+
const runtimeEnv = _collectRuntimeEnv();
|
|
17498
|
+
const encScan = _scanShellScriptsEncoding(root);
|
|
17499
|
+
out.envInfo = {
|
|
17500
|
+
os: runtimeEnv.os.platform,
|
|
17501
|
+
isKoreanWindows: runtimeEnv.locale.isKoreanWindows || false,
|
|
17502
|
+
codepage: runtimeEnv.locale.codepage || null,
|
|
17503
|
+
nodeVersion: runtimeEnv.node.version,
|
|
17504
|
+
shellScriptsScanned: encScan.scanned,
|
|
17505
|
+
encodingRiskCount: encScan.atRisk.length,
|
|
17506
|
+
encodingRiskFiles: encScan.atRisk.slice(0, 5).map(r => r.file)
|
|
17507
|
+
};
|
|
17508
|
+
} catch { out.envInfo = { error: 'envInfo μ κ² μ€ν¨' }; }
|
|
17351
17509
|
// 1.9.163: 5λ₯λ ₯ λ§€νΈλ¦μ€ μλ νκ° (1.9.155 sub-agent μ κ² β μ½λ κΈ°λ° μλν)
|
|
17352
17510
|
// κ° λ₯λ ₯μ μ½λ grep μΌλ‘ κ²μΆ β 0~100 μ μ. μ¬μ©μκ° λ§€ health νΈμΆ μ leerness μκΈ° νκ° νμΈ.
|
|
17353
17511
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.243",
|
|
4
4
|
"description": "Leerness: λΉνκ΄΄ λ§μ΄κ·Έλ μ΄μ
, μλ λ²μ κ°μ§Β·μ
λ°μ΄νΈ, κ³ν/μ§ν/νΈλμ€ν μλν, κ²μΌλ¦Β·μν¬λ¦ΏΒ·μΈμ½λ© μλ κ°λ, Claude Code μ¬λμ ν΅ν©μ κ°μΆ νκ΅μ΄ μ°μ AI κ°λ° νλ€μ€.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|