Skip to content

Implement Dioptra agent fleet dashboard - #1

Open
surrealwolf wants to merge 9 commits into
mainfrom
cursor/dioptra-impl-2b72
Open

Implement Dioptra agent fleet dashboard#1
surrealwolf wants to merge 9 commits into
mainfrom
cursor/dioptra-impl-2b72

Conversation

@surrealwolf

@surrealwolf surrealwolf commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Vite + React SPA (Fleet + Setup tabs) for agent fleet status
  • Read-only live API with X-Dioptra-Site marker, Origin allowlist, rate limit
  • Setup diagrams: Coder workspaces, agent loops, fleet wiring
  • GitLab mirror dk-raas/dkai/tools/dioptra → Harbor → Rancher prd-apps

Deploy path

GitHub main → CI → reusable GitLab mirror push (secrets: inheritorg GITLAB_TOKEN) → GitLab CI → Harbor → k8s/ on prd-apps

See docs/GITLAB_MIRROR.md. No per-repo GITLAB_TOKEN needed.


Note

Medium Risk
Large greenfield change with production deploy jobs and auth that depends on shared site markers and origin allowlists; misconfigured secrets or CI kubeconfig could affect prd-apps rollouts.

Overview
Replaces the mock-only repo with a full Dioptra stack: a Vite + React SPA and a Node read-only API that serves live fleet snapshots.

The Fleet tab polls GET /api/status with a baked-in X-Dioptra-Site marker (must match DIOPTRA_SITE_MARKER on the API), plus an Origin/Referer allowlist and per-IP rate limiting. The API refreshes on an interval via buildStatus (GitHub/GitLab issue collectors; nodes/agents from env JSON or seeded public/status.json). npm run publish:status still writes an offline snapshot.

The Setup tab adds SVG diagrams (Coder workspace provisioning, agent observe/plan/act/verify loops, fleet wiring). README and docs are updated for the new architecture; Apache-2.0 license is added.

Ops: dual Docker images (nginx SPA + API), Compose, k8s/ manifests for dioptra on prd-apps, GitHub CI (test/build + mirror to GitLab), and GitLab CI (Harbor publish + optional kubectl deploy). Collector tokens stay server-side only; the SPA marker is explicitly not a strong secret.

Reviewed by Cursor Bugbot for commit ae16c89. Bugbot is set up for automated code reviews on this repo. Configure here.

Vite/React UI polls status.json for k8s nodes, Cursor/Hermes agents,
infra topology, and GitHub/GitLab issue backlogs (top 10 by priority).
Add publish-status scraper, nginx GET-only container, and CI.
@cursor

cursor Bot commented Jul 23, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

Serve GET /api/status from a collector cache. Require X-Dioptra-Site,
allowlisted Origin/Referer, and per-IP rate limits. Wire the SPA and
nginx/compose so only the Dioptra site is meant to consume the API.
Split Fleet (live status) from Setup (how agents work): Coder template
desktop spaces, tools/resources, outside router vs inside vLLM, and
fleet wiring diagram moved onto the Setup tab.
Show outer lifecycle plus observe/plan/act/verify cycle, tool micro-loop,
CI/review re-entry, and blocked/handoff exits on the Setup tab.
Create dk-raas/dkai/tools/dioptra mirror path, GitHub→GitLab mirror
workflow, Harbor publish CI, and prd-apps k8s manifests for web+api.
Comment thread Dockerfile.api
Comment thread .gitlab-ci.yml Outdated
Comment thread scripts/lib/build-status.mjs
Comment thread scripts/lib/build-status.mjs
Comment thread server/index.mjs Outdated
Comment thread .gitlab-ci.yml Outdated
Switch to reusable-gitlab-mirror-push with secrets: inherit so the
shared DataKnifeAI org mirror token is used; drop per-repo secret docs.
Document shared DataKnifeAI org mirror token and call
reusable-gitlab-mirror-push from ci.yml on main.
Comment thread scripts/lib/build-status.mjs Outdated
Comment thread src/components/Topology.tsx
Comment thread .gitlab-ci.yml Outdated
Comment thread server/index.mjs
Use Node fetch for collectors (no curl/gh in API image), await shared
refresh, omit HEAD bodies, count online agents consistently, use
GitHub/GitLab total counts, and deploy SHA tags without applying
secret.example.yaml.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 4 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ae16c89. Configure here.

platform: "gitlab",
totalOpen: 0,
top: [],
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub error blocks GitLab

Medium Severity

buildStatus() always awaits GitHub issue collection first; if that throws, the whole refresh fails and GitLab is never queried. GitLab backlog and summary counts stop updating during GitHub outages or rate limits even when GitLab credentials and the API are healthy.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ae16c89. Configure here.


export function readJson(path, fallback) {
if (!path || !existsSync(path)) return fallback;
return JSON.parse(readFileSync(path, "utf8"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid JSON crashes refresh

Medium Severity

readJson() calls JSON.parse with no error handling. A malformed DIOPTRA_NODES_JSON or DIOPTRA_AGENTS_JSON file causes every buildStatus() refresh to throw, leaving cache.error set and blocking updates until the file is fixed (initial seed load at API startup can crash the process the same way).

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ae16c89. Configure here.

Comment thread server/index.mjs
void refresh();
}, REFRESH_MS);

server.listen(PORT, HOST, () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTTP server starts after refresh

High Severity

The server awaits the initial refresh() call before server.listen(), preventing it from accepting connections until buildStatus() completes its external calls. This delays /healthz and /api/status availability, leading to startup probe failures and restarts, despite public/status.json being pre-loaded.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ae16c89. Configure here.

Comment thread k8s/deploy-to-prd-apps.sh
kubectl apply -f k8s/web-deployment.yaml

kubectl -n "$NAMESPACE" rollout status deployment/dioptra-api --timeout=180s
kubectl -n "$NAMESPACE" rollout status deployment/dioptra-web --timeout=180s

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual deploy resets image tag

Medium Severity

The deploy-to-prd-apps.sh script applies deployments using :latest image tags. Unlike our GitLab CI, it doesn't update images to specific commit SHAs. This can result in deploying stale images or rolling back to older versions, potentially causing mismatches between API and web components.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit ae16c89. Configure here.

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