leerness 1.36.70 → 1.36.71
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 +9 -0
- package/README.md +4 -4
- package/bin/leerness.js +24 -14
- package/lib/mcp-tools.js +1 -1
- package/package.json +1 -1
- package/scripts/e2e.js +32 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.36.71 — 2026-07-24 — 성장 한계 클래스 3: retro/insights --json rows 상한 + 워크스페이스 --days 기존 버그 — R-0001 검수 14회전
|
|
4
|
+
|
|
5
|
+
- **retro/insights --json 의 data.rows 전량 임베드**(무한 성장, 72 task 에 22KB)를 기본 최신 30행으로 상한 — `rowsTotal/rowsShown/rowsTruncated` 정직 표기, `--all/--limit N` 옵트인, **집계 수치(totalTasks 등)는 전량 기준 그대로**(수치 왜곡 없음). 4개 JSON 배출 지점(단일/워크스페이스 × retro/insights) 일괄. 실측 33KB → 14KB.
|
|
6
|
+
- (검수 High) e2e 가 init 기본 T-0001 을 몰라 하드코딩 35 로 확정 실패할 케이스 — 기준선 유도 방식 + init/add exit 단언으로 교정(--force 가 init 실패를 가리던 문제도 제거).
|
|
7
|
+
- (검수 Medium) MCP `leerness_retro` 에 `limit`/`all` 노출+전달 (whats-new 1.36.69 와 동일 계약 규율). insights 는 MCP 도구 자체가 없음(현행 유지).
|
|
8
|
+
- (검수 Medium, **기존 버그**) 워크스페이스 retro(`--include/--all-apps`)가 `--days` 를 조용히 무시 — cutoff 를 `_retroWorkspace` 로 전달해 단일 모드와 일관(실측: days 0→fix 0 / 36500→fix 3 분리 확인).
|
|
9
|
+
- (검수 Low) help 에 `[--limit N|--all]` + rowsTotal 의미(수명 전체, --days 창 아님) 명시.
|
|
10
|
+
- 검증: selftest 334, e2e +1. codex 확인: 텍스트 모드 바이트 동일, data.rows 하위 소비자 없음, focusNext/집계 무변형.
|
|
11
|
+
|
|
3
12
|
## 1.36.70 — 2026-07-24 — 성장 한계 클래스 2: migrate 보고 상한 (88KB → 13.5KB) — R-0001 검수 13회전
|
|
4
13
|
|
|
5
14
|
1.36.69 whats-new 상한과 동일 규율을 migrate 보고서의 "AI must re-read" 섹션에 적용. 큰 버전 점프(602 릴리스)에서 보고서가 ~88KB 로 폭주해 AI 컨텍스트를 태우던 것.
|
package/README.md
CHANGED
|
@@ -122,7 +122,7 @@ MIT
|
|
|
122
122
|
<!-- leerness:project-readme:start -->
|
|
123
123
|
## Leerness Project Harness
|
|
124
124
|
|
|
125
|
-
이 프로젝트는 Leerness v1.36.
|
|
125
|
+
이 프로젝트는 Leerness v1.36.71 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
|
|
126
126
|
|
|
127
127
|
### 정체성 — AI 에이전트 운영 레이어 (UR-0030)
|
|
128
128
|
|
|
@@ -176,7 +176,7 @@ leerness memory restore decision <date|title>
|
|
|
176
176
|
|
|
177
177
|
### MCP server (외부 AI 통합)
|
|
178
178
|
|
|
179
|
-
Leerness v1.36.
|
|
179
|
+
Leerness v1.36.71는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **86개 도구**를 노출:
|
|
180
180
|
|
|
181
181
|
```jsonc
|
|
182
182
|
// 카테고리별
|
|
@@ -197,7 +197,7 @@ Leerness v1.36.70는 stdio JSON-RPC MCP server를 내장합니다 — Claude Cod
|
|
|
197
197
|
`<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
|
|
198
198
|
1) 다음 라운드 후보 선정 → 2) 코드 변경 → 3) 회귀 테스트 갱신 → 4) 전체 e2e 스위트 통과 → 5) npm publish + git tag → 6) main push → 7) session close → 8) 다음 라운드 예약.
|
|
199
199
|
|
|
200
|
-
현재 누적: **v1.9.x → 1.36.
|
|
200
|
+
현재 누적: **v1.9.x → 1.36.71 릴리스 태그 이력** (수백 라운드) · _reports/는 비공개 보존.
|
|
201
201
|
|
|
202
202
|
### 성능 가이드
|
|
203
203
|
|
|
@@ -235,5 +235,5 @@ leerness release pack --close --auto-main-push
|
|
|
235
235
|
- `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
|
|
236
236
|
- `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
|
|
237
237
|
|
|
238
|
-
Last synced by Leerness v1.36.
|
|
238
|
+
Last synced by Leerness v1.36.71: 2026-07-24
|
|
239
239
|
<!-- leerness:project-readme:end -->
|
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.
|
|
37
|
+
const VERSION = '1.36.71';
|
|
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') 시 호스트 프로세스 오염.
|
|
@@ -15302,21 +15302,31 @@ function _collectWorkspacePaths(rootBase) {
|
|
|
15302
15302
|
return Array.from(set);
|
|
15303
15303
|
}
|
|
15304
15304
|
|
|
15305
|
+
// 1.36.71 (성장 한계 클래스 3, whats-new 1.36.69 규율): retro/insights --json 이 data.rows 에 전체 task row 를
|
|
15306
|
+
// 임베드해 프로젝트와 함께 무한 성장(72 task 에 이미 22KB — AI 소비자 컨텍스트 낭비). 기본 최신 30행 +
|
|
15307
|
+
// rowsTotal/rowsShown/rowsTruncated 정직 표기, 전체는 --all, 개수는 --limit N. 집계 수치는 전량 기준 그대로.
|
|
15308
|
+
function _retroJsonData(agg) {
|
|
15309
|
+
const rawLim = parseInt(arg('--limit', '30'), 10);
|
|
15310
|
+
const lim = has('--all') ? agg.rows.length : (Number.isFinite(rawLim) && rawLim > 0 ? rawLim : 30);
|
|
15311
|
+
const rows = agg.rows.slice(-lim); // progress rows 는 오래된 것부터 — 최신 lim 개
|
|
15312
|
+
return Object.assign({}, agg, { rows, rowsTotal: agg.rows.length, rowsShown: rows.length, rowsTruncated: rows.length < agg.rows.length });
|
|
15313
|
+
}
|
|
15314
|
+
|
|
15305
15315
|
function retroCmd(root) {
|
|
15306
15316
|
root = absRoot(root);
|
|
15307
|
-
// 1.9.15: --all-apps / --include 통합 모드
|
|
15308
|
-
if (has('--all-apps') || arg('--include', null)) {
|
|
15309
|
-
return _retroWorkspace(root);
|
|
15310
|
-
}
|
|
15311
15317
|
// 1.26.1 (13번째 외부리뷰 P2): 비숫자 --days → NaN → new Date(Invalid) throw 로 --json 소비자에 plain text 누출. 숫자 가드 + 음수/오버플로 클램프(insights/round-history 와 일관).
|
|
15312
15318
|
let days = parseInt(arg('--days', '7'), 10);
|
|
15313
15319
|
if (!Number.isFinite(days)) { failJson(has('--json'), 'invalid_arg', _uiLang(root) === 'en' ? '--days must be a number' : '--days 는 숫자여야 합니다'); return; }
|
|
15314
15320
|
days = Math.max(0, Math.min(days, 36500));
|
|
15315
15321
|
const cutoff = new Date(Date.now() - days * 86400 * 1000).toISOString().slice(0, 10);
|
|
15322
|
+
// 1.9.15: --all-apps / --include 통합 모드 — 1.36.71 (검수, 기존 버그): 워크스페이스 모드가 --days 를 조용히 무시하던 것, cutoff 전달
|
|
15323
|
+
if (has('--all-apps') || arg('--include', null)) {
|
|
15324
|
+
return _retroWorkspace(root, cutoff);
|
|
15325
|
+
}
|
|
15316
15326
|
const agg = _retroAggregate(root, cutoff); // 1.36.38 (#2): 기간 필터 적용
|
|
15317
15327
|
// 1.9.16: --json
|
|
15318
15328
|
if (has('--json')) {
|
|
15319
|
-
log(JSON.stringify({ project: path.basename(root), days, cutoff, summary: _retroOneLine(agg), data: agg }, null, 2));
|
|
15329
|
+
log(JSON.stringify({ project: path.basename(root), days, cutoff, summary: _retroOneLine(agg), data: _retroJsonData(agg) }, null, 2));
|
|
15320
15330
|
return;
|
|
15321
15331
|
}
|
|
15322
15332
|
log(`# 회고 (retro) — 최근 ${days}일 (since ${cutoff})`);
|
|
@@ -15365,14 +15375,14 @@ function retroCmd(root) {
|
|
|
15365
15375
|
}
|
|
15366
15376
|
|
|
15367
15377
|
// 1.9.15: 워크스페이스 통합 retro (다수 프로젝트 묶음 회고)
|
|
15368
|
-
function _retroWorkspace(rootBase) {
|
|
15378
|
+
function _retroWorkspace(rootBase, cutoff) {
|
|
15369
15379
|
const paths = _collectWorkspacePaths(rootBase);
|
|
15370
15380
|
if (!paths.length) return fail('대상 프로젝트 없음. --include <path1,path2> 또는 --all-apps 사용 필요.');
|
|
15371
15381
|
// 1.9.16: --json
|
|
15372
15382
|
if (has('--json')) {
|
|
15373
15383
|
const projects = paths.map(p => {
|
|
15374
|
-
const a = _retroAggregate(p);
|
|
15375
|
-
return { project: path.basename(p), path: p, summary: _retroOneLine(a), data: a };
|
|
15384
|
+
const a = _retroAggregate(p, cutoff);
|
|
15385
|
+
return { project: path.basename(p), path: p, summary: _retroOneLine(a), data: _retroJsonData(a) };
|
|
15376
15386
|
});
|
|
15377
15387
|
const totals = projects.reduce((t, p) => ({
|
|
15378
15388
|
tasks: t.tasks + p.data.totalTasks, done: t.done + p.data.doneCount,
|
|
@@ -15386,7 +15396,7 @@ function _retroWorkspace(rootBase) {
|
|
|
15386
15396
|
log(`# Cross-project retro — ${paths.length}개 프로젝트`);
|
|
15387
15397
|
const totals = { tasks: 0, done: 0, decisions: 0, skills: 0, totalSkillUsage: 0, totalOpts: 0, activeRules: 0, fixSig: 0, passSig: 0 };
|
|
15388
15398
|
for (const p of paths) {
|
|
15389
|
-
const agg = _retroAggregate(p);
|
|
15399
|
+
const agg = _retroAggregate(p, cutoff);
|
|
15390
15400
|
const name = path.basename(p);
|
|
15391
15401
|
log(`\n## ${name}`);
|
|
15392
15402
|
log(` 📈 ${_retroOneLine(agg)}`);
|
|
@@ -15421,7 +15431,7 @@ function insightsCmd(root) {
|
|
|
15421
15431
|
// 1.9.16: --json
|
|
15422
15432
|
if (has('--json')) {
|
|
15423
15433
|
const sc = readSessionCounter(root);
|
|
15424
|
-
log(JSON.stringify({ project: path.basename(root), sessionCount: sc.count, lastCloseAt: sc.lastCloseAt, data: agg }, null, 2));
|
|
15434
|
+
log(JSON.stringify({ project: path.basename(root), sessionCount: sc.count, lastCloseAt: sc.lastCloseAt, data: _retroJsonData(agg) }, null, 2));
|
|
15425
15435
|
return;
|
|
15426
15436
|
}
|
|
15427
15437
|
const sc = readSessionCounter(root);
|
|
@@ -15463,7 +15473,7 @@ function _insightsWorkspace(rootBase) {
|
|
|
15463
15473
|
if (!paths.length) return fail('대상 프로젝트 없음. --include 또는 --all-apps 사용.');
|
|
15464
15474
|
// 1.9.16: --json
|
|
15465
15475
|
if (has('--json')) {
|
|
15466
|
-
const projects = paths.map(p => ({ project: path.basename(p), path: p, data: _retroAggregate(p) }));
|
|
15476
|
+
const projects = paths.map(p => ({ project: path.basename(p), path: p, data: _retroJsonData(_retroAggregate(p)) }));
|
|
15467
15477
|
log(JSON.stringify({ projects, projectCount: paths.length }, null, 2));
|
|
15468
15478
|
return;
|
|
15469
15479
|
}
|
|
@@ -18686,7 +18696,7 @@ function _mcpToCliArgs(name, args, targetPath) {
|
|
|
18686
18696
|
case 'leerness_skill_info': cliArgs = ['skill', 'info', args.id || '', '--path', targetPath, '--json']; break;
|
|
18687
18697
|
case 'leerness_benchmark': cliArgs = ['benchmark', targetPath, '--json', ...(args.scenario ? ['--scenario', args.scenario] : [])]; break;
|
|
18688
18698
|
case 'leerness_lazy_detect': cliArgs = ['lazy', 'detect', targetPath, '--json']; break;
|
|
18689
|
-
case 'leerness_retro': cliArgs = ['retro', targetPath, '--json', ...(args.days ? ['--days', String(args.days)] : []), ...(args.allApps ? ['--all-apps'] : [])]; break;
|
|
18699
|
+
case 'leerness_retro': cliArgs = ['retro', targetPath, '--json', ...(args.days ? ['--days', String(args.days)] : []), ...(args.allApps ? ['--all-apps'] : []), ...(args.all ? ['--all'] : []), ...(args.limit ? ['--limit', String(args.limit)] : [])]; break; // 1.36.71 (검수): rows 상한 조절 인자 전달
|
|
18690
18700
|
case 'leerness_task_add': cliArgs = ['task', 'add', String(args.text || ''), '--path', targetPath, ...(args.status ? ['--status', args.status] : []), ...(args.evidence ? ['--evidence', args.evidence] : []), ...(args.nextAction ? ['--next', args.nextAction] : [])]; break;
|
|
18691
18701
|
case 'leerness_task_update': cliArgs = ['task', 'update', String(args.id || ''), '--path', targetPath, ...(args.status ? ['--status', args.status] : []), ...(args.evidence ? ['--evidence', args.evidence] : []), ...(args.nextAction ? ['--next', args.nextAction] : []), ...(args.note ? ['--note', args.note] : [])]; break;
|
|
18692
18702
|
case 'leerness_task_drop': cliArgs = ['task', 'drop', String(args.id || ''), '--path', targetPath, ...(args.reason ? ['--reason', args.reason] : [])]; break;
|
|
@@ -22829,7 +22839,7 @@ HANDOFF & SESSION
|
|
|
22829
22839
|
handoff [path] [--compact] [--all-apps] [--json] Session-start context in one call
|
|
22830
22840
|
session close [path] Closing report + auto handoff
|
|
22831
22841
|
context [path] [--json] Agent onboarding context
|
|
22832
|
-
retro | insights [path] [--json]
|
|
22842
|
+
retro | insights [path] [--json] [--limit N|--all] Retrospective / cumulative stats (JSON rows: newest 30 by default; rowsTotal = lifetime count, not the --days window)
|
|
22833
22843
|
|
|
22834
22844
|
MEMORY (canonical JSON + markdown projections)
|
|
22835
22845
|
task list|add|update|drop|fix-evidence|relink [args]
|
package/lib/mcp-tools.js
CHANGED
|
@@ -27,7 +27,7 @@ module.exports = [
|
|
|
27
27
|
{ name: 'leerness_skill_info', requiredTier: 'read-only', description: '1.9.92 — 개별 skill 상세 조회 (version/capabilities/sources/patterns/usage/optimizations). 외부 AI가 skill 능력 정확히 파악', inputSchema: { type: 'object', properties: { id: { type: 'string' }, path: { type: 'string' } }, required: ['id'] } },
|
|
28
28
|
{ name: 'leerness_benchmark', requiredTier: 'read-only', description: '1.9.46/51/94 — 6 차원 점수 + 검수 시나리오 (--scenario) 결과 JSON. 외부 AI가 워크스페이스 leerness 활용 점수 확인', inputSchema: { type: 'object', properties: { path: { type: 'string' }, scenario: { type: 'string' } } } },
|
|
29
29
|
{ name: 'leerness_lazy_detect', requiredTier: 'read-only', description: '1.9.101 — 게으른 작업 자동 감지 결과 JSON (evidence 없는 done / empty handoff / no test run / TODO 미추적 / blocker no-next-action 등). 외부 AI가 거짓 완료 신호 사전 점검', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
|
|
30
|
-
{ name: 'leerness_retro', requiredTier: 'read-only', description: '1.9.104 — 4세션 누적 회고 보고서 JSON (statusCounts/focusNext/skillUsage/recentDecisions/durations/activeRules/fixSignals/passSignals/totalOptimizations). 외부 AI가 누적 패턴 자동
|
|
30
|
+
{ name: 'leerness_retro', requiredTier: 'read-only', description: '1.9.104 — 4세션 누적 회고 보고서 JSON (statusCounts/focusNext/skillUsage/recentDecisions/durations/activeRules/fixSignals/passSignals/totalOptimizations). 외부 AI가 누적 패턴 자동 학습. 1.36.71: data.rows 는 기본 최신 30행(rowsTotal/rowsShown/rowsTruncated 로 절단 확인, rowsTotal 은 --days 창이 아니라 전체 task 수), 더 필요하면 limit(개수)/all=true(전체) 지정', inputSchema: { type: 'object', properties: { path: { type: 'string' }, days: { type: 'number' }, allApps: { type: 'boolean' }, limit: { type: 'number' }, all: { type: 'boolean' } } } },
|
|
31
31
|
{ name: 'leerness_task_add', requiredTier: 'safe-write', description: '1.9.105 — progress-tracker.md 에 새 task 추가 (양방향 제어 완성). 외부 AI가 사용자 요청을 task로 즉시 등록. 인자: { text (required), status?, evidence?, nextAction?, path? }', inputSchema: { type: 'object', properties: { text: { type: 'string' }, status: { type: 'string', enum: ['requested', 'planned', 'in-progress', 'waiting', 'on-hold', 'blocked', 'incomplete', 'done', 'dropped'] }, evidence: { type: 'string' }, nextAction: { type: 'string' }, path: { type: 'string' } }, required: ['text'] } },
|
|
32
32
|
{ name: 'leerness_task_update', requiredTier: 'safe-write', description: '1.9.106 — 기존 task 상태/evidence/nextAction 갱신. 외부 AI가 작업 진행에 따라 task를 단계적으로 업데이트 (read+add+update 3종 surface 완성). 인자: { id (required), status?, evidence?, nextAction?, note?, path? }', inputSchema: { type: 'object', properties: { id: { type: 'string' }, status: { type: 'string', enum: ['requested', 'planned', 'in-progress', 'waiting', 'on-hold', 'blocked', 'incomplete', 'done', 'dropped'] }, evidence: { type: 'string' }, nextAction: { type: 'string' }, note: { type: 'string' }, path: { type: 'string' } }, required: ['id'] } },
|
|
33
33
|
{ name: 'leerness_task_drop', requiredTier: 'safe-write', description: '1.9.107 — task를 dropped 상태로 폐기 (CRUD 완성: read/add/update/drop). 외부 AI가 사용자 요청으로 task 취소. 인자: { id (required), reason?, path? }', inputSchema: { type: 'object', properties: { id: { type: 'string' }, reason: { type: 'string' }, path: { type: 'string' } }, required: ['id'] } },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.36.
|
|
3
|
+
"version": "1.36.71",
|
|
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
|
@@ -7238,5 +7238,37 @@ total++;
|
|
|
7238
7238
|
if (!ok) failed++;
|
|
7239
7239
|
}
|
|
7240
7240
|
|
|
7241
|
+
// 1.36.71 (성장 한계 클래스 3): retro/insights --json data.rows 상한 — 전 task row 임베드로 무한 성장하던 것 (집계는 전량 기준 유지)
|
|
7242
|
+
total++;
|
|
7243
|
+
{
|
|
7244
|
+
let ok = false;
|
|
7245
|
+
const _d = [];
|
|
7246
|
+
try {
|
|
7247
|
+
const d = fs.mkdtempSync(path.join(os.tmpdir(), 'leerness-retrocap-')); _d.push(d);
|
|
7248
|
+
const initR = cp.spawnSync(process.execPath, [CLI, 'init', d, '--yes', '--no-env', '--no-stale-check'], { encoding: 'utf8', timeout: 40000 });
|
|
7249
|
+
const R = (extra) => JSON.parse(cp.spawnSync(process.execPath, [CLI, ...extra, '--path', d, '--json'], { encoding: 'utf8', timeout: 20000, maxBuffer: 32 * 1024 * 1024 }).stdout);
|
|
7250
|
+
// (검수 High) init 이 기본 T-0001 을 만들 수 있음 — 하드코딩 35 대신 기준선에서 유도 + exit 단언
|
|
7251
|
+
const baseline = R(['retro', '--all']).data.rowsTotal;
|
|
7252
|
+
let addFails = 0;
|
|
7253
|
+
for (let i = 1; i <= 35; i++) { const a = cp.spawnSync(process.execPath, [CLI, 'task', 'add', `t${i}`, '--path', d], { encoding: 'utf8', timeout: 15000 }); if (a.status !== 0) addFails++; }
|
|
7254
|
+
const expTotal = baseline + 35;
|
|
7255
|
+
const r = R(['retro']);
|
|
7256
|
+
const retroOk = initR.status === 0 && addFails === 0
|
|
7257
|
+
&& r.data.rowsShown === 30 && r.data.rowsTotal === expTotal && r.data.rowsTruncated === true
|
|
7258
|
+
&& r.data.rows.length === 30 && r.data.rows[29].request === 't35' // 최신 유지 (오래된 것부터 잘림)
|
|
7259
|
+
&& r.data.totalTasks === expTotal; // 집계는 전량 기준
|
|
7260
|
+
const rAll = R(['retro', '--all']);
|
|
7261
|
+
const allOk = rAll.data.rowsShown === expTotal && rAll.data.rowsTruncated === false;
|
|
7262
|
+
const rLim = R(['retro', '--limit', '5']);
|
|
7263
|
+
const limOk = rLim.data.rowsShown === 5 && rLim.data.rows[4].request === 't35';
|
|
7264
|
+
const ins = R(['insights']);
|
|
7265
|
+
const insOk = ins.data.rowsShown === 30 && ins.data.rowsTotal === expTotal;
|
|
7266
|
+
ok = retroOk && allOk && limOk && insOk;
|
|
7267
|
+
if (!ok) console.log(` [retrocap 디버그] retro=${retroOk}(exp=${expTotal},got=${r.data.rowsTotal},addFail=${addFails}) all=${allOk} lim=${limOk} ins=${insOk}`);
|
|
7268
|
+
} catch (e) {} finally { _d.forEach(x => { try { fs.rmSync(x, { recursive: true, force: true }); } catch {} }); }
|
|
7269
|
+
console.log(ok ? '✓ B(1.36.71) retro/insights --json rows 상한 30 + 최신 유지 + 집계 전량 기준 + --all/--limit' : '✗ retro/insights rows 상한 실패');
|
|
7270
|
+
if (!ok) failed++;
|
|
7271
|
+
}
|
|
7272
|
+
|
|
7241
7273
|
console.log(`\nE2E result: ${total - failed}/${total} passed · ${((Date.now() - _e2eStart) / 1000).toFixed(0)}s`);
|
|
7242
7274
|
if (failed > 0) process.exit(1);
|