@kal-elsam/kairo-runtime 0.10.0 → 0.12.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 (76) hide show
  1. package/global-template/components/agent-skills/LICENSE +21 -0
  2. package/global-template/components/agent-skills/PROVENANCE.md +26 -0
  3. package/global-template/components/agent-skills/skills/context-engineering/SKILL.md +289 -0
  4. package/global-template/components/agent-skills/skills/frontend-ui-engineering/SKILL.md +328 -0
  5. package/global-template/components/agent-skills/skills/observability-and-instrumentation/SKILL.md +203 -0
  6. package/global-template/components/agent-skills/skills/performance-optimization/SKILL.md +396 -0
  7. package/global-template/components/agent-skills/skills/source-driven-development/SKILL.md +194 -0
  8. package/global-template/components/catalog.json +29 -0
  9. package/package.json +5 -2
  10. package/scripts/cockpit-smoke.mjs +1 -1
  11. package/src/cli.js +136 -8
  12. package/src/global/component-builders.js +3 -1
  13. package/src/global/components/agent-skills.js +27 -0
  14. package/src/global/ink/brand/wordmark.js +50 -0
  15. package/src/global/ink/cockpit/primitives.js +45 -35
  16. package/src/global/ink/cockpit-control-center.js +104 -4
  17. package/src/global/ink/cockpit-scan.js +20 -2
  18. package/src/global/ink/cockpit-views.js +2 -1
  19. package/src/global/ink/ecosystem-updates-display.js +37 -0
  20. package/src/global/ink/launch-input.js +32 -1
  21. package/src/global/ink/orchestrator-app.js +14 -5
  22. package/src/global/ink/orchestrator-state.js +17 -2
  23. package/src/global/ink/system-resources-display.js +109 -0
  24. package/src/global/ink/theme.js +13 -8
  25. package/src/global/ink/use-orchestrator-data.js +40 -4
  26. package/src/global/ink/ux/live-activity.js +4 -7
  27. package/src/global/ink/ux/live-alerts.js +2 -5
  28. package/src/global/ink/ux/live-governance.js +2 -6
  29. package/src/global/ink/ux/live-orchestration.js +2 -5
  30. package/src/global/ink/ux/live-overview.js +88 -28
  31. package/src/global/ink/ux/live-settings.js +3 -6
  32. package/src/global/ink/ux/live-usage.js +5 -7
  33. package/src/global/ink/ux/semantic.js +23 -6
  34. package/src/global/mcp/kairo-mcp.js +230 -0
  35. package/src/global/observability/build-companion-snapshot.js +281 -0
  36. package/src/global/observability/build-observability-snapshot.js +24 -0
  37. package/src/global/observability/ecosystem-updates.js +224 -0
  38. package/src/global/observability/gentle-bundle-export.js +71 -0
  39. package/src/global/observability/gentle-bundle-import.js +122 -0
  40. package/src/global/observability/gentle-probe.js +155 -0
  41. package/src/global/observability/graphify-ops.js +133 -0
  42. package/src/global/observability/graphify-parse-cache.js +90 -0
  43. package/src/global/observability/graphify-probe.js +185 -0
  44. package/src/global/observability/hermes-activity.js +163 -0
  45. package/src/global/observability/hermes-probe.js +171 -0
  46. package/src/global/observability/index.js +85 -0
  47. package/src/global/observability/passive-snapshot-flight.js +93 -0
  48. package/src/global/observability/probe-contract.js +38 -0
  49. package/src/global/observability/probe-registry.js +30 -0
  50. package/src/global/observability/resource-advisor.js +71 -0
  51. package/src/global/observability/system-resources.js +171 -0
  52. package/src/global/runtime/alerts/alert-cli.js +31 -0
  53. package/src/global/runtime/alerts/alert-store.js +29 -6
  54. package/src/global/runtime/alerts/alert-validate.js +25 -1
  55. package/src/global/runtime/alerts/controlled-alert-actions.js +56 -0
  56. package/src/global/runtime/execution-adapters/claude.js +2 -1
  57. package/src/global/runtime/execution-adapters/codex.js +2 -1
  58. package/src/global/runtime/execution-adapters/create-execution-adapter.js +3 -14
  59. package/src/global/runtime/execution-adapters/cursor.js +2 -1
  60. package/src/global/runtime/execution-adapters/opencode.js +2 -1
  61. package/src/global/runtime/execution-adapters/pi.js +2 -1
  62. package/src/global/runtime/review/index.js +1 -1
  63. package/src/global/runtime/review/review-cli.js +113 -3
  64. package/src/global/runtime/review/review-git.js +142 -11
  65. package/src/global/runtime/review/review-patch.js +2 -0
  66. package/src/global/runtime/review/review-receipts.js +12 -7
  67. package/src/global/runtime/review/review-runner.js +2 -2
  68. package/src/global/runtime/review/review-types.js +8 -5
  69. package/src/global/runtime/review/review-validate.js +5 -1
  70. package/src/global/runtime/run-cli.js +2 -0
  71. package/src/global/runtime/run-manager.js +39 -18
  72. package/src/global/runtime/run-permissions.js +231 -0
  73. package/src/global/runtime/run-profile.js +2 -0
  74. package/src/global/runtime/run-supervisor.js +77 -37
  75. package/src/global/runtime/run-types.js +2 -0
  76. package/src/global/updates-cli.js +41 -0
@@ -1,15 +1,20 @@
1
1
  /**
2
- * Deep-space cockpit theme. Status always has a text label — never color alone.
2
+ * Kairo Cockpit theme amber brand, ice interactive, semantic status.
3
+ * Status always has a text label — never color alone.
3
4
  */
4
5
 
5
6
  export const COCKPIT_COLORS = {
6
- primary: "cyan",
7
- secondary: "magenta",
8
- success: "green",
9
- warning: "yellow",
10
- danger: "red",
7
+ brand: "#E8A017",
8
+ interactive: "#7EC8E8",
9
+ success: "#3DDC97",
10
+ warning: "#F0C674",
11
+ danger: "#FF6B6B",
11
12
  muted: "gray",
12
- border: "cyan"
13
+ /** @deprecated alias — prefer interactive */
14
+ primary: "#7EC8E8",
15
+ /** @deprecated alias — prefer brand */
16
+ secondary: "#E8A017",
17
+ border: "#7EC8E8"
13
18
  };
14
19
 
15
20
  export const STATUS_LABELS = {
@@ -69,7 +74,7 @@ export function statusColor(kind, { colorEnabled = true } = {}) {
69
74
  case "muted":
70
75
  return COCKPIT_COLORS.muted;
71
76
  default:
72
- return COCKPIT_COLORS.primary;
77
+ return COCKPIT_COLORS.interactive;
73
78
  }
74
79
  }
75
80
 
@@ -40,7 +40,14 @@ import {
40
40
  } from "./cockpit-settings.js";
41
41
  import { listReviewReceipts } from "../runtime/review/review-receipts.js";
42
42
  import { assertReceiptSecretFree } from "../runtime/review/review-validate.js";
43
- import { listAlerts, resolveAlert, dismissAlert } from "../runtime/alerts/alert-store.js";
43
+ import { listAlerts } from "../runtime/alerts/alert-store.js";
44
+ import {
45
+ controlledDismissAlert, controlledResolveAlert
46
+ } from "../runtime/alerts/controlled-alert-actions.js";
47
+ import { buildCompanionSnapshot } from "../observability/build-companion-snapshot.js";
48
+ import { resolveGitHeadSha } from "../observability/graphify-probe.js";
49
+ import { runPassiveObservabilitySnapshot } from "../observability/passive-snapshot-flight.js";
50
+ import { inspectEngramIntegration } from "../integrations/engram-evidence.js";
44
51
 
45
52
  export function useOrchestratorData({
46
53
  homeDir,
@@ -56,6 +63,7 @@ export function useOrchestratorData({
56
63
  const [dashboard, setDashboard] = useState(null);
57
64
  const [diagnostics, setDiagnostics] = useState(null);
58
65
  const [snapshot, setSnapshot] = useState(null);
66
+ const [companion, setCompanion] = useState(null);
59
67
  const [selectedRun, setSelectedRun] = useState(null);
60
68
  const [selectedEvents, setSelectedEvents] = useState([]);
61
69
  const [reviews, setReviews] = useState([]);
@@ -78,7 +86,24 @@ export function useOrchestratorData({
78
86
  cliVersion,
79
87
  buildDashboard: buildRuntimeDashboardData,
80
88
  buildDiagnostics: buildReadOnlyDiagnostics,
81
- buildSnapshot: buildControlPlaneSnapshot
89
+ buildSnapshot: buildControlPlaneSnapshot,
90
+ buildCompanion: async ({ dashboard, snapshot: snap }) => buildCompanionSnapshot({
91
+ controlPlaneHealth: snap?.health ?? null,
92
+ runs: dashboard?.recentRuns ?? [],
93
+ inspectEngram: (ctx) => inspectEngramIntegration({
94
+ env: ctx?.env ?? process.env,
95
+ homeDir: ctx?.homeDir ?? homeDir
96
+ }),
97
+ buildObservability: (ctx) => runPassiveObservabilitySnapshot(ctx, {
98
+ force: Boolean(ctx?.force)
99
+ }),
100
+ observabilityContext: {
101
+ cwd: workspaceRoot, workspaceRoot, env: process.env,
102
+ headSha: resolveGitHeadSha(workspaceRoot)
103
+ },
104
+ loadReviews: async () => listReviewReceipts({ homeDir, limit: 20 }),
105
+ loadAlerts: async () => listAlerts({ homeDir, limit: 50 })
106
+ })
82
107
  })), [homeDir, workspaceRoot, packageName, packageRoot, cliVersion]);
83
108
 
84
109
  const reload = async ({ showLoading = false, asRetry = false } = {}) => {
@@ -98,6 +123,7 @@ export function useOrchestratorData({
98
123
  setDashboard(outcome.result.dashboard);
99
124
  setDiagnostics(outcome.result.diagnostics);
100
125
  setSnapshot(outcome.result.snapshot);
126
+ setCompanion(outcome.result.companion ?? null);
101
127
  try {
102
128
  setAlerts(await listAlerts({ homeDir, limit: 50 }));
103
129
  } catch {
@@ -166,8 +192,14 @@ export function useOrchestratorData({
166
192
  if (!alert) return;
167
193
  setBusy(true);
168
194
  try {
169
- if (action === "dismiss") await dismissAlert(alert.alertId, { homeDir });
170
- else await resolveAlert(alert.alertId, { homeDir });
195
+ const result = action === "dismiss"
196
+ ? await controlledDismissAlert({
197
+ alertId: alert.alertId, confirmed: true, source: "cockpit", homeDir
198
+ })
199
+ : await controlledResolveAlert({
200
+ alertId: alert.alertId, confirmed: true, source: "cockpit", homeDir
201
+ });
202
+ if (!result.ok) throw new Error(result.message ?? result.code);
171
203
  setAlerts(await listAlerts({ homeDir, limit: 50 }));
172
204
  setStatusMessage(action === "dismiss" ? "Alert dismissed" : "Alert resolved");
173
205
  } catch (error) {
@@ -197,6 +229,9 @@ export function useOrchestratorData({
197
229
  cwd: workspaceRoot,
198
230
  model: draft.model.trim() || null,
199
231
  permissions,
232
+ allowUnsafePermissions: Boolean(draft.allowUnsafePermissions),
233
+ permissionSource: draft.permissionSource ?? "cockpit",
234
+ permissionConsentType: draft.allowUnsafePermissions ? "cockpit-unsafe-confirm" : null,
200
235
  cliVersion,
201
236
  profile: profile ?? null,
202
237
  follow: false,
@@ -424,6 +459,7 @@ export function useOrchestratorData({
424
459
  dashboard,
425
460
  diagnostics,
426
461
  snapshot,
462
+ companion,
427
463
  selectedRun,
428
464
  setSelectedRun,
429
465
  selectedEvents,
@@ -1,13 +1,12 @@
1
1
  /** Live semantic Activity/Recovery. Callout=status · Confirm=action · footer=keys · snapshots=focus. */
2
2
  import React from "react";
3
3
  import { Box, Text } from "ink";
4
- import { COCKPIT_COLORS } from "../theme.js";
5
4
  import { formatConfirmPath } from "../cockpit-path-label.js";
6
5
  import {
7
6
  RECOVERY_PHASE, listRecoverySnapshots, formatWhen, formatResult, shortName
8
7
  } from "../cockpit-recovery.js";
9
8
  import { LAYOUT_MODES } from "../layout.js";
10
- import { ActionList, Callout, Confirm, Details } from "./semantic.js";
9
+ import { ActionList, Callout, Confirm, Details, SectionLabel, ViewTitle } from "./semantic.js";
11
10
  import { detailsPathLimit } from "./live-governance.js";
12
11
 
13
12
  export function activityContentLimits(layoutMode = LAYOUT_MODES.COMPACT) {
@@ -157,9 +156,7 @@ export function SemanticActivityPanel({
157
156
  snapshot, recoveryAction, dashboard, listIndex, homeDir, detailsOpen, layoutMode
158
157
  });
159
158
  return React.createElement(Box, { flexDirection: "column" },
160
- React.createElement(Text, {
161
- bold: true, color: colorEnabled ? COCKPIT_COLORS.secondary : undefined
162
- }, view.title),
159
+ React.createElement(ViewTitle, { colorEnabled }, view.title),
163
160
  React.createElement(Callout, {
164
161
  tone: view.callout.tone, title: view.callout.title,
165
162
  body: view.callout.body || undefined, colorEnabled, compact: true
@@ -174,11 +171,11 @@ export function SemanticActivityPanel({
174
171
  : null,
175
172
  view.primary?.detail && !view.confirm
176
173
  ? React.createElement(Text, null, view.primary.detail) : null,
177
- React.createElement(Text, { bold: true }, "Recent"),
174
+ React.createElement(SectionLabel, { colorEnabled }, "Recent"),
178
175
  React.createElement(ActionList, {
179
176
  items: view.recent, selectedIndex: -1, focused: false, colorEnabled, unicode
180
177
  }),
181
- React.createElement(Text, { bold: true }, "Snapshots"),
178
+ React.createElement(SectionLabel, { colorEnabled }, "Snapshots"),
182
179
  React.createElement(ActionList, {
183
180
  items: view.snapshots, selectedIndex: view.selectedIndex,
184
181
  focused: contentFocused, colorEnabled, unicode
@@ -5,11 +5,10 @@
5
5
  */
6
6
  import React from "react";
7
7
  import { Box, Text } from "ink";
8
- import { COCKPIT_COLORS } from "../theme.js";
9
8
  import { LAYOUT_MODES } from "../layout.js";
10
9
  import { ALERT_STATES } from "../../runtime/alerts/alert-types.js";
11
10
  import { formatAlertsHeadline, selectAlertFromList } from "../cockpit-alerts.js";
12
- import { ActionList, Callout } from "./semantic.js";
11
+ import { ActionList, Callout, ViewTitle } from "./semantic.js";
13
12
  import { windowSlice } from "./live-activity.js";
14
13
 
15
14
  export function alertsListLimit(layoutMode = LAYOUT_MODES.COMPACT) {
@@ -138,9 +137,7 @@ export function SemanticAlertsPanel({
138
137
  const model = adaptAlertsModel({ alerts, listIndex, layoutMode });
139
138
  const listFocused = contentFocused && !model.isEmpty && !model.isUnavailable;
140
139
  return React.createElement(Box, { flexDirection: "column" },
141
- React.createElement(Text, {
142
- bold: true, color: colorEnabled ? COCKPIT_COLORS.secondary : undefined
143
- }, model.title),
140
+ React.createElement(ViewTitle, { colorEnabled }, model.title),
144
141
  React.createElement(Callout, {
145
142
  tone: model.callout.tone,
146
143
  title: model.callout.title,
@@ -1,11 +1,10 @@
1
1
  /** Live semantic Governance. Ownership: Callout=status · Confirm/primary=action · footer=keys. */
2
2
  import React from "react";
3
3
  import { Box, Text } from "ink";
4
- import { COCKPIT_COLORS } from "../theme.js";
5
4
  import { formatConfirmPath } from "../cockpit-path-label.js";
6
5
  import { CHANGES_PHASE } from "../cockpit-changes.js";
7
6
  import { LAYOUT_MODES } from "../layout.js";
8
- import { ActionList, Callout, Confirm, Details } from "./semantic.js";
7
+ import { ActionList, Callout, Confirm, Details, ViewTitle } from "./semantic.js";
9
8
  import { mapHealthTone } from "./live-overview.js";
10
9
 
11
10
  function healthLabel(kind) {
@@ -151,10 +150,7 @@ export function SemanticGovernancePanel({
151
150
  snapshot, changesAction, homeDir, detailsOpen, layoutMode
152
151
  });
153
152
  return React.createElement(Box, { flexDirection: "column" },
154
- React.createElement(Text, {
155
- bold: true,
156
- color: colorEnabled ? COCKPIT_COLORS.secondary : undefined
157
- }, view.title),
153
+ React.createElement(ViewTitle, { colorEnabled }, view.title),
158
154
  React.createElement(Callout, {
159
155
  tone: view.callout.tone,
160
156
  title: view.callout.title,
@@ -5,14 +5,13 @@
5
5
  */
6
6
  import React from "react";
7
7
  import { Box, Text } from "ink";
8
- import { COCKPIT_COLORS } from "../theme.js";
9
8
  import { LAYOUT_MODES } from "../layout.js";
10
9
  import { ORCHESTRATOR_VIEWS, formatRunLines } from "../orchestrator-state.js";
11
10
  import {
12
11
  RUNS_HUB_ITEMS, formatOrchestrationStatus, formatRunsHubLines
13
12
  } from "../cockpit-runs.js";
14
13
  import { formatReviewListLines } from "../cockpit-reviews.js";
15
- import { ActionList, Callout } from "./semantic.js";
14
+ import { ActionList, Callout, ViewTitle } from "./semantic.js";
16
15
  import { windowSlice } from "./live-activity.js";
17
16
 
18
17
  export function orchestrationListLimit(layoutMode = LAYOUT_MODES.COMPACT) {
@@ -167,9 +166,7 @@ export function SemanticOrchestrationPanel({
167
166
  });
168
167
  const listFocused = contentFocused && !model.isEmpty;
169
168
  return React.createElement(Box, { flexDirection: "column" },
170
- React.createElement(Text, {
171
- bold: true, color: colorEnabled ? COCKPIT_COLORS.secondary : undefined
172
- }, model.title),
169
+ React.createElement(ViewTitle, { colorEnabled }, model.title),
173
170
  React.createElement(Callout, {
174
171
  tone: model.callout.tone,
175
172
  title: model.callout.title,
@@ -1,11 +1,18 @@
1
1
  /**
2
- * Live semantic Overview for Cockpit HOME.
2
+ * Live semantic Overview for Cockpit HOME — product cover.
3
3
  * Nav owns the sole focus mark — this panel never renders `>`.
4
+ * ASCII wordmark only here (wide/compact); minimal is textual.
4
5
  */
5
6
  import React from "react";
6
7
  import { Box, Text } from "ink";
7
8
  import { CONTROL_PLANE_HEALTH } from "../../control-plane-snapshot.js";
9
+ import { LAYOUT_MODES } from "../layout.js";
8
10
  import { COCKPIT_COLORS } from "../theme.js";
11
+ import {
12
+ overviewBrandTitle,
13
+ shouldShowWordmark,
14
+ wordmarkLines
15
+ } from "../brand/wordmark.js";
9
16
  import { ActionList, Callout, Details } from "./semantic.js";
10
17
 
11
18
  const DESTINATION_LABELS = {
@@ -48,6 +55,10 @@ export function buildOverviewDetails(model = {}) {
48
55
  if (typeof model.alerts?.count === "number") {
49
56
  lines.push(`Open alerts · ${model.alerts.count}`);
50
57
  }
58
+ const secondary = model.companionNextAction;
59
+ if (secondary?.title && secondary.kind !== "idle") {
60
+ lines.push(`Companion · ${secondary.title}`);
61
+ }
51
62
  if (lines.length === 0) return ["No extra evidence beyond the metrics above."];
52
63
  return lines;
53
64
  }
@@ -55,10 +66,15 @@ export function buildOverviewDetails(model = {}) {
55
66
  /**
56
67
  * Pure adapter: buildControlCenterModel → semantic overview props.
57
68
  * Callout / CTA / metrics never include paths or IDs.
69
+ * Primary action is always governance CTA — companion is secondary metrics/details only.
58
70
  */
59
71
  export function adaptControlCenterToOverview(model = {}) {
60
72
  const status = model.status ?? model.health ?? {};
61
73
  const next = model.nextAction ?? model.cta ?? {};
74
+ const companionMetrics = (model.companion?.lines ?? []).map((label, i) => ({
75
+ id: `companion-${i}`,
76
+ label
77
+ }));
62
78
  return {
63
79
  title: model.title ?? "Overview",
64
80
  callout: {
@@ -74,45 +90,89 @@ export function adaptControlCenterToOverview(model = {}) {
74
90
  metrics: [
75
91
  { id: "activity", label: `Activity · ${model.activity?.headline ?? "Idle"}` },
76
92
  { id: "alerts", label: `Alerts · ${model.alerts?.headline ?? "Alert data unavailable"}` },
77
- { id: "tokens", label: `Tokens · ${model.tokens?.headline ?? "Data unavailable"}` }
93
+ { id: "tokens", label: `Tokens · ${model.tokens?.headline ?? "Data unavailable"}` },
94
+ ...companionMetrics
78
95
  ],
79
96
  details: buildOverviewDetails(model)
80
97
  };
81
98
  }
82
99
 
100
+ function renderWordmark({ layoutMode, colorEnabled = true, unicode = true }) {
101
+ const lines = wordmarkLines(layoutMode, { unicode });
102
+ if (lines.length === 0) return null;
103
+ return React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
104
+ ...lines.map((line, i) => React.createElement(Text, {
105
+ key: `wm-${i}`,
106
+ bold: i === 0,
107
+ color: colorEnabled ? COCKPIT_COLORS.brand : undefined
108
+ }, line))
109
+ );
110
+ }
111
+
112
+ function renderCallout(view, colorEnabled) {
113
+ return React.createElement(Callout, {
114
+ tone: view.callout.tone,
115
+ title: view.callout.title,
116
+ body: view.callout.body,
117
+ colorEnabled,
118
+ compact: true
119
+ });
120
+ }
121
+
83
122
  export function SemanticOverviewPanel({
84
123
  model,
85
124
  detailsOpen = false,
86
125
  colorEnabled = true,
87
- unicode = true
126
+ unicode = true,
127
+ layoutMode = LAYOUT_MODES.COMPACT
88
128
  }) {
89
129
  const view = adaptControlCenterToOverview(model);
130
+ const showArt = shouldShowWordmark(layoutMode);
131
+ const brandTitle = overviewBrandTitle(layoutMode);
132
+ const isWide = layoutMode === LAYOUT_MODES.WIDE;
133
+ const mark = renderWordmark({ layoutMode, colorEnabled, unicode });
134
+ const status = renderCallout(view, colorEnabled);
135
+
136
+ const hero = showArt
137
+ ? (isWide
138
+ ? React.createElement(Box, { flexDirection: "row", marginBottom: 1 },
139
+ React.createElement(Box, { marginRight: 2 }, mark),
140
+ React.createElement(Box, { flexDirection: "column", flexGrow: 1 }, status)
141
+ )
142
+ : React.createElement(Box, { flexDirection: "column" }, mark, status))
143
+ : React.createElement(Box, { flexDirection: "column" },
144
+ React.createElement(Text, {
145
+ bold: true,
146
+ color: colorEnabled ? COCKPIT_COLORS.brand : undefined
147
+ }, brandTitle),
148
+ status
149
+ );
150
+
90
151
  return React.createElement(Box, { flexDirection: "column" },
91
- React.createElement(Text, {
92
- bold: true,
93
- color: colorEnabled ? COCKPIT_COLORS.secondary : undefined
94
- }, view.title),
95
- React.createElement(Callout, {
96
- tone: view.callout.tone,
97
- title: view.callout.title,
98
- body: view.callout.body,
99
- colorEnabled,
100
- compact: true
101
- }),
102
- React.createElement(Text, { bold: true }, ` ${view.primary.label}`),
103
- view.primary.detail
104
- ? React.createElement(Text, null, view.primary.detail)
105
- : null,
106
- view.primary.hint
107
- ? React.createElement(Text, { color: colorEnabled ? COCKPIT_COLORS.muted : undefined }, view.primary.hint)
108
- : null,
109
- React.createElement(ActionList, {
110
- items: view.metrics,
111
- selectedIndex: -1,
112
- focused: false,
113
- colorEnabled,
114
- unicode
115
- }),
152
+ hero,
153
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" },
154
+ React.createElement(Text, {
155
+ bold: true,
156
+ color: colorEnabled ? COCKPIT_COLORS.interactive : undefined
157
+ }, view.primary.label),
158
+ view.primary.detail
159
+ ? React.createElement(Text, null, view.primary.detail)
160
+ : null,
161
+ view.primary.hint
162
+ ? React.createElement(Text, {
163
+ color: colorEnabled ? COCKPIT_COLORS.muted : undefined
164
+ }, view.primary.hint)
165
+ : null
166
+ ),
167
+ React.createElement(Box, { marginTop: 1, flexDirection: "column" },
168
+ React.createElement(ActionList, {
169
+ items: view.metrics,
170
+ selectedIndex: -1,
171
+ focused: false,
172
+ colorEnabled,
173
+ unicode
174
+ })
175
+ ),
116
176
  React.createElement(Details, {
117
177
  open: detailsOpen,
118
178
  summary: "Details",
@@ -4,12 +4,11 @@
4
4
  */
5
5
  import React from "react";
6
6
  import { Box, Text } from "ink";
7
- import { COCKPIT_COLORS } from "../theme.js";
8
7
  import { LAYOUT_MODES } from "../layout.js";
9
8
  import {
10
9
  SETTINGS_PHASE, getCuratedIntegration, listCuratedIntegrations
11
10
  } from "../cockpit-settings.js";
12
- import { ActionList, Callout, Confirm, Details, Receipt } from "./semantic.js";
11
+ import { ActionList, Callout, Confirm, Details, Receipt, SectionLabel, ViewTitle } from "./semantic.js";
13
12
  import { windowSlice } from "./live-activity.js";
14
13
 
15
14
  export function settingsListLimit(layoutMode = LAYOUT_MODES.COMPACT) {
@@ -160,9 +159,7 @@ export function SemanticSettingsPanel({
160
159
  model.receipt && React.createElement(Receipt, {
161
160
  title: model.receipt.title, lines: model.receipt.lines, colorEnabled
162
161
  }),
163
- React.createElement(Text, {
164
- bold: true, color: colorEnabled ? COCKPIT_COLORS.secondary : undefined
165
- }, model.title),
162
+ React.createElement(ViewTitle, { colorEnabled }, model.title),
166
163
  React.createElement(Callout, {
167
164
  tone: model.callout.tone, title: model.callout.title,
168
165
  body: model.callout.body || undefined, colorEnabled, compact: true
@@ -176,7 +173,7 @@ export function SemanticSettingsPanel({
176
173
  focused: listFocused, colorEnabled, unicode
177
174
  }),
178
175
  model.profilePolicy.length > 0 && React.createElement(Box, { flexDirection: "column" },
179
- React.createElement(Text, { bold: true }, "Profile & Policy"),
176
+ React.createElement(SectionLabel, { colorEnabled }, "Profile & Policy"),
180
177
  React.createElement(ActionList, {
181
178
  items: model.profilePolicy, selectedIndex: -1, focused: false, colorEnabled, unicode
182
179
  })
@@ -7,7 +7,7 @@ import { Box, Text } from "ink";
7
7
  import { COCKPIT_COLORS } from "../theme.js";
8
8
  import { LAYOUT_MODES } from "../layout.js";
9
9
  import { adaptUsageModel } from "../cockpit-usage.js";
10
- import { ActionList, Callout } from "./semantic.js";
10
+ import { ActionList, Callout, SectionLabel, ViewTitle } from "./semantic.js";
11
11
 
12
12
  export function SemanticUsagePanel({
13
13
  snapshot = null,
@@ -19,9 +19,7 @@ export function SemanticUsagePanel({
19
19
  const model = adaptUsageModel({ snapshot, dashboard, layoutMode });
20
20
  const muted = colorEnabled ? COCKPIT_COLORS.muted : undefined;
21
21
  return React.createElement(Box, { flexDirection: "column" },
22
- React.createElement(Text, {
23
- bold: true, color: colorEnabled ? COCKPIT_COLORS.secondary : undefined
24
- }, model.title),
22
+ React.createElement(ViewTitle, { colorEnabled }, model.title),
25
23
  React.createElement(Callout, {
26
24
  tone: model.callout.tone,
27
25
  title: model.callout.title,
@@ -29,11 +27,11 @@ export function SemanticUsagePanel({
29
27
  colorEnabled,
30
28
  compact: true
31
29
  }),
32
- React.createElement(Text, { bold: true }, "Measured"),
30
+ React.createElement(SectionLabel, { colorEnabled }, "Measured"),
33
31
  React.createElement(Text, null, ` ${model.measured}`),
34
- React.createElement(Text, { bold: true }, "Configured limits"),
32
+ React.createElement(SectionLabel, { colorEnabled }, "Configured limits"),
35
33
  React.createElement(Text, null, ` ${model.configured}`),
36
- React.createElement(Text, { bold: true }, "Run usage"),
34
+ React.createElement(SectionLabel, { colorEnabled }, "Run usage"),
37
35
  model.runs.length === 0
38
36
  ? React.createElement(Text, null, " No auditable run tokenUsage yet.")
39
37
  : React.createElement(ActionList, {
@@ -4,6 +4,15 @@ import { Box, Text } from "ink";
4
4
  import { COCKPIT_COLORS, statusColor, resolveGlyphs } from "../theme.js";
5
5
 
6
6
  const mute = (on) => (on ? COCKPIT_COLORS.muted : undefined);
7
+ const ice = (on) => (on ? COCKPIT_COLORS.interactive : undefined);
8
+
9
+ /** Short typographic view title — brand amber, no border. */
10
+ export function ViewTitle({ children, colorEnabled = true }) {
11
+ return React.createElement(Text, {
12
+ bold: true,
13
+ color: colorEnabled ? COCKPIT_COLORS.brand : undefined
14
+ }, children);
15
+ }
7
16
 
8
17
  export function ActionList({ items = [], selectedIndex = 0, focused = true, colorEnabled = true, unicode = true }) {
9
18
  const g = resolveGlyphs(unicode);
@@ -13,7 +22,7 @@ export function ActionList({ items = [], selectedIndex = 0, focused = true, colo
13
22
  return React.createElement(Text, {
14
23
  key: item.id ?? String(i),
15
24
  bold: sel,
16
- color: sel && focused && colorEnabled ? COCKPIT_COLORS.primary : undefined
25
+ color: sel && focused && colorEnabled ? COCKPIT_COLORS.interactive : undefined
17
26
  }, `${sel && focused ? g.focus : " "} ${item.label}${item.hint ? ` ${item.hint}` : ""}`);
18
27
  })
19
28
  );
@@ -30,7 +39,7 @@ export function Stepper({ steps = [], currentIndex = 0, colorEnabled = true, uni
30
39
  const cur = i === currentIndex;
31
40
  const color = isDone
32
41
  ? (colorEnabled ? COCKPIT_COLORS.success : undefined)
33
- : cur ? (colorEnabled ? COCKPIT_COLORS.primary : undefined) : mute(colorEnabled);
42
+ : cur ? ice(colorEnabled) : mute(colorEnabled);
34
43
  return React.createElement(Text, {
35
44
  key: step.id ?? String(i), bold: cur, color
36
45
  }, `${isDone ? done : cur ? current : idle} ${i + 1}. ${step.label}`);
@@ -50,24 +59,24 @@ export function Callout({ tone = "info", title, body, colorEnabled = true, compa
50
59
  }
51
60
 
52
61
  export function Confirm({ summary, primaryLabel = "Confirm", focused = true, colorEnabled = true, mark = " " }) {
53
- return React.createElement(Box, { flexDirection: "column" },
62
+ return React.createElement(Box, { flexDirection: "column", marginY: 1 },
54
63
  summary ? React.createElement(Text, null, summary) : null,
55
64
  React.createElement(Text, {
56
65
  bold: focused,
57
- color: focused && colorEnabled ? COCKPIT_COLORS.primary : undefined
66
+ color: focused && colorEnabled ? COCKPIT_COLORS.interactive : undefined
58
67
  }, `${mark} ${primaryLabel}`)
59
68
  );
60
69
  }
61
70
 
62
71
  export function Receipt({ title = "Receipt", lines = [], colorEnabled = true }) {
63
- return React.createElement(Box, { flexDirection: "column" },
72
+ return React.createElement(Box, { flexDirection: "column", marginY: 1 },
64
73
  React.createElement(Text, { bold: true, color: colorEnabled ? COCKPIT_COLORS.success : undefined }, title),
65
74
  ...lines.map((line, i) => React.createElement(Text, { key: `r${i}`, color: mute(colorEnabled) }, line))
66
75
  );
67
76
  }
68
77
 
69
78
  export function Details({ open = false, summary = "Details", lines = [], colorEnabled = true, focused = false, mark = " " }) {
70
- const color = focused && colorEnabled ? COCKPIT_COLORS.primary : mute(colorEnabled);
79
+ const color = focused && colorEnabled ? COCKPIT_COLORS.interactive : mute(colorEnabled);
71
80
  if (!open) return React.createElement(Text, { bold: focused, color }, `${mark} ${summary} · Space`);
72
81
  return React.createElement(Box, { flexDirection: "column" },
73
82
  React.createElement(Text, { bold: true, color }, `${mark} ${summary}`),
@@ -82,3 +91,11 @@ export function KeyBar({ hints = [], colorEnabled = true, columns = 80 }) {
82
91
  hints.map((h) => `${h.keys} ${h.label}`).join(" · "))
83
92
  );
84
93
  }
94
+
95
+ /** Section label inside a panel — muted brand hierarchy under ViewTitle. */
96
+ export function SectionLabel({ children, colorEnabled = true }) {
97
+ return React.createElement(Text, {
98
+ bold: true,
99
+ color: colorEnabled ? COCKPIT_COLORS.muted : undefined
100
+ }, children);
101
+ }