@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
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: source-driven-development
3
+ description: Grounds every implementation decision in official documentation. Use when you want authoritative, source-cited code free from outdated patterns. Use when building with any framework or library where correctness matters.
4
+ ---
5
+
6
+ # Source-Driven Development
7
+
8
+ ## Overview
9
+
10
+ Every framework-specific code decision must be backed by official documentation. Don't implement from memory — verify, cite, and let the user see your sources. Training data goes stale, APIs get deprecated, best practices evolve. This skill ensures the user gets code they can trust because every pattern traces back to an authoritative source they can check.
11
+
12
+ ## When to Use
13
+
14
+ - The user wants code that follows current best practices for a given framework
15
+ - Building boilerplate, starter code, or patterns that will be copied across a project
16
+ - The user explicitly asks for documented, verified, or "correct" implementation
17
+ - Implementing features where the framework's recommended approach matters (forms, routing, data fetching, state management, auth)
18
+ - Reviewing or improving code that uses framework-specific patterns
19
+ - Any time you are about to write framework-specific code from memory
20
+
21
+ **When NOT to use:**
22
+
23
+ - Correctness does not depend on a specific version (renaming variables, fixing typos, moving files)
24
+ - Pure logic that works the same across all versions (loops, conditionals, data structures)
25
+ - The user explicitly wants speed over verification ("just do it quickly")
26
+
27
+ ## The Process
28
+
29
+ ```
30
+ DETECT ──→ FETCH ──→ IMPLEMENT ──→ CITE
31
+ │ │ │ │
32
+ ▼ ▼ ▼ ▼
33
+ What Get the Follow the Show your
34
+ stack? relevant documented sources
35
+ docs patterns
36
+ ```
37
+
38
+ ### Step 1: Detect Stack and Versions
39
+
40
+ Read the project's dependency file to identify exact versions:
41
+
42
+ ```
43
+ package.json → Node/React/Vue/Angular/Svelte
44
+ composer.json → PHP/Symfony/Laravel
45
+ requirements.txt / pyproject.toml → Python/Django/Flask
46
+ go.mod → Go
47
+ Cargo.toml → Rust
48
+ Gemfile → Ruby/Rails
49
+ ```
50
+
51
+ State what you found explicitly:
52
+
53
+ ```
54
+ STACK DETECTED:
55
+ - React 19.1.0 (from package.json)
56
+ - Vite 6.2.0
57
+ - Tailwind CSS 4.0.3
58
+ → Fetching official docs for the relevant patterns.
59
+ ```
60
+
61
+ If versions are missing or ambiguous, **ask the user**. Don't guess — the version determines which patterns are correct.
62
+
63
+ ### Step 2: Fetch Official Documentation
64
+
65
+ Fetch the specific documentation page for the feature you're implementing. Not the homepage, not the full docs — the relevant page.
66
+
67
+ **Source hierarchy (in order of authority):**
68
+
69
+ | Priority | Source | Example |
70
+ |----------|--------|---------|
71
+ | 1 | Official documentation | react.dev, docs.djangoproject.com, symfony.com/doc |
72
+ | 2 | Official blog / changelog | react.dev/blog, nextjs.org/blog |
73
+ | 3 | Web standards references | MDN, web.dev, html.spec.whatwg.org |
74
+ | 4 | Browser/runtime compatibility | caniuse.com, node.green |
75
+
76
+ **Not authoritative — never cite as primary sources:**
77
+
78
+ - Stack Overflow answers
79
+ - Blog posts or tutorials (even popular ones)
80
+ - AI-generated documentation or summaries
81
+ - Your own training data (that is the whole point — verify it)
82
+
83
+ **Be precise with what you fetch:**
84
+
85
+ ```
86
+ BAD: Fetch the React homepage
87
+ GOOD: Fetch react.dev/reference/react/useActionState
88
+
89
+ BAD: Search "django authentication best practices"
90
+ GOOD: Fetch docs.djangoproject.com/en/6.0/topics/auth/
91
+ ```
92
+
93
+ After fetching, extract the key patterns and note any deprecation warnings or migration guidance.
94
+
95
+ When official sources conflict with each other (e.g. a migration guide contradicts the API reference), surface the discrepancy to the user and verify which pattern actually works against the detected version.
96
+
97
+ ### Step 3: Implement Following Documented Patterns
98
+
99
+ Write code that matches what the documentation shows:
100
+
101
+ - Use the API signatures from the docs, not from memory
102
+ - If the docs show a new way to do something, use the new way
103
+ - If the docs deprecate a pattern, don't use the deprecated version
104
+ - If the docs don't cover something, flag it as unverified
105
+
106
+ **When docs conflict with existing project code:**
107
+
108
+ ```
109
+ CONFLICT DETECTED:
110
+ The existing codebase uses useState for form loading state,
111
+ but React 19 docs recommend useActionState for this pattern.
112
+ (Source: react.dev/reference/react/useActionState)
113
+
114
+ Options:
115
+ A) Use the modern pattern (useActionState) — consistent with current docs
116
+ B) Match existing code (useState) — consistent with codebase
117
+ → Which approach do you prefer?
118
+ ```
119
+
120
+ Surface the conflict. Don't silently pick one.
121
+
122
+ ### Step 4: Cite Your Sources
123
+
124
+ Every framework-specific pattern gets a citation. The user must be able to verify every decision.
125
+
126
+ **In code comments:**
127
+
128
+ ```typescript
129
+ // React 19 form handling with useActionState
130
+ // Source: https://react.dev/reference/react/useActionState#usage
131
+ const [state, formAction, isPending] = useActionState(submitOrder, initialState);
132
+ ```
133
+
134
+ **In conversation:**
135
+
136
+ ```
137
+ I'm using useActionState instead of manual useState for the
138
+ form submission state. React 19 replaced the manual
139
+ isPending/setIsPending pattern with this hook.
140
+
141
+ Source: https://react.dev/blog/2024/12/05/react-19#actions
142
+ "useTransition now supports async functions [...] to handle
143
+ pending states automatically"
144
+ ```
145
+
146
+ **Citation rules:**
147
+
148
+ - Full URLs, not shortened
149
+ - Prefer deep links with anchors where possible (e.g. `/useActionState#usage` over `/useActionState`) — anchors survive doc restructuring better than top-level pages
150
+ - Quote the relevant passage when it supports a non-obvious decision
151
+ - Include browser/runtime support data when recommending platform features
152
+ - If you cannot find documentation for a pattern, say so explicitly:
153
+
154
+ ```
155
+ UNVERIFIED: I could not find official documentation for this
156
+ pattern. This is based on training data and may be outdated.
157
+ Verify before using in production.
158
+ ```
159
+
160
+ Honesty about what you couldn't verify is more valuable than false confidence.
161
+
162
+ ## Common Rationalizations
163
+
164
+ | Rationalization | Reality |
165
+ |---|---|
166
+ | "I'm confident about this API" | Confidence is not evidence. Training data contains outdated patterns that look correct but break against current versions. Verify. |
167
+ | "Fetching docs wastes tokens" | Hallucinating an API wastes more. The user debugs for an hour, then discovers the function signature changed. One fetch prevents hours of rework. |
168
+ | "The docs won't have what I need" | If the docs don't cover it, that's valuable information — the pattern may not be officially recommended. |
169
+ | "I'll just mention it might be outdated" | A disclaimer doesn't help. Either verify and cite, or clearly flag it as unverified. Hedging is the worst option. |
170
+ | "This is a simple task, no need to check" | Simple tasks with wrong patterns become templates. The user copies your deprecated form handler into ten components before discovering the modern approach exists. |
171
+
172
+ ## Red Flags
173
+
174
+ - Writing framework-specific code without checking the docs for that version
175
+ - Using "I believe" or "I think" about an API instead of citing the source
176
+ - Implementing a pattern without knowing which version it applies to
177
+ - Citing Stack Overflow or blog posts instead of official documentation
178
+ - Using deprecated APIs because they appear in training data
179
+ - Not reading `package.json` / dependency files before implementing
180
+ - Delivering code without source citations for framework-specific decisions
181
+ - Fetching an entire docs site when only one page is relevant
182
+
183
+ ## Verification
184
+
185
+ After implementing with source-driven development:
186
+
187
+ - [ ] Framework and library versions were identified from the dependency file
188
+ - [ ] Official documentation was fetched for framework-specific patterns
189
+ - [ ] All sources are official documentation, not blog posts or training data
190
+ - [ ] Code follows the patterns shown in the current version's documentation
191
+ - [ ] Non-trivial decisions include source citations with full URLs
192
+ - [ ] No deprecated APIs are used (checked against migration guides)
193
+ - [ ] Conflicts between docs and existing code were surfaced to the user
194
+ - [ ] Anything that could not be verified is explicitly flagged as unverified
@@ -108,6 +108,35 @@
108
108
  "claude": "- Graphify CLI is not auto-installed; run `graphify update .` after code changes when graphify is in PATH.",
109
109
  "opencode": "- Graphify CLI is not auto-installed; run `graphify update .` after code changes when graphify is in PATH."
110
110
  }
111
+ },
112
+ {
113
+ "id": "agent-skills",
114
+ "kind": "component",
115
+ "label": "Agent Skills (complementary)",
116
+ "version": "1.0.0",
117
+ "defaultEnabled": false,
118
+ "capabilities": ["skills.complementary"],
119
+ "dependencies": [],
120
+ "healthChecks": [
121
+ { "id": "assets", "type": "assets" },
122
+ { "id": "drift", "type": "drift" }
123
+ ],
124
+ "assetFiles": [
125
+ "LICENSE",
126
+ "PROVENANCE.md",
127
+ "skills/context-engineering/SKILL.md",
128
+ "skills/source-driven-development/SKILL.md",
129
+ "skills/frontend-ui-engineering/SKILL.md",
130
+ "skills/performance-optimization/SKILL.md",
131
+ "skills/observability-and-instrumentation/SKILL.md"
132
+ ],
133
+ "adapterHints": {
134
+ "cursor": "- Complementary only; Gentle AI remains methodological authority. After install, run `gentle-ai skill-registry refresh` when available.",
135
+ "codex": "- Complementary only; Gentle AI remains methodological authority. After install, run `gentle-ai skill-registry refresh` when available.",
136
+ "claude": "- Complementary only; Gentle AI remains methodological authority. After install, run `gentle-ai skill-registry refresh` when available.",
137
+ "opencode": "- Complementary only; Gentle AI remains methodological authority. After install, run `gentle-ai skill-registry refresh` when available.",
138
+ "pi": "- Complementary only; Gentle AI remains methodological authority. Skills load from the shared Agent Skills root when linked; do not replace Gentle AI SDD/review gates."
139
+ }
111
140
  }
112
141
  ]
113
142
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kal-elsam/kairo-runtime",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Kairo Runtime — local agent operating system for Codex, Cursor, Claude, Pi, Engram, and Graphify.",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/Kal-elSam/harness#readme",
@@ -30,6 +30,7 @@
30
30
  ],
31
31
  "scripts": {
32
32
  "test": "node --test",
33
+ "test:cool": "node --test --test-concurrency=1",
33
34
  "doctor": "node ./bin/kairo.js doctor",
34
35
  "smoke": "bash scripts/smoke-test.sh",
35
36
  "ux:smoke": "bash scripts/ux-smoke-test.sh",
@@ -61,8 +62,10 @@
61
62
  },
62
63
  "dependencies": {
63
64
  "@clack/prompts": "^1.7.0",
65
+ "@modelcontextprotocol/server": "2.0.0",
64
66
  "ansi-escapes": "^7.3.0",
65
67
  "ink": "^5.2.1",
66
- "react": "^18.3.1"
68
+ "react": "^18.3.1",
69
+ "zod": "4.4.3"
67
70
  }
68
71
  }
@@ -26,7 +26,7 @@ const root = join(dirname(fileURLToPath(import.meta.url)), "..");
26
26
  const require = createRequire(import.meta.url);
27
27
  const pkg = require(join(root, "package.json"));
28
28
 
29
- assert.equal(pkg.version, "0.10.0");
29
+ assert.equal(pkg.version, "0.11.0");
30
30
  assert.ok(pkg.dependencies["ansi-escapes"]);
31
31
 
32
32
  assert.equal(resolveLayoutMode({ columns: 120, rows: 40 }), LAYOUT_MODES.WIDE);
package/src/cli.js CHANGED
@@ -32,6 +32,7 @@ import {
32
32
  runGlobalHistory,
33
33
  runGlobalReport
34
34
  } from "./global/global-cli.js";
35
+ import { runEcosystemUpdatesCheck } from "./global/updates-cli.js";
35
36
  import { applyPolicyToOptions, loadPolicyFile } from "./global/policy.js";
36
37
  import { resolveHomeDir } from "./global/paths.js";
37
38
  import { runWorkspaceDetect, runWorkspaceDoctor, runWorkspaceInit, runWorkspaceUpdate } from "./workspace-cli.js";
@@ -40,6 +41,9 @@ import { runIntelligenceCli } from "./global/intelligence-cli.js";
40
41
  import { runGlobalRun, runGlobalRuns } from "./global/runtime/run-cli.js";
41
42
  import { runGlobalReview, runGlobalReviews } from "./global/runtime/review/review-cli.js";
42
43
  import { runGlobalMonitor } from "./global/runtime/monitor/monitor-cli.js";
44
+ import { runGlobalAlerts } from "./global/runtime/alerts/alert-cli.js";
45
+ import { runGraphifyCli } from "./global/observability/graphify-ops.js";
46
+ import { runKairoMcp } from "./global/mcp/kairo-mcp.js";
43
47
  import { normalizeRunStrategy } from "./global/runtime/run-strategy.js";
44
48
  import {
45
49
  LEGACY_PACKAGE_NAME,
@@ -123,6 +127,21 @@ export async function runCli(argv) {
123
127
  case "monitor":
124
128
  await runGlobalMonitor(optionsWithPolicy, packageManifest, { packageRoot });
125
129
  return;
130
+ case "alerts":
131
+ await runGlobalAlerts(optionsWithPolicy);
132
+ return;
133
+ case "graphify":
134
+ await runGraphifyCli(optionsWithPolicy, packageManifest);
135
+ return;
136
+ case "mcp":
137
+ // stdout reserved for MCP protocol — no banners/logs here
138
+ await runKairoMcp({
139
+ cwd: optionsWithPolicy.cwd,
140
+ packageRoot,
141
+ packageName: packageManifest.name,
142
+ version: packageManifest.version
143
+ });
144
+ return;
126
145
  case "intelligence":
127
146
  await runIntelligenceCli(optionsWithPolicy, packageManifest);
128
147
  return;
@@ -142,6 +161,9 @@ export async function runCli(argv) {
142
161
  case "upgrade":
143
162
  await runGlobalUpgrade(optionsWithPolicy, packageManifest, packageRoot);
144
163
  return;
164
+ case "updates":
165
+ await runEcosystemUpdatesCheck(optionsWithPolicy, packageManifest);
166
+ return;
145
167
  case "install":
146
168
  await dispatchByScope(options, "agent-global", {
147
169
  "agent-global": () => runGlobalInstall(options, packageManifest, packageRoot),
@@ -384,9 +406,18 @@ export function parseArgs(argv) {
384
406
  runsAction: null,
385
407
  runId: null,
386
408
  reviewId: null,
409
+ lineage: null,
387
410
  reviewsAction: null,
411
+ confirmImport: false,
412
+ alertsAction: null,
413
+ alertId: null,
414
+ confirmResolve: false,
415
+ confirmDismiss: false,
416
+ graphifyAction: null, graphifyArgs: [], graphifyBudget: null, graphPath: null,
417
+ updatesAction: "check",
388
418
  base: null,
389
419
  commit: null,
420
+ staged: false,
390
421
  failOn: null,
391
422
  agent: null,
392
423
  task: null,
@@ -394,6 +425,7 @@ export function parseArgs(argv) {
394
425
  strategy: "direct",
395
426
  intelligenceBackend: null,
396
427
  permissions: null,
428
+ allowUnsafePermissions: false,
397
429
  captureTranscript: false,
398
430
  follow: false,
399
431
  wait: true,
@@ -431,6 +463,13 @@ export function parseArgs(argv) {
431
463
  parseMonitorAction(args, options);
432
464
  }
433
465
 
466
+ if (command === "alerts") {
467
+ parseAlertsAction(args, options);
468
+ }
469
+
470
+ if (command === "graphify") parseGraphifyAction(args, options);
471
+ if (command === "updates") parseUpdatesAction(args, options);
472
+
434
473
  for (let index = 0; index < args.length; index += 1) {
435
474
  const arg = args[index];
436
475
 
@@ -520,6 +559,16 @@ export function parseArgs(argv) {
520
559
  else if (arg.startsWith("--backend=")) options.intelligenceBackend = arg.slice("--backend=".length);
521
560
  else if (arg === "--permissions") options.permissions = parsePathList(args[++index]);
522
561
  else if (arg.startsWith("--permissions=")) options.permissions = parsePathList(arg.slice("--permissions=".length));
562
+ else if (arg === "--bundle") options.bundlePath = resolve(args[++index]);
563
+ else if (arg.startsWith("--bundle=")) options.bundlePath = resolve(arg.slice("--bundle=".length));
564
+ else if (arg === "--graph") options.graphPath = resolve(args[++index]);
565
+ else if (arg.startsWith("--graph=")) options.graphPath = resolve(arg.slice("--graph=".length));
566
+ else if (arg === "--budget") options.graphifyBudget = requireFlagValue("--budget", args[++index]);
567
+ else if (arg.startsWith("--budget=")) options.graphifyBudget = requireFlagValue("--budget", arg.slice("--budget=".length));
568
+ else if (arg === "--confirm-import") options.confirmImport = true;
569
+ else if (arg === "--confirm-resolve") options.confirmResolve = true;
570
+ else if (arg === "--confirm-dismiss") options.confirmDismiss = true;
571
+ else if (arg === "--allow-unsafe-permissions") options.allowUnsafePermissions = true;
523
572
  else if (arg === "--capture-transcript") options.captureTranscript = true;
524
573
  else if (arg === "--follow") options.follow = true;
525
574
  else if (arg === "--no-wait") options.wait = false;
@@ -533,7 +582,8 @@ export function parseArgs(argv) {
533
582
  else if (arg === "--commit") options.commit = requireFlagValue("--commit", args[++index]);
534
583
  else if (arg.startsWith("--commit=")) {
535
584
  options.commit = requireFlagValue("--commit", arg.slice("--commit=".length));
536
- } else if (arg === "--fail-on") options.failOn = requireFlagValue("--fail-on", args[++index]);
585
+ } else if (arg === "--staged") options.staged = true;
586
+ else if (arg === "--fail-on") options.failOn = requireFlagValue("--fail-on", args[++index]);
537
587
  else if (arg.startsWith("--fail-on=")) {
538
588
  options.failOn = requireFlagValue("--fail-on", arg.slice("--fail-on=".length));
539
589
  }
@@ -546,6 +596,16 @@ export function parseArgs(argv) {
546
596
  options.task = args.join(" ").trim();
547
597
  }
548
598
 
599
+ if (command === "reviews" && options.reviewsAction === "import" && !options.bundlePath) {
600
+ throw new Error(
601
+ `Missing --bundle. Use: ${formatCliCommand("reviews import --bundle <path> --confirm-import")}`
602
+ );
603
+ }
604
+
605
+ if (command === "graphify" && !options.graphPath) {
606
+ throw new Error(`Missing --graph. Use: ${formatCliCommand("graphify <query|path|explain> ... --graph <path>")}`);
607
+ }
608
+
549
609
  return { command, options, isImplicitCommand: implicitCommand };
550
610
  }
551
611
 
@@ -672,18 +732,27 @@ function parseReviewsAction(args, options) {
672
732
  options.reviewsAction = "list";
673
733
  return;
674
734
  }
675
- if (!new Set(["list", "show"]).has(action)) {
676
- throw new Error(`Unknown reviews action "${action}". Use list or show.`);
735
+ if (!new Set(["list", "show", "verify", "export", "import"]).has(action)) {
736
+ throw new Error(`Unknown reviews action "${action}". Use list, show, verify, export, or import.`);
677
737
  }
678
738
  args.shift();
679
739
  options.reviewsAction = action;
680
- if (action === "show") {
740
+ if (action === "show" || action === "verify") {
681
741
  const reviewId = args[0];
682
742
  if (!reviewId || reviewId.startsWith("-")) {
683
- throw new Error(`Missing review id. Use: ${formatCliCommand("reviews show <reviewId>")}`);
743
+ throw new Error(`Missing review id. Use: ${formatCliCommand(`reviews ${action} <reviewId>`)}`);
684
744
  }
685
745
  options.reviewId = args.shift();
686
746
  }
747
+ if (action === "export") {
748
+ const lineage = args[0];
749
+ if (!lineage || lineage.startsWith("-")) {
750
+ throw new Error(
751
+ `Missing lineage. Use: ${formatCliCommand("reviews export <lineage> --out <path>")}`
752
+ );
753
+ }
754
+ options.lineage = args.shift();
755
+ }
687
756
  }
688
757
 
689
758
  function parseMonitorAction(args, options) {
@@ -699,6 +768,20 @@ function parseMonitorAction(args, options) {
699
768
  options.monitorAction = action;
700
769
  }
701
770
 
771
+ function parseAlertsAction(args, options) {
772
+ const action = args[0];
773
+ if (!action || action.startsWith("-") || !new Set(["resolve", "dismiss"]).has(action)) {
774
+ throw new Error(`Unknown alerts action "${action ?? ""}". Use resolve or dismiss.`);
775
+ }
776
+ args.shift();
777
+ options.alertsAction = action;
778
+ const alertId = args[0];
779
+ if (!alertId || alertId.startsWith("-")) {
780
+ throw new Error(`Missing alert id. Use: ${formatCliCommand(`alerts ${action} <alertId>`)}`);
781
+ }
782
+ options.alertId = args.shift();
783
+ }
784
+
702
785
  function parseIntelligenceAction(args, options) {
703
786
  const action = args[0];
704
787
  if (!action || action.startsWith("-")) {
@@ -714,6 +797,39 @@ function parseIntelligenceAction(args, options) {
714
797
  options.intelligenceAction = action;
715
798
  }
716
799
 
800
+ function parseGraphifyAction(args, options) {
801
+ const action = args[0];
802
+ const usage = formatCliCommand("graphify <query|path|explain> ... --graph <path>");
803
+ if (!action || action.startsWith("-")) throw new Error(`Missing graphify action. Use: ${usage}`);
804
+ if (!["query", "path", "explain"].includes(action)) {
805
+ throw new Error(`Unknown graphify action "${action}". Use query, path, or explain.`);
806
+ }
807
+ args.shift();
808
+ options.graphifyAction = action;
809
+ const positional = [];
810
+ while (args.length && !String(args[0]).startsWith("-")) positional.push(args.shift());
811
+ const need = action === "path" ? 2 : 1;
812
+ if (positional.length < need) {
813
+ throw new Error(action === "path"
814
+ ? `Missing arguments. Use: ${formatCliCommand('graphify path "<A>" "<B>" --graph <path>')}`
815
+ : `Missing argument. Use: ${formatCliCommand(`graphify ${action} "<text>" --graph <path>`)}`);
816
+ }
817
+ options.graphifyArgs = positional.slice(0, need);
818
+ }
819
+
820
+ function parseUpdatesAction(args, options) {
821
+ const action = args[0];
822
+ if (!action || action.startsWith("-")) {
823
+ options.updatesAction = "check";
824
+ return;
825
+ }
826
+ if (action !== "check") {
827
+ throw new Error(`Unknown updates action "${action}". Use: kairo updates check`);
828
+ }
829
+ args.shift();
830
+ options.updatesAction = "check";
831
+ }
832
+
717
833
  function parsePathList(value) {
718
834
  if (!value) return [];
719
835
  return [...new Set(
@@ -758,11 +874,15 @@ function normalizeCommand(command) {
758
874
  if (command === "review") return "review";
759
875
  if (command === "reviews") return "reviews";
760
876
  if (command === "monitor") return "monitor";
877
+ if (command === "alerts") return "alerts";
878
+ if (command === "graphify") return "graphify";
879
+ if (command === "mcp") return "mcp";
761
880
  if (command === "intelligence" || command === "intel") return "intelligence";
762
881
  if (command === "setup") return "setup";
763
882
  if (command === "status") return "status";
764
883
  if (command === "sync") return "sync";
765
884
  if (command === "upgrade") return "upgrade";
885
+ if (command === "updates") return "updates";
766
886
  if (command === "init") return "init";
767
887
  if (command === "update" || command === "u") return "update";
768
888
  if (command === "doctor") return "doctor";
@@ -828,13 +948,18 @@ Usage:
828
948
  ${cli} --dry-run Setup dry-run (scriptable)
829
949
  ${cli} --version
830
950
  ${cli} shell Operations cockpit (TTY)
831
- ${cli} run --agent <id> --task "..." [--strategy direct|orchestrated] [--model <name>] [--cwd <dir>] [--permissions force] [--capture-transcript] [--follow] [--no-wait] [--json]
951
+ ${cli} run --agent <id> --task "..." [--strategy direct|orchestrated] [--model <name>] [--cwd <dir>] [--permissions force|yolo|read-only] [--allow-unsafe-permissions] [--capture-transcript] [--follow] [--no-wait] [--json]
832
952
  ${cli} runs list [--json] [--limit <n>] [--active-only]
833
953
  ${cli} runs show <runId> [--json] [--limit <n>] [--follow]
834
954
  ${cli} runs stop <runId> [--json]
835
- ${cli} review --agent codex|pi [--base <ref>|--commit <sha>] [--model <name>] [--include-private] [--yes|--confirm] [--fail-on high|medium|low] [--json]
955
+ ${cli} alerts resolve|dismiss <alertId> --confirm-resolve|--confirm-dismiss [--json]
956
+ ${cli} review --agent codex|pi [--base <ref>|--commit <sha>|--staged] [--model <name>] [--include-private] [--yes|--confirm] [--fail-on high|medium|low] [--json]
836
957
  ${cli} reviews list [--limit <n>] [--json]
837
958
  ${cli} reviews show <reviewId> [--json]
959
+ ${cli} reviews verify <reviewId> --staged [--json]
960
+ ${cli} reviews export <lineage> --out <path> [--json]
961
+ ${cli} reviews import --bundle <path> --confirm-import [--cwd <dir>] [--json]
962
+ ${cli} graphify query|path|explain ... --graph <path> [--budget N] [--json]
838
963
  ${cli} orchestrator [--json] Read-only agent capability diagnostics
839
964
  ${cli} intelligence [status|models|context|route|ask] [--json]
840
965
  ${cli} intelligence models --backend opencode-go|opencode-zen|opencode
@@ -844,6 +969,7 @@ Usage:
844
969
  ${cli} status [--json]
845
970
  ${cli} sync [--dry-run] [--yes] [--confirm] [--json] [--no-preflight]
846
971
  ${cli} upgrade [--dry-run] [--yes] [--confirm] [--no-preflight]
972
+ ${cli} updates check [--json] [--force]
847
973
  ${cli} install [--agents <list|all>] [--components <list>] [--dry-run]
848
974
  ${cli} install --no-default-components
849
975
  ${cli} doctor [--json]
@@ -883,8 +1009,9 @@ Commands:
883
1009
  Tab switches region only when content is interactive (runs/launch).
884
1010
  run Launch a managed agent run with local audit trail.
885
1011
  runs List, inspect, or cancel agent runs under ~/.harness/runs/.
1012
+ alerts Consent-gated alert resolve/dismiss (Permission Authority).
886
1013
  review Bounded read-only review via Codex or Pi; receipts under ~/.harness/reviews/.
887
- reviews List or show prior review receipts (secret-free).
1014
+ reviews List/show/verify receipts, or Gentle portable export/import.
888
1015
  monitor Opt-in anomaly monitor (enable|disable|status|tick). macOS LaunchAgent; notify shell:false.
889
1016
  orchestrator Read-only capability registry diagnostics (--json supported).
890
1017
  intelligence Harness Engineering layer: backends, context packs, routing, budgets.
@@ -895,6 +1022,7 @@ Commands:
895
1022
  status Control panel: agents, components, drift, backups, next action.
896
1023
  sync Converge managed content (repair drift), then show status.
897
1024
  upgrade Preview or apply ecosystem updates (apply requires --yes).
1025
+ updates Read-only ecosystem update check (kairo/hermes/gentle/skills). Never applies.
898
1026
  install Non-interactive configure (agent-global) or legacy workspace scaffold.
899
1027
  doctor Detailed health checks for managed state and configs.
900
1028
  update Technical repair alias (prefer sync for day-to-day use).
@@ -1,4 +1,5 @@
1
1
  import { join } from "node:path";
2
+ import { buildAgentSkillsManagedSection } from "./components/agent-skills.js";
2
3
  import { buildEngramMemoryManagedSection } from "./components/engram-memory.js";
3
4
  import { buildGraphifyContextManagedSection } from "./components/graphify-context.js";
4
5
  import { buildOrchestratorManagedSection } from "./components/orchestrator.js";
@@ -8,7 +9,8 @@ export const COMPONENT_BUILDERS = {
8
9
  orchestrator: buildOrchestratorManagedSection,
9
10
  "sdd-core": buildSddCoreManagedSection,
10
11
  "engram-memory": buildEngramMemoryManagedSection,
11
- "graphify-context": buildGraphifyContextManagedSection
12
+ "graphify-context": buildGraphifyContextManagedSection,
13
+ "agent-skills": buildAgentSkillsManagedSection
12
14
  };
13
15
 
14
16
  export function resolveComponentBuilder(componentId) {
@@ -0,0 +1,27 @@
1
+ import { join } from "node:path";
2
+
3
+ export const AGENT_SKILLS_IDS = Object.freeze([
4
+ "context-engineering",
5
+ "source-driven-development",
6
+ "frontend-ui-engineering",
7
+ "performance-optimization",
8
+ "observability-and-instrumentation"
9
+ ]);
10
+
11
+ export function buildAgentSkillsManagedSection(context, adapter, catalogEntry) {
12
+ const baseDir = join(context.componentsDir, "agent-skills");
13
+ const adapterNote = catalogEntry?.adapterHints?.[adapter.id] ?? null;
14
+
15
+ return [
16
+ "### Agent Skills (complementary)",
17
+ "",
18
+ `- Skills root: ${join(baseDir, "skills")}`,
19
+ `- Provenance: ${join(baseDir, "PROVENANCE.md")}`,
20
+ `- License: ${join(baseDir, "LICENSE")}`,
21
+ `- Adopted skills (only): ${AGENT_SKILLS_IDS.join(", ")}.`,
22
+ "- Complementary only: Gentle AI remains the methodological authority for SDD, RDD, review, and Git workflow.",
23
+ "- Do not treat these skills as replacements for Gentle AI phase skills or review gates.",
24
+ "- After install or update, run `gentle-ai skill-registry refresh` when Gentle AI is available.",
25
+ adapterNote
26
+ ].filter(Boolean).join("\n");
27
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Static ASCII wordmark for Kairo Overview — no figlet dependency.
3
+ * Hero art appears only on Overview (wide / compact); minimal stays textual.
4
+ */
5
+
6
+ import { LAYOUT_MODES } from "../layout.js";
7
+
8
+ const WORDMARK_WIDE = [
9
+ "╦╔═╔═╗╦╦═╗╔═╗",
10
+ "╠╩╗╠═╣║╠╦╝║ ║",
11
+ "╩ ╩╩ ╩╩╩╚═╚═╝"
12
+ ];
13
+
14
+ const WORDMARK_COMPACT = [
15
+ "╦╔═╔═╗╦╦═╗╔═╗",
16
+ "╩ ╩╩ ╩╩╩╚═╚═╝"
17
+ ];
18
+
19
+ const WORDMARK_WIDE_ASCII = [
20
+ "K A I R O",
21
+ "========="
22
+ ];
23
+
24
+ const WORDMARK_COMPACT_ASCII = [
25
+ "KAIRO"
26
+ ];
27
+
28
+ export function shouldShowWordmark(layoutMode) {
29
+ return layoutMode === LAYOUT_MODES.WIDE || layoutMode === LAYOUT_MODES.COMPACT;
30
+ }
31
+
32
+ /**
33
+ * @param {"wide"|"compact"|"minimal"|string} layoutMode
34
+ * @param {{ unicode?: boolean }} [opts]
35
+ * @returns {string[]}
36
+ */
37
+ export function wordmarkLines(layoutMode, { unicode = true } = {}) {
38
+ if (layoutMode === LAYOUT_MODES.WIDE) {
39
+ return unicode ? WORDMARK_WIDE.slice() : WORDMARK_WIDE_ASCII.slice();
40
+ }
41
+ if (layoutMode === LAYOUT_MODES.COMPACT) {
42
+ return unicode ? WORDMARK_COMPACT.slice() : WORDMARK_COMPACT_ASCII.slice();
43
+ }
44
+ return [];
45
+ }
46
+
47
+ export function overviewBrandTitle(layoutMode) {
48
+ if (shouldShowWordmark(layoutMode)) return null;
49
+ return "KAIRO · Overview";
50
+ }