leerness 1.9.239 β†’ 1.9.240

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,37 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.240 β€” 2026-05-24
4
+
5
+ **🐍 UR-0013 2단계: handoff/session close/health --json pyFiles (9 ν•„λ“œ) + ν—€λ“œλΌμΈ μžλ™.**
6
+
7
+ ### 1. handoff/session close/health --json 9번째 톡합 ν•„λ“œ `pyFiles`
8
+ - Python 파일 μžλ™ detect (1.9.239 `_collectPyFiles` μž¬μ‚¬μš©)
9
+ - ν˜•μ‹: `{ total, analyzed, totalLOC, totalImports, totalFuncs, totalClasses }`
10
+ - 3 λͺ…λ Ή 일관성 맀트릭슀 μ§„ν™”: 7 β†’ 8 β†’ **9 ν•„λ“œ** (3 Γ— 9 = 27 톡합 포인트)
11
+ - AI κ°€ 닀쀑 μ–Έμ–΄ μ›Œν¬μŠ€νŽ˜μ΄μŠ€ (.md + .py) 인지
12
+
13
+ ### 2. handoff ν—€λ“œλΌμΈ 18번째 μš”μ†Œ
14
+ - `.py` 파일 β‰₯ 1 μ‹œ: `🐍 py N` μžλ™ λ…ΈμΆœ
15
+ - 0개일 λ•Œ λ―Έλ…ΈμΆœ (μ‘°μš©ν•¨)
16
+
17
+ ### 3. UR-0013 2단계 μ™„λ£Œ
18
+ - 1.9.239 1단계: py-check CLI + agent-mode CLI + MCP 67/68
19
+ - **1.9.240 2단계**: JSON 9 ν•„λ“œ + ν—€λ“œλΌμΈ μžλ™
20
+ - 닀쀑 μ–Έμ–΄ ν‘œλ©΄ (.md + .py) μžλ™ κ°€μ‹œν™”
21
+
22
+ ### 4. λˆ„μ  νšŒκ·€ (1.9.207~239) β€” λͺ¨λ‘ μœ μ§€
23
+
24
+ ### 5. stress-v185 β€” 16/16 PASS
25
+ - 1.9.240 (7): VERSION + handoff/session close/health JSON + 9 ν•„λ“œ + ν—€λ“œλΌμΈ (있음/μ—†μŒ)
26
+ - μ„±λŠ₯ (1): cold_start avg 386ms
27
+ - λˆ„μ  νšŒκ·€ (8): 1.9.207~239
28
+
29
+ ### 6. μžλ™ release (102 λΌμš΄λ“œ main-push streak Β· 63 λΌμš΄λ“œ npm publish streak)
30
+
31
+ 🐍 **닀쀑 μ–Έμ–΄ ν‘œλ©΄ κ°€μ‹œν™”** β€” .md + .py μžλ™ 톡합 (μ™ΈλΆ€ AI κ°€ 두 ν‘œλ©΄ λͺ¨λ‘ 회수)
32
+
33
+ ---
34
+
3
35
  ## 1.9.239 β€” 2026-05-24
4
36
 
5
37
  **🐍 leerness py-check + πŸ€– agent-mode + MCP 67/68 (μ‚¬μš©μž λͺ…μ‹œ UR-0013).**
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.239-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v184-18%2F18-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-68-brightgreen)]() [![cli](https://img.shields.io/badge/CLI_commands-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-195-blueviolet)]() [![main-push](https://img.shields.io/badge/πŸŽ‰_main--push_streak-101_rounds-success)]() [![npm-streak](https://img.shields.io/badge/πŸŽ‰_npm--publish-62_streak-success)]() [![langs](https://img.shields.io/badge/🐍_supported-md_%2B_py-blueviolet)]() [![agent-mode](https://img.shields.io/badge/πŸ€–_agent--mode-start%2Ftick%2Fstop-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-372ms-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.240-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v185-16%2F16-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-68-brightgreen)]() [![cli](https://img.shields.io/badge/CLI_commands-54-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-196-blueviolet)]() [![main-push](https://img.shields.io/badge/πŸŽ‰_main--push_streak-102_rounds-success)]() [![npm-streak](https://img.shields.io/badge/πŸŽ‰_npm--publish-63_streak-success)]() [![json-9fields](https://img.shields.io/badge/πŸ“œ_JSON_톡합-9%2F9_ν•„λ“œ-blueviolet)]() [![langs](https://img.shields.io/badge/🐍_md_%2B_py-μžλ™_detect-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-386ms-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.239 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.240 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ 🐍 py-check Β· πŸ€– agent-mode Β· MCP 68 (μ‚¬μš©μž λͺ…μ‹œ UR-0013) β•‘
17
+ β•‘ 🐍 JSON 9 ν•„λ“œ (3 λͺ…λ Ή Γ— 9 = 27 톡합 β€” UR-0013 2단계) β•‘
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.239';
10
+ const VERSION = '1.9.240';
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 처리).
@@ -6390,6 +6390,19 @@ function handoff(root) {
6390
6390
  try {
6391
6391
  result.recentChanges = _computeRecentChanges(root, 5);
6392
6392
  } catch {}
6393
+ // 1.9.240: pyFiles 톡합 (handoff JSON 9번째 톡합 ν•„λ“œ) β€” Python 닀쀑 μ–Έμ–΄ κ°€μ‹œν™” (UR-0013 2단계)
6394
+ try {
6395
+ const pyFiles = _collectPyFiles(root, 200);
6396
+ const analyses = pyFiles.slice(0, 200).map(f => _analyzePyFile(f)).filter(Boolean);
6397
+ result.pyFiles = {
6398
+ total: pyFiles.length,
6399
+ analyzed: analyses.length,
6400
+ totalLOC: analyses.reduce((s, a) => s + a.loc, 0),
6401
+ totalImports: analyses.reduce((s, a) => s + a.imports, 0),
6402
+ totalFuncs: analyses.reduce((s, a) => s + a.funcs, 0),
6403
+ totalClasses: analyses.reduce((s, a) => s + a.classes, 0)
6404
+ };
6405
+ } catch {}
6393
6406
  } catch {}
6394
6407
  try {
6395
6408
  const pwState = _loadPreWakeReport(root);
@@ -6552,6 +6565,13 @@ function handoff(root) {
6552
6565
  parts.push(`🌐 official ${m.total}/${m.cacheTotal} (${ageStr}${status})`);
6553
6566
  }
6554
6567
  } catch {}
6568
+ // 18) 1.9.240: pyFiles ν—€λ“œλΌμΈ β€” Python 닀쀑 μ–Έμ–΄ κ°€μ‹œν™” (UR-0013 2단계, .py 파일 β‰₯ 1)
6569
+ try {
6570
+ const pyFiles = _collectPyFiles(root, 200);
6571
+ if (pyFiles.length > 0) {
6572
+ parts.push(`🐍 py ${pyFiles.length}`);
6573
+ }
6574
+ } catch {}
6555
6575
  // 17) 1.9.226: round-history ν—€λ“œλΌμΈ β€” 자율 λΌμš΄λ“œ μΉ΄μš΄ν„° + λ‹€μŒ λ§ˆμΌμŠ€ν†€ (5 λΌμš΄λ“œ 이상 μ‹œλ§Œ ν‘œμ‹œ)
6556
6576
  // 1.9.230: λ‹€μŒ λ§ˆμΌμŠ€ν†€ ETA (10R 이내 + ETA 7일 이내일 λ•Œ κ°•μ‘°)
6557
6577
  try {
@@ -10572,6 +10592,19 @@ function sessionClose(root, opts = {}) {
10572
10592
  try {
10573
10593
  jsonResult.recentChanges = _computeRecentChanges(root, 5);
10574
10594
  } catch {}
10595
+ // 1.9.240: pyFiles 톡합 (session close JSON 9번째 톡합 ν•„λ“œ) β€” UR-0013 2단계
10596
+ try {
10597
+ const pyFiles = _collectPyFiles(root, 200);
10598
+ const analyses = pyFiles.slice(0, 200).map(f => _analyzePyFile(f)).filter(Boolean);
10599
+ jsonResult.pyFiles = {
10600
+ total: pyFiles.length,
10601
+ analyzed: analyses.length,
10602
+ totalLOC: analyses.reduce((s, a) => s + a.loc, 0),
10603
+ totalImports: analyses.reduce((s, a) => s + a.imports, 0),
10604
+ totalFuncs: analyses.reduce((s, a) => s + a.funcs, 0),
10605
+ totalClasses: analyses.reduce((s, a) => s + a.classes, 0)
10606
+ };
10607
+ } catch {}
10575
10608
  } catch {}
10576
10609
  try {
10577
10610
  // 1.9.209: pre-wake-audit μžλ™ μ‹€ν–‰ + μ €μž₯ (sleep μ „ μžλ™ 점검)
@@ -17125,6 +17158,19 @@ function healthCmd(root) {
17125
17158
  try {
17126
17159
  out.recentChanges = _computeRecentChanges(root, 5);
17127
17160
  } catch { out.recentChanges = { error: 'recentChanges 점검 μ‹€νŒ¨' }; }
17161
+ // 1.9.240: health --json pyFiles 톡합 (3 λͺ…λ Ή 9 ν•„λ“œ β€” UR-0013 2단계)
17162
+ try {
17163
+ const pyFiles = _collectPyFiles(root, 200);
17164
+ const analyses = pyFiles.slice(0, 200).map(f => _analyzePyFile(f)).filter(Boolean);
17165
+ out.pyFiles = {
17166
+ total: pyFiles.length,
17167
+ analyzed: analyses.length,
17168
+ totalLOC: analyses.reduce((s, a) => s + a.loc, 0),
17169
+ totalImports: analyses.reduce((s, a) => s + a.imports, 0),
17170
+ totalFuncs: analyses.reduce((s, a) => s + a.funcs, 0),
17171
+ totalClasses: analyses.reduce((s, a) => s + a.classes, 0)
17172
+ };
17173
+ } catch { out.pyFiles = { error: 'pyFiles 점검 μ‹€νŒ¨' }; }
17128
17174
  // 1.9.163: 5λŠ₯λ ₯ 맀트릭슀 μžλ™ 평가 (1.9.155 sub-agent 점검 β†’ μ½”λ“œ 기반 μžλ™ν™”)
17129
17175
  // 각 λŠ₯λ ₯을 μ½”λ“œ grep 으둜 κ²€μΆœ β†’ 0~100 점수. μ‚¬μš©μžκ°€ λ§€ health 호좜 μ‹œ leerness 자기 평가 확인.
17130
17176
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.239",
3
+ "version": "1.9.240",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",