leerness 1.9.222 β†’ 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 CHANGED
@@ -1,5 +1,47 @@
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
+
3
45
  ## 1.9.222 β€” 2026-05-22
4
46
 
5
47
  **πŸ›‘ session-resume --auto-fix μ•ˆμ „ 회볡 + handoff λ³Έλ¬Έ 비정상 μ’…λ£Œ μžλ™ λ…ΈμΆœ.**
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **AI μ½”λ”© μ—μ΄μ „νŠΈμ˜ κ±°μ§“ μ™„λ£ŒΒ·μ€‘λ³΅Β·λ§κ°Β·μΆ©λŒμ„ λ§‰μ•„μ£ΌλŠ” κ²€μˆ˜Β·κΈ°μ–΅Β·ν˜‘μ—… CLI ν•˜λ„€μŠ€.**
4
4
 
5
- [![npm](https://img.shields.io/badge/npm-leerness-blue)](https://www.npmjs.com/package/leerness) [![version](https://img.shields.io/badge/version-1.9.222-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v167-14%2F14-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-60_πŸŽ‰-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-152-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-84_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![auto-fix](https://img.shields.io/badge/πŸ›‘_session--resume-auto--fix-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-408ms-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
5
+ [![npm](https://img.shields.io/badge/npm-leerness-blue)](https://www.npmjs.com/package/leerness) [![version](https://img.shields.io/badge/version-1.9.223-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v168-15%2F15-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-60_πŸŽ‰-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-153-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-85_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![auto-complete](https://img.shields.io/badge/πŸ“₯_requests-auto--complete-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-401ms-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
6
6
 
7
7
  ```
8
8
  ╔══════════════════════════════════════════════════════════════╗
@@ -12,9 +12,9 @@
12
12
  β•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β•šβ•β•β•β•β–ˆβ–ˆβ•‘ β•‘
13
13
  β•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β•‘
14
14
  β•‘ β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β• β•‘
15
- β•‘ v1.9.222 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.223 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ πŸ›‘ session-resume --auto-fix Β· handoff λ³Έλ¬Έ 비정상 μ’…λ£Œ μžλ™ β•‘
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.222';
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 β†’ λˆ„λ½ 후보 + tracked + stale 보고 (--json κ°€λŠ₯)`);
2960
- log(` add "<text>" β†’ μ‚¬μš©μž μš”μ²­ μˆ˜λ™ 기둝`);
2961
- log(` list β†’ 전체 μš”μ²­ 좜λ ₯ (--json κ°€λŠ₯, --status open|completed|dropped)`);
2962
- log(` complete <id> β†’ μš”μ²­ μ™„λ£Œ ν‘œμ‹œ (예: UR-0003)`);
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
 
@@ -5723,6 +5815,16 @@ function handoff(root) {
5723
5815
  tracked: reqAudit.tracked ? reqAudit.tracked.length : 0,
5724
5816
  stale: reqAudit.stale ? reqAudit.stale.length : 0
5725
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 {}
5726
5828
  } catch {}
5727
5829
  try {
5728
5830
  const pwState = _loadPreWakeReport(root);
@@ -5912,9 +6014,14 @@ function handoff(root) {
5912
6014
  }
5913
6015
  } catch {}
5914
6016
  // 13) 1.9.207: μ‚¬μš©μž μš”μ²­ λˆ„λ½ 확인 절차 (μ‚¬μš©μž λͺ…μ‹œ) β€” λˆ„λ½ 후보 β‰₯ 1 μ‹œ ν—€λ“œλΌμΈ λ…ΈμΆœ
6017
+ // 1.9.223: delivered νŒ¨ν„΄ 후보 μ‹œ `πŸ“₯ μžλ™μ™„λ£Œκ°€λŠ₯ N건` μš°μ„  λ…ΈμΆœ (μˆ˜λ™ 정리 λΆ€λ‹΄ κ°μ†Œ)
5915
6018
  try {
5916
6019
  const audit = _auditUserRequests(root);
5917
- if (audit.missing && audit.missing.length > 0) {
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) {
5918
6025
  parts.push(`πŸ“₯ λ―Έλ‹΅ μš”μ²­ ${audit.missing.length}건`);
5919
6026
  } else if (audit.open > 0) {
5920
6027
  parts.push(`πŸ“₯ μš”μ²­ ${audit.open} (tracked)`);
@@ -9783,6 +9890,15 @@ function sessionClose(root, opts = {}) {
9783
9890
  tracked: reqAudit.tracked ? reqAudit.tracked.length : 0,
9784
9891
  stale: reqAudit.stale ? reqAudit.stale.length : 0
9785
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 {}
9786
9902
  } catch {}
9787
9903
  try {
9788
9904
  // 1.9.209: pre-wake-audit μžλ™ μ‹€ν–‰ + μ €μž₯ (sleep μ „ μžλ™ 점검)
@@ -9834,11 +9950,16 @@ function sessionClose(root, opts = {}) {
9834
9950
 
9835
9951
  log('');
9836
9952
  log(`## πŸ”š session close μžλ™ 톡합 보고 (1.9.217)`);
9837
- // 1.9.207
9953
+ // 1.9.207 + 1.9.223 (delivered νŒ¨ν„΄ μžλ™ ꢌμž₯)
9838
9954
  try {
9839
9955
  const reqAudit = _auditUserRequests(root);
9840
9956
  const missCnt = reqAudit.missing ? reqAudit.missing.length : 0;
9841
- if (missCnt > 0) {
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) {
9842
9963
  log(red(` ⚠ λ―Έλ‹΅ μ‚¬μš©μž μš”μ²­ ${missCnt}건 (task-log/plan/decisions λ§€μΉ­ μ•ˆ 됨)`));
9843
9964
  } else if (reqAudit.open > 0) {
9844
9965
  log(grn(` βœ“ μ‚¬μš©μž μš”μ²­ ${reqAudit.open}건 λͺ¨λ‘ tracked`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.222",
3
+ "version": "1.9.223",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",