Skip to content

feat(v2.0.0-rc2): close 3 endpoint-coverage gaps + 1 dead route (retry / un-duplicate / app-overlay)#39

Merged
aksOps merged 1 commit into
mainfrom
feat/v2-rc2-close-endpoint-gaps
May 16, 2026
Merged

feat(v2.0.0-rc2): close 3 endpoint-coverage gaps + 1 dead route (retry / un-duplicate / app-overlay)#39
aksOps merged 1 commit into
mainfrom
feat/v2-rc2-close-endpoint-gaps

Conversation

@aksOps
Copy link
Copy Markdown
Contributor

@aksOps aksOps commented May 16, 2026

Summary

Post-rc1 endpoint audit found the React UI was behind the backend on 3 features + one route was defined but unmounted in production. rc2 closes all four and corrects the parity-doc overclaim that flagged this gap initially.

Gap Endpoint(s) rc1 state rc2 state
A POST /sessions/{id}/retry + GET /sessions/{id}/retry/preview Retry button was a local refresh() no-op useRetryPreview drives enabled/reason; ConfirmModal POSTs and drains SSE
B GET /apps/{app}/ui-views parity doc claimed "full"; code had no consumer useAppViews + <SelectedPanel> "App-specific views →" links filtered by applies_to
C POST /sessions/{id}/un-duplicate route defined in api_dedup.py but register_dedup_routes never called outside tests — dead in dist/app.py wired in build_app + <UnDuplicateModal> + button on <CanvasHead> (status==='duplicate'); regression test pins the mount
Doc docs/REACT_UI_PARITY.md overclaimed app-overlay full rc2 changelog at top; matrix 22 full / 2 partial / 2 deferred

Files

Backend (3 lines + regression test):

  • src/runtime/api.py (+5 / -1): register_dedup_routes(api_v1, store_provider=…)
  • tests/test_dedup_mounted_in_build_app.py (new): pins the mount

Frontend:

  • web/src/state/useRetryPreview.ts (new, 28 lines)
  • web/src/state/useAppViews.ts (new, 54 lines + filter helper)
  • web/src/modals/UnDuplicateModal.tsx (new, 124 lines)
  • web/src/canvas/CanvasHead.tsx (+18 / -4): retry prop + un-duplicate button
  • web/src/canvas/SessionCanvas.tsx (+62 / -3): retry/un-duplicate state + handlers + modals
  • web/src/monitors/SelectedPanel.tsx (+34 / -2): app-views section
  • web/package.json + web/src/App.tsx: bumped to 2.0.0-rc2

Docs:

  • docs/REACT_UI_PARITY.md: rc2 changelog + matrix updates

Tests (new, 16 cases):

  • web/tests/component/UnDuplicateModal.test.tsx (5)
  • web/tests/component/useAppViews.test.ts (5)
  • web/tests/component/useRetryPreview.test.tsx (3)

Bundles:

  • dist/app.py, dist/apps/*.py regenerated (HARD-08)

Verification (locally)

  • uv run pytest -x1336 passed / 8 skipped (with ASR_WEB_DIST=/tmp/empty; the unrelated test_unknown_endpoint_returns_404_envelope is fragile when web/dist exists on disk — pre-existing flake, not introduced here)
  • cd web && npm run typecheck → clean
  • npm run test:unit48 files / 196 tests (was 45/183 on rc1; +3/+13 from rc2 tests)
  • npm run build → 321 kB raw / 98 kB gzip (under 400/130 budget)
  • npm run lint → 0 errors, 2 acceptable react-refresh warnings
  • npm run check:size → ✓
  • Playwright vs https://clm.randomcodespace.dev (Caddy → uvicorn:37777 running this branch):
    • new-session.live.spec.tsPASS
    • retry-after-error.live.spec.tsPASS
    • hitl-approve.live.spec.tsSKIP (config-dependent; HITL pause doesn't trigger in smoke backend)

Test plan

  • CI Lint / Type-check / Test / Sonar green
  • CI Web CI (.github/workflows/web.yml) green
  • After merge: tag v2.0.0-rc2 on main

Notes

  • useRetryPreview translates 4xx into {retry: false, reason: <msg>} (non-throwing) so the panel doesn't crash on unknown ids.
  • The un-duplicate endpoint accepts an optional {retracted_by, note} body; UI sends note=null when the textarea is empty.
  • App-overlay filtering parses tool:NAME against the {tool}@{ts} selected-ref shape used by useSetSelected.

🤖 Generated with Claude Code

@aksOps aksOps force-pushed the feat/v2-rc2-close-endpoint-gaps branch from 8490cec to d2d287a Compare May 16, 2026 12:20
@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 16, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​vitest/​coverage-v8@​3.2.4991007299100

View full report

@aksOps aksOps force-pushed the feat/v2-rc2-close-endpoint-gaps branch from d2d287a to a56ccb9 Compare May 16, 2026 12:21
The post-rc1 endpoint audit found that the React UI was behind the
backend on 3 features and that one route (`/un-duplicate`) was defined
but never mounted on the production app (only on a test fixture). rc2
closes all four.

Gap A — retry pipeline (rc1: partial, rc2: full)
  - web/src/state/useRetryPreview.ts: GET /sessions/{sid}/retry/preview
    drives the Retry button's enabled state + tooltip reason.
  - web/src/canvas/CanvasHead.tsx: optional retry={enabled, reason} prop;
    legacy callers fall back to the status==='error' heuristic.
  - web/src/canvas/SessionCanvas.tsx: ConfirmModal showing the preview
    reason; on confirm, POSTs /sessions/{sid}/retry and drains the SSE
    body so the long-lived useSessionFull SSE picks up the new events.

Gap B — app-overlay views (rc1: docs lied "full", code unwired; rc2: real)
  - web/src/state/useAppViews.ts: GET /apps/{app}/ui-views + filter
    helper that honours `always`, `agent:NAME`, `tool:NAME` scopes.
  - web/src/monitors/SelectedPanel.tsx: "App-specific views →" section
    rendered when a selection matches at least one view.

Gap C — un-duplicate (rc1: dead route + no UI; rc2: full)
  - src/runtime/api.py: register_dedup_routes(api_v1, store_provider=…)
    wired in build_app so /api/v1/sessions/{id}/un-duplicate is live in
    dist/app.py (was only live in tests).
  - src/runtime/api_dedup.py: parameter widened to Union[FastAPI,
    APIRouter] so the mount on the api_v1 router type-checks under
    pyright (HARD-03).
  - web/src/modals/UnDuplicateModal.tsx: confirm + free-text note +
    error envelope rendering.
  - web/src/canvas/CanvasHead.tsx: Un-duplicate button shown only when
    status==='duplicate' and onUnDuplicate is provided.
  - web/src/canvas/SessionCanvas.tsx: modal mount + handler.
  - tests/test_dedup_mounted_in_build_app.py: regression test pins the
    route into build_app so it can't drift dead again.

Other:
  - web/package.json + web/src/App.tsx: bumped to 2.0.0-rc2.
  - web/package.json: added @vitest/coverage-v8 devDep (web.yml runs
    `npx vitest run --coverage`).
  - web/.gitignore: coverage/ (vitest's lcov report).
  - .github/workflows/web-e2e.yml: corrected boot to
    `uvicorn runtime.api:get_app --factory` (the module exports a
    factory, not an `app` instance); readiness probe switched to
    `/health` (the previous `/api/v1/ui/hints` path was wrong).
  - docs/REACT_UI_PARITY.md: rc2 changelog at the top; matrix now shows
    22 full (was 21) with 2 partial (was 3) and 2 deferred. Explicitly
    notes the rc1 app-overlay overclaim.
  - dist/* regenerated (HARD-08).

Verified locally:
  - uv run pyright src/runtime → 0 errors
  - ASR_WEB_DIST=/tmp/empty uv run pytest -x → 1336 passed / 8 skipped
  - cd web && npm run typecheck → clean
  - npm run test:unit → 48 files / 196 tests pass
  - npx vitest run --coverage → green
  - npm run build → 321 kB raw / 98 kB gzip (under 400/130 budget)
  - npm run lint → 0 errors, 2 acceptable warnings
  - Playwright vs https://clm.randomcodespace.dev (Caddy → uvicorn:37777
    running this branch): new-session.live PASS, retry-after-error.live
    PASS, hitl-approve.live SKIP.
@aksOps aksOps force-pushed the feat/v2-rc2-close-endpoint-gaps branch from a56ccb9 to d33ca27 Compare May 16, 2026 12:24
@sonarqubecloud
Copy link
Copy Markdown

@aksOps aksOps merged commit 2efde89 into main May 16, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant