Files
relicario/docs/superpowers/coordination/v0.7-dev-c-architecture-slice.md
adlee-was-taken 108965ec84 tools(relay): durable JSONL message log + pm wrapper + 120-char preview
- queue.ts: append every posted message to relay-log.jsonl (full body,
  survives the consume-once drain + restarts). gitignored.
- server.ts: bump the stdout preview from 60 to 120 chars.
- tools/relay/pm: absolute-path bash wrapper (read|pending|send) so relay
  ops work from any cwd without cd or hand-built JSON escaping.
- Fold in Dev-C's Phase 6 ARCHITECTURE.md slice as a coordination artifact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:51:02 -04:00

4.1 KiB

Dev-C ARCHITECTURE.md slice — Plan C Phase 6 (get_vault_status + sidebar status indicator)

Ready-to-fold additions for extension/ARCHITECTURE.md, scoped to Dev-C's Phase 6 work only. Phase 3 (create_vault/attach_vault, setup-SW migration) and Phase 4 (the vault.tsvault-shell/vault-sidebar/vault-list/vault-drawer/vault-form-wrapper split) doc updates are Dev-A's / Dev-B's slices — not included here.

Merged to origin/main as 397cc78 (Merge Plan C Phase 6). Local source ref: 675452a.


1. SW message-protocol row — get_vault_status (read-only, popup-only)

Where: the router/popup-only.ts bullet in the service-worker module map (around line 270), and/or wherever the read-only popup messages are enumerated.

Add:

  • get_vault_status (popup-only, read-only) — returns the cached sync summary { ahead, behind, lastSyncAt, pendingItems } with no network call. ahead/behind/ lastSyncAt are read straight off state.gitHost (populated by the sync handler, which records lastSyncAt = Math.floor(Date.now()/1000) — unix seconds — after a successful manifest fetch). pendingItems is a live count of active (non-trashed) manifest entries via vault.listItems(manifest).length. ahead/behind are structurally always 0 in the extension (it writes straight to the host via the Contents REST API; there is no local commit graph) and exist for parity with relicario status. Handler: vault.handleGetVaultStatus(state) — synchronous; its Pick<GitHost,'lastSyncAt'|'ahead'|'behind'>-typed param both breaks the PopupState import cycle and structurally forbids it from making a network call.

2. git-host.ts cache fields

Where: the git-host.ts bullet in the SW module map (around line 299, listing the interface methods).

Amend the interface description to note the cached sync metadata:

The GitHost interface also carries cached sync metadata — lastSyncAt: number | null (unix seconds), ahead: number, behind: number — initialized to null/0/0 in both GiteaHost and GitHubHost. The cache rides the gitHost lifecycle: it is created on unlock and cleared whenever state.gitHost is nulled — on session-timer expiry (index.ts) and on the explicit lock message handler (popup-only.ts), which now nulls state.gitHost symmetrically so a lock→unlock cycle can't surface a stale lastSyncAt.

3. Sidebar status-indicator UI flow

Where: the src/vault/ module map (around line 184). Add a vault-status.ts entry and a note on the vault-sidebar.ts footer wiring. (If Dev-B's Phase 4 slice has already added the vault-sidebar.ts entry, fold the status note into it rather than duplicating.)

Add:

  • vault-status.ts — sidebar-footer sync indicator renderer. renderStatusIndicator(el, status) is pure DOM: it renders, by priority, N pending / N ahead / N behind, falling back to in sync, plus a last sync <relativeTime> / never synced line. Reuses shared/glyphs.ts (GLYPH_PENDING/AHEAD/BEHIND/SYNCED) and shared/relative-time.ts. VaultStatus is an alias of GetVaultStatusResponse['data'], so the renderer's input shape is single-sourced from the message contract and can't drift from the SW handler.
  • Status-indicator flow (in the vault-sidebar.ts entry): the footer holds a #vault-status-slot plus a manual refresh button (GLYPH_REFRESH). wireSidebar calls refreshStatus() once on mount and again on the button's click — sending get_vault_status via ctx.sendMessage and rendering the result into the slot. There is no timer polling: the indicator only refreshes on mount + explicit button press, matching the spec's no-network-without-user-intent discipline (sync is user-initiated).

4. Living-docs note

This closes the last relicario status CLI/extension parity gap (called out in the extension restructure spec, docs/superpowers/specs/2026-05-04-extension-restructure-design.md). STATUS.md should move the extension-restructure line to shipped as part of the Task 7.1 pass.