leerness 1.9.76 → 1.9.78

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,56 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.78 — 2026-05-20
4
+
5
+ **`drift check`에 5번째 신호 추가 — 보안 누락이 drift score 가중** (1.9.75/76 보안 검사 통합).
6
+
7
+ ### Added — drift check 보안 신호
8
+ - 기존 4 신호: session-handoff / current-state / progress-tracker / task-log.
9
+ - **5번째 신호**: `.env` + `.gitignore` 보안 점검.
10
+ - `.env→.env.example` 누락 → +15 score.
11
+ - `.gitignore`에 `.env` 누락 → **+30 score** (최우선 위험).
12
+ - 기타 시크릿 패턴 (`.env.local`, `*.pem`, `credentials.json` 등) 누락 → max +20 (개당 +5).
13
+ - `drift check --json` 의 `fired` 배열에 새 항목 추가:
14
+ ```json
15
+ {
16
+ "file": ".env / .gitignore",
17
+ "weight": 45,
18
+ "label": "보안 위험 (1.9.78): .env→.env.example 누락 N건 · .gitignore 시크릿 누락 M건"
19
+ }
20
+ ```
21
+ - 보안 누락이 drift level을 critical로 승격시킬 수 있음 (CI 친화).
22
+
23
+ ### Use Case
24
+ - 매 \`leerness handoff\` 시 drift 신호로 보안 위험 즉시 인지 (1.9.76 보안 요약과 동시).
25
+ - AI 에이전트가 drift critical 시 \`drift check --auto-fix\` → `audit --fix` 호출 → 자동 회복.
26
+
27
+ ### Verified
28
+ - stress-v24 — drift 보안 신호 + level 승격 + 1.9.43~77 누적 회귀 + 성능.
29
+ - e2e 219/219 PASS 유지.
30
+
31
+ ---
32
+
33
+ ## 1.9.77 — 2026-05-20
34
+
35
+ **MCP server 15번째 도구 `leerness_brainstorm` 추가** (1.9.72 brainstorm 외부 노출).
36
+
37
+ ### Added — MCP 15번째 도구
38
+ - `leerness_brainstorm` — 1.9.16/72 brainstorm 명령을 MCP 도구로 노출.
39
+ - inputSchema: `{ topic: string (required), path: string, allApps: boolean }`
40
+ - 응답: brainstorm --json 결과 (decisions + skills + tasks + rules + evidence + lessons + skillHistory + taskLogFails).
41
+ - 외부 AI 에이전트가 새 작업 시작 전 누적 컨텍스트 자동 회수 가능.
42
+ - MCP server 도구 카운트: **14 → 15**.
43
+
44
+ ### Use Case
45
+ - Claude Code / Cursor 가 사용자 요청을 받으면 자동으로 `brainstorm` 호출 → 같은 주제 과거 결정/스킬/실패 회수.
46
+ - 같은 실수 반복 방지 + 누적 학습 활용.
47
+
48
+ ### Verified
49
+ - stress-v23 — MCP 15 도구 + brainstorm 호출 + 1.9.43~76 누적 회귀 + 성능.
50
+ - e2e 회귀: 219/219 PASS 유지.
51
+
52
+ ---
53
+
3
54
  ## 1.9.76 — 2026-05-20
4
55
 
5
56
  **`leerness handoff`에 보안 상태 요약 자동 표시** (1.9.71 env + 1.9.75 gitignore 결합).
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.76-green)]() [![tests](https://img.shields.io/badge/e2e-219%2F219-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.78-green)]() [![tests](https://img.shields.io/badge/e2e-219%2F219-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
6
6
 
7
7
  ```
8
8
  ╔══════════════════════════════════════════════════════════════╗
@@ -12,7 +12,7 @@
12
12
  ║ ██║ ██╔══╝ ██╔══╝ ██╔══██╗██║╚██╗██║██╔══╝ ╚════██║ ║
13
13
  ║ ███████╗███████╗███████╗██║ ██║██║ ╚████║███████╗███████║ ║
14
14
  ║ ╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝ ║
15
- ║ v1.9.76 AI Agent Reliability Harness ║
15
+ ║ v1.9.78 AI Agent Reliability Harness ║
16
16
  ║ verify · remember · orchestrate · audit · prevent drift ║
17
17
  ╚══════════════════════════════════════════════════════════════╝
18
18
  ```
@@ -433,6 +433,8 @@ npm test # = node ./scripts/e2e.js
433
433
 
434
434
  ## 변경 이력 (최근)
435
435
 
436
+ - **1.9.78** — **`drift check` 5번째 신호** — `.env` + `.gitignore` 보안 누락을 drift score에 가중 (`.env` 자체 누락 시 +30, 동기화 누락 +15). 보안 위험이 drift critical 승격 가능.
437
+ - **1.9.77** — **MCP server 15번째 도구 `leerness_brainstorm`** — 1.9.72 brainstorm (decisions + skills + tasks + rules + evidence + lessons + skillHistory + taskLogFails)을 외부 AI에 노출. AI가 새 작업 시작 전 누적 컨텍스트 자동 회수.
436
438
  - **1.9.76** — **`leerness handoff`에 보안 상태 요약 자동 표시** — `.env→.env.example` 누락 + `.gitignore` 시크릿 패턴 누락을 매 handoff에 1-2 line 자동 노출. AI가 세션 시작 즉시 보안 위험 인지.
437
439
  - **1.9.75** — **`leerness audit` 보안 강화** — `.env` 존재 시 `.gitignore`에 시크릿 패턴 (`.env`/`.env.local`/`.env.production`/`*.pem`/`credentials.json`) 자동 검증, `--fix`로 자동 추가.
438
440
  - **1.9.74** — **`session close` 마감 시 누적 회고 통계 강화** — MCP tools/call 카운트 + skill match query top + drift 통계를 자동 요약 (1.9.70 + 1.9.68 결합).
package/bin/harness.js CHANGED
@@ -6,7 +6,7 @@ const path = require('path');
6
6
  const cp = require('child_process');
7
7
  const readline = require('readline');
8
8
 
9
- const VERSION = '1.9.76';
9
+ const VERSION = '1.9.78';
10
10
  const MARK = '<!-- leerness:managed -->';
11
11
  const README_START = '<!-- leerness:project-readme:start -->';
12
12
  const README_END = '<!-- leerness:project-readme:end -->';
@@ -3309,7 +3309,7 @@ function _banner(opts = {}) {
3309
3309
  lines.push('');
3310
3310
  for (const ln of lines) log(ln);
3311
3311
  if (opts.quickStart) {
3312
- log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.76+ 워크플로)')));
3312
+ log(C.bold(C.cyan(' ✨ 빠른 시작 (1.9.78+ 워크플로)')));
3313
3313
  log(' ' + C.green('npx leerness@latest init .') + C.dim(' # 신규 프로젝트 + 외부 AI CLI 설정'));
3314
3314
  log(' ' + C.green('npx leerness handoff .') + C.dim(' # 컨텍스트 + lessons + 매칭 skill + 이전 history hit (1.9.69)'));
3315
3315
  log(' ' + C.green('npx leerness skill match "<query>"') + C.dim(' # 매칭 skill + rolling history 자동 누적 (1.9.68)'));
@@ -3318,7 +3318,7 @@ function _banner(opts = {}) {
3318
3318
  log(' ' + C.green('npx leerness session close .') + C.dim(' # 마감 + 다음 라운드 추천 (default)'));
3319
3319
  log('');
3320
3320
  log(C.bold(C.cyan(' 🤖 메인 에이전트 (Claude/Cursor/Copilot)용')));
3321
- log(' ' + C.green('npx leerness mcp serve') + C.dim(' # MCP 서버 — 14 도구 (env_check 포함) + tools/call 통계'));
3321
+ log(' ' + C.green('npx leerness mcp serve') + C.dim(' # MCP 서버 — 15 도구 (brainstorm 포함, 1.9.77)'));
3322
3322
  log(' ' + C.green('npx leerness agents bench "<task>"') + C.dim(' # 3 CLI 동시 비교'));
3323
3323
  log('');
3324
3324
  }
@@ -6310,6 +6310,39 @@ function driftCheckCmd(root, opts = {}) {
6310
6310
  fired.push(s);
6311
6311
  }
6312
6312
  }
6313
+ // 1.9.78: 보안 신호 (env / .gitignore 누락) — 5번째 신호
6314
+ try {
6315
+ const envPath = path.join(root, '.env');
6316
+ if (exists(envPath)) {
6317
+ let secScore = 0;
6318
+ const secIssues = [];
6319
+ // (a) .env vs .env.example 동기화
6320
+ try {
6321
+ const d = envDiff(root);
6322
+ if (d.inEnvOnly.length) {
6323
+ secIssues.push(`.env→.env.example 누락 ${d.inEnvOnly.length}건`);
6324
+ secScore += 15;
6325
+ }
6326
+ } catch {}
6327
+ // (b) .gitignore 시크릿 패턴
6328
+ try {
6329
+ const giText = exists(path.join(root, '.gitignore')) ? read(path.join(root, '.gitignore')) : '';
6330
+ const giLines = giText.split('\n').map(l => l.trim());
6331
+ const SECRET_PATTERNS = ['.env', '.env.local', '.env.production', '.env.*.local', '*.pem', 'credentials.json'];
6332
+ const missing = SECRET_PATTERNS.filter(p => !giLines.some(l => l === p || l === '/' + p));
6333
+ if (missing.length) {
6334
+ secIssues.push(`.gitignore 시크릿 누락 ${missing.length}건`);
6335
+ // 누락이 .env 자체면 최우선 위험 — 15점 가중
6336
+ if (missing.includes('.env')) secScore += 30;
6337
+ else secScore += Math.min(20, missing.length * 5);
6338
+ }
6339
+ } catch {}
6340
+ if (secScore > 0) {
6341
+ totalScore += secScore;
6342
+ fired.push({ file: '.env / .gitignore', ageDays: null, threshold: 0, weight: secScore, label: `보안 위험 (1.9.78): ${secIssues.join(' · ')}` });
6343
+ }
6344
+ }
6345
+ } catch {}
6313
6346
  // 신규 _apps/* 에서 task 0건도 신호로
6314
6347
  const appsDir = path.join(root, '_apps');
6315
6348
  let appsZeroTask = [];
@@ -7174,7 +7207,8 @@ function mcpServeCmd(root) {
7174
7207
  { name: 'leerness_skill_suggest', description: '1.9.53 — 사용 패턴 자동 분석 → 새 skill 후보 제안 (Hermes-style 자동 학습)', inputSchema: { type: 'object', properties: { path: { type: 'string' }, min: { type: 'number' }, days: { type: 'number' } } } },
7175
7208
  { name: 'leerness_lessons', description: '1.9.7/54 — 과거 결정·실수 자동 회수 (--auto: 현재 task 키워드 자동 추출)', inputSchema: { type: 'object', properties: { path: { type: 'string' }, query: { type: 'string' }, auto: { type: 'boolean' }, limit: { type: 'number' } } } },
7176
7209
  { name: 'leerness_task_export', description: '1.9.60/66 — leerness task → Claude Code TodoWrite 호환 JSON (외부 AI 양방향 sync)', inputSchema: { type: 'object', properties: { path: { type: 'string' }, to: { type: 'string' } } } },
7177
- { name: 'leerness_env_check', description: '1.9.71/73 — .env vs .env.example 동기화 검사 (보안: 키만, 값 미노출). exit 1 if 누락 키 있음', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } }
7210
+ { name: 'leerness_env_check', description: '1.9.71/73 — .env vs .env.example 동기화 검사 (보안: 키만, 값 미노출). exit 1 if 누락 키 있음', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
7211
+ { name: 'leerness_brainstorm', description: '1.9.16/72/77 — 누적 컨텍스트(decisions+skills+tasks+rules+evidence+lessons+skillHistory+taskLogFails) 자원 회수. 외부 AI가 새 작업 시작 전 호출', inputSchema: { type: 'object', properties: { topic: { type: 'string' }, path: { type: 'string' }, allApps: { type: 'boolean' } }, required: ['topic'] } }
7178
7212
  ];
7179
7213
 
7180
7214
  function send(obj) {
@@ -7220,6 +7254,7 @@ function mcpServeCmd(root) {
7220
7254
  case 'leerness_lessons': cliArgs = ['lessons', '--path', targetPath, ...(args.auto ? ['--auto'] : []), ...(args.query ? ['--query', args.query] : []), ...(args.limit ? ['--limit', String(args.limit)] : [])]; break;
7221
7255
  case 'leerness_task_export': cliArgs = ['task', 'export', '--path', targetPath, ...(args.to ? ['--to', args.to] : ['--json'])]; break;
7222
7256
  case 'leerness_env_check': cliArgs = ['env', 'check', targetPath, '--json']; break;
7257
+ case 'leerness_brainstorm': cliArgs = ['brainstorm', args.topic || '', '--path', targetPath, '--json', ...(args.allApps ? ['--all-apps'] : [])]; break;
7223
7258
  default:
7224
7259
  return send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Unknown tool: ${name}` } });
7225
7260
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.76",
3
+ "version": "1.9.78",
4
4
  "description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
5
5
  "keywords": [
6
6
  "leerness",