codeloop-mcp-server 0.1.61 → 0.1.63

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,EAqE1C,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,EA+E1C,CAAC"}
@@ -92,9 +92,17 @@ export const CRITICAL_FLOORS = [
92
92
  min_version: "0.1.60",
93
93
  reason: "Deep internal verification (code + backend + terminal) — pre-0.1.60 CodeLoop was almost entirely an EXTERNAL UI/UX checker: the only internal checks were build_passes, required_tests_pass, zero_critical_issues and (Flutter-only) `flutter analyze`; the Node runner literally just ran `npm test`. Type errors that the build tolerated, lint errors, untested changed lines, backend 500s, schema drift, broken API contracts, and runtime stack traces logged behind a 200 OK all reached ready_for_review unchallenged. 0.1.60 adds a deep INTERNAL verification layer as six applicable-or-n/a blocker gates that activate only when relevant to the stack (a missing analyzer / backend / ORM yields n/a, never a false-positive fail): static_analysis_passes (tsc / eslint / ruff / mypy / cargo clippy / dotnet format / flutter analyze — errors block, warnings don't), code_coverage_threshold (changed-LINE coverage scored against THIS cycle's git diff via lcov/cobertura, default 70%), backend_smoke_evidence (auto-detect + start the server as a managed subprocess with guaranteed teardown, wait for health 2xx / ready-log, probe routes, block on any 5xx), api_contract_evidence (validate probed routes against the OpenAPI/Swagger schema), db_schema_evidence (EF / Django / Alembic / Prisma / Rails migration-drift check), and runtime_log_clean_evidence (scan the backend/app/console logs for unhandled exceptions / fatal lines / 5xx even when the HTTP response was 2xx). codeloop_init_project now auto-detects + writes the `backend` config block (ASP.NET / Express / Nest / FastAPI / Django / Flask / Rails / Spring), codeloop_diagnose gains evidence-driven classifiers (typecheck_error / lint_error / coverage_gap / backend_5xx / runtime_exception / db_schema_drift / api_contract_violation), and codeloop_generate_dev_report documents the new evidence. Works across macOS / Windows / Linux and Cursor / Claude Code.",
94
94
  },
95
+ {
96
+ min_version: "0.1.62",
97
+ reason: "0.1.60/0.1.61 dotnet static-analysis FALSE-POSITIVE blocker — the new static_analysis_passes gate ran bare `dotnet format --verify-no-changes` with no solution target, so on a workspace with multiple .sln files (e.g. PhotometryDB.sln + PhotometryDB-Dev.sln) it CRASHED with an ambiguity error ('Specify which project or solution file to use…'); the non-zero exit was then promoted to a blocking 'error', and diagnose mislabeled the format-log crash as a `dotnet build` ambiguity even though the build itself passed. Even with a single solution, the DEFAULT `dotnet format` also runs analyzers, so pre-existing analyzer WARNINGS (e.g. CA1416 platform-compatibility) made it exit non-zero with zero real style issues — again wrongly blocking ready_for_review. 0.1.62 fixes the false positive three ways: (1) the dotnet-format check now reuses pickDotnetTarget (honoring config.dotnet.solution and the same multi-.sln heuristic the build uses) so it never crashes on ambiguity — and skips as n/a when no target can be resolved instead of running bare; (2) it is scoped to `dotnet format whitespace` to exclude analyzer diagnostics like CA1416 entirely; (3) `dotnet format` drift is recorded as a NON-BLOCKING warning (formatting is not a correctness blocker — the build gate already catches real errors), and the reconcile() exit-code heuristic no longer promotes a warnings-explained non-zero exit to an error (also fixes a latent `flutter analyze` warnings-only false positive). The misleading diagnose hint that said `dotnet_target` now correctly says `dotnet.solution`.",
98
+ },
95
99
  {
96
100
  min_version: "0.1.61",
97
101
  reason: "0.1.60 could CRASH THE ENTIRE MCP SERVER on a warm npx cache — backend_runtime.js (new in 0.1.60) statically imported @codelooptech/shared/init/detect-backend, a submodule first shipped in shared@0.1.30, but both codeloop-mcp-server and codeloop only pinned `@codelooptech/shared: ^0.1.22`. So npx could pair mcp-server 0.1.60 with an OLDER cached shared (0.1.22–0.1.29) that lacks detect-backend.js, and the static import threw ERR_MODULE_NOT_FOUND at module-load time, taking down index -> verify -> backend_runtime before any tool could run (the same class of stale-cache skew the 0.1.53 floor first patched for rules-version.js, reintroduced when the dep floor wasn't raised alongside the new submodule). 0.1.61 fixes it durably two ways: (1) raises the @codelooptech/shared dependency floor to ^0.1.30 in BOTH codeloop-mcp-server and codeloop so a fresh resolve can never pick a shared missing the file, and (2) makes detect-backend a LAZY, GUARDED dynamic import — if the submodule can't be loaded for any reason, backend auto-detection degrades to n/a (backend gates skip) instead of crashing the server, so no future shared-submodule addition can ever hard-crash CodeLoop again. Users on a broken 0.1.60 install must clear the npx cache (delete %LocalAppData%/npm-cache/_npx on Windows or ~/.npm/_npx on macOS/Linux, or run `npx clear-npx-cache`) and relaunch so npx fetches 0.1.61.",
98
102
  },
103
+ {
104
+ min_version: "0.1.63",
105
+ reason: "Out-of-app confirm/alert modal was NEVER detected (recurrence) — 0.1.54/0.1.55/0.1.57 only hardened FILE dialogs; a plain Yes/No confirmation MessageBox raised by clicking a button (e.g. Photometry-DB 'Delete TEMP PCB Test Range') stayed invisible to the detector and blocked the journey. detectWindowsModal only flagged a window when UIA reported IsModal=true AND the dialog TITLE contained the app name, OR the title matched a file-dialog pattern — but a WPF/WinForms MessageBox is a SEPARATE top-level #32770 window whose caption is 'Confirm'/'Delete'/the app name and whose UIA IsModal flag is frequently FALSE, so it slipped through every pass (is_modal_present:false). No F4 directive fired and the agent kept clicking the now-blocked button beneath it, then mis-read 'click missed' and looped. A second bug compounded it: win_ui_inspect / win_ui_automate located the app window with an EXACT NameProperty match, so app_name 'Photometry DB' never matched the live title 'PhotometryDB - Professional…' (no space) and every inspect returned 'App window not found', forcing coordinate guessing. 0.1.63 ships H12: (1) the Windows modal probe now collects each window's ProcessId and resolves the app's own pid(s) + main-window handle(s), and flags any app-OWNED secondary top-level window carrying a dialog signal (modal flag / #32770 or dialog class / confirm-or-alert title) as the modal regardless of its caption — the title- and IsModal-independent ownership signal that finally catches in-process MessageBox confirms; (2) classifyModalKind now treats an ambiguous #32770 as `confirm` (routes to codeloop_handle_modal for an agent decision) instead of `file_dialog` (auto-Escape), while a file-TITLED #32770 stays file_dialog; (3) codeloop_handle_modal with decision confirm/cancel now INVOKES the matching Yes/OK/Save/Delete or No/Cancel button on the dialog directly via UIA and re-detects to confirm it cleared, so a destructive Yes/No box no longer depends on which button is the Enter/Escape default; (4) buildUiaAppElementLookup + a whitespace-insensitive process-lookup fallback make win_ui_inspect / win_ui_automate / screenshot / window-bounds resolve the app window even when app_name differs from the live title by spaces or a suffix, or doesn't embed it at all (owning-process match).",
106
+ },
99
107
  ];
100
108
  //# 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,g3CAAg3C;KACn3C;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,gwEAAgwE;KACnwE;CACF,CAAC"}
package/dist/index.js CHANGED
@@ -3847,7 +3847,7 @@ Wait 1-2 seconds between interactions so video frames capture state changes.`, {
3847
3847
  if (!autoClosed) {
3848
3848
  const killHint = isStuckFileDialog
3849
3849
  ? `CodeLoop already attempted the multi-strategy close ladder and it FAILED — call codeloop_kill_modal_window with hwnd ${detection.hwnd ?? "(from codeloop_handle_modal)"} now. `
3850
- : `Stop sending raw clicks / Escape keystrokes against it and call codeloop_handle_modal with decision: "cancel" or "dismiss" the multi-strategy ladder (Escape Alt+F4 UIA Invoke "Close" EndDialog) handles file dialogs the keystroke path cannot. If codeloop_handle_modal returns escalation: "kill_window_required", call codeloop_kill_modal_window with the returned hwnd. `;
3850
+ : `Stop sending raw clicks / keystrokes against it. Call codeloop_handle_modal with the decision the planned journey needs — "confirm" to proceed (approve the delete / save / overwrite), "cancel" to abort, or "dismiss" to close. CodeLoop clicks the matching Yes/OK/Save/Delete or No/Cancel button on the dialog directly via UIA (0.1.63 H12), so it no longer depends on which button happens to be the Enter/Escape default. If codeloop_handle_modal returns escalation: "kill_window_required", call codeloop_kill_modal_window with the returned hwnd. `;
3851
3851
  modalPersistenceDirective =
3852
3852
  `\n\n[CodeLoop F4] HARD: A ${detection.modal_kind ?? "modal"} dialog (${desc}) is STILL present after this interaction ` +
3853
3853
  `(${consecutive} consecutive interactions have not cleared it). ` +
@@ -4054,6 +4054,44 @@ Returns: detected modal description + result of the chosen decision.`, {
4054
4054
  `Continue with codeloop_interact against the application.`,
4055
4055
  };
4056
4056
  }
4057
+ // 0.1.63 H12 — deterministic confirm/cancel for desktop dialogs
4058
+ // (Win32 MessageBox / WPF confirm — the Photometry-DB delete-confirm
4059
+ // class). Walk the dialog's buttons via UIA and INVOKE the affirmative
4060
+ // (confirm ⇒ Yes/OK/Save/Delete/Continue) or negative (cancel ⇒
4061
+ // No/Cancel/Discard) button by name, then re-detect to confirm it
4062
+ // cleared. This avoids depending on which button is the keystroke
4063
+ // default — on a destructive Yes/No box the default is often "No", so
4064
+ // a blind Enter/Escape would silently abort the action. `dismiss`
4065
+ // stays on the Escape path below; an unmatched custom dialog falls
4066
+ // through to the keystroke fallback too.
4067
+ if (detection.target_type === "desktop" &&
4068
+ (params.decision === "confirm" || params.decision === "cancel")) {
4069
+ const { invokeDialogDecisionButton } = await import("./runners/modal_close_strategies.js");
4070
+ const invoke = await invokeDialogDecisionButton({
4071
+ decision: params.decision,
4072
+ hwnd: detection.hwnd,
4073
+ cwd,
4074
+ });
4075
+ if (invoke.ok) {
4076
+ await new Promise((r) => setTimeout(r, 400));
4077
+ const after = await detectModal({
4078
+ target_type: "desktop",
4079
+ app_name: params.app_name,
4080
+ cwd,
4081
+ config,
4082
+ });
4083
+ return {
4084
+ decision_taken: params.decision,
4085
+ detection,
4086
+ invoked_button: invoke.button,
4087
+ modal_cleared: !after.is_modal_present,
4088
+ next_step: after.is_modal_present
4089
+ ? `Clicked "${invoke.button ?? params.decision}" but a modal is STILL present (${after.modal_description ?? "unknown"}). It may be a stacked dialog — call codeloop_handle_modal again, or codeloop_kill_modal_window with hwnd="${after.hwnd ?? detection.hwnd ?? ""}" if it is stuck.`
4090
+ : `Clicked the "${invoke.button ?? params.decision}" button and the dialog cleared. Continue the journey with codeloop_interact.`,
4091
+ };
4092
+ }
4093
+ // No matching button found — fall through to the keystroke fallback.
4094
+ }
4057
4095
  // For confirm / cancel / dismiss we delegate to codeloop_interact
4058
4096
  // semantics by issuing a key press that maps to the right OS
4059
4097
  // convention. dismiss ⇒ Escape, cancel ⇒ Escape (most modals