@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.
Files changed (295) hide show
  1. package/dist/AgentManager.d.ts +0 -4
  2. package/dist/AgentManager.d.ts.map +1 -1
  3. package/dist/AgentManager.js +2 -2
  4. package/dist/AgentManager.js.map +1 -1
  5. package/dist/__tests__/capacity/anthropic.test.js +115 -0
  6. package/dist/__tests__/capacity/anthropic.test.js.map +1 -0
  7. package/dist/__tests__/capacity/boundaries.test.js +45 -0
  8. package/dist/__tests__/capacity/boundaries.test.js.map +1 -0
  9. package/dist/__tests__/capacity/claude.test.js +3 -3
  10. package/dist/__tests__/capacity/claude.test.js.map +1 -1
  11. package/dist/__tests__/capacity/codex.test.js +3 -1
  12. package/dist/__tests__/capacity/codex.test.js.map +1 -1
  13. package/dist/__tests__/capacity/openai.test.js +21 -12
  14. package/dist/__tests__/capacity/openai.test.js.map +1 -1
  15. package/dist/__tests__/capacity/wham.test.js +1 -1
  16. package/dist/__tests__/capacity/wham.test.js.map +1 -1
  17. package/dist/__tests__/capacity/zai.test.js +7 -8
  18. package/dist/__tests__/capacity/zai.test.js.map +1 -1
  19. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js +2 -1
  20. package/dist/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.js.map +1 -1
  21. package/dist/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.js.map +1 -1
  22. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js +7 -15
  23. package/dist/__tests__/harnesses/codex/durable/CodexCliProbe.test.js.map +1 -1
  24. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js +3 -1
  25. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.js.map +1 -1
  26. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js +11 -26
  27. package/dist/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.js.map +1 -1
  28. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js +3 -7
  29. package/dist/__tests__/harnesses/codex/durable/CodexPrintRunner.test.js.map +1 -1
  30. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js +5 -11
  31. package/dist/__tests__/harnesses/pi/durable/PiCliProbe.test.js.map +1 -1
  32. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js +9 -19
  33. package/dist/__tests__/harnesses/pi/durable/PiPrintAgentService.test.js.map +1 -1
  34. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js +3 -7
  35. package/dist/__tests__/harnesses/pi/durable/PiPrintRunner.test.js.map +1 -1
  36. package/dist/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.js +31 -10
  37. package/dist/__tests__/harnesses/readiness/AgentReadiness.test.js.map +1 -0
  38. package/dist/__tests__/harnesses/runtimeProfiles.test.js +89 -0
  39. package/dist/__tests__/harnesses/runtimeProfiles.test.js.map +1 -0
  40. package/dist/__tests__/print/DurableAgent.test.js +4 -6
  41. package/dist/__tests__/print/DurableAgent.test.js.map +1 -1
  42. package/dist/__tests__/print/DurableAgentRepository.test.js +1 -12
  43. package/dist/__tests__/print/DurableAgentRepository.test.js.map +1 -1
  44. package/dist/__tests__/runtime/ManagedAgentRuntime.test.js.map +1 -1
  45. package/dist/__tests__/terminal/TmuxManager.test.js +1 -1
  46. package/dist/__tests__/terminal/TmuxManager.test.js.map +1 -1
  47. package/dist/capacity/index.d.ts +9 -19
  48. package/dist/capacity/index.d.ts.map +1 -1
  49. package/dist/capacity/index.js +11 -4
  50. package/dist/capacity/index.js.map +1 -1
  51. package/dist/capacity/providers/anthropic.d.ts +9 -0
  52. package/dist/capacity/providers/anthropic.d.ts.map +1 -0
  53. package/dist/capacity/{claude.js → providers/anthropic.js} +10 -128
  54. package/dist/capacity/providers/anthropic.js.map +1 -0
  55. package/dist/capacity/providers/openai-platform.d.ts +14 -0
  56. package/dist/capacity/providers/openai-platform.d.ts.map +1 -0
  57. package/dist/capacity/providers/openai-platform.js +120 -0
  58. package/dist/capacity/providers/openai-platform.js.map +1 -0
  59. package/dist/capacity/providers/openai-subscription.d.ts +20 -0
  60. package/dist/capacity/providers/openai-subscription.d.ts.map +1 -0
  61. package/dist/capacity/providers/openai-subscription.js +129 -0
  62. package/dist/capacity/providers/openai-subscription.js.map +1 -0
  63. package/dist/capacity/providers/zai.d.ts +8 -0
  64. package/dist/capacity/providers/zai.d.ts.map +1 -0
  65. package/dist/capacity/{zai.js → providers/zai.js} +17 -62
  66. package/dist/capacity/providers/zai.js.map +1 -0
  67. package/dist/capacity/sources/claude.d.ts +9 -0
  68. package/dist/capacity/sources/claude.d.ts.map +1 -0
  69. package/dist/capacity/sources/claude.js +17 -0
  70. package/dist/capacity/sources/claude.js.map +1 -0
  71. package/dist/capacity/{codex.d.ts → sources/codex.d.ts} +5 -9
  72. package/dist/capacity/sources/codex.d.ts.map +1 -0
  73. package/dist/capacity/{codex.js → sources/codex.js} +31 -84
  74. package/dist/capacity/sources/codex.js.map +1 -0
  75. package/dist/capacity/sources/pi.d.ts +30 -0
  76. package/dist/capacity/sources/pi.d.ts.map +1 -0
  77. package/dist/capacity/sources/pi.js +81 -0
  78. package/dist/capacity/sources/pi.js.map +1 -0
  79. package/dist/capacity/types.d.ts +2 -0
  80. package/dist/capacity/types.d.ts.map +1 -1
  81. package/dist/capacity/types.js +1 -1
  82. package/dist/capacity/types.js.map +1 -1
  83. package/dist/harnesses/claude/credentials.d.ts +10 -0
  84. package/dist/harnesses/claude/credentials.d.ts.map +1 -0
  85. package/dist/harnesses/claude/credentials.js +112 -0
  86. package/dist/harnesses/claude/credentials.js.map +1 -0
  87. package/dist/harnesses/claude/readiness.d.ts +3 -0
  88. package/dist/harnesses/claude/readiness.d.ts.map +1 -0
  89. package/dist/harnesses/claude/readiness.js +63 -0
  90. package/dist/harnesses/claude/readiness.js.map +1 -0
  91. package/dist/harnesses/codex/credentials.d.ts +15 -0
  92. package/dist/harnesses/codex/credentials.d.ts.map +1 -0
  93. package/dist/harnesses/codex/credentials.js +58 -0
  94. package/dist/harnesses/codex/credentials.js.map +1 -0
  95. package/dist/harnesses/codex/readiness.d.ts +3 -0
  96. package/dist/harnesses/codex/readiness.d.ts.map +1 -0
  97. package/dist/harnesses/codex/readiness.js +60 -0
  98. package/dist/harnesses/codex/readiness.js.map +1 -0
  99. package/dist/harnesses/copilot/readiness.d.ts +3 -0
  100. package/dist/harnesses/copilot/readiness.d.ts.map +1 -0
  101. package/dist/harnesses/copilot/readiness.js +39 -0
  102. package/dist/harnesses/copilot/readiness.js.map +1 -0
  103. package/dist/harnesses/opencode/readiness.d.ts +3 -0
  104. package/dist/harnesses/opencode/readiness.d.ts.map +1 -0
  105. package/dist/harnesses/opencode/readiness.js +50 -0
  106. package/dist/harnesses/opencode/readiness.js.map +1 -0
  107. package/dist/harnesses/pi/credentials.d.ts +22 -0
  108. package/dist/harnesses/pi/credentials.d.ts.map +1 -0
  109. package/dist/harnesses/pi/credentials.js +98 -0
  110. package/dist/harnesses/pi/credentials.js.map +1 -0
  111. package/dist/harnesses/pi/readiness.d.ts +3 -0
  112. package/dist/harnesses/pi/readiness.d.ts.map +1 -0
  113. package/dist/harnesses/pi/readiness.js +96 -0
  114. package/dist/harnesses/pi/readiness.js.map +1 -0
  115. package/dist/harnesses/readiness/AgentReadiness.d.ts +6 -0
  116. package/dist/harnesses/readiness/AgentReadiness.d.ts.map +1 -0
  117. package/dist/harnesses/readiness/AgentReadiness.js +68 -0
  118. package/dist/harnesses/readiness/AgentReadiness.js.map +1 -0
  119. package/dist/harnesses/readiness/checks.d.ts +31 -0
  120. package/dist/harnesses/readiness/checks.d.ts.map +1 -0
  121. package/dist/harnesses/readiness/checks.js +270 -0
  122. package/dist/harnesses/readiness/checks.js.map +1 -0
  123. package/dist/{readiness/AgentReadiness.d.ts → harnesses/readiness/types.d.ts} +19 -10
  124. package/dist/harnesses/readiness/types.d.ts.map +1 -0
  125. package/dist/harnesses/readiness/types.js +4 -0
  126. package/dist/harnesses/readiness/types.js.map +1 -0
  127. package/dist/harnesses/runtimeProfiles.d.ts +11 -0
  128. package/dist/harnesses/runtimeProfiles.d.ts.map +1 -0
  129. package/dist/harnesses/runtimeProfiles.js +99 -0
  130. package/dist/harnesses/runtimeProfiles.js.map +1 -0
  131. package/dist/index.d.ts +16 -42
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +9 -23
  134. package/dist/index.js.map +1 -1
  135. package/dist/runtime/ManagedAgentRuntime.d.ts +3 -3
  136. package/dist/runtime/ManagedAgentRuntime.d.ts.map +1 -1
  137. package/dist/runtime/ManagedAgentRuntime.js +6 -20
  138. package/dist/runtime/ManagedAgentRuntime.js.map +1 -1
  139. package/dist/runtime/herdr/HerdrAgentDiscovery.d.ts.map +1 -1
  140. package/dist/runtime/herdr/HerdrAgentDiscovery.js +2 -43
  141. package/dist/runtime/herdr/HerdrAgentDiscovery.js.map +1 -1
  142. package/dist/runtime/tmux/PidPolling.d.ts +1 -1
  143. package/dist/runtime/tmux/PidPolling.d.ts.map +1 -1
  144. package/dist/runtime/tmux/PidPolling.js.map +1 -1
  145. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts +1 -1
  146. package/dist/runtime/tmux/TmuxAgentRuntime.d.ts.map +1 -1
  147. package/dist/runtime/tmux/TmuxAgentRuntime.js +1 -1
  148. package/dist/runtime/tmux/TmuxAgentRuntime.js.map +1 -1
  149. package/dist/runtime/tmux/TmuxManager.d.ts +12 -0
  150. package/dist/runtime/tmux/TmuxManager.d.ts.map +1 -0
  151. package/dist/{terminal → runtime/tmux}/TmuxManager.js +9 -28
  152. package/dist/runtime/tmux/TmuxManager.js.map +1 -0
  153. package/dist/runtime/types.d.ts +1 -1
  154. package/dist/runtime/types.d.ts.map +1 -1
  155. package/dist/runtime/types.js.map +1 -1
  156. package/dist/terminal/TerminalFocusManager.d.ts +4 -32
  157. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -1
  158. package/dist/terminal/TerminalFocusManager.js +17 -267
  159. package/dist/terminal/TerminalFocusManager.js.map +1 -1
  160. package/dist/terminal/TtyWriter.d.ts +1 -44
  161. package/dist/terminal/TtyWriter.d.ts.map +1 -1
  162. package/dist/terminal/TtyWriter.js +11 -347
  163. package/dist/terminal/TtyWriter.js.map +1 -1
  164. package/dist/terminal/backends/index.d.ts +5 -0
  165. package/dist/terminal/backends/index.d.ts.map +1 -0
  166. package/dist/terminal/backends/index.js +19 -0
  167. package/dist/terminal/backends/index.js.map +1 -0
  168. package/dist/terminal/backends/iterm2.d.ts +3 -0
  169. package/dist/terminal/backends/iterm2.d.ts.map +1 -0
  170. package/dist/terminal/backends/iterm2.js +135 -0
  171. package/dist/terminal/backends/iterm2.js.map +1 -0
  172. package/dist/terminal/backends/shared.d.ts +7 -0
  173. package/dist/terminal/backends/shared.d.ts.map +1 -0
  174. package/dist/terminal/backends/shared.js +35 -0
  175. package/dist/terminal/backends/shared.js.map +1 -0
  176. package/dist/terminal/backends/terminal-app.d.ts +3 -0
  177. package/dist/terminal/backends/terminal-app.d.ts.map +1 -0
  178. package/dist/terminal/backends/terminal-app.js +129 -0
  179. package/dist/terminal/backends/terminal-app.js.map +1 -0
  180. package/dist/terminal/backends/tmux.d.ts +3 -0
  181. package/dist/terminal/backends/tmux.d.ts.map +1 -0
  182. package/dist/terminal/backends/tmux.js +76 -0
  183. package/dist/terminal/backends/tmux.js.map +1 -0
  184. package/dist/terminal/backends/wezterm.d.ts +3 -0
  185. package/dist/terminal/backends/wezterm.d.ts.map +1 -0
  186. package/dist/terminal/backends/wezterm.js +71 -0
  187. package/dist/terminal/backends/wezterm.js.map +1 -0
  188. package/dist/terminal/types.d.ts +21 -0
  189. package/dist/terminal/types.d.ts.map +1 -0
  190. package/dist/terminal/types.js +10 -0
  191. package/dist/terminal/types.js.map +1 -0
  192. package/package.json +1 -1
  193. package/src/AgentManager.ts +1 -1
  194. package/src/__tests__/capacity/anthropic.test.ts +105 -0
  195. package/src/__tests__/capacity/boundaries.test.ts +36 -0
  196. package/src/__tests__/capacity/claude.test.ts +3 -8
  197. package/src/__tests__/capacity/codex.test.ts +12 -35
  198. package/src/__tests__/capacity/fixtures/openai-codex-auth.json +1 -1
  199. package/src/__tests__/capacity/openai.test.ts +15 -15
  200. package/src/__tests__/capacity/wham.test.ts +1 -1
  201. package/src/__tests__/capacity/zai.test.ts +27 -62
  202. package/src/__tests__/harnesses/claude/durable/ClaudePrintAgent.integration.test.ts +2 -2
  203. package/src/__tests__/harnesses/claude/durable/ClaudePrintRunner.test.ts +1 -1
  204. package/src/__tests__/harnesses/codex/durable/CodexCliProbe.test.ts +14 -19
  205. package/src/__tests__/harnesses/codex/durable/CodexPrintAgent.integration.test.ts +3 -3
  206. package/src/__tests__/harnesses/codex/durable/CodexPrintAgentService.test.ts +24 -30
  207. package/src/__tests__/harnesses/codex/durable/CodexPrintRunner.test.ts +4 -8
  208. package/src/__tests__/harnesses/pi/durable/PiCliProbe.test.ts +7 -11
  209. package/src/__tests__/harnesses/pi/durable/PiPrintAgentService.test.ts +19 -22
  210. package/src/__tests__/harnesses/pi/durable/PiPrintRunner.test.ts +7 -8
  211. package/src/__tests__/{readiness → harnesses/readiness}/AgentReadiness.test.ts +36 -9
  212. package/src/__tests__/harnesses/runtimeProfiles.test.ts +110 -0
  213. package/src/__tests__/print/DurableAgent.test.ts +4 -13
  214. package/src/__tests__/print/DurableAgentRepository.test.ts +1 -13
  215. package/src/__tests__/runtime/ManagedAgentRuntime.test.ts +1 -1
  216. package/src/__tests__/terminal/TmuxManager.test.ts +1 -1
  217. package/src/capacity/index.ts +29 -23
  218. package/src/capacity/{claude.ts → providers/anthropic.ts} +16 -131
  219. package/src/capacity/providers/openai-platform.ts +150 -0
  220. package/src/capacity/{wham.ts → providers/openai-subscription.ts} +86 -8
  221. package/src/capacity/{zai.ts → providers/zai.ts} +29 -111
  222. package/src/capacity/sources/claude.ts +30 -0
  223. package/src/capacity/{codex.ts → sources/codex.ts} +54 -124
  224. package/src/capacity/sources/pi.ts +131 -0
  225. package/src/capacity/types.ts +3 -0
  226. package/src/harnesses/claude/credentials.ts +122 -0
  227. package/src/harnesses/claude/readiness.ts +69 -0
  228. package/src/harnesses/codex/credentials.ts +81 -0
  229. package/src/harnesses/codex/readiness.ts +72 -0
  230. package/src/harnesses/copilot/readiness.ts +33 -0
  231. package/src/harnesses/opencode/readiness.ts +48 -0
  232. package/src/harnesses/pi/credentials.ts +129 -0
  233. package/src/harnesses/pi/readiness.ts +104 -0
  234. package/src/harnesses/readiness/AgentReadiness.ts +87 -0
  235. package/src/harnesses/readiness/checks.ts +336 -0
  236. package/src/harnesses/readiness/types.ts +90 -0
  237. package/src/{utils/agents.ts → harnesses/runtimeProfiles.ts} +34 -38
  238. package/src/index.ts +15 -128
  239. package/src/runtime/ManagedAgentRuntime.ts +7 -22
  240. package/src/runtime/herdr/HerdrAgentDiscovery.ts +3 -19
  241. package/src/runtime/tmux/PidPolling.ts +1 -1
  242. package/src/runtime/tmux/TmuxAgentRuntime.ts +1 -1
  243. package/src/{terminal → runtime/tmux}/TmuxManager.ts +9 -30
  244. package/src/runtime/types.ts +1 -1
  245. package/src/terminal/TerminalFocusManager.ts +19 -292
  246. package/src/terminal/TtyWriter.ts +16 -336
  247. package/src/terminal/backends/index.ts +21 -0
  248. package/src/terminal/backends/iterm2.ts +126 -0
  249. package/src/terminal/backends/shared.ts +42 -0
  250. package/src/terminal/backends/terminal-app.ts +122 -0
  251. package/src/terminal/backends/tmux.ts +62 -0
  252. package/src/terminal/backends/wezterm.ts +65 -0
  253. package/src/terminal/types.ts +22 -0
  254. package/dist/__tests__/readiness/AgentReadiness.test.js.map +0 -1
  255. package/dist/__tests__/utils/agents.test.js +0 -93
  256. package/dist/__tests__/utils/agents.test.js.map +0 -1
  257. package/dist/capacity/claude.d.ts +0 -17
  258. package/dist/capacity/claude.d.ts.map +0 -1
  259. package/dist/capacity/claude.js.map +0 -1
  260. package/dist/capacity/codex.d.ts.map +0 -1
  261. package/dist/capacity/codex.js.map +0 -1
  262. package/dist/capacity/openai.d.ts +0 -47
  263. package/dist/capacity/openai.d.ts.map +0 -1
  264. package/dist/capacity/openai.js +0 -307
  265. package/dist/capacity/openai.js.map +0 -1
  266. package/dist/capacity/wham.d.ts +0 -16
  267. package/dist/capacity/wham.d.ts.map +0 -1
  268. package/dist/capacity/wham.js +0 -66
  269. package/dist/capacity/wham.js.map +0 -1
  270. package/dist/capacity/zai.d.ts +0 -14
  271. package/dist/capacity/zai.d.ts.map +0 -1
  272. package/dist/capacity/zai.js.map +0 -1
  273. package/dist/readiness/AgentReadiness.d.ts.map +0 -1
  274. package/dist/readiness/AgentReadiness.js +0 -614
  275. package/dist/readiness/AgentReadiness.js.map +0 -1
  276. package/dist/terminal/TmuxManager.d.ts +0 -28
  277. package/dist/terminal/TmuxManager.d.ts.map +0 -1
  278. package/dist/terminal/TmuxManager.js.map +0 -1
  279. package/dist/terminal/index.d.ts +0 -5
  280. package/dist/terminal/index.d.ts.map +0 -1
  281. package/dist/terminal/index.js +0 -5
  282. package/dist/terminal/index.js.map +0 -1
  283. package/dist/utils/agents.d.ts +0 -16
  284. package/dist/utils/agents.d.ts.map +0 -1
  285. package/dist/utils/agents.js +0 -117
  286. package/dist/utils/agents.js.map +0 -1
  287. package/dist/utils/index.d.ts +0 -8
  288. package/dist/utils/index.d.ts.map +0 -1
  289. package/dist/utils/index.js +0 -6
  290. package/dist/utils/index.js.map +0 -1
  291. package/src/__tests__/utils/agents.test.ts +0 -105
  292. package/src/capacity/openai.ts +0 -355
  293. package/src/readiness/AgentReadiness.ts +0 -730
  294. package/src/terminal/index.ts +0 -4
  295. package/src/utils/index.ts +0 -14
@@ -0,0 +1,98 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ const OPENAI_CREDENTIALS_MISSING = "OpenAI credentials not found; set OPENAI_API_KEY, configure the Pi openai provider, or log in to OpenAI via Pi";
5
+ const ZAI_CREDENTIAL_MISSING = "z.ai API key not found; set Z_AI_API_KEY or configure Pi provider zai";
6
+ function record(value) {
7
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
8
+ }
9
+ function nonEmptyText(value) {
10
+ return typeof value === "string" && value.trim() ? value.trim() : null;
11
+ }
12
+ function epochMilliseconds(value) {
13
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return null;
14
+ return value > 1e12 ? value : value * 1000;
15
+ }
16
+ async function readPiAuthRoot(options) {
17
+ const env = options.env ?? process.env;
18
+ const authPath = join(env.HOME || homedir(), ".pi", "agent", "auth.json");
19
+ const contents = await (options.readFile ?? readFile)(authPath, "utf8");
20
+ const parsed = record(JSON.parse(contents));
21
+ if (!parsed) throw new Error("Pi auth file is malformed");
22
+ return parsed;
23
+ }
24
+ export async function resolvePiAnthropicCredential(options = {}) {
25
+ let root;
26
+ try {
27
+ root = await readPiAuthRoot(options);
28
+ } catch (error) {
29
+ if (record(error)?.code === "ENOENT") {
30
+ throw new Error("Pi Anthropic OAuth credentials not found");
31
+ }
32
+ throw new Error("Pi Anthropic auth file is malformed");
33
+ }
34
+ const credential = record(root.anthropic);
35
+ if (!credential) throw new Error("Pi Anthropic OAuth credentials not found");
36
+ const access = credential.type === "oauth" ? nonEmptyText(credential.access) : null;
37
+ if (!access) throw new Error("Pi Anthropic OAuth credential is malformed");
38
+ return {
39
+ kind: "oauth",
40
+ access,
41
+ expiresMs: epochMilliseconds(credential.expires)
42
+ };
43
+ }
44
+ export async function resolvePiOpenAiCredential(options = {}) {
45
+ const env = options.env ?? process.env;
46
+ const environmentKey = nonEmptyText(env.OPENAI_API_KEY);
47
+ if (environmentKey) return {
48
+ kind: "platform",
49
+ key: environmentKey
50
+ };
51
+ let root;
52
+ try {
53
+ root = await readPiAuthRoot(options);
54
+ } catch (error) {
55
+ if (record(error)?.code === "ENOENT") throw new Error(OPENAI_CREDENTIALS_MISSING);
56
+ throw new Error("OpenAI Pi auth file is malformed");
57
+ }
58
+ const platform = record(root.openai);
59
+ if (platform) {
60
+ const key = platform.type === "api_key" ? nonEmptyText(platform.key) : null;
61
+ if (!key) throw new Error("OpenAI Pi auth file has a malformed openai credential");
62
+ return {
63
+ kind: "platform",
64
+ key
65
+ };
66
+ }
67
+ const oauth = record(root["openai-codex"]);
68
+ const access = oauth?.type === "oauth" ? nonEmptyText(oauth.access) : null;
69
+ const accountId = nonEmptyText(oauth?.accountId);
70
+ if (oauth && access && accountId) {
71
+ return {
72
+ kind: "oauth",
73
+ access,
74
+ accountId,
75
+ expiresMs: epochMilliseconds(oauth.expires)
76
+ };
77
+ }
78
+ throw new Error(OPENAI_CREDENTIALS_MISSING);
79
+ }
80
+ export async function resolvePiZaiApiKey(options = {}) {
81
+ const env = options.env ?? process.env;
82
+ const environmentKey = nonEmptyText(env.Z_AI_API_KEY);
83
+ if (environmentKey) return environmentKey;
84
+ let root;
85
+ try {
86
+ root = await readPiAuthRoot(options);
87
+ } catch (error) {
88
+ if (record(error)?.code === "ENOENT") throw new Error(ZAI_CREDENTIAL_MISSING);
89
+ throw new Error("z.ai Pi auth file is malformed");
90
+ }
91
+ const credential = record(root.zai);
92
+ if (!credential) throw new Error(ZAI_CREDENTIAL_MISSING);
93
+ const key = credential.type === "api_key" ? nonEmptyText(credential.key) : null;
94
+ if (!key) throw new Error("z.ai Pi auth file has a malformed zai credential");
95
+ return key;
96
+ }
97
+
98
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/harnesses/pi/credentials.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport type PiCredentialOptions = {\n env?: NodeJS.ProcessEnv;\n readFile?: (path: string, encoding: BufferEncoding) => Promise<string>;\n};\n\nexport type PiAnthropicCredential = {\n kind: \"oauth\";\n access: string;\n expiresMs: number | null;\n};\n\nexport type PiOpenAiCredential =\n | { kind: \"platform\"; key: string }\n | { kind: \"oauth\"; access: string; accountId: string; expiresMs: number | null };\n\nconst OPENAI_CREDENTIALS_MISSING =\n \"OpenAI credentials not found; set OPENAI_API_KEY, configure the Pi openai provider, or log in to OpenAI via Pi\";\nconst ZAI_CREDENTIAL_MISSING =\n \"z.ai API key not found; set Z_AI_API_KEY or configure Pi provider zai\";\n\nfunction record(value: unknown): UnknownRecord | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as UnknownRecord)\n : null;\n}\n\nfunction nonEmptyText(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value.trim() : null;\n}\n\nfunction epochMilliseconds(value: unknown): number | null {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value <= 0) return null;\n return value > 1e12 ? value : value * 1000;\n}\n\nasync function readPiAuthRoot(options: PiCredentialOptions): Promise<UnknownRecord> {\n const env = options.env ?? process.env;\n const authPath = join(env.HOME || homedir(), \".pi\", \"agent\", \"auth.json\");\n const contents = await (options.readFile ?? readFile)(authPath, \"utf8\");\n const parsed = record(JSON.parse(contents));\n if (!parsed) throw new Error(\"Pi auth file is malformed\");\n return parsed;\n}\n\nexport async function resolvePiAnthropicCredential(\n options: PiCredentialOptions = {},\n): Promise<PiAnthropicCredential> {\n let root: UnknownRecord;\n try {\n root = await readPiAuthRoot(options);\n } catch (error) {\n if (record(error)?.code === \"ENOENT\") {\n throw new Error(\"Pi Anthropic OAuth credentials not found\");\n }\n throw new Error(\"Pi Anthropic auth file is malformed\");\n }\n\n const credential = record(root.anthropic);\n if (!credential) throw new Error(\"Pi Anthropic OAuth credentials not found\");\n const access = credential.type === \"oauth\" ? nonEmptyText(credential.access) : null;\n if (!access) throw new Error(\"Pi Anthropic OAuth credential is malformed\");\n return {\n kind: \"oauth\",\n access,\n expiresMs: epochMilliseconds(credential.expires),\n };\n}\n\nexport async function resolvePiOpenAiCredential(\n options: PiCredentialOptions = {},\n): Promise<PiOpenAiCredential> {\n const env = options.env ?? process.env;\n const environmentKey = nonEmptyText(env.OPENAI_API_KEY);\n if (environmentKey) return { kind: \"platform\", key: environmentKey };\n\n let root: UnknownRecord;\n try {\n root = await readPiAuthRoot(options);\n } catch (error) {\n if (record(error)?.code === \"ENOENT\") throw new Error(OPENAI_CREDENTIALS_MISSING);\n throw new Error(\"OpenAI Pi auth file is malformed\");\n }\n\n const platform = record(root.openai);\n if (platform) {\n const key = platform.type === \"api_key\" ? nonEmptyText(platform.key) : null;\n if (!key) throw new Error(\"OpenAI Pi auth file has a malformed openai credential\");\n return { kind: \"platform\", key };\n }\n\n const oauth = record(root[\"openai-codex\"]);\n const access = oauth?.type === \"oauth\" ? nonEmptyText(oauth.access) : null;\n const accountId = nonEmptyText(oauth?.accountId);\n if (oauth && access && accountId) {\n return {\n kind: \"oauth\",\n access,\n accountId,\n expiresMs: epochMilliseconds(oauth.expires),\n };\n }\n throw new Error(OPENAI_CREDENTIALS_MISSING);\n}\n\nexport async function resolvePiZaiApiKey(options: PiCredentialOptions = {}): Promise<string> {\n const env = options.env ?? process.env;\n const environmentKey = nonEmptyText(env.Z_AI_API_KEY);\n if (environmentKey) return environmentKey;\n\n let root: UnknownRecord;\n try {\n root = await readPiAuthRoot(options);\n } catch (error) {\n if (record(error)?.code === \"ENOENT\") throw new Error(ZAI_CREDENTIAL_MISSING);\n throw new Error(\"z.ai Pi auth file is malformed\");\n }\n\n const credential = record(root.zai);\n if (!credential) throw new Error(ZAI_CREDENTIAL_MISSING);\n const key = credential.type === \"api_key\" ? nonEmptyText(credential.key) : null;\n if (!key) throw new Error(\"z.ai Pi auth file has a malformed zai credential\");\n return key;\n}\n"],"names":["readFile","homedir","join","OPENAI_CREDENTIALS_MISSING","ZAI_CREDENTIAL_MISSING","record","value","Array","isArray","nonEmptyText","trim","epochMilliseconds","Number","isFinite","readPiAuthRoot","options","env","process","authPath","HOME","contents","parsed","JSON","parse","Error","resolvePiAnthropicCredential","root","error","code","credential","anthropic","access","type","kind","expiresMs","expires","resolvePiOpenAiCredential","environmentKey","OPENAI_API_KEY","key","platform","openai","oauth","accountId","resolvePiZaiApiKey","Z_AI_API_KEY","zai"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessReadinessProfile } from "../readiness/types.js";
2
+ export declare const piReadiness: HarnessReadinessProfile;
3
+ //# sourceMappingURL=readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../../../src/harnesses/pi/readiness.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,uBAAuB,EAGxB,MAAM,uBAAuB,CAAC;AAsF/B,eAAO,MAAM,WAAW,EAAE,uBAIzB,CAAC"}
@@ -0,0 +1,96 @@
1
+ import { join } from "node:path";
2
+ import { displayHome, mappingCheck, nonEmpty, record, worstReadinessStatus } from "../readiness/checks.js";
3
+ function providerNames(parsed) {
4
+ const names = new Set();
5
+ if (nonEmpty(parsed.provider)) names.add(parsed.provider.trim());
6
+ const providers = record(parsed.providers);
7
+ if (providers) {
8
+ for (const name of Object.keys(providers)){
9
+ if (name.trim()) names.add(name);
10
+ }
11
+ }
12
+ for (const [name, value] of Object.entries(parsed)){
13
+ if (name === "provider" || name === "providers") continue;
14
+ if (record(value) && name.trim()) names.add(name);
15
+ }
16
+ return [
17
+ ...names
18
+ ].sort();
19
+ }
20
+ async function authCheck(runtime) {
21
+ const sourcePath = join(runtime.homeDir, ".pi", "agent", "auth.json");
22
+ try {
23
+ const parsed = record(JSON.parse(await runtime.readFile(sourcePath)));
24
+ if (!parsed) throw new Error("invalid");
25
+ const availableProviders = providerNames(parsed);
26
+ const provider = nonEmpty(parsed.provider) ? parsed.provider.trim() : null;
27
+ const authenticated = availableProviders.length > 0;
28
+ return {
29
+ state: authenticated ? "authenticated" : "unauthenticated",
30
+ source: displayHome(sourcePath, runtime.homeDir),
31
+ provider,
32
+ availableProviders,
33
+ status: authenticated ? "pass" : "fail",
34
+ errors: authenticated ? [] : [
35
+ "Pi credential file has no configured model provider"
36
+ ]
37
+ };
38
+ } catch {
39
+ return {
40
+ state: "unauthenticated",
41
+ source: displayHome(sourcePath, runtime.homeDir),
42
+ provider: null,
43
+ availableProviders: [],
44
+ status: "fail",
45
+ errors: [
46
+ "Pi credential file is missing or invalid"
47
+ ]
48
+ };
49
+ }
50
+ }
51
+ function isSessionTrackerListed(output) {
52
+ const normalized = output.toLowerCase();
53
+ return normalized.includes("@ai-devkit/pi-session-tracker") || /\bsession[\s-]+tracker\b/.test(normalized);
54
+ }
55
+ async function integrationCheck(runtime) {
56
+ let installed = false;
57
+ try {
58
+ const result = await runtime.runCommand("pi", [
59
+ "list"
60
+ ]);
61
+ installed = isSessionTrackerListed(result.stdout);
62
+ } catch {
63
+ // Safe fixed result below.
64
+ }
65
+ const mapping = await mappingCheck(join(runtime.homeDir, ".pi", "agent", "sessions.json"), runtime);
66
+ const mappingStatus = mapping.valid || !mapping.present ? "pass" : "fail";
67
+ const status = worstReadinessStatus([
68
+ installed ? "pass" : "fail",
69
+ mappingStatus
70
+ ]);
71
+ return {
72
+ label: "ai-devkit plugin",
73
+ installed,
74
+ status,
75
+ errors: [
76
+ ...!installed ? [
77
+ "Pi session tracker is not registered"
78
+ ] : [],
79
+ ...mappingStatus === "fail" ? mapping.errors : []
80
+ ],
81
+ details: {
82
+ package: "@ai-devkit/pi-session-tracker",
83
+ registryPath: mapping.path,
84
+ registryValid: mapping.valid,
85
+ invalidEntries: mapping.invalidEntries,
86
+ staleEntries: mapping.staleEntries
87
+ }
88
+ };
89
+ }
90
+ export const piReadiness = {
91
+ configDir: ".pi",
92
+ auth: authCheck,
93
+ integration: integrationCheck
94
+ };
95
+
96
+ //# sourceMappingURL=readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/harnesses/pi/readiness.ts"],"sourcesContent":["import { join } from \"node:path\";\nimport {\n displayHome,\n mappingCheck,\n nonEmpty,\n record,\n worstReadinessStatus,\n} from \"../readiness/checks.js\";\nimport type {\n AuthReadinessCheck,\n HarnessReadinessProfile,\n IntegrationReadinessCheck,\n ReadinessRuntime,\n} from \"../readiness/types.js\";\n\nfunction providerNames(parsed: Record<string, unknown>): string[] {\n const names = new Set<string>();\n if (nonEmpty(parsed.provider)) names.add((parsed.provider as string).trim());\n const providers = record(parsed.providers);\n if (providers) {\n for (const name of Object.keys(providers)) {\n if (name.trim()) names.add(name);\n }\n }\n for (const [name, value] of Object.entries(parsed)) {\n if (name === \"provider\" || name === \"providers\") continue;\n if (record(value) && name.trim()) names.add(name);\n }\n return [...names].sort();\n}\n\nasync function authCheck(runtime: ReadinessRuntime): Promise<AuthReadinessCheck> {\n const sourcePath = join(runtime.homeDir, \".pi\", \"agent\", \"auth.json\");\n try {\n const parsed = record(JSON.parse(await runtime.readFile(sourcePath)));\n if (!parsed) throw new Error(\"invalid\");\n const availableProviders = providerNames(parsed);\n const provider = nonEmpty(parsed.provider) ? (parsed.provider as string).trim() : null;\n const authenticated = availableProviders.length > 0;\n return {\n state: authenticated ? \"authenticated\" : \"unauthenticated\",\n source: displayHome(sourcePath, runtime.homeDir),\n provider,\n availableProviders,\n status: authenticated ? \"pass\" : \"fail\",\n errors: authenticated ? [] : [\"Pi credential file has no configured model provider\"],\n };\n } catch {\n return {\n state: \"unauthenticated\",\n source: displayHome(sourcePath, runtime.homeDir),\n provider: null,\n availableProviders: [],\n status: \"fail\",\n errors: [\"Pi credential file is missing or invalid\"],\n };\n }\n}\n\nfunction isSessionTrackerListed(output: string): boolean {\n const normalized = output.toLowerCase();\n return (\n normalized.includes(\"@ai-devkit/pi-session-tracker\") ||\n /\\bsession[\\s-]+tracker\\b/.test(normalized)\n );\n}\n\nasync function integrationCheck(runtime: ReadinessRuntime): Promise<IntegrationReadinessCheck> {\n let installed = false;\n try {\n const result = await runtime.runCommand(\"pi\", [\"list\"]);\n installed = isSessionTrackerListed(result.stdout);\n } catch {\n // Safe fixed result below.\n }\n const mapping = await mappingCheck(\n join(runtime.homeDir, \".pi\", \"agent\", \"sessions.json\"),\n runtime,\n );\n const mappingStatus = mapping.valid || !mapping.present ? \"pass\" : \"fail\";\n const status = worstReadinessStatus([installed ? \"pass\" : \"fail\", mappingStatus]);\n return {\n label: \"ai-devkit plugin\",\n installed,\n status,\n errors: [\n ...(!installed ? [\"Pi session tracker is not registered\"] : []),\n ...(mappingStatus === \"fail\" ? mapping.errors : []),\n ],\n details: {\n package: \"@ai-devkit/pi-session-tracker\",\n registryPath: mapping.path,\n registryValid: mapping.valid,\n invalidEntries: mapping.invalidEntries,\n staleEntries: mapping.staleEntries,\n },\n };\n}\n\nexport const piReadiness: HarnessReadinessProfile = {\n configDir: \".pi\",\n auth: authCheck,\n integration: integrationCheck,\n};\n"],"names":["join","displayHome","mappingCheck","nonEmpty","record","worstReadinessStatus","providerNames","parsed","names","Set","provider","add","trim","providers","name","Object","keys","value","entries","sort","authCheck","runtime","sourcePath","homeDir","JSON","parse","readFile","Error","availableProviders","authenticated","length","state","source","status","errors","isSessionTrackerListed","output","normalized","toLowerCase","includes","test","integrationCheck","installed","result","runCommand","stdout","mapping","mappingStatus","valid","present","label","details","package","registryPath","path","registryValid","invalidEntries","staleEntries","piReadiness","configDir","auth","integration"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type AgentReadinessOptions, type AgentReadinessReport, type ReadinessAgentType } from "./types.js";
2
+ export declare function getAgentReadinessReport(agent: ReadinessAgentType, options?: AgentReadinessOptions): Promise<AgentReadinessReport>;
3
+ export declare function getAgentReadinessReports(options?: AgentReadinessOptions): Promise<Record<ReadinessAgentType, AgentReadinessReport>>;
4
+ export { worstReadinessStatus } from "./checks.js";
5
+ export type { AgentReadinessOptions, AgentReadinessReport, ReadinessAgentType, ReadinessStatus, } from "./types.js";
6
+ //# sourceMappingURL=AgentReadiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentReadiness.d.ts","sourceRoot":"","sources":["../../../src/harnesses/readiness/AgentReadiness.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAEzB,KAAK,kBAAkB,EAExB,MAAM,YAAY,CAAC;AAcpB,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AA8BD,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC,CAQ3D;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,68 @@
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 { builtInSkillsCheck, createReadinessRuntime, directoryCheck, executableCheck, worstReadinessStatus } from "./checks.js";
7
+ import { READINESS_AGENT_TYPES } from "./types.js";
8
+ const READINESS_PROFILES = {
9
+ claude: claudeReadiness,
10
+ codex: codexReadiness,
11
+ gemini_cli: {
12
+ configDir: ".gemini"
13
+ },
14
+ grok_cli: {
15
+ configDir: ".grok"
16
+ },
17
+ kiro: {
18
+ configDir: ".kiro"
19
+ },
20
+ antigravity_cli: {
21
+ configDir: ".gemini/antigravity-cli"
22
+ },
23
+ opencode: openCodeReadiness,
24
+ copilot: copilotReadiness,
25
+ pi: piReadiness
26
+ };
27
+ export async function getAgentReadinessReport(agent, options = {}) {
28
+ return agentReadiness(agent, createReadinessRuntime(options));
29
+ }
30
+ async function agentReadiness(agent, runtime) {
31
+ const profile = READINESS_PROFILES[agent];
32
+ const [executable, globalConfig, builtInSkills, auth, integration] = await Promise.all([
33
+ executableCheck(agent, runtime),
34
+ directoryCheck(profile.configDir, runtime),
35
+ builtInSkillsCheck(agent, runtime),
36
+ profile.auth?.(runtime),
37
+ profile.integration?.(runtime)
38
+ ]);
39
+ return {
40
+ type: agent,
41
+ executable,
42
+ globalConfig,
43
+ builtInSkills,
44
+ auth,
45
+ integration,
46
+ status: worstReadinessStatus([
47
+ executable.status,
48
+ globalConfig.status,
49
+ ...auth ? [
50
+ auth.status
51
+ ] : [],
52
+ ...integration ? [
53
+ integration.status
54
+ ] : []
55
+ ])
56
+ };
57
+ }
58
+ export async function getAgentReadinessReports(options = {}) {
59
+ const runtime = createReadinessRuntime(options);
60
+ const entries = await Promise.all(READINESS_AGENT_TYPES.map(async (agent)=>[
61
+ agent,
62
+ await agentReadiness(agent, runtime)
63
+ ]));
64
+ return Object.fromEntries(entries);
65
+ }
66
+ export { worstReadinessStatus } from "./checks.js";
67
+
68
+ //# sourceMappingURL=AgentReadiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/harnesses/readiness/AgentReadiness.ts"],"sourcesContent":["import { claudeReadiness } from \"../claude/readiness.js\";\nimport { codexReadiness } from \"../codex/readiness.js\";\nimport { copilotReadiness } from \"../copilot/readiness.js\";\nimport { openCodeReadiness } from \"../opencode/readiness.js\";\nimport { piReadiness } from \"../pi/readiness.js\";\nimport {\n builtInSkillsCheck,\n createReadinessRuntime,\n directoryCheck,\n executableCheck,\n worstReadinessStatus,\n} from \"./checks.js\";\nimport {\n READINESS_AGENT_TYPES,\n type AgentReadinessOptions,\n type AgentReadinessReport,\n type HarnessReadinessProfile,\n type ReadinessAgentType,\n type ReadinessRuntime,\n} from \"./types.js\";\n\nconst READINESS_PROFILES: Record<ReadinessAgentType, HarnessReadinessProfile> = {\n claude: claudeReadiness,\n codex: codexReadiness,\n gemini_cli: { configDir: \".gemini\" },\n grok_cli: { configDir: \".grok\" },\n kiro: { configDir: \".kiro\" },\n antigravity_cli: { configDir: \".gemini/antigravity-cli\" },\n opencode: openCodeReadiness,\n copilot: copilotReadiness,\n pi: piReadiness,\n};\n\nexport async function getAgentReadinessReport(\n agent: ReadinessAgentType,\n options: AgentReadinessOptions = {},\n): Promise<AgentReadinessReport> {\n return agentReadiness(agent, createReadinessRuntime(options));\n}\n\nasync function agentReadiness(\n agent: ReadinessAgentType,\n runtime: ReadinessRuntime,\n): Promise<AgentReadinessReport> {\n const profile = READINESS_PROFILES[agent];\n const [executable, globalConfig, builtInSkills, auth, integration] = await Promise.all([\n executableCheck(agent, runtime),\n directoryCheck(profile.configDir, runtime),\n builtInSkillsCheck(agent, runtime),\n profile.auth?.(runtime),\n profile.integration?.(runtime),\n ]);\n return {\n type: agent,\n executable,\n globalConfig,\n builtInSkills,\n auth,\n integration,\n status: worstReadinessStatus([\n executable.status,\n globalConfig.status,\n ...(auth ? [auth.status] : []),\n ...(integration ? [integration.status] : []),\n ]),\n };\n}\n\nexport async function getAgentReadinessReports(\n options: AgentReadinessOptions = {},\n): Promise<Record<ReadinessAgentType, AgentReadinessReport>> {\n const runtime = createReadinessRuntime(options);\n const entries = await Promise.all(\n READINESS_AGENT_TYPES.map(\n async (agent) => [agent, await agentReadiness(agent, runtime)] as const,\n ),\n );\n return Object.fromEntries(entries) as Record<ReadinessAgentType, AgentReadinessReport>;\n}\n\nexport { worstReadinessStatus } from \"./checks.js\";\nexport type {\n AgentReadinessOptions,\n AgentReadinessReport,\n ReadinessAgentType,\n ReadinessStatus,\n} from \"./types.js\";\n"],"names":["claudeReadiness","codexReadiness","copilotReadiness","openCodeReadiness","piReadiness","builtInSkillsCheck","createReadinessRuntime","directoryCheck","executableCheck","worstReadinessStatus","READINESS_AGENT_TYPES","READINESS_PROFILES","claude","codex","gemini_cli","configDir","grok_cli","kiro","antigravity_cli","opencode","copilot","pi","getAgentReadinessReport","agent","options","agentReadiness","runtime","profile","executable","globalConfig","builtInSkills","auth","integration","Promise","all","type","status","getAgentReadinessReports","entries","map","Object","fromEntries"],"mappings":"AAAA,SAASA,eAAe,QAAQ,yBAAyB;AACzD,SAASC,cAAc,QAAQ,wBAAwB;AACvD,SAASC,gBAAgB,QAAQ,0BAA0B;AAC3D,SAASC,iBAAiB,QAAQ,2BAA2B;AAC7D,SAASC,WAAW,QAAQ,qBAAqB;AACjD,SACEC,kBAAkB,EAClBC,sBAAsB,EACtBC,cAAc,EACdC,eAAe,EACfC,oBAAoB,QACf,cAAc;AACrB,SACEC,qBAAqB,QAMhB,aAAa;AAEpB,MAAMC,qBAA0E;IAC9EC,QAAQZ;IACRa,OAAOZ;IACPa,YAAY;QAAEC,WAAW;IAAU;IACnCC,UAAU;QAAED,WAAW;IAAQ;IAC/BE,MAAM;QAAEF,WAAW;IAAQ;IAC3BG,iBAAiB;QAAEH,WAAW;IAA0B;IACxDI,UAAUhB;IACViB,SAASlB;IACTmB,IAAIjB;AACN;AAEA,OAAO,eAAekB,wBACpBC,KAAyB,EACzBC,UAAiC,CAAC,CAAC;IAEnC,OAAOC,eAAeF,OAAOjB,uBAAuBkB;AACtD;AAEA,eAAeC,eACbF,KAAyB,EACzBG,OAAyB;IAEzB,MAAMC,UAAUhB,kBAAkB,CAACY,MAAM;IACzC,MAAM,CAACK,YAAYC,cAAcC,eAAeC,MAAMC,YAAY,GAAG,MAAMC,QAAQC,GAAG,CAAC;QACrF1B,gBAAgBe,OAAOG;QACvBnB,eAAeoB,QAAQZ,SAAS,EAAEW;QAClCrB,mBAAmBkB,OAAOG;QAC1BC,QAAQI,IAAI,GAAGL;QACfC,QAAQK,WAAW,GAAGN;KACvB;IACD,OAAO;QACLS,MAAMZ;QACNK;QACAC;QACAC;QACAC;QACAC;QACAI,QAAQ3B,qBAAqB;YAC3BmB,WAAWQ,MAAM;YACjBP,aAAaO,MAAM;eACfL,OAAO;gBAACA,KAAKK,MAAM;aAAC,GAAG,EAAE;eACzBJ,cAAc;gBAACA,YAAYI,MAAM;aAAC,GAAG,EAAE;SAC5C;IACH;AACF;AAEA,OAAO,eAAeC,yBACpBb,UAAiC,CAAC,CAAC;IAEnC,MAAME,UAAUpB,uBAAuBkB;IACvC,MAAMc,UAAU,MAAML,QAAQC,GAAG,CAC/BxB,sBAAsB6B,GAAG,CACvB,OAAOhB,QAAU;YAACA;YAAO,MAAME,eAAeF,OAAOG;SAAS;IAGlE,OAAOc,OAAOC,WAAW,CAACH;AAC5B;AAEA,SAAS7B,oBAAoB,QAAQ,cAAc"}
@@ -0,0 +1,31 @@
1
+ import type { AgentReadinessOptions, BuiltInSkillsReadinessCheck, DirectoryReadinessCheck, ExecutableReadinessCheck, ReadinessAgentType, ReadinessCheck, ReadinessRuntime, ReadinessStatus } from "./types.js";
2
+ export declare function createReadinessRuntime(options: AgentReadinessOptions): ReadinessRuntime;
3
+ export declare function worstReadinessStatus(statuses: ReadinessStatus[]): ReadinessStatus;
4
+ export declare function displayHome(target: string, homeDir: string): string;
5
+ export declare function record(value: unknown): Record<string, unknown> | null;
6
+ export declare function nonEmpty(value: unknown): boolean;
7
+ export declare function accessible(target: string, runtime: ReadinessRuntime, mode?: number): Promise<boolean>;
8
+ export declare function executableCheck(agent: ReadinessAgentType, runtime: ReadinessRuntime): Promise<ExecutableReadinessCheck>;
9
+ export declare function directoryCheck(configDir: string, runtime: ReadinessRuntime): Promise<DirectoryReadinessCheck>;
10
+ export declare function builtInSkillsCheck(agent: ReadinessAgentType, runtime: ReadinessRuntime): Promise<BuiltInSkillsReadinessCheck>;
11
+ export declare function scriptCheck(installed: string, bundled: string, runtime: ReadinessRuntime): Promise<ReadinessCheck & {
12
+ path: string;
13
+ present: boolean;
14
+ readable: boolean;
15
+ matchesBundledAsset: boolean;
16
+ }>;
17
+ export declare function registrationCheck(target: string, event: string, command: string, runtime: ReadinessRuntime): Promise<ReadinessCheck & {
18
+ path: string;
19
+ event: string;
20
+ command: string;
21
+ present: boolean;
22
+ valid: boolean;
23
+ }>;
24
+ export declare function mappingCheck(target: string, runtime: ReadinessRuntime): Promise<ReadinessCheck & {
25
+ path: string;
26
+ present: boolean;
27
+ valid: boolean;
28
+ invalidEntries: number;
29
+ staleEntries: number;
30
+ }>;
31
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../../src/harnesses/readiness/checks.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAC;AAIpB,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,qBAAqB,GAAG,gBAAgB,CAYvF;AAeD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,eAAe,CAKjF;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAMnE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAIrE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhD;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,IAAI,SAAiB,GACpB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAmBD,wBAAsB,eAAe,CACnC,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,wBAAwB,CAAC,CASnC;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,uBAAuB,CAAC,CAUlC;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,2BAA2B,CAAC,CA6BtC;AAED,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GACxB,OAAO,CACR,cAAc,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CACF,CAmCA;AAkBD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GACxB,OAAO,CACR,cAAc,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB,CACF,CAwBA;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,GACxB,OAAO,CACR,cAAc,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,CACF,CAwDA"}
@@ -0,0 +1,270 @@
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
+ const execFileAsync = promisify(execFile);
9
+ export function createReadinessRuntime(options) {
10
+ return {
11
+ homeDir: options.homeDir ?? process.env.HOME ?? "",
12
+ path: options.path ?? process.env.PATH ?? "",
13
+ assetRoot: options.assetRoot ?? null,
14
+ builtInSkillNames: options.builtInSkillNames ?? [],
15
+ skillRoots: options.skillRoots ?? {},
16
+ readFile: options.readFile ?? ((target)=>fsReadFile(target, "utf8")),
17
+ access: options.access ?? ((target, mode = constants.R_OK)=>fsAccess(target, mode)),
18
+ runCommand: options.runCommand ?? defaultRunCommand,
19
+ codexAuth: options.codexAuth ?? (async ()=>(await getCodexCapacityReport()).authenticated)
20
+ };
21
+ }
22
+ async function defaultRunCommand(command, args) {
23
+ const result = await execFileAsync(command, args, {
24
+ encoding: "utf8",
25
+ timeout: 5000,
26
+ maxBuffer: 1024 * 1024
27
+ });
28
+ return {
29
+ stdout: result.stdout,
30
+ stderr: result.stderr
31
+ };
32
+ }
33
+ function statusRank(status) {
34
+ return status === "fail" ? 2 : status === "warn" ? 1 : 0;
35
+ }
36
+ export function worstReadinessStatus(statuses) {
37
+ return statuses.reduce((worst, current)=>statusRank(current) > statusRank(worst) ? current : worst, "pass");
38
+ }
39
+ export function displayHome(target, homeDir) {
40
+ return target === homeDir ? "~" : target.startsWith(`${homeDir}/`) ? `~${target.slice(homeDir.length)}` : target;
41
+ }
42
+ export function record(value) {
43
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
44
+ }
45
+ export function nonEmpty(value) {
46
+ return typeof value === "string" && value.trim().length > 0;
47
+ }
48
+ export async function accessible(target, runtime, mode = constants.R_OK) {
49
+ try {
50
+ await runtime.access(target, mode);
51
+ return true;
52
+ } catch {
53
+ return false;
54
+ }
55
+ }
56
+ async function resolveExecutable(command, runtime) {
57
+ const candidates = runtime.path.split(delimiter).filter(Boolean).map((directory)=>join(directory, command));
58
+ const checks = await Promise.all(candidates.map(async (target)=>({
59
+ target,
60
+ available: await accessible(target, runtime, constants.X_OK)
61
+ })));
62
+ return checks.find((check)=>check.available)?.target ?? null;
63
+ }
64
+ export async function executableCheck(agent, runtime) {
65
+ const command = HARNESS_RUNTIME_PROFILES[agent].command;
66
+ const resolvedPath = await resolveExecutable(command, runtime);
67
+ return {
68
+ command,
69
+ path: resolvedPath,
70
+ status: resolvedPath ? "pass" : "fail",
71
+ errors: resolvedPath ? [] : [
72
+ `${command} was not found on PATH`
73
+ ]
74
+ };
75
+ }
76
+ export async function directoryCheck(configDir, runtime) {
77
+ const target = join(runtime.homeDir, configDir);
78
+ const readable = await accessible(target, runtime);
79
+ return {
80
+ path: displayHome(target, runtime.homeDir),
81
+ present: readable,
82
+ readable,
83
+ status: readable ? "pass" : "fail",
84
+ errors: readable ? [] : [
85
+ "global configuration directory is unavailable"
86
+ ]
87
+ };
88
+ }
89
+ export async function builtInSkillsCheck(agent, runtime) {
90
+ const relativeRoot = runtime.skillRoots[agent];
91
+ if (!relativeRoot) {
92
+ return {
93
+ path: null,
94
+ required: runtime.builtInSkillNames.length,
95
+ present: 0,
96
+ missing: [
97
+ ...runtime.builtInSkillNames
98
+ ],
99
+ status: "info",
100
+ errors: []
101
+ };
102
+ }
103
+ const root = join(runtime.homeDir, relativeRoot);
104
+ const checks = await Promise.all(runtime.builtInSkillNames.map(async (name)=>({
105
+ name,
106
+ present: await accessible(join(root, name, "SKILL.md"), runtime)
107
+ })));
108
+ const present = checks.filter((check)=>check.present).map((check)=>check.name);
109
+ const missing = runtime.builtInSkillNames.filter((name)=>!present.includes(name));
110
+ return {
111
+ path: displayHome(root, runtime.homeDir),
112
+ required: runtime.builtInSkillNames.length,
113
+ present: present.length,
114
+ missing: [
115
+ ...missing
116
+ ],
117
+ status: "info",
118
+ errors: []
119
+ };
120
+ }
121
+ export async function scriptCheck(installed, bundled, runtime) {
122
+ let installedText;
123
+ try {
124
+ installedText = await runtime.readFile(installed);
125
+ } catch {
126
+ return {
127
+ path: displayHome(installed, runtime.homeDir),
128
+ present: false,
129
+ readable: false,
130
+ matchesBundledAsset: false,
131
+ status: "fail",
132
+ errors: [
133
+ "hook script is unavailable"
134
+ ]
135
+ };
136
+ }
137
+ try {
138
+ const bundledText = await runtime.readFile(bundled);
139
+ const matches = installedText === bundledText;
140
+ return {
141
+ path: displayHome(installed, runtime.homeDir),
142
+ present: true,
143
+ readable: true,
144
+ matchesBundledAsset: matches,
145
+ status: matches ? "pass" : "fail",
146
+ errors: matches ? [] : [
147
+ "hook script differs from the bundled AI DevKit asset"
148
+ ]
149
+ };
150
+ } catch {
151
+ return {
152
+ path: displayHome(installed, runtime.homeDir),
153
+ present: true,
154
+ readable: true,
155
+ matchesBundledAsset: false,
156
+ status: "fail",
157
+ errors: [
158
+ "bundled hook asset is unavailable"
159
+ ]
160
+ };
161
+ }
162
+ }
163
+ function containsHook(root, event, command) {
164
+ const hooks = record(record(root)?.hooks);
165
+ const entries = hooks?.[event];
166
+ if (!Array.isArray(entries)) return false;
167
+ return entries.some((entry)=>{
168
+ const commands = record(entry)?.hooks;
169
+ return Array.isArray(commands) && commands.some((hook)=>{
170
+ const item = record(hook);
171
+ return item?.type === "command" && item.command === command;
172
+ });
173
+ });
174
+ }
175
+ export async function registrationCheck(target, event, command, runtime) {
176
+ try {
177
+ const parsed = JSON.parse(await runtime.readFile(target));
178
+ const valid = containsHook(parsed, event, command);
179
+ return {
180
+ path: displayHome(target, runtime.homeDir),
181
+ event,
182
+ command,
183
+ present: true,
184
+ valid,
185
+ status: valid ? "pass" : "fail",
186
+ errors: valid ? [] : [
187
+ "required hook registration is missing"
188
+ ]
189
+ };
190
+ } catch {
191
+ return {
192
+ path: displayHome(target, runtime.homeDir),
193
+ event,
194
+ command,
195
+ present: false,
196
+ valid: false,
197
+ status: "fail",
198
+ errors: [
199
+ "hook configuration is missing or invalid"
200
+ ]
201
+ };
202
+ }
203
+ }
204
+ export async function mappingCheck(target, runtime) {
205
+ let text;
206
+ try {
207
+ text = await runtime.readFile(target);
208
+ } catch {
209
+ return {
210
+ path: displayHome(target, runtime.homeDir),
211
+ present: false,
212
+ valid: false,
213
+ invalidEntries: 0,
214
+ staleEntries: 0,
215
+ status: "warn",
216
+ errors: [
217
+ "session mapping has not been created"
218
+ ]
219
+ };
220
+ }
221
+ let parsed = null;
222
+ try {
223
+ parsed = record(JSON.parse(text));
224
+ } catch {
225
+ // Fixed safe error below.
226
+ }
227
+ if (!parsed) {
228
+ return {
229
+ path: displayHome(target, runtime.homeDir),
230
+ present: true,
231
+ valid: false,
232
+ invalidEntries: 0,
233
+ staleEntries: 0,
234
+ status: "fail",
235
+ errors: [
236
+ "session mapping is invalid"
237
+ ]
238
+ };
239
+ }
240
+ const entries = await Promise.all(Object.entries(parsed).map(async ([pid, sessionPath])=>{
241
+ if (!/^\d+$/.test(pid) || typeof sessionPath !== "string" || !sessionPath) {
242
+ return {
243
+ valid: false,
244
+ stale: false
245
+ };
246
+ }
247
+ return {
248
+ valid: true,
249
+ stale: !await accessible(sessionPath, runtime)
250
+ };
251
+ }));
252
+ const invalidEntries = entries.filter((entry)=>!entry.valid).length;
253
+ const staleEntries = entries.filter((entry)=>entry.stale).length;
254
+ const valid = invalidEntries === 0;
255
+ return {
256
+ path: displayHome(target, runtime.homeDir),
257
+ present: true,
258
+ valid,
259
+ invalidEntries,
260
+ staleEntries,
261
+ status: !valid ? "fail" : staleEntries ? "warn" : "pass",
262
+ errors: !valid ? [
263
+ "session mapping contains invalid entries"
264
+ ] : staleEntries ? [
265
+ "session mapping contains stale entries"
266
+ ] : []
267
+ };
268
+ }
269
+
270
+ //# sourceMappingURL=checks.js.map