leerness 1.9.221 β 1.9.223
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 +77 -0
- package/README.md +3 -3
- package/bin/harness.js +206 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,82 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.223 β 2026-05-22
|
|
4
|
+
|
|
5
|
+
**π₯ μ¬μ©μ μμ² auto-complete (delivered ν¨ν΄ μλ κ°μ§) + handoff/session close ν΅ν©.**
|
|
6
|
+
|
|
7
|
+
### 1. `leerness requests auto-complete` β delivered ν¨ν΄ μλ μ 리
|
|
8
|
+
- 1.9.207 μμ€ν
μ΄μ μ€ λμ λ "Round X.Y.Z β ꡬν μλ£" ν¨ν΄μ μκΈ°-κΈ°λ‘ μμ²μ μλ κ°μ§
|
|
9
|
+
- μ κ·μ: `(Round\s+)?\d+\.\d+\.\d+` + `(ꡬν μλ£|implemented|delivered|shipped|λ°°ν¬ μλ£)`
|
|
10
|
+
- νμ¬ package.json λ²μ μ΄νλ§ ν보 (λ―Έλ λ²μ 무μ) β μμ κ°λ
|
|
11
|
+
- κΈ°λ³Έ dry-run (λͺ©λ‘λ§), `--apply` λͺ
μ μμλ§ μ€μ μν λ³κ²½
|
|
12
|
+
- μν λ³κ²½ μ `autoCompletedAt` + `autoCompleteReason: 'delivered-pattern-1.9.223'` μΆμ κΈ°λ‘
|
|
13
|
+
|
|
14
|
+
### 2. handoff ν€λλΌμΈ μλ λ
ΈμΆ
|
|
15
|
+
- delivered ν보 β₯ 1건 μ: `π₯ μλμλ£κ°λ₯ N건 (1.9.223)` β λ―Έλ΅ μμ² μ νΈ λμ μ°μ λ
ΈμΆ
|
|
16
|
+
- μ΄μ μ€ λμ λ κ°μ§ λ―Έλ΅ μ νΈ (μ€μ λ λͺ¨λ μ²λ¦¬λ¨) μλ μ 리 κΆμ₯
|
|
17
|
+
|
|
18
|
+
### 3. handoff/session close JSON 5λ²μ§Έ ν΅ν© νλ β `deliveredRequests`
|
|
19
|
+
- `{ candidates, currentVersion, autoCompleteAvailable, ids[] }`
|
|
20
|
+
- 1.9.218 4 νλ (userRequests/preWake/idempotency/abnormalShutdown) β **5 νλ μμ±**
|
|
21
|
+
- μΈλΆ λͺ¨λν°λ§/CI μλ κ°μ§
|
|
22
|
+
|
|
23
|
+
### 4. session close μλ ν΅ν© λ³Έλ¬Έ λ
ΈμΆ
|
|
24
|
+
- 1.9.207/209/212/220 ν΅ν© ν¨ν΄μ 1.9.223 μΆκ°
|
|
25
|
+
- delivered ν보 μ: `π₯ delivered ν¨ν΄ N건 (1.9.223) β μλ μλ£ κ°λ₯`
|
|
26
|
+
- `β leerness requests auto-complete --apply` κ°μ΄λ μλ
|
|
27
|
+
|
|
28
|
+
### 5. μ€ μ΄μ κ²μ¦ β λμ 8건 μ 리 μλ£
|
|
29
|
+
- UR-0004~UR-0011 (1.9.208~213 λΌμ΄λ μκΈ°-κΈ°λ‘) β λͺ¨λ μλ μ 리 μλ£
|
|
30
|
+
- 1.9.223 μμ€ν
μ ν₯ν μ¬λ° μ 1μ€ λͺ
λ ΉμΌλ‘ μ¦μ μ 리
|
|
31
|
+
|
|
32
|
+
### 6. λμ νκ· (1.9.207~222) β λͺ¨λ μ μ§
|
|
33
|
+
|
|
34
|
+
### 7. stress-v168 β 15/15 PASS
|
|
35
|
+
- 1.9.223 (6): VERSION + μλ κ°μ§ + --apply + dry-run + handoff JSON + session close JSON
|
|
36
|
+
- μ±λ₯ (2): cold_start avg 401ms / auto-complete 432ms
|
|
37
|
+
- λμ νκ· (7): 1.9.207~222
|
|
38
|
+
|
|
39
|
+
### 8. μλ release (85 λΌμ΄λ main-push streak Β· 46 λΌμ΄λ npm publish streak)
|
|
40
|
+
|
|
41
|
+
π₯ **μ¬μ©μ μμ² λΌμ΄νμ¬μ΄ν΄ μμ±**: 1.9.207 (μλ audit) β 1.9.217 (λ§κ° μλ) β **1.9.223 (μλ μλ£)** β 3 λΌμ΄λ λμ
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 1.9.222 β 2026-05-22
|
|
46
|
+
|
|
47
|
+
**π‘ session-resume --auto-fix μμ ν볡 + handoff λ³Έλ¬Έ λΉμ μ μ’
λ£ μλ λ
ΈμΆ.**
|
|
48
|
+
|
|
49
|
+
### 1. `leerness session-resume --auto-fix` β μμ ν μλ ν볡
|
|
50
|
+
- 1.9.220 detect / 1.9.221 MCP / 1.9.222 **auto-fix**
|
|
51
|
+
- `wakeup-missed` μ νΈ κ°μ§ μ β 30λΆ+ μ§λ pending wakeup μλ `superseded`
|
|
52
|
+
- `state.supersededReason: 'auto-fix-1.9.222-abnormal-shutdown'`
|
|
53
|
+
- μ¬μ©μ/AIκ° μλ μ 리ν νμ μμ΄ λ€μ wakeupμ΄ μ μ λμ
|
|
54
|
+
- `--auto-fix` μ΅μ
μ΄ μμΌλ©΄ κΈ°μ‘΄ λμ κ·Έλλ‘ (κ°μ§λ§, λ³κ²½ X)
|
|
55
|
+
|
|
56
|
+
### 2. handoff λ³Έλ¬Έ μλ λ
ΈμΆ β λΉμ μ μ’
λ£ μΉμ
|
|
57
|
+
- 1.9.220 ν€λλΌμΈ (`π λΉμ μμ’
λ£ <severity>`) + 1.9.222 **λ³Έλ¬Έ**
|
|
58
|
+
- `severity: high` β `## π¨ λΉμ μ μ’
λ£ κ°μ§ (1.9.220, severity: high)` λ³Έλ¬Έ μΉμ
μλ
|
|
59
|
+
- `severity: medium` β `## β λΉμ μ μ’
λ£ κ°μ§` λ³Έλ¬Έ μΉμ
μλ
|
|
60
|
+
- λ³Έλ¬Έ μΆλ ₯ μμΉ: pre-wake-audit μΉμ
λ€μ, νμ± λ£° μ΄μ
|
|
61
|
+
- top 3 μ νΈ + μ¬κ° κ°μ΄λ + auto-fix κ°μ΄λ ν λ²μ λ
ΈμΆ
|
|
62
|
+
|
|
63
|
+
### 3. CLAUDE.md / AGENTS.md 1.9.214~221 μ΄μ κ°ν 8 λΌμ΄λ ν΅ν©
|
|
64
|
+
- drift μ°¨λ¨μ μν `## μ΄μ κ°ν 8 λΌμ΄λ (1.9.214~221)` μΉμ
λμ
|
|
65
|
+
- 9 λΌμ΄λ (drift μ°¨λ¨ / handoff ν€λλΌμΈ / MCP 5μ’
/ session close / handoff JSON 4 ν΅ν© / 80 λΌμ΄λ / λΉμ μ μ’
λ£ / MCP 60 / auto-fix) λͺ¨λ λ¨μΌ μμΌ λ
ΈμΆ
|
|
66
|
+
|
|
67
|
+
### 4. λμ νκ· (1.9.207~221) β λͺ¨λ μ μ§
|
|
68
|
+
|
|
69
|
+
### 5. stress-v167 β 14/14 PASS
|
|
70
|
+
- 1.9.222 (6): VERSION + auto-fix (격리) + auto-fix λ―Έμ§μ μ λμ + handoff λ³Έλ¬Έ λ
ΈμΆ + handoff μ μ μ λ―Έλ
ΈμΆ + CLAUDE 8 λΌμ΄λ μΉμ
|
|
71
|
+
- μ±λ₯ (2): cold_start avg 408ms / MCP 60 λꡬ 413ms
|
|
72
|
+
- λμ νκ· (6): 1.9.207~221
|
|
73
|
+
|
|
74
|
+
### 6. μλ release (84 λΌμ΄λ main-push streak Β· 45 λΌμ΄λ npm publish streak)
|
|
75
|
+
|
|
76
|
+
π‘ **λΉμ μ μ’
λ£ μμ€ν
μμ±**: 1.9.220 detect β 1.9.221 MCP β 1.9.222 **auto-fix** + **λ³Έλ¬Έ μλ λ
ΈμΆ** (3 λΌμ΄λ λμ )
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
3
80
|
## 1.9.221 β 2026-05-22
|
|
4
81
|
|
|
5
82
|
**π MCP 60 λꡬ λ§μΌμ€ν€ + abnormalShutdown JSON ν΅ν© (handoff/session close).**
|
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) []() []() []() []() []() []() [-brightgreen)]() []() []() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
β βββ ββββββ ββββββ ββββββββββββββββββββββββ ββββββββ β
|
|
13
13
|
β βββββββββββββββββββββββββββ ββββββ ββββββββββββββββββββββ β
|
|
14
14
|
β βββββββββββββββββββββββββββ ββββββ βββββββββββββββββββββ β
|
|
15
|
-
β v1.9.
|
|
15
|
+
β v1.9.223 AI Agent Reliability Harness + Sandbox β
|
|
16
16
|
β verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β
|
|
17
|
-
β
|
|
17
|
+
β π₯ requests auto-complete Β· handoff JSON 5 ν΅ν© νλ β
|
|
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.223';
|
|
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 μ²λ¦¬).
|
|
@@ -2006,6 +2006,54 @@ function _auditUserRequests(root) {
|
|
|
2006
2006
|
};
|
|
2007
2007
|
}
|
|
2008
2008
|
|
|
2009
|
+
// 1.9.223: delivered-by-pattern κ°μ§ β μ¬μ©μ μμ² λ³Έλ¬Έμ "Round X.Y.Z β ꡬν μλ£" κ°μ μκΈ°-κΈ°λ‘ ν¨ν΄μ΄ μκ³
|
|
2010
|
+
// ν΄λΉ λ²μ μ΄ μ΄λ―Έ μΆμλ κ²½μ°, μλ μλ£ νλ³΄λ‘ λΆλ₯. μ΄μ μ€ λμ λ β― μ νΈ μ 리μ©.
|
|
2011
|
+
// μμ μμΉ: κΈ°λ³Έ dry-run (λͺ©λ‘λ§), --apply μμλ§ μ€μ μν λ³κ²½.
|
|
2012
|
+
function _detectDeliveredRequests(root) {
|
|
2013
|
+
const state = _loadUserRequests(root);
|
|
2014
|
+
const open = state.requests.filter(r => r.status === 'open' || r.status === 'in-progress');
|
|
2015
|
+
// ν¨ν΄: "Round 1.9.123" λλ "1.9.123" + ("ꡬν μλ£" | "implemented" | "delivered" | "shipped" | "ROUND β¦ μλ£")
|
|
2016
|
+
const versionRe = /(?:Round\s+)?(\d+\.\d+\.\d+)/i;
|
|
2017
|
+
const doneRe = /(ꡬν\s*μλ£|ꡬνμλ£|implemented|delivered|shipped|ship\s*μλ£|λ°°ν¬\s*μλ£)/i;
|
|
2018
|
+
let currentMajor = '0.0.0';
|
|
2019
|
+
try {
|
|
2020
|
+
const pkg = JSON.parse(read(path.join(root, 'package.json')));
|
|
2021
|
+
if (pkg && pkg.version) currentMajor = pkg.version;
|
|
2022
|
+
} catch {}
|
|
2023
|
+
const candidates = [];
|
|
2024
|
+
open.forEach(req => {
|
|
2025
|
+
const text = req.text || '';
|
|
2026
|
+
const vMatch = text.match(versionRe);
|
|
2027
|
+
const dMatch = text.match(doneRe);
|
|
2028
|
+
if (vMatch && dMatch) {
|
|
2029
|
+
const claimedVer = vMatch[1];
|
|
2030
|
+
// νμ¬ λ²μ μ΄νμΈμ§ (μκΈ°-κΈ°λ‘ μμ μ λ²μ μ΄ μ΄λ―Έ μΆμλ¨)
|
|
2031
|
+
const cmp = _compareSemver(claimedVer, currentMajor);
|
|
2032
|
+
if (cmp <= 0) {
|
|
2033
|
+
candidates.push({
|
|
2034
|
+
id: req.id,
|
|
2035
|
+
text: text.slice(0, 120),
|
|
2036
|
+
claimedVersion: claimedVer,
|
|
2037
|
+
currentVersion: currentMajor,
|
|
2038
|
+
deliveredKeyword: dMatch[0],
|
|
2039
|
+
recordedAt: req.recordedAt
|
|
2040
|
+
});
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
});
|
|
2044
|
+
return { total: open.length, candidates, currentVersion: currentMajor };
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
function _compareSemver(a, b) {
|
|
2048
|
+
const pa = String(a).split('.').map(n => parseInt(n, 10) || 0);
|
|
2049
|
+
const pb = String(b).split('.').map(n => parseInt(n, 10) || 0);
|
|
2050
|
+
for (let i = 0; i < 3; i++) {
|
|
2051
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return -1;
|
|
2052
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return 1;
|
|
2053
|
+
}
|
|
2054
|
+
return 0;
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2009
2057
|
// 1.9.208: νλ«νΌ/API μ μ½ μ¬μ μ²΄ν¬ (μ¬μ©μ λͺ
μ)
|
|
2010
2058
|
// "μ¬μ©μμ λͺ
λ Ήμ λ°μΌλ©΄, κ³ λ €ν΄μΌνλ λΆλΆμ λ¨Όμ νμΈνκ³ μ§ννκ² νλ©΄ μ΄λ¨μ§"
|
|
2011
2059
|
// "νΉμ νλ«νΌμ API ... νΈμΆμλκ° μ΄λΉ 5ν μ΄νλ‘λ§ ν΄μΌνλ€λ κ·μ μ λ¨Όμ νμΈ"
|
|
@@ -2956,11 +3004,55 @@ function requestsCmd(root, sub, ...rest) {
|
|
|
2956
3004
|
if (!sub || sub === 'help' || sub === '--help') {
|
|
2957
3005
|
log(`# leerness requests (1.9.207) β μ¬μ©μ μμ² λλ½ νμΈ μ μ°¨`);
|
|
2958
3006
|
log('');
|
|
2959
|
-
log(` audit
|
|
2960
|
-
log(` add "<text>"
|
|
2961
|
-
log(` list
|
|
2962
|
-
log(` complete <id>
|
|
2963
|
-
log(` drop <id>
|
|
3007
|
+
log(` audit β λλ½ ν보 + tracked + stale λ³΄κ³ (--json κ°λ₯)`);
|
|
3008
|
+
log(` add "<text>" β μ¬μ©μ μμ² μλ κΈ°λ‘`);
|
|
3009
|
+
log(` list β μ 체 μμ² μΆλ ₯ (--json κ°λ₯, --status open|completed|dropped)`);
|
|
3010
|
+
log(` complete <id> β μμ² μλ£ νμ (μ: UR-0003)`);
|
|
3011
|
+
log(` drop <id> β μμ² λλ‘ νμ`);
|
|
3012
|
+
log(` auto-complete β "Round X.Y.Z β ꡬν μλ£" ν¨ν΄ μλ κ°μ§ (default: dry-run, --apply μ μ μ©) [1.9.223]`);
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
3015
|
+
|
|
3016
|
+
// 1.9.223: auto-complete β μκΈ°-κΈ°λ‘λ "ꡬν μλ£" ν¨ν΄ μλ μ 리 (default dry-run)
|
|
3017
|
+
if (sub === 'auto-complete') {
|
|
3018
|
+
const apply = has('--apply');
|
|
3019
|
+
const detected = _detectDeliveredRequests(root);
|
|
3020
|
+
if (has('--json')) {
|
|
3021
|
+
const result = { ...detected, applied: false, completedIds: [] };
|
|
3022
|
+
if (apply) {
|
|
3023
|
+
for (const c of detected.candidates) {
|
|
3024
|
+
const u = _updateUserRequest(root, c.id, { status: 'completed', autoCompletedAt: new Date().toISOString(), autoCompleteReason: 'delivered-pattern-1.9.223' });
|
|
3025
|
+
if (u) result.completedIds.push(c.id);
|
|
3026
|
+
}
|
|
3027
|
+
result.applied = true;
|
|
3028
|
+
}
|
|
3029
|
+
log(JSON.stringify(result, null, 2));
|
|
3030
|
+
return;
|
|
3031
|
+
}
|
|
3032
|
+
log(cyan(`# leerness requests auto-complete (1.9.223) β delivered pattern μλ κ°μ§`));
|
|
3033
|
+
log('');
|
|
3034
|
+
log(` νμ¬ λ²μ : ${detected.currentVersion} Β· open ${detected.total} Β· ν보 ${detected.candidates.length}건`);
|
|
3035
|
+
log('');
|
|
3036
|
+
if (detected.candidates.length === 0) {
|
|
3037
|
+
log(grn(` β delivered ν¨ν΄ ν보 μμ β open μμ²μ λͺ¨λ μλ‘μ΄ μμ
`));
|
|
3038
|
+
return;
|
|
3039
|
+
}
|
|
3040
|
+
log(yel(` π₯ delivered ν¨ν΄ ν보 ${detected.candidates.length}건:`));
|
|
3041
|
+
detected.candidates.forEach(c => {
|
|
3042
|
+
log(` β’ [${c.id}] v${c.claimedVersion} (${c.deliveredKeyword}) β ${c.text.slice(0, 80)}β¦`);
|
|
3043
|
+
});
|
|
3044
|
+
log('');
|
|
3045
|
+
if (apply) {
|
|
3046
|
+
let ok = 0;
|
|
3047
|
+
for (const c of detected.candidates) {
|
|
3048
|
+
const u = _updateUserRequest(root, c.id, { status: 'completed', autoCompletedAt: new Date().toISOString(), autoCompleteReason: 'delivered-pattern-1.9.223' });
|
|
3049
|
+
if (u) ok++;
|
|
3050
|
+
}
|
|
3051
|
+
log(grn(` β μλ μλ£ ${ok}/${detected.candidates.length}건`));
|
|
3052
|
+
} else {
|
|
3053
|
+
log(dim(` β μ μ©νλ €λ©΄: leerness requests auto-complete --apply`));
|
|
3054
|
+
log(dim(` β μμ μμΉ: κΈ°λ³Έ dry-run (λ³κ²½ X), --apply λͺ
μ μμλ§ μ μ©`));
|
|
3055
|
+
}
|
|
2964
3056
|
return;
|
|
2965
3057
|
}
|
|
2966
3058
|
|
|
@@ -3055,6 +3147,7 @@ function requestsCmd(root, sub, ...rest) {
|
|
|
3055
3147
|
}
|
|
3056
3148
|
|
|
3057
3149
|
// 1.9.220: leerness session-resume β λΉμ μ μ’
λ£ κ°μ§ + μμ¨ μ¬κ° κ°μ΄λ (μ¬μ©μ λͺ
μ)
|
|
3150
|
+
// 1.9.222: --auto-fix μ΅μ
μΆκ° β μμ ν μλ ν볡 (wakeup supersede)
|
|
3058
3151
|
function sessionResumeCmd(root) {
|
|
3059
3152
|
root = absRoot(root);
|
|
3060
3153
|
const isTty = process.stdout && process.stdout.isTTY;
|
|
@@ -3065,6 +3158,45 @@ function sessionResumeCmd(root) {
|
|
|
3065
3158
|
const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
3066
3159
|
|
|
3067
3160
|
const result = _detectAbnormalShutdown(root);
|
|
3161
|
+
|
|
3162
|
+
// 1.9.222: --auto-fix β μμ ν μ νΈλ³ μλ ν볡
|
|
3163
|
+
const autoFix = has('--auto-fix');
|
|
3164
|
+
if (autoFix && result.abnormalShutdown) {
|
|
3165
|
+
result.autoFixed = [];
|
|
3166
|
+
// 1) wakeup-missed β μ€λλ pending wakeup supersede (μμ : λ¨μ μν λ³κ²½)
|
|
3167
|
+
if (result.signals.some(s => s.kind === 'wakeup-missed')) {
|
|
3168
|
+
try {
|
|
3169
|
+
const state = _loadActiveWakeups(root);
|
|
3170
|
+
let fixed = 0;
|
|
3171
|
+
state.wakeups = state.wakeups.map(w => {
|
|
3172
|
+
if (w.status === 'pending') {
|
|
3173
|
+
const expectedMs = new Date(w.expectedFireAt).getTime();
|
|
3174
|
+
const deltaMin = Math.floor((Date.now() - expectedMs) / 60000);
|
|
3175
|
+
if (deltaMin > 30) {
|
|
3176
|
+
w.status = 'superseded';
|
|
3177
|
+
w.supersededReason = 'auto-fix-1.9.222-abnormal-shutdown';
|
|
3178
|
+
w.supersededAt = new Date().toISOString();
|
|
3179
|
+
fixed++;
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
return w;
|
|
3183
|
+
});
|
|
3184
|
+
if (fixed > 0) {
|
|
3185
|
+
_writeActiveWakeups(root, state.wakeups);
|
|
3186
|
+
result.autoFixed.push({ kind: 'wakeup-missed', action: 'superseded', count: fixed });
|
|
3187
|
+
}
|
|
3188
|
+
} catch {}
|
|
3189
|
+
}
|
|
3190
|
+
// 2) auto-resume-plan-unused β 60min+ λ―Έμ¬μ©μ μλ΄λ§ (μλ μμ X, μ¬μ©μκ° κ²ν ν΄μΌ ν¨)
|
|
3191
|
+
if (result.signals.some(s => s.kind === 'auto-resume-plan-unused')) {
|
|
3192
|
+
result.autoFixed.push({ kind: 'auto-resume-plan-unused', action: 'guidance-only', detail: 'leerness resume μΌλ‘ μ μ© κ²ν ' });
|
|
3193
|
+
}
|
|
3194
|
+
// 3) in-progress-stale β drop κ²°μ μ μ¬μ©μ μμ (μλ X)
|
|
3195
|
+
if (result.signals.some(s => s.kind === 'in-progress-stale')) {
|
|
3196
|
+
result.autoFixed.push({ kind: 'in-progress-stale', action: 'guidance-only', detail: 'leerness task list --status in-progress ν μ¬μ©μ κ²°μ νμ' });
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3068
3200
|
if (has('--json')) { log(JSON.stringify(result, null, 2)); return; }
|
|
3069
3201
|
log(cyan(`# leerness session-resume (1.9.220) β λΉμ μ μ’
λ£ κ°μ§ + μμ¨ μ¬κ°`));
|
|
3070
3202
|
log(` detected at: ${result.detectedAt}`);
|
|
@@ -3093,6 +3225,18 @@ function sessionResumeCmd(root) {
|
|
|
3093
3225
|
for (const g of result.resumeGuide) {
|
|
3094
3226
|
log(` ${g}`);
|
|
3095
3227
|
}
|
|
3228
|
+
// 1.9.222: --auto-fix κ²°κ³Ό λ
ΈμΆ
|
|
3229
|
+
if (result.autoFixed && result.autoFixed.length > 0) {
|
|
3230
|
+
log('');
|
|
3231
|
+
log(grn(`## π§ auto-fix κ²°κ³Ό (${result.autoFixed.length})`));
|
|
3232
|
+
for (const af of result.autoFixed) {
|
|
3233
|
+
const icon = af.action === 'superseded' ? 'β' : 'βΉ';
|
|
3234
|
+
log(` ${icon} [${af.kind}] ${af.action}${af.count ? ` (count: ${af.count})` : ''}`);
|
|
3235
|
+
if (af.detail) log(dim(` ${af.detail}`));
|
|
3236
|
+
}
|
|
3237
|
+
} else if (autoFix) {
|
|
3238
|
+
log(dim(` (auto-fix μ μ© λμ μμ)`));
|
|
3239
|
+
}
|
|
3096
3240
|
}
|
|
3097
3241
|
|
|
3098
3242
|
// 1.9.208: leerness constraints <list|check|add> β νλ«νΌ/API μ μ½ μ¬μ μ²΄ν¬ CLI (μ¬μ©μ λͺ
μ)
|
|
@@ -5671,6 +5815,16 @@ function handoff(root) {
|
|
|
5671
5815
|
tracked: reqAudit.tracked ? reqAudit.tracked.length : 0,
|
|
5672
5816
|
stale: reqAudit.stale ? reqAudit.stale.length : 0
|
|
5673
5817
|
};
|
|
5818
|
+
// 1.9.223: delivered ν¨ν΄ μλ κ°μ§ ν΅ν© (handoff JSON 5λ²μ§Έ ν΅ν© νλ)
|
|
5819
|
+
try {
|
|
5820
|
+
const delivered = _detectDeliveredRequests(root);
|
|
5821
|
+
result.deliveredRequests = {
|
|
5822
|
+
candidates: delivered.candidates.length,
|
|
5823
|
+
currentVersion: delivered.currentVersion,
|
|
5824
|
+
autoCompleteAvailable: delivered.candidates.length > 0,
|
|
5825
|
+
ids: delivered.candidates.map(c => c.id)
|
|
5826
|
+
};
|
|
5827
|
+
} catch {}
|
|
5674
5828
|
} catch {}
|
|
5675
5829
|
try {
|
|
5676
5830
|
const pwState = _loadPreWakeReport(root);
|
|
@@ -5860,9 +6014,14 @@ function handoff(root) {
|
|
|
5860
6014
|
}
|
|
5861
6015
|
} catch {}
|
|
5862
6016
|
// 13) 1.9.207: μ¬μ©μ μμ² λλ½ νμΈ μ μ°¨ (μ¬μ©μ λͺ
μ) β λλ½ ν보 β₯ 1 μ ν€λλΌμΈ λ
ΈμΆ
|
|
6017
|
+
// 1.9.223: delivered ν¨ν΄ ν보 μ `π₯ μλμλ£κ°λ₯ N건` μ°μ λ
ΈμΆ (μλ μ 리 λΆλ΄ κ°μ)
|
|
5863
6018
|
try {
|
|
5864
6019
|
const audit = _auditUserRequests(root);
|
|
5865
|
-
|
|
6020
|
+
let detected = { candidates: [] };
|
|
6021
|
+
try { detected = _detectDeliveredRequests(root); } catch {}
|
|
6022
|
+
if (detected.candidates && detected.candidates.length > 0) {
|
|
6023
|
+
parts.push(`π₯ μλμλ£κ°λ₯ ${detected.candidates.length}건 (1.9.223)`);
|
|
6024
|
+
} else if (audit.missing && audit.missing.length > 0) {
|
|
5866
6025
|
parts.push(`π₯ λ―Έλ΅ μμ² ${audit.missing.length}건`);
|
|
5867
6026
|
} else if (audit.open > 0) {
|
|
5868
6027
|
parts.push(`π₯ μμ² ${audit.open} (tracked)`);
|
|
@@ -5956,6 +6115,30 @@ function handoff(root) {
|
|
|
5956
6115
|
}
|
|
5957
6116
|
}
|
|
5958
6117
|
} catch {}
|
|
6118
|
+
|
|
6119
|
+
// 1.9.222: λΉμ μ μ’
λ£ κ°μ§ λ³Έλ¬Έ μλ λ
ΈμΆ (handoff μ§ν β κ°μ₯ λ¨Όμ λ΄μΌ ν¨)
|
|
6120
|
+
// high/medium severity μ μ¦μ λ
ΈμΆ, low/none μ 무μ
|
|
6121
|
+
try {
|
|
6122
|
+
const ad = _detectAbnormalShutdown(root);
|
|
6123
|
+
if (ad.abnormalShutdown && (ad.severity === 'high' || ad.severity === 'medium')) {
|
|
6124
|
+
const isTty = process.stdout && process.stdout.isTTY;
|
|
6125
|
+
const cy3 = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
|
|
6126
|
+
const rd3 = s => isTty ? `\x1b[31m${s}\x1b[0m` : s;
|
|
6127
|
+
const yl3 = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
|
|
6128
|
+
const dm3 = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
6129
|
+
log('');
|
|
6130
|
+
const sevIcon = ad.severity === 'high' ? 'π¨' : 'β ';
|
|
6131
|
+
const sevColor = ad.severity === 'high' ? rd3 : yl3;
|
|
6132
|
+
log(sevColor(`## ${sevIcon} λΉμ μ μ’
λ£ κ°μ§ (1.9.220, severity: ${ad.severity})`));
|
|
6133
|
+
ad.signals.slice(0, 3).forEach(s => {
|
|
6134
|
+
const ic = s.severity === 'high' ? 'π¨' : (s.severity === 'medium' ? 'β ' : 'βΉ');
|
|
6135
|
+
log(` ${ic} [${s.kind}] ${s.detail}`);
|
|
6136
|
+
});
|
|
6137
|
+
log(dm3(` β μ¬κ° κ°μ΄λ: leerness session-resume`));
|
|
6138
|
+
log(dm3(` β μλ ν볡: leerness session-resume --auto-fix (1.9.222)`));
|
|
6139
|
+
}
|
|
6140
|
+
} catch {}
|
|
6141
|
+
|
|
5959
6142
|
// 1.9.8: active rules μλ λ
ΈμΆ (λ§€ μΈμ
μμ μ AIμκ² λ³΄μ)
|
|
5960
6143
|
const activeRules = readRules(root).filter(r => r.status === 'active');
|
|
5961
6144
|
if (activeRules.length) {
|
|
@@ -9707,6 +9890,15 @@ function sessionClose(root, opts = {}) {
|
|
|
9707
9890
|
tracked: reqAudit.tracked ? reqAudit.tracked.length : 0,
|
|
9708
9891
|
stale: reqAudit.stale ? reqAudit.stale.length : 0
|
|
9709
9892
|
};
|
|
9893
|
+
// 1.9.223: delivered ν¨ν΄ μλ κ°μ§ ν΅ν©
|
|
9894
|
+
try {
|
|
9895
|
+
const delivered = _detectDeliveredRequests(root);
|
|
9896
|
+
jsonResult.deliveredRequests = {
|
|
9897
|
+
candidates: delivered.candidates.length,
|
|
9898
|
+
currentVersion: delivered.currentVersion,
|
|
9899
|
+
autoCompleteAvailable: delivered.candidates.length > 0
|
|
9900
|
+
};
|
|
9901
|
+
} catch {}
|
|
9710
9902
|
} catch {}
|
|
9711
9903
|
try {
|
|
9712
9904
|
// 1.9.209: pre-wake-audit μλ μ€ν + μ μ₯ (sleep μ μλ μ κ²)
|
|
@@ -9758,11 +9950,16 @@ function sessionClose(root, opts = {}) {
|
|
|
9758
9950
|
|
|
9759
9951
|
log('');
|
|
9760
9952
|
log(`## π session close μλ ν΅ν© λ³΄κ³ (1.9.217)`);
|
|
9761
|
-
// 1.9.207
|
|
9953
|
+
// 1.9.207 + 1.9.223 (delivered ν¨ν΄ μλ κΆμ₯)
|
|
9762
9954
|
try {
|
|
9763
9955
|
const reqAudit = _auditUserRequests(root);
|
|
9764
9956
|
const missCnt = reqAudit.missing ? reqAudit.missing.length : 0;
|
|
9765
|
-
|
|
9957
|
+
let delivered = { candidates: [] };
|
|
9958
|
+
try { delivered = _detectDeliveredRequests(root); } catch {}
|
|
9959
|
+
if (delivered.candidates && delivered.candidates.length > 0) {
|
|
9960
|
+
log(yel(` π₯ delivered ν¨ν΄ ${delivered.candidates.length}건 (1.9.223) β μλ μλ£ κ°λ₯`));
|
|
9961
|
+
log(dim(` β leerness requests auto-complete --apply (μμ μ 리)`));
|
|
9962
|
+
} else if (missCnt > 0) {
|
|
9766
9963
|
log(red(` β λ―Έλ΅ μ¬μ©μ μμ² ${missCnt}건 (task-log/plan/decisions λ§€μΉ μ λ¨)`));
|
|
9767
9964
|
} else if (reqAudit.open > 0) {
|
|
9768
9965
|
log(grn(` β μ¬μ©μ μμ² ${reqAudit.open}건 λͺ¨λ tracked`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.223",
|
|
4
4
|
"description": "Leerness: λΉνκ΄΄ λ§μ΄κ·Έλ μ΄μ
, μλ λ²μ κ°μ§Β·μ
λ°μ΄νΈ, κ³ν/μ§ν/νΈλμ€ν μλν, κ²μΌλ¦Β·μν¬λ¦ΏΒ·μΈμ½λ© μλ κ°λ, Claude Code μ¬λμ ν΅ν©μ κ°μΆ νκ΅μ΄ μ°μ AI κ°λ° νλ€μ€.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|