Commit Graph

7 Commits

Author SHA1 Message Date
96b4fd7721 feat(dashboard): GuruConnect v2 Users admin view
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 4m43s
Build and Test / Build Agent (Windows) (push) Successful in 8m48s
Build and Test / Security Audit (push) Successful in 4m38s
Build and Test / Build Summary (push) Has been skipped
Admin-only user management: list, create, edit role/permissions/status,
reset password, and disable/delete, against the v2 users API.

- Admin-gated three ways: AdminRoute on /users (calm access-denied panel
  for non-admins, no redirect loop or data fetch), Sidebar hides the nav
  item, and every mutation relies on the server AdminUser 403 as the real
  authority. isAdmin is derived from the server-validated user, not the
  client token.
- Users table: role badge (admin/operator/viewer), permissions summary,
  enabled/disabled status, created, last-login. Sticky header, skeleton,
  empty/error states. Self row tagged "You".
- Create/edit use the real roles and permission strings
  (view/control/transfer/manage_users/manage_clients); admin permissions
  are server-implicit and shown locked. Passwords: typed or Web Crypto
  generated (rejection-sampled, copy-once reveal), type=password +
  autoComplete=new-password, cleared from state on open/close/success,
  never logged/persisted/in-URL; blank on edit means unchanged.
- Self-lockout guards: cannot disable, delete, or demote your own admin
  account (controls disabled + submit-handler checks, matched on the
  authoritative user id). Server mirrors self-disable/self-delete; the
  self-demotion guard is client-side (server todo filed).
- useUpdateUser sequences user-update then permissions-set; invalidates
  ["users"] on settled so the table reconciles after a partial failure,
  with an actionable message if only permissions failed.

Passed Code Review (no blockers after fixes) and local gates
(tsc/lint/build green). Completes the v2 dashboard view set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 14:18:40 -07:00
664f33d5ab feat(dashboard): GuruConnect v2 Support Codes view
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 3m27s
Build and Test / Build Agent (Windows) (push) Successful in 7m11s
Build and Test / Security Audit (push) Successful in 4m32s
Build and Test / Build Summary (push) Has been skipped
Generate, list, and cancel attended-support codes (XXX-XXX-XXX), built
on the v2 codes API and existing UI primitives.

- Codes table: code in mono, status badge (pending+pulse/connected/
  completed/cancelled), bound client/machine, created-by, created
  (relative + absolute tooltip). Sticky header, skeleton load,
  actionable empty/error states.
- Generate opens a focused reveal modal showing the code large in
  JetBrains Mono with copy and a read-aloud instruction; the code is
  announced character-by-character for screen readers. Mint is ref-
  guarded so it creates exactly one code per open (no StrictMode dupe).
- Cancel via confirm dialog (POST /api/codes/:code/cancel), disabled for
  non-cancellable statuses; invalidates the codes query. List polls 7s.
- Shared API client now tolerates non-JSON 200 bodies, so the cancel
  endpoint's plain-text "Code cancelled" success no longer surfaces as a
  failure. Error-envelope handling unchanged.

Passed Code Review (no blockers after fixes) and local gates
(tsc/lint/build green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:59:18 -07:00
67f3722b3c feat(server): serve dashboard SPA with deep-link fallback; remove v1 portal
Some checks failed
Build and Test / Build Server (Linux) (push) Failing after 3m26s
Build and Test / Build Agent (Windows) (push) Successful in 7m17s
Build and Test / Security Audit (push) Successful in 4m29s
Build and Test / Build Summary (push) Has been skipped
Axum now serves the v2 React/Vite dashboard SPA at / with a client-side
routing fallback, and the dead v1 HTML portal is removed (nothing was
live on the server to preserve).

- SPA served from server/static/app via ServeDir with a fallback to
  index.html, so deep links (/machines, /sessions) resolve to the SPA.
- /api/*rest and /ws/*rest return JSON 404 so unrouted API/WS paths never
  leak index.html to clients; real /api, /ws, /health, /metrics, and the
  /downloads nest keep precedence (matchit static-over-wildcard).
- Path-aware Cache-Control: hashed /assets immutable, index.html no-cache.
- Vite builds to server/static/app (base /); the artifact is gitignored
  and rebuilt at deploy time (npm ci && npm run build).
- Removed v1 portal files (login/dashboard/users/index/viewer .html) and
  their dead serve_* handlers; the SPA owns /, /login, /dashboard, /users.

Verified locally: server boots, / and deep links serve the SPA, unknown
/api path returns JSON 404 (not HTML), /health and /downloads intact.
cargo build + clippy -D warnings green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:44:13 -07:00
6ecb937eb6 feat(dashboard): GuruConnect v2 Sessions view (pass 2)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m9s
Build and Test / Build Server (Linux) (push) Successful in 10m41s
Build and Test / Security Audit (push) Successful in 4m25s
Build and Test / Build Summary (push) Successful in 10s
Active-sessions table with consent-state badges, viewer-token Join,
and disconnect, built on the v2 session API and existing UI primitives.

- Sessions table: machine, mode (managed/attended), consent badge
  (granted/pending+pulse/denied/not_required), viewers, started,
  duration, status. Sticky header, skeleton load, empty/error states.
- Join action mints a session-scoped viewer token
  (POST /api/sessions/:id/viewer-token) and reveals it with the
  /ws/viewer relay URL and copy buttons. The static viewer.html is
  intentionally not targeted: it sends the raw login JWT, which the v2
  viewer plane rejects. In-dashboard web viewer ships in a later pass.
- Authz split mirrors the server mint gate: admin or control permission
  gets Control; view permission gets View only; neither hides the action.
  Server remains authoritative; the minted token carries the signed
  access claim.
- Disconnect via confirm dialog (DELETE /api/sessions/:id), invalidates
  the sessions query. List polls every 8s so consent transitions surface.

Passed Code Review (no blockers) and local gates (tsc/lint/build green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:12:04 -07:00
43a9432b81 feat(dashboard): GuruConnect v2 operator console (pass 1)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 6m56s
Build and Test / Build Server (Linux) (push) Successful in 10m15s
Build and Test / Security Audit (push) Successful in 4m12s
Build and Test / Build Summary (push) Successful in 10s
React + Vite + TypeScript SPA: scaffold, operations-terminal design
system, Bearer-token auth, and the Machines view.

- Design system: OKLCH-tinted dark theme (ink-slate + signal-cyan),
  Hanken Grotesk + JetBrains Mono, status-color language
  (online/offline/granted/pending/denied/not_required), motion with
  prefers-reduced-motion honored.
- Auth: token in sessionStorage via ref (never React state), protected
  routes, 401 session teardown, admin-gated per-agent-key UI.
- Machines view: data table (sticky header, keyboard-activated rows,
  skeleton loading, actionable empty/error states), non-blocking detail
  drawer, delete confirm, admin key management with copy-once reveal.
- UI primitives: Modal (focus trap + inert + portal + dialogStack),
  Drawer, Table, Badge/StatusDot, toast, states.
- Typed API client normalizing the two error-envelope shapes.

Passed Code Review (no blockers), impeccable critique-and-polish, and
local gates (tsc/lint/build green). Dev-only Vite proxy to :3002.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:51:11 -07:00
guruconnect-ci
520569937c chore: release v0.2.0 [skip ci] 2026-05-29 17:56:38 +00:00
AZ Computer Guru
33893ea73b Initial GuruConnect implementation - Phase 1 MVP
- Agent: DXGI/GDI screen capture, mouse/keyboard input, WebSocket transport
- Server: Axum relay, session management, REST API
- Dashboard: React viewer components with TypeScript
- Protocol: Protobuf definitions for all message types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 17:18:05 -07:00