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.
- package/CHANGELOG.md +15 -0
- package/README.md +4 -4
- package/bin/leerness.js +3 -2
- package/lib/session-close.js +660 -647
- package/lib/tech-profile.js +3 -0
- package/package.json +1 -1
- package/scripts/e2e.js +32 -1
package/lib/tech-profile.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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);
|