leerness 1.36.66 → 1.36.68

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.
@@ -166,6 +166,9 @@ function techCmd(root, sub, deps = {}) {
166
166
  const json = !!(has && has('--json'));
167
167
  if (!exists(path.join(root, '.harness'))) { failJson(json, 'harness_missing', `leerness 미설치: ${root} — 먼저 leerness init`); return; }
168
168
  const r = refreshTechProfile(root); // show 도 항상 최신화(감지는 저비용·로컬)
169
+ // 1.36.67 (8차 헌트 F15): 프로필이 실제로 바뀌었고 그래프 산출물이 이미 있으면 함께 갱신 —
170
+ // 종전엔 tech 만 최신, leerness.html 🛠 탭은 옛 서비스를 계속 보여줬다(handoff 전까지 불일치).
171
+ if (r && r.changed && typeof deps.regenGraph === 'function') { try { deps.regenGraph(root); } catch {} }
169
172
  const p = r.profile;
170
173
  if (json) { log(JSON.stringify({ ok: true, ...p, changedNow: r.changed, diffNow: r.diff }, null, 2)); return; }
171
174
  log(`# leerness tech — 프로젝트 기술 프로필 (${p.updatedAt.slice(0, 10)})`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.36.66",
3
+ "version": "1.36.68",
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",
package/scripts/e2e.js CHANGED
@@ -1444,7 +1444,8 @@ total++;
1444
1444
  total++;
1445
1445
  {
1446
1446
  // whats-new --from 큰 점프 → 신규 명령 추출
1447
- const r = cp.spawnSync(process.execPath, [CLI, 'whats-new', '--from', '1.9.33', '--json'], { encoding: 'utf8', timeout: 15000 });
1447
+ // 1.36.68: CHANGELOG 성장으로 응답이 기본 stdout 버퍼(1MB 근처)를 넘어 절단되던 — 상한 명시(제품 무변경)
1448
+ const r = cp.spawnSync(process.execPath, [CLI, 'whats-new', '--from', '1.9.33', '--json'], { encoding: 'utf8', timeout: 20000, maxBuffer: 32 * 1024 * 1024 });
1448
1449
  let parsed = null;
1449
1450
  try { parsed = JSON.parse(r.stdout); } catch {}
1450
1451
  const ok = parsed
@@ -7143,5 +7144,35 @@ total++;
7143
7144
  if (!ok) failed++;
7144
7145
  }
7145
7146
 
7147
+ // 1.36.68 (8차 헌트 F14 재구현): 마감 보고/JSON 에 미승인 미리보기 노출 — 텍스트·JSON 양 모드 + 승인 후 소거
7148
+ total++;
7149
+ {
7150
+ let ok = false;
7151
+ const _d = [];
7152
+ try {
7153
+ const d = fs.mkdtempSync(path.join(os.tmpdir(), 'leerness-f14-')); _d.push(d);
7154
+ cp.spawnSync(process.execPath, [CLI, 'init', d, '--yes', '--no-env'], { encoding: 'utf8', timeout: 40000 });
7155
+ cp.spawnSync(process.execPath, [CLI, 'preview', 'add', '결제 화면', '--design', '모달', '--path', d], { encoding: 'utf8', timeout: 20000 });
7156
+ const txt = cp.spawnSync(process.execPath, [CLI, 'session', 'close', d], { encoding: 'utf8', timeout: 40000 });
7157
+ const textOk = txt.status === 0 && /미승인 미리보기 1건|1 preview\(s\) awaiting/.test(txt.stdout) && /P-0001/.test(txt.stdout);
7158
+ const js = cp.spawnSync(process.execPath, [CLI, 'session', 'close', d, '--json'], { encoding: 'utf8', timeout: 40000 });
7159
+ let jsonOk = false;
7160
+ try { const j = JSON.parse(js.stdout); jsonOk = j.pendingPreviews && j.pendingPreviews.count === 1 && j.pendingPreviews.items[0].id === 'P-0001'; } catch {}
7161
+ // (검수) --no-suggest 에서도 승인 대기 상태는 노출돼야 — suggest 게이트 밖 배치 회귀 가드
7162
+ const ns = cp.spawnSync(process.execPath, [CLI, 'session', 'close', d, '--no-suggest'], { encoding: 'utf8', timeout: 40000 });
7163
+ const nsJs = cp.spawnSync(process.execPath, [CLI, 'session', 'close', d, '--json', '--no-suggest'], { encoding: 'utf8', timeout: 40000 });
7164
+ let noSuggestOk = /미승인 미리보기|awaiting approval/.test(ns.stdout);
7165
+ try { noSuggestOk = noSuggestOk && JSON.parse(nsJs.stdout).pendingPreviews.count === 1; } catch { noSuggestOk = false; }
7166
+ cp.spawnSync(process.execPath, [CLI, 'preview', 'approve', 'P-0001', '--path', d], { encoding: 'utf8', timeout: 20000 });
7167
+ const after = cp.spawnSync(process.execPath, [CLI, 'session', 'close', d, '--json'], { encoding: 'utf8', timeout: 40000 });
7168
+ let clearedOk = false;
7169
+ try { clearedOk = JSON.parse(after.stdout).pendingPreviews.count === 0; } catch {}
7170
+ ok = textOk && jsonOk && noSuggestOk && clearedOk;
7171
+ if (!ok) console.log(` [f14 디버그] text=${textOk} json=${jsonOk} noSuggest=${noSuggestOk} cleared=${clearedOk}`);
7172
+ } catch (e) {} finally { _d.forEach(x => { try { fs.rmSync(x, { recursive: true, force: true }); } catch {} }); }
7173
+ console.log(ok ? '✓ B(1.36.68) F14: session close 미승인 미리보기 노출 (텍스트+JSON 일치 · --no-suggest 무영향 · 승인 시 소거)' : '✗ F14 미승인 미리보기 노출 실패');
7174
+ if (!ok) failed++;
7175
+ }
7176
+
7146
7177
  console.log(`\nE2E result: ${total - failed}/${total} passed · ${((Date.now() - _e2eStart) / 1000).toFixed(0)}s`);
7147
7178
  if (failed > 0) process.exit(1);