@kal-elsam/kairo-runtime 0.1.3 → 0.1.5
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/package.json +1 -1
- package/scripts/install.sh +2 -2
- package/scripts/lib/install-script-url.mjs +30 -1
- package/src/cli.js +59 -3
- package/src/global/action-planner.js +178 -0
- package/src/global/agent-capabilities/create-capability-adapter.js +224 -0
- package/src/global/agent-capabilities/index.js +54 -0
- package/src/global/brand/cli.js +11 -7
- package/src/global/capability-registry.js +80 -0
- package/src/global/capability-states.js +30 -0
- package/src/global/cli-probe.js +47 -0
- package/src/global/ink/orchestrator-app.js +209 -0
- package/src/global/ink/orchestrator-state.js +78 -0
- package/src/global/ink/run-orchestrator-ink.js +29 -0
- package/src/global/orchestrator.js +139 -0
- package/src/global/paths.js +1 -0
- package/src/global/profile.js +146 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { harnessHomePaths } from "./paths.js";
|
|
5
|
+
import { AGENT_CAPABILITY_IDS } from "./agent-capabilities/index.js";
|
|
6
|
+
|
|
7
|
+
export const PROFILE_KEYS = new Set([
|
|
8
|
+
"coordinator",
|
|
9
|
+
"defaultAgents",
|
|
10
|
+
"defaultComponents",
|
|
11
|
+
"applyMode"
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
export const DEFAULT_PROFILE = {
|
|
15
|
+
coordinator: null,
|
|
16
|
+
defaultAgents: "detected",
|
|
17
|
+
defaultComponents: null,
|
|
18
|
+
applyMode: "prompt"
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const APPLY_MODES = new Set(["prompt", "confirm"]);
|
|
22
|
+
|
|
23
|
+
export function getGlobalProfilePath(homeDir) {
|
|
24
|
+
return join(harnessHomePaths(homeDir).root, "profile.json");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getProjectProfilePath(workspaceRoot) {
|
|
28
|
+
return join(workspaceRoot, ".harness", "kairo.json");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function loadProfileFile(filePath) {
|
|
32
|
+
if (!existsSync(filePath)) return null;
|
|
33
|
+
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = JSON.parse(await readFile(filePath, "utf8"));
|
|
37
|
+
} catch (error) {
|
|
38
|
+
throw new Error(`Invalid profile file at ${filePath}: ${error.message}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
42
|
+
throw new Error(`Invalid profile file at ${filePath}: expected a JSON object.`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function loadGlobalProfile(homeDir) {
|
|
49
|
+
return loadProfileFile(getGlobalProfilePath(homeDir));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export async function loadProjectProfile(workspaceRoot) {
|
|
53
|
+
return loadProfileFile(getProjectProfilePath(workspaceRoot));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function resolveProfile({ homeDir, workspaceRoot }) {
|
|
57
|
+
const globalRaw = await loadGlobalProfile(homeDir);
|
|
58
|
+
const projectRaw = await loadProjectProfile(workspaceRoot);
|
|
59
|
+
|
|
60
|
+
const merged = {
|
|
61
|
+
...DEFAULT_PROFILE,
|
|
62
|
+
...(globalRaw ?? {}),
|
|
63
|
+
...(projectRaw ?? {})
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
validateProfile(merged);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
profile: merged,
|
|
70
|
+
sources: {
|
|
71
|
+
global: globalRaw ? getGlobalProfilePath(homeDir) : null,
|
|
72
|
+
project: projectRaw ? getProjectProfilePath(workspaceRoot) : null
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function buildProfileJson(resolved) {
|
|
78
|
+
const { profile, sources } = resolved;
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
coordinator: profile.coordinator,
|
|
82
|
+
defaultAgents: profile.defaultAgents,
|
|
83
|
+
defaultComponents: profile.defaultComponents,
|
|
84
|
+
applyMode: profile.applyMode,
|
|
85
|
+
sources: {
|
|
86
|
+
global: sources.global,
|
|
87
|
+
project: sources.project,
|
|
88
|
+
precedence: "project overrides global overrides defaults"
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function saveGlobalProfile(homeDir, profile) {
|
|
94
|
+
validateProfile(profile);
|
|
95
|
+
const { root } = harnessHomePaths(homeDir);
|
|
96
|
+
const profilePath = getGlobalProfilePath(homeDir);
|
|
97
|
+
await mkdir(root, { recursive: true });
|
|
98
|
+
await writeFile(profilePath, `${JSON.stringify(profile, null, 2)}\n`, "utf8");
|
|
99
|
+
return profilePath;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function resolveProfileAgents(profile, detectedAgentIds) {
|
|
103
|
+
if (profile.defaultAgents === "detected") {
|
|
104
|
+
return detectedAgentIds.length > 0 ? [...detectedAgentIds] : [...AGENT_CAPABILITY_IDS];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (profile.defaultAgents === "all") {
|
|
108
|
+
return [...AGENT_CAPABILITY_IDS];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (Array.isArray(profile.defaultAgents)) {
|
|
112
|
+
return profile.defaultAgents.filter((id) => AGENT_CAPABILITY_IDS.includes(id));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return [...AGENT_CAPABILITY_IDS];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function validateProfile(profile) {
|
|
119
|
+
if (profile.coordinator != null && !AGENT_CAPABILITY_IDS.includes(profile.coordinator)) {
|
|
120
|
+
throw new Error(`Unknown coordinator "${profile.coordinator}". Use ${AGENT_CAPABILITY_IDS.join(", ")} or null.`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!APPLY_MODES.has(profile.applyMode)) {
|
|
124
|
+
throw new Error(`Invalid applyMode "${profile.applyMode}". Use prompt or confirm.`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (
|
|
128
|
+
profile.defaultAgents !== "detected"
|
|
129
|
+
&& profile.defaultAgents !== "all"
|
|
130
|
+
&& !Array.isArray(profile.defaultAgents)
|
|
131
|
+
) {
|
|
132
|
+
throw new Error('Profile defaultAgents must be "detected", "all", or an agent list.');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (Array.isArray(profile.defaultAgents)) {
|
|
136
|
+
for (const agent of profile.defaultAgents) {
|
|
137
|
+
if (!AGENT_CAPABILITY_IDS.includes(agent)) {
|
|
138
|
+
throw new Error(`Unknown agent "${agent}" in profile.`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (profile.defaultComponents != null && !Array.isArray(profile.defaultComponents)) {
|
|
144
|
+
throw new Error("Profile defaultComponents must be an array or null.");
|
|
145
|
+
}
|
|
146
|
+
}
|