Console UX: eliminate CLI dependency, fix project-recovery dead end, never show an empty dashboard#1
Open
archdex-art wants to merge 3 commits into
Open
Conversation
- Setup tab (new default landing view after login/signup): shows the current project's real ID + API key + a ready-to-paste Python SDK snippet and curl healthcheck, so 'how do I use this outside the browser' never requires the CLI or re-deriving credentials. - MCP Registry: in-UI 'Register server' form posts directly to POST /v1/mcp/servers, replacing the 'agentmesh mcp register <manifest.yaml>' CLI-only requirement. - run.sh: one-command startup (docker compose up --build, health-wait on the Query API, then opens the Console). 'run.sh stop'/'reset' for teardown. Verified live end-to-end in a real browser: sign up -> Setup screen shows real project_id/api_key/snippet -> Registry tab registers a real MCP server with no CLI calls.
Root cause of the blank/stuck screen users hit on repeat login: the
ProjectPicker let you click an existing project, but clicking it only
expanded a note saying the key 'can't be recovered here, use the CLI'
— there was no button, no action, nothing that actually let you into
that project. First-time signup worked (new project + key minted
inline); every subsequent login into an existing project was a wall.
Fix:
- New POST /v1/auth/projects/{id}/rotate-key endpoint (auth.go +
project_provisioning.go): mints a fresh API key for a project the
caller owns and revokes the previous one, keeping the 'exactly one
active key per project' invariant createProjectAndKey establishes.
Ownership is checked against projects.owner_user_id before any
mutation.
- cmd/main.go: registered the missing '/v1/auth/projects/' SUBTREE
mux pattern alongside the existing exact '/v1/auth/projects' match
— Go's stdlib ServeMux only routes .../projects/<id>/rotate-key to
a subtree registration, so without this the new endpoint 404'd at
the router before ever reaching the handler (caught by live
end-to-end testing, not unit tests, since the unit suite talks to
the handler directly).
- ProjectPicker (AuthGate.tsx): existing-project note replaced with a
working 'Use this project' button wired to the new endpoint, with
loading state and an explicit warning that it rotates the key.
Verified live: signed up, created a project, logged out, logged back
in, clicked the existing project, hit 'Use this project' -> landed in
the Console on the SAME project_id with a fresh key; confirmed in
Postgres the old key is revoked and exactly one key is active.
Addresses the onboarding gap: a brand-new project has zero traffic, so
every view (Trace DAG, Cost Dashboard, Replay, Anomaly Detector) was
empty until a user wired up the real SDK. One click now populates a
project with realistic, internally-consistent traces through the exact
same write+publish path real ingestion uses.
- services/collector/internal/demo (new package): Generate() builds a
complete trace (root span + children, real parent/child linkage,
timestamps ending at 'now') for one of four scenarios —
default (research-assistant happy path), tool_failure (a tool call
errors, the agent retries and recovers), cost_spike (one LLM call
processes an unbatched full corpus — an outlier on the Cost
Dashboard), loop (the same tool call repeats 4x with no progress —
the exact shape the Anomaly Detector's loop tracker watches for).
- POST /v1/demo/seed (handler.go): API-key authenticated (same
X-AgentMesh-API-Key convention as every other endpoint), writes via
the Collector's existing SpanWriter and fans out via SpanPublisher —
a demo trace is indistinguishable downstream from a real one.
- New HTTP surface on the Collector (:4318, cmd/main.go) alongside its
existing OTLP/gRPC receiver (:4317): a browser can't speak gRPC, so
this is the one plain-HTTP door into span ingestion, deliberately
separate from the real SDK ingestion path.
- Console: RunDemoPanel — 'Run Demo' one-click CTA replaces the bare
'No traces found' empty state (TraceList), plus a persistent
'Generate Sample Data' section on the Setup tab with a scenario
picker and 1/10/100/1,000-trace bulk generation (chunked into <=50
per request, matching the server's per-request cap).
Bug caught during test authoring and fixed: Generate()'s doc comment
promised timestamps 'ending at now', but the builder's fixed -2s start
offset only covered the shortest scenario — cost_spike's summed span
durations (~14s) pushed its last span's EndTime into the future.
Fixed by shifting the whole trace uniformly so it always ends at
exactly 'now', verified against a live ClickHouse query (freshly
generated trace ends -8s from now, not +14s).
Tests: services/collector/internal/demo/{scenario,handler}_test.go —
unit tests for every scenario's structural invariants (single root,
correct parent linkage, span.Validate() passing, non-decreasing
timestamps) and the full HTTP contract (auth, role check, CORS,
count-clamping, writer/publisher wiring, error paths). go build/vet/
test and gofmt all clean.
Verified live end-to-end in a real browser against the running Docker
stack: signed up, created a project, clicked Run Demo from the Setup
tab -> Traces list populated -> opened the Trace DAG (5 real spans,
correct costs/tokens) -> Time-Travel Replay -> Cost Dashboard reflected
the same spend. Ran all four scenarios and confirmed distinct,
correct shapes (cost_spike: $2.19/128k tokens; tool_failure and loop:
both surfaced as Error status with the right span/error counts).
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
Three fixes to the Web Console's first-run and repeat-login experience, in commit order:
1.
f09f522— Eliminate CLI dependency for setup and MCP registrationproject_id+api_keyfor the active project, a ready-to-paste Python SDK snippet, and a curl healthcheck — the Console previously minted credentials but never showed them to the user, forcing everyone intocurl/CLI to retrieve their own key.POST /v1/mcp/servers, replacing theagentmesh mcp register <manifest.yaml>CLI-only requirement.run.sh— one command (./run.sh) brings up the stack, health-waits on the Query API, then opens the Console.stop/resetfor teardown.2.
0772dda— Fix existing-project login dead endRoot cause of users getting stuck on repeat login: clicking an existing project in the picker only expanded a note saying the key "can't be recovered, use the CLI" — no actual action. First-time signup worked; every subsequent login into an existing project was a wall.
POST /v1/auth/projects/{id}/rotate-key(ownership-checked, revokes the old key and mints one fresh key, keeping the "exactly one active key per project" invariant).ServeMuxbecause only the exact/v1/auth/projectspattern was registered, not the/v1/auth/projects/subtree — needed for path params.3.
53a48be— Run Demo / Generate Sample DataAddresses "never show an empty dashboard": a brand-new project has zero traffic, so every view (Trace DAG, Cost Dashboard, Replay, Anomaly Detector) was empty until real SDK traffic arrived.
services/collector/internal/demopackage +POST /v1/demo/seed(Collector:4318, a plain-HTTP door since browsers can't speak the real OTLP/gRPC ingestion path at:4317): generates realistic, fully-linked traces through the exact same write+publish pipeline real spans use.default(happy path),tool_failure,cost_spike,loop(the last two exercise Cost Dashboard outliers and the Anomaly Detector's loop tracker).Verification
go build/go vet/gofmtclean across all touched services;npx oxlint+vite buildclean for the console.services/collector/internal/demo(scenario structural invariants + full HTTP contract) — all passing, zero regressions.Base note
This branch is rebased off
db537eb(pre-session state);masterwas reset to that same commit before opening this PR, per an explicit request to make this session's work reviewable as a normal PR rather than having landed via direct pushes.