leerness 1.36.45 → 1.36.46

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.36.46 — 2026-07-16 — JSON 계약 완결 — persona/review/guide (codex 5차 #10 잔여 소진)
4
+
5
+ `--json` 을 광고하면서 마크다운/혼합 출력을 내던 마지막 3종 — MCP·자동화 소비자가 파싱 가능한 **단일 JSON 문서**로:
6
+
7
+ - **`persona show <id> --json`**: `{id, name, description, body}` (종전: 마크다운 방출) + 에러 경로 failJson 구조화.
8
+ - **`review <file> --persona … --json`**: `--emit json` 과 동치화 + **`prompts[]`(실제 리뷰 프롬프트 전문) 포함** — 종전 JSON 은 메타만 있어 소비자가 프롬프트를 재조립해야 했다.
9
+ - **`guide <target> --json`**: 하위 4섹션(impact/reuse/uiConsistency/lessons) 출력을 캡처해 `{target, query, date, sections}` 단일 객체로 집계 (종전: 사람용 헤딩+JSON 파편 혼합).
10
+ - 사람용 출력 3종 모두 무회귀. **이로써 codex 5차 헌트 10건 완전 소진(부분 이연 0).**
11
+ - **검증**: selftest 316/316, 3종 JSON.parse 실측 + 프롬프트 포함 확인, exit 전파형 게이트 e2e, 클린룸.
12
+
3
13
  ## 1.36.45 — 2026-07-16 — `adapter codex --global` — goal 모드까지 닿는 조건부 전역 지침 (사용자 버그 후속 2층)
4
14
 
5
15
  1.36.43 enforce(커밋 관문)에 이은 **지침층 보완**: codex 는 프로젝트 AGENTS.md 를 안 읽는 모드(goal 모드 — 사용자 실측)에서도 **전역 `~/.codex/AGENTS.md` 는 읽는다**. 여기에 조건부 블록을 설치해 커버.
package/README.md CHANGED
@@ -121,7 +121,7 @@ MIT
121
121
  <!-- leerness:project-readme:start -->
122
122
  ## Leerness Project Harness
123
123
 
124
- 이 프로젝트는 Leerness v1.36.45 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
124
+ 이 프로젝트는 Leerness v1.36.46 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
125
125
 
126
126
  ### 정체성 — AI 에이전트 운영 레이어 (UR-0030)
127
127
 
@@ -175,7 +175,7 @@ leerness memory restore decision <date|title>
175
175
 
176
176
  ### MCP server (외부 AI 통합)
177
177
 
178
- Leerness v1.36.45는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **86개 도구**를 노출:
178
+ Leerness v1.36.46는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **86개 도구**를 노출:
179
179
 
180
180
  ```jsonc
181
181
  // 카테고리별
@@ -196,7 +196,7 @@ Leerness v1.36.45는 stdio JSON-RPC MCP server를 내장합니다 — Claude Cod
196
196
  `<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
197
197
  1) 다음 라운드 후보 선정 → 2) 코드 변경 → 3) 회귀 테스트 갱신 → 4) 전체 e2e 스위트 통과 → 5) npm publish + git tag → 6) main push → 7) session close → 8) 다음 라운드 예약.
198
198
 
199
- 현재 누적: **v1.9.x → 1.36.45 릴리스 태그 이력** (수백 라운드) · _reports/는 비공개 보존.
199
+ 현재 누적: **v1.9.x → 1.36.46 릴리스 태그 이력** (수백 라운드) · _reports/는 비공개 보존.
200
200
 
201
201
  ### 성능 가이드
202
202
 
@@ -234,6 +234,6 @@ leerness release pack --close --auto-main-push
234
234
  - `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
235
235
  - `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
236
236
 
237
- Last synced by Leerness v1.36.45: 2026-07-16
237
+ Last synced by Leerness v1.36.46: 2026-07-16
238
238
  <!-- leerness:project-readme:end -->
239
239
 
package/bin/leerness.js CHANGED
@@ -34,7 +34,7 @@ const { CAPABILITY_SURFACE, POWERFUL_COMMANDS, ADAPTERS, REUSE_CATEGORIES, REUSE
34
34
  const { tokenizeForRank: _tokenizeForRank, expandQuery: _expandQuery, scoreHits: _scoreHits, suggestTerms: _suggestTerms } = require('../lib/search-core'); // 1.36.23: memory search 랭킹 코어(순수·0-deps)
35
35
  const { findCorruptedStateJson: _findCorruptedStateJson } = require('../lib/state-integrity'); // 1.36.1 (클린룸 리뷰 FN): .harness/*.json 상태 무결성 (audit/health/check 공유)
36
36
 
37
- const VERSION = '1.36.45';
37
+ const VERSION = '1.36.46';
38
38
 
39
39
  // 1.9.290 (UR-0037, Codex gpt-5.5 #4 수렴): CLI 전용 부작용은 require 시 실행하지 않는다.
40
40
  // 이전: warning listener 제거 / NODE_OPTIONS 변경 / chcp IIFE 가 top-level 즉시 실행 → require('harness') 시 호스트 프로세스 오염.
@@ -3361,6 +3361,13 @@ function _selfTestCases() {
3361
3361
  const removeOk = /has\('--remove'\)[\s\S]{0,400}codex 전역 leerness 블록 제거/.test(s);
3362
3362
  return wired && conditional && mergeOk && removeOk;
3363
3363
  } },
3364
+ { name: 'JSON 계약 완결 (1.36.46, codex 5차 #10 잔여): persona show/review/guide --json 단일 JSON 문서 (소스가드)', run: () => {
3365
+ const s = read(__filename);
3366
+ const personaOk = s.includes("log(JSON.stringify({ id: p.id, name: p.name, description: p.description, body: p.body }, null, 2)); return;");
3367
+ const reviewOk = s.includes("has('--json') ? 'json' : arg('--emit', 'prompt')") && s.includes('prompts: personas.map(p => ({ personaId: p.id, prompt: _mkPrompt(p) }))');
3368
+ const guideOk = /guideCmd[\s\S]{0,600}if \(has\('--json'\)\) \{[\s\S]{0,900}sections/.test(s) && s.includes('uiConsistency: _cap(() => uiConsistency(root))');
3369
+ return personaOk && reviewOk && guideOk;
3370
+ } },
3364
3371
  { name: 'debug 렌즈 (1.36.27, obra/superpowers systematic-debugging): 자기질문 6문항 ko/en 락스텝 + affects 유효 + route bugfix 힌트 + 파일매핑 미확장 — 행위검사', run: () => {
3365
3372
  const d = LENS_CATALOG.debug;
3366
3373
  if (!d) return false;
@@ -14124,9 +14131,11 @@ function personaCmd(root, sub, idOrName, ...rest) {
14124
14131
  return;
14125
14132
  }
14126
14133
  if (sub === 'show') {
14127
- if (!idOrName) { fail('persona show <id> 필요'); return process.exit(1); }
14134
+ if (!idOrName) { failJson(has('--json'), 'missing_arg', 'persona show <id> 필요'); return process.exit(1); }
14128
14135
  const p = _resolvePersona(root, idOrName);
14129
- if (!p) { fail(`페르소나 없음: ${idOrName}`); return process.exit(1); }
14136
+ if (!p) { failJson(has('--json'), 'not_found', `페르소나 없음: ${idOrName}`); return process.exit(1); }
14137
+ // 1.36.46 (codex 5차 #10 잔여): --json 은 단일 JSON 문서 (종전 마크다운 방출)
14138
+ if (has('--json')) { log(JSON.stringify({ id: p.id, name: p.name, description: p.description, body: p.body }, null, 2)); return; }
14130
14139
  log(`# ${p.name} (${p.id})`);
14131
14140
  log(`\n${p.description}\n`);
14132
14141
  log(`---\n${p.body}`);
@@ -14170,13 +14179,16 @@ function reviewCmd(root, target) {
14170
14179
  }
14171
14180
 
14172
14181
  // 출력 형식: emit
14173
- const emit = arg('--emit', 'prompt'); // prompt | md | json
14182
+ const emit = has('--json') ? 'json' : arg('--emit', 'prompt'); // prompt | md | json (1.36.46: --json ≡ --emit json)
14174
14183
 
14175
14184
  if (emit === 'json') {
14185
+ // 1.36.46 (codex 5차 #10 잔여): JSON 에 실제 산출물(프롬프트)까지 — 메타만 주던 종전은 소비자가 재조립해야 했다.
14186
+ const _mkPrompt = (p) => [`# Review Prompt — ${p.name} (${p.id})`, `## 대상: ${target} (${fileSize} bytes)`, `## 페르소나 활성화`, p.body, ``, `## 작업`, `아래 코드를 위 페르소나 관점에서 정밀 리뷰하라. 한국어 보고 ~600단어.`, ``, `## 코드`, '```javascript', fileContent, '```'].join('\n');
14176
14187
  log(JSON.stringify({
14177
14188
  file: target,
14178
14189
  filePath, fileSize,
14179
- personas: personas.map(p => ({ id: p.id, name: p.name }))
14190
+ personas: personas.map(p => ({ id: p.id, name: p.name })),
14191
+ prompts: personas.map(p => ({ personaId: p.id, prompt: _mkPrompt(p) }))
14180
14192
  }, null, 2));
14181
14193
  return;
14182
14194
  }
@@ -16796,6 +16808,23 @@ function graphCmd(root) {
16796
16808
 
16797
16809
  function guideCmd(root, target) {
16798
16810
  root = absRoot(root);
16811
+ // 1.36.46 (codex 5차 #10 잔여): --json 은 하위 4섹션 출력을 캡처해 단일 JSON 으로 집계 (종전: 사람용 헤딩+JSON 파편 혼합).
16812
+ if (has('--json')) {
16813
+ const q0 = target ? path.basename(target, path.extname(target)) : arg('--query', '');
16814
+ const _cap = (fn) => {
16815
+ const _w = process.stdout.write; let out = '';
16816
+ try { process.stdout.write = s => { out += s; return true; }; fn(); } catch (e) { out += `\n(error: ${e.message})`; } finally { process.stdout.write = _w; }
16817
+ return out.trim();
16818
+ };
16819
+ const sections = {
16820
+ impact: target ? _cap(() => impactCmd(root, target)) : null,
16821
+ reuse: q0 ? _cap(() => reuseFind(root, q0)) : null,
16822
+ uiConsistency: _cap(() => uiConsistency(root)),
16823
+ lessons: q0 ? _cap(() => { if (!process.argv.includes('--query')) process.argv.push('--query', q0); lessonsCmd(root); }) : null,
16824
+ };
16825
+ log(JSON.stringify({ target: target || null, query: q0 || null, date: today(), sections }, null, 2));
16826
+ return;
16827
+ }
16799
16828
  log(`# 변경 전 가이드 ${target ? `(target: ${target})` : ''}`);
16800
16829
  log(`Date: ${today()}\n`);
16801
16830
  if (target) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.36.45",
3
+ "version": "1.36.46",
4
4
  "description": "The AI-coding operations layer that makes \"done\" require evidence — persistent memory, evidence-gated completion checks, and clean handoffs for any AI agent (Claude Code, Codex, Cursor). State lives as plain files in your repo. CLI + MCP, 0 runtime dependencies.",
5
5
  "keywords": [
6
6
  "leerness",