@ai-devkit/agent-manager 0.37.0 → 0.38.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/dist/AgentManager.d.ts +0 -4
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +2 -2
- package/dist/AgentManager.js.map +1 -1
- package/dist/__tests__/capacity/anthropic.test.js +115 -0
- package/dist/__tests__/capacity/anthropic.test.js.map +1 -0
- package/dist/__tests__/capacity/boundaries.test.js +45 -0
- package/dist/__tests__/capacity/boundaries.test.js.map +1 -0
- package/dist/__tests__/capacity/claude.test.js +3 -3
- package/dist/__tests__/capacity/claude.test.js.map +1 -1
- package/dist/__tests__/capacity/codex.test.js +3 -1
- package/dist/__tests__/capacity/codex.test.js.map +1 -1
- package/dist/__tests__/capacity/openai.test.js +21 -12
- package/dist/__tests__/capacity/openai.test.js.map +1 -1
- package/dist/__tests__/capacity/wham.test.js +1 -1
- package/dist/__tests__/capacity/wham.test.js.map +1 -1
- package/dist/__tests__/capacity/zai.test.js +7 -8
- package/dist/__tests__/capacity/zai.test.js.map +1 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js +2 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -1
- package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js +7 -15
- package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js +3 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js +11 -26
- package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -1
- package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js +3 -7
- package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -1
- package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +5 -11
- package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -1
- package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +9 -19
- package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -1
- package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +3 -7
- package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -1
- package/dist/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.js +31 -10
- package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
- package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
- package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
- package/dist/__tests__/print/DurableAgent.test.js +4 -6
- package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
- package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
- package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
- package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
- package/dist/__tests__/terminal/TmuxManager.test.js +1 -1
- package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
- package/dist/capacity/index.d.ts +9 -19
- package/dist/capacity/index.d.ts.map +1 -1
- package/dist/capacity/index.js +11 -4
- package/dist/capacity/index.js.map +1 -1
- package/dist/capacity/providers/anthropic.d.ts +9 -0
- package/dist/capacity/providers/anthropic.d.ts.map +1 -0
- package/dist/capacity/{claude.js → providers/anthropic.js} +10 -128
- package/dist/capacity/providers/anthropic.js.map +1 -0
- package/dist/capacity/providers/openai-platform.d.ts +14 -0
- package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
- package/dist/capacity/providers/openai-platform.js +120 -0
- package/dist/capacity/providers/openai-platform.js.map +1 -0
- package/dist/capacity/providers/openai-subscription.d.ts +20 -0
- package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
- package/dist/capacity/providers/openai-subscription.js +129 -0
- package/dist/capacity/providers/openai-subscription.js.map +1 -0
- package/dist/capacity/providers/zai.d.ts +8 -0
- package/dist/capacity/providers/zai.d.ts.map +1 -0
- package/dist/capacity/{zai.js → providers/zai.js} +17 -62
- package/dist/capacity/providers/zai.js.map +1 -0
- package/dist/capacity/sources/claude.d.ts +9 -0
- package/dist/capacity/sources/claude.d.ts.map +1 -0
- package/dist/capacity/sources/claude.js +17 -0
- package/dist/capacity/sources/claude.js.map +1 -0
- package/dist/capacity/{codex.d.ts → sources/codex.d.ts} +5 -9
- package/dist/capacity/sources/codex.d.ts.map +1 -0
- package/dist/capacity/{codex.js → sources/codex.js} +31 -84
- package/dist/capacity/sources/codex.js.map +1 -0
- package/dist/capacity/sources/pi.d.ts +30 -0
- package/dist/capacity/sources/pi.d.ts.map +1 -0
- package/dist/capacity/sources/pi.js +81 -0
- package/dist/capacity/sources/pi.js.map +1 -0
- package/dist/capacity/types.d.ts +2 -0
- package/dist/capacity/types.d.ts.map +1 -1
- package/dist/capacity/types.js +1 -1
- package/dist/capacity/types.js.map +1 -1
- package/dist/harnesses/claude/credentials.d.ts +10 -0
- package/dist/harnesses/claude/credentials.d.ts.map +1 -0
- package/dist/harnesses/claude/credentials.js +112 -0
- package/dist/harnesses/claude/credentials.js.map +1 -0
- package/dist/harnesses/claude/readiness.d.ts +3 -0
- package/dist/harnesses/claude/readiness.d.ts.map +1 -0
- package/dist/harnesses/claude/readiness.js +63 -0
- package/dist/harnesses/claude/readiness.js.map +1 -0
- package/dist/harnesses/codex/credentials.d.ts +15 -0
- package/dist/harnesses/codex/credentials.d.ts.map +1 -0
- package/dist/harnesses/codex/credentials.js +58 -0
- package/dist/harnesses/codex/credentials.js.map +1 -0
- package/dist/harnesses/codex/readiness.d.ts +3 -0
- package/dist/harnesses/codex/readiness.d.ts.map +1 -0
- package/dist/harnesses/codex/readiness.js +60 -0
- package/dist/harnesses/codex/readiness.js.map +1 -0
- package/dist/harnesses/copilot/readiness.d.ts +3 -0
- package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
- package/dist/harnesses/copilot/readiness.js +39 -0
- package/dist/harnesses/copilot/readiness.js.map +1 -0
- package/dist/harnesses/opencode/readiness.d.ts +3 -0
- package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
- package/dist/harnesses/opencode/readiness.js +50 -0
- package/dist/harnesses/opencode/readiness.js.map +1 -0
- package/dist/harnesses/pi/credentials.d.ts +22 -0
- package/dist/harnesses/pi/credentials.d.ts.map +1 -0
- package/dist/harnesses/pi/credentials.js +98 -0
- package/dist/harnesses/pi/credentials.js.map +1 -0
- package/dist/harnesses/pi/readiness.d.ts +3 -0
- package/dist/harnesses/pi/readiness.d.ts.map +1 -0
- package/dist/harnesses/pi/readiness.js +96 -0
- package/dist/harnesses/pi/readiness.js.map +1 -0
- package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
- package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
- package/dist/harnesses/readiness/AgentReadiness.js +68 -0
- package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
- package/dist/harnesses/readiness/checks.d.ts +31 -0
- package/dist/harnesses/readiness/checks.d.ts.map +1 -0
- package/dist/harnesses/readiness/checks.js +270 -0
- package/dist/harnesses/readiness/checks.js.map +1 -0
- package/dist/{readiness/AgentReadiness.d.ts → harnesses/readiness/types.d.ts} +19 -10
- package/dist/harnesses/readiness/types.d.ts.map +1 -0
- package/dist/harnesses/readiness/types.js +4 -0
- package/dist/harnesses/readiness/types.js.map +1 -0
- package/dist/harnesses/runtimeProfiles.d.ts +11 -0
- package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
- package/dist/harnesses/runtimeProfiles.js +99 -0
- package/dist/harnesses/runtimeProfiles.js.map +1 -0
- package/dist/index.d.ts +16 -42
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -23
- package/dist/index.js.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
- package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
- package/dist/runtime/ManagedAgentRuntime.js +6 -20
- package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
- package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
- package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
- package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
- package/dist/runtime/tmux/PidPolling.d.ts +1 -1
- package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
- package/dist/runtime/tmux/PidPolling.js.map +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
- package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
- package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
- package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
- package/dist/{terminal → runtime/tmux}/TmuxManager.js +9 -28
- package/dist/runtime/tmux/TmuxManager.js.map +1 -0
- package/dist/runtime/types.d.ts +1 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/terminal/TerminalFocusManager.d.ts +4 -32
- package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
- package/dist/terminal/TerminalFocusManager.js +17 -267
- package/dist/terminal/TerminalFocusManager.js.map +1 -1
- package/dist/terminal/TtyWriter.d.ts +1 -44
- package/dist/terminal/TtyWriter.d.ts.map +1 -1
- package/dist/terminal/TtyWriter.js +11 -347
- package/dist/terminal/TtyWriter.js.map +1 -1
- package/dist/terminal/backends/index.d.ts +5 -0
- package/dist/terminal/backends/index.d.ts.map +1 -0
- package/dist/terminal/backends/index.js +19 -0
- package/dist/terminal/backends/index.js.map +1 -0
- package/dist/terminal/backends/iterm2.d.ts +3 -0
- package/dist/terminal/backends/iterm2.d.ts.map +1 -0
- package/dist/terminal/backends/iterm2.js +135 -0
- package/dist/terminal/backends/iterm2.js.map +1 -0
- package/dist/terminal/backends/shared.d.ts +7 -0
- package/dist/terminal/backends/shared.d.ts.map +1 -0
- package/dist/terminal/backends/shared.js +35 -0
- package/dist/terminal/backends/shared.js.map +1 -0
- package/dist/terminal/backends/terminal-app.d.ts +3 -0
- package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
- package/dist/terminal/backends/terminal-app.js +129 -0
- package/dist/terminal/backends/terminal-app.js.map +1 -0
- package/dist/terminal/backends/tmux.d.ts +3 -0
- package/dist/terminal/backends/tmux.d.ts.map +1 -0
- package/dist/terminal/backends/tmux.js +76 -0
- package/dist/terminal/backends/tmux.js.map +1 -0
- package/dist/terminal/backends/wezterm.d.ts +3 -0
- package/dist/terminal/backends/wezterm.d.ts.map +1 -0
- package/dist/terminal/backends/wezterm.js +71 -0
- package/dist/terminal/backends/wezterm.js.map +1 -0
- package/dist/terminal/types.d.ts +21 -0
- package/dist/terminal/types.d.ts.map +1 -0
- package/dist/terminal/types.js +10 -0
- package/dist/terminal/types.js.map +1 -0
- package/package.json +1 -1
- package/src/AgentManager.ts +1 -1
- package/src/__tests__/capacity/anthropic.test.ts +105 -0
- package/src/__tests__/capacity/boundaries.test.ts +36 -0
- package/src/__tests__/capacity/claude.test.ts +3 -8
- package/src/__tests__/capacity/codex.test.ts +12 -35
- package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
- package/src/__tests__/capacity/openai.test.ts +15 -15
- package/src/__tests__/capacity/wham.test.ts +1 -1
- package/src/__tests__/capacity/zai.test.ts +27 -62
- package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +2 -2
- package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +1 -1
- package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +14 -19
- package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +3 -3
- package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +24 -30
- package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +4 -8
- package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +7 -11
- package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +19 -22
- package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +7 -8
- package/src/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.ts +36 -9
- package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
- package/src/__tests__/print/DurableAgent.test.ts +4 -13
- package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
- package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +1 -1
- package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
- package/src/capacity/index.ts +29 -23
- package/src/capacity/{claude.ts → providers/anthropic.ts} +16 -131
- package/src/capacity/providers/openai-platform.ts +150 -0
- package/src/capacity/{wham.ts → providers/openai-subscription.ts} +86 -8
- package/src/capacity/{zai.ts → providers/zai.ts} +29 -111
- package/src/capacity/sources/claude.ts +30 -0
- package/src/capacity/{codex.ts → sources/codex.ts} +54 -124
- package/src/capacity/sources/pi.ts +131 -0
- package/src/capacity/types.ts +3 -0
- package/src/harnesses/claude/credentials.ts +122 -0
- package/src/harnesses/claude/readiness.ts +69 -0
- package/src/harnesses/codex/credentials.ts +81 -0
- package/src/harnesses/codex/readiness.ts +72 -0
- package/src/harnesses/copilot/readiness.ts +33 -0
- package/src/harnesses/opencode/readiness.ts +48 -0
- package/src/harnesses/pi/credentials.ts +129 -0
- package/src/harnesses/pi/readiness.ts +104 -0
- package/src/harnesses/readiness/AgentReadiness.ts +87 -0
- package/src/harnesses/readiness/checks.ts +336 -0
- package/src/harnesses/readiness/types.ts +90 -0
- package/src/{utils/agents.ts → harnesses/runtimeProfiles.ts} +34 -38
- package/src/index.ts +15 -128
- package/src/runtime/ManagedAgentRuntime.ts +7 -22
- package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
- package/src/runtime/tmux/PidPolling.ts +1 -1
- package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
- package/src/{terminal → runtime/tmux}/TmuxManager.ts +9 -30
- package/src/runtime/types.ts +1 -1
- package/src/terminal/TerminalFocusManager.ts +19 -292
- package/src/terminal/TtyWriter.ts +16 -336
- package/src/terminal/backends/index.ts +21 -0
- package/src/terminal/backends/iterm2.ts +126 -0
- package/src/terminal/backends/shared.ts +42 -0
- package/src/terminal/backends/terminal-app.ts +122 -0
- package/src/terminal/backends/tmux.ts +62 -0
- package/src/terminal/backends/wezterm.ts +65 -0
- package/src/terminal/types.ts +22 -0
- package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
- package/dist/__tests__/utils/agents.test.js +0 -93
- package/dist/__tests__/utils/agents.test.js.map +0 -1
- package/dist/capacity/claude.d.ts +0 -17
- package/dist/capacity/claude.d.ts.map +0 -1
- package/dist/capacity/claude.js.map +0 -1
- package/dist/capacity/codex.d.ts.map +0 -1
- package/dist/capacity/codex.js.map +0 -1
- package/dist/capacity/openai.d.ts +0 -47
- package/dist/capacity/openai.d.ts.map +0 -1
- package/dist/capacity/openai.js +0 -307
- package/dist/capacity/openai.js.map +0 -1
- package/dist/capacity/wham.d.ts +0 -16
- package/dist/capacity/wham.d.ts.map +0 -1
- package/dist/capacity/wham.js +0 -66
- package/dist/capacity/wham.js.map +0 -1
- package/dist/capacity/zai.d.ts +0 -14
- package/dist/capacity/zai.d.ts.map +0 -1
- package/dist/capacity/zai.js.map +0 -1
- package/dist/readiness/AgentReadiness.d.ts.map +0 -1
- package/dist/readiness/AgentReadiness.js +0 -614
- package/dist/readiness/AgentReadiness.js.map +0 -1
- package/dist/terminal/TmuxManager.d.ts +0 -28
- package/dist/terminal/TmuxManager.d.ts.map +0 -1
- package/dist/terminal/TmuxManager.js.map +0 -1
- package/dist/terminal/index.d.ts +0 -5
- package/dist/terminal/index.d.ts.map +0 -1
- package/dist/terminal/index.js +0 -5
- package/dist/terminal/index.js.map +0 -1
- package/dist/utils/agents.d.ts +0 -16
- package/dist/utils/agents.d.ts.map +0 -1
- package/dist/utils/agents.js +0 -117
- package/dist/utils/agents.js.map +0 -1
- package/dist/utils/index.d.ts +0 -8
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -6
- package/dist/utils/index.js.map +0 -1
- package/src/__tests__/utils/agents.test.ts +0 -105
- package/src/capacity/openai.ts +0 -355
- package/src/readiness/AgentReadiness.ts +0 -730
- package/src/terminal/index.ts +0 -4
- package/src/utils/index.ts +0 -14
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { claudeReadiness } from "../claude/readiness.js";
|
|
2
|
+
import { codexReadiness } from "../codex/readiness.js";
|
|
3
|
+
import { copilotReadiness } from "../copilot/readiness.js";
|
|
4
|
+
import { openCodeReadiness } from "../opencode/readiness.js";
|
|
5
|
+
import { piReadiness } from "../pi/readiness.js";
|
|
6
|
+
import {
|
|
7
|
+
builtInSkillsCheck,
|
|
8
|
+
createReadinessRuntime,
|
|
9
|
+
directoryCheck,
|
|
10
|
+
executableCheck,
|
|
11
|
+
worstReadinessStatus,
|
|
12
|
+
} from "./checks.js";
|
|
13
|
+
import {
|
|
14
|
+
READINESS_AGENT_TYPES,
|
|
15
|
+
type AgentReadinessOptions,
|
|
16
|
+
type AgentReadinessReport,
|
|
17
|
+
type HarnessReadinessProfile,
|
|
18
|
+
type ReadinessAgentType,
|
|
19
|
+
type ReadinessRuntime,
|
|
20
|
+
} from "./types.js";
|
|
21
|
+
|
|
22
|
+
const READINESS_PROFILES: Record<ReadinessAgentType, HarnessReadinessProfile> = {
|
|
23
|
+
claude: claudeReadiness,
|
|
24
|
+
codex: codexReadiness,
|
|
25
|
+
gemini_cli: { configDir: ".gemini" },
|
|
26
|
+
grok_cli: { configDir: ".grok" },
|
|
27
|
+
kiro: { configDir: ".kiro" },
|
|
28
|
+
antigravity_cli: { configDir: ".gemini/antigravity-cli" },
|
|
29
|
+
opencode: openCodeReadiness,
|
|
30
|
+
copilot: copilotReadiness,
|
|
31
|
+
pi: piReadiness,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export async function getAgentReadinessReport(
|
|
35
|
+
agent: ReadinessAgentType,
|
|
36
|
+
options: AgentReadinessOptions = {},
|
|
37
|
+
): Promise<AgentReadinessReport> {
|
|
38
|
+
return agentReadiness(agent, createReadinessRuntime(options));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function agentReadiness(
|
|
42
|
+
agent: ReadinessAgentType,
|
|
43
|
+
runtime: ReadinessRuntime,
|
|
44
|
+
): Promise<AgentReadinessReport> {
|
|
45
|
+
const profile = READINESS_PROFILES[agent];
|
|
46
|
+
const [executable, globalConfig, builtInSkills, auth, integration] = await Promise.all([
|
|
47
|
+
executableCheck(agent, runtime),
|
|
48
|
+
directoryCheck(profile.configDir, runtime),
|
|
49
|
+
builtInSkillsCheck(agent, runtime),
|
|
50
|
+
profile.auth?.(runtime),
|
|
51
|
+
profile.integration?.(runtime),
|
|
52
|
+
]);
|
|
53
|
+
return {
|
|
54
|
+
type: agent,
|
|
55
|
+
executable,
|
|
56
|
+
globalConfig,
|
|
57
|
+
builtInSkills,
|
|
58
|
+
auth,
|
|
59
|
+
integration,
|
|
60
|
+
status: worstReadinessStatus([
|
|
61
|
+
executable.status,
|
|
62
|
+
globalConfig.status,
|
|
63
|
+
...(auth ? [auth.status] : []),
|
|
64
|
+
...(integration ? [integration.status] : []),
|
|
65
|
+
]),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function getAgentReadinessReports(
|
|
70
|
+
options: AgentReadinessOptions = {},
|
|
71
|
+
): Promise<Record<ReadinessAgentType, AgentReadinessReport>> {
|
|
72
|
+
const runtime = createReadinessRuntime(options);
|
|
73
|
+
const entries = await Promise.all(
|
|
74
|
+
READINESS_AGENT_TYPES.map(
|
|
75
|
+
async (agent) => [agent, await agentReadiness(agent, runtime)] as const,
|
|
76
|
+
),
|
|
77
|
+
);
|
|
78
|
+
return Object.fromEntries(entries) as Record<ReadinessAgentType, AgentReadinessReport>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { worstReadinessStatus } from "./checks.js";
|
|
82
|
+
export type {
|
|
83
|
+
AgentReadinessOptions,
|
|
84
|
+
AgentReadinessReport,
|
|
85
|
+
ReadinessAgentType,
|
|
86
|
+
ReadinessStatus,
|
|
87
|
+
} from "./types.js";
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { access as fsAccess, readFile as fsReadFile } from "node:fs/promises";
|
|
4
|
+
import { delimiter, join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { getCodexCapacityReport } from "../../capacity/index.js";
|
|
7
|
+
import { HARNESS_RUNTIME_PROFILES } from "../runtimeProfiles.js";
|
|
8
|
+
import type {
|
|
9
|
+
AgentReadinessOptions,
|
|
10
|
+
BuiltInSkillsReadinessCheck,
|
|
11
|
+
DirectoryReadinessCheck,
|
|
12
|
+
ExecutableReadinessCheck,
|
|
13
|
+
ReadinessAgentType,
|
|
14
|
+
ReadinessCheck,
|
|
15
|
+
ReadinessRuntime,
|
|
16
|
+
ReadinessStatus,
|
|
17
|
+
} from "./types.js";
|
|
18
|
+
|
|
19
|
+
const execFileAsync = promisify(execFile);
|
|
20
|
+
|
|
21
|
+
export function createReadinessRuntime(options: AgentReadinessOptions): ReadinessRuntime {
|
|
22
|
+
return {
|
|
23
|
+
homeDir: options.homeDir ?? process.env.HOME ?? "",
|
|
24
|
+
path: options.path ?? process.env.PATH ?? "",
|
|
25
|
+
assetRoot: options.assetRoot ?? null,
|
|
26
|
+
builtInSkillNames: options.builtInSkillNames ?? [],
|
|
27
|
+
skillRoots: options.skillRoots ?? {},
|
|
28
|
+
readFile: options.readFile ?? ((target) => fsReadFile(target, "utf8")),
|
|
29
|
+
access: options.access ?? ((target, mode = constants.R_OK) => fsAccess(target, mode)),
|
|
30
|
+
runCommand: options.runCommand ?? defaultRunCommand,
|
|
31
|
+
codexAuth: options.codexAuth ?? (async () => (await getCodexCapacityReport()).authenticated),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function defaultRunCommand(command: string, args: string[]) {
|
|
36
|
+
const result = await execFileAsync(command, args, {
|
|
37
|
+
encoding: "utf8",
|
|
38
|
+
timeout: 5000,
|
|
39
|
+
maxBuffer: 1024 * 1024,
|
|
40
|
+
});
|
|
41
|
+
return { stdout: result.stdout, stderr: result.stderr };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function statusRank(status: ReadinessStatus): number {
|
|
45
|
+
return status === "fail" ? 2 : status === "warn" ? 1 : 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function worstReadinessStatus(statuses: ReadinessStatus[]): ReadinessStatus {
|
|
49
|
+
return statuses.reduce<ReadinessStatus>(
|
|
50
|
+
(worst, current) => (statusRank(current) > statusRank(worst) ? current : worst),
|
|
51
|
+
"pass",
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function displayHome(target: string, homeDir: string): string {
|
|
56
|
+
return target === homeDir
|
|
57
|
+
? "~"
|
|
58
|
+
: target.startsWith(`${homeDir}/`)
|
|
59
|
+
? `~${target.slice(homeDir.length)}`
|
|
60
|
+
: target;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function record(value: unknown): Record<string, unknown> | null {
|
|
64
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
65
|
+
? (value as Record<string, unknown>)
|
|
66
|
+
: null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function nonEmpty(value: unknown): boolean {
|
|
70
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function accessible(
|
|
74
|
+
target: string,
|
|
75
|
+
runtime: ReadinessRuntime,
|
|
76
|
+
mode = constants.R_OK,
|
|
77
|
+
): Promise<boolean> {
|
|
78
|
+
try {
|
|
79
|
+
await runtime.access(target, mode);
|
|
80
|
+
return true;
|
|
81
|
+
} catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function resolveExecutable(
|
|
87
|
+
command: string,
|
|
88
|
+
runtime: ReadinessRuntime,
|
|
89
|
+
): Promise<string | null> {
|
|
90
|
+
const candidates = runtime.path
|
|
91
|
+
.split(delimiter)
|
|
92
|
+
.filter(Boolean)
|
|
93
|
+
.map((directory) => join(directory, command));
|
|
94
|
+
const checks = await Promise.all(
|
|
95
|
+
candidates.map(async (target) => ({
|
|
96
|
+
target,
|
|
97
|
+
available: await accessible(target, runtime, constants.X_OK),
|
|
98
|
+
})),
|
|
99
|
+
);
|
|
100
|
+
return checks.find((check) => check.available)?.target ?? null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function executableCheck(
|
|
104
|
+
agent: ReadinessAgentType,
|
|
105
|
+
runtime: ReadinessRuntime,
|
|
106
|
+
): Promise<ExecutableReadinessCheck> {
|
|
107
|
+
const command = HARNESS_RUNTIME_PROFILES[agent].command;
|
|
108
|
+
const resolvedPath = await resolveExecutable(command, runtime);
|
|
109
|
+
return {
|
|
110
|
+
command,
|
|
111
|
+
path: resolvedPath,
|
|
112
|
+
status: resolvedPath ? "pass" : "fail",
|
|
113
|
+
errors: resolvedPath ? [] : [`${command} was not found on PATH`],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function directoryCheck(
|
|
118
|
+
configDir: string,
|
|
119
|
+
runtime: ReadinessRuntime,
|
|
120
|
+
): Promise<DirectoryReadinessCheck> {
|
|
121
|
+
const target = join(runtime.homeDir, configDir);
|
|
122
|
+
const readable = await accessible(target, runtime);
|
|
123
|
+
return {
|
|
124
|
+
path: displayHome(target, runtime.homeDir),
|
|
125
|
+
present: readable,
|
|
126
|
+
readable,
|
|
127
|
+
status: readable ? "pass" : "fail",
|
|
128
|
+
errors: readable ? [] : ["global configuration directory is unavailable"],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function builtInSkillsCheck(
|
|
133
|
+
agent: ReadinessAgentType,
|
|
134
|
+
runtime: ReadinessRuntime,
|
|
135
|
+
): Promise<BuiltInSkillsReadinessCheck> {
|
|
136
|
+
const relativeRoot = runtime.skillRoots[agent];
|
|
137
|
+
if (!relativeRoot) {
|
|
138
|
+
return {
|
|
139
|
+
path: null,
|
|
140
|
+
required: runtime.builtInSkillNames.length,
|
|
141
|
+
present: 0,
|
|
142
|
+
missing: [...runtime.builtInSkillNames],
|
|
143
|
+
status: "info",
|
|
144
|
+
errors: [],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const root = join(runtime.homeDir, relativeRoot);
|
|
148
|
+
const checks = await Promise.all(
|
|
149
|
+
runtime.builtInSkillNames.map(async (name) => ({
|
|
150
|
+
name,
|
|
151
|
+
present: await accessible(join(root, name, "SKILL.md"), runtime),
|
|
152
|
+
})),
|
|
153
|
+
);
|
|
154
|
+
const present = checks.filter((check) => check.present).map((check) => check.name);
|
|
155
|
+
const missing = runtime.builtInSkillNames.filter((name) => !present.includes(name));
|
|
156
|
+
return {
|
|
157
|
+
path: displayHome(root, runtime.homeDir),
|
|
158
|
+
required: runtime.builtInSkillNames.length,
|
|
159
|
+
present: present.length,
|
|
160
|
+
missing: [...missing],
|
|
161
|
+
status: "info",
|
|
162
|
+
errors: [],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export async function scriptCheck(
|
|
167
|
+
installed: string,
|
|
168
|
+
bundled: string,
|
|
169
|
+
runtime: ReadinessRuntime,
|
|
170
|
+
): Promise<
|
|
171
|
+
ReadinessCheck & {
|
|
172
|
+
path: string;
|
|
173
|
+
present: boolean;
|
|
174
|
+
readable: boolean;
|
|
175
|
+
matchesBundledAsset: boolean;
|
|
176
|
+
}
|
|
177
|
+
> {
|
|
178
|
+
let installedText: string;
|
|
179
|
+
try {
|
|
180
|
+
installedText = await runtime.readFile(installed);
|
|
181
|
+
} catch {
|
|
182
|
+
return {
|
|
183
|
+
path: displayHome(installed, runtime.homeDir),
|
|
184
|
+
present: false,
|
|
185
|
+
readable: false,
|
|
186
|
+
matchesBundledAsset: false,
|
|
187
|
+
status: "fail",
|
|
188
|
+
errors: ["hook script is unavailable"],
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const bundledText = await runtime.readFile(bundled);
|
|
193
|
+
const matches = installedText === bundledText;
|
|
194
|
+
return {
|
|
195
|
+
path: displayHome(installed, runtime.homeDir),
|
|
196
|
+
present: true,
|
|
197
|
+
readable: true,
|
|
198
|
+
matchesBundledAsset: matches,
|
|
199
|
+
status: matches ? "pass" : "fail",
|
|
200
|
+
errors: matches ? [] : ["hook script differs from the bundled AI DevKit asset"],
|
|
201
|
+
};
|
|
202
|
+
} catch {
|
|
203
|
+
return {
|
|
204
|
+
path: displayHome(installed, runtime.homeDir),
|
|
205
|
+
present: true,
|
|
206
|
+
readable: true,
|
|
207
|
+
matchesBundledAsset: false,
|
|
208
|
+
status: "fail",
|
|
209
|
+
errors: ["bundled hook asset is unavailable"],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function containsHook(root: unknown, event: string, command: string): boolean {
|
|
215
|
+
const hooks = record(record(root)?.hooks);
|
|
216
|
+
const entries = hooks?.[event];
|
|
217
|
+
if (!Array.isArray(entries)) return false;
|
|
218
|
+
return entries.some((entry) => {
|
|
219
|
+
const commands = record(entry)?.hooks;
|
|
220
|
+
return (
|
|
221
|
+
Array.isArray(commands) &&
|
|
222
|
+
commands.some((hook) => {
|
|
223
|
+
const item = record(hook);
|
|
224
|
+
return item?.type === "command" && item.command === command;
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export async function registrationCheck(
|
|
231
|
+
target: string,
|
|
232
|
+
event: string,
|
|
233
|
+
command: string,
|
|
234
|
+
runtime: ReadinessRuntime,
|
|
235
|
+
): Promise<
|
|
236
|
+
ReadinessCheck & {
|
|
237
|
+
path: string;
|
|
238
|
+
event: string;
|
|
239
|
+
command: string;
|
|
240
|
+
present: boolean;
|
|
241
|
+
valid: boolean;
|
|
242
|
+
}
|
|
243
|
+
> {
|
|
244
|
+
try {
|
|
245
|
+
const parsed = JSON.parse(await runtime.readFile(target));
|
|
246
|
+
const valid = containsHook(parsed, event, command);
|
|
247
|
+
return {
|
|
248
|
+
path: displayHome(target, runtime.homeDir),
|
|
249
|
+
event,
|
|
250
|
+
command,
|
|
251
|
+
present: true,
|
|
252
|
+
valid,
|
|
253
|
+
status: valid ? "pass" : "fail",
|
|
254
|
+
errors: valid ? [] : ["required hook registration is missing"],
|
|
255
|
+
};
|
|
256
|
+
} catch {
|
|
257
|
+
return {
|
|
258
|
+
path: displayHome(target, runtime.homeDir),
|
|
259
|
+
event,
|
|
260
|
+
command,
|
|
261
|
+
present: false,
|
|
262
|
+
valid: false,
|
|
263
|
+
status: "fail",
|
|
264
|
+
errors: ["hook configuration is missing or invalid"],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export async function mappingCheck(
|
|
270
|
+
target: string,
|
|
271
|
+
runtime: ReadinessRuntime,
|
|
272
|
+
): Promise<
|
|
273
|
+
ReadinessCheck & {
|
|
274
|
+
path: string;
|
|
275
|
+
present: boolean;
|
|
276
|
+
valid: boolean;
|
|
277
|
+
invalidEntries: number;
|
|
278
|
+
staleEntries: number;
|
|
279
|
+
}
|
|
280
|
+
> {
|
|
281
|
+
let text: string;
|
|
282
|
+
try {
|
|
283
|
+
text = await runtime.readFile(target);
|
|
284
|
+
} catch {
|
|
285
|
+
return {
|
|
286
|
+
path: displayHome(target, runtime.homeDir),
|
|
287
|
+
present: false,
|
|
288
|
+
valid: false,
|
|
289
|
+
invalidEntries: 0,
|
|
290
|
+
staleEntries: 0,
|
|
291
|
+
status: "warn",
|
|
292
|
+
errors: ["session mapping has not been created"],
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
let parsed: Record<string, unknown> | null = null;
|
|
296
|
+
try {
|
|
297
|
+
parsed = record(JSON.parse(text));
|
|
298
|
+
} catch {
|
|
299
|
+
// Fixed safe error below.
|
|
300
|
+
}
|
|
301
|
+
if (!parsed) {
|
|
302
|
+
return {
|
|
303
|
+
path: displayHome(target, runtime.homeDir),
|
|
304
|
+
present: true,
|
|
305
|
+
valid: false,
|
|
306
|
+
invalidEntries: 0,
|
|
307
|
+
staleEntries: 0,
|
|
308
|
+
status: "fail",
|
|
309
|
+
errors: ["session mapping is invalid"],
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
const entries = await Promise.all(
|
|
313
|
+
Object.entries(parsed).map(async ([pid, sessionPath]) => {
|
|
314
|
+
if (!/^\d+$/.test(pid) || typeof sessionPath !== "string" || !sessionPath) {
|
|
315
|
+
return { valid: false, stale: false };
|
|
316
|
+
}
|
|
317
|
+
return { valid: true, stale: !(await accessible(sessionPath, runtime)) };
|
|
318
|
+
}),
|
|
319
|
+
);
|
|
320
|
+
const invalidEntries = entries.filter((entry) => !entry.valid).length;
|
|
321
|
+
const staleEntries = entries.filter((entry) => entry.stale).length;
|
|
322
|
+
const valid = invalidEntries === 0;
|
|
323
|
+
return {
|
|
324
|
+
path: displayHome(target, runtime.homeDir),
|
|
325
|
+
present: true,
|
|
326
|
+
valid,
|
|
327
|
+
invalidEntries,
|
|
328
|
+
staleEntries,
|
|
329
|
+
status: !valid ? "fail" : staleEntries ? "warn" : "pass",
|
|
330
|
+
errors: !valid
|
|
331
|
+
? ["session mapping contains invalid entries"]
|
|
332
|
+
: staleEntries
|
|
333
|
+
? ["session mapping contains stale entries"]
|
|
334
|
+
: [],
|
|
335
|
+
};
|
|
336
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { AGENT_TYPES } from "../../adapters/AgentAdapter.js";
|
|
2
|
+
|
|
3
|
+
export const READINESS_AGENT_TYPES = AGENT_TYPES;
|
|
4
|
+
|
|
5
|
+
export type ReadinessStatus = "pass" | "warn" | "fail";
|
|
6
|
+
export type ReadinessAuthState = "authenticated" | "unauthenticated" | "unknown";
|
|
7
|
+
export type ReadinessAgentType = (typeof READINESS_AGENT_TYPES)[number];
|
|
8
|
+
type ReadinessInfoStatus = ReadinessStatus | "info";
|
|
9
|
+
|
|
10
|
+
export type CommandResult = { stdout: string; stderr: string };
|
|
11
|
+
export type ReadFile = (target: string) => Promise<string>;
|
|
12
|
+
export type Access = (target: string, mode?: number) => Promise<void>;
|
|
13
|
+
export type RunCommand = (command: string, args: string[]) => Promise<CommandResult>;
|
|
14
|
+
|
|
15
|
+
export interface ReadinessCheck<S extends ReadinessInfoStatus = ReadinessStatus> {
|
|
16
|
+
status: S;
|
|
17
|
+
errors: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ExecutableReadinessCheck extends ReadinessCheck {
|
|
21
|
+
command: string;
|
|
22
|
+
path: string | null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface DirectoryReadinessCheck extends ReadinessCheck {
|
|
26
|
+
path: string;
|
|
27
|
+
present: boolean;
|
|
28
|
+
readable: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface BuiltInSkillsReadinessCheck extends ReadinessCheck<"info"> {
|
|
32
|
+
path: string | null;
|
|
33
|
+
required: number;
|
|
34
|
+
present: number;
|
|
35
|
+
missing: string[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface AuthReadinessCheck extends ReadinessCheck {
|
|
39
|
+
state: ReadinessAuthState;
|
|
40
|
+
source: string;
|
|
41
|
+
provider: string | null;
|
|
42
|
+
availableProviders: string[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface IntegrationReadinessCheck extends ReadinessCheck {
|
|
46
|
+
label: string;
|
|
47
|
+
installed: boolean;
|
|
48
|
+
details?: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface AgentReadinessReport {
|
|
52
|
+
type: ReadinessAgentType;
|
|
53
|
+
executable: ExecutableReadinessCheck;
|
|
54
|
+
globalConfig: DirectoryReadinessCheck;
|
|
55
|
+
builtInSkills: BuiltInSkillsReadinessCheck;
|
|
56
|
+
auth?: AuthReadinessCheck;
|
|
57
|
+
integration?: IntegrationReadinessCheck;
|
|
58
|
+
status: ReadinessStatus;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface AgentReadinessOptions {
|
|
62
|
+
homeDir?: string;
|
|
63
|
+
path?: string;
|
|
64
|
+
assetRoot?: string;
|
|
65
|
+
builtInSkillNames?: readonly string[];
|
|
66
|
+
skillRoots?: Partial<Record<ReadinessAgentType, string>>;
|
|
67
|
+
readFile?: ReadFile;
|
|
68
|
+
access?: Access;
|
|
69
|
+
runCommand?: RunCommand;
|
|
70
|
+
codexAuth?: () => Promise<boolean | null>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export type ReadinessRuntime = Required<
|
|
74
|
+
Omit<AgentReadinessOptions, "assetRoot" | "builtInSkillNames" | "skillRoots">
|
|
75
|
+
> & {
|
|
76
|
+
assetRoot: string | null;
|
|
77
|
+
builtInSkillNames: readonly string[];
|
|
78
|
+
skillRoots: Partial<Record<ReadinessAgentType, string>>;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export type AuthReadinessProbe = (runtime: ReadinessRuntime) => Promise<AuthReadinessCheck>;
|
|
82
|
+
export type IntegrationReadinessProbe = (
|
|
83
|
+
runtime: ReadinessRuntime,
|
|
84
|
+
) => Promise<IntegrationReadinessCheck>;
|
|
85
|
+
|
|
86
|
+
export interface HarnessReadinessProfile {
|
|
87
|
+
configDir: string;
|
|
88
|
+
auth?: AuthReadinessProbe;
|
|
89
|
+
integration?: IntegrationReadinessProbe;
|
|
90
|
+
}
|
|
@@ -1,44 +1,46 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import
|
|
3
|
-
import { executablePath } from "
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { AGENT_TYPES, type AgentType } from "../adapters/AgentAdapter.js";
|
|
3
|
+
import { executablePath } from "../utils/process.js";
|
|
4
4
|
|
|
5
|
-
/** Every built-in harness can be started, so each needs an {@link AGENTS} entry. */
|
|
6
5
|
export type StartableAgentType = (typeof AGENT_TYPES)[number];
|
|
7
6
|
|
|
8
|
-
export interface
|
|
9
|
-
/** Shell command to launch the agent (sent to tmux via `send-keys`). */
|
|
7
|
+
export interface HarnessRuntimeProfile {
|
|
10
8
|
command: string;
|
|
11
|
-
|
|
9
|
+
runtimeKind: string;
|
|
10
|
+
discoveryAliases: readonly string[];
|
|
12
11
|
matches: (psCommand: string) => boolean;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
grok_cli: { command: "grok", matches: matchArgv0("grok") },
|
|
26
|
-
antigravity_cli: { command: "agy", matches: matchArgv0("agy") },
|
|
27
|
-
opencode: { command: "opencode", matches: matchArgv0("opencode") },
|
|
28
|
-
pi: { command: "pi", matches: matchAnyBasename(["pi"]) },
|
|
29
|
-
kiro: { command: "kiro-cli", matches: matchAnyBasename(["kiro-cli", "kiro"]) },
|
|
14
|
+
export const HARNESS_RUNTIME_PROFILES: Record<StartableAgentType, HarnessRuntimeProfile> = {
|
|
15
|
+
claude: profile("claude", matchArgv0("claude")),
|
|
16
|
+
codex: profile("codex", matchArgv0("codex")),
|
|
17
|
+
copilot: profile("copilot", matchArgv0Name("copilot-cli")),
|
|
18
|
+
gemini_cli: profile("gemini", matchAnyBasename(["gemini"]), ["gemini_cli"]),
|
|
19
|
+
grok_cli: profile("grok", matchArgv0("grok"), ["grok_cli"]),
|
|
20
|
+
antigravity_cli: profile("agy", matchArgv0("agy"), ["antigravity", "antigravity_cli"]),
|
|
21
|
+
opencode: profile("opencode", matchArgv0("opencode")),
|
|
22
|
+
pi: profile("pi", matchAnyBasename(["pi"])),
|
|
23
|
+
kiro: profile("kiro", matchAnyBasename(["kiro-cli", "kiro"]), ["kiro_cli", "kiro-cli"]),
|
|
30
24
|
};
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
export function runtimeAgentMatchesHarness(runtimeAgent: string, type: AgentType): boolean {
|
|
27
|
+
if (type === "other") return runtimeAgent.toLowerCase() === "other";
|
|
28
|
+
return HARNESS_RUNTIME_PROFILES[type].discoveryAliases.includes(runtimeAgent.toLowerCase());
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function profile(
|
|
32
|
+
runtimeKind: string,
|
|
33
|
+
matches: (psCommand: string) => boolean,
|
|
34
|
+
extraAliases: readonly string[] = [],
|
|
35
|
+
): HarnessRuntimeProfile {
|
|
36
|
+
return {
|
|
37
|
+
command: runtimeKind === "kiro" ? "kiro-cli" : runtimeKind,
|
|
38
|
+
runtimeKind,
|
|
39
|
+
discoveryAliases: [runtimeKind, ...extraAliases],
|
|
40
|
+
matches,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
42
44
|
const ABSOLUTE_PATH = /^(?:\/|[a-zA-Z]:[\\/])/;
|
|
43
45
|
const PATH_SEPARATOR = /[\\/]/;
|
|
44
46
|
|
|
@@ -50,14 +52,12 @@ function tokensOf(psCommand: string): string[] {
|
|
|
50
52
|
return psCommand.trim().split(/\s+/).filter(Boolean);
|
|
51
53
|
}
|
|
52
54
|
|
|
53
|
-
/** Split a command line into its resolved argv[0] and the remaining argument tokens. */
|
|
54
55
|
function splitArgv0(psCommand: string): { argv0: string; args: string[] } {
|
|
55
56
|
const command = psCommand.trim();
|
|
56
57
|
const argv0 = executablePath(command);
|
|
57
58
|
return { argv0, args: tokensOf(command.slice(argv0.length)) };
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
/** Whether argv[0] may span several tokens, i.e. a later path-like token satisfies `test`. */
|
|
61
61
|
function mayContinueArgv0(tokens: string[], test: (token: string) => boolean): boolean {
|
|
62
62
|
return (
|
|
63
63
|
ABSOLUTE_PATH.test(tokens[0]) &&
|
|
@@ -87,10 +87,6 @@ function matchArgv0Name(name: string): (psCommand: string) => boolean {
|
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
function matchAnyToken(name: string): (psCommand: string) => boolean {
|
|
91
|
-
return matchAnyBasename([name]);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
90
|
function matchAnyBasename(names: string[]): (psCommand: string) => boolean {
|
|
95
91
|
const lowers = new Set(names.map((name) => name.toLowerCase()));
|
|
96
92
|
const test = (token: string) => lowers.has(basenameOf(token));
|