#406 was the JS-split refactor: pull shared helpers into common.js (step 1), pull the flow-only IIFEs into flow.js (step 2), then rename the legacy combined entry from app.js to tabs.js (step 3 — this commit) to reflect that the bundle now owns the dashboard tabs surface only. What moved: - `frontend/packages/dashboard/src/app.js` → `tabs.js` - `build.mjs` entry: `src('app.js')` → `src('tabs.js')`; output is now `static/tabs.js` - `index.html` `<script>` src: `/static/app.js` → `/static/tabs.js`; the FL0W-section comment retouched - `flow.html` reference from `/static/app.js`-as-tabs to `/static/tabs.js`; notif + offscreen-inbox comments rewired to point at the correct owners (common.js for NOTIF, flow.js for renderInbox) - `common.js`, `flow.js`, `tabs.js` headers: scrub stale "app.js" references; document that #406 steps 2 + 3 are done and both pages import directly from common.js - `dashboard.css` comments: every "by app.js" → "by tabs.js" - `docs/web-ui.md`, `docs/conventions.md`: legacy `assets/app.js` → `assets/tabs.js` (the path prefix is itself stale from a much-earlier rename, but consistent with the rest of those docs) - `CLAUDE.md` file map: refresh the dashboard package's src/ and dist/ layouts to reflect the post-split shape (tabs.js, flow.js, common.js, stream-worker.js) What did NOT move: - `frontend/packages/agent/src/app.js` (per-agent UI entry) stays named `app.js` — it's a separate package, has only one entry point, no split happened there - The two "no-op when target absent" guards in renderContainers and renderQuestions are kept as belt-and-suspenders for any future page that adds tabs.js without the corresponding sections; comments updated to note this rather than the pre-split flow.html reason Functional behaviour identical; this is a pure rename + comment sweep.
79 lines
3.2 KiB
Markdown
79 lines
3.2 KiB
Markdown
# Conventions
|
|
|
|
Code-style and process expectations across the workspace. Most of these
|
|
exist because something already went wrong without them.
|
|
|
|
## Naming
|
|
|
|
- Containers are length-bounded by `nixos-container` (≤ 11 chars).
|
|
- Sub-agents are `h-<name>` with `<name>` ≤ 9 chars.
|
|
- The manager is `hm1nd` (no `h-` prefix, fixed name).
|
|
- `MAX_AGENT_NAME` in `lifecycle.rs` enforces the cap.
|
|
- Per-agent web UI port = `WEB_PORT_BASE + FNV1a(name) % WEB_PORT_RANGE`
|
|
(8100..8999); manager fixed at 8000; dashboard `cfg.dashboardPort`
|
|
(default 7000).
|
|
|
|
## Identity = socket
|
|
|
|
There are no auth tokens on the per-agent unix sockets. The socket
|
|
*path* identifies the principal; perms come from "who has the
|
|
bind-mount." A sub-agent only sees its own `/run/hive/mcp.sock`; the
|
|
manager has access to its privileged socket; hive-c0re owns the host
|
|
admin socket.
|
|
|
|
## Wire protocol
|
|
|
|
JSON line-delimited over unix sockets in both directions (host admin
|
|
/ manager / agent). SSE streams (`/dashboard/stream` on hive-c0re,
|
|
`/events/stream` on the per-agent web UIs) are `text/event-stream`;
|
|
each frame carries a `seq` field for the snapshot-dedupe dance
|
|
(see `docs/web-ui.md`). Request/response types live in `hive-sh4re`
|
|
— change them in one place. The dashboard event vocabulary lives
|
|
in `hive-c0re::dashboard_events::DashboardEvent`.
|
|
|
|
## Async forms
|
|
|
|
Dashboard + per-agent mutating forms carry `data-async`; a delegated
|
|
`submit` listener in `assets/tabs.js` intercepts, shows a spinner,
|
|
POSTs `application/x-www-form-urlencoded` (axum's `Form` extractor
|
|
rejects multipart), calls `refreshState()` on success. New mutating
|
|
forms should add `data-async` and optionally `data-confirm` (for a
|
|
JS-side `confirm()` prompt) or `data-prompt="…"` (for a
|
|
`window.prompt()` whose answer goes into a hidden input named by
|
|
`data-prompt-field`, default `note`).
|
|
|
|
`refreshState` defers automatically when `document.activeElement`
|
|
sits inside a managed section so the operator's typing isn't lost;
|
|
collapsible `<details data-restore-key=…>` survive the re-render
|
|
via `snapshotOpenDetails` / `restoreOpenDetails`.
|
|
|
|
## `rebuild` is the reconcile verb
|
|
|
|
`lifecycle::rebuild` idempotently rewrites
|
|
`/etc/nixos-containers/<C>.conf` (`PRIVATE_NETWORK=0`, clears
|
|
`HOST_ADDRESS` / `LOCAL_ADDRESS`, sets `EXTRA_NSPAWN_FLAGS`),
|
|
regenerates `applied/<name>/flake.nix`, writes the systemd limits
|
|
drop-in, then `nixos-container update` + stop + start.
|
|
|
|
Anything that changes per-container state on the host should be
|
|
re-applied here so a manual `↻ R3BU1LD` from the dashboard is
|
|
sufficient to recover.
|
|
|
|
## Actions are factored
|
|
|
|
`approve` / `deny` / `destroy` (and the lifecycle helper) live in
|
|
`actions.rs` / `dashboard.rs`. The admin socket and the dashboard
|
|
POST handlers both call into them so the two surfaces never drift.
|
|
|
|
## Commit messages
|
|
|
|
Short, lowercase, no `Co-Authored-By` trailer. Imperative mood, no
|
|
period. Body explains *why* if non-obvious; otherwise the subject
|
|
alone is fine. Wrap at ~72 cols.
|
|
|
|
## Commit before test
|
|
|
|
Stage and commit when work *looks* ready, then run validation
|
|
(`cargo check`, `nix flake check`, real deploy). Failures get a
|
|
follow-up commit rather than an amend. The commit history is the
|
|
work log; rewriting it loses signal.
|