@kal-elsam/kairo-runtime 0.13.0 → 0.13.1

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.
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Plain-language Overview needs — no machine noise on the first screen.
3
+ */
4
+ import { CONTROL_PLANE_HEALTH } from "../../control-plane-snapshot.js";
5
+ import { formatCliCommand } from "../../brand/cli.js";
6
+
7
+ export const OVERVIEW_NEED_LIMIT = 3;
8
+
9
+ /** Prefixes that never belong on the first screen (machine / internals). */
10
+ export const DETAILS_ONLY_PREFIXES = [
11
+ "System",
12
+ "Advisor",
13
+ "Soft links",
14
+ "Gentle",
15
+ "Graphify",
16
+ "Hermes"
17
+ ];
18
+
19
+ const DESTINATION_LABELS = {
20
+ setup: "Setup",
21
+ changes: "Governance",
22
+ ides: "Agents",
23
+ runs: "Orchestration",
24
+ "control-center": "Overview",
25
+ activity: "Activity",
26
+ usage: "Usage",
27
+ profile: "Settings"
28
+ };
29
+
30
+ export function mapHealthTone(kind) {
31
+ switch (kind) {
32
+ case CONTROL_PLANE_HEALTH.CHECK_FAILED:
33
+ return "danger";
34
+ case CONTROL_PLANE_HEALTH.ACTION_REQUIRED:
35
+ case CONTROL_PLANE_HEALTH.NOT_CONFIGURED:
36
+ case CONTROL_PLANE_HEALTH.HEALTHY_WITH_NOTES:
37
+ return "warn";
38
+ case CONTROL_PLANE_HEALTH.HEALTHY:
39
+ return "ready";
40
+ default:
41
+ return "warn";
42
+ }
43
+ }
44
+
45
+ /** Plain-language status title — never shouty ALL-CAPS jargon alone. */
46
+ export function humanizeHealthTitle(kind, fallback = "Unknown") {
47
+ switch (kind) {
48
+ case CONTROL_PLANE_HEALTH.NOT_CONFIGURED:
49
+ return "Needs setup";
50
+ case CONTROL_PLANE_HEALTH.ACTION_REQUIRED:
51
+ return "Needs attention";
52
+ case CONTROL_PLANE_HEALTH.CHECK_FAILED:
53
+ return "Something failed";
54
+ case CONTROL_PLANE_HEALTH.HEALTHY_WITH_NOTES:
55
+ return "Ready · with notes";
56
+ case CONTROL_PLANE_HEALTH.HEALTHY:
57
+ return "Ready";
58
+ default:
59
+ return typeof fallback === "string" && fallback ? fallback : "Unknown";
60
+ }
61
+ }
62
+
63
+ export function humanizeDestination(destination) {
64
+ if (!destination) return null;
65
+ return DESTINATION_LABELS[destination] ?? null;
66
+ }
67
+
68
+ /**
69
+ * Turn a raw companion line into a user-facing need, or null to skip.
70
+ * System/machine lines are never returned here.
71
+ */
72
+ export function humanizeCompanionNeed(line) {
73
+ if (typeof line !== "string" || line.trim().length === 0) return null;
74
+ if (/^\s/.test(line)) return null;
75
+
76
+ for (const prefix of DETAILS_ONLY_PREFIXES) {
77
+ if (line.startsWith(prefix)) return null;
78
+ }
79
+
80
+ if (line.startsWith("Obsidian · unconfigured")) {
81
+ return "Obsidian not connected · open Settings to choose your vault";
82
+ }
83
+ if (line.startsWith("Obsidian · missing")) {
84
+ return "Obsidian vault folder missing · check Settings";
85
+ }
86
+ if (line.startsWith("Obsidian · unavailable") || line.startsWith("Obsidian · error")) {
87
+ return "Obsidian unavailable · check Settings";
88
+ }
89
+ if (/^Updates · \d+\s+available/i.test(line)) {
90
+ return `Update available · run ${formatCliCommand("updates check")}`;
91
+ }
92
+ if (line.startsWith("Engram · conflict")) {
93
+ return "Memory conflict · open Settings → Engram";
94
+ }
95
+ if (line.startsWith("Engram · missing") || line.startsWith("Engram · error")) {
96
+ return "Memory not ready · open Settings → Engram";
97
+ }
98
+ return null;
99
+ }
100
+
101
+ /** Partition companion lines: plain needs for Overview, raw rest for Details. */
102
+ export function partitionCompanionLines(lines = []) {
103
+ const needs = [];
104
+ const rest = [];
105
+ for (const line of lines) {
106
+ if (typeof line !== "string" || line.trim().length === 0) continue;
107
+ const need = humanizeCompanionNeed(line);
108
+ if (need && needs.length < OVERVIEW_NEED_LIMIT) {
109
+ needs.push(need);
110
+ continue;
111
+ }
112
+ rest.push(line);
113
+ }
114
+ return { needs, rest };
115
+ }
116
+
117
+ export function humanizePrimary(next = {}) {
118
+ const kind = next.kind;
119
+ const detail = typeof next.actionDetail === "string" && next.actionDetail.trim()
120
+ ? next.actionDetail.trim()
121
+ : null;
122
+ switch (kind) {
123
+ case "setup":
124
+ return {
125
+ label: "Start setup",
126
+ detail: detail ?? `Run ${formatCliCommand("setup")} to configure agents for this project.`,
127
+ hint: "Enter → open Setup"
128
+ };
129
+ case "repair":
130
+ return {
131
+ label: "Fix drift",
132
+ detail: detail ?? `Run ${formatCliCommand("sync")} to repair managed content.`,
133
+ hint: "Enter → preview in Governance"
134
+ };
135
+ case "verify":
136
+ return {
137
+ label: "Check what failed",
138
+ detail: detail ?? `Run ${formatCliCommand("doctor")} for details.`,
139
+ hint: "Enter → reload"
140
+ };
141
+ case "review":
142
+ return {
143
+ label: "Review notes",
144
+ detail: detail ?? "Open Governance to inspect remaining notes.",
145
+ hint: "Enter → open"
146
+ };
147
+ case "idle":
148
+ return {
149
+ label: "All clear",
150
+ detail: detail ?? "No action needed right now.",
151
+ hint: null
152
+ };
153
+ default:
154
+ return {
155
+ label: next.actionTitle ?? "Review control plane",
156
+ detail,
157
+ hint: next.enterHint ?? "Enter →"
158
+ };
159
+ }
160
+ }