feat(server): REST endpoints for project next/standup/changelog + WebMCP wiring (TASK-1894)#791
Merged
Merged
Conversation
Adds GET /workspaces/{ws}/next, /standup, /changelog — session-authed
reads mirroring `pad project next|standup|changelog --format json`,
reusing buildDashboardResponse + store.ListItems so the browser
WebMCP surface stops returning "not available" for these catalog
actions (TASK-1894). Cross-references the MCP HTTP transport's
existing dispatchProjectNext/Standup/Changelog (dispatch_http_slice4.go)
with KEEP IN SYNC comments at both sites, since this is now a third
reproduction of the same reshaping contract pending a follow-up
consolidation.
Adds client.ts next()/standup()/changelog() methods and replaces the three "not available in the browser" dispatch.ts stubs with real handlers now that the backend endpoints exist (TASK-1894). Extracts DashboardSuggestion as a shared type and adds StandupResponse / ChangelogResponse types mirroring the Go response shapes.
…x R1) standup/changelog's own item-list scoping used visibleCollectionIDs, which has no bearer gate: a platform admin authenticated via a bearer token (PAT/CLI/OAuth) who is only a restricted member of a workspace got the unrestricted admin view instead of being scoped to their real membership. Adds bearerAwareVisibleCollectionIDs, mirroring reportVisibleCollections' existing BUG-1616/1617 gate, and switches projectIntelVisibility onto it while preserving its item-level grant handling (which reportVisibleCollections deliberately drops for aggregate reports). buildDashboardResponse (and therefore /next, and standup's blockers/ suggested_next sections) is intentionally left ungated in this change — gating it would break next's parity with dashboard.suggested_next and diverge it from the CLI and MCP siblings. The resulting asymmetry is documented inline pending a follow-up fix to buildDashboardResponse itself.
Replaces the textual placeholder ("the visibleCollectionIDs bearer-gate
bug filed from TASK-1894 review") with the actual bug number now that
it's been filed. Comment-only change, no behavior difference.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WebMCP Phase 3c (TASK-1894): the catalog actions
pad_project.next/.standup/.changeloghad no REST endpoint, so the browser WebMCP dispatcher returned honest "not available in the browser" errors. This adds three session-authed GET endpoints under the existing/workspaces/{slug}access-controlled group and wires the browser surface to them:GET /workspaces/{slug}/next— bare array, parity withdashboard.suggested_next(the CLI's exact contract post BUG-987)GET /workspaces/{slug}/standup?days=N(default 1)GET /workspaces/{slug}/changelog?days=N&since=YYYY-MM-DD&parent=REF(default 7; silent since-wins matching both siblings)Frontend:
client.tsgets top-levelnext()/standup()/changelog()methods;dispatch.tsHANDLERS replace the honest-error stubs; new TS types mirror the Go response shapes (extractingDashboardSuggestionalso fixed its previously missingitem_reffield).The third-sibling problem (deliberate)
These handlers are the third reproduction of this reshaping contract, alongside the CLI (
cmd/pad/main.go) and the MCP HTTP dispatcher (internal/mcp/dispatch_http_slice4.go) — the latter exists only because these endpoints didn't. All three sites now carry KEEP IN SYNC cross-references (storetest-mirror precedent). TASK-1916 (filed, blocked by this PR) consolidates the MCP dispatcher onto these endpoints and deletes its custom reshaping.Deliberate semantics, pinned by tests: days is lenient (absent/malformed/≤0 → default, matching both siblings and the REST convention for
depth/window); malformedsince→ 400 (matching the CLI's hard error); parent filter matches ref/UUID/title case-insensitively via enriched parent fields (usingresolveParentFilterinstead would have silently dropped title matching vs both siblings).Review
2+ codex rounds, rotated framing. R1 (plain) caught a real ACL finding: the visibility helper reproduced the ungated
visibleCollectionIDsadmin bypass, so a bearer-authed platform admin who is only a restricted member would see unfiltered results. Investigation showed that pattern is pre-existing and pervasive (dashboard/bootstrap/items/graph all ungated on main;reportVisibleCollectionsis the one bearer-aware exception) — filed as BUG-1917. Fix in eaaef80, scoped to what this PR owns: standup's direct queries and all of changelog get the bearer-aware gate (mirroringreportVisibleCollections, keeping item-grant granularity);nextand standup's dashboard-derived sections keep dashboard parity and inherit BUG-1917's resolution (asymmetry documented in the file header). The regression test was revert-verified (fails on the ungated code). R2 (cross-surface parity lens) confirmed no divergence in field names, day defaults, since precedence, terminal-status ordering, per-status best-effort behavior, group ordering, or limit values; its only two findings were restatements of the documented-deliberate scoping decisions from R1's fix. Converged.Test plan
go test ./...(SQLite) — all green, 14 new endpoint tests incl. bearer-admin scoping regressionmake test-pg— full suite green (dual-driver mandatory: endpoints read the store)make lint— 0 issuesnpm test(109/109) /npm run check/npm run build— greenRefs: TASK-1894, TASK-1916, BUG-1917, TASK-1893
https://claude.ai/code/session_01CL1pBjNpPUX6SWkuAuYXHS