Skip to content

JARVIS epistemic UI (slices 1–7a): additive design system, read-only data wiring - #785

Closed
Co11inss wants to merge 15 commits into
outsourc-e:mainfrom
Co11inss:feat/jarvis-epistemic-ui
Closed

Co11inss wants to merge 15 commits into
outsourc-e:mainfrom
Co11inss:feat/jarvis-epistemic-ui

Conversation

@Co11inss

@Co11inss Co11inss commented Sep 5, 2026

Copy link
Copy Markdown

Summary

Adds the JARVIS epistemic UI — a self-contained, additive design system built over slices 1–7a. It reproduces four artboards (Desktop Command/Conductor + responsive mobile) and wires the parts that have a real data source today, read-only. Everything that has no source is rendered visibly inert, never faked.

Dev routes (gated on import.meta.env.DEV): /jarvis-gallery, /jarvis-command, /jarvis-conductor.

What's included

  • --jv-* token layer registered as a 13th theme (data-theme='jarvis', dark-only, self-maps the light slot — no invented light palette).
  • Four primitives: epistemic mark (KN/RC/AS), verification badge (verified/claimed), worker status line, approval-gate card.
  • Desktop Command + Conductor boards and recomposed mobile boards (not scaled — matched to the mobile artboards directly). Conductor's failed & stale states are first-class.
  • Real data, read-only (slices 6a–6c, 7a):
    • Scheduled jobs ← ClaudeJob (verified live against a real gateway).
    • Worker board/rail ← swarm store, with blocked derived from a pending-approval join.
    • Approval gate displays real approvals; resolve is behind a per-session arm toggle (default OFF) + a two-step confirm — nothing writes without both.
    • Code-checkpoint verification ← WorkspaceCheckpointVerificationItem (tsc/tests/lint/e2e), on the dev gallery only.

Honesty model (the point of this work)

Every value the backend can't produce is rendered inert with a data-jv-fixture="no-source" marker, never a plausible fake. The 7 "product-thesis" NO-SOURCE items (epistemic marks on chat, verified/claimed on chat, evidence-on-claim, "I DISAGREE", gate blast-radius/undo/caveat) stay inert pending a separate agent/gateway contract — 5 of the 7 cannot be delivered in this fork at all (chat content is agent-sourced; approvals are gateway-served). Code-checkpoint verification is the one real fork-only win and is kept explicitly separate from chat.

Footprint

59 files, +11,124 / −2 — additive and contained. Shared-infra touches are minimal and flagged: theme.ts (theme registration), __root.tsx (dev-only /jarvis-* onboarding bypass, tree-shaken from prod), styles.css (one font @import), routeTree.gen.ts (auto-generated). No existing route/component/screen behaviour changed; nothing deleted.

Verification

Each slice was independently verified (not on the builder's word): pnpm build exit 0, pnpm lint 0 new findings vs baseline (repo baseline is pre-existing red), pnpm test +227 new tests, 0 regressions (same 37 pre-existing failures throughout). Read-only proven by grep on every data slice. The resolve write-path is guarded by a two-step confirm + a default-off per-session flag with 16 dedicated safety tests.

Known limitations (stated plainly)

  • Live-data verification is partial. Scheduled jobs are confirmed live against the real gateway. The swarm-sessions and approvals feeds are not served by this gateway build (mode=disconnected, missing=[…sessions…]), so the worker board, approval gate, and checkpoint surfaces render their fixture fallback here — their real-data paths are unit-tested and were exercised via labelled browser stubs, but are unverified against real data until those feeds exist.
  • The repo's vitest can't render hook-using components (pre-existing infra limitation); hook logic is covered via pure reducers/mappers tested directly.

Test plan

  • pnpm build (exit 0)
  • pnpm test (37 pre-existing failures unchanged; jarvis tests pass)
  • Review /jarvis-gallery, /jarvis-command, /jarvis-conductor in dev
  • Confirm the NO-SOURCE items render inert, not faked
  • Decide whether to enable live resolve against a real approvals feed (currently off by default)

🤖 Generated with JARVIS (delegated builders, independently verified). Base branch is main; opened as draft for review.

Co11inss and others added 15 commits August 23, 2026 22:22
Slice 1 of the JARVIS UI work: the token layer alone, no components.

- src/jarvis-theme.css (new): all 65 colours extracted from the
  `JARVIS Interface.dc.html` artboard, the 17-step type scale, 3 weights,
  12 line-heights, 10 tracking steps, 3 radii, a 4px-grid spacing scale,
  and the 4 keyframes (jv-pulse / jv-ring / jv-caret / jv-flow) reproduced
  verbatim. Values are declared once in a Tailwind v4 `@theme` block (so
  `bg-jv-surface-1`, `text-jv-live`, `border-jv-line`, `animate-jv-pulse`,
  `p-jv-14`, … resolve) and aliased into the `--jv-*` namespace inside
  `[data-theme='jarvis']`, matching how every other theme declares vars.
  Semantic bindings from the artboard legend are encoded and commented:
  Known/solid, Recalled/dotted, Assumed/dashed; verified vs claimed; and
  the three reserved hues (live #35D6E8, blocked #F0A340, failed #FF4D6D).

- src/styles.css: one added `@import './jarvis-theme.css';`. It sits in the
  import prologue rather than beside the scifi import — CSS requires
  `@import` to precede all other rules, so from the bottom of the file the
  bundler silently dropped the IBM Plex font import. Cascade-neutral:
  nothing else defines `--jv-*` / `--color-jv-*`.

- src/lib/theme.ts, src/routes/__root.tsx: register `jarvis` so it survives
  a reload and appears in the switcher. Dark-only — no `jarvis-light` id;
  it self-maps in both theme maps (their types are widened by `| 'jarvis'`
  only, no restructuring) and is absent from LIGHT_THEMES.

Additive only: no `--theme-*` value changed, no new npm dependency
(IBM Plex is a Google-Fonts `@import`, the same mechanism styles.css
already uses), no components or routes.

pnpm build exits 0. pnpm lint and pnpm test are unchanged against HEAD
(1880 lint problems; 37 failed / 668 passed) — both were already failing
on this branch for unrelated reasons; this slice adds no new findings.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Builds the components that carry the JARVIS product idea, each with every
state, entirely from the `--jv-*` token layer added in Slice 1:

  epistemic-mark      KN / RC / AS — the underline STYLE is semantic and is
                      itself a token (`--jv-<kind>-rule-style`), so the
                      known→solid / recalled→dotted / assumed→dashed binding
                      cannot drift out of the theme file.
  verification-badge  VERIFIED vs CLAIMED · UNVERIFIED. Presentational only —
                      it renders the state it is handed and verifies nothing.
  worker-status-line  running / blocked / idle / stale / failed / queued /
                      complete. Blocked is the only SQUARE dot: shape as well
                      as hue, so "waiting on a human" survives a colourblind
                      reading.
  approval-gate-card  Blast radius and undo path stated before the buttons,
                      plus resolved approved/rejected states. Buttons call an
                      optional `onAction` and resolve nothing themselves.

All four are shown at `/jarvis-gallery`, a dev-only route driven by fixtures
in `src/components/jarvis/fixtures.ts`. Nothing here is wired to a store, the
gateway, or real data — per docs/design/jarvis-ui-mapping.md §3.5 most of these
states have NO SOURCE in today's backend, so the components take them as props
and never invent them. Wiring is a later slice.

The gallery sets `data-theme='jarvis'` directly on <html> for as long as it is
mounted and restores the previous value on unmount, deliberately bypassing the
app's setTheme so the user's stored theme is left untouched.

Token discipline: no hex, px font-size, or raw spacing in any component. The
claimed card's hatch derives its tint from `--jv-blocked` via `color-mix` so
the amber is still written down exactly once.

Two notes for review:
- These components use `clsx` directly rather than the repo's `cn()`. `cn()`
  runs tailwind-merge, which does not know the `jv-*` scale and puts
  `text-jv-3xs` (a size) in the same conflict group as `text-jv-verified` (a
  colour) — the size was being silently dropped. No class set here needs
  conflict resolution.
- The route is gated on `import.meta.env.DEV` and renders a "Not available"
  stub otherwise, so the gallery never ships in a production build.

Additive only: no existing route, component, screen, style, or config touched;
no npm dependency added. `src/routeTree.gen.ts` regenerated by the build.
…lice 3)

Composes artboard 01 (Desktop Command, 1440x900) entirely from the Slice 2
primitives and the --jv-* token layer, on a dev-only /jarvis-command route.

  top bar   session/uptime/vault, GATE WAITING pill, greenlight
  left rail WORKERS (every WorkerStatusLine status) + THREADS + ctx footer
  centre    conversation with inline EpistemicMark claims, a VerificationBadge
            pair, the I DISAGREE turn, the inline ApprovalGateCard, composer
  right     WORK TRAIL: delegation chain, files touched, tool calls, cost

FIXTURES ONLY. No store, no gateway client, no HTTP endpoint, no request or
event stream — every value lives in src/components/jarvis/fixtures.ts so
slice 6 can see in one place exactly what still needs a real source. The
NO SOURCE rows from docs/design/jarvis-ui-mapping.md §3.5 are drawn to prove
the layout and are labelled as fixtures both in a banner above the frame and
via data-jv-fixture="no-source" in the DOM. Nothing on the board is live.

The four primitives and jarvis-theme.css are unchanged; the board composes
them and re-styles none. Token discipline holds: no raw hex, font size,
spacing, radius or duration in src/screens/jarvis/command/. The handful of
structural dimensions the token layer has no utility for (frame, rail widths,
top-bar height, prose measure) go through geometry.ts, which expresses each as
a multiple of --jv-space-4 rather than a magic px.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…routes render directly

The workspace shell gates every route behind onboarding until a backend is
connected/skipped, which made the dev-only /jarvis-* design-review surfaces
unreachable. Add a bypass in RootLayout: import.meta.env.DEV && pathname
startsWith '/jarvis' renders the Outlet directly (no shell, no onboarding).
Hard-gated on DEV (tree-shaken out of prod builds — verified absent from dist/)
and scoped to the /jarvis path prefix, so no other route or production surface
is affected.
…(Slice 4)

Composes artboard 02 (1440x900) on the dev-only /jarvis-conductor route:
COMMAND/CONDUCTOR top bar, WORKER BOARD (5-col grid with the jv-flow chain
connectors), SCHEDULED JOBS (3-col grid) and RUN LOG - UNATTENDED.

Failed and stale are treated as the point of the screen rather than as edge
cases: ops-watch:certs gets a red frame, a hazard-striped left edge, the
verbatim certbot error and TRIAGE / FULL LOG; maintainer:dep-audit gets an
amber frame, the arithmetic that proves the silence and RELOAD & RUN. The
failed run-log row is repainted end to end, not just in its OUTCOME cell.

FIXTURES ONLY. This directory imports no store, gateway client or HTTP
endpoint and opens no request or event stream. Per mapping S3.3-S3.4 worker
status and job last-run health DO have real sources today; this slice
deliberately does not read them so slice 6 has one file to replace. The rows
with no source at all (S3.5 items 11-14: the PARTIAL badge as a structured
state, the launchd diagnostic, run-log history beyond the latest run, and the
chain as a real edge graph) carry data-jv-fixture="no-source" and are named in
the banner above the frame.

Token discipline: no hex, px size, spacing, radius or duration in the new
files - including the hazard stripe, which is a repeating-linear-gradient over
--jv-failed / --jv-failed-bg at --jv-space-4 intervals. Structural dimensions
come from the shared JV_BOARD plus a Conductor-local JV_CONDUCTOR, both grid
multiples of --jv-space-4.

Verified against the artboard by computed-style probe: card names, badges and
section labels match on x, width, height, colour, font-size, weight,
line-height and letter-spacing exactly. Two known deviations are reported in
the slice notes (a uniform 1px y-offset from the shared top-bar geometry, and
no stagger delay on the second chain connector).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rds (Slice 5)

Each route now renders its desktop board at lg and above and a purpose-built
mobile board below it. Mobile is a different composition, not the 1440 board
reflowed: Command leads with the approval gate and drops both rails; Conductor
collapses ten worker cards to four numbers plus the two that are running, six
jobs to the two that are unhealthy, and an eight-column run table to time +
stem + outcome. The swap is CSS, so there is no viewport read to mismatch on
first paint, and the bare desktop board components are untouched.

The mobile hero is the real ApprovalGateCard — the primitive declares no width
of its own, so it lays out at 390 without a variant. Composing a second gate
card would have given the honest BLAST RADIUS / UNDO PATH panel two owners.

Also closes the two items deferred from slices 3 and 4:

  - JV_BOARD.topbarHeight was jvGrid(11). Under box-sizing: border-box that
    44px included the bar's own bottom rule, leaving 43px of content and
    sitting both desktop boards a pixel high. New jvRule() helper adds the
    hairline as --jv-space-1, so the value stays grid-derived.
  - The Command board inherited the app's letter-spacing: -0.15px, which the
    Conductor board has reset since slice 4. Added the same reset for parity.

Verified against pre-slice HEAD by pixel diff: with the body translated up by
the one pixel the fix adds, board 02 is identical except its last boundary row,
and board 01 is identical above y=802 — the residual is the composer and the
two rail footers, which are pinned to the frame bottom and correctly do not
move. Removing the tracking reset makes board 01 diff and leaves board 02 at
zero, confirming the reset touches only the board that had the bleed.

Fixtures only: no store, no gateway, no /api/, no fetch. Mobile fixtures reuse
the existing gate, roster, jobs and runs, and add entries only where mobile
shows something desktop does not. NO SOURCE rows keep data-jv-fixture and the
banner. No raw hex, px, or arbitrary values in any new or edited board file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ice 6a)

The Conductor board's SCHEDULED JOBS section now renders real jobs from
GET /api/claude-jobs, and falls back to the slice-4 fixtures when the
gateway is unreachable so the dev board still works offline.

  • use-scheduled-jobs.ts runs the SAME query as the product jobs screen
    (key ['claude','jobs'], fetchJobs, 30s poll), so both surfaces share
    one cache and show the same jobs at the same moment. GET only — no
    mutation is introduced anywhere under src/screens/jarvis.
  • map-scheduled-jobs.ts is the honesty boundary: pure ClaudeJob → card.
    REAL fields map through; SILENT/stale is DERIVED from enabled +
    last_run_at age against one conservative cadence-independent
    threshold; and nothing without a source is ever produced — no PARTIAL
    badge (§3.5 item 11), no launchd diagnostic (item 12), no invented
    duration, run tally or payload count, and no action chips, because
    TRIAGE / FULL LOG / RELOAD & RUN each imply a write this slice
    cannot do.
  • The honesty banner now states which of the two you are looking at
    instead of always claiming every value is invented. The NO SOURCE
    notice is unchanged either way.
  • Mobile SCHEDULE HEALTH is wired from the same mapped data and drops
    the PARTIAL half-line when live. Both boards take jobs as props with
    the fixtures as defaults, so they still render standalone.

Three behaviours came from testing against a real gateway rather than
from the fixtures, and each is documented at its definition:

  • profiles=all returns the same job registered under several profiles,
    so cards are titled `profile:name` (the board's existing owner:job
    idiom) and the list mapper guarantees unique names — ScheduledJobs
    keys its grid by name, and a collision would reconcile the wrong
    card, one of which is the FAILED one.
  • Real records report last_run_success: null beside a populated
    last_run_error. A run that recorded an error and never reported
    success is FAILED; a reported success still outranks an error left
    beside it.
  • last_run_error is unbounded (300+ char provider diagnostics) and the
    artboard is a fixed 1440x900 frame, so the error line is clamped at a
    word boundary with an ellipsis. Left whole it clipped the RUN LOG off
    the bottom of the board.

Verified against a live gateway (6 real jobs) and against the fallback:
live renders 6 real cards with 0 no-source marks and 0 action chips in
the section; fallback renders the 6 fixtures with their no-source marks
intact. pnpm build exits 0, pnpm lint holds at the 1880 baseline, and the
suite goes 701 -> 725 passing with the same 37 pre-existing failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ice 6b)

The Conductor WORKER BOARD, the Command WORKER RAIL, and the Mobile Conductor
stat strip / RUNNING NOW now render real workers from `useSwarmStore`, with
`blocked` DERIVED from a pending gateway approval joined onto the worker.
Read-only throughout: two GETs (`/api/gateway/sessions` via the store's own
poller, `/api/gateway/approvals`) and no mutation anywhere.

The board is mostly narrative, so most of it stays unwired on purpose. A real
card gets only what the session list actually supplies:

  • tone / badge — from `swarmStatus` (+ the blocked join), with the STALE
    override for a session that claims to be thinking and has not moved in ten
    minutes. `swarmStatus` is the store's heuristic and the banner says so.
  • detail — a status word plus a real age (`running 4m`, `idle 2h 11m`,
    `blocked 44s · needs approval`). No task name, file path, count or verdict.
  • sub — the pending approval's own action text, or the gateway's own error
    text, or the model, or NOTHING. Never a fixture narrative.
  • action — omitted. HOLD ⌥ and OPEN GATE both imply a write (slice 6c).
  • connector — omitted. The parent→child delegation graph is NO SOURCE
    (§3.5 item 14), so no edge is drawn between real workers at all.

The blocked join is the authoritative one: a PENDING approval matched by exact
`sessionKey` or exact-normalised `agentName`. The `waiting_for_input` text
heuristic is deliberately not consulted — no matching approval means not
blocked, whatever the output text looks like.

Grid and rail are capped at two rows' worth so a large swarm cannot push the
other sections off a fixed 1440×900 frame; the cap is not silent — the section
caption reports the true total and how many are drawn, and the RUN/BLK/IDLE
line tallies the whole roster regardless.

Fixture fallback is unchanged and is what an offline design review still sees;
the banners now report each wire separately, since jobs and workers fail
independently.

New: `map-workers.ts` (pure mappers) + 32 tests, `use-workers.ts` (the one
subscription, refcounted onto the store's existing 5s poller — no new loop).
…t OFF (Slice 6c)

The gate on Command (desktop hero, mobile hero) and NEEDS YOU on the mobile
Conductor now read the gateway's pending approvals queue — the SAME
['gateway','approvals'] query slice 6b already opened, so one GET feeds both the
BLOCKED worker badge and the gate. The oldest pending entry is the hero; the
rest are a real "+N more waiting" count. No gateway, or an empty queue, falls
back to the slice-3 fixtures exactly as before.

REAL on a live gate (§3.2): agent, action, tool + input, status, and a wait
derived from requestedAt. NO SOURCE, and never invented: BLAST RADIUS and UNDO
PATH carry the inert sentinel "— not modelled —" unconditionally, and the caveat
is dropped rather than synthesised. HOLD FOR QA is dropped too — there is no
third resolution on the endpoint.

RESOLVE IS BUILT AND DISABLED. resolveGatewayApproval is a POST that authorises
a real agent action, so it sits behind three locks in use-resolve-approval.ts:
an `enabled` flag that is false at its signature and at its one call site, a
two-step confirm, and a real approval id. It is referenced in exactly one file,
imported and used only as a default parameter — never called at load, in an
effect, or from a test. With the flag off, APPROVE still enters the confirm step
and confirming lands in a terminal `blocked` state that says nothing was sent;
a browser run of the board issues no non-GET request of any kind.

Verified: build exit 0 · lint 1880 (baseline 1880) · tests 804 passed vs 757
baseline, same 37 pre-existing failures · 47 new tests, including a machine-wide
proof that a guarded confirm is the only state/event pair that can emit a write.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… 6d)

The gate's LOCK 1 stops being a constant in `desktop-command.tsx` and becomes
a switch the user throws for one browser session. It is OFF on every fresh
session and OFF in committed code; arming it opens LOCK 1 and nothing else.

- `use-resolve-arm.ts` owns the flag. `sessionStorage` only, never
  `localStorage` — an arm that survives a browser restart is indistinguishable
  from a build-time default. Every uncertain read (no storage, a storage that
  throws, a missing key, any value but `'true'`) resolves to OFF.
- `resolve-arm-toggle.tsx` is the switch: a token-styled `role="switch"`
  button plus a line saying which world you are in. Pressing it sends nothing.
- `desktop-command.tsx` passes `arm.armed` into `useResolveApproval`'s
  `enabled` and says so in the banner, armed-vs-off. Both frames carry the
  switch because both frames carry the gate.

`use-resolve-approval.ts` has NO diff: the two-step confirm and the need for a
real approval id are untouched, so an armed session still cannot POST from a
single click or from a fixture gate. Verified in the browser: OFF + confirm →
`blocked`, zero requests; armed + one click → zero requests; armed + confirm
→ exactly one POST (intercepted in the browser against a stubbed queue — no
real approval was resolved, and the local gateway was unreachable throughout).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Additive design system: --jv-* token layer (13th theme), four epistemic
primitives, Desktop Command/Conductor + responsive mobile boards, dev-only
/jarvis-* routes, and read-only wiring to real ClaudeJob / swarm / approval
data. Approval resolve is built behind a per-session arm toggle (default OFF)
plus a two-step confirm; nothing writes without both.

All slices verified independently (build/lint/test == baseline, +203 tests,
0 regressions). NO-SOURCE product-thesis items render visibly inert pending a
separate agent/gateway backend slice. Local merge only.
… short labels (Slice 6e)

Four small items carried over from slices 3–6, all additive:

  • DISABLED_NOTE said "DISABLED in this build". Since 6d the gate is
    disarmed PER SESSION, so the note now says so and points at the switch.
  • ApprovalGateCard takes an optional `hint` — a keyboard affordance
    printed after the buttons while pending. Text only; the card binds no
    keys, and no caller passes one yet precisely because nothing binds them.
  • ApprovalGateCard takes optional `cellLabels`, defaulting to the full
    BLAST RADIUS / UNDO PATH.
  • The mobile board passes RADIUS / UNDO to match artboard 03. Same
    primitive, same cells, fewer words — a second mobile gate card would
    have let the honest panel drift, which is the one thing it must not do.

A caller that passes neither new prop renders exactly what it rendered
before, so every desktop gate is untouched.

pnpm build exit 0. pnpm lint 1880 problems — identical to baseline.
pnpm test 37 failed | 828 passed (865), against a baseline of
37 failed | 826 passed (863): same 14 pre-existing failing files, +2 new
primitive tests. The 16 resolve-machine tests pass and their test file
has no diff.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Disarm-note wording fix; optional ApprovalGateCard hint? + short cell labels
(mobile gate reads RADIUS/UNDO). Desktop gates byte-identical (new props unset).
Resolve safety machine untouched (16 tests unchanged). Local merge only.
Wires the VerificationBadge primitive to the one real verified-vs-claimed
source in the codebase — the tsc/tests/lint/e2e results recorded on a
workspace checkpoint (docs/design/jarvis-ui-mapping.md §3.6) — on its own
dev surface, with fixture fallback.

The honesty boundary: verification on a CHAT MESSAGE is NO SOURCE (§3.5
items 2-3), so this data lands in a new CODE CHECKPOINTS section of the
dev gallery and nowhere near the conversation. conversation.tsx and
mobile-thread.tsx are untouched and stay inert.

- map-checkpoints.ts (+ tests): passed -> VERIFIED, failed -> CLAIMED with
  FAILED stated in the title, missing/not_configured -> no badge at all
  (returned as inert lines instead). Real `output` becomes evidence,
  clamped per line and per line-count with the truncation declared.
- use-checkpoint-verification.ts: two GETs (list, then detail), retry off,
  fixture fallback on loading/error/no-daemon/no-checkpoints. A real
  checkpoint with no checks run stays LIVE and shows the inert lines,
  because "nothing ran" is real information.
- Read-only: no write client imported, no action chips on any badge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… (read-only)

Wire VerificationBadge to real WorkspaceCheckpointVerificationItem (tsc/tests/
lint/e2e) on the dev gallery ONLY — code-check state, explicitly NOT chat
verification (that stays NO SOURCE / inert). passed→verified, failed→claimed,
missing/not_configured→inert no-badge. Read-only; fixture fallback. Local only.
@Co11inss
Co11inss marked this pull request as ready for review September 5, 2026 00:30
@Co11inss Co11inss closed this Sep 5, 2026
@Co11inss
Co11inss deleted the feat/jarvis-epistemic-ui branch September 5, 2026 00:35
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