@kal-elsam/kairo-runtime 0.13.1 → 0.15.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.
- package/CHANGELOG.md +107 -0
- package/README.md +12 -10
- package/bin/kairo-runtime.js +0 -0
- package/bin/kairo.js +0 -0
- package/package.json +5 -1
- package/scripts/cockpit-smoke.mjs +14 -10
- package/src/cli.js +182 -11
- package/src/global/check-resolutions.js +31 -0
- package/src/global/cli-help.js +23 -4
- package/src/global/component-ecosystem-checks.js +2 -0
- package/src/global/component-integration-cli.js +29 -10
- package/src/global/components-resolve-cli.js +246 -0
- package/src/global/connection-actions.js +147 -0
- package/src/global/connections.js +269 -0
- package/src/global/fleet-configure-plan.js +123 -0
- package/src/global/fleet-configure.js +303 -0
- package/src/global/fleet-models.js +188 -0
- package/src/global/fleet-set.js +219 -0
- package/src/global/fleet-shared.js +38 -0
- package/src/global/ink/cockpit-controller.js +2 -4
- package/src/global/ink/cockpit-enter.js +3 -1
- package/src/global/ink/cockpit-focus.js +7 -1
- package/src/global/ink/cockpit-models.js +33 -21
- package/src/global/ink/cockpit-palette.js +8 -3
- package/src/global/ink/cockpit-views.js +9 -2
- package/src/global/ink/orchestrator-app.js +42 -4
- package/src/global/ink/ux/live-overview.js +53 -26
- package/src/global/ink/ux/overview-actions.js +80 -0
- package/src/global/ink/ux/overview-needs.js +1 -1
- package/src/global/integrations/engram-evidence.js +7 -2
- package/src/global/integrations/sdd-apply.js +17 -7
- package/src/global/integrations/sdd-evidence.js +22 -3
- package/src/global/integrations/sdd-plan.js +21 -3
- package/src/global/integrations/sdd-resolutions.js +73 -0
- package/src/global/integrations/sdd-state.js +69 -0
- package/src/global/integrations/sdd-verify.js +9 -4
- package/src/global/mcp/kairo-mcp.js +56 -5
- package/src/global/mcp/resolve-mcp-workspace.js +51 -0
- package/src/global/mcp/work-snapshot-rule.js +89 -0
- package/src/global/mcp/work-snapshot-tool.js +49 -0
- package/src/global/mcp-install.js +239 -0
- package/src/global/next/next-cli.js +35 -0
- package/src/global/next/next-report.js +145 -0
- package/src/global/next/project-key.js +36 -0
- package/src/global/next/publish-work-snapshot.js +116 -0
- package/src/global/next/work-enroll.js +91 -0
- package/src/global/next/work-snapshot.js +216 -0
- package/src/global/observability/fleet-activity.js +197 -0
- package/src/global/observability/fleet-models-catalog.js +137 -0
- package/src/global/observability/fleet-platforms.js +166 -0
- package/src/global/observability/fleet-probe.js +229 -0
- package/src/global/paths.js +2 -1
- package/src/global/self-update.js +216 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,113 @@ Historical entries below may reference the legacy `@kal-elsam/harness` package n
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## 0.15.0 — 2026-08-12 (Kairo Runtime)
|
|
9
|
+
|
|
10
|
+
Minor release. Declared Fleet board + model configure, and the Cursor
|
|
11
|
+
observable companion (work snapshots, MCP publish, `kairo next`, managed
|
|
12
|
+
rule, honest panel). Publish tag: `kairo-runtime-v0.15.0`. Extension
|
|
13
|
+
marketplace delivery stays out of this unit.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Contract `kairo.work-snapshot/v1` and MCP tool `kairo_publish_work_snapshot`
|
|
18
|
+
to enroll the current Cursor conversation with Goal / Progress / Now /
|
|
19
|
+
Constraints / Next.
|
|
20
|
+
- `kairo next` / `kairo.next/v1`: selected work snapshot plus integration
|
|
21
|
+
state (`active` / `enrolled` / `showRepair`) for the IDE panel.
|
|
22
|
+
- `kairo mcp install [--yes]`: consent-gated registration of Kairo MCP in
|
|
23
|
+
`~/.cursor/mcp.json` (plan first; atomic write + backup) and managed
|
|
24
|
+
Cursor rule `~/.cursor/rules/kairo-work-snapshot.mdc` (`alwaysApply`).
|
|
25
|
+
- Panel **0.7.0**: honest companion surface — Repair only when integration
|
|
26
|
+
is broken; otherwise active/enrolled without false prompts.
|
|
27
|
+
- MCP workspace binding: prefer Cursor env (`VSCODE_CWD` /
|
|
28
|
+
`WORKSPACE_FOLDER_PATHS`) over process cwd; canonicalize macOS `/tmp` vs
|
|
29
|
+
`/private/tmp` before hashing `projectKey`.
|
|
30
|
+
- Panel **0.6.5**: One **Configure all** for multi-agent (Claude + OpenCode +
|
|
31
|
+
Cursor agents). **Codex aparte** (`--codex-model`). `kairo fleet models`
|
|
32
|
+
shows available vs enabled per tool. Cursor desk: open agents/skills/rules.
|
|
33
|
+
Profile at `~/.harness/fleet-models.json` (seeded from disk; preserves
|
|
34
|
+
tuned OpenCode). `--from gentle` remaps OpenCode tiers when you want that.
|
|
35
|
+
- Panel **0.6.4**: Fleet Details puts configure buttons first (Edit per
|
|
36
|
+
minion on Claude/OpenCode; Cursor offers Claude/OpenCode configure +
|
|
37
|
+
optional Pixel Agents). `fleet configure` defaults to Claude only (no
|
|
38
|
+
surprise OpenCode overwrite).
|
|
39
|
+
- `kairo fleet configure`: Gentle-style model assignments across OpenCode +
|
|
40
|
+
Claude (+ Codex when `codex_default` set). Plan / `--yes` + backups. Panel
|
|
41
|
+
**Models** button. Cursor Auto remains IDE-managed.
|
|
42
|
+
- Panel **0.6.2**: Fleet floor (compact platform desks). Working floor only
|
|
43
|
+
shows live agents — no idle OpenCode wall. CLI `kairo fleet` compact by
|
|
44
|
+
default (`--verbose` for full minion list).
|
|
45
|
+
- Panel **0.6.3**: Configure models toolbar + desk actions for sync/set.
|
|
46
|
+
- `kairo fleet [--json]`: declared orchestrator→minion fleet topology from
|
|
47
|
+
OpenCode config (Gentle + SDD models); Cursor Auto marked opaque.
|
|
48
|
+
MCP tool `kairo_fleet`; `kairo connections --json` includes `fleets`.
|
|
49
|
+
- Panel **0.5.0**: Fleet tree under connections (platform · orchestrator ·
|
|
50
|
+
model, indented minions). Details note: declared config, not live tokens.
|
|
51
|
+
- `kairo connections [--json]`: Gentle / Hermes / Engram / Graphify / Agent
|
|
52
|
+
connection chips for the IDE panel (companion probes + MCP registration).
|
|
53
|
+
- VS Code / Cursor panel **0.3.0**: connection chips, Connect Agent button,
|
|
54
|
+
Entries + Details webview. Docs: `docs/mcp.md`.
|
|
55
|
+
- Panel **0.3.1**: soften "not installed / unconfigured" entries to `note`;
|
|
56
|
+
fix false Engram conflict when Claude uses `~/.claude/mcp/engram.json`
|
|
57
|
+
without `mcpServers.engram` in settings.json.
|
|
58
|
+
- Panel **0.3.2**: **Setup** button + per-connection actions (Configure /
|
|
59
|
+
How to install / Update graph). Optional tools labeled; Kairo never
|
|
60
|
+
auto-installs Gentle/Hermes/Graphify.
|
|
61
|
+
- Panel **0.3.3**: every Entry shows resolve buttons in Details (Fix SDD,
|
|
62
|
+
Repair, Update graph, Why optional?). Hermes chip offers **Start Hermes
|
|
63
|
+
gateway**. Conflicts sort first so buttons are visible immediately.
|
|
64
|
+
- Panel **0.3.4**: Hermes tip documents `API_SERVER_ENABLED=true` — gateway
|
|
65
|
+
alone without API Server does not expose :8642.
|
|
66
|
+
- Check **resolutions[]** contract + panel **0.4.0**: status checks can declare
|
|
67
|
+
clickable fix buttons. For `sdd-core:skills` conflicts:
|
|
68
|
+
- `kairo components diff sdd-core` (read-only)
|
|
69
|
+
- `kairo components adopt sdd-core` (keep disk; record adopted hashes)
|
|
70
|
+
- `kairo components configure sdd-core --overwrite-conflicts` (backup + replace)
|
|
71
|
+
Destructive overwrite asks for a modal confirm in the IDE panel.
|
|
72
|
+
- Panel **0.4.1**: adopt/overwrite buttons apply with `--yes` (click = consent).
|
|
73
|
+
Previous `--dry-run` left CONFLICT unchanged after clicking Conservar el mío.
|
|
74
|
+
- Panel **0.4.2**: status/connections/terminal use the open workspace folder as
|
|
75
|
+
`cwd`, so graphify-out/ is detected (was falsely "not found" from IDE cwd).
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- Cockpit Home opened with focus on the tab bar, so the two Home buttons never
|
|
80
|
+
showed a selection mark and the arrow keys moved between tabs instead. Home
|
|
81
|
+
now starts on the buttons.
|
|
82
|
+
|
|
83
|
+
### Changed
|
|
84
|
+
|
|
85
|
+
- Home buttons render as `› [1] Label` with `← Press Enter` on the focused
|
|
86
|
+
option; press `1` / `2` to run a button without arrow navigation.
|
|
87
|
+
- Home footer names each key (`1·2 Select · Enter Run · ? Help · Esc Exit`)
|
|
88
|
+
instead of listing bare keys.
|
|
89
|
+
- Home shows at most two plain-language needs; the rest collapse into the
|
|
90
|
+
`More info (n)` disclosure, which absorbs the duplicated "n more" line.
|
|
91
|
+
|
|
92
|
+
## 0.14.0 — 2026-08-07 (Kairo Runtime)
|
|
93
|
+
|
|
94
|
+
Minor release. Simpler Cockpit, one-command CLI self-update, pnpm for
|
|
95
|
+
contributors, and a minimal IDE status panel. Publish tag:
|
|
96
|
+
`kairo-runtime-v0.14.0`.
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
|
|
100
|
+
- Cockpit Home with three tabs (Home · Settings · History) and two clear
|
|
101
|
+
actions (prepare/repair + Configure). Secondary destinations stay in `/`.
|
|
102
|
+
- `kairo update`: update the Kairo CLI from npm (`--yes` applies). Workspace
|
|
103
|
+
template refresh stays at `kairo update --scope=workspace`.
|
|
104
|
+
- VS Code / Cursor extension scaffold in `packages/kairo-vscode`: status bar +
|
|
105
|
+
explorer tree from `kairo status --json`; sync/doctor/cockpit open a terminal
|
|
106
|
+
(no silent writes). Local VSIX via `npm run package`.
|
|
107
|
+
|
|
108
|
+
### Changed
|
|
109
|
+
|
|
110
|
+
- Local development and CI use **pnpm 10.x** (`packageManager` pinned). End-user
|
|
111
|
+
installs and `npm publish` (OIDC Trusted Publishing) stay on npm.
|
|
112
|
+
- Install scripts blocked by default (`pnpm.onlyBuiltDependencies: []`);
|
|
113
|
+
`.npmrc` sets `strict-dep-builds` and `minimum-release-age=1440`.
|
|
114
|
+
|
|
8
115
|
## 0.13.1 — 2026-08-07 (Kairo Runtime)
|
|
9
116
|
|
|
10
117
|
Patch release. Docs/UX/license polish for npm adoption. Publish tag:
|
package/README.md
CHANGED
|
@@ -24,25 +24,23 @@ KAIRO
|
|
|
24
24
|
Needs attention · 4/4 agents · drift pending
|
|
25
25
|
Kairo coordinates installed AI agents for this project.
|
|
26
26
|
|
|
27
|
-
→
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Obsidian not connected · open Settings to choose your vault
|
|
33
|
-
Update available · run kairo updates check
|
|
34
|
-
9 more in Details · Space
|
|
27
|
+
→ Repair 3 changes
|
|
28
|
+
You will see the exact plan before anything is written.
|
|
29
|
+
|
|
30
|
+
Configure
|
|
31
|
+
Agents, Obsidian vault, integrations.
|
|
35
32
|
```
|
|
36
33
|
|
|
37
|
-
`↑↓` move · `Enter` open · `Space` details · `R` refresh · `Esc` back · `?` help
|
|
34
|
+
`↑↓` move · `Enter` open · `Tab` nav · `Space` details · `R` refresh · `Esc` back · `?` help
|
|
38
35
|
|
|
39
|
-
##
|
|
36
|
+
## Day-to-day commands
|
|
40
37
|
|
|
41
38
|
| Command | What it does |
|
|
42
39
|
|---|---|
|
|
43
40
|
| `kairo` | Open the cockpit |
|
|
44
41
|
| `kairo status` | See how your setup is doing |
|
|
45
42
|
| `kairo sync` | Repair what drifted |
|
|
43
|
+
| `kairo update` | Update Kairo itself from npm |
|
|
46
44
|
| `kairo doctor` | Deeper health checks |
|
|
47
45
|
|
|
48
46
|
Run `kairo help --all` for everything else, or read the
|
|
@@ -70,6 +68,10 @@ npx @kal-elsam/kairo-runtime
|
|
|
70
68
|
# Install globally
|
|
71
69
|
npm i -g @kal-elsam/kairo-runtime && kairo
|
|
72
70
|
|
|
71
|
+
# Later: update the CLI itself
|
|
72
|
+
kairo update
|
|
73
|
+
kairo update --yes
|
|
74
|
+
|
|
73
75
|
# Preview the setup plan, write nothing
|
|
74
76
|
npx @kal-elsam/kairo-runtime --dry-run
|
|
75
77
|
```
|
package/bin/kairo-runtime.js
CHANGED
|
File without changes
|
package/bin/kairo.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kal-elsam/kairo-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.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",
|
|
@@ -62,6 +62,10 @@
|
|
|
62
62
|
"engines": {
|
|
63
63
|
"node": ">=20.12.0"
|
|
64
64
|
},
|
|
65
|
+
"packageManager": "pnpm@10.34.5",
|
|
66
|
+
"pnpm": {
|
|
67
|
+
"onlyBuiltDependencies": []
|
|
68
|
+
},
|
|
65
69
|
"dependencies": {
|
|
66
70
|
"@clack/prompts": "^1.7.0",
|
|
67
71
|
"@modelcontextprotocol/server": "2.0.0",
|
|
@@ -86,7 +86,7 @@ const asciiNav = buildNavModel({
|
|
|
86
86
|
assert.equal(asciiNav.items[1].marker, ">");
|
|
87
87
|
assert.equal(asciiNav.items[0].current, true);
|
|
88
88
|
assert.equal(asciiNav.items[1].selected, true);
|
|
89
|
-
assert.match(asciiNav.explanation, /
|
|
89
|
+
assert.match(asciiNav.explanation, /agents|Obsidian|integrations/i);
|
|
90
90
|
|
|
91
91
|
function applyKey(state, keyAction) {
|
|
92
92
|
const routed = routeCockpitKey(state, keyAction);
|
|
@@ -99,25 +99,29 @@ function smokeNavigation(layoutMode) {
|
|
|
99
99
|
layoutMode,
|
|
100
100
|
region: layoutMode === LAYOUT_MODES.MINIMAL ? COCKPIT_REGIONS.CONTENT : COCKPIT_REGIONS.NAV
|
|
101
101
|
});
|
|
102
|
-
const
|
|
103
|
-
while (state.navIndex <
|
|
102
|
+
const settingsIndex = COCKPIT_NAV.findIndex((item) => item.id === "settings");
|
|
103
|
+
while (state.navIndex < settingsIndex) {
|
|
104
104
|
state = applyKey(state, { type: "arrow", direction: "down" });
|
|
105
105
|
}
|
|
106
106
|
state = applyKey(state, { type: "enter" });
|
|
107
|
-
assert.equal(state.view, ORCHESTRATOR_VIEWS.
|
|
108
|
-
assert.equal(state.region, COCKPIT_REGIONS.
|
|
107
|
+
assert.equal(state.view, ORCHESTRATOR_VIEWS.PROFILE);
|
|
108
|
+
assert.equal(state.region, COCKPIT_REGIONS.CONTENT);
|
|
109
109
|
|
|
110
|
-
state = applyKey(state, { type: "
|
|
110
|
+
state = applyKey(state, { type: "tab" });
|
|
111
|
+
assert.equal(state.region, COCKPIT_REGIONS.NAV);
|
|
112
|
+
while (state.navIndex > 0) {
|
|
113
|
+
state = applyKey(state, { type: "arrow", direction: "up" });
|
|
114
|
+
}
|
|
111
115
|
state = applyKey(state, { type: "enter" });
|
|
112
116
|
assert.equal(state.view, ORCHESTRATOR_VIEWS.HOME);
|
|
113
|
-
assert.equal(state.region, COCKPIT_REGIONS.
|
|
117
|
+
assert.equal(state.region, COCKPIT_REGIONS.CONTENT);
|
|
114
118
|
|
|
115
119
|
const footer = buildFooterModel({
|
|
116
|
-
view: ORCHESTRATOR_VIEWS.
|
|
117
|
-
region: COCKPIT_REGIONS.
|
|
120
|
+
view: ORCHESTRATOR_VIEWS.HOME,
|
|
121
|
+
region: COCKPIT_REGIONS.CONTENT,
|
|
118
122
|
unicode: false
|
|
119
123
|
});
|
|
120
|
-
assert.
|
|
124
|
+
assert.match(footer.text, /Tab/);
|
|
121
125
|
|
|
122
126
|
state = applyKey(state, { type: "escape" });
|
|
123
127
|
assert.equal(state.view, ORCHESTRATOR_VIEWS.HOME);
|
package/src/cli.js
CHANGED
|
@@ -6,6 +6,10 @@ import {
|
|
|
6
6
|
runComponentsRollback,
|
|
7
7
|
runComponentsVerify
|
|
8
8
|
} from "./global/component-integration-cli.js";
|
|
9
|
+
import {
|
|
10
|
+
runComponentsAdopt,
|
|
11
|
+
runComponentsDiff
|
|
12
|
+
} from "./global/components-resolve-cli.js";
|
|
9
13
|
import {
|
|
10
14
|
printGlobalComponents,
|
|
11
15
|
printGlobalDetect,
|
|
@@ -30,6 +34,7 @@ import {
|
|
|
30
34
|
runGlobalReport
|
|
31
35
|
} from "./global/global-cli.js";
|
|
32
36
|
import { runEcosystemUpdatesCheck } from "./global/updates-cli.js";
|
|
37
|
+
import { runSelfUpdate } from "./global/self-update.js";
|
|
33
38
|
import { applyPolicyToOptions, loadPolicyFile } from "./global/policy.js";
|
|
34
39
|
import { resolveHomeDir } from "./global/paths.js";
|
|
35
40
|
import { runWorkspaceDetect, runWorkspaceDoctor, runWorkspaceInit, runWorkspaceUpdate } from "./workspace-cli.js";
|
|
@@ -127,17 +132,100 @@ export async function runCli(argv) {
|
|
|
127
132
|
await runGraphifyCli(optionsWithPolicy, packageManifest);
|
|
128
133
|
return;
|
|
129
134
|
case "mcp": {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
135
|
+
const { runMcpCli } = await import("./global/mcp-install.js");
|
|
136
|
+
await runMcpCli({
|
|
137
|
+
mcpAction: optionsWithPolicy.mcpAction ?? "serve",
|
|
138
|
+
mcpClient: optionsWithPolicy.mcpClient ?? "cursor",
|
|
139
|
+
yes: optionsWithPolicy.yes === true,
|
|
140
|
+
json: optionsWithPolicy.json === true,
|
|
134
141
|
cwd: optionsWithPolicy.cwd,
|
|
142
|
+
cwdExplicit: optionsWithPolicy.cwdExplicit,
|
|
135
143
|
packageRoot,
|
|
136
144
|
packageName: packageManifest.name,
|
|
137
145
|
version: packageManifest.version
|
|
138
146
|
});
|
|
139
147
|
return;
|
|
140
148
|
}
|
|
149
|
+
case "connections": {
|
|
150
|
+
const { buildConnectionsReport } = await import("./global/connections.js");
|
|
151
|
+
const { printJson } = await import("./global/json-output.js");
|
|
152
|
+
const { commandHeader } = await import("./global/brand/index.js");
|
|
153
|
+
const report = await buildConnectionsReport({
|
|
154
|
+
workspaceRoot: optionsWithPolicy.cwd,
|
|
155
|
+
packageRoot,
|
|
156
|
+
packageName: packageManifest.name,
|
|
157
|
+
cliVersion: packageManifest.version,
|
|
158
|
+
client: optionsWithPolicy.mcpClient ?? "cursor"
|
|
159
|
+
});
|
|
160
|
+
if (optionsWithPolicy.json) {
|
|
161
|
+
printJson(report);
|
|
162
|
+
} else {
|
|
163
|
+
console.log(commandHeader("Connections"));
|
|
164
|
+
for (const c of report.connections) {
|
|
165
|
+
console.log(`${c.label} · ${c.state}`);
|
|
166
|
+
console.log(` ${c.access}`);
|
|
167
|
+
if (c.detail) console.log(` ${c.detail}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
case "next": {
|
|
173
|
+
const { runNextCli } = await import("./global/next/next-cli.js");
|
|
174
|
+
await runNextCli({
|
|
175
|
+
cwd: optionsWithPolicy.cwd,
|
|
176
|
+
json: optionsWithPolicy.json === true,
|
|
177
|
+
mcpClient: optionsWithPolicy.mcpClient ?? "cursor"
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
case "fleet": {
|
|
182
|
+
const fleetAction = optionsWithPolicy.fleetAction ?? "show";
|
|
183
|
+
if (fleetAction === "set") {
|
|
184
|
+
const { runFleetSet } = await import("./global/fleet-set.js");
|
|
185
|
+
await runFleetSet({
|
|
186
|
+
platform: optionsWithPolicy.fleetPlatform,
|
|
187
|
+
agent: optionsWithPolicy.fleetAgent ?? optionsWithPolicy.agent,
|
|
188
|
+
model: optionsWithPolicy.model,
|
|
189
|
+
yes: optionsWithPolicy.yes === true,
|
|
190
|
+
dryRun: optionsWithPolicy.dryRun === true,
|
|
191
|
+
json: optionsWithPolicy.json === true
|
|
192
|
+
});
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (fleetAction === "configure") {
|
|
196
|
+
const { runFleetConfigure } = await import("./global/fleet-configure.js");
|
|
197
|
+
await runFleetConfigure({
|
|
198
|
+
yes: optionsWithPolicy.yes === true,
|
|
199
|
+
json: optionsWithPolicy.json === true,
|
|
200
|
+
platforms: optionsWithPolicy.fleetPlatforms ?? null,
|
|
201
|
+
from: optionsWithPolicy.fleetFrom ?? "profile",
|
|
202
|
+
assignmentsRaw: optionsWithPolicy.fleetAssignments ?? null,
|
|
203
|
+
codexModel: optionsWithPolicy.fleetCodexModel ?? null
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (fleetAction === "models") {
|
|
208
|
+
const { runFleetModels } = await import("./global/fleet-configure.js");
|
|
209
|
+
await runFleetModels({
|
|
210
|
+
json: optionsWithPolicy.json === true,
|
|
211
|
+
profile: optionsWithPolicy.fleetProfile === true
|
|
212
|
+
});
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const { buildFleetReport, formatFleetText } = await import("./global/observability/fleet-probe.js");
|
|
216
|
+
const { printJson } = await import("./global/json-output.js");
|
|
217
|
+
const report = await buildFleetReport({
|
|
218
|
+
includeVariants: optionsWithPolicy.includeVariants === true
|
|
219
|
+
});
|
|
220
|
+
if (optionsWithPolicy.json) {
|
|
221
|
+
printJson(report);
|
|
222
|
+
} else {
|
|
223
|
+
console.log(formatFleetText(report, {
|
|
224
|
+
verbose: optionsWithPolicy.verbose === true || optionsWithPolicy.includeVariants === true
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
141
229
|
case "intelligence":
|
|
142
230
|
await runIntelligenceCli(optionsWithPolicy, packageManifest);
|
|
143
231
|
return;
|
|
@@ -173,9 +261,15 @@ export async function runCli(argv) {
|
|
|
173
261
|
});
|
|
174
262
|
return;
|
|
175
263
|
case "update":
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
264
|
+
if (options.scope === "workspace") {
|
|
265
|
+
await runWorkspaceUpdate(options, packageManifest, packageRoot);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
await runSelfUpdate({
|
|
269
|
+
packageName: packageManifest.name,
|
|
270
|
+
cliVersion: packageManifest.version,
|
|
271
|
+
yes: optionsWithPolicy.yes === true,
|
|
272
|
+
json: optionsWithPolicy.json === true
|
|
179
273
|
});
|
|
180
274
|
return;
|
|
181
275
|
case "doctor":
|
|
@@ -278,6 +372,12 @@ async function dispatchComponentsCommand(options, invoke) {
|
|
|
278
372
|
case "verify":
|
|
279
373
|
await runComponentsVerify({ ...options, packageRoot });
|
|
280
374
|
return;
|
|
375
|
+
case "adopt":
|
|
376
|
+
await runComponentsAdopt({ ...options, packageRoot });
|
|
377
|
+
return;
|
|
378
|
+
case "diff":
|
|
379
|
+
await runComponentsDiff({ ...options, packageRoot });
|
|
380
|
+
return;
|
|
281
381
|
case "rollback":
|
|
282
382
|
await runComponentsRollback(options);
|
|
283
383
|
return;
|
|
@@ -356,6 +456,7 @@ export function parseArgs(argv) {
|
|
|
356
456
|
const command = normalizeCommand(rawCommand);
|
|
357
457
|
const options = {
|
|
358
458
|
cwd: process.cwd(),
|
|
459
|
+
cwdExplicit: false,
|
|
359
460
|
scope: null,
|
|
360
461
|
mode: "standard",
|
|
361
462
|
modeExplicit: false,
|
|
@@ -375,6 +476,7 @@ export function parseArgs(argv) {
|
|
|
375
476
|
dryRun: false,
|
|
376
477
|
yes: false,
|
|
377
478
|
confirm: false,
|
|
479
|
+
overwriteConflicts: false,
|
|
378
480
|
preflight: true,
|
|
379
481
|
preflightExplicit: false,
|
|
380
482
|
yesExplicit: false,
|
|
@@ -412,6 +514,18 @@ export function parseArgs(argv) {
|
|
|
412
514
|
confirmDismiss: false,
|
|
413
515
|
graphifyAction: null, graphifyArgs: [], graphifyBudget: null, graphPath: null,
|
|
414
516
|
updatesAction: "check",
|
|
517
|
+
mcpAction: "serve",
|
|
518
|
+
mcpClient: "cursor",
|
|
519
|
+
fleetAction: "show",
|
|
520
|
+
fleetPlatform: null,
|
|
521
|
+
fleetAgent: null,
|
|
522
|
+
fleetPlatforms: null,
|
|
523
|
+
fleetFrom: "profile",
|
|
524
|
+
fleetAssignments: null,
|
|
525
|
+
fleetCodexModel: null,
|
|
526
|
+
fleetProfile: false,
|
|
527
|
+
includeVariants: false,
|
|
528
|
+
verbose: false,
|
|
415
529
|
base: null,
|
|
416
530
|
commit: null,
|
|
417
531
|
staged: false,
|
|
@@ -466,6 +580,8 @@ export function parseArgs(argv) {
|
|
|
466
580
|
|
|
467
581
|
if (command === "graphify") parseGraphifyAction(args, options);
|
|
468
582
|
if (command === "updates") parseUpdatesAction(args, options);
|
|
583
|
+
if (command === "mcp") parseMcpAction(args, options);
|
|
584
|
+
if (command === "fleet") parseFleetAction(args, options);
|
|
469
585
|
|
|
470
586
|
if (command === "help") {
|
|
471
587
|
while (args[0] === "all" || args[0] === "--all") {
|
|
@@ -477,7 +593,10 @@ export function parseArgs(argv) {
|
|
|
477
593
|
for (let index = 0; index < args.length; index += 1) {
|
|
478
594
|
const arg = args[index];
|
|
479
595
|
|
|
480
|
-
if (arg === "--cwd")
|
|
596
|
+
if (arg === "--cwd") {
|
|
597
|
+
options.cwd = resolve(args[++index]);
|
|
598
|
+
options.cwdExplicit = true;
|
|
599
|
+
}
|
|
481
600
|
else if (arg === "--scope") options.scope = parseScope(args[++index]);
|
|
482
601
|
else if (arg.startsWith("--scope=")) options.scope = parseScope(arg.slice("--scope=".length));
|
|
483
602
|
else if (arg === "--mode") {
|
|
@@ -511,8 +630,26 @@ export function parseArgs(argv) {
|
|
|
511
630
|
options.componentsExplicit = true;
|
|
512
631
|
} else if (arg === "--force") options.force = true;
|
|
513
632
|
else if (arg === "--dry-run") options.dryRun = true;
|
|
633
|
+
else if (arg === "--overwrite-conflicts") options.overwriteConflicts = true;
|
|
514
634
|
else if (arg === "--json") options.json = true;
|
|
515
|
-
else if (arg === "--
|
|
635
|
+
else if (arg === "--include-variants") options.includeVariants = true;
|
|
636
|
+
else if (arg === "--platforms") options.fleetPlatforms = args[++index];
|
|
637
|
+
else if (arg.startsWith("--platforms=")) options.fleetPlatforms = arg.slice("--platforms=".length);
|
|
638
|
+
else if (arg === "--from") options.fleetFrom = args[++index];
|
|
639
|
+
else if (arg.startsWith("--from=")) options.fleetFrom = arg.slice("--from=".length);
|
|
640
|
+
else if (arg === "--assignments") options.fleetAssignments = args[++index];
|
|
641
|
+
else if (arg.startsWith("--assignments=")) options.fleetAssignments = arg.slice("--assignments=".length);
|
|
642
|
+
else if (arg === "--codex-model") options.fleetCodexModel = args[++index];
|
|
643
|
+
else if (arg.startsWith("--codex-model=")) options.fleetCodexModel = arg.slice("--codex-model=".length);
|
|
644
|
+
else if (arg === "--profile") options.fleetProfile = true;
|
|
645
|
+
else if (arg === "--verbose") options.verbose = true;
|
|
646
|
+
else if (arg === "--platform") options.fleetPlatform = args[++index];
|
|
647
|
+
else if (arg.startsWith("--platform=")) options.fleetPlatform = arg.slice("--platform=".length);
|
|
648
|
+
else if (arg === "--client") {
|
|
649
|
+
options.mcpClient = args[++index];
|
|
650
|
+
} else if (arg.startsWith("--client=")) {
|
|
651
|
+
options.mcpClient = arg.slice("--client=".length);
|
|
652
|
+
} else if (arg === "--yes" || arg === "-y") {
|
|
516
653
|
options.yes = true;
|
|
517
654
|
options.yesExplicit = true;
|
|
518
655
|
} else if (arg === "--confirm") {
|
|
@@ -644,7 +781,8 @@ function parseComponentsAction(args, options) {
|
|
|
644
781
|
|
|
645
782
|
if (action === "validate") return;
|
|
646
783
|
|
|
647
|
-
if (action === "configure" || action === "verify" || action === "rollback"
|
|
784
|
+
if (action === "configure" || action === "verify" || action === "rollback"
|
|
785
|
+
|| action === "adopt" || action === "diff") {
|
|
648
786
|
const componentId = args[0];
|
|
649
787
|
if (!componentId || componentId.startsWith("-")) {
|
|
650
788
|
throw new Error(
|
|
@@ -655,7 +793,7 @@ function parseComponentsAction(args, options) {
|
|
|
655
793
|
return;
|
|
656
794
|
}
|
|
657
795
|
|
|
658
|
-
throw new Error(`Unknown components action "${action}". Use validate, init, pack, import, configure, verify, or rollback.`);
|
|
796
|
+
throw new Error(`Unknown components action "${action}". Use validate, init, pack, import, configure, verify, adopt, diff, or rollback.`);
|
|
659
797
|
}
|
|
660
798
|
|
|
661
799
|
function parsePolicyAction(args, options) {
|
|
@@ -835,6 +973,36 @@ function parseUpdatesAction(args, options) {
|
|
|
835
973
|
options.updatesAction = "check";
|
|
836
974
|
}
|
|
837
975
|
|
|
976
|
+
function parseMcpAction(args, options) {
|
|
977
|
+
const action = args[0];
|
|
978
|
+
if (!action || action.startsWith("-")) {
|
|
979
|
+
options.mcpAction = "serve";
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
if (!new Set(["serve", "install"]).has(action)) {
|
|
983
|
+
throw new Error(
|
|
984
|
+
`Unknown mcp action "${action}". Use: ${formatCliCommand("mcp")} or ${formatCliCommand("mcp install [--yes]")}`
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
args.shift();
|
|
988
|
+
options.mcpAction = action;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
function parseFleetAction(args, options) {
|
|
992
|
+
const action = args[0];
|
|
993
|
+
if (!action || action.startsWith("-")) {
|
|
994
|
+
options.fleetAction = "show";
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
if (!new Set(["show", "set", "activity", "configure", "models"]).has(action)) {
|
|
998
|
+
throw new Error(
|
|
999
|
+
`Unknown fleet action "${action}". Use: ${formatCliCommand("fleet")}, ${formatCliCommand("fleet models")}, ${formatCliCommand("fleet configure")}, or ${formatCliCommand("fleet set --platform opencode --agent <id> --model <id>")}`
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
args.shift();
|
|
1003
|
+
options.fleetAction = action === "activity" ? "show" : action;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
838
1006
|
function parsePathList(value) {
|
|
839
1007
|
if (!value) return [];
|
|
840
1008
|
return [...new Set(
|
|
@@ -882,6 +1050,9 @@ function normalizeCommand(command) {
|
|
|
882
1050
|
if (command === "alerts") return "alerts";
|
|
883
1051
|
if (command === "graphify") return "graphify";
|
|
884
1052
|
if (command === "mcp") return "mcp";
|
|
1053
|
+
if (command === "connections") return "connections";
|
|
1054
|
+
if (command === "next") return "next";
|
|
1055
|
+
if (command === "fleet") return "fleet";
|
|
885
1056
|
if (command === "intelligence" || command === "intel") return "intelligence";
|
|
886
1057
|
if (command === "setup") return "setup";
|
|
887
1058
|
if (command === "status") return "status";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable resolution contract for doctor/status checks.
|
|
3
|
+
* Panels render these as buttons; commands stay consent-gated in the CLI.
|
|
4
|
+
*/
|
|
5
|
+
export function resolution(id, label, command, {
|
|
6
|
+
kind = "run",
|
|
7
|
+
safety = "consent",
|
|
8
|
+
detail = ""
|
|
9
|
+
} = {}) {
|
|
10
|
+
return {
|
|
11
|
+
id: String(id),
|
|
12
|
+
label: String(label),
|
|
13
|
+
command: command == null ? null : String(command),
|
|
14
|
+
kind: String(kind),
|
|
15
|
+
safety: String(safety),
|
|
16
|
+
detail: detail == null ? "" : String(detail)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const RESOLUTION_SAFETY = Object.freeze({
|
|
21
|
+
READ_ONLY: "read-only",
|
|
22
|
+
CONSENT: "consent",
|
|
23
|
+
DESTRUCTIVE: "destructive"
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const RESOLUTION_KIND = Object.freeze({
|
|
27
|
+
RUN: "run",
|
|
28
|
+
CONFIGURE: "configure",
|
|
29
|
+
GUIDE: "guide",
|
|
30
|
+
REFRESH: "refresh"
|
|
31
|
+
});
|
package/src/global/cli-help.js
CHANGED
|
@@ -29,6 +29,7 @@ Usage:
|
|
|
29
29
|
${cli} Open the cockpit (setup on first run)
|
|
30
30
|
${cli} status See how your setup is doing
|
|
31
31
|
${cli} sync Repair what drifted
|
|
32
|
+
${cli} update Update Kairo itself (npm)
|
|
32
33
|
${cli} doctor Deeper health checks
|
|
33
34
|
|
|
34
35
|
${cli} help --all Every command and flag
|
|
@@ -63,7 +64,8 @@ Bootstrap: see README.md and docs/install.md (curl install.sh or npx ${PACKAGE_N
|
|
|
63
64
|
${cli} updates check [--json] [--force]
|
|
64
65
|
${cli} install [--agents <list|all>] [--components <list>] [--dry-run]
|
|
65
66
|
${cli} install --no-default-components
|
|
66
|
-
${cli} update [--
|
|
67
|
+
${cli} update [--yes] [--json] Update the Kairo CLI from npm
|
|
68
|
+
${cli} update --scope=workspace [--dry-run] Refresh workspace template files
|
|
67
69
|
${cli} uninstall [--dry-run]
|
|
68
70
|
|
|
69
71
|
## Agents & runs
|
|
@@ -107,10 +109,19 @@ Bootstrap: see README.md and docs/install.md (curl install.sh or npx ${PACKAGE_N
|
|
|
107
109
|
${cli} components
|
|
108
110
|
${cli} components validate|init|pack|import ...
|
|
109
111
|
${cli} components configure engram-memory [--agents <list>] [--dry-run|--yes] [--json]
|
|
110
|
-
${cli} components configure sdd-core [--agents <list>] [--persona off|teaching] [--dry-run|--yes] [--json]
|
|
112
|
+
${cli} components configure sdd-core [--agents <list>] [--persona off|teaching] [--overwrite-conflicts] [--dry-run|--yes] [--json]
|
|
111
113
|
${cli} components verify sdd-core [--agents <list>] [--json]
|
|
114
|
+
${cli} components adopt sdd-core [--agents <list>] [--dry-run|--yes] [--json]
|
|
115
|
+
${cli} components diff sdd-core [--agents <list>] [--json]
|
|
112
116
|
${cli} components rollback engram-memory|sdd-core --receipt <id> [--dry-run|--yes] [--json]
|
|
117
|
+
${cli} connections [--json] [--client cursor]
|
|
118
|
+
${cli} next [--json] [--client cursor]
|
|
119
|
+
${cli} fleet [--json] [--verbose] [--include-variants]
|
|
120
|
+
${cli} fleet models [--profile] [--json]
|
|
121
|
+
${cli} fleet configure [--platforms claude,opencode,cursor|codex] [--from profile|gentle] [--codex-model <id>] [--assignments a=b,...] [--yes] [--json]
|
|
122
|
+
${cli} fleet set --platform opencode|claude|codex --agent <id> --model <id> [--yes] [--json]
|
|
113
123
|
${cli} mcp
|
|
124
|
+
${cli} mcp install [--yes] [--json] [--client cursor]
|
|
114
125
|
${cli} install --scope=workspace [--mode minimal|standard|enterprise] (opt-in/legacy)
|
|
115
126
|
${cli} init [--mode minimal|standard|enterprise] (workspace alias)
|
|
116
127
|
|
|
@@ -143,7 +154,7 @@ Commands:
|
|
|
143
154
|
updates Read-only ecosystem update check (kairo/hermes/gentle/skills). Never applies.
|
|
144
155
|
install Non-interactive configure (agent-global) or legacy workspace scaffold.
|
|
145
156
|
doctor Detailed health checks for managed state and configs.
|
|
146
|
-
update
|
|
157
|
+
update Update the Kairo CLI from npm (--yes applies). Workspace templates: --scope=workspace.
|
|
147
158
|
detect Inspect global agents and the current project. Read-only.
|
|
148
159
|
adapters Official adapter matrix: roots, config files, detected/managed.
|
|
149
160
|
explain Read-only audit of managed adapters, configs, markers, and backups.
|
|
@@ -155,12 +166,20 @@ Commands:
|
|
|
155
166
|
policy View or edit local operation preferences under ~/.harness/policy.json.
|
|
156
167
|
report Read-only diagnostics bundle: status, policy, adapters, diff, history.
|
|
157
168
|
components List, validate, scaffold, pack, import, or configure integrations (Engram, SDD).
|
|
169
|
+
connections Companion chips + MCP registration (IDE panel).
|
|
170
|
+
next Selected work snapshot + integration state (panel contract).
|
|
171
|
+
fleet Declared fleet floor + working activity; configure/set models across CLIs.
|
|
172
|
+
fleet models [--profile] available vs enabled per tool
|
|
173
|
+
fleet configure one plan for Claude+OpenCode+Cursor (profile)
|
|
174
|
+
fleet configure --codex-model <id> Codex only (single-default)
|
|
175
|
+
fleet set --platform opencode|claude|codex --agent <id> --model <id> [--yes]
|
|
176
|
+
mcp Serve or install MCP for agents (mcp install writes entry + snapshot rule).
|
|
158
177
|
uninstall Remove managed sections and global state. Backups are preserved.
|
|
159
178
|
init Alias for install --scope=workspace (legacy).
|
|
160
179
|
|
|
161
180
|
JSON output (--json on supported commands):
|
|
162
181
|
status, sync, doctor, adapters, explain, diff, history, history last,
|
|
163
|
-
policy (show/set/reset), report, monitor
|
|
182
|
+
policy (show/set/reset), report, monitor, connections, fleet
|
|
164
183
|
Human text remains the default. See docs/cli-reference.md for examples and field notes.
|
|
165
184
|
|
|
166
185
|
Version:
|
|
@@ -9,6 +9,7 @@ import { requireIntegrationProvider } from "./integrations/provider-registry.js"
|
|
|
9
9
|
import { buildEngramIntegrationChecks, buildSddIntegrationChecks } from "./component-integration-cli.js";
|
|
10
10
|
import { KAIRO_ENGRAM_AGENT_IDS } from "./integrations/engram-evidence.js";
|
|
11
11
|
import { SDD_MANAGED_AGENT_IDS } from "./integrations/sdd-destinations.js";
|
|
12
|
+
import { adoptedHashesFromState } from "./integrations/sdd-state.js";
|
|
12
13
|
import { harnessHomePaths } from "./paths.js";
|
|
13
14
|
import { readGlobalState } from "./state.js";
|
|
14
15
|
|
|
@@ -78,6 +79,7 @@ async function buildSddChecks({ homeDir }) {
|
|
|
78
79
|
requestedAgentIds: installedAgents.length ? installedAgents : [],
|
|
79
80
|
detectedAgentIds: installedAgents,
|
|
80
81
|
trackedFiles,
|
|
82
|
+
adoptedFiles: adoptedHashesFromState(state?.sdd),
|
|
81
83
|
personaAgentIds: state?.sdd?.personaAgentIds ?? [],
|
|
82
84
|
packageRoot: PACKAGE_ROOT
|
|
83
85
|
});
|