leerness 1.9.219 โ 1.9.221
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 +86 -0
- package/README.md +3 -3
- package/bin/harness.js +214 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.221 โ 2026-05-22
|
|
4
|
+
|
|
5
|
+
**๐ MCP 60 ๋๊ตฌ ๋ง์ผ์คํค + abnormalShutdown JSON ํตํฉ (handoff/session close).**
|
|
6
|
+
|
|
7
|
+
### 1. MCP 60๋ฒ์งธ ๋๊ตฌ โ `leerness_session_resume`
|
|
8
|
+
- 1.9.220 ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง ์์คํ
์ ์ธ๋ถ AI์ ๋
ธ์ถ
|
|
9
|
+
- ์ธ์: `{ path? }`
|
|
10
|
+
- ์๋ต: `{ abnormalShutdown, severity, signals[], resumeGuide[] }`
|
|
11
|
+
- 5์ ํธ ๋ถ์ (last-handoff/wakeup-missed/in-progress-stale/auto-resume-plan/release-branch)
|
|
12
|
+
|
|
13
|
+
### 2. handoff --json `abnormalShutdown` ํ๋ ์ถ๊ฐ
|
|
14
|
+
- `{ detected, severity, signalCount, signals[], resumeGuide[] }`
|
|
15
|
+
- ์ธ๋ถ ๋ชจ๋ํฐ๋ง ๋๊ตฌ / CI ๊ฐ ๋น์ ์ ์ข
๋ฃ ์๋ ๊ฐ์ง
|
|
16
|
+
- 1.9.218 ํตํฉ ํจํด ํ์ฅ (handoff JSON 4์ข
ํ๋ ์์ฑ: userRequests/preWake/idempotency/abnormalShutdown)
|
|
17
|
+
|
|
18
|
+
### 3. session close --json ๋์ผ ํตํฉ
|
|
19
|
+
- ๋ง๊ฐ ์ ๋ค์ ๋ผ์ด๋ ์ง์
์ ์ฌ๊ฐ ๊ฐ์ด๋ ์๋ ํ์
|
|
20
|
+
- CI ๋ง๊ฐ ํ ๋น์ ์ ์ข
๋ฃ detect ๊ฐ๋ฅ
|
|
21
|
+
|
|
22
|
+
### 4. ๋์ ํ๊ท (1.9.207~220) โ ๋ชจ๋ ์ ์ง
|
|
23
|
+
|
|
24
|
+
### 5. stress-v166 โ 16/16 PASS
|
|
25
|
+
- 1.9.221 (4): VERSION + MCP 60 + session_resume ๋ฑ๋ก + ์ค ํธ์ถ (high severity ์๋ต)
|
|
26
|
+
- abnormalShutdown JSON ํตํฉ (3): handoff/session close + wakeup miss ์๋๋ฆฌ์ค
|
|
27
|
+
- ์ฑ๋ฅ (2): cold_start 374ms / MCP 60 ๋๊ตฌ 385ms
|
|
28
|
+
- ๋์ ํ๊ท (7): 1.9.207~220
|
|
29
|
+
|
|
30
|
+
### 6. ์๋ release (83 ๋ผ์ด๋ main-push streak ยท 44 ๋ผ์ด๋ npm publish streak)
|
|
31
|
+
|
|
32
|
+
๐ **MCP 60 ๋๊ตฌ ๋๋ฌ** (53 โ 60, +7: 1.9.168 +3 / 1.9.216 +5 / 1.9.221 +1)
|
|
33
|
+
๐ **handoff/session close JSON 4 ํตํฉ ํ๋ ์์ฑ** (userRequests/preWake/idempotency/abnormalShutdown)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1.9.220 โ 2026-05-22
|
|
38
|
+
|
|
39
|
+
**๐ ๋น์ ์ ์ข
๋ฃ ํ ์์จ ์ฌ๊ฐ ์์คํ
(์ฌ์ฉ์ ๋ช
์).**
|
|
40
|
+
|
|
41
|
+
### ์ฌ์ฉ์ ๋ช
์
|
|
42
|
+
> *"์์จ๋ชจ๋์ผ๋ ์ ์ ๋ชจ๋์๊ฑฐ๋, ์์คํ
์ข
๋ฃ๋ AI์์ด์ ํธ ์ธ์
์ข
๋ฃ๋ฑ์ผ๋ก ์์จ๊ฐ๋ฐ๋ชจ๋๊ฐ ๋น์ ์์ ์ผ๋ก ์ข
๋ฃ๋์๋ค๊ฐ ๋ค์ ์คํํ์ฌ ์ธ์
์ ์ด์ด๊ฐ๋, ๊ฐ์งํ๊ณ ์์
์ด ์ค๋จ๋์ง์ ์ด๋ ๋๋ฝ๋์์
์ ๊ฐ์งํ๊ณ ๊ฐ๋ฐ์์ด์ด๊ฐ๊ฑฐ๋ ์์จ๋ชจ๋๋ฅผ ๋ค์ ์งํ"*
|
|
43
|
+
|
|
44
|
+
### 1. `_detectAbnormalShutdown(root)` โ 5์ ํธ ์ข
ํฉ ๊ฐ์ง
|
|
45
|
+
| # | ์ ํธ | ํธ๋ฆฌ๊ฑฐ | severity |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| 1 | `last-handoff-stale` | gap > 60min (์ ์ 25min ๋๋น) | gap > 240min: high / else medium |
|
|
48
|
+
| 2 | `wakeup-missed` | active-wakeups pending โ 30min+ ์ง๋จ | gap > 120min: high |
|
|
49
|
+
| 3 | `in-progress-stale` | in-progress task + progress-tracker 24h+ stale | high |
|
|
50
|
+
| 4 | `auto-resume-plan-unused` | auto-resume-plan 60min+ ๋ฏธ์ฌ์ฉ | ageMin > 240: medium |
|
|
51
|
+
| 5 | `release-branch-pending` | 2+ release/* branch (sync-main ๋๋ฝ) | low |
|
|
52
|
+
|
|
53
|
+
### 2. `leerness session-resume` CLI
|
|
54
|
+
- ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง + 5์ ํธ ๋ถ์
|
|
55
|
+
- ์๋ ์ฌ๊ฐ ๊ฐ์ด๋ ์ถ๋ ฅ (7๋จ๊ณ)
|
|
56
|
+
- `--json` ์ต์
(์ธ๋ถ ์๋ํ)
|
|
57
|
+
|
|
58
|
+
### 3. handoff ํค๋๋ผ์ธ 16๋ฒ์งธ ์์
|
|
59
|
+
- ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง ์: `๐ ๋น์ ์์ข
๋ฃ <severity> (N์ ํธ)`
|
|
60
|
+
- ํค๋๋ผ์ธ ๋ผ๋ฒจ: `1.9.81/93/113/152/162/192/197/204/207/209/215/220`
|
|
61
|
+
|
|
62
|
+
### 4. ์ฌ๊ฐ ๊ฐ์ด๋ 7๋จ๊ณ (์๋ ์์ฑ)
|
|
63
|
+
์ ํธ๋ณ ๋ง์ถค ๊ฐ์ด๋:
|
|
64
|
+
1. `leerness handoff .` โ ํ์ฌ ์ํ ์ข
ํฉ
|
|
65
|
+
2. `leerness resume` โ auto-resume-plan ์ ์ฉ (auto-resume-plan-unused ์)
|
|
66
|
+
3. `leerness task list --status in-progress` โ stale task ๊ฒํ (in-progress-stale ์)
|
|
67
|
+
4. ScheduleWakeup ์ฌ๋ฑ๋ก (wakeup-missed ์)
|
|
68
|
+
5. `git branch -a` โ `leerness release sync-main` (release-branch-pending ์)
|
|
69
|
+
6. `leerness pre-wake-audit` โ ๋๋ฝ ์์
/ ์ถฉ๋ ์ ๊ฒ
|
|
70
|
+
7. `leerness requests audit` โ ๋ฏธ๋ต ์ฌ์ฉ์ ์์ฒญ ํ์ธ
|
|
71
|
+
|
|
72
|
+
### 5. ์ค ๊ฒ์ฆ ์๋๋ฆฌ์ค
|
|
73
|
+
- **์ ์ ์ํฌ์คํ์ด์ค** โ `abnormalShutdown: false / severity: none`
|
|
74
|
+
- **wakeup 2024๋ถ ์ง๋จ** (์๋ฎฌ๋ ์ด์
) โ `severity: high / wakeup-missed 1์ ํธ + ๊ฐ์ด๋ 4๋จ๊ณ ์๋ ์์ฑ`
|
|
75
|
+
|
|
76
|
+
### 6. ๋์ ํ๊ท (1.9.207~219) โ ๋ชจ๋ ์ ์ง
|
|
77
|
+
|
|
78
|
+
### 7. stress-v165 โ 18/18 PASS
|
|
79
|
+
- 1.9.220 (7): VERSION + 5์ ํธ ๋ฑ๋ก + ์ ์/๋น์ ์ ์๋๋ฆฌ์ค + handoff ํตํฉ + CLI ๋ผ์ฐํ
|
|
80
|
+
- ์ฑ๋ฅ (2): cold_start 461ms / MCP 59 ๋๊ตฌ 424ms
|
|
81
|
+
- ๋์ ํ๊ท (9): 1.9.207~219
|
|
82
|
+
|
|
83
|
+
### 8. ์๋ release (82 ๋ผ์ด๋ main-push streak ยท 43 ๋ผ์ด๋ npm publish streak)
|
|
84
|
+
|
|
85
|
+
๐ **์์จ ๋ชจ๋ ๋ณต์๋ ฅ ๊ฐํ** โ ์ ์ /์ข
๋ฃ/์ธ์
์ข
๋ฃ ๋ฌด๊ด, ์ฌ์์ ์ ์๋ ์ง๋จ + ์ฌ๊ฐ ๊ฐ๋ฅ
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
3
89
|
## 1.9.219 โ 2026-05-22
|
|
4
90
|
|
|
5
91
|
**๐ 80 ๋ผ์ด๋ ์์จ ๋ชจ๋ ๋ง์ผ์คํค + session-workflow.md ํตํฉ ๊ฐฑ์ .**
|
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.221 AI Agent Reliability Harness + Sandbox โ
|
|
16
16
|
โ verify ยท remember ยท orchestrate ยท audit ยท sandbox ยท drift โ
|
|
17
|
-
โ ๐
|
|
17
|
+
โ ๐ MCP 60 ๋๊ตฌ ๋ง์ผ์คํค ยท handoff JSON 4 ํตํฉ ํ๋ ์์ฑ โ
|
|
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.221';
|
|
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 ์ฒ๋ฆฌ).
|
|
@@ -2251,6 +2251,140 @@ function _saveAndAppendPreWakeReport(root, audit) {
|
|
|
2251
2251
|
return audit;
|
|
2252
2252
|
}
|
|
2253
2253
|
|
|
2254
|
+
// 1.9.220: ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง + ์์จ ์ฌ๊ฐ (์ฌ์ฉ์ ๋ช
์)
|
|
2255
|
+
// "์ ์ ๋ชจ๋/์์คํ
์ข
๋ฃ/AI์์ด์ ํธ ์ธ์
์ข
๋ฃ๋ก ๋น์ ์ ์ข
๋ฃ๋ ํ ์ฌ์คํ ์ ์ค๋จ์ง์ /๋๋ฝ์์
๊ฐ์ง"
|
|
2256
|
+
// 5์ ํธ ์ข
ํฉ ๋ถ์:
|
|
2257
|
+
// 1) last-handoff gap > 60min (1.9.199, 25min interval ๊ธฐ๋ ๋๋น 2.4๋ฐฐ+)
|
|
2258
|
+
// 2) wakeup miss (active-wakeups pending โ 30min+ ์ง๋จ, 1.9.205)
|
|
2259
|
+
// 3) in-progress task 24h+ ๊ฐฑ์ ์์ (stale, progress-tracker mtime)
|
|
2260
|
+
// 4) auto-resume-plan ์กด์ฌ + ageMin > 60min (1.9.203, ์ฌ์ฉ ์ ๋จ)
|
|
2261
|
+
// 5) release/X.X.X branch ์์ + main ๋ฏธ๋จธ์ง (release sync-main ๋๋ฝ)
|
|
2262
|
+
// ๊ฒฐ๊ณผ: { abnormalShutdown: true/false, signals: [...], severity, resumeGuide }
|
|
2263
|
+
function _detectAbnormalShutdown(root) {
|
|
2264
|
+
const result = {
|
|
2265
|
+
detectedAt: new Date().toISOString(),
|
|
2266
|
+
signals: [],
|
|
2267
|
+
severity: 'none',
|
|
2268
|
+
abnormalShutdown: false,
|
|
2269
|
+
resumeGuide: []
|
|
2270
|
+
};
|
|
2271
|
+
const now = Date.now();
|
|
2272
|
+
|
|
2273
|
+
// 1) last-handoff gap > 60min (์ ์ 25min interval ๋๋น)
|
|
2274
|
+
try {
|
|
2275
|
+
const lhFp = path.join(root, '.harness', 'last-handoff.json');
|
|
2276
|
+
if (exists(lhFp)) {
|
|
2277
|
+
const j = JSON.parse(read(lhFp));
|
|
2278
|
+
const last = j.lastAt || (j.history && j.history.length > 0 ? j.history[j.history.length - 1] : null);
|
|
2279
|
+
if (last) {
|
|
2280
|
+
const lastMs = new Date(last).getTime();
|
|
2281
|
+
const gapMin = Math.floor((now - lastMs) / 60000);
|
|
2282
|
+
if (gapMin > 60) {
|
|
2283
|
+
result.signals.push({
|
|
2284
|
+
kind: 'last-handoff-stale',
|
|
2285
|
+
gapMin,
|
|
2286
|
+
detail: `last handoff ${gapMin}๋ถ ์ (์ ์ 25min ๊ฐ๊ฒฉ ๋๋น ${Math.round(gapMin/25)}x ์ด๊ณผ) โ ์ ์ /์ข
๋ฃ ์์ฌ`,
|
|
2287
|
+
severity: gapMin > 240 ? 'high' : 'medium'
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
} catch {}
|
|
2293
|
+
|
|
2294
|
+
// 2) wakeup miss (active-wakeups pending โ 30min+ ์ง๋จ)
|
|
2295
|
+
try {
|
|
2296
|
+
const wkStat = _analyzeWakeupStatus(root);
|
|
2297
|
+
if (wkStat.hasWakeup && wkStat.deltaMin > 30 && wkStat.kind === 'missed') {
|
|
2298
|
+
result.signals.push({
|
|
2299
|
+
kind: 'wakeup-missed',
|
|
2300
|
+
gapMin: wkStat.deltaMin,
|
|
2301
|
+
detail: `wakeup ${wkStat.deltaMin}๋ถ ์ง๋จ (status=pending) โ ์๋ ์ฌ๊ฐ ์คํจ`,
|
|
2302
|
+
severity: wkStat.deltaMin > 120 ? 'high' : 'medium'
|
|
2303
|
+
});
|
|
2304
|
+
}
|
|
2305
|
+
} catch {}
|
|
2306
|
+
|
|
2307
|
+
// 3) in-progress task 24h+ stale (progress-tracker mtime + ํ์ฑ task ์นด์ดํธ)
|
|
2308
|
+
try {
|
|
2309
|
+
const ptPath = path.join(root, '.harness', 'progress-tracker.md');
|
|
2310
|
+
if (exists(ptPath)) {
|
|
2311
|
+
const stat = fs.statSync(ptPath);
|
|
2312
|
+
const ageMin = Math.floor((now - stat.mtimeMs) / 60000);
|
|
2313
|
+
const content = read(ptPath);
|
|
2314
|
+
const inProgress = (content.match(/^\|\s*T-\d{4,}\s*\|\s*in-progress\s*\|/gm) || []).length;
|
|
2315
|
+
if (inProgress > 0 && ageMin > 24 * 60) {
|
|
2316
|
+
result.signals.push({
|
|
2317
|
+
kind: 'in-progress-stale',
|
|
2318
|
+
inProgressCount: inProgress,
|
|
2319
|
+
ageMin,
|
|
2320
|
+
detail: `${inProgress}๊ฑด in-progress task, progress-tracker ${Math.floor(ageMin/60)}h ๊ฐฑ์ ์์`,
|
|
2321
|
+
severity: 'high'
|
|
2322
|
+
});
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
} catch {}
|
|
2326
|
+
|
|
2327
|
+
// 4) auto-resume-plan ์กด์ฌ + ageMin > 60min (์ฌ์ฉ ์ ๋จ)
|
|
2328
|
+
try {
|
|
2329
|
+
const plan = _loadAutoResumePlan(root);
|
|
2330
|
+
if (plan && plan.ageMin > 60) {
|
|
2331
|
+
result.signals.push({
|
|
2332
|
+
kind: 'auto-resume-plan-unused',
|
|
2333
|
+
ageMin: plan.ageMin,
|
|
2334
|
+
nextRound: plan.nextRoundVersion,
|
|
2335
|
+
detail: `auto-resume-plan ${plan.ageMin}๋ถ ์ ์์ฑ (${plan.nextRoundVersion}) โ ์ฌ์ฉ ์ ๋จ`,
|
|
2336
|
+
severity: plan.ageMin > 240 ? 'medium' : 'low'
|
|
2337
|
+
});
|
|
2338
|
+
}
|
|
2339
|
+
} catch {}
|
|
2340
|
+
|
|
2341
|
+
// 5) release/X.X.X branch ์์ + main ๋ฏธ๋จธ์ง (git ์ํ)
|
|
2342
|
+
try {
|
|
2343
|
+
const r = cp.spawnSync('git', ['branch', '--list', 'release/*'], { cwd: root, encoding: 'utf8', timeout: 3000 });
|
|
2344
|
+
if (r.status === 0) {
|
|
2345
|
+
const branches = (r.stdout || '').split('\n').map(s => s.trim().replace(/^\*?\s*/, '')).filter(b => b.startsWith('release/'));
|
|
2346
|
+
if (branches.length >= 2) { // 2๊ฐ ์ด์์ด๋ฉด ๋๋ฝ ๊ฐ๋ฅ์ฑ
|
|
2347
|
+
result.signals.push({
|
|
2348
|
+
kind: 'release-branch-pending',
|
|
2349
|
+
count: branches.length,
|
|
2350
|
+
recent: branches.slice(-3),
|
|
2351
|
+
detail: `${branches.length}๊ฑด release/* branch (sync-main ๋๋ฝ ๊ฐ๋ฅ)`,
|
|
2352
|
+
severity: 'low'
|
|
2353
|
+
});
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
} catch {}
|
|
2357
|
+
|
|
2358
|
+
// ์ข
ํฉ ํ๋จ
|
|
2359
|
+
const high = result.signals.filter(s => s.severity === 'high').length;
|
|
2360
|
+
const medium = result.signals.filter(s => s.severity === 'medium').length;
|
|
2361
|
+
if (high > 0) { result.severity = 'high'; result.abnormalShutdown = true; }
|
|
2362
|
+
else if (medium > 0) { result.severity = 'medium'; result.abnormalShutdown = true; }
|
|
2363
|
+
else if (result.signals.length > 0) result.severity = 'low';
|
|
2364
|
+
|
|
2365
|
+
// ์ฌ๊ฐ ๊ฐ์ด๋
|
|
2366
|
+
if (result.abnormalShutdown) {
|
|
2367
|
+
result.resumeGuide.push('1. leerness handoff . โ ํ์ฌ ์ํ ์ข
ํฉ ํ์ธ');
|
|
2368
|
+
if (result.signals.some(s => s.kind === 'auto-resume-plan-unused')) {
|
|
2369
|
+
result.resumeGuide.push('2. leerness resume โ ์ ์ฅ๋ auto-resume-plan ์ ์ฉ (1.9.203)');
|
|
2370
|
+
}
|
|
2371
|
+
if (result.signals.some(s => s.kind === 'in-progress-stale')) {
|
|
2372
|
+
result.resumeGuide.push('3. leerness task list --status in-progress โ stale task ๊ฒํ (drop or ์ฌ๊ฐ)');
|
|
2373
|
+
}
|
|
2374
|
+
if (result.signals.some(s => s.kind === 'wakeup-missed')) {
|
|
2375
|
+
result.resumeGuide.push('4. ScheduleWakeup ์ฌ๋ฑ๋ก (์ฌ์ฉ์ ํธ๋ฆฌ๊ฑฐ ๋๋ R-0001 ๋ฃฐ)');
|
|
2376
|
+
}
|
|
2377
|
+
if (result.signals.some(s => s.kind === 'release-branch-pending')) {
|
|
2378
|
+
result.resumeGuide.push('5. git branch -a๋ก release/* ํ์ธ + leerness release sync-main ์ฌ์คํ');
|
|
2379
|
+
}
|
|
2380
|
+
result.resumeGuide.push('6. leerness pre-wake-audit โ ๋๋ฝ ์์
/ ์ถฉ๋ ์ข
ํฉ ์ ๊ฒ');
|
|
2381
|
+
result.resumeGuide.push('7. leerness requests audit โ ๋ฏธ๋ต ์ฌ์ฉ์ ์์ฒญ ํ์ธ');
|
|
2382
|
+
} else {
|
|
2383
|
+
result.resumeGuide.push('์ ์ ์ด์ ์ค โ ๋น์ ์ ์ข
๋ฃ ์ ํธ ์์');
|
|
2384
|
+
}
|
|
2385
|
+
return result;
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2254
2388
|
// 1.9.210: adaptive wakeup interval (์ฌ์ฉ์ ๋ช
์)
|
|
2255
2389
|
// "wakeup 30๋ถ๋ฑ ๊ธด ์๊ฐ์ด ํ์์๋ค๋ฉด ๊ฐ๊ฒฉ์ ํ์ดํธํ๊ฒ ์๋์ผ๋ก ์กฐ์ ํ๋๋ก"
|
|
2256
2390
|
// ์ฌ์ฉ์ ํ๋๋ ๊ธฐ๋ฐ ๊ถ์ฅ interval ๊ณ์ฐ โ ScheduleWakeup ์ ์๋ ์ ์ฉ (R-0001 ๋ฃฐ ์ธ ๋์ ๋ณด์ )
|
|
@@ -2920,6 +3054,47 @@ function requestsCmd(root, sub, ...rest) {
|
|
|
2920
3054
|
process.exit(1);
|
|
2921
3055
|
}
|
|
2922
3056
|
|
|
3057
|
+
// 1.9.220: leerness session-resume โ ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง + ์์จ ์ฌ๊ฐ ๊ฐ์ด๋ (์ฌ์ฉ์ ๋ช
์)
|
|
3058
|
+
function sessionResumeCmd(root) {
|
|
3059
|
+
root = absRoot(root);
|
|
3060
|
+
const isTty = process.stdout && process.stdout.isTTY;
|
|
3061
|
+
const cyan = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
|
|
3062
|
+
const grn = s => isTty ? `\x1b[32m${s}\x1b[0m` : s;
|
|
3063
|
+
const yel = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
|
|
3064
|
+
const red = s => isTty ? `\x1b[31m${s}\x1b[0m` : s;
|
|
3065
|
+
const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
3066
|
+
|
|
3067
|
+
const result = _detectAbnormalShutdown(root);
|
|
3068
|
+
if (has('--json')) { log(JSON.stringify(result, null, 2)); return; }
|
|
3069
|
+
log(cyan(`# leerness session-resume (1.9.220) โ ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง + ์์จ ์ฌ๊ฐ`));
|
|
3070
|
+
log(` detected at: ${result.detectedAt}`);
|
|
3071
|
+
log('');
|
|
3072
|
+
if (!result.abnormalShutdown) {
|
|
3073
|
+
log(grn(` โ ๋น์ ์ ์ข
๋ฃ ์ ํธ ์์ โ ์ ์ ์ด์ ์ค`));
|
|
3074
|
+
if (result.signals.length > 0) {
|
|
3075
|
+
log(dim(` (low-severity ์ ํธ ${result.signals.length}๊ฑด โ ๋ฌด์ ๊ฐ๋ฅ)`));
|
|
3076
|
+
}
|
|
3077
|
+
log('');
|
|
3078
|
+
log(dim(` โ ํ์๋๋ก leerness handoff . ๋ก ์์`));
|
|
3079
|
+
return;
|
|
3080
|
+
}
|
|
3081
|
+
const sevIcon = result.severity === 'high' ? '๐จ' : 'โ ';
|
|
3082
|
+
const sevColor = result.severity === 'high' ? red : yel;
|
|
3083
|
+
log(sevColor(` ${sevIcon} ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง โ severity: ${result.severity} (signals: ${result.signals.length})`));
|
|
3084
|
+
log('');
|
|
3085
|
+
log(`## ๊ฐ์ง ์ ํธ`);
|
|
3086
|
+
for (const s of result.signals) {
|
|
3087
|
+
const icon = s.severity === 'high' ? '๐จ' : (s.severity === 'medium' ? 'โ ' : 'โน');
|
|
3088
|
+
const c = s.severity === 'high' ? red : (s.severity === 'medium' ? yel : dim);
|
|
3089
|
+
log(c(` ${icon} [${s.kind}] ${s.detail}`));
|
|
3090
|
+
}
|
|
3091
|
+
log('');
|
|
3092
|
+
log(`## ์ฌ๊ฐ ๊ฐ์ด๋`);
|
|
3093
|
+
for (const g of result.resumeGuide) {
|
|
3094
|
+
log(` ${g}`);
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
|
|
2923
3098
|
// 1.9.208: leerness constraints <list|check|add> โ ํ๋ซํผ/API ์ ์ฝ ์ฌ์ ์ฒดํฌ CLI (์ฌ์ฉ์ ๋ช
์)
|
|
2924
3099
|
// "ํน์ ํ๋ซํผ์ API ... ํธ์ถ์๋๊ฐ ์ด๋น 5ํ ์ดํ๋ก๋ง ํด์ผํ๋ค๋ ๊ท์ ์ ๋จผ์ ํ์ธ"
|
|
2925
3100
|
// list โ ๋ฑ๋ก๋ ๋ชจ๋ ํ๋ซํผ catalog ์ถ๋ ฅ
|
|
@@ -5522,6 +5697,17 @@ function handoff(root) {
|
|
|
5522
5697
|
overall: idemp.summary.overall
|
|
5523
5698
|
};
|
|
5524
5699
|
} catch {}
|
|
5700
|
+
// 1.9.221: abnormalShutdown ์๋ ๊ฐ์ง (1.9.220 ํตํฉ)
|
|
5701
|
+
try {
|
|
5702
|
+
const ad = _detectAbnormalShutdown(root);
|
|
5703
|
+
result.abnormalShutdown = {
|
|
5704
|
+
detected: ad.abnormalShutdown,
|
|
5705
|
+
severity: ad.severity,
|
|
5706
|
+
signalCount: ad.signals.length,
|
|
5707
|
+
signals: ad.signals.map(s => ({ kind: s.kind, severity: s.severity, detail: s.detail })),
|
|
5708
|
+
resumeGuide: ad.resumeGuide
|
|
5709
|
+
};
|
|
5710
|
+
} catch {}
|
|
5525
5711
|
log(JSON.stringify(result, null, 2));
|
|
5526
5712
|
return;
|
|
5527
5713
|
}
|
|
@@ -5694,6 +5880,13 @@ function handoff(root) {
|
|
|
5694
5880
|
}
|
|
5695
5881
|
}
|
|
5696
5882
|
} catch {}
|
|
5883
|
+
// 16) 1.9.220: ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง (์ฌ์ฉ์ ๋ช
์) โ ๊นจ์ด๋จ ์งํ ์๋ ๋
ธ์ถ
|
|
5884
|
+
try {
|
|
5885
|
+
const ad = _detectAbnormalShutdown(root);
|
|
5886
|
+
if (ad.abnormalShutdown) {
|
|
5887
|
+
parts.push(`๐ ๋น์ ์์ข
๋ฃ ${ad.severity} (${ad.signals.length}์ ํธ)`);
|
|
5888
|
+
}
|
|
5889
|
+
} catch {}
|
|
5697
5890
|
// 15) 1.9.215: ํ์ฌ ํ์ฑ task์์ constraints/intent ์๋ ๋ถ์ (1.9.208/213 ํตํฉ)
|
|
5698
5891
|
try {
|
|
5699
5892
|
// progress-tracker.md ์ ์ฒซ active task request ์ถ์ถ
|
|
@@ -5732,7 +5925,7 @@ function handoff(root) {
|
|
|
5732
5925
|
if (parts.length) {
|
|
5733
5926
|
const isTty = process.stdout && process.stdout.isTTY;
|
|
5734
5927
|
const cy = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
|
|
5735
|
-
log(cy(`๐ ํค๋๋ผ์ธ (1.9.81/93/113/152/162/192/197/204/207/209/215): ${parts.join(' ยท ')}`));
|
|
5928
|
+
log(cy(`๐ ํค๋๋ผ์ธ (1.9.81/93/113/152/162/192/197/204/207/209/215/220): ${parts.join(' ยท ')}`));
|
|
5736
5929
|
}
|
|
5737
5930
|
} catch {}
|
|
5738
5931
|
}
|
|
@@ -9541,6 +9734,17 @@ function sessionClose(root, opts = {}) {
|
|
|
9541
9734
|
overall: idemp.summary.overall
|
|
9542
9735
|
};
|
|
9543
9736
|
} catch {}
|
|
9737
|
+
try {
|
|
9738
|
+
// 1.9.221: abnormalShutdown ์๋ ๊ฐ์ง (1.9.220 ํตํฉ) โ session close ์ ๋ค์ ์ฌ๊ฐ ๊ฐ์ด๋ ํ์
|
|
9739
|
+
const ad = _detectAbnormalShutdown(root);
|
|
9740
|
+
jsonResult.abnormalShutdown = {
|
|
9741
|
+
detected: ad.abnormalShutdown,
|
|
9742
|
+
severity: ad.severity,
|
|
9743
|
+
signalCount: ad.signals.length,
|
|
9744
|
+
signals: ad.signals.map(s => ({ kind: s.kind, severity: s.severity, detail: s.detail })),
|
|
9745
|
+
resumeGuide: ad.resumeGuide
|
|
9746
|
+
};
|
|
9747
|
+
} catch {}
|
|
9544
9748
|
|
|
9545
9749
|
process.stdout.write(JSON.stringify(jsonResult, null, 2) + '\n');
|
|
9546
9750
|
} else {
|
|
@@ -13416,7 +13620,8 @@ function mcpServeCmd(root) {
|
|
|
13416
13620
|
{ name: 'leerness_constraints_check', description: '1.9.216 (1.9.208 ์ฌ์ฉ์ ๋ช
์) โ ํ๋ซํผ/API ์ ์ฝ ์ฌ์ ์ฒดํฌ. ์ฌ์ฉ์ ์์ฒญ ํ
์คํธ์์ ํ๋ซํผ alias ๋งค์นญ (stripe/openai/anthropic/github/discord/twitter 6์ข
+ ์ฌ์ฉ์ ์ ์) โ ๊ฐ ํ๋ซํผ์ rate-limit / idempotency / auth / cost ์ ์ฝ ๋
ธ์ถ. ์ธ๋ถ AI๊ฐ "์ด ๊ธฐ๋ฅ ๊ตฌํ ์ ์ด๋ค ๊ท์ ์ ๋ด์ผ ํ๋?"๋ฅผ ์ง์ ํ์. ์ธ์: { request (required), path? }', inputSchema: { type: 'object', properties: { request: { type: 'string' }, path: { type: 'string' } }, required: ['request'] } },
|
|
13417
13621
|
{ name: 'leerness_pre_wake_audit', description: '1.9.216 (1.9.209 ์ฌ์ฉ์ ๋ช
์) โ sleep ์ sub-agent audit. 6 ์์ญ ์ ๊ฒ: missing-user-requests / stale-in-progress / drift-handoff-stale / wakeup-missed / next-action-pending / auto-resume-plan. ์ธ๋ถ AI๊ฐ "๊นจ์ด๋๊ธฐ ์ ์ ๊ฒํ ๋ถ๋ถ"์ ํ์. ์๋ต: { auditedAt, findings: {critical, warning, info}, summary }. ์ธ์: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
|
|
13418
13622
|
{ name: 'leerness_intent_classify', description: '1.9.216 (1.9.213 ์ฌ์ฉ์ ๋ช
์) โ ์ฌ์ฉ์ ์๋ ํ์
+ scope expansion ๊ฒ์ดํธ. ์๋ต: { intent: precise|broad|default, signals, domain, explicitMentions, expansionCandidates, mode: dry-run }. 3์์น ์์ : (1) Always-Off Opt-In, (2) Dry-run ๊ธฐ๋ณธ (์คํ X), (3) ๋ช
์ vs ์ถ๋ก ๋ถ๋ฆฌ ๋ผ๋ฒจ๋ง. 5 ๋๋ฉ์ธ (game/web/api/cli/data). ์ธ๋ถ AI๊ฐ "์ด ์์ฒญ์ ์ ํํ ๊ทธ๊ฒ๋ง / ํฌ๊ด์ / ๊ธฐ๋ณธ์ธ๊ฐ?"๋ฅผ ํ์. ์ธ์: { request (required), path? }', inputSchema: { type: 'object', properties: { request: { type: 'string' }, path: { type: 'string' } }, required: ['request'] } },
|
|
13419
|
-
{ name: 'leerness_idempotency_audit', description: '1.9.216 (1.9.212 ์ฌ์ฉ์ ๋ช
์) โ ๋ฉฑ๋ฑ์ฑ ์๋ฐ ํ์ง. 4์์ญ ์ ๊ฒ: rule-duplicate (medium) / task-duplicate-request (medium) / user-request-duplicate (low) / wakeup-duplicate (high). ์๋ต: { violations[], verified[], summary: {totalViolations, high/medium/low, overall} }. ์ธ๋ถ AI๊ฐ "์ํฌ์คํ์ด์ค์ ์ค๋ณต/์ถฉ๋์ด ์๋?"๋ฅผ ํ์. ๐ MCP 58 ๋๊ตฌ ๋ง์ผ์คํค (50โ58). ์ธ์: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
|
|
13623
|
+
{ name: 'leerness_idempotency_audit', description: '1.9.216 (1.9.212 ์ฌ์ฉ์ ๋ช
์) โ ๋ฉฑ๋ฑ์ฑ ์๋ฐ ํ์ง. 4์์ญ ์ ๊ฒ: rule-duplicate (medium) / task-duplicate-request (medium) / user-request-duplicate (low) / wakeup-duplicate (high). ์๋ต: { violations[], verified[], summary: {totalViolations, high/medium/low, overall} }. ์ธ๋ถ AI๊ฐ "์ํฌ์คํ์ด์ค์ ์ค๋ณต/์ถฉ๋์ด ์๋?"๋ฅผ ํ์. ๐ MCP 58 ๋๊ตฌ ๋ง์ผ์คํค (50โ58). ์ธ์: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
|
|
13624
|
+
{ name: 'leerness_session_resume', description: '1.9.221 (1.9.220 ์ฌ์ฉ์ ๋ช
์) โ ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง + ์์จ ์ฌ๊ฐ. 5์ ํธ ๋ถ์: last-handoff-stale / wakeup-missed / in-progress-stale / auto-resume-plan-unused / release-branch-pending. ์๋ต: { abnormalShutdown, severity (none/low/medium/high), signals[], resumeGuide[] }. ์ธ๋ถ AI๊ฐ "์ ์ /์์คํ
์ข
๋ฃ/์ธ์
์ข
๋ฃ ํ leerness ์ํ๊ฐ ์ ์์ธ๊ฐ? ์ด๋ป๊ฒ ์ฌ๊ฐ?"๋ฅผ ํ์. ๐ MCP 60 ๋๊ตฌ ๋ง์ผ์คํค (53โ60, +7 in 1.9.168/216/221). ์ธ์: { path? }', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
|
|
13420
13625
|
];
|
|
13421
13626
|
|
|
13422
13627
|
function send(obj) {
|
|
@@ -13568,6 +13773,10 @@ function mcpServeCmd(root) {
|
|
|
13568
13773
|
// 1.9.216 (1.9.212): ๋ฉฑ๋ฑ์ฑ ๊ฐ์ฌ (rule/task/user-requests/wakeups 4์์ญ)
|
|
13569
13774
|
cliArgs = ['idempotency', 'audit', '--path', targetPath, '--json'];
|
|
13570
13775
|
break;
|
|
13776
|
+
case 'leerness_session_resume':
|
|
13777
|
+
// 1.9.221 (1.9.220): ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง + ์์จ ์ฌ๊ฐ
|
|
13778
|
+
cliArgs = ['session-resume', '--path', targetPath, '--json'];
|
|
13779
|
+
break;
|
|
13571
13780
|
default:
|
|
13572
13781
|
return send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Unknown tool: ${name}` } });
|
|
13573
13782
|
}
|
|
@@ -17197,6 +17406,8 @@ async function main() {
|
|
|
17197
17406
|
if (cmd === 'resume') return resumeCmd(arg('--path', process.cwd()));
|
|
17198
17407
|
// 1.9.207: leerness requests <audit|add|list|complete|drop> โ ์ฌ์ฉ์ ์์ฒญ ๋๋ฝ ํ์ธ ์ ์ฐจ (์ฌ์ฉ์ ๋ช
์)
|
|
17199
17408
|
if (cmd === 'requests') return requestsCmd(arg('--path', process.cwd()), args[1], ...args.slice(2));
|
|
17409
|
+
// 1.9.220: leerness session-resume โ ๋น์ ์ ์ข
๋ฃ ๊ฐ์ง + ์์จ ์ฌ๊ฐ ๊ฐ์ด๋ (์ฌ์ฉ์ ๋ช
์)
|
|
17410
|
+
if (cmd === 'session-resume') return sessionResumeCmd(arg('--path', process.cwd()));
|
|
17200
17411
|
// 1.9.208: leerness constraints <list|check|add> โ ํ๋ซํผ/API ์ ์ฝ ์ฌ์ ์ฒดํฌ (์ฌ์ฉ์ ๋ช
์)
|
|
17201
17412
|
if (cmd === 'constraints') return constraintsCmd(arg('--path', process.cwd()), args[1], ...args.slice(2));
|
|
17202
17413
|
// 1.9.209: leerness pre-wake-audit โ sleep ์ sub-agent audit (์ฌ์ฉ์ ๋ช
์)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.221",
|
|
4
4
|
"description": "Leerness: ๋นํ๊ดด ๋ง์ด๊ทธ๋ ์ด์
, ์๋ ๋ฒ์ ๊ฐ์งยท์
๋ฐ์ดํธ, ๊ณํ/์งํ/ํธ๋์คํ ์๋ํ, ๊ฒ์ผ๋ฆยท์ํฌ๋ฆฟยท์ธ์ฝ๋ฉ ์๋ ๊ฐ๋, Claude Code ์ฌ๋์ ํตํฉ์ ๊ฐ์ถ ํ๊ตญ์ด ์ฐ์ AI ๊ฐ๋ฐ ํ๋ค์ค.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|