leerness 1.17.0 → 1.19.0
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 +172 -0
- package/README.ko.md +187 -0
- package/README.md +50 -134
- package/SECURITY.md +66 -56
- package/bin/leerness.js +417 -84
- package/lib/audit.js +336 -322
- package/lib/pure-utils.js +1 -1
- package/lib/session-close.js +17 -1
- package/package.json +1 -1
- package/scripts/e2e.js +15 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,177 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.19.0 — 2026-06-14 — 🛡️ [안정화/Stable] 검증 하네스 강화 + 정직한 프레이밍 안정 minor
|
|
4
|
+
|
|
5
|
+
**🛡️ 안정화(Stable) minor — "거짓 완료를 못 하게" 만드는 검증 계층을 한층 더 단단하게.** 직전 minor(1.18.0) 이후 누적된 패치 4건(1.18.1~1.18.4)을 검증·통합해 npm 공개. R-0011 정책의 10번째 stable minor. 핵심 테마: **검증 계층 강화(비-JS 거짓FAIL 해소 + 위장 스텁 차단) + AI 자기질문 품질 렌즈 + 정직한 프레이밍(협조 vs 강제, 영문 우선)**.
|
|
6
|
+
|
|
7
|
+
### 이번 minor 통합 (1.18.1~1.18.4)
|
|
8
|
+
- **🌐 비-JS `--test-cmd` 거짓 FAIL 해소 (P1, 1.18.1)**: 기본 권한(basic)이 `python/pytest` 등 사용자 명시 테스트 명령을 막아(exit 126) 초록 프로젝트를 "주장 불일치 FAIL"로 오판하던 것 — 명시 `--test-cmd`/config `testCommand`는 명시 권한으로 실행 허용(cwd jail 유지), 차단 시엔 FAIL 아닌 skip. + task update 위치인자 status 무시 차단 + 종합 라벨 정직화.
|
|
9
|
+
- **🛡️ 위장 스텁 차단 (P2, 1.18.2)**: `module.exports = {}` 같은 빈 export 껍데기가 "구현 실체 ✓"를 통과하던 우회 폐쇄. 적대 워크플로로 한-단어 우회 9종(Object.freeze/new Object/async fn/exports.default/인라인 주석/`()=>({})`/class{}) 재발견·차단. 과탐 0(이름붙은 export·재노출·실코드 통과). `.java/.php/.mjs/.cjs` 추출 정합.
|
|
10
|
+
- **🧭 분야별 자기질문 품질 렌즈 (1.18.3)**: `leerness lens [code|design|docs|test|security]` — 완료 선언 전 AI가 스스로 답하는 질문(코드: "선임 개발자가 복잡하다 느끼지 않을까?" / 디자인: "선임 디자이너+일반 사용자가 이쁘고 직관적인가?") + 분야간 인과관계. AGENTS.md/anti-lazy 정책 통합. README 영문 우선 재작성(README.ko.md 분리) + 설치 직후 REPL 문항 제거.
|
|
11
|
+
- **🔒 보안 제보 비공개화 + 자기정합 (1.18.4)**: SECURITY.md를 GitHub Private Vulnerability Reporting + 보안 이메일로(공개 이슈 안내 모순 해소). README 관리블록 버전 자기정합 + audit가 동적 배지 README의 관리블록 lag도 감지. README "Guidance vs enforcement"(협조형 기본, `ci init`+branch protection으로 강제) + `init --minimal` 노출.
|
|
12
|
+
|
|
13
|
+
### 검증 (회귀 0)
|
|
14
|
+
- **selftest 222→231** · **E2E 365/365** · 각 패치 행위 재현(공격 차단 + 정직 작업 과탐 0) + 위장 스텁 적대 워크플로 + 게시본 재실증(1.18.1 P1) 완료.
|
|
15
|
+
|
|
16
|
+
### 안정화 표시 (R-0006)
|
|
17
|
+
CHANGELOG [안정화/Stable] · git tag (Stable) · GitHub release (`--latest`) · npm dist-tag `stable` 시도.
|
|
18
|
+
|
|
19
|
+
## 1.18.4 — 2026-06-14 — GPT-5.5 외부평가 채택: 보안 제보 비공개화 + 자기정합 + 정직한 강제 프레이밍
|
|
20
|
+
|
|
21
|
+
**🔎 외부평가(GPT-5.5)를 맹신 X로 검증해 진짜 결함만 채택.** 8개 한계 지적을 리포지토리에서 직접 확인 — #3(오케스트레이션 과대홍보)은 현 포지셔닝상 **기각**(이미 "operations/verification layer"), #6(채택 증거)은 범위 밖. 검증된 결함을 이번 패치에 반영.
|
|
22
|
+
|
|
23
|
+
### 변경 (채택)
|
|
24
|
+
- **🔒 SECURITY.md 비공개 제보 채널 (#8, P1, UR-0005)**: "비공개로 알려주세요" 하면서 **공개** GitHub Issues+보안라벨로 안내하던 모순 해소(공개 이슈는 모두에게 노출). → **GitHub Private Vulnerability Reporting**(`/security/advisories/new`) + 보안 이메일(`[leerness security]`)로 교체, "공개 이슈 금지" 명시 + 책임 있는 공개 안내. 권한 큰 하네스의 기본 위생.
|
|
25
|
+
- **🪞 README 자기정합 (#7, P2, UR-0006)**: 관리블록 버전이 package.json(1.18.x)과 어긋나던 것(v1.18.0 표기) 해소 — `readme sync` 로 1.18.4 재스탬프. 게다가 audit 이 **동적 npm 배지 README 에서 못 잡던 갭**을 닫음: 배지뿐 아니라 "Last synced by Leerness vX" 관리블록 버전도 package.json 과 대조(`readme_synced_version_stale`, `--fix` 자동). 정합성 관리 도구가 자기 정합부터.
|
|
26
|
+
- **🛡️ 정직한 강제 프레이밍 (#2, P2, UR-0007)**: README 에 "Guidance vs enforcement" 섹션 — leerness 는 **기본 협조형**(에이전트가 자발 실행)이며, **강제**하려면 `leerness ci init`(PR 게이트 워크플로) + branch protection required check 로 검증 건너뛴 PR 머지 차단. 가이드라인과 가드레일의 차이를 솔직히 명시.
|
|
27
|
+
- **🪶 가벼운 진입 (#4, P2, UR-0008)**: README 30초 퀵스타트에 `init --minimal`(핵심 메모리+검증 파일만) 노출 — 사용자 "가볍게" 철학과 정합. 핵심8 vs 플러그인 경계 분리는 백로그.
|
|
28
|
+
- 백로그(UR-0009): 클린룸 평가 요약 공개 + 커버리지 측정.
|
|
29
|
+
|
|
30
|
+
### 검증 (회귀 0)
|
|
31
|
+
- **selftest 229→231** (SECURITY.md 비공개 채널 행위 + audit 관리블록 lag 소스 가드) · audit 행위 재현(인위적 stale → 감지+`--fix`) · **E2E 365/365**.
|
|
32
|
+
- patch(1.18.4) — npm 미배포(R-0011, GitHub/CHANGELOG 누적).
|
|
33
|
+
|
|
34
|
+
## 1.18.3 — 2026-06-12 — 품질 렌즈(분야별 자기질문) + README 영문 우선 + 설치 REPL 문항 제거 (사용자 명시 3종)
|
|
35
|
+
|
|
36
|
+
**🧭 "AI가 스스로 질문하고 행동하도록".** 사용자 명시 지시 3종을 한 패치로: (1) 분야별 자기질문 품질 렌즈, (2) README 영어권 우선 재작성, (3) 설치 직후 REPL 진입 문항 제거.
|
|
37
|
+
|
|
38
|
+
### 변경
|
|
39
|
+
- **`leerness lens [code|design|docs|test|security]` 신설 (UR-0003)**: 완료 선언 전 AI가 스스로 답하는 분야별 질문 + **분야간 인과관계**(↔ affects). 사용자 원문 그대로 — 코드: *"선임 개발자가 이 코드를 보고 복잡하다고 느끼지 않을까?"* / 디자인: *"선임 디자이너와 일반 사용자가 봤을 때 이쁘고 편하고 직관적이며 헷갈리지 않는가?"* / 문서: *"30초 안에 뭘 해보면 되지?"*. "그렇다(통과)"라고 답할 수 없으면 완료가 아님. `--json` 지원. AGENTS.md 템플릿 Required behavior + anti-lazy-work-policy 규칙 7로 통합(새 init 워크스페이스부터 AI가 자동으로 읽음).
|
|
40
|
+
- **README 영어권 우선 재작성 (UR-0004)**: 첫 화면 영문 — *Try it in 30 seconds*(즉시 해볼 명령) / *No terminal? Let your AI run it*(비개발자: AI에게 붙여넣는 한 문단 + MCP 85 도구) / *Why leerness?*(자체 하네스 대비 차별점 표 — "기억은 말한 것, leerness는 한 것을 검증"). 한국어 전문은 `README.ko.md` 분리. 관리 블록(project-readme) 보존.
|
|
41
|
+
- **설치 직후 REPL agent 모드 진입 문항 제거 (사용자 명시)**: REPL은 완성도가 올라가면 구현 예정 — 설치 흐름에서 질문·자동 진입 삭제(수동 `leerness agent`는 유지). 설치 문항이 한 개 줄어 더 단순.
|
|
42
|
+
- **운영**: leerness 영상(쇼츠) 생성 당분간 중지 — site release-pipeline의 렌더/검증/업로드 3단계에 `LEERNESS_VIDEO_ENABLED` 가드(레포 변수로 재개). 룰 R-0006(토큰 예산 고려)/R-0007(영상 중지) 등록.
|
|
43
|
+
|
|
44
|
+
### 기록만 (토큰 예산 고려 — 다음 라운드 후보, UR-0003 완전판)
|
|
45
|
+
- 렌즈 워크스페이스 커스텀(`.harness/quality-lenses.json` — 프로젝트별 질문 추가/수정), handoff 헤드라인에 in-progress task 키워드 → 관련 렌즈 자동 힌트, verify-claim/session close에 렌즈 자가답변 기록(advisory), MCP `leerness_lens` 노출, 인과관계 그래프 자동 추론(변경 파일 확장자 → 영향 분야 매핑).
|
|
46
|
+
|
|
47
|
+
### 검증 (회귀 0)
|
|
48
|
+
- **selftest 227→229** (카탈로그 무결성·사용자 원문·affects 상호참조 행위 + 표면 등재/REPL 제거 소스 가드 — 자기참조 함정 1건 즉시 수정) · **E2E 365/365** · lens 행위 확인(유효/무효 도메인 exit 0/1).
|
|
49
|
+
- patch(1.18.3) — npm 미배포(R-0011, GitHub/CHANGELOG 누적).
|
|
50
|
+
|
|
51
|
+
## 1.18.2 — 2026-06-11 — 위장 스텁(빈 export 껍데기) 차단 — 거짓완료 우회 폐쇄 + 적대 강화
|
|
52
|
+
|
|
53
|
+
**🛡️ "거짓완료 차단"의 위장 스텁 우회 폐쇄 — 적대 워크플로로 강화.** 1.18.1 재실증에서 정직한 한계로 남겼던 위장 스텁을 닫고, 적대 헌터(우회·오탐 병렬)로 1차 수정의 우회를 재발견해 함께 폐쇄. `module.exports = {};` 한 줄 "빈 껍데기 구현"이 `verify-claim` "구현 실체 ✓"를 통과하고 `require` 만 하는 가짜 테스트와 결합하면 **`--strict-claims` 에서도 exit 0** 으로 통과하던 우회(맹신 X 클린룸 케이스 B).
|
|
54
|
+
|
|
55
|
+
### 변경 (재실증 후속 + 적대 강화)
|
|
56
|
+
- **빈 export 껍데기 = 스텁 판정**: 비주석 코드가 빈 값(zero-logic) producer 뿐이면 스텁 → done 주장 기본 게이팅 FAIL. 순수 함수 `_vcImplIsEmpty` 분리(단위 테스트). 적대 헌터가 찾은 우회형까지 포함: `{}`·`[]`·`Object.freeze({})`·`new Object()`·`(async) function(){}`·`(async)()=>{}`·`()=>({})`·`class {}`·`export default {}`·`export {}`·`exports.default = {}`·`pass`, TS 캐스트(`{} as any`) 허용.
|
|
57
|
+
- **인라인 주석 우회 차단**: 같은 줄 트레일링 주석(`module.exports = {}; // ...`)이 앵커를 깨던 가장 사소한 누수 — 줄별 인라인 `//` 제거(따옴표 없는 줄 한정, 문자열 보호) 후 판정.
|
|
58
|
+
- **확장자 정합(`FILE_EXTS`)**: `java`·`php`·`mjs`·`cjs` 추가 — 이전엔 `.java`/`.php` 임플 주장이 추출조차 안 돼 스텁/존재 검사를 무검사 통과하던 불일치 버그 해소.
|
|
59
|
+
- **과탐 0(오탐 헌터 ~45 합법패턴 확인)**: 이름붙은 export(`{ a, b }`)·재노출(`require('./x')`/`export * from`)·멤버 객체(`{ port: 3000 }`)·`Object.freeze({a:1})`·메서드 있는 클래스·비어있지 않은 화살표(`(a,b)=>a+b`)·`class Foo {}` + 별도 export(스펙 FP-가드)는 전부 정상 통과.
|
|
60
|
+
- 참고: 재실증이 의심했던 "테스트-구현 연결 OR 우회"는 **실재하지 않음**(내용 기반 검사가 미연결 테스트를 정확히 잡음 — 클린룸 케이스 A strict=exit 1).
|
|
61
|
+
- 정직한 잔여(백로그): 호출식 다중 인자(`Object.assign({},{})`), Python def/class-wrapped `pass`·`...`·`raise NotImplementedError`, 다언어(Ruby/Go/Rust `todo!()`) 빈 본문 — 정규식 누적보다 경량 토큰/AST 기반 "빈 컨테이너" 재설계로 미룸.
|
|
62
|
+
|
|
63
|
+
### 검증 (회귀 0)
|
|
64
|
+
- **selftest 225→227** (빈 껍데기 기본+우회형 8종+정상 10종 행위 단위 + 소스/확장자 가드) · **E2E 365/365** · **적대 워크플로 2회**(우회 9건 isReal 재현 → 수정 → CLI 행위 14/14 재확인; 오탐 0).
|
|
65
|
+
- **행위 재현(맹신 X)**: Object.freeze/new Object/async fn/exports.default/=>({})/class{}/인라인주석/리터럴 8종 → strict exit 1(이전 0); 진짜 구현·배럴·freeze({a:1})·메서드 클래스·설정 객체 6종 → exit 0(오탐 0).
|
|
66
|
+
- patch(1.18.2) — npm 미배포(R-0011, GitHub/CHANGELOG 누적).
|
|
67
|
+
|
|
68
|
+
## 1.18.1 — 2026-06-11 — 재실증 후속: --test-cmd 비-JS 거짓차단 해소 (P1) + 정합 구멍 2건
|
|
69
|
+
|
|
70
|
+
**🔁 1.18.0 을 게시본에서 다시 검증(맹신 X)했더니, "범용" 약속의 핵심인 비-JS 사용자에게 새 P1 이 보였다.** 독립 클린룸 3곳(파이썬 재개발·적대 재공격·Node 회귀)으로 1.18.0 의 5격차를 재실증한 결과 4건은 닫혔으나, `verify-claim --run-tests --test-cmd "python ..."` 이 권한 차단(126)으로 막혀 **초록 프로젝트에 거짓 "✗ 불일치 FAIL"**(exit 1)을 내던 것을 발견·수정.
|
|
71
|
+
|
|
72
|
+
### 변경 (재실증 발견)
|
|
73
|
+
- **🌐 --test-cmd 비-JS 인터프리터 거짓차단 해소 (P1)**: `leerness init` 기본 권한(basic, `shell.exec=false`)의 allowList 가 JS 도구(git/npm/node…)만 허용해 `python/py/pytest/uv` 등이 status 126 으로 막히고, 그게 "테스트 실패→주장 불일치" 거짓 판정으로 둔갑했음. 이제 **사용자가 명시한 `--test-cmd`/설정 `testCommand` 는 명시 권한(userAuthorized)** 으로 인터프리터 실행 허용(cwd jail 은 유지). 추가 방어: 권한/jail 로 막힌 실행은 **"테스트 실패"가 아니라 "측정 불가(skip, 불일치 판정 아님)"** 로 처리 — 차단이 절대 거짓 FAIL 로 바뀌지 않음.
|
|
74
|
+
- **🔚 task update 위치인자 status 무시 차단 (P2)**: `task update T-0003 done` 처럼 상태를 위치인자로 주면 조용히 무시되고 "✓ updated"가 출력돼 **done 이 안 되고 verify-claim/마감 정직성 검사가 통째로 건너뛰던** 데이터 정합 구멍 해소 — id 뒤 떠도는 positional 거부 + did-you-mean(`--status done`). 정상 `--status`/`--next` 는 과탐 0.
|
|
75
|
+
- **🏷 종합 라벨 정직화 (P3)**: 커스텀 `--test-cmd` 인데도 종합 줄이 "npm test 실행"으로 하드코딩되던 것 → 실제 실행 명령 표기.
|
|
76
|
+
|
|
77
|
+
### 검증 (회귀 0)
|
|
78
|
+
- **selftest 222→225** (권한 결정 `_isCommandPermitted` 행위 단위 + 정합 가드) · **E2E 365/365** (대기 중 갱신).
|
|
79
|
+
- **행위 재현(맹신 X)**: 초록 파이썬 프로젝트에서 `verify-claim --run-tests --test-cmd "python test_todo.py"` → exit 0 + "python test_todo.py 실행: ✓ all passed" + 일치 판정(이전: 126/거짓 FAIL/exit 1). `task update T-0001 done` → 명확 에러+exit 1, status 는 그대로(done 아님), `--status done`/`--next` 정상.
|
|
80
|
+
- patch(1.18.1) — npm 미배포(R-0011, GitHub/CHANGELOG 누적). 다음 minor 때 묶음 공개.
|
|
81
|
+
|
|
82
|
+
## 1.18.0 — 2026-06-10 — 🛡️ [안정화/Stable] 범용 검증 하네스 안정 minor
|
|
83
|
+
|
|
84
|
+
**🛡️ 안정화(Stable) minor — "범용 AI 코딩 하네스" 실증 격차 전부 해소.** 5개 독립 클린룸 실사용 평가(Python/Node/Rust 실개발·에이전트 교대·적대 공격)가 찾은 P1 2건 + P2 3건(1.17.2~1.17.6)을 검증·통합해 npm 공개. R-0011 정책의 9번째 minor. 새 포지셔닝: **"어떤 언어, 어떤 AI 에이전트로 작업하든 — 증거 없이는 끝났다고 말할 수 없게."**
|
|
85
|
+
|
|
86
|
+
### 이번 minor 통합 (1.17.1~1.17.6)
|
|
87
|
+
- **🌐 테스트 명령 해석 체인 (P1)**: `verify-claim --run-tests` 가 npm test 하드코딩 → `--test-cmd` > 설정 `testCommand` > 실제 npm test(placeholder 제외) > skip. 파이썬 프로젝트 오판 해소 + pytest 출력 파싱.
|
|
88
|
+
- **🛡️ 빈껍데기·가짜 테스트 차단 (P1)**: 주석뿐 구현(비주석 코드 0줄) done 게이팅 FAIL + 테스트-구현 연결 검사(12개 언어, 파이썬 `#` 스텁 포함). `--json implementationSubstance/testImplLink`.
|
|
89
|
+
- **🧪 테스트 카운트 정직화 (P2)**: pytest·루트 `*.test.*` 관례 인식 + 측정불가="검증 미수행"(통과 위장 금지) + 한국어 "테스트 N개" 주장 추출(부풀린 주장 차단).
|
|
90
|
+
- **🔗 unknown flag 거부 (P2)**: `task update --next-action` 같은 미존재 옵션이 값을 조용히 버리던 것 → 거부 + did-you-mean(인수인계 유실 차단).
|
|
91
|
+
- **🔚 마감 정합 (P2)**: session close 가 done 낙관 의심·살아있는 시크릿을 재확인해 표면화 — 마감이 마지막 관문 역할.
|
|
92
|
+
- **plan add 공백제목 손상 수정** + milestone 파서 개행 미흡수(1.17.1).
|
|
93
|
+
|
|
94
|
+
### 검증 (회귀 0)
|
|
95
|
+
- **selftest 222 PASS** · **E2E 365/365 PASS** · npm gate=minor_bump. 각 격차 행위 재현(공격 차단 + 정직 작업 과탐 0) 완료.
|
|
96
|
+
|
|
97
|
+
### 안정화 표시 (R-0006)
|
|
98
|
+
CHANGELOG [안정화/Stable] · git tag (Stable) · GitHub release (Stable) · npm dist-tag `stable` 시도.
|
|
99
|
+
|
|
100
|
+
## 1.17.6 — 2026-06-10 — 범용성⑤(P2 완결): session close 마감 정합 (UR-0049)
|
|
101
|
+
|
|
102
|
+
**🔚 마감이 "마지막 관문" 역할을 하도록.** 5축 실증에서 — verify-claim 이 거짓으로 판정했던 task 가 마감 보고서에 평범한 "done"으로, gate 가 시크릿으로 실패 중인데 "clean (sleep 안전)"으로 선언되던 정합 문제 해소. **이로써 5축 격차(P1 2건 + P2 3건) 전부 닫힘.**
|
|
103
|
+
|
|
104
|
+
### 변경 (UR-0049)
|
|
105
|
+
- **done 낙관 재확인**: 마감 시 done task 들의 evidence 를 코드 흔적과 재대조(`_detectOptimism`) — verify-claim 을 건너뛴 거짓 주장(예: "DB 저장 구현" 인데 코드에 DB 호출 없음)을 `⚠ 낙관 의심 미해소` 로 표면화. `--json completionHonesty.optimismUnresolved`.
|
|
106
|
+
- **마감 보안 재확인**: 커밋 대상 시크릿이 살아있으면 `🚨 마감 보안: N건 미해소 — clean 아님` 표면화. `--json closeSecurity.committedSecrets`.
|
|
107
|
+
- advisory(차단 X) — 마감 흐름은 유지하되 거짓/위험이 조용히 통과하지 않음.
|
|
108
|
+
|
|
109
|
+
### 검증 (회귀 0)
|
|
110
|
+
- **selftest 221→222** · **E2E 365/365** · 행위 3종: 거짓 DB 주장 done + 시크릿 → 두 경고 표면화 ✓ · --json 필드 ✓ · 진짜 구현+시크릿 제거 → 경고 0(과탐 0) ✓.
|
|
111
|
+
- patch(1.17.6) — npm 미배포(R-0011, GitHub). **다음: 1.18.0 [Stable] "범용 검증 하네스" minor(1.17.1~1.17.6 묶음 공개).**
|
|
112
|
+
|
|
113
|
+
## 1.17.5 — 2026-06-10 — 범용성④: 모르는 옵션 조용히 무시 차단 (UR-0048)
|
|
114
|
+
|
|
115
|
+
**🔗 인수인계 유실의 최악 양식 차단.** 5축 실증에서 — `task update --next-action "..."` 처럼 존재하지 않는 옵션을 줘도 "✓ task updated"만 출력하고 값을 버려, **쓴 에이전트는 기록됐다고 믿고 다음 에이전트는 placeholder 를 받던** P2 해소.
|
|
116
|
+
|
|
117
|
+
### 변경 (UR-0048)
|
|
118
|
+
- **`task update` unknown flag 거부**: 지원 외 `--플래그` 발견 시 exit 1 + **did-you-mean**(`--next-action` → "혹시 `--next`?") + 지원 플래그/사용법 안내. `--json` 은 `{code:'unknown_flag'}` 구조화.
|
|
119
|
+
- 전역 플래그(`--path/--json/--force/--lenient`)는 항상 허용 — 과탐 0. 재사용 가능한 `_rejectUnknownFlags` 헬퍼(다른 쓰기 명령 확대 여지).
|
|
120
|
+
|
|
121
|
+
### 검증 (회귀 0)
|
|
122
|
+
- **selftest 220→221** · **E2E 365/365** · 행위 4종: `--next-action` 거부+제안 ✓ · `--json` 구조화 ✓ · 올바른 `--next` 정상 저장 ✓ · 전역 플래그 통과 ✓.
|
|
123
|
+
- patch(1.17.5) — npm 미배포(R-0011, GitHub). 잔여: UR-0049(마감 정합) → 완료 시 1.18.0 "범용 검증" minor.
|
|
124
|
+
|
|
125
|
+
## 1.17.4 — 2026-06-10 — 범용성③: 테스트 카운트 "측정실패=통과" 역전 해소 (UR-0047)
|
|
126
|
+
|
|
127
|
+
**🧪 5개 클린룸 리포트가 공통 지적한 P2.** "실측: 테스트 파일 못 찾음"이라면서 바로 아래 "✓ pass (실측 ≥ 주장)"로 통과시키던 모순 — 부풀린 테스트 주장("cargo test 12개", "테스트 50개")이 검증을 헛통과하던 것 해소.
|
|
128
|
+
|
|
129
|
+
### 변경 (UR-0047)
|
|
130
|
+
- **관례 확대**: 주장된 테스트 파일 우선 합산 + 글롭(pytest `test_*.py`·`*_test.py` / 루트·tests/ 의 `*.test.*`·`*.spec.*`) — 이전엔 `tests/test.js` 등 3개 하드코딩. 파이썬은 `def test_` 개수로 카운트.
|
|
131
|
+
- **측정불가 = 검증 미수행**: 테스트 파일을 못 찾으면 "⊘ 측정 불가 — 주장 N개 검증 미수행 (pass 아님)" 정직 표기 + verdict `testCountMatch: null`(게이팅 미기여 — false 만 FAIL).
|
|
132
|
+
- **🐛 주장 추출 보강(맹신 X 행위검증 중 발견)**: "테스트 50개"(한국어 자연어순)를 못 잡아 **부풀린 주장이 카운트 검증을 아예 안 탔음** → `테스트 N개` 패턴 추가.
|
|
133
|
+
|
|
134
|
+
### 검증 (회귀 0)
|
|
135
|
+
- **selftest 219→220** · **E2E 365/365** · 행위 4종: pytest 실측(2개) ✓ · **부풀린 "테스트 50개"(실측 2) exit 1 차단**(이전 헛통과) · 측정불가 정직 표기 ✓ · 루트 `*.test.js` 인식(실측 3) ✓ · 정직 주장 exit 0(과탐 0).
|
|
136
|
+
- patch(1.17.4) — npm 미배포(R-0011, GitHub). 잔여: UR-0048(unknown flag)·UR-0049(마감 정합).
|
|
137
|
+
|
|
138
|
+
## 1.17.3 — 2026-06-10 — 범용성②: 빈껍데기 구현·가짜 테스트 차단 (UR-0046)
|
|
139
|
+
|
|
140
|
+
**🛡️ 간판 기능 "거짓완료 차단"의 상한선 끌어올리기.** 5축 실증 분석의 Attack C — 주석뿐인 구현 파일 + 아무것도 검사하지 않는 `assert(true)` 테스트가 `verify-claim` 을 **exit 0 으로 완전 통과**하던 P1 — 을 차단.
|
|
141
|
+
|
|
142
|
+
### 변경 (UR-0046)
|
|
143
|
+
- **구현 실체(스텁) 검사**: 주장된 구현 파일(테스트 제외, js/ts/py/go/rs 등 12종 확장자)의 **비주석 코드줄이 0** 이면 done 게이팅 FAIL — "주석/TODO 뿐인 빈껍데기"를 확실 신호만으로 차단(과탐 0).
|
|
144
|
+
- **테스트-구현 연결 검사**: 구현+테스트가 함께 주장됐는데 어떤 테스트도 구현 파일명을 참조하지 않으면 "빈 테스트 의심" advisory ⚠ (`--strict-claims` 시 FAIL).
|
|
145
|
+
- `--json` verdict 에 `implementationSubstance` / `testImplLink` + `stubFiles` 노출(머신 경로 동일 게이팅).
|
|
146
|
+
|
|
147
|
+
### 검증 (회귀 0)
|
|
148
|
+
- **selftest 218→219** · **E2E 365/365** · Attack C 재현: 스텁+가짜테스트 **exit 0→1 차단** · 진짜 구현 exit 0(과탐 0) · **파이썬 스텁(#주석뿐)도 차단**(언어중립) · --json verdict 노출.
|
|
149
|
+
- patch(1.17.3) — npm 미배포(R-0011, GitHub). 잔여 격차: UR-0047(테스트카운트 역전)·0048(unknown flag)·0049(마감 정합).
|
|
150
|
+
|
|
151
|
+
## 1.17.2 — 2026-06-10 — 범용성①: verify-claim 테스트 명령 해석 체인 (UR-0045)
|
|
152
|
+
|
|
153
|
+
**🌐 "범용 AI 코딩 하네스" 5축 실증 분석의 P1 1호 해소.** `verify-claim --run-tests` 가 `npm test` 하드코딩이라 — 테스트가 전부 통과한 파이썬 프로젝트(npm init 잔재 placeholder 존재)를 "주장 불일치 FAIL"로 오판하던 범용성 정면 반례를 수정.
|
|
154
|
+
|
|
155
|
+
### 변경 (UR-0045)
|
|
156
|
+
- **테스트 명령 해석 체인**: `--test-cmd "<명령>"` > `.harness/leerness-config.json` 의 `"testCommand"` > package.json 의 **실제** test 스크립트(npm placeholder "no test specified" 는 테스트가 아니므로 제외) > **skip 표기**(불일치 판정 금지).
|
|
157
|
+
- **pytest 출력 파싱**: "N passed in …s" 형식 인식(파이썬 러너 pass/fail 비율 표시).
|
|
158
|
+
- 신규 value-flag `--test-cmd` 를 `nonFlagArgs` withValue 에 등록(1.14.2 교훈 적용 — 제목 흡수 차단).
|
|
159
|
+
|
|
160
|
+
### 검증 (회귀 0)
|
|
161
|
+
- **selftest 217→218** · **E2E 365/365** · 행위 재현: ① placeholder-only 파이썬 프로젝트 `--run-tests` → skip + exit 0(오판 해소, 이전 exit 1) ② `--test-cmd "node mytest.js"` → 실행+파싱(2/2 passed)+주장 대조 ✓ ③ config testCommand 경유 동작 ④ 실제 npm test 스크립트는 기존대로 ⑤ 실패 명령은 정직하게 exit 1.
|
|
162
|
+
- patch(1.17.2) — npm 미배포(R-0011, GitHub). 다음: UR-0046(스텁/연결 검사 — 빈껍데기 구현 차단).
|
|
163
|
+
|
|
164
|
+
## 1.17.1 — 2026-06-09 — 17번째 버그헌트: plan add 공백제목 데이터 손상 차단
|
|
165
|
+
|
|
166
|
+
**🔬 17번째 버그헌트(이번 세션 신규코드 회귀 + 광역 스윕).** 신규코드(gate --json stdout-swap·memory --json·_GROUP_USAGE·scan break·_cellSafe)는 **0 결함**(5000키 664ms 등 입증). plan add 입력검증 1건 발견·수정.
|
|
167
|
+
|
|
168
|
+
### 수정 (재현 검증)
|
|
169
|
+
- **🟠 plan add 공백 제목 → plan.md 손상 (P2)**: `plan add " "`(공백만)이 `|| 기본값`을 우회(truthy)해 빈 제목으로 기록 → milestone 파서의 `\s*` 가 개행을 흡수해 **다음 줄 `Status: planned` 를 제목으로 오인**. 2중 수정: ① dispatch 에서 `.trim()` 후 판정(공백→기본값 '새 계획'), ② 파서 `\.\s*` → `\.[ \t]*`(개행 미흡수, 5곳 + pure-utils) — 손상 클래스 차단.
|
|
170
|
+
|
|
171
|
+
### 검증 (회귀 0)
|
|
172
|
+
- **selftest 216→217** · **E2E 365/365** · `plan add " "` → '새 계획'(손상 없음)·정상 제목 보존 행위 재현.
|
|
173
|
+
- patch(1.17.1) — npm 미배포(R-0011, GitHub). (P3 plan add 빈-인자 기본값은 의도된 동작 — trim 으로 안전화.)
|
|
174
|
+
|
|
3
175
|
## 1.17.0 — 2026-06-09 — 🛡️ [안정화/Stable] 외부 클린룸 일관성 안정 minor
|
|
4
176
|
|
|
5
177
|
**🛡️ 안정화(Stable) minor.** 외부 클린룸 리뷰(게시본 무README 신규사용자 관점)에서 도출한 --json·CLI 일관성 개선(1.16.1~1.16.2)을 검증·통합해 npm 공개. R-0011 정책의 8번째 minor. 영상은 HyperFrames "문제→해소" 디자인.
|
package/README.ko.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
> **English version: [README.md](./README.md)** — 영어권 우선 정책에 따라 첫 화면은 영문이며, 이 문서가 한국어 전문입니다.
|
|
2
|
+
|
|
3
|
+
# leerness
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
██╗ ███████╗███████╗██████╗ ███╗ ██╗███████╗███████╗
|
|
7
|
+
██║ ██╔════╝██╔════╝██╔══██╗████╗ ██║██╔════╝██╔════╝
|
|
8
|
+
██║ █████╗ █████╗ ██████╔╝██╔██╗ ██║█████╗ ███████╗
|
|
9
|
+
██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║
|
|
10
|
+
███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║
|
|
11
|
+
╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
> **어떤 언어, 어떤 AI 에이전트로 작업하든 — "증거 없이는 끝났다고 말할 수 없게" 만드는 AI 코딩 운영 레이어.** 코드를 대신 쓰는 도구가 아니라, AI 에이전트의 **기억·인수인계·검증·감사·보안 가드**를 프로젝트에 영속화하는 CLI + MCP 서버입니다. (이 포지셔닝은 5개 독립 클린룸 실사용 평가 — Python/Node/Rust 실개발·에이전트 교대·적대 공격 — 로 검증됐습니다.)
|
|
15
|
+
|
|
16
|
+
[](https://www.npmjs.com/package/leerness) ·  · **런타임 의존성 0** · **install-script 0** · offline-first · Node ≥ 18 · MIT
|
|
17
|
+
|
|
18
|
+
> 이 문서는 **외부 다중 모델(Codex / Claude Sonnet / Claude Opus)이 README 를 보지 않고 leerness 를 직접 설치·실행·소스 분석한 객관 리뷰**를 바탕으로 재구성되었습니다. 매 릴리스마다 자동 갱신됩니다.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## leerness가 뭔가요?
|
|
23
|
+
|
|
24
|
+
AI 코딩 에이전트(Claude Code, Cursor, Codex, Aider, Goose 등)는 코드를 잘 쓰지만 세 가지 약점이 있습니다.
|
|
25
|
+
|
|
26
|
+
1. **기억하지 못합니다** — 세션이 바뀌면 현재 상태·결정·다음 작업을 잊습니다.
|
|
27
|
+
2. **거짓 완료를 선언합니다** — 증거(파일·테스트·로그) 없이 "완료했습니다"라고 말합니다.
|
|
28
|
+
3. **표준이 없습니다** — 여러 에이전트 간 인수인계, 보안/인코딩 점검, 드리프트 관리가 제각각입니다.
|
|
29
|
+
|
|
30
|
+
leerness는 이 문제들을 해결하는 **외부 운영 substrate**입니다. 어떤 에이전트 위에도 얹어, 프로젝트의 상태를 `.harness/` 파일로 영속화하고 CLI · MCP 도구로 노출합니다. **leerness 자체는 LLM을 호출하거나 코드를 실행하지 않습니다.**
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 해결하는 문제
|
|
35
|
+
|
|
36
|
+
| 문제 | leerness의 해법 |
|
|
37
|
+
|---|---|
|
|
38
|
+
| 세션 간 맥락·결정·다음 작업 유실 | `task`/`decision`/`lesson`/`plan`/`rule` 메모리를 영속화하고, 세션 시작 시 `handoff` 1콜로 회수 |
|
|
39
|
+
| 증거 없는 "완료" 주장 | `verify-claim --require-evidence`, `lazy detect`, anti-lazy 정책으로 차단 |
|
|
40
|
+
| Claude → Codex → Cursor 교체 시 맥락 소실 | 표준 세션 워크플로(handoff → 작업 → session close)로 에이전트 독립 인수인계 |
|
|
41
|
+
| 하드코딩 시크릿 · 인코딩 깨짐(BOM/CP949) | `scan secrets`, `encoding check` 자동 감지 (CI 게이트) |
|
|
42
|
+
| 워크스페이스 노화(drift)를 에이전트가 모름 | `drift check [--auto-fix]` 점수화 + 자동 회복 |
|
|
43
|
+
| 명세 ↔ 구현 불일치 | `contract verify spec.md impl.js` 함수/필드 일치 검사 |
|
|
44
|
+
| 여러 AI CLI의 역할/분배 표준 부재 | `agents`/`roles`/`team` 오케스트레이션(기본 opt-in, dispatch는 실행이 아닌 명령 생성) |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 빠른 시작
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 설치 (런타임 의존성 0 — 추가 패키지 없음)
|
|
52
|
+
npm install -g leerness
|
|
53
|
+
|
|
54
|
+
# 프로젝트 초기화 (.harness/ 거버넌스 문서 + .claude/.cursor/.github 어댑터 생성)
|
|
55
|
+
leerness init .
|
|
56
|
+
|
|
57
|
+
# 세션 시작 — 이전 맥락/기억/다음 작업을 1콜로 회수
|
|
58
|
+
leerness handoff .
|
|
59
|
+
|
|
60
|
+
# ... 에이전트가 작업 ...
|
|
61
|
+
leerness task add "사용자 인증 API 구현"
|
|
62
|
+
leerness gate . # verify + audit + scan secrets + encoding + lazy 통합 게이트
|
|
63
|
+
|
|
64
|
+
# 세션 종료 — 마감 통계 + 다음 라운드 추천 + 인수인계 문서 자동 생성
|
|
65
|
+
leerness session close .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
CLAUDE.md / AGENTS.md 에 `세션 시작 시 leerness handoff .`, `종료 전 leerness session close .` 지침을 추가하면 에이전트가 자동으로 호출합니다.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 거짓 완료 차단 — 핵심 차별점
|
|
73
|
+
|
|
74
|
+
세 모델의 블라인드 리뷰가 공통으로 꼽은 leerness의 핵심 가치입니다. AI 에이전트가 가장 자주 하는 거짓말 "다 했어요"를, leerness는 **완료 주장을 실제 코드와 대조**해 검증합니다.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# 에이전트가 "결제 API 연동 완료"라고 주장하지만 코드엔 호출 흔적이 없으면:
|
|
78
|
+
leerness verify-claim T-0001 --require-evidence
|
|
79
|
+
# ⚠ FAIL (낙관 1) · [Payment] 결제: evidence에 주장 있으나 코드에 호출 흔적 없음 → exit 1
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- `optimism-check` · `verify-claim` — evidence의 도메인 주장(API·DB·결제·이메일·큐·캐시·알림·스토리지 등 10종)을 실제 소스 호출과 대조. **JavaScript뿐 아니라 Python·Ruby·Go·C#·Java·PHP·Rust 구현도 인식**합니다(1.13).
|
|
83
|
+
- `lazy detect` — 증거 없는 done, 빈 handoff, 테스트 미실행, 미추적 TODO를 탐지.
|
|
84
|
+
- 정직한 완료는 통과하고 가짜 완료만 exit 1로 차단 — `gate` 또는 CI에 그대로 연결됩니다.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 핵심 개념 — 5계층
|
|
89
|
+
|
|
90
|
+
- **기억(Memory)** — `task`/`plan`/`decision`/`lesson`/`rule`/`feature`(그래프). canonical JSON 을 단일 진실소스로 저장하고 마크다운은 projection. archive/restore 지원.
|
|
91
|
+
- **인수인계(Handoff)** — `handoff`(세션 시작 컨텍스트), `session close`(마감 보고). 에이전트 교체에도 맥락 보존.
|
|
92
|
+
- **검증(Verification)** — `verify-claim`(증거 강제), `contract verify`(명세↔구현), `verify-code`(테스트/빌드 실행 + 증거 기록).
|
|
93
|
+
- **감사(Audit)** — `scan secrets`, `encoding check`, `lazy detect`, `drift check`, `audit`, 그리고 이를 묶는 `gate`.
|
|
94
|
+
- **정책/보안(Policy)** — 8단계 권한 등급 enforce, 외부 에이전트 opt-in, 자연어 영구 룰(`rule add ... --trigger`).
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 명령 카테고리
|
|
99
|
+
|
|
100
|
+
- **초기화/진단**: `init` · `status` · `which` · `doctor` · `selftest` · `capabilities`
|
|
101
|
+
- **메모리**: `task` · `plan` · `decision` · `lesson` · `rule` · `feature` · `memory status/search`
|
|
102
|
+
- **인수인계/세션**: `handoff` · `session close` · `pulse` · `health`
|
|
103
|
+
- **검증/감사**: `check` · `gate` · `audit` · `drift check` · `lazy detect` · `scan secrets` · `encoding check` · `verify-code` · `verify-claim` · `contract verify`
|
|
104
|
+
- **외부 에이전트**: `agents list/check/dispatch` · `provider` · `roles` · `adapter`
|
|
105
|
+
- **운영/확장**: `release` · `migrate` · `team` · `install-safety` · `route` · `review`(페르소나)
|
|
106
|
+
- **브리지(opt-in)**: `web`(playwright) · `pc`(robotjs) · `lsp`
|
|
107
|
+
- **MCP**: `mcp serve` — stdio JSON-RPC 서버로 85개 도구 노출
|
|
108
|
+
|
|
109
|
+
전체 명령은 `leerness commands` 또는 `leerness --help` 로 확인하세요.
|
|
110
|
+
|
|
111
|
+
> **경로 규칙** — 대부분 명령은 `[path]` 위치 인자를 받습니다. `task`/`decision`/`lesson` 등 메모리 명령에 다른 폴더를 지정할 땐 `--path <dir>` 또는 `./dir` 형태를 쓰세요(맨 폴더 이름만 주면 현재 폴더로 처리됩니다). 출력은 한국어가 기본이며 `--language en` 으로 영어를 늘릴 수 있습니다(일부 메시지는 한국어 유지).
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 대표 워크플로
|
|
116
|
+
|
|
117
|
+
**기본 세션 사이클**
|
|
118
|
+
```bash
|
|
119
|
+
leerness handoff . # 이전 맥락 자동 로드
|
|
120
|
+
leerness task add "API 응답 검증 로직 구현"
|
|
121
|
+
leerness task update T-0001 --status in-progress --evidence "검증 함수 구현"
|
|
122
|
+
leerness gate . # 배포 전 통합 품질 게이트
|
|
123
|
+
leerness session close . # 마감 + 다음 에이전트 인수인계
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**보안·검증 게이트 (CI)**
|
|
127
|
+
```bash
|
|
128
|
+
leerness scan secrets . # 커밋 대상 하드코딩 시크릿 → exit 1
|
|
129
|
+
leerness contract verify spec.md src/api.js # 명세 함수/필드 누락 → exit 1
|
|
130
|
+
leerness verify-claim T-0001 --require-evidence
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**다중 에이전트 조율**
|
|
134
|
+
```bash
|
|
135
|
+
leerness agents list # 설치된 외부 AI CLI 가용성
|
|
136
|
+
leerness agents dispatch "코드 리뷰" --to codex # 실행 명령 생성(직접 실행은 사용자/메인 에이전트)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**MCP (외부 AI 에이전트에 도구로 노출)**
|
|
140
|
+
```bash
|
|
141
|
+
leerness mcp serve # JSON-RPC over stdio, 85 도구
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 아키텍처 (외부 리뷰 검증)
|
|
147
|
+
|
|
148
|
+
- **런타임 의존성 0 / install-script 0** — `package.json` 의 dependencies/optional/peer 가 전부 비어 있고 postinstall 도 없습니다. 순수 Node stdlib(`fs`/`path`/`child_process`/`readline`). 공급망 공격면 최소. `leerness install-safety` 로 확인 가능.
|
|
149
|
+
- **canonical JSON 단일 진실소스 + 마크다운 projection** — 메모리는 JSON 으로 저장하고 사람이 읽는 `.md` 는 파생물. 파이프(`|`)·개행·백틱·이모지·한글이 마크다운 테이블에서도 안전(셀 이스케이프 + round-trip).
|
|
150
|
+
- **원자적 UTF-8 쓰기** — temp + rename 으로 부분쓰기 손상 방지, BOM 자동 strip.
|
|
151
|
+
- **shell 미경유 MCP** — `mcp serve` 의 도구 호출은 셸을 거치지 않고 인자를 직접 전달(명령 주입 차단).
|
|
152
|
+
- **순수 `--json` / 일관 exit code** — 성공·실패·미존재 경로 모두 파싱 가능한 JSON(`{ok,error,code}`) + 실패 시 exit 1. 자동화·CI 친화.
|
|
153
|
+
- **모듈 분리(DI)** + **내장 자가검증** — `lib/` 순수 유틸/IO/카탈로그 분리, `selftest` 210 케이스로 설치 무결성 검증(`doctor` 가 함께 실행). 문서(README) 부재에도 코어 무결성 진단은 통과.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 차별점
|
|
158
|
+
|
|
159
|
+
- **진짜 0-dependency** — SaaS 가 아니라 파일 기반 로컬 운영 메모리. 네트워크 불필요(업데이트 확인 제외).
|
|
160
|
+
- **에이전트 중립** — Claude / Codex / Cursor / Aider / Goose 등 어디에나 적용.
|
|
161
|
+
- **거짓 완료 방지** — 완료 주장에 evidence 를 요구하는 anti-lazy 흐름.
|
|
162
|
+
- **통합 게이트** — 보안·인코딩·드리프트·검증을 `gate` 하나로.
|
|
163
|
+
- **한국어 우선 + Windows/인코딩 1급 시민** — CP949/BOM 가드, 한국어 출력 기본(`--language en` 지원).
|
|
164
|
+
- **자기기술(self-describing)** — `about`/`commands`/`capabilities`/`doctor` 로 도구가 스스로 설명.
|
|
165
|
+
- **지속적 외부 검증** — 다중 모델 클린룸 리뷰로 회귀 0 을 유지하며 진화.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 보안
|
|
170
|
+
|
|
171
|
+
- 시크릿/키/토큰을 소스에 하드코딩하지 마세요. `.env` 사용 + `.gitignore` 포함. `scan secrets`/`gate` 가 커밋 대상 시크릿을 차단합니다.
|
|
172
|
+
- 외부 AI CLI 연동은 **기본 비활성**입니다(`LEERNESS_ENABLE_*` opt-in). 브리지(web/pc/lsp)도 opt-in.
|
|
173
|
+
- 자세한 권한 표면은 [SECURITY.md](./SECURITY.md) 참고.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 링크
|
|
178
|
+
|
|
179
|
+
- 홈페이지: https://leerness.com
|
|
180
|
+
- npm: https://www.npmjs.com/package/leerness
|
|
181
|
+
- GitHub: https://github.com/gugu9999gu/leerness
|
|
182
|
+
- 변경 이력: [CHANGELOG.md](./CHANGELOG.md)
|
|
183
|
+
|
|
184
|
+
## 라이선스
|
|
185
|
+
|
|
186
|
+
MIT
|
|
187
|
+
|