@lcv-ideas-software/cross-review 4.1.0 → 4.2.0
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 +52 -0
- package/README.md +75 -73
- package/dist/scripts/runtime-smoke.js +59 -3
- package/dist/scripts/runtime-smoke.js.map +1 -1
- package/dist/scripts/smoke.js +58 -0
- package/dist/scripts/smoke.js.map +1 -1
- package/dist/src/core/config.d.ts +1 -1
- package/dist/src/core/config.js +1 -1
- package/dist/src/core/session-store.js +7 -9
- package/dist/src/core/session-store.js.map +1 -1
- package/dist/src/mcp/server.js +101 -7
- package/dist/src/mcp/server.js.map +1 -1
- package/package.json +3 -3
|
@@ -58,23 +58,64 @@ async function callTool(name, args) {
|
|
|
58
58
|
const text = content[0]?.type === "text" ? (content[0].text ?? "{}") : "{}";
|
|
59
59
|
return JSON.parse(text);
|
|
60
60
|
}
|
|
61
|
+
async function callToolText(name, args) {
|
|
62
|
+
const result = await client.callTool({ name, arguments: args }, undefined, {
|
|
63
|
+
timeout: MCP_REQUEST_TIMEOUT_MS,
|
|
64
|
+
maxTotalTimeout: MCP_REQUEST_TIMEOUT_MS,
|
|
65
|
+
});
|
|
66
|
+
const content = result.content ?? [];
|
|
67
|
+
return content[0]?.type === "text" ? (content[0].text ?? "") : "";
|
|
68
|
+
}
|
|
69
|
+
const POLL_INTERVAL_MS = 250;
|
|
70
|
+
const POLL_TIMEOUT_MS = 60_000;
|
|
71
|
+
const TERMINAL_OUTCOMES = new Set(["converged", "aborted", "max-rounds"]);
|
|
61
72
|
async function pollUntilDone(sessionId) {
|
|
62
|
-
|
|
73
|
+
const deadline = Date.now() + POLL_TIMEOUT_MS;
|
|
74
|
+
while (Date.now() < deadline) {
|
|
63
75
|
const state = (await callTool("session_poll", {
|
|
64
76
|
session_id: sessionId,
|
|
65
77
|
response_format: "json",
|
|
66
78
|
}));
|
|
79
|
+
if (state.outcome && TERMINAL_OUTCOMES.has(state.outcome)) {
|
|
80
|
+
return state;
|
|
81
|
+
}
|
|
67
82
|
if (state.jobs?.some((job) => job.status === "completed" || job.status === "failed" || job.status === "cancelled")) {
|
|
68
83
|
return state;
|
|
69
84
|
}
|
|
70
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
85
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
71
86
|
}
|
|
72
|
-
throw new Error(`Timed out polling runtime-smoke session ${sessionId}`);
|
|
87
|
+
throw new Error(`Timed out polling runtime-smoke session ${sessionId} after ${POLL_TIMEOUT_MS} ms`);
|
|
73
88
|
}
|
|
74
89
|
try {
|
|
75
90
|
await client.connect(transport);
|
|
76
91
|
const serverInfo = await callTool("server_info", { response_format: "json" });
|
|
77
92
|
const capabilities = await callTool("runtime_capabilities", { response_format: "json" });
|
|
93
|
+
const markdownInitText = await callToolText("session_init", {
|
|
94
|
+
task: "Runtime smoke: verify session_init markdown response.",
|
|
95
|
+
review_focus: "runtime/markdown-init",
|
|
96
|
+
response_format: "markdown",
|
|
97
|
+
});
|
|
98
|
+
const sessionListResult = (await callTool("session_list", {
|
|
99
|
+
limit: 2,
|
|
100
|
+
offset: 0,
|
|
101
|
+
outcome_filter: "all",
|
|
102
|
+
detail: "summary",
|
|
103
|
+
response_format: "json",
|
|
104
|
+
}));
|
|
105
|
+
const noJobSession = (await callTool("session_init", {
|
|
106
|
+
task: "Runtime smoke: verify no-job cancellation is non-terminal.",
|
|
107
|
+
review_focus: "runtime/cancel-no-job",
|
|
108
|
+
response_format: "json",
|
|
109
|
+
}));
|
|
110
|
+
const noJobCancelResult = (await callTool("session_cancel_job", {
|
|
111
|
+
session_id: noJobSession.session_id,
|
|
112
|
+
reason: "runtime_smoke_no_active_job",
|
|
113
|
+
response_format: "json",
|
|
114
|
+
}));
|
|
115
|
+
const noJobCancelState = (await callTool("session_poll", {
|
|
116
|
+
session_id: noJobSession.session_id,
|
|
117
|
+
response_format: "json",
|
|
118
|
+
}));
|
|
78
119
|
const roundStart = (await callTool("session_start_round", {
|
|
79
120
|
task: "Runtime smoke: verify async review round.",
|
|
80
121
|
review_focus: "runtime/smoke",
|
|
@@ -122,6 +163,16 @@ try {
|
|
|
122
163
|
// running. These asserts run BEFORE the `ok: true` print, so any flow
|
|
123
164
|
// that did not reach its intended terminal state fails the smoke loudly
|
|
124
165
|
// with a non-zero exit.
|
|
166
|
+
assert.match(markdownInitText, /^# cross-review session [0-9a-f-]+/m, "runtime-smoke: session_init markdown response must start with a markdown heading");
|
|
167
|
+
assert.ok(markdownInitText.includes("## Task"), "runtime-smoke: session_init markdown response must include a Task section");
|
|
168
|
+
assert.equal(markdownInitText.trimStart().startsWith("{"), false, "runtime-smoke: session_init markdown response must not be JSON serialization");
|
|
169
|
+
assert.equal(sessionListResult.detail, "summary", "runtime-smoke: session_list must default/return summary detail for bounded list calls");
|
|
170
|
+
assert.equal(sessionListResult.outcome_filter, "all", "runtime-smoke: session_list must echo the outcome_filter");
|
|
171
|
+
assert.equal(sessionListResult.pagination?.limit, 2, "runtime-smoke: session_list must honor the requested page limit");
|
|
172
|
+
assert.ok((sessionListResult.sessions?.length ?? 0) <= 2, "runtime-smoke: session_list must not return more entries than the requested limit");
|
|
173
|
+
assert.equal(noJobCancelResult.requested, false, "runtime-smoke: no-job cancellation must not claim a cancellation request was issued");
|
|
174
|
+
assert.equal(noJobCancelResult.reason, "no_running_job_matched", "runtime-smoke: no-job cancellation must report no_running_job_matched");
|
|
175
|
+
assert.equal(noJobCancelState.outcome, undefined, `runtime-smoke: no-job cancellation must not terminal-abort the session — outcome=${String(noJobCancelState.outcome)}`);
|
|
125
176
|
assert.equal(roundState.outcome, "converged", `runtime-smoke: review round did not converge — outcome=${String(roundState.outcome)}`);
|
|
126
177
|
assert.equal(unanimousState.outcome, "converged", `runtime-smoke: unanimity flow did not converge — outcome=${String(unanimousState.outcome)}`);
|
|
127
178
|
assert.equal(cancelState.outcome, "aborted", `runtime-smoke: cancellation flow did not abort — outcome=${String(cancelState.outcome)}`);
|
|
@@ -129,6 +180,11 @@ try {
|
|
|
129
180
|
ok: true,
|
|
130
181
|
serverInfo,
|
|
131
182
|
capabilities,
|
|
183
|
+
markdownInitText,
|
|
184
|
+
sessionListResult,
|
|
185
|
+
no_job_cancel_session_id: noJobSession.session_id,
|
|
186
|
+
noJobCancelResult,
|
|
187
|
+
noJobCancelState,
|
|
132
188
|
round_session_id: roundStart.session_id,
|
|
133
189
|
roundState,
|
|
134
190
|
events,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-smoke.js","sourceRoot":"","sources":["../../scripts/runtime-smoke.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runtime-smoke.js","sourceRoot":"","sources":["../../scripts/runtime-smoke.ts"],"names":[],"mappings":"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"}
|
package/dist/scripts/smoke.js
CHANGED
|
@@ -574,6 +574,8 @@ assert.equal(checkConvergence(["codex", "claude"], "READY", [fakeReady("codex"),
|
|
|
574
574
|
assert.ok(/assert\.equal\(\s*roundState\.outcome,\s*"converged"/.test(runtimeSmokeSrc), 'v3.7.4 / runtime-smoke: must assert roundState.outcome === "converged"');
|
|
575
575
|
assert.ok(/assert\.equal\(\s*unanimousState\.outcome,\s*"converged"/.test(runtimeSmokeSrc), 'v3.7.4 / runtime-smoke: must assert unanimousState.outcome === "converged"');
|
|
576
576
|
assert.ok(/assert\.equal\(\s*cancelState\.outcome,\s*"aborted"/.test(runtimeSmokeSrc), 'v3.7.4 / runtime-smoke: must assert cancelState.outcome === "aborted"');
|
|
577
|
+
assert.ok(/TERMINAL_OUTCOMES\s*=\s*new Set\(\["converged", "aborted", "max-rounds"\]\)/.test(runtimeSmokeSrc), "runtime-smoke: pollUntilDone must return on terminal outcome even when job status lags.");
|
|
578
|
+
assert.ok(/POLL_TIMEOUT_MS\s*=\s*60_000/.test(runtimeSmokeSrc), "runtime-smoke: pollUntilDone must allow a 60s deadline so a slow-but-converged stub flow is not reported as timeout.");
|
|
577
579
|
console.log("[smoke] runtime_smoke_outcome_assert_test: PASS");
|
|
578
580
|
}
|
|
579
581
|
const probes = await orchestrator.probeAll();
|
|
@@ -6308,8 +6310,16 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
|
|
|
6308
6310
|
// withSessionLock — fail-closed implies the legacy file is
|
|
6309
6311
|
// NEVER deleted by v4.1.0.
|
|
6310
6312
|
assert.ok(!/fs\.rmSync\(\s*lockfilePath\b/.test(storeSrc), "v4.1.0 / F6: session-store.ts must NOT contain `fs.rmSync(lockfilePath, ...)` — v4.1.0 fails closed on legacy locks and never auto-removes them.");
|
|
6313
|
+
assert.ok(!/if\s*\(\s*!\s*fs\.existsSync\(\s*target\s*\)\s*\)\s*\{[\s\S]{0,300}fs\.writeFileSync\(\s*target/.test(storeSrc), "v4.1.1 / CodeQL: meta placeholder creation must not use existsSync(target) before writeFileSync(target); rely on writeFileSync(..., { flag: 'wx' }) and EEXIST handling instead.");
|
|
6311
6314
|
console.log("[smoke] session_lock_proper_lockfile_test: PASS");
|
|
6312
6315
|
}
|
|
6316
|
+
{
|
|
6317
|
+
const migrationRaceSrc = fs.readFileSync(path.join(process.cwd(), "scripts", "race-migration-toctou.mjs"), "utf8");
|
|
6318
|
+
assert.ok(/fs\.openSync\(\s*lockfilePath,\s*["']r["']\s*\)/.test(migrationRaceSrc), "v4.1.1 / CodeQL: race-migration-toctou must open lockfilePath and snapshot through the file descriptor.");
|
|
6319
|
+
assert.ok(/fs\.fstatSync\(\s*endFd\s*\)/.test(migrationRaceSrc), "v4.1.1 / CodeQL: race-migration-toctou must use fstatSync(endFd) rather than statSync(lockfilePath) before reading.");
|
|
6320
|
+
assert.ok(!/fs\.statSync\(\s*lockfilePath\s*\)[\s\S]{0,120}fs\.readFileSync\(\s*lockfilePath/.test(migrationRaceSrc), "v4.1.1 / CodeQL: race-migration-toctou must not statSync(lockfilePath) then readFileSync(lockfilePath).");
|
|
6321
|
+
console.log("[smoke] codeql_file_system_race_regression_test: PASS");
|
|
6322
|
+
}
|
|
6313
6323
|
for (const required of ["dist", "shasum", "integrity", "tarball"]) {
|
|
6314
6324
|
assert.ok(verifyScript.includes(required), `v4.0.5 / AUDIT-6: verify-registry-dist.mjs must validate npm registry dist.${required}.`);
|
|
6315
6325
|
}
|
|
@@ -6359,6 +6369,54 @@ assert.equal(Object.hasOwn(metrics.decision_quality, "undefined"), false);
|
|
|
6359
6369
|
}
|
|
6360
6370
|
console.log("[smoke] npm_registry_discipline_test: PASS");
|
|
6361
6371
|
}
|
|
6372
|
+
{
|
|
6373
|
+
const prettierIgnore = fs.readFileSync(path.join(process.cwd(), ".prettierignore"), "utf8");
|
|
6374
|
+
const ignoredPatterns = prettierIgnore
|
|
6375
|
+
.split(/\r?\n/)
|
|
6376
|
+
.map((line) => line.trim())
|
|
6377
|
+
.filter((line) => line && !line.startsWith("#"));
|
|
6378
|
+
for (const forbidden of ["README.md", "**/README.md", "src", "src/**", "scripts", "scripts/**"]) {
|
|
6379
|
+
assert.ok(!ignoredPatterns.includes(forbidden), `hard-gate / no-mask: .prettierignore must not hide ${forbidden} from Prettier coverage.`);
|
|
6380
|
+
}
|
|
6381
|
+
const eslintConfig = fs.readFileSync(path.join(process.cwd(), "eslint.config.js"), "utf8");
|
|
6382
|
+
assert.ok(!/"@typescript-eslint\/no-explicit-any"\s*:\s*["']off["']/.test(eslintConfig), "hard-gate / no-mask: eslint.config.js must not disable @typescript-eslint/no-explicit-any globally.");
|
|
6383
|
+
assert.ok(!/"@typescript-eslint\/no-unused-vars"\s*:\s*["']off["']/.test(eslintConfig), "hard-gate / no-mask: eslint.config.js must not disable @typescript-eslint/no-unused-vars globally.");
|
|
6384
|
+
assert.ok(/"@typescript-eslint\/no-unused-vars"\s*:\s*\[\s*["']error["']/.test(eslintConfig), "hard-gate / no-mask: @typescript-eslint/no-unused-vars must remain an error.");
|
|
6385
|
+
console.log("[smoke] hard_gate_no_linter_formatter_masking_test: PASS");
|
|
6386
|
+
}
|
|
6387
|
+
{
|
|
6388
|
+
const serverSrc = fs.readFileSync(path.join(process.cwd(), "src", "mcp", "server.ts"), "utf8");
|
|
6389
|
+
const sessionListBlock = serverSrc.match(/"session_list"[\s\S]{0,2500}?async \(\{ limit, offset, outcome_filter, detail, response_format \}\)/);
|
|
6390
|
+
assert.ok(sessionListBlock, "v4.2.0 / session_list: handler must expose bounded pagination inputs.");
|
|
6391
|
+
assert.ok(serverSrc.includes("const SESSION_LIST_DEFAULT_LIMIT = 25"), "v4.2.0 / session_list: default limit must stay bounded for stdio transports.");
|
|
6392
|
+
assert.ok(serverSrc.includes("const SESSION_LIST_MAX_LIMIT = 100"), "v4.2.0 / session_list: max limit must cap oversized pages.");
|
|
6393
|
+
assert.ok(serverSrc.includes("SessionListOutcomeFilterSchema"), "v4.2.0 / session_list: outcome_filter schema must remain wired.");
|
|
6394
|
+
assert.ok(serverSrc.includes("summarizeSessionForList"), "v4.2.0 / session_list: default list output must stay summary-based.");
|
|
6395
|
+
assert.ok(serverSrc.includes("pagination: {"), "v4.2.0 / session_list: response must surface pagination metadata.");
|
|
6396
|
+
const runtimeSmokeSrc = fs.readFileSync(path.join(process.cwd(), "scripts", "runtime-smoke.ts"), "utf8");
|
|
6397
|
+
assert.ok(runtimeSmokeSrc.includes('callTool("session_list"'), "v4.2.0 / session_list: runtime-smoke must exercise bounded session_list.");
|
|
6398
|
+
console.log("[smoke] session_list_bounded_pagination_test: PASS");
|
|
6399
|
+
}
|
|
6400
|
+
{
|
|
6401
|
+
const serverSrc = fs.readFileSync(path.join(process.cwd(), "src", "mcp", "server.ts"), "utf8");
|
|
6402
|
+
const cancelJobBlock = serverSrc.match(/"session_cancel_job"[\s\S]{0,2600}?server\.registerTool\(\s*"session_recover_interrupted"/);
|
|
6403
|
+
assert.ok(cancelJobBlock, "v4.2.0 / session_cancel_job: smoke must find the cancel-job handler block.");
|
|
6404
|
+
const cancelJobSrc = cancelJobBlock?.[0] ?? "";
|
|
6405
|
+
assert.ok(/if \(!jobs\.length\) \{[\s\S]{0,500}?requested:\s*false[\s\S]{0,500}?no_running_job_matched/.test(cancelJobSrc), "v4.2.0 / session_cancel_job: no active job must return requested=false/no_running_job_matched.");
|
|
6406
|
+
assert.ok(!/if \(!jobs\.length\) \{[\s\S]{0,300}?markCancelled/.test(cancelJobSrc), "v4.2.0 / session_cancel_job: no active job must not terminal-abort the whole session.");
|
|
6407
|
+
const runtimeSmokeSrc = fs.readFileSync(path.join(process.cwd(), "scripts", "runtime-smoke.ts"), "utf8");
|
|
6408
|
+
assert.ok(runtimeSmokeSrc.includes("runtime_smoke_no_active_job"), "v4.2.0 / session_cancel_job: runtime-smoke must exercise the no-active-job path.");
|
|
6409
|
+
assert.ok(/assert\.equal\(\s*noJobCancelState\.outcome,\s*undefined/.test(runtimeSmokeSrc), "v4.2.0 / session_cancel_job: runtime-smoke must assert no-job cancellation stays non-terminal.");
|
|
6410
|
+
console.log("[smoke] session_cancel_job_no_active_job_test: PASS");
|
|
6411
|
+
}
|
|
6412
|
+
{
|
|
6413
|
+
const serverSrc = fs.readFileSync(path.join(process.cwd(), "src", "mcp", "server.ts"), "utf8");
|
|
6414
|
+
assert.ok(serverSrc.includes("function sessionInitMarkdown"), "v4.2.0 / session_init: markdown renderer must exist.");
|
|
6415
|
+
assert.ok(/response_format === "markdown"\s*\?\s*textResult\(sessionInitMarkdown\(meta\), "markdown"\)/.test(serverSrc), 'v4.2.0 / session_init: response_format="markdown" must not fall through to JSON.stringify.');
|
|
6416
|
+
const runtimeSmokeSrc = fs.readFileSync(path.join(process.cwd(), "scripts", "runtime-smoke.ts"), "utf8");
|
|
6417
|
+
assert.ok(runtimeSmokeSrc.includes('callToolText("session_init"'), "v4.2.0 / session_init: runtime-smoke must exercise markdown session_init.");
|
|
6418
|
+
console.log("[smoke] session_init_markdown_response_test: PASS");
|
|
6419
|
+
}
|
|
6362
6420
|
// v2.6.1 NOTE: smoke coverage for `peer.fallback.budget_blocked` and
|
|
6363
6421
|
// `peer.moderation_recovery.budget_blocked` is intentionally NOT
|
|
6364
6422
|
// included. These two gates use the same arithmetic shape as preflight
|