codeloop-mcp-server 0.1.70 → 0.1.72

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.
@@ -1 +1 @@
1
- {"version":3,"file":"critical_floors.d.ts","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EAkH1C,CAAC"}
1
+ {"version":3,"file":"critical_floors.d.ts","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EA4H1C,CAAC"}
@@ -116,6 +116,10 @@ export const CRITICAL_FLOORS = [
116
116
  min_version: "0.1.66",
117
117
  reason: "codeloop_verify could HANG FOREVER on Flutter projects — the three primary Flutter runners (flutter analyze, flutter test, flutter test integration_test/) all called runCommand WITHOUT a timeout, so any one of them could block the whole verify (and the MCP response, which only returns when the entire sequential pipeline finishes) indefinitely. The dominant trigger: `flutter test integration_test/` is launched with NO `-d` device flag and NO device probe, so when no emulator/simulator/device is booted the Flutter CLI waits forever for one — the user saw verify 'hang at here for 10 mins' on a fresh Flutter project with no device. `flutter analyze` could likewise stall on an implicit `pub get` over a slow/blocked network, and a brand-new machine could even block on Flutter's first-run analytics consent prompt. (The later deep-internal duplicates static_analysis `flutter analyze` and coverage `flutter test --coverage` already had 4-/5-min caps, but they never ran because the un-timed primary trio came first.) 0.1.66 fixes it: every primary Flutter runner now passes a wall-clock timeout (analyze 4 min, test 5 min, integration_test 6 min) — on expiry runCommand SIGKILLs and returns exit_code 124, which the runner surfaces as an explicit FAILED result with a clear note ('killed after N min … waiting on a cold emulator/device or a stalled pub get — boot a device or run flutter pub get, then re-verify') instead of a silent freeze — and all three now run with CI=true so Flutter never blocks on its first-run analytics/consent prompt. CRUCIALLY, 0.1.66 also fixes the runCommand watchdog itself: commands were spawned via `shell: true`, so killing the direct child only reaped the `/bin/sh -c …` wrapper, NOT the grandchild it forked (flutter is a bash script that spawns dart) — the grandchild kept the stdout pipe open so the `close` event never fired and the promise hung forever, defeating the timeout. The watchdog now makes the timed child a process-group leader (detached on POSIX) and SIGKILLs the ENTIRE group via process.kill(-pid) (taskkill /T /F on Windows), with a 1.5s safety net that force-settles the promise even if `close` is somehow withheld. Without this, every timeout added above would have been silently ineffective on real Flutter (and any shell-wrapped) commands.",
118
118
  },
119
+ {
120
+ min_version: "0.1.71",
121
+ reason: "codeloop_verify could still HANG for several MINUTES on a Flutter (and any compact-reporter) test suite that hangs MID-RUN — the 0.1.69/0.1.70 completion-settle watchdog could NOT catch it. Real case (WedCheese, on 0.1.70): one test isolate passed its assertions but leaked a Timer/StreamController/Firebase listener, so the isolate never exited and the WHOLE `flutter test --coverage` run froze at `+24 -5: …` while the compact reporter's elapsed clock ticked 00:16 → 05:54. The suite NEVER printed its end-of-run marker (`All tests passed!`/`Some tests failed.`), so the completion-settle watchdog never armed; and the ticking clock is CONTINUOUS output, so the silence-based grace never tripped either — only the 6-min hard cap eventually freed it (a multi-minute freeze the agent/user reads as a hang, and usually interrupts first). 0.1.71 adds a PROGRESS-STALL watchdog to runCommand: it tracks the reporter's progress signature with the volatile clock stripped (Flutter compact `+P -F ~S: desc`); while that signature is FROZEN it counts down a grace and force-closes the process tree, but ANY change (a test passed/failed, a new test started) RESETS the grace so a legitimately slow single test only delays, never falsely kills. Once the end-of-run marker prints it disables itself and hands off to the silence-based settle watchdog, so legitimate end-of-run work with frozen counts (e.g. `--coverage` writing lcov) is never killed. Wired into `flutter test --coverage` and `flutter test integration_test/` with a 90s stall grace (well above between-file compile pauses and Flutter's 30s default per-test timeout, a fraction of the 6-min cap). A mid-run stall is force-closed in ~90s with PARTIAL results, the suite is marked failed (never a false pass), and verify pushes a `[CodeLoop ASK]` directive telling the agent to ask the user (Y/N) to dispose the leaked resource in tearDown() or re-run with skip_tests:true. Anyone below 0.1.71 still risks a multi-minute verify freeze on a Flutter suite that hangs before it finishes.",
122
+ },
119
123
  {
120
124
  min_version: "0.1.70",
121
125
  reason: "codeloop_verify could HANG INDEFINITELY on a hanging/leaky test suite for EVERY non-Flutter stack — the 0.1.66–0.1.69 fixes only ever covered Flutter. Pre-0.1.70, the generic/node runner (`npm test` → jest/vitest/mocha), the python (pytest/unittest/django), the rust (`cargo test`), the playwright, and the Maestro runners ALL called runCommand with NO timeout at all, and the native build runner ran `xcodebuild`, `gradle assembleDebug` + `gradle test`, and `dotnet build` + `dotnet test` untimed too. So a Node/Jest suite that leaks an open handle (a DB pool, socket, server, or unref-less setInterval — Jest's own 'did not exit one second after the test run' warning), a pytest non-daemon thread, a stuck Gradle daemon, a codesign/keychain prompt, or a hung Maestro device wait would block the WHOLE verify (and the MCP response) FOREVER. 0.1.70 makes verify hang-proof on every OS (Windows/macOS/Linux), every agent (Cursor/Claude Code), and every app type (website, Node, Python, Rust, native iOS/Android, Windows/macOS .NET, Flutter): (1) every test runner now has a hard wall-clock cap (10 min tests, 15 min native builds, 1 min probes) so a true hang is always BOUNDED, not infinite; (2) a SILENCE-BASED completion-settle watchdog (generalised from the Flutter fix) arms on each runner's end-of-run marker (jest 'Ran all test suites'/'Tests:', vitest 'Test Files', mocha 'N passing', node:test TAP, pytest's '=== N passed in ===', cargo 'test result:', dotnet 'Test Run Successful./Failed.') and force-closes the process tree once output goes QUIET for the grace — recovering the real pass/fail in ~30s instead of burning the full timeout. It RESETS the grace on every subsequent output chunk, so monorepo runs (turbo/nx/lerna that print one summary PER PACKAGE) are never killed mid-stream; only true post-completion silence trips it. The settle force-close now also engages the POSIX process group (previously only timeouts did), so a leaked grandchild (npm→node→jest, flutter→dart) is actually reaped instead of orphaned. (3) A new skip_tests control (per-call `skip_tests:true` on codeloop_verify, or persistent config.tests.run=false) runs every check EXCEPT the project's own test suite + coverage — for suites that are known-broken, leak, or are too slow to run every cycle — and crucially now reaches the NATIVE test suites embedded in the build runner (`gradle test`, `dotnet test`) too, while the build itself still runs. Skipping is HONEST: the required_tests_pass gate BLOCKS ready_for_review (a skipped suite can never silently produce a 'Verified by CodeLoop' result) unless explicitly waived via config.tests.waive_gate. (4) verify now distinguishes a TRUE timeout (exit 124 — pushes the agent to ASK the user Y/N to skip or fix) from an AUTO-RECOVERED leak (completed but didn't exit — an informational note telling the developer to dispose the resource in tearDown(), no skip needed). Anyone below 0.1.70 still risks an indefinite verify freeze on a non-Flutter hanging test suite.",
@@ -132,5 +136,9 @@ export const CRITICAL_FLOORS = [
132
136
  min_version: "0.1.67",
133
137
  reason: "Mobile real-device E2E + read-only audit mode + nested native builds — three gaps that left Flutter/native mobile and 'just-tell-me-the-problems' workflows underserved. (1) DEVICE-DRIVEN INTERACTIVE TESTING: 0.1.66 stopped `flutter test integration_test/` from hanging when no device was booted, but only via a 6-min timeout, and NOTHING ever pushed the agent to OPEN the Android emulator / iOS simulator the user actually tests on — so real interactive verification (typing in the app, exercising native channels) never happened. 0.1.67 adds a fast cross-platform device-readiness probe (adb devices / xcrun simctl list booted, each wrapped in the 0.1.66 process-tree-killable 15s timeout, degrading to 'no device' when the CLI is absent): the Flutter integration runner now probes FIRST and, when nothing is booted, SKIPS the command (no 6-min stall) and returns a HARD directive with copy-paste commands telling the agent to boot an Android emulator AND/OR iOS simulator (and to exercise BOTH when the project targets both — the user uses Android + Xcode simulators); codeloop_start_recording runs the same probe for android_emulator/ios_simulator targets and attaches the open-simulator directive instead of failing cryptically inside adb/simctl. (2) ANALYZING IN-APP AI ANSWERS: codeloop_interact gains a `get_text` action (browser: Playwright textContent of a selector or the page body; android_emulator: uiautomator-hierarchy text extraction so the agent can read a Flutter/native AI chatbot's answer off a booted emulator without OCR; iOS: screenshot+vision) plus an `expect_contains` assertion, and the AI-prompt depth tip now instructs the agent to READ BACK and verify each chatbot answer instead of just submitting prompts — so 'type into the chatbox and analyze the AI's answer' is a first-class, evidence-logged flow. (3) READ-ONLY AUDIT MODE: when the user says 'do NOT modify my code, just list the problems', the agent can now set mode='audit' on codeloop_verify/diagnose/gate_check (persisted per session in .codeloop/agent_mode.json, also settable via config.agent_mode) — CodeLoop still runs every verification and returns the full findings, but its responses STOP pushing the auto-fix loop (no 'EXECUTE REPAIR TASKS NOW', no 'MANDATORY AUTO-FIX LOOP', no continue_fixing chase) and instead instruct the agent to present an audit report and stop, finally letting CodeLoop OBEY a no-modification request. ALSO in 0.1.67: native iOS/Android builds now discover NESTED project dirs — runNativeBuild walks up to 2 levels for ios/*.xcodeproj|*.xcworkspace and android/(app/)build.gradle(.kts) and builds in that dir (RN/Capacitor/monorepo layouts were DETECTED as xcode/android but then skipped with 'No project found'), and codeloop_capture_screenshot accepts target_type='android_emulator'|'ios_simulator' to capture the booted emulator/simulator via adb/simctl instead of the host desktop. Cross-platform: web verify+evidence works on Windows+macOS, Android on both, iOS on macOS (gracefully skipped off-Mac), Cursor and Claude Code identical.",
134
138
  },
139
+ {
140
+ min_version: "0.1.72",
141
+ reason: "codeloop_verify ran SILENT for minutes and looked frozen — so users INTERRUPTED it mid-build, orphaning gradle/gen_snapshot + flutter assemble processes. After the 0.1.71 mid-run-stall fix, the WedCheese hang was finally a real, BOUNDED long-running step (not a leak): a scope:'full' verify on a Flutter project also builds the native android/ host, and `gradle assembleDebug` triggers a CPU-intensive multi-arch AOT compile (gen_snapshot) that legitimately takes several minutes. But codeloop_verify is a SINGLE blocking MCP call that buffers all output and returns ONCE at the end — no progress is streamed — so the tool-call card sat silent past the 3-minute mark and the user reasonably read it as a freeze, hit cancel, and left orphaned native-build processes behind (which then contended for the next run). 0.1.72 streams live progress via MCP notifications/progress (rendered on Cursor's tool-call card since 1.7.39): a 10s heartbeat plus a per-phase boundary marker emit the CURRENT phase (e.g. 'Building Android app (gradle + AOT/gen_snapshot)'), elapsed mm:ss, and a rough ETA / honest 'still running (longer than expected)' once past the estimate — so even a 7-minute native build visibly keeps ticking instead of looking hung. The progress value is strictly monotonic per the MCP spec and the bar's total is clamped above elapsed so it never sticks at 100% before verify returns; the heartbeat interval is unref()'d and cleared on return so it can never hold the process open or fire against a stale token, and it only emits when the client requested progress (passed a progressToken) — otherwise verify behaves exactly as before. sendNotification is fire-and-forget and fully swallowed, so a transport hiccup can never fail or slow the verify itself. CROSS-CLIENT SAFETY: progress is gated per client — Cursor (and other spec-compliant clients: VS Code / Windsurf / Cline / generic SDK clients) get it, but Claude Code is explicitly EXCLUDED because as of 2026 it neither renders notifications/progress NOR tolerates it — emitting progress tears down its stdio transport and respawns the MCP server mid-run (anthropics/claude-code #47765 / #53617), and Claude Code DOES send a progressToken, so a naive 'honor the token' implementation would have BROKEN CodeLoop on Claude Code. progressClientDecision suppresses emission for any client whose name contains 'claude' (overridable via CODELOOP_PROGRESS=on|off), and runVerify never emits a terminal progress>=total notification and clears its heartbeat BEFORE returning, so progress can never race the tool response (the other half of the #47765 unknown-token hazard). Works identically on Windows/macOS/Linux for every app type (Windows/macOS .NET desktop, Flutter mobile, native iOS/Android, web) since the phase markers mirror the per-platform runner gating. Anyone below 0.1.72 either sees a silent multi-minute verify on slow native builds (Cursor) and is liable to interrupt it, or — had progress shipped without the client gate — would have hit transport crashes on Claude Code.",
142
+ },
135
143
  ];
136
144
  //# sourceMappingURL=critical_floors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"critical_floors.js","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,ufAAuf;KAC1f;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,4hBAA4hB;KACriB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,yvBAAyvB;KAClwB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,kxBAAkxB;KACrxB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,0/BAA0/B;KAC7/B;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,0iCAA0iC;KAC7iC;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,gqDAAgqD;KACnqD;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,uqDAAuqD;KAC1qD;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,w+EAAw+E;KAC3+E;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,88EAA88E;KACj9E;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,uiEAAuiE;KAC1iE;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,u/DAAu/D;KAC1/D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,k3DAAk3D;KACr3D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,oiDAAoiD;KACviD;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,g3CAAg3C;KACn3C;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,srFAAsrF;KACzrF;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,gwEAAgwE;KACnwE;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,84EAA84E;KACj5E;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,gwEAAgwE;KACnwE;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,g8FAAg8F;KACn8F;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,09DAA09D;KAC79D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,u4DAAu4D;KAC14D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,u/FAAu/F;KAC1/F;CACF,CAAC"}
1
+ {"version":3,"file":"critical_floors.js","sourceRoot":"","sources":["../../src/auth/critical_floors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,eAAe,GAAoB;IAC9C;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,ufAAuf;KAC1f;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,4hBAA4hB;KACriB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,yvBAAyvB;KAClwB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,kxBAAkxB;KACrxB;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,0/BAA0/B;KAC7/B;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,0iCAA0iC;KAC7iC;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,gqDAAgqD;KACnqD;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,uqDAAuqD;KAC1qD;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,w+EAAw+E;KAC3+E;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,88EAA88E;KACj9E;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,uiEAAuiE;KAC1iE;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,u/DAAu/D;KAC1/D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,k3DAAk3D;KACr3D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,oiDAAoiD;KACviD;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,g3CAAg3C;KACn3C;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,srFAAsrF;KACzrF;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,gwEAAgwE;KACnwE;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,84EAA84E;KACj5E;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,gwEAAgwE;KACnwE;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,s/DAAs/D;KACz/D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,g8FAAg8F;KACn8F;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,09DAA09D;KAC79D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,u4DAAu4D;KAC14D;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,u/FAAu/F;KAC1/F;IACD;QACE,WAAW,EAAE,QAAQ;QACrB,MAAM,EACJ,w+FAAw+F;KAC3+F;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA6lBA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEjD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAgmBA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEjD"}
package/dist/index.js CHANGED
@@ -608,20 +608,53 @@ Returns: structured report with pass/fail counts, artifact paths, and next-step
608
608
  tasks_completed: z.array(z.string()).optional().describe("0.1.52 C5 — free-text titles of the tasks the agent claims to have completed in this code change. Cross-checked against the change manifest produced by C1: every claim should map to >= 1 manifest entry and every manifest entry should map to >= 1 claim. Mismatches surface as warnings in the verify response and feed the change_coverage_evidence gate (C3)."),
609
609
  skip_tests: z.boolean().optional().describe("0.1.70 — Run every check EXCEPT the project's own test suite (flutter test / npm test / pytest / cargo test / playwright / maestro) and coverage. Use ONLY with the user's consent — when their suite is known-broken, hangs (a leaked Timer/StreamController/listener keeps the process alive after assertions pass), or is too slow to run every cycle. Analysis, build, backend, observability, screenshots, and design comparison still run. The required_tests_pass gate then BLOCKS ready_for_review until tests run (skip_tests:false) OR config.tests.waive_gate:true is set — so a skipped suite can never silently produce a 'Verified by CodeLoop' result. When a prior verify reports a hung/force-closed test runner ([CodeLoop ASK] note), ASK the user Y/N before setting this."),
610
610
  mode: z.string().optional().describe(AGENT_MODE_PARAM_DESC),
611
- }, async (params) => {
611
+ }, async (params, extra) => {
612
612
  const cwd = resolveCwd(params);
613
613
  const explicitDir = params.project_dir || params.workspace_root;
614
614
  const cfg = explicitDir ? loadConfig(explicitDir) : config;
615
615
  const auditMode = resolveAgentMode({ cwd, paramMode: params.mode, configMode: cfg.agent_mode }) === "audit";
616
+ // 0.1.72 — Stream live progress so a multi-minute verify (native AOT
617
+ // build, slow test suite) doesn't look frozen in the chat. Cursor renders
618
+ // notifications/progress.message on the tool-call card. We only emit when
619
+ // (a) the client requested progress (it passed a progressToken in the
620
+ // request _meta) AND (b) the client is SAFE to stream to — Claude Code is
621
+ // NOT (it neither renders progress nor tolerates it: emitting tears down
622
+ // its stdio transport and respawns the server — anthropics/claude-code
623
+ // #47765 / #53617 — which would BREAK CodeLoop mid-run). progressClientDecision
624
+ // gates this (CODELOOP_PROGRESS=on|off overrides). When suppressed this is a
625
+ // no-op and verify behaves exactly as before; sendNotification is otherwise
626
+ // fire-and-forget and swallowed so a transport hiccup never fails/slows verify.
627
+ const progressToken = extra?._meta?.progressToken;
628
+ let clientName;
629
+ try {
630
+ clientName = server.server.getClientVersion?.()?.name;
631
+ }
632
+ catch {
633
+ clientName = undefined;
634
+ }
635
+ let lastProgress = 0;
616
636
  const result = await withAuth(async () => {
617
- const { runVerify } = await import("./tools/verify.js");
637
+ const { runVerify, formatVerifyProgress, progressClientDecision } = await import("./tools/verify.js");
638
+ const progressSafe = progressClientDecision(clientName, process.env.CODELOOP_PROGRESS);
639
+ const onProgress = !progressSafe || progressToken === undefined
640
+ ? undefined
641
+ : (u) => {
642
+ const { progress, total, message } = formatVerifyProgress(u, lastProgress);
643
+ lastProgress = progress;
644
+ void extra
645
+ .sendNotification({
646
+ method: "notifications/progress",
647
+ params: { progressToken, progress, total, message },
648
+ })
649
+ .catch(() => { });
650
+ };
618
651
  const input = {
619
652
  scope: params.scope,
620
653
  platform: params.platform,
621
654
  tasks_completed: params.tasks_completed,
622
655
  skip_tests: params.skip_tests,
623
656
  };
624
- const output = await runVerify(input, cfg, cwd);
657
+ const output = await runVerify(input, cfg, cwd, onProgress);
625
658
  await trackUsage(apiKey, "verification_run");
626
659
  return output;
627
660
  }, { tool: "codeloop_verify", cwd, input: params });