@legioncodeinc/hive 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +262 -0
  3. package/dist/cli-commands.d.ts +41 -0
  4. package/dist/cli-commands.js +76 -0
  5. package/dist/cli-commands.js.map +1 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +46 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/daemon/dashboard/app.js +118 -0
  10. package/dist/daemon/dashboard/host.d.ts +90 -0
  11. package/dist/daemon/dashboard/host.js +172 -0
  12. package/dist/daemon/dashboard/host.js.map +1 -0
  13. package/dist/daemon/dashboard/web-assets.d.ts +88 -0
  14. package/dist/daemon/dashboard/web-assets.js +195 -0
  15. package/dist/daemon/dashboard/web-assets.js.map +1 -0
  16. package/dist/daemon/fleet-status.d.ts +15 -0
  17. package/dist/daemon/fleet-status.js +56 -0
  18. package/dist/daemon/fleet-status.js.map +1 -0
  19. package/dist/daemon/gate.d.ts +55 -0
  20. package/dist/daemon/gate.js +128 -0
  21. package/dist/daemon/gate.js.map +1 -0
  22. package/dist/daemon/proxy.d.ts +38 -0
  23. package/dist/daemon/proxy.js +126 -0
  24. package/dist/daemon/proxy.js.map +1 -0
  25. package/dist/daemon/registry.d.ts +31 -0
  26. package/dist/daemon/registry.js +120 -0
  27. package/dist/daemon/registry.js.map +1 -0
  28. package/dist/daemon/server.d.ts +41 -0
  29. package/dist/daemon/server.js +126 -0
  30. package/dist/daemon/server.js.map +1 -0
  31. package/dist/daemon/setup-auth.d.ts +37 -0
  32. package/dist/daemon/setup-auth.js +51 -0
  33. package/dist/daemon/setup-auth.js.map +1 -0
  34. package/dist/daemon/telemetry-proxy.d.ts +47 -0
  35. package/dist/daemon/telemetry-proxy.js +63 -0
  36. package/dist/daemon/telemetry-proxy.js.map +1 -0
  37. package/dist/dashboard/contracts.d.ts +235 -0
  38. package/dist/dashboard/contracts.js +43 -0
  39. package/dist/dashboard/contracts.js.map +1 -0
  40. package/dist/dashboard/web/app.d.ts +44 -0
  41. package/dist/dashboard/web/app.js +179 -0
  42. package/dist/dashboard/web/app.js.map +1 -0
  43. package/dist/dashboard/web/boot-route.d.ts +23 -0
  44. package/dist/dashboard/web/boot-route.js +29 -0
  45. package/dist/dashboard/web/boot-route.js.map +1 -0
  46. package/dist/dashboard/web/build-graph-button.d.ts +46 -0
  47. package/dist/dashboard/web/build-graph-button.js +81 -0
  48. package/dist/dashboard/web/build-graph-button.js.map +1 -0
  49. package/dist/dashboard/web/buzzing-screen.d.ts +30 -0
  50. package/dist/dashboard/web/buzzing-screen.js +135 -0
  51. package/dist/dashboard/web/buzzing-screen.js.map +1 -0
  52. package/dist/dashboard/web/folder-picker.d.ts +54 -0
  53. package/dist/dashboard/web/folder-picker.js +125 -0
  54. package/dist/dashboard/web/folder-picker.js.map +1 -0
  55. package/dist/dashboard/web/graph-layout.d.ts +101 -0
  56. package/dist/dashboard/web/graph-layout.js +0 -0
  57. package/dist/dashboard/web/graph-layout.js.map +1 -0
  58. package/dist/dashboard/web/harness-strip.d.ts +38 -0
  59. package/dist/dashboard/web/harness-strip.js +65 -0
  60. package/dist/dashboard/web/harness-strip.js.map +1 -0
  61. package/dist/dashboard/web/health-rail.d.ts +26 -0
  62. package/dist/dashboard/web/health-rail.js +61 -0
  63. package/dist/dashboard/web/health-rail.js.map +1 -0
  64. package/dist/dashboard/web/main.d.ts +22 -0
  65. package/dist/dashboard/web/main.js +51 -0
  66. package/dist/dashboard/web/main.js.map +1 -0
  67. package/dist/dashboard/web/needs-project.d.ts +51 -0
  68. package/dist/dashboard/web/needs-project.js +69 -0
  69. package/dist/dashboard/web/needs-project.js.map +1 -0
  70. package/dist/dashboard/web/page-frame.d.ts +95 -0
  71. package/dist/dashboard/web/page-frame.js +98 -0
  72. package/dist/dashboard/web/page-frame.js.map +1 -0
  73. package/dist/dashboard/web/pages/coming-soon.d.ts +23 -0
  74. package/dist/dashboard/web/pages/coming-soon.js +19 -0
  75. package/dist/dashboard/web/pages/coming-soon.js.map +1 -0
  76. package/dist/dashboard/web/pages/dashboard.d.ts +32 -0
  77. package/dist/dashboard/web/pages/dashboard.js +205 -0
  78. package/dist/dashboard/web/pages/dashboard.js.map +1 -0
  79. package/dist/dashboard/web/pages/graph.d.ts +72 -0
  80. package/dist/dashboard/web/pages/graph.js +362 -0
  81. package/dist/dashboard/web/pages/graph.js.map +1 -0
  82. package/dist/dashboard/web/pages/harnesses.d.ts +65 -0
  83. package/dist/dashboard/web/pages/harnesses.js +210 -0
  84. package/dist/dashboard/web/pages/harnesses.js.map +1 -0
  85. package/dist/dashboard/web/pages/health.d.ts +22 -0
  86. package/dist/dashboard/web/pages/health.js +91 -0
  87. package/dist/dashboard/web/pages/health.js.map +1 -0
  88. package/dist/dashboard/web/pages/lifecycle-panel.d.ts +60 -0
  89. package/dist/dashboard/web/pages/lifecycle-panel.js +187 -0
  90. package/dist/dashboard/web/pages/lifecycle-panel.js.map +1 -0
  91. package/dist/dashboard/web/pages/logs.d.ts +55 -0
  92. package/dist/dashboard/web/pages/logs.js +311 -0
  93. package/dist/dashboard/web/pages/logs.js.map +1 -0
  94. package/dist/dashboard/web/pages/memories.d.ts +35 -0
  95. package/dist/dashboard/web/pages/memories.js +439 -0
  96. package/dist/dashboard/web/pages/memories.js.map +1 -0
  97. package/dist/dashboard/web/pages/projects.d.ts +38 -0
  98. package/dist/dashboard/web/pages/projects.js +325 -0
  99. package/dist/dashboard/web/pages/projects.js.map +1 -0
  100. package/dist/dashboard/web/pages/roi-chart.d.ts +52 -0
  101. package/dist/dashboard/web/pages/roi-chart.js +133 -0
  102. package/dist/dashboard/web/pages/roi-chart.js.map +1 -0
  103. package/dist/dashboard/web/pages/roi.d.ts +93 -0
  104. package/dist/dashboard/web/pages/roi.js +375 -0
  105. package/dist/dashboard/web/pages/roi.js.map +1 -0
  106. package/dist/dashboard/web/pages/settings.d.ts +103 -0
  107. package/dist/dashboard/web/pages/settings.js +420 -0
  108. package/dist/dashboard/web/pages/settings.js.map +1 -0
  109. package/dist/dashboard/web/pages/sync.d.ts +59 -0
  110. package/dist/dashboard/web/pages/sync.js +280 -0
  111. package/dist/dashboard/web/pages/sync.js.map +1 -0
  112. package/dist/dashboard/web/panels.d.ts +178 -0
  113. package/dist/dashboard/web/panels.js +471 -0
  114. package/dist/dashboard/web/panels.js.map +1 -0
  115. package/dist/dashboard/web/primitives.d.ts +80 -0
  116. package/dist/dashboard/web/primitives.js +208 -0
  117. package/dist/dashboard/web/primitives.js.map +1 -0
  118. package/dist/dashboard/web/readiness-splash.d.ts +39 -0
  119. package/dist/dashboard/web/readiness-splash.js +201 -0
  120. package/dist/dashboard/web/readiness-splash.js.map +1 -0
  121. package/dist/dashboard/web/registry.d.ts +96 -0
  122. package/dist/dashboard/web/registry.js +99 -0
  123. package/dist/dashboard/web/registry.js.map +1 -0
  124. package/dist/dashboard/web/router.d.ts +48 -0
  125. package/dist/dashboard/web/router.js +76 -0
  126. package/dist/dashboard/web/router.js.map +1 -0
  127. package/dist/dashboard/web/scope-context.d.ts +155 -0
  128. package/dist/dashboard/web/scope-context.js +266 -0
  129. package/dist/dashboard/web/scope-context.js.map +1 -0
  130. package/dist/dashboard/web/service-icons.d.ts +33 -0
  131. package/dist/dashboard/web/service-icons.js +80 -0
  132. package/dist/dashboard/web/service-icons.js.map +1 -0
  133. package/dist/dashboard/web/setup-gate.d.ts +116 -0
  134. package/dist/dashboard/web/setup-gate.js +272 -0
  135. package/dist/dashboard/web/setup-gate.js.map +1 -0
  136. package/dist/dashboard/web/sidebar.d.ts +63 -0
  137. package/dist/dashboard/web/sidebar.js +91 -0
  138. package/dist/dashboard/web/sidebar.js.map +1 -0
  139. package/dist/dashboard/web/use-fleet-telemetry.d.ts +111 -0
  140. package/dist/dashboard/web/use-fleet-telemetry.js +278 -0
  141. package/dist/dashboard/web/use-fleet-telemetry.js.map +1 -0
  142. package/dist/dashboard/web/wire.d.ts +1937 -0
  143. package/dist/dashboard/web/wire.js +1837 -0
  144. package/dist/dashboard/web/wire.js.map +1 -0
  145. package/dist/errors.d.ts +5 -0
  146. package/dist/errors.js +11 -0
  147. package/dist/errors.js.map +1 -0
  148. package/dist/install/registry.d.ts +35 -0
  149. package/dist/install/registry.js +110 -0
  150. package/dist/install/registry.js.map +1 -0
  151. package/dist/lock.d.ts +10 -0
  152. package/dist/lock.js +87 -0
  153. package/dist/lock.js.map +1 -0
  154. package/dist/service/commands.d.ts +15 -0
  155. package/dist/service/commands.js +49 -0
  156. package/dist/service/commands.js.map +1 -0
  157. package/dist/service/index.d.ts +38 -0
  158. package/dist/service/index.js +174 -0
  159. package/dist/service/index.js.map +1 -0
  160. package/dist/service/platform.d.ts +37 -0
  161. package/dist/service/platform.js +67 -0
  162. package/dist/service/platform.js.map +1 -0
  163. package/dist/service/templates.d.ts +10 -0
  164. package/dist/service/templates.js +120 -0
  165. package/dist/service/templates.js.map +1 -0
  166. package/dist/shared/constants.d.ts +15 -0
  167. package/dist/shared/constants.js +19 -0
  168. package/dist/shared/constants.js.map +1 -0
  169. package/dist/shared/daemon-routing.d.ts +11 -0
  170. package/dist/shared/daemon-routing.js +38 -0
  171. package/dist/shared/daemon-routing.js.map +1 -0
  172. package/dist/shared/fleet-readiness.d.ts +18 -0
  173. package/dist/shared/fleet-readiness.js +9 -0
  174. package/dist/shared/fleet-readiness.js.map +1 -0
  175. package/dist/shared/fleet-telemetry.d.ts +68 -0
  176. package/dist/shared/fleet-telemetry.js +61 -0
  177. package/dist/shared/fleet-telemetry.js.map +1 -0
  178. package/dist/shared/lifecycle-flags.d.ts +34 -0
  179. package/dist/shared/lifecycle-flags.js +39 -0
  180. package/dist/shared/lifecycle-flags.js.map +1 -0
  181. package/dist/shared/memory-types.d.ts +55 -0
  182. package/dist/shared/memory-types.js +75 -0
  183. package/dist/shared/memory-types.js.map +1 -0
  184. package/dist/shared/service-status.d.ts +82 -0
  185. package/dist/shared/service-status.js +97 -0
  186. package/dist/shared/service-status.js.map +1 -0
  187. package/dist/telemetry/emit.d.ts +197 -0
  188. package/dist/telemetry/emit.js +196 -0
  189. package/dist/telemetry/emit.js.map +1 -0
  190. package/package.json +50 -0
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The SYNC page — PRD-042 (view · promote · control skills AND agents + activity).
3
+ *
4
+ * Mounted at the PRD-037 `#/sync` slot (replacing the `ComingSoon` placeholder). A WRITE-action page:
5
+ * every control invokes the REAL daemon pipeline over the shared `wire` (never `createWireClient`,
6
+ * never DeepLake — the thin-client invariant holds). ONE shared component family renders BOTH the
7
+ * skills view (042a) and the agents view (042b), parameterized over `asset_type` — the agent surface
8
+ * is the skill surface keyed by asset kind, not a fork (b-AC-6). Plus the activity feed + per-scope
9
+ * state (042c).
10
+ *
11
+ * - LIST (a-AC-1 / b-AC-1) — every skill/agent from the `installed ∪ synced` union view-model
12
+ * (`wire.assetsView()`), each with its honest state badge (`local`/`pulled`/`shared`), no
13
+ * double-count. A tab switches between the Skills and Agents views over the same components.
14
+ * - DETAIL (a-AC-2 / b-AC-2) — name, description, provenance, scope, source harness, tier/style,
15
+ * version, state. NEVER the `native` blob / author email / org GUID (the view-model omits them).
16
+ * - CONTROLS (a-AC-3..7 / b-AC-3..6) — promote / pull / demote / enable / disable, each dispatching
17
+ * to the real endpoint and showing an IN-FLIGHT state until the daemon's poll-convergent
18
+ * read-back confirms (no optimistic flip — a-AC-7). Demote is DISABLED when not the author
19
+ * (`authoredByMe`, parent OQ-4 — honest, never attempt-and-fail).
20
+ * - ACTIVITY (042c) — a recent-activity feed of sync events (publish/pull/tombstone) filtered from
21
+ * `/api/logs`, newest first, plus a per-scope summary (org/team `shared`, user `local`/`pulled`)
22
+ * derived from the SAME union view-model so the summary and the lists never disagree (c-AC-3).
23
+ *
24
+ * Every visual value is an existing DS token + an existing primitive (`Badge`/`Button`/`Panel`/
25
+ * `LiveLog`, the `SYNC_TONE` map). NO new dependency, NO CDN React, NO secret in the page (D-9).
26
+ */
27
+ import React from "react";
28
+ import type { PageProps } from "../page-frame.js";
29
+ import { type AssetSyncViewWire, type LogRecordWire } from "../wire.js";
30
+ /**
31
+ * The per-scope sync-state summary (042c c-AC-3). Counts are derived from the SAME union view-model
32
+ * the lists render, so the summary and the per-asset views can never disagree: `shared` = team scope,
33
+ * `local` + `pulled` = the user's personal scope. No separate read, no drift.
34
+ */
35
+ export declare function summarizeScopes(view: AssetSyncViewWire): {
36
+ shared: number;
37
+ local: number;
38
+ pulled: number;
39
+ };
40
+ /**
41
+ * Build the activity feed lines from `/api/logs` records (042c c-AC-1 / c-AC-2). Filters to the
42
+ * sync-relevant records (action POSTs under `/api/diagnostics/sync/`), newest first, and renders a
43
+ * human line ("published · 200"). No record carries a secret (logger.ts), so the lines are safe.
44
+ */
45
+ export declare function buildActivityLines(records: readonly LogRecordWire[]): string[];
46
+ /**
47
+ * Append one SSE-tailed record to the chronological (oldest-last) sync-activity buffer (042c c-AC-2).
48
+ * Drops non-sync records (the feed shows only `/api/diagnostics/sync/*` events) and caps the buffer so
49
+ * the follow tail can run unbounded without growing memory. Pure + exported so the page test can drive
50
+ * the follow-handler deterministically (inject a record, assert it lands) without a live EventSource.
51
+ */
52
+ export declare function appendActivityRecord(buffer: readonly LogRecordWire[], record: LogRecordWire): readonly LogRecordWire[];
53
+ /**
54
+ * The Sync page (042a + 042b + 042c). Hydrates the union view-model from the shared wire, renders the
55
+ * Skills / Agents tabs over ONE component family, dispatches the real actions with an
56
+ * in-flight→converged lifecycle (re-reading the view after each action — no optimistic flip), and
57
+ * shows the per-scope summary + the sync activity feed.
58
+ */
59
+ export declare function SyncPage({ wire }: PageProps): React.JSX.Element;
@@ -0,0 +1,280 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * The SYNC page — PRD-042 (view · promote · control skills AND agents + activity).
4
+ *
5
+ * Mounted at the PRD-037 `#/sync` slot (replacing the `ComingSoon` placeholder). A WRITE-action page:
6
+ * every control invokes the REAL daemon pipeline over the shared `wire` (never `createWireClient`,
7
+ * never DeepLake — the thin-client invariant holds). ONE shared component family renders BOTH the
8
+ * skills view (042a) and the agents view (042b), parameterized over `asset_type` — the agent surface
9
+ * is the skill surface keyed by asset kind, not a fork (b-AC-6). Plus the activity feed + per-scope
10
+ * state (042c).
11
+ *
12
+ * - LIST (a-AC-1 / b-AC-1) — every skill/agent from the `installed ∪ synced` union view-model
13
+ * (`wire.assetsView()`), each with its honest state badge (`local`/`pulled`/`shared`), no
14
+ * double-count. A tab switches between the Skills and Agents views over the same components.
15
+ * - DETAIL (a-AC-2 / b-AC-2) — name, description, provenance, scope, source harness, tier/style,
16
+ * version, state. NEVER the `native` blob / author email / org GUID (the view-model omits them).
17
+ * - CONTROLS (a-AC-3..7 / b-AC-3..6) — promote / pull / demote / enable / disable, each dispatching
18
+ * to the real endpoint and showing an IN-FLIGHT state until the daemon's poll-convergent
19
+ * read-back confirms (no optimistic flip — a-AC-7). Demote is DISABLED when not the author
20
+ * (`authoredByMe`, parent OQ-4 — honest, never attempt-and-fail).
21
+ * - ACTIVITY (042c) — a recent-activity feed of sync events (publish/pull/tombstone) filtered from
22
+ * `/api/logs`, newest first, plus a per-scope summary (org/team `shared`, user `local`/`pulled`)
23
+ * derived from the SAME union view-model so the summary and the lists never disagree (c-AC-3).
24
+ *
25
+ * Every visual value is an existing DS token + an existing primitive (`Badge`/`Button`/`Panel`/
26
+ * `LiveLog`, the `SYNC_TONE` map). NO new dependency, NO CDN React, NO secret in the page (D-9).
27
+ */
28
+ import React from "react";
29
+ import { Badge, Button } from "../primitives.js";
30
+ import { LiveLog, Panel, SYNC_TONE } from "../panels.js";
31
+ import { isTabHidden, PageFrame } from "../page-frame.js";
32
+ import { useScope } from "../scope-context.js";
33
+ import { NeedsProjectSelection } from "../needs-project.js";
34
+ import { EMPTY_ASSET_SYNC_VIEW, formatLogLine, isSyncActivityRecord, syncActivityVerb, } from "../wire.js";
35
+ /** How often the union view-model re-hydrates (ms) — light refresh, stopped on unmount. */
36
+ const VIEW_POLL_MS = 5000;
37
+ /** How many recent sync-event lines the activity feed keeps (the SSE-followed buffer cap). */
38
+ const MAX_ACTIVITY_LINES = 12;
39
+ /** Build the in-flight map key for an asset row (kind + name, stable across re-hydrations). */
40
+ function flightKey(assetType, name) {
41
+ return `${assetType}:${name}`;
42
+ }
43
+ // ─────────────────────────────────────────────────────────────────────────────
44
+ // The shared row + detail + controls (rendered for BOTH skills and agents).
45
+ // ─────────────────────────────────────────────────────────────────────────────
46
+ /** A presentation-safe key/value row inside the detail panel. */
47
+ function DetailRow({ label, children }) {
48
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12, padding: "8px 6px", borderTop: "1px solid var(--border-subtle)" }, children: [_jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--text-tertiary)", minWidth: 130 }, children: label }), _jsx("span", { style: { flex: 1 } }), _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--text-primary)", textAlign: "right", wordBreak: "break-word" }, children: children })] }));
49
+ }
50
+ /** The state badge for a sync state (reuses the `SYNC_TONE` map from `panels.tsx`). */
51
+ function StateBadge({ state }) {
52
+ const tone = SYNC_TONE[state] ?? "neutral";
53
+ return (_jsx(Badge, { tone: tone, mono: true, dot: true, children: state }));
54
+ }
55
+ /**
56
+ * The control bar for one asset row (a-AC-3..7 / b-AC-3..6). The available actions are gated by state:
57
+ * - `local` → Promote (publish to team) + Disable (remove local install);
58
+ * - `shared` → Pull (install locally) + Demote (tombstone — DISABLED when not author);
59
+ * - `pulled` → Demote (if author) + Disable.
60
+ * Every button shows an IN-FLIGHT label while the action runs and re-enables only after the converged
61
+ * read-back (no optimistic flip — a-AC-7). `onAction` returns a promise the parent awaits + re-reads.
62
+ */
63
+ function RowControls({ row, flight, onAction, }) {
64
+ const busy = flight !== undefined;
65
+ const label = (action, idle) => (flight === action ? `${idle}…` : idle);
66
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }, children: [row.state === "local" && (_jsx(Button, { variant: "primary", size: "sm", disabled: busy, "data-testid": `promote-${row.assetType}-${row.name}`, onClick: () => onAction("promote", row), children: label("promote", "Promote") })), row.state === "shared" && (_jsx(Button, { variant: "secondary", size: "sm", disabled: busy, "data-testid": `pull-${row.assetType}-${row.name}`, onClick: () => onAction("pull", row), children: label("pull", "Pull") })), row.state === "shared" && (_jsx(Button, { variant: "ghost", size: "sm", disabled: busy, "data-testid": `enable-${row.assetType}-${row.name}`, onClick: () => onAction("enable", row), children: label("enable", "Enable") })), (row.state === "shared" || row.state === "pulled") && (_jsx(Button, { variant: "danger", size: "sm",
67
+ // Demote is DISABLED when the viewer did not author the asset (parent OQ-4: honest,
68
+ // never attempt-and-fail). It is also disabled while another action is in flight.
69
+ disabled: busy || !row.authoredByMe, title: row.authoredByMe ? "Demote (tombstone) this asset" : "Only the author can demote this asset", "data-testid": `demote-${row.assetType}-${row.name}`, onClick: () => onAction("demote", row), children: label("demote", "Demote") })), (row.state === "local" || row.state === "pulled") && (_jsx(Button, { variant: "ghost", size: "sm", disabled: busy, "data-testid": `disable-${row.assetType}-${row.name}`, onClick: () => onAction("disable", row), children: label("disable", "Disable") })), busy && _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-tertiary)" }, children: "in-flight\u2026" })] }));
70
+ }
71
+ /** The expandable detail panel for a selected asset (a-AC-2 / b-AC-2 — no secret rendered). */
72
+ function AssetDetail({ row }) {
73
+ return (_jsx("div", { "data-testid": `detail-${row.assetType}-${row.name}`, style: { marginTop: 4 }, children: _jsxs(Panel, { title: row.name, eyebrow: row.assetType, style: { marginBottom: 4 }, children: [row.description !== "" && (_jsx("div", { style: { fontSize: 13, color: "var(--text-secondary)", padding: "4px 6px 8px", lineHeight: "19px" }, children: row.description })), _jsx(DetailRow, { label: "state", children: _jsx(StateBadge, { state: row.state }) }), _jsx(DetailRow, { label: "provenance", children: row.sourceHarness || "—" }), _jsx(DetailRow, { label: "scope", children: row.scope || "—" }), _jsx(DetailRow, { label: "source harness", children: row.sourceHarness || "—" }), _jsx(DetailRow, { label: "tier / style", children: row.tier !== "" ? `${row.tier} / ${row.style}` : "—" }), _jsx(DetailRow, { label: "version", children: row.version > 0 ? `v${row.version}` : "—" })] }) }));
74
+ }
75
+ /** One row in the asset list: name + state badge + controls, click toggles the detail panel. */
76
+ function AssetRow({ row, open, flight, onToggle, onAction, }) {
77
+ return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 4, padding: "10px 6px", borderTop: "1px solid var(--border-subtle)" }, children: [_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }, children: [_jsxs("button", { type: "button", "data-testid": `row-${row.assetType}-${row.name}`, onClick: () => onToggle(row), style: {
78
+ display: "flex",
79
+ alignItems: "center",
80
+ gap: 8,
81
+ background: "transparent",
82
+ border: "none",
83
+ padding: 0,
84
+ cursor: "pointer",
85
+ minWidth: 0,
86
+ flex: "1 1 200px",
87
+ textAlign: "left",
88
+ }, children: [_jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 13, color: "var(--text-primary)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, children: row.name }), _jsx(StateBadge, { state: row.state }), row.version > 0 && _jsxs("span", { style: { fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-tertiary)" }, children: ["v", row.version] })] }), _jsx(RowControls, { row: row, flight: flight, onAction: onAction })] }), open && _jsx(AssetDetail, { row: row })] }));
89
+ }
90
+ /** The list of one asset kind (skills or agents), each row with badges + controls (a-AC-1 / b-AC-1). */
91
+ function AssetList({ kind, rows, openKey, inFlight, onToggle, onAction, }) {
92
+ const title = kind === "skill" ? "Skills" : "Agents";
93
+ return (_jsx(Panel, { title: title, eyebrow: `${rows.length} ${kind === "skill" ? "skills" : "agents"}`, children: rows.length === 0 ? (_jsxs("div", { style: { padding: "12px 4px", fontSize: 13, color: "var(--text-tertiary)" }, children: ["No ", kind === "skill" ? "skills" : "agents", " found."] })) : (_jsx("div", { style: { display: "flex", flexDirection: "column" }, children: rows.map((row) => (_jsx(AssetRow, { row: row, open: openKey === flightKey(kind, row.name), flight: inFlight[flightKey(kind, row.name)], onToggle: onToggle, onAction: onAction }, `${row.assetType}:${row.name}`))) })) }));
94
+ }
95
+ // ─────────────────────────────────────────────────────────────────────────────
96
+ // 042c — the per-scope state summary + the activity feed.
97
+ // ─────────────────────────────────────────────────────────────────────────────
98
+ /** A single labeled count tile in the per-scope summary. */
99
+ function ScopeCount({ label, value, tone }) {
100
+ return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, padding: "8px 6px" }, children: [_jsx(Badge, { tone: tone, mono: true, children: value }), _jsx("span", { style: { fontSize: 13, color: "var(--text-secondary)" }, children: label })] }));
101
+ }
102
+ /**
103
+ * The per-scope sync-state summary (042c c-AC-3). Counts are derived from the SAME union view-model
104
+ * the lists render, so the summary and the per-asset views can never disagree: `shared` = team scope,
105
+ * `local` + `pulled` = the user's personal scope. No separate read, no drift.
106
+ */
107
+ export function summarizeScopes(view) {
108
+ let shared = 0;
109
+ let local = 0;
110
+ let pulled = 0;
111
+ for (const row of [...view.skills, ...view.agents]) {
112
+ if (row.state === "shared")
113
+ shared++;
114
+ else if (row.state === "local")
115
+ local++;
116
+ else if (row.state === "pulled")
117
+ pulled++;
118
+ }
119
+ return { shared, local, pulled };
120
+ }
121
+ /** The per-scope summary panel (042c c-AC-3): converged counts that match the lists. */
122
+ function ScopeSummary({ view }) {
123
+ const counts = summarizeScopes(view);
124
+ return (_jsx(Panel, { title: "Sync state", eyebrow: "per scope", children: _jsxs("div", { style: { display: "flex", flexWrap: "wrap", gap: 18 }, children: [_jsx(ScopeCount, { label: "shared with team", value: counts.shared, tone: "verified" }), _jsx(ScopeCount, { label: "local only", value: counts.local, tone: "neutral" }), _jsx(ScopeCount, { label: "pulled", value: counts.pulled, tone: "honey" })] }) }));
125
+ }
126
+ /**
127
+ * Build the activity feed lines from `/api/logs` records (042c c-AC-1 / c-AC-2). Filters to the
128
+ * sync-relevant records (action POSTs under `/api/diagnostics/sync/`), newest first, and renders a
129
+ * human line ("published · 200"). No record carries a secret (logger.ts), so the lines are safe.
130
+ */
131
+ export function buildActivityLines(records) {
132
+ return records
133
+ .filter(isSyncActivityRecord)
134
+ .slice(-MAX_ACTIVITY_LINES)
135
+ .reverse()
136
+ .map((r) => {
137
+ const base = formatLogLine(r);
138
+ const verb = syncActivityVerb(r);
139
+ return verb !== "" ? `${base} · ${verb}` : base;
140
+ });
141
+ }
142
+ /**
143
+ * Append one SSE-tailed record to the chronological (oldest-last) sync-activity buffer (042c c-AC-2).
144
+ * Drops non-sync records (the feed shows only `/api/diagnostics/sync/*` events) and caps the buffer so
145
+ * the follow tail can run unbounded without growing memory. Pure + exported so the page test can drive
146
+ * the follow-handler deterministically (inject a record, assert it lands) without a live EventSource.
147
+ */
148
+ export function appendActivityRecord(buffer, record) {
149
+ if (!isSyncActivityRecord(record))
150
+ return buffer;
151
+ const next = [...buffer, record];
152
+ // Keep only the most recent window (the lines render the last MAX_ACTIVITY_LINES anyway).
153
+ return next.length > MAX_ACTIVITY_LINES ? next.slice(-MAX_ACTIVITY_LINES) : next;
154
+ }
155
+ // ─────────────────────────────────────────────────────────────────────────────
156
+ // The routed page.
157
+ // ─────────────────────────────────────────────────────────────────────────────
158
+ /**
159
+ * The Sync page (042a + 042b + 042c). Hydrates the union view-model from the shared wire, renders the
160
+ * Skills / Agents tabs over ONE component family, dispatches the real actions with an
161
+ * in-flight→converged lifecycle (re-reading the view after each action — no optimistic flip), and
162
+ * shows the per-scope summary + the sync activity feed.
163
+ */
164
+ export function SyncPage({ wire }) {
165
+ // PRD-049e (49e-AC-2 / 49e-AC-5): the dashboard-selected project gates this page. With no project
166
+ // selected the page renders the needs-selection state (never another scope's assets); a project
167
+ // change re-hydrates the view (the poll effect is keyed on `project`).
168
+ const { scope } = useScope();
169
+ const project = scope.project;
170
+ const [view, setView] = React.useState(EMPTY_ASSET_SYNC_VIEW);
171
+ // The chronological (oldest-last) sync-activity buffer: BACKFILLED from the /api/logs snapshot, then
172
+ // EXTENDED by the /api/logs/stream SSE tail (042c c-AC-2). The LiveLog lines derive from it.
173
+ const [activityRecords, setActivityRecords] = React.useState([]);
174
+ const [tab, setTab] = React.useState("skill");
175
+ const [openKey, setOpenKey] = React.useState(null);
176
+ const [inFlight, setInFlight] = React.useState({});
177
+ // Hydrate the union view-model (the read backbone). A light poll keeps it fresh; stops on unmount.
178
+ // 49e-AC-2/AC-5: re-hydrate when the selected project changes; with no project selected, do not
179
+ // fetch (the page renders the needs-selection state below) so another scope's assets never show.
180
+ React.useEffect(() => {
181
+ if (project === undefined) {
182
+ setView(EMPTY_ASSET_SYNC_VIEW);
183
+ return;
184
+ }
185
+ let alive = true;
186
+ const tick = async () => {
187
+ if (!alive || isTabHidden())
188
+ return; // background-tab pause: no assets-view poll while hidden
189
+ const v = await wire.assetsView();
190
+ if (alive)
191
+ setView(v);
192
+ };
193
+ void tick();
194
+ const id = setInterval(() => void tick(), VIEW_POLL_MS);
195
+ return () => {
196
+ alive = false;
197
+ clearInterval(id);
198
+ };
199
+ }, [wire, project]);
200
+ // The activity feed FOLLOWS the SSE tail (042c c-AC-2): BACKFILL the recent records from the
201
+ // /api/logs snapshot ONCE, THEN subscribe to /api/logs/stream and append each NEW sync record as it
202
+ // lands — no client poll. The EventSource is closed on unmount via the returned unsubscribe. In a
203
+ // non-browser env (jsdom test) `wire.logsStream` is an inert no-op, so the feed degrades to the
204
+ // backfill snapshot and the test never crashes (the SSE-record handling is exercised directly via
205
+ // the injected handler). An `alive` guard prevents a late-resolving backfill from writing post-unmount.
206
+ React.useEffect(() => {
207
+ let alive = true;
208
+ void (async () => {
209
+ const records = await wire.logs(MAX_ACTIVITY_LINES * 6);
210
+ if (!alive)
211
+ return;
212
+ // Seed the buffer with only the sync-relevant records (chronological, capped).
213
+ setActivityRecords(records.filter(isSyncActivityRecord).slice(-MAX_ACTIVITY_LINES));
214
+ })();
215
+ const unsubscribe = wire.logsStream((record) => {
216
+ if (!alive)
217
+ return;
218
+ setActivityRecords((buf) => appendActivityRecord(buf, record));
219
+ });
220
+ return () => {
221
+ alive = false;
222
+ unsubscribe();
223
+ };
224
+ }, [wire]);
225
+ // Derive the rendered lines from the followed buffer (newest first, sync-only — pure helper).
226
+ const activity = React.useMemo(() => buildActivityLines(activityRecords), [activityRecords]);
227
+ const onToggle = React.useCallback((row) => {
228
+ const key = flightKey(row.assetType, row.name);
229
+ setOpenKey((cur) => (cur === key ? null : key));
230
+ }, []);
231
+ // The in-flight→converged action dispatch (a-AC-7): mark the row in-flight, run the REAL action
232
+ // (the daemon does the poll-convergent read-back), then RE-READ the union and reflect the
233
+ // persisted state — never an optimistic flip. The in-flight flag clears on completion.
234
+ const onAction = React.useCallback((action, row) => {
235
+ const key = flightKey(row.assetType, row.name);
236
+ setInFlight((m) => ({ ...m, [key]: action }));
237
+ void (async () => {
238
+ try {
239
+ await wire.syncAction(action, {
240
+ assetType: row.assetType,
241
+ name: row.name,
242
+ // Promote sends the on-disk body as `native`; here the daemon reads the disk copy
243
+ // via the install path on pull/enable, so the page sends only id + name. The
244
+ // honeycombId targets the existing substrate row for pull/demote.
245
+ honeycombId: row.honeycombId !== "" ? row.honeycombId : undefined,
246
+ });
247
+ // Re-read the union so the row reflects the CONVERGED persisted state (a-AC-7).
248
+ setView(await wire.assetsView());
249
+ }
250
+ finally {
251
+ setInFlight((m) => {
252
+ const next = { ...m };
253
+ delete next[key];
254
+ return next;
255
+ });
256
+ }
257
+ })();
258
+ }, [wire]);
259
+ const rows = tab === "skill" ? view.skills : view.agents;
260
+ return (_jsx(PageFrame, { title: "Sync", eyebrow: project === undefined ? "sync" : `${view.skills.length + view.agents.length} assets`, children: project === undefined ? (_jsx(NeedsProjectSelection, { surface: "sync state" })) : (_jsxs(_Fragment, { children: [_jsx(ScopeSummary, { view: view }), _jsx("div", { style: { height: 16 } }), _jsxs("div", { style: { display: "flex", gap: 8, marginBottom: 12 }, children: [_jsx(TabButton, { label: "Skills", active: tab === "skill", count: view.skills.length, onClick: () => setTab("skill") }), _jsx(TabButton, { label: "Agents", active: tab === "agent", count: view.agents.length, onClick: () => setTab("agent") })] }), _jsx(AssetList, { kind: tab, rows: rows, openKey: openKey, inFlight: inFlight, onToggle: onToggle, onAction: onAction }), _jsx("div", { style: { height: 16 } }), _jsx(LiveLog, { lines: activity })] })) }));
261
+ }
262
+ /** A tab button for the Skills / Agents switch (mono pill, honey when active). */
263
+ function TabButton({ label, active, count, onClick }) {
264
+ return (_jsxs("button", { type: "button", "data-testid": `tab-${label.toLowerCase()}`, "aria-pressed": active, onClick: onClick, style: {
265
+ display: "inline-flex",
266
+ alignItems: "center",
267
+ gap: 8,
268
+ height: 34,
269
+ padding: "0 14px",
270
+ background: active ? "var(--honey-subtle)" : "var(--bg-elevated)",
271
+ border: `1px solid ${active ? "var(--honey-border)" : "var(--border-default)"}`,
272
+ borderRadius: "var(--radius-full)",
273
+ color: active ? "var(--honey)" : "var(--text-secondary)",
274
+ fontFamily: "var(--font-sans)",
275
+ fontSize: 13,
276
+ fontWeight: 600,
277
+ cursor: "pointer",
278
+ }, children: [label, _jsx("span", { style: { fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-tertiary)" }, children: count })] }));
279
+ }
280
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../../src/dashboard/web/pages/sync.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAkB,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAGN,qBAAqB,EACrB,aAAa,EACb,oBAAoB,EACpB,gBAAgB,GAEhB,MAAM,YAAY,CAAC;AAKpB,2FAA2F;AAC3F,MAAM,YAAY,GAAG,IAAI,CAAC;AAC1B,8FAA8F;AAC9F,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAK9B,+FAA+F;AAC/F,SAAS,SAAS,CAAC,SAAoB,EAAE,IAAY;IACpD,OAAO,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAEhF,iEAAiE;AACjE,SAAS,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAgD;IACnF,OAAO,CACN,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,gCAAgC,EAAE,aAC9H,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAG,KAAK,GAAQ,EAC3H,eAAM,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAI,EAC5B,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAG,QAAQ,GAAQ,IACtJ,CACN,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,SAAS,UAAU,CAAC,EAAE,KAAK,EAAqB;IAC/C,MAAM,IAAI,GAAc,SAAS,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC;IACtD,OAAO,CACN,KAAC,KAAK,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,QAAC,GAAG,kBACzB,KAAK,GACC,CACR,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,EACpB,GAAG,EACH,MAAM,EACN,QAAQ,GAKR;IACA,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC;IAClC,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,IAAY,EAAU,EAAE,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEhG,OAAO,CACN,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,aAC7E,GAAG,CAAC,KAAK,KAAK,OAAO,IAAI,CACzB,KAAC,MAAM,IACN,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,IAAI,iBACD,WAAW,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,EACnD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,YAEtC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,GACpB,CACT,EACA,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,CAC1B,KAAC,MAAM,IACN,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,IAAI,iBACD,QAAQ,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,EAChD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,YAEnC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,GACd,CACT,EAKA,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,CAC1B,KAAC,MAAM,IACN,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,IAAI,iBACD,UAAU,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,EAClD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,YAErC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAClB,CACT,EACA,CAAC,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,IAAI,CACtD,KAAC,MAAM,IACN,OAAO,EAAC,QAAQ,EAChB,IAAI,EAAC,IAAI;gBACT,oFAAoF;gBACpF,kFAAkF;gBAClF,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,EACnC,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,uCAAuC,iBACtF,UAAU,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,EAClD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,YAErC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAClB,CACT,EAGA,CAAC,GAAG,CAAC,KAAK,KAAK,OAAO,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,IAAI,CACrD,KAAC,MAAM,IACN,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,EACT,QAAQ,EAAE,IAAI,iBACD,WAAW,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,EACnD,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,YAEtC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,GACpB,CACT,EACA,IAAI,IAAI,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,gCAAmB,IACnH,CACN,CAAC;AACH,CAAC;AAED,+FAA+F;AAC/F,SAAS,WAAW,CAAC,EAAE,GAAG,EAA6B;IACtD,OAAO,CACN,6BAAkB,UAAU,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,YAC/E,MAAC,KAAK,IAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,aACxE,GAAG,CAAC,WAAW,KAAK,EAAE,IAAI,CAC1B,cAAK,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,YAAG,GAAG,CAAC,WAAW,GAAO,CACjI,EACD,KAAC,SAAS,IAAC,KAAK,EAAC,OAAO,YACvB,KAAC,UAAU,IAAC,KAAK,EAAE,GAAG,CAAC,KAAK,GAAI,GACrB,EACZ,KAAC,SAAS,IAAC,KAAK,EAAC,YAAY,YAAE,GAAG,CAAC,aAAa,IAAI,GAAG,GAAa,EACpE,KAAC,SAAS,IAAC,KAAK,EAAC,OAAO,YAAE,GAAG,CAAC,KAAK,IAAI,GAAG,GAAa,EACvD,KAAC,SAAS,IAAC,KAAK,EAAC,gBAAgB,YAAE,GAAG,CAAC,aAAa,IAAI,GAAG,GAAa,EACxE,KAAC,SAAS,IAAC,KAAK,EAAC,cAAc,YAAE,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,GAAa,EAClG,KAAC,SAAS,IAAC,KAAK,EAAC,SAAS,YAAE,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,GAAa,IAC3E,GACH,CACN,CAAC;AACH,CAAC;AAED,gGAAgG;AAChG,SAAS,QAAQ,CAAC,EACjB,GAAG,EACH,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,QAAQ,GAOR;IACA,OAAO,CACN,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,gCAAgC,EAAE,aACjI,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,aAC/E,kBACC,IAAI,EAAC,QAAQ,iBACA,OAAO,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,EAC/C,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAC5B,KAAK,EAAE;4BACN,OAAO,EAAE,MAAM;4BACf,UAAU,EAAE,QAAQ;4BACpB,GAAG,EAAE,CAAC;4BACN,UAAU,EAAE,aAAa;4BACzB,MAAM,EAAE,MAAM;4BACd,OAAO,EAAE,CAAC;4BACV,MAAM,EAAE,SAAS;4BACjB,QAAQ,EAAE,CAAC;4BACX,IAAI,EAAE,WAAW;4BACjB,SAAS,EAAE,MAAM;yBACjB,aAED,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,YAC7J,GAAG,CAAC,IAAI,GACH,EACP,KAAC,UAAU,IAAC,KAAK,EAAE,GAAG,CAAC,KAAK,GAAI,EAC/B,GAAG,CAAC,OAAO,GAAG,CAAC,IAAI,gBAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,kBAAI,GAAG,CAAC,OAAO,IAAQ,IAC/H,EACT,KAAC,WAAW,IAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAI,IACxD,EACL,IAAI,IAAI,KAAC,WAAW,IAAC,GAAG,EAAE,GAAG,GAAI,IAC7B,CACN,CAAC;AACH,CAAC;AAED,wGAAwG;AACxG,SAAS,SAAS,CAAC,EAClB,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,QAAQ,GAQR;IACA,MAAM,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrD,OAAO,CACN,KAAC,KAAK,IAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,YACtF,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACpB,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,oBAAM,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,eAAc,CAC1I,CAAC,CAAC,CAAC,CACH,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,YACtD,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAClB,KAAC,QAAQ,IAER,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAC3C,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAC3C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,IALb,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,CAMlC,CACF,CAAC,GACG,CACN,GACM,CACR,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,0DAA0D;AAC1D,gFAAgF;AAEhF,4DAA4D;AAC5D,SAAS,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAqD;IAC5F,OAAO,CACN,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,aAChF,KAAC,KAAK,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,kBACrB,KAAK,GACC,EACR,eAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,YAAG,KAAK,GAAQ,IACxE,CACN,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAuB;IACtD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,EAAE,CAAC;aAChC,IAAI,GAAG,CAAC,KAAK,KAAK,OAAO;YAAE,KAAK,EAAE,CAAC;aACnC,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC;AAED,wFAAwF;AACxF,SAAS,YAAY,CAAC,EAAE,IAAI,EAA+B;IAC1D,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CACN,KAAC,KAAK,IAAC,KAAK,EAAC,YAAY,EAAC,OAAO,EAAC,WAAW,YAC5C,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,aACzD,KAAC,UAAU,IAAC,KAAK,EAAC,kBAAkB,EAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAC,UAAU,GAAG,EAC7E,KAAC,UAAU,IAAC,KAAK,EAAC,YAAY,EAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAC,SAAS,GAAG,EACrE,KAAC,UAAU,IAAC,KAAK,EAAC,QAAQ,EAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAC,OAAO,GAAG,IAC3D,GACC,CACR,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAiC;IACnE,OAAO,OAAO;SACZ,MAAM,CAAC,oBAAoB,CAAC;SAC5B,KAAK,CAAC,CAAC,kBAAkB,CAAC;SAC1B,OAAO,EAAE;SACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACV,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACjC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CACnC,MAAgC,EAChC,MAAqB;IAErB,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACjD,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,0FAA0F;IAC1F,OAAO,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClF,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,EAAa;IAC3C,kGAAkG;IAClG,gGAAgG;IAChG,uEAAuE;IACvE,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAoB,qBAAqB,CAAC,CAAC;IACjF,qGAAqG;IACrG,6FAA6F;IAC7F,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,KAAK,CAAC,QAAQ,CAA2B,EAAE,CAAC,CAAC;IAC3F,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAY,OAAO,CAAC,CAAC;IACzD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAClE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAc,EAAE,CAAC,CAAC;IAEhE,mGAAmG;IACnG,gGAAgG;IAChG,iGAAiG;IACjG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAC;YAC/B,OAAO;QACR,CAAC;QACD,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;YACtC,IAAI,CAAC,KAAK,IAAI,WAAW,EAAE;gBAAE,OAAO,CAAC,yDAAyD;YAC9F,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YAClC,IAAI,KAAK;gBAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC,CAAC;QACF,KAAK,IAAI,EAAE,CAAC;QACZ,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,YAAY,CAAC,CAAC;QACxD,OAAO,GAAG,EAAE;YACX,KAAK,GAAG,KAAK,CAAC;YACd,aAAa,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAEpB,6FAA6F;IAC7F,oGAAoG;IACpG,kGAAkG;IAClG,gGAAgG;IAChG,kGAAkG;IAClG,wGAAwG;IACxG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACpB,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,KAAK,CAAC,KAAK,IAAI,EAAE;YAChB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC;YACxD,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,+EAA+E;YAC/E,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACrF,CAAC,CAAC,EAAE,CAAC;QACL,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,EAAE;YAC9C,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,kBAAkB,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACX,KAAK,GAAG,KAAK,CAAC;YACd,WAAW,EAAE,CAAC;QACf,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,8FAA8F;IAC9F,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,eAAe,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;IAE7F,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,GAAqB,EAAQ,EAAE;QAClE,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/C,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,gGAAgG;IAChG,0FAA0F;IAC1F,uFAAuF;IACvF,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CACjC,CAAC,MAA4D,EAAE,GAAqB,EAAQ,EAAE;QAC7F,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/C,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC9C,KAAK,CAAC,KAAK,IAAI,EAAE;YAChB,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;oBAC7B,SAAS,EAAE,GAAG,CAAC,SAAS;oBACxB,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,kFAAkF;oBAClF,6EAA6E;oBAC7E,kEAAkE;oBAClE,WAAW,EAAE,GAAG,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;iBACjE,CAAC,CAAC;gBACH,gFAAgF;gBAChF,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAClC,CAAC;oBAAS,CAAC;gBACV,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE;oBACjB,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjB,OAAO,IAAI,CAAC;gBACb,CAAC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC,CAAC,EAAE,CAAC;IACN,CAAC,EACD,CAAC,IAAI,CAAC,CACN,CAAC;IAEF,MAAM,IAAI,GAAG,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAEzD,OAAO,CACN,KAAC,SAAS,IAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,SAAS,YACnH,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAExB,KAAC,qBAAqB,IAAC,OAAO,EAAC,YAAY,GAAG,CAC9C,CAAC,CAAC,CAAC,CACJ,8BACA,KAAC,YAAY,IAAC,IAAI,EAAE,IAAI,GAAI,EAC5B,cAAK,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,GAAI,EAG9B,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,aACxD,KAAC,SAAS,IAAC,KAAK,EAAC,QAAQ,EAAC,MAAM,EAAE,GAAG,KAAK,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAI,EAChH,KAAC,SAAS,IAAC,KAAK,EAAC,QAAQ,EAAC,MAAM,EAAE,GAAG,KAAK,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAI,IAC3G,EAEN,KAAC,SAAS,IAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAI,EAElH,cAAK,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,GAAI,EAE9B,KAAC,OAAO,IAAC,KAAK,EAAE,QAAQ,GAAI,IACzB,CACF,GACU,CACZ,CAAC;AACH,CAAC;AAED,kFAAkF;AAClF,SAAS,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAA0E;IAC3H,OAAO,CACN,kBACC,IAAI,EAAC,QAAQ,iBACA,OAAO,KAAK,CAAC,WAAW,EAAE,EAAE,kBAC3B,MAAM,EACpB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE;YACN,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,CAAC;YACN,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,QAAQ;YACjB,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,oBAAoB;YACjE,MAAM,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,uBAAuB,EAAE;YAC/E,YAAY,EAAE,oBAAoB;YAClC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,uBAAuB;YACxD,UAAU,EAAE,kBAAkB;YAC9B,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,GAAG;YACf,MAAM,EAAE,SAAS;SACjB,aAEA,KAAK,EACN,eAAM,KAAK,EAAE,EAAE,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,sBAAsB,EAAE,YAAG,KAAK,GAAQ,IACpG,CACT,CAAC;AACH,CAAC"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * The dashboard PANEL components, ported to TSX — PRD-024 Wave 2 (AC-1..AC-6, D-5).
3
+ *
4
+ * These are the panels the UI kit declares in `assets/ui_kits/dashboard/components.jsx`
5
+ * (SessionsPanel, RulesPanel, SkillSyncPanel, GraphCanvas, LiveLog, ConnectivityBanner),
6
+ * ported verbatim from JSX to typed TSX so esbuild compiles + bundles them at build time
7
+ * (D-1 — no in-browser Babel). They compose the {@link Badge} primitive and read the SAME
8
+ * view-model shapes the daemon serves (`src/dashboard/contracts.ts`, via `wire.ts`), so the
9
+ * panels render the LIVE data (D-2) with the kit's exact markup + tokens.
10
+ *
11
+ * Each panel honors its empty/zero state (AC-2): no sessions → an empty session list (not a
12
+ * crash); graph not built → the kit's `honeycomb graph build` prompt; no skills/rules → an
13
+ * empty list. The data NEVER comes from the canned `data.js` — it is whatever the wire client
14
+ * fetched.
15
+ */
16
+ import React from "react";
17
+ import { type BadgeTone } from "./primitives.js";
18
+ import type { GraphWire, LogRecordWire, ProviderEntryWire, RuleRowWire, SessionRowWire, SettingValueWire, SkillRowWire, WireClient } from "./wire.js";
19
+ /** Props for the titled {@link Panel} shell. */
20
+ export interface PanelProps {
21
+ title: string;
22
+ eyebrow?: string;
23
+ right?: React.ReactNode;
24
+ children?: React.ReactNode;
25
+ style?: React.CSSProperties;
26
+ }
27
+ /** A titled dashboard panel (ported from `components.jsx` `Panel`). */
28
+ export declare function Panel({ title, eyebrow, right, children, style }: PanelProps): React.JSX.Element;
29
+ /**
30
+ * The shared per-harness colour language (PRD-039 OQ-4 — extended to ALL SIX). Keyed by the
31
+ * `sessions.agent` value the capture pipeline stamps; the Sessions panel tints each turn's dot by it
32
+ * and the Harnesses page (039b) reuses the SAME map so dots and the page agree. Wave-1 keyed only
33
+ * four; `hermes` + `pi` are added here so no captured harness renders an off-palette dot. Exported so
34
+ * the Harnesses page imports ONE source rather than re-deriving its own palette.
35
+ */
36
+ export declare const AGENT_DOT: Record<string, string>;
37
+ /** The fallback dot colour for an unknown/empty agent (mirrors the Sessions panel's neutral dot). */
38
+ export declare const AGENT_DOT_FALLBACK: "var(--text-tertiary)";
39
+ /**
40
+ * The captured-sessions table (ported from `components.jsx` `SessionsPanel`). AC-2 empty state.
41
+ *
42
+ * The wire ships up to a few hundred captured sessions, so the panel paginates client-side and
43
+ * renders at most {@link PAGE_SIZE} rows per page (no giant scrolling list). The header eyebrow
44
+ * keeps showing the TOTAL captured count; the `right` slot carries the `‹` / `›` controls + a
45
+ * mono `"{start}–{end} of {total}"` label, hidden entirely when there are ≤ PAGE_SIZE sessions.
46
+ */
47
+ export declare function SessionsPanel({ sessions }: {
48
+ sessions: readonly SessionRowWire[];
49
+ }): React.JSX.Element;
50
+ /** The org-wide rules list (ported from `components.jsx` `RulesPanel`). AC-2 empty state. */
51
+ export declare function RulesPanel({ rules }: {
52
+ rules: readonly RuleRowWire[];
53
+ }): React.JSX.Element;
54
+ export declare const SYNC_TONE: Record<string, BadgeTone>;
55
+ /** The skill-sync panel (ported from `components.jsx` `SkillSyncPanel`). AC-2 empty state. */
56
+ export declare function SkillSyncPanel({ skills }: {
57
+ skills: readonly SkillRowWire[];
58
+ }): React.JSX.Element;
59
+ /**
60
+ * The node-kind → fill-color map (D-5). Keyed by the snapshot's `node.kind` values; an unknown kind
61
+ * falls back to `--text-tertiary` at the render site. Exported so the PRD-041 full-page Graph page
62
+ * reuses the EXACT same legend swatches the mini-widget draws (no second color map to drift).
63
+ */
64
+ export declare const KIND_COLOR: Record<string, string>;
65
+ /** The fallback fill for a node whose `kind` is not in {@link KIND_COLOR} (shared by both canvases). */
66
+ export declare const KIND_COLOR_FALLBACK: "var(--text-tertiary)";
67
+ /**
68
+ * The codebase-graph canvas (PRD-035c). When the wire's `graph.built` is false, renders the empty state
69
+ * with the wired "Build graph" button (the graph is buildable ONLY from the UI — there is no CLI verb).
70
+ * When built, it computes a
71
+ * deterministic position per node via {@link layout} (NOT a hardcoded id map — the old `NODE_POS`
72
+ * keyed on six fixed ids that real file-path / symbol ids never matched, so every node was skipped
73
+ * and the canvas was blank), then draws ONE mark per node (FR-1) and every edge whose endpoints
74
+ * exist (FR-3). So the "N nodes · M edges" eyebrow matches what is drawn (FR-4 / AC-6).
75
+ *
76
+ * Nodes are clickable (D-3 / FR-5): a click selects a node (highlight ring + larger radius, FR-6)
77
+ * and renders the {@link NodeDetail} block with the node's id/kind/label and its neighbors; clicking
78
+ * the selected node again — or clicking empty canvas — clears the selection. `pollinating` re-expresses
79
+ * the old id-specific pulse HONESTLY (OQ-2): with no hardcoded `"pollinating"` node in real data, it
80
+ * pulses the selected/active node (or the first node as a stable panel-level indicator while no node
81
+ * is selected), only while a real pollinate pass is active.
82
+ */
83
+ export declare function GraphCanvas({ graph, pollinating, wire, onBuilt, }: {
84
+ graph: GraphWire;
85
+ pollinating: boolean;
86
+ /** The shared wire client (threaded from the home page). When present, the empty state shows the build button. */
87
+ wire?: WireClient;
88
+ /** Re-hydrate the panel's graph after a successful build (the home page re-runs its `wire.graph()`). */
89
+ onBuilt?: () => void | Promise<void>;
90
+ }): React.JSX.Element;
91
+ /** The live-log panel (ported from `components.jsx` `LiveLog`). Lines are pre-formatted, secret-free. */
92
+ export declare function LiveLog({ lines }: {
93
+ lines: readonly string[];
94
+ }): React.JSX.Element;
95
+ /** The vault setting keys this panel reads/writes (mirrors the Wave-1 `KNOWN_SETTING_KEYS`). */
96
+ export declare const SETTING_KEY: Readonly<{
97
+ readonly activeProvider: "activeProvider";
98
+ readonly activeModel: "activeModel";
99
+ readonly pollinatingEnabled: "pollinating.enabled";
100
+ readonly recallMode: "recallMode";
101
+ readonly portkeyEnabled: "portkey.enabled";
102
+ readonly portkeyConfig: "portkey.config";
103
+ readonly portkeyFallbackToProvider: "portkey.fallbackToProvider";
104
+ }>;
105
+ /**
106
+ * The provider→key-name mapping for the names-only PRESENCE badge (D-4 / AC-5). A provider's
107
+ * API key lives in the secret class under this conventional NAME (e.g. `ANTHROPIC_API_KEY`);
108
+ * the panel reads `GET /api/secrets` (NAMES only) and shows "set ✓" iff the name is present.
109
+ * It NEVER reads or renders the value — there is no value-returning route.
110
+ */
111
+ export declare const PROVIDER_KEY_NAME: Record<string, string>;
112
+ /** Props for {@link SettingsPanel}. */
113
+ export interface SettingsPanelProps {
114
+ /** The curated provider→model catalog (from `GET /api/settings`). */
115
+ readonly catalog: readonly ProviderEntryWire[];
116
+ /** The current persisted settings (key→value) from the vault. */
117
+ readonly settings: Readonly<Record<string, SettingValueWire>>;
118
+ /** The secret NAMES present (from `GET /api/secrets`) — for key presence only, never a value. */
119
+ readonly secretNames: readonly string[];
120
+ /**
121
+ * Persist one setting through the daemon, then re-read. Returns the daemon's accept flag.
122
+ * The panel calls this for every change; the parent re-hydrates so the rendered value is the
123
+ * PERSISTED vault value, not a local-only toggle (FR-3 / FR-4 / AC-5).
124
+ */
125
+ readonly onSave: (key: string, value: SettingValueWire) => Promise<boolean>;
126
+ }
127
+ /**
128
+ * The PRD-032c Settings panel (AC-5). Renders, from daemon-served `setting`-class data:
129
+ * - a PROVIDER select (Anthropic / OpenAI / OpenRouter from the catalog);
130
+ * - a MODEL control populated from THAT provider's catalog models — a `<select>` for a
131
+ * closed-list provider, a free-form text input for OpenRouter (`openEnded`, D-6);
132
+ * - a pollinating on/off toggle;
133
+ * - a names-only provider-key PRESENCE badge ("set ✓" / "not set") — NO secret value.
134
+ *
135
+ * Every write goes through `onSave` (the daemon `/api/settings` POST); the panel never opens
136
+ * the vault directly and holds no storage logic (PRD-020b posture). On (re)load the controls
137
+ * reflect the PERSISTED `settings`/`secretNames` props the parent hydrated from the daemon —
138
+ * this component is controlled by those props, not by a local-only optimistic toggle.
139
+ */
140
+ export declare function SettingsPanel({ catalog, settings, secretNames, onSave }: SettingsPanelProps): React.JSX.Element;
141
+ /** Props for the {@link PortkeyGatewaySection}. */
142
+ export interface PortkeyGatewaySectionProps {
143
+ /** The current persisted settings (key→value) from the vault — same record the SettingsPanel uses. */
144
+ readonly settings: Readonly<Record<string, SettingValueWire>>;
145
+ /** The secret NAMES present (from `GET /api/secrets`) — for key presence only, never a value. */
146
+ readonly secretNames: readonly string[];
147
+ /**
148
+ * Persist one setting through the daemon, then re-read. Same contract as `SettingsPanelProps.onSave`.
149
+ * The section calls this for `portkey.enabled`, `portkey.config`, and `portkey.fallbackToProvider`.
150
+ */
151
+ readonly onSaveSetting: (key: string, value: SettingValueWire) => Promise<boolean>;
152
+ /**
153
+ * Write-only store the `PORTKEY_API_KEY` secret. Called with the raw key value; the section
154
+ * CLEARS the draft on success (write-only discipline, a-AC-6). Returns true iff the daemon accepted.
155
+ */
156
+ readonly onSaveKey: (value: string) => Promise<boolean>;
157
+ }
158
+ /**
159
+ * PRD-063a Portkey gateway section (a-AC-1 / a-AC-2 / a-AC-4 / a-AC-5 / a-AC-6).
160
+ *
161
+ * Renders:
162
+ * - `portkey.enabled` toggle (on/off)
163
+ * - `portkey.config` free-form text input (config id or virtual key)
164
+ * - `PORTKEY_API_KEY` write-only password input + presence badge ("key set ✓" / "not set")
165
+ * - `portkey.fallbackToProvider` opt-in toggle (default false)
166
+ *
167
+ * Built entirely from existing DS tokens/primitives (Panel, Toggle, SettingRow, etc.).
168
+ * Every write goes through `onSaveSetting` / `onSaveKey` — the section never opens the vault
169
+ * directly. The API key input is write-only and CLEARED on a successful save (a-AC-6).
170
+ */
171
+ export declare function PortkeyGatewaySection({ settings, secretNames, onSaveSetting, onSaveKey }: PortkeyGatewaySectionProps): React.JSX.Element;
172
+ /** The daemon-down banner (ported from `components.jsx` `ConnectivityBanner`). AC-5. */
173
+ export declare function ConnectivityBanner({ url, onRetry }: {
174
+ url: string;
175
+ onRetry: () => void;
176
+ }): React.JSX.Element;
177
+ /** Re-export so the app can format a wire log record into a panel line without importing wire twice. */
178
+ export type { LogRecordWire };