@kal-elsam/kairo-runtime 0.8.0 → 0.10.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 (49) hide show
  1. package/README.md +41 -15
  2. package/package.json +1 -1
  3. package/scripts/cockpit-smoke.mjs +6 -6
  4. package/scripts/ux-prototype-tty.mjs +9 -0
  5. package/src/cli.js +24 -1
  6. package/src/global/control-plane-proposals.js +2 -1
  7. package/src/global/control-plane-snapshot.js +1 -1
  8. package/src/global/global-doctor.js +2 -0
  9. package/src/global/ink/cockpit/primitives.js +127 -50
  10. package/src/global/ink/cockpit-alerts.js +36 -0
  11. package/src/global/ink/cockpit-changes.js +61 -37
  12. package/src/global/ink/cockpit-control-center.js +79 -53
  13. package/src/global/ink/cockpit-controller.js +98 -15
  14. package/src/global/ink/cockpit-enter.js +1 -0
  15. package/src/global/ink/cockpit-focus.js +4 -2
  16. package/src/global/ink/cockpit-models.js +100 -51
  17. package/src/global/ink/cockpit-palette.js +109 -0
  18. package/src/global/ink/cockpit-path-label.js +19 -0
  19. package/src/global/ink/cockpit-recovery.js +84 -18
  20. package/src/global/ink/cockpit-reviews.js +14 -10
  21. package/src/global/ink/cockpit-runs.js +13 -4
  22. package/src/global/ink/cockpit-settings.js +194 -0
  23. package/src/global/ink/cockpit-usage.js +111 -0
  24. package/src/global/ink/cockpit-views.js +119 -116
  25. package/src/global/ink/orchestrator-app.js +169 -46
  26. package/src/global/ink/orchestrator-state.js +24 -14
  27. package/src/global/ink/setup-app.js +55 -72
  28. package/src/global/ink/setup-state.js +16 -0
  29. package/src/global/ink/theme.js +27 -0
  30. package/src/global/ink/use-orchestrator-data.js +58 -0
  31. package/src/global/ink/ux/live-activity.js +194 -0
  32. package/src/global/ink/ux/live-alerts.js +159 -0
  33. package/src/global/ink/ux/live-governance.js +195 -0
  34. package/src/global/ink/ux/live-orchestration.js +188 -0
  35. package/src/global/ink/ux/live-overview.js +125 -0
  36. package/src/global/ink/ux/live-settings.js +189 -0
  37. package/src/global/ink/ux/live-setup.js +160 -0
  38. package/src/global/ink/ux/live-usage.js +51 -0
  39. package/src/global/ink/ux/semantic.js +84 -0
  40. package/src/global/ink/ux/task-flow-app.js +85 -0
  41. package/src/global/ink/ux/task-flow.js +173 -0
  42. package/src/global/orchestrator.js +37 -20
  43. package/src/global/paths.js +3 -0
  44. package/src/global/runtime/alerts/alert-store.js +216 -0
  45. package/src/global/runtime/alerts/alert-types.js +59 -0
  46. package/src/global/runtime/alerts/alert-validate.js +117 -0
  47. package/src/global/runtime/monitor/monitor-cli.js +62 -0
  48. package/src/global/runtime/monitor/monitor-platform.js +95 -0
  49. package/src/global/runtime/monitor/monitor.js +249 -0
@@ -1,4 +1,4 @@
1
- import { formatProposalLines, proposalLimitForLayout } from "./cockpit-proposals.js";
1
+ import { formatConfirmPath } from "./cockpit-path-label.js";
2
2
 
3
3
  export const CHANGES_PHASE = Object.freeze({
4
4
  IDLE: "idle",
@@ -62,53 +62,77 @@ export function reduceChangesAction(state, action) {
62
62
  }
63
63
  }
64
64
 
65
- export function formatChangesActionLines({ snapshot, changesAction, layoutMode = "compact" }) {
66
- const diff = snapshot?.diff;
65
+ function healthLabel(kind) {
66
+ return String(kind ?? "unknown").replaceAll("_", " ");
67
+ }
68
+
69
+ /**
70
+ * Governance surface: status, coverage, recommended action first.
71
+ * Paths only when detail=true or during confirm (home-relative / distinct).
72
+ */
73
+ export function formatChangesActionLines({
74
+ snapshot,
75
+ changesAction,
76
+ detail = false,
77
+ homeDir = null
78
+ } = {}) {
67
79
  const phase = changesAction?.phase ?? CHANGES_PHASE.IDLE;
68
- const lines = [`Changes · ${phase}`];
80
+ const coverage = snapshot?.coverage ?? {};
81
+ const diff = snapshot?.diff;
82
+ const cta = snapshot?.cta;
83
+ const pending = diff?.hasChanges
84
+ ? (diff.changeCount ?? diff.changes?.length ?? 0)
85
+ : 0;
86
+ const lines = [
87
+ "STATUS",
88
+ `${healthLabel(snapshot?.health)}${pending > 0 ? ` · ${pending} pending` : " · drift clean"}`,
89
+ "",
90
+ "COVERAGE",
91
+ `${coverage.governedAgents ?? 0}/${coverage.detectedAgents ?? 0} agents governed · ${coverage.components ?? 0} components`,
92
+ "",
93
+ "NEXT",
94
+ cta?.title ?? "Review governance when ready"
95
+ ];
96
+ if (cta?.detail) lines.push(cta.detail);
69
97
 
70
- const proposalLines = formatProposalLines(snapshot?.proposals ?? [], {
71
- limit: proposalLimitForLayout(layoutMode),
72
- destinationFilter: "changes",
73
- budgets: snapshot?.budgets ?? null
74
- });
75
- if (proposalLines[0] !== "No proposals targeting this view.") {
76
- lines.push(...proposalLines, "");
98
+ if (changesAction?.message) lines.push("", changesAction.message);
99
+ if (changesAction?.error && changesAction.error !== "setup-required") {
100
+ lines.push(`Error: ${changesAction.error}`);
77
101
  }
78
102
 
79
- if (changesAction?.message) lines.push(changesAction.message);
80
- if (changesAction?.error && changesAction.error !== "setup-required") lines.push(`Error: ${changesAction.error}`);
81
-
82
103
  const preview = changesAction?.preview;
83
- if (preview?.hasChanges) {
84
- lines.push(`${preview.changes?.length ?? 0} planned change(s)`);
85
- for (const change of preview.changes ?? []) {
86
- lines.push(`${change.action ?? change.kind} · ${change.target} · ${change.status ?? "planned"}`);
87
- }
88
- if (preview.integrations?.status && preview.integrations.status !== "skipped") {
89
- lines.push(`SDD lifecycle · ${preview.integrations.status}${preview.integrations.partial ? " (partial)" : ""}`);
90
- }
91
- if (preview.fingerprint) lines.push(`Fingerprint · ${preview.fingerprint.slice(0, 12)}…`);
92
- } else if (diff && !preview) {
93
- if (!diff.installed) lines.push(diff.summary ?? "Setup required before changes can be previewed.");
94
- else if (!diff.hasChanges) lines.push(diff.summary ?? "No pending governance changes.");
95
- else {
96
- lines.push(diff.summary ?? "Pending changes");
97
- for (const change of diff.changes ?? []) lines.push(`${change.action ?? change.kind} · ${change.target} · ${change.status}`);
104
+ const planned = preview?.hasChanges
105
+ ? (preview.changes ?? [])
106
+ : (diff?.hasChanges && !preview ? (diff.changes ?? []) : []);
107
+ if (planned.length > 0) {
108
+ lines.push("", `${planned.length} planned change(s)`);
109
+ const showDetail = detail || phase === CHANGES_PHASE.CONFIRMING;
110
+ if (showDetail) {
111
+ lines.push("DETAILS");
112
+ const limit = detail ? 12 : 3;
113
+ for (const change of planned.slice(0, limit)) {
114
+ lines.push(
115
+ `${change.action ?? change.kind} · ${formatConfirmPath(change.target, homeDir)}`
116
+ );
117
+ }
118
+ if (planned.length > limit) lines.push(`… ${planned.length - limit} more`);
98
119
  }
99
120
  } else if (!diff) {
100
- lines.push("Scan did not include diff yet. Press R to re-scan.");
121
+ lines.push("", "Scan did not include diff yet. Press R to re-scan.");
122
+ } else if (!diff.installed) {
123
+ lines.push("", diff.summary ?? "Setup required before changes can be previewed.");
124
+ } else if (!diff.hasChanges && !changesAction?.message) {
125
+ lines.push("", diff.summary ?? "No pending governance changes.");
101
126
  }
102
127
 
103
128
  const receipt = changesAction?.receipt;
104
129
  if (receipt) {
105
- lines.push("", `Receipt · ${receipt.action}`);
106
- if (receipt.backups?.length) lines.push(`Backups · ${receipt.backups.length}`);
107
- if (receipt.checksBefore && receipt.checksAfter) {
130
+ lines.push("", `Result · ${receipt.action}${receipt.partial ? " (partial)" : ""}`);
131
+ if (receipt.backups?.length) lines.push(`${receipt.backups.length} backup(s) retained`);
132
+ if (detail && receipt.checksBefore && receipt.checksAfter) {
133
+ lines.push("DETAILS");
108
134
  lines.push(`Checks · before ok=${receipt.checksBefore.ok} → after ok=${receipt.checksAfter.ok}`);
109
135
  }
110
- if (receipt.integrations) lines.push(`Integrations · ${receipt.integrations.status ?? "n/a"}`);
111
- if (receipt.partial) lines.push("Partial evidence retained — success not claimed.");
112
136
  }
113
137
 
114
138
  if (phase === CHANGES_PHASE.IDLE || phase === CHANGES_PHASE.COMPLETED || phase === CHANGES_PHASE.FAILED) {
@@ -119,6 +143,6 @@ export function formatChangesActionLines({ snapshot, changesAction, layoutMode =
119
143
 
120
144
  export function buildChangesFooterParts(phase) {
121
145
  if (phase === CHANGES_PHASE.PREVIEWING || phase === CHANGES_PHASE.APPLYING) return ["Working…", "Esc Back"];
122
- if (phase === CHANGES_PHASE.CONFIRMING) return ["Y Apply", "N/Esc Cancel"];
123
- return ["A Preview", "R Re-scan", "Esc Back"];
146
+ if (phase === CHANGES_PHASE.CONFIRMING) return ["Y Apply", "N/Esc Cancel", "Space"];
147
+ return ["A Preview", "R Re-scan", "Space", "Esc Back"];
124
148
  }
@@ -1,20 +1,32 @@
1
1
  import { CONTROL_PLANE_HEALTH } from "../control-plane-snapshot.js";
2
- import { formatProposalLines, proposalLimitForLayout } from "./cockpit-proposals.js";
2
+ import { formatAlertsHeadline } from "./cockpit-alerts.js";
3
+ import {
4
+ adaptUsageModel,
5
+ formatMeasuredBudgets,
6
+ formatUsageLinesFromModel
7
+ } from "./cockpit-usage.js";
3
8
 
4
9
  export function buildControlCenterModel({
5
10
  projectName = "project",
6
11
  snapshot = null,
7
- layoutMode = "compact"
12
+ dashboard = null,
13
+ layoutMode = "compact",
14
+ alerts = null
8
15
  } = {}) {
9
16
  if (!snapshot) {
10
17
  return {
11
- title: `CONTROL CENTER — ${projectName}`,
12
- purpose: "Kairo aligns installed IDEs and agents with this project's architecture, rules, tools, and workflows.",
18
+ title: `OVERVIEW — ${projectName}`,
19
+ purpose: "",
13
20
  health: {
14
21
  kind: CONTROL_PLANE_HEALTH.CHECK_FAILED,
15
22
  label: "CHECK FAILED",
16
23
  summaryLine: "Control-plane scan not available yet."
17
24
  },
25
+ status: {
26
+ kind: CONTROL_PLANE_HEALTH.CHECK_FAILED,
27
+ label: "CHECK FAILED",
28
+ summaryLine: "Control-plane scan not available yet."
29
+ },
18
30
  coverageLines: [],
19
31
  cta: {
20
32
  title: "NEXT",
@@ -24,54 +36,66 @@ export function buildControlCenterModel({
24
36
  kind: "verify",
25
37
  destination: null
26
38
  },
39
+ nextAction: {
40
+ title: "NEXT",
41
+ actionTitle: "Retry scan",
42
+ actionDetail: "Press R to reload the read-only governance scan.",
43
+ enterHint: "R Retry",
44
+ kind: "verify",
45
+ destination: null
46
+ },
27
47
  notes: [],
28
- proposalLines: ["No evidence-backed proposals."],
29
- includeEmbeddedStatus: layoutMode !== "wide"
48
+ proposalLines: [],
49
+ activity: { headline: "No activity yet" },
50
+ alerts: formatAlertsHeadline(alerts),
51
+ tokens: { headline: "Data unavailable" },
52
+ includeEmbeddedStatus: layoutMode !== "wide",
53
+ runsSecondaryHint: "Detail via Enter · / actions"
30
54
  };
31
55
  }
32
56
 
33
57
  const healthLabel = formatHealthLabel(snapshot.health);
34
58
  const coverage = snapshot.coverage ?? {};
35
- const policy = snapshot.policy;
36
- const warnings = snapshot.status?.counts?.warning ?? 0;
59
+ const active = dashboard?.activeRuns?.length ?? snapshot.runtime?.activeRuns ?? 0;
60
+ const recent = dashboard?.recentRuns?.[0] ?? null;
61
+ const health = {
62
+ kind: snapshot.health,
63
+ label: healthLabel,
64
+ summaryLine: [
65
+ `${coverage.governedAgents ?? 0}/${coverage.detectedAgents ?? 0} agents governed`,
66
+ snapshot.diff?.hasChanges ? "drift pending" : "drift clean"
67
+ ].join(" · ")
68
+ };
69
+ const cta = {
70
+ title: "NEXT",
71
+ actionTitle: snapshot.cta?.title ?? "Review control plane",
72
+ actionDetail: snapshot.cta?.detail ?? "",
73
+ enterHint: "Enter again →",
74
+ kind: snapshot.cta?.kind ?? null,
75
+ destination: snapshot.cta?.destination ?? null
76
+ };
37
77
 
38
78
  return {
39
- title: `CONTROL CENTER — ${projectName}`,
40
- purpose: "Kairo aligns installed IDEs and agents with this project's architecture, rules, tools, and workflows.",
41
- health: {
42
- kind: snapshot.health,
43
- label: healthLabel,
44
- summaryLine: [
45
- `${coverage.governedAgents ?? 0}/${coverage.detectedAgents ?? 0} agents governed`,
46
- `${coverage.components ?? 0} modules`,
47
- `${snapshot.backups?.count ?? 0} backups`
48
- ].join(" · ")
49
- },
50
- coverageLines: [
51
- `Active modules: ${(coverage.activeModules ?? []).join(", ") || "none"}`,
52
- `Policy: ${policy?.profile ?? "none"} · applyMode ${policy?.applyMode ?? "n/a"}`,
53
- warnings > 0
54
- ? `Notes: ${warnings} non-blocking check warning(s)`
55
- : "Notes: none",
56
- snapshot.diff?.hasChanges
57
- ? `Drift: ${snapshot.diff.changeCount ?? snapshot.diff.changes?.length ?? 0} change(s) pending review`
58
- : "Drift: clean"
59
- ],
60
- cta: {
61
- title: "NEXT",
62
- actionTitle: snapshot.cta?.title ?? "Review control plane",
63
- actionDetail: snapshot.cta?.detail ?? "",
64
- enterHint: "Enter again →",
65
- kind: snapshot.cta?.kind ?? null,
66
- destination: snapshot.cta?.destination ?? null
79
+ title: `OVERVIEW — ${projectName}`,
80
+ purpose: "",
81
+ health,
82
+ status: health,
83
+ coverageLines: [],
84
+ cta,
85
+ nextAction: cta,
86
+ notes: [],
87
+ proposalLines: [],
88
+ activity: {
89
+ headline: active > 0
90
+ ? `${active} active run${active === 1 ? "" : "s"}`
91
+ : recent?.agentId
92
+ ? `Last · ${recent.agentId} · ${recent.state ?? "done"}`
93
+ : "Idle"
67
94
  },
68
- notes: buildNotes(snapshot),
69
- proposalLines: formatProposalLines(snapshot.proposals ?? [], {
70
- limit: proposalLimitForLayout(layoutMode),
71
- budgets: snapshot.budgets ?? null
72
- }),
95
+ alerts: formatAlertsHeadline(alerts),
96
+ tokens: { headline: formatTokenHeadline(snapshot.budgets) },
73
97
  includeEmbeddedStatus: layoutMode !== "wide",
74
- runsSecondaryHint: "Runs remain available as a secondary capability after setup and repairs."
98
+ runsSecondaryHint: "Detail via Enter · / actions"
75
99
  };
76
100
  }
77
101
 
@@ -92,15 +116,17 @@ function formatHealthLabel(kind) {
92
116
  }
93
117
  }
94
118
 
95
- function buildNotes(snapshot) {
96
- const notes = [];
97
- for (const check of snapshot.status?.checks ?? []) {
98
- if (check.status === "warning") {
99
- notes.push(`${check.name}: ${check.detail ?? check.status}`);
100
- }
101
- }
102
- if (notes.length === 0 && snapshot.health === CONTROL_PLANE_HEALTH.HEALTHY_WITH_NOTES) {
103
- notes.push("Non-blocking notes are present. Open IDEs & models or Harness modules for detail.");
104
- }
105
- return notes.slice(0, 6);
119
+ function formatTokenHeadline(budgets) {
120
+ return formatMeasuredBudgets(budgets) ?? "Data unavailable";
121
+ }
122
+
123
+ /** Usage surface via shared auditable model — never invent totals. */
124
+ export function formatUsageLines({
125
+ snapshot = null, dashboard = null, layoutMode = undefined
126
+ } = {}) {
127
+ return formatUsageLinesFromModel(adaptUsageModel({ snapshot, dashboard, layoutMode }));
128
+ }
129
+
130
+ export function hasAuditableUsage({ snapshot = null, dashboard = null } = {}) {
131
+ return adaptUsageModel({ snapshot, dashboard }).hasEvidence;
106
132
  }
@@ -33,7 +33,12 @@ export function createCockpitUiState({
33
33
  navIndex = 0,
34
34
  listIndex = 0,
35
35
  helpOpen = false,
36
- returnView = null
36
+ returnView = null,
37
+ paletteOpen = false,
38
+ paletteIndex = 0,
39
+ overviewDetailsOpen = false,
40
+ governanceDetailsOpen = false,
41
+ activityDetailsOpen = false
37
42
  } = {}) {
38
43
  const regions = regionsForLayout(layoutMode);
39
44
  const preferred = region ?? defaultRegionForView(view, layoutMode);
@@ -48,12 +53,57 @@ export function createCockpitUiState({
48
53
  listIndex: Math.max(0, listIndex),
49
54
  helpOpen,
50
55
  returnView,
56
+ paletteOpen,
57
+ paletteIndex: Math.max(0, paletteIndex),
58
+ overviewDetailsOpen: Boolean(overviewDetailsOpen),
59
+ governanceDetailsOpen: Boolean(governanceDetailsOpen),
60
+ activityDetailsOpen: Boolean(activityDetailsOpen),
51
61
  shouldExit: false
52
62
  };
53
63
  }
54
64
 
65
+ function closePalette(state) {
66
+ return { ...state, paletteOpen: false, paletteIndex: 0 };
67
+ }
68
+
55
69
  export function reduceCockpitUi(state, action) {
56
70
  switch (action.type) {
71
+ case "toggle-palette":
72
+ if (state.paletteOpen) return closePalette(state);
73
+ return { ...state, paletteOpen: true, paletteIndex: 0, helpOpen: false };
74
+ case "close-palette":
75
+ return closePalette(state);
76
+ case "palette-arrow": {
77
+ const max = Math.max(0, (action.listLength ?? 1) - 1);
78
+ const delta = action.direction === "up" ? -1 : 1;
79
+ return {
80
+ ...state,
81
+ paletteIndex: clamp(state.paletteIndex + delta, 0, max)
82
+ };
83
+ }
84
+ case "run-palette": {
85
+ const next = closePalette(state);
86
+ if (action.kind === "help") {
87
+ return {
88
+ ...next,
89
+ helpOpen: true,
90
+ view: ORCHESTRATOR_VIEWS.HELP,
91
+ region: defaultRegionForView(ORCHESTRATOR_VIEWS.HELP, state.layoutMode)
92
+ };
93
+ }
94
+ if (action.kind === "navigate" && action.view) {
95
+ return {
96
+ ...next,
97
+ view: action.view,
98
+ navIndex: navIndexForView(action.view),
99
+ listIndex: 0,
100
+ region: defaultRegionForView(action.view, state.layoutMode),
101
+ helpOpen: false,
102
+ returnView: null
103
+ };
104
+ }
105
+ return next;
106
+ }
57
107
  case "resize": {
58
108
  const regions = regionsForLayout(action.layoutMode);
59
109
  const preferred = regions.includes(state.region)
@@ -95,18 +145,21 @@ export function reduceCockpitUi(state, action) {
95
145
  case "enter-nav": {
96
146
  const item = COCKPIT_NAV[state.navIndex];
97
147
  if (!item) return state;
98
- return {
148
+ return closePalette({
99
149
  ...state,
100
150
  view: item.view,
101
151
  listIndex: 0,
102
152
  region: defaultRegionForView(item.view, state.layoutMode),
103
153
  helpOpen: false,
104
- returnView: null
105
- };
154
+ returnView: null,
155
+ overviewDetailsOpen: false,
156
+ governanceDetailsOpen: false,
157
+ activityDetailsOpen: false
158
+ });
106
159
  }
107
160
  case "set-view": {
108
161
  const nextView = action.view;
109
- return {
162
+ return closePalette({
110
163
  ...state,
111
164
  view: nextView,
112
165
  listIndex: 0,
@@ -115,20 +168,47 @@ export function reduceCockpitUi(state, action) {
115
168
  : clamp(action.navIndex, 0, COCKPIT_NAV.length - 1),
116
169
  region: action.region ?? defaultRegionForView(nextView, state.layoutMode),
117
170
  returnView: action.returnView ?? state.returnView,
118
- helpOpen: nextView === ORCHESTRATOR_VIEWS.HELP
119
- };
171
+ helpOpen: nextView === ORCHESTRATOR_VIEWS.HELP,
172
+ overviewDetailsOpen: false,
173
+ governanceDetailsOpen: false,
174
+ activityDetailsOpen: false
175
+ });
120
176
  }
177
+ case "toggle-overview-details":
178
+ if (state.view !== ORCHESTRATOR_VIEWS.HOME) return state;
179
+ return { ...state, overviewDetailsOpen: !state.overviewDetailsOpen };
180
+ case "toggle-governance-details":
181
+ if (state.view !== ORCHESTRATOR_VIEWS.CHANGES) return state;
182
+ return { ...state, governanceDetailsOpen: !state.governanceDetailsOpen };
183
+ case "toggle-activity-details":
184
+ if (state.view !== ORCHESTRATOR_VIEWS.ACTIVITY) return state;
185
+ return { ...state, activityDetailsOpen: !state.activityDetailsOpen };
121
186
  case "toggle-help":
122
187
  if (state.helpOpen || state.view === ORCHESTRATOR_VIEWS.HELP) {
123
188
  return goOverview(state);
124
189
  }
125
- return {
190
+ return closePalette({
126
191
  ...state,
127
192
  helpOpen: true,
128
193
  view: ORCHESTRATOR_VIEWS.HELP,
129
- region: defaultRegionForView(ORCHESTRATOR_VIEWS.HELP, state.layoutMode)
130
- };
194
+ region: defaultRegionForView(ORCHESTRATOR_VIEWS.HELP, state.layoutMode),
195
+ overviewDetailsOpen: false,
196
+ governanceDetailsOpen: false,
197
+ activityDetailsOpen: false
198
+ });
131
199
  case "escape": {
200
+ if (state.paletteOpen) {
201
+ return closePalette(state);
202
+ }
203
+ if (state.view === ORCHESTRATOR_VIEWS.HOME && state.overviewDetailsOpen) {
204
+ return { ...state, overviewDetailsOpen: false };
205
+ }
206
+ if (state.view === ORCHESTRATOR_VIEWS.CHANGES && state.governanceDetailsOpen) {
207
+ return { ...state, governanceDetailsOpen: false };
208
+ }
209
+ if (state.view === ORCHESTRATOR_VIEWS.ACTIVITY && state.activityDetailsOpen) {
210
+ return { ...state, activityDetailsOpen: false };
211
+ }
132
212
  if (state.helpOpen || state.view === ORCHESTRATOR_VIEWS.HELP) {
133
213
  return goOverview(state);
134
214
  }
@@ -174,19 +254,22 @@ export function resolveNavAction(navIndex) {
174
254
  }
175
255
 
176
256
  function goOverview(state) {
177
- return {
257
+ return closePalette({
178
258
  ...state,
179
259
  helpOpen: false,
180
260
  view: ORCHESTRATOR_VIEWS.HOME,
181
261
  navIndex: 0,
182
262
  listIndex: 0,
183
263
  region: defaultRegionForView(ORCHESTRATOR_VIEWS.HOME, state.layoutMode),
184
- returnView: null
185
- };
264
+ returnView: null,
265
+ overviewDetailsOpen: false,
266
+ governanceDetailsOpen: false,
267
+ activityDetailsOpen: false
268
+ });
186
269
  }
187
270
 
188
271
  function goRunsHub(state) {
189
- return {
272
+ return closePalette({
190
273
  ...state,
191
274
  helpOpen: false,
192
275
  view: ORCHESTRATOR_VIEWS.RUNS,
@@ -194,5 +277,5 @@ function goRunsHub(state) {
194
277
  listIndex: 0,
195
278
  region: defaultRegionForView(ORCHESTRATOR_VIEWS.RUNS, state.layoutMode),
196
279
  returnView: null
197
- };
280
+ });
198
281
  }
@@ -14,6 +14,7 @@ export function resolveEnterNavIntent({
14
14
  const isOverview = navItem.id === "overview" || navItem.view === ORCHESTRATOR_VIEWS.HOME;
15
15
  if (isOverview) {
16
16
  if (currentView === ORCHESTRATOR_VIEWS.HOME && ctaDestination) {
17
+ if (ctaDestination === "setup") return { kind: "activate-setup" };
17
18
  return { kind: "activate-cta", destination: ctaDestination };
18
19
  }
19
20
  return { kind: "open-nav", view: ORCHESTRATOR_VIEWS.HOME };
@@ -7,9 +7,9 @@ const NAV_FOCUSED_VIEWS = new Set([
7
7
  ORCHESTRATOR_VIEWS.IDES,
8
8
  ORCHESTRATOR_VIEWS.MODULES,
9
9
  ORCHESTRATOR_VIEWS.CHANGES,
10
- ORCHESTRATOR_VIEWS.PROFILE,
11
10
  ORCHESTRATOR_VIEWS.PROVIDERS,
12
11
  ORCHESTRATOR_VIEWS.DIAGNOSTICS,
12
+ ORCHESTRATOR_VIEWS.USAGE,
13
13
  ORCHESTRATOR_VIEWS.HELP
14
14
  ]);
15
15
 
@@ -20,8 +20,10 @@ const CONTENT_INTERACTIVE_VIEWS = new Set([
20
20
  ORCHESTRATOR_VIEWS.RUN_DETAIL,
21
21
  ORCHESTRATOR_VIEWS.REVIEWS,
22
22
  ORCHESTRATOR_VIEWS.REVIEW_DETAIL,
23
+ ORCHESTRATOR_VIEWS.ALERTS,
23
24
  ORCHESTRATOR_VIEWS.LAUNCH,
24
- ORCHESTRATOR_VIEWS.ACTIVITY
25
+ ORCHESTRATOR_VIEWS.ACTIVITY,
26
+ ORCHESTRATOR_VIEWS.PROFILE
25
27
  ]);
26
28
 
27
29
  export function isNavFocusedView(view) {