@herdctl/core 0.0.1 → 0.1.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 (284) hide show
  1. package/dist/config/__tests__/agent.test.js +61 -13
  2. package/dist/config/__tests__/agent.test.js.map +1 -1
  3. package/dist/config/__tests__/merge.test.js +10 -3
  4. package/dist/config/__tests__/merge.test.js.map +1 -1
  5. package/dist/config/__tests__/schema.test.js +350 -1
  6. package/dist/config/__tests__/schema.test.js.map +1 -1
  7. package/dist/config/index.d.ts +1 -1
  8. package/dist/config/index.d.ts.map +1 -1
  9. package/dist/config/index.js +3 -1
  10. package/dist/config/index.js.map +1 -1
  11. package/dist/config/schema.d.ts +841 -27
  12. package/dist/config/schema.d.ts.map +1 -1
  13. package/dist/config/schema.js +129 -10
  14. package/dist/config/schema.js.map +1 -1
  15. package/dist/fleet-manager/__tests__/coverage.test.js +14 -331
  16. package/dist/fleet-manager/__tests__/coverage.test.js.map +1 -1
  17. package/dist/fleet-manager/__tests__/errors.test.js +1 -49
  18. package/dist/fleet-manager/__tests__/errors.test.js.map +1 -1
  19. package/dist/fleet-manager/__tests__/integration.test.js +114 -0
  20. package/dist/fleet-manager/__tests__/integration.test.js.map +1 -1
  21. package/dist/fleet-manager/__tests__/job-control.test.js +13 -14
  22. package/dist/fleet-manager/__tests__/job-control.test.js.map +1 -1
  23. package/dist/fleet-manager/__tests__/reload.test.js +12 -2
  24. package/dist/fleet-manager/__tests__/reload.test.js.map +1 -1
  25. package/dist/fleet-manager/__tests__/status-queries.test.js +6 -0
  26. package/dist/fleet-manager/__tests__/status-queries.test.js.map +1 -1
  27. package/dist/fleet-manager/__tests__/trigger.test.js +10 -2
  28. package/dist/fleet-manager/__tests__/trigger.test.js.map +1 -1
  29. package/dist/fleet-manager/config-reload.d.ts +164 -0
  30. package/dist/fleet-manager/config-reload.d.ts.map +1 -0
  31. package/dist/fleet-manager/config-reload.js +445 -0
  32. package/dist/fleet-manager/config-reload.js.map +1 -0
  33. package/dist/fleet-manager/context.d.ts +76 -0
  34. package/dist/fleet-manager/context.d.ts.map +1 -0
  35. package/dist/fleet-manager/context.js +11 -0
  36. package/dist/fleet-manager/context.js.map +1 -0
  37. package/dist/fleet-manager/errors.d.ts +0 -25
  38. package/dist/fleet-manager/errors.d.ts.map +1 -1
  39. package/dist/fleet-manager/errors.js +0 -38
  40. package/dist/fleet-manager/errors.js.map +1 -1
  41. package/dist/fleet-manager/event-emitters.d.ts +123 -0
  42. package/dist/fleet-manager/event-emitters.d.ts.map +1 -0
  43. package/dist/fleet-manager/event-emitters.js +136 -0
  44. package/dist/fleet-manager/event-emitters.js.map +1 -0
  45. package/dist/fleet-manager/event-types.d.ts +0 -15
  46. package/dist/fleet-manager/event-types.d.ts.map +1 -1
  47. package/dist/fleet-manager/fleet-manager.d.ts +40 -653
  48. package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
  49. package/dist/fleet-manager/fleet-manager.js +95 -1720
  50. package/dist/fleet-manager/fleet-manager.js.map +1 -1
  51. package/dist/fleet-manager/index.d.ts +13 -2
  52. package/dist/fleet-manager/index.d.ts.map +1 -1
  53. package/dist/fleet-manager/index.js +19 -6
  54. package/dist/fleet-manager/index.js.map +1 -1
  55. package/dist/fleet-manager/job-control.d.ts +67 -0
  56. package/dist/fleet-manager/job-control.d.ts.map +1 -0
  57. package/dist/fleet-manager/job-control.js +333 -0
  58. package/dist/fleet-manager/job-control.js.map +1 -0
  59. package/dist/fleet-manager/log-streaming.d.ts +171 -0
  60. package/dist/fleet-manager/log-streaming.d.ts.map +1 -0
  61. package/dist/fleet-manager/log-streaming.js +503 -0
  62. package/dist/fleet-manager/log-streaming.js.map +1 -0
  63. package/dist/fleet-manager/schedule-executor.d.ts +63 -0
  64. package/dist/fleet-manager/schedule-executor.d.ts.map +1 -0
  65. package/dist/fleet-manager/schedule-executor.js +209 -0
  66. package/dist/fleet-manager/schedule-executor.js.map +1 -0
  67. package/dist/fleet-manager/schedule-management.d.ts +71 -0
  68. package/dist/fleet-manager/schedule-management.d.ts.map +1 -0
  69. package/dist/fleet-manager/schedule-management.js +171 -0
  70. package/dist/fleet-manager/schedule-management.js.map +1 -0
  71. package/dist/fleet-manager/status-queries.d.ts +105 -0
  72. package/dist/fleet-manager/status-queries.d.ts.map +1 -0
  73. package/dist/fleet-manager/status-queries.js +247 -0
  74. package/dist/fleet-manager/status-queries.js.map +1 -0
  75. package/dist/fleet-manager/types.d.ts +0 -39
  76. package/dist/fleet-manager/types.d.ts.map +1 -1
  77. package/dist/runner/__tests__/job-executor.test.js +206 -1
  78. package/dist/runner/__tests__/job-executor.test.js.map +1 -1
  79. package/dist/runner/job-executor.d.ts +9 -0
  80. package/dist/runner/job-executor.d.ts.map +1 -1
  81. package/dist/runner/job-executor.js +78 -4
  82. package/dist/runner/job-executor.js.map +1 -1
  83. package/dist/runner/message-processor.d.ts.map +1 -1
  84. package/dist/runner/message-processor.js +53 -0
  85. package/dist/runner/message-processor.js.map +1 -1
  86. package/dist/runner/types.d.ts +3 -1
  87. package/dist/runner/types.d.ts.map +1 -1
  88. package/dist/scheduler/__tests__/cron.test.d.ts +2 -0
  89. package/dist/scheduler/__tests__/cron.test.d.ts.map +1 -0
  90. package/dist/scheduler/__tests__/cron.test.js +867 -0
  91. package/dist/scheduler/__tests__/cron.test.js.map +1 -0
  92. package/dist/scheduler/__tests__/scheduler.test.js +164 -5
  93. package/dist/scheduler/__tests__/scheduler.test.js.map +1 -1
  94. package/dist/scheduler/cron.d.ts +126 -0
  95. package/dist/scheduler/cron.d.ts.map +1 -0
  96. package/dist/scheduler/cron.js +390 -0
  97. package/dist/scheduler/cron.js.map +1 -0
  98. package/dist/scheduler/errors.d.ts +81 -1
  99. package/dist/scheduler/errors.d.ts.map +1 -1
  100. package/dist/scheduler/errors.js +81 -6
  101. package/dist/scheduler/errors.js.map +1 -1
  102. package/dist/scheduler/index.d.ts +1 -0
  103. package/dist/scheduler/index.d.ts.map +1 -1
  104. package/dist/scheduler/index.js +2 -0
  105. package/dist/scheduler/index.js.map +1 -1
  106. package/dist/scheduler/schedule-runner.d.ts +2 -2
  107. package/dist/scheduler/schedule-runner.d.ts.map +1 -1
  108. package/dist/scheduler/schedule-runner.js +20 -8
  109. package/dist/scheduler/schedule-runner.js.map +1 -1
  110. package/dist/scheduler/scheduler.d.ts +4 -4
  111. package/dist/scheduler/scheduler.d.ts.map +1 -1
  112. package/dist/scheduler/scheduler.js +95 -20
  113. package/dist/scheduler/scheduler.js.map +1 -1
  114. package/dist/scheduler/types.d.ts +1 -1
  115. package/dist/scheduler/types.d.ts.map +1 -1
  116. package/dist/state/schemas/job-metadata.d.ts +2 -2
  117. package/package.json +33 -8
  118. package/.turbo/turbo-build.log +0 -4
  119. package/.turbo/turbo-test.log +0 -219
  120. package/.turbo/turbo-typecheck.log +0 -4
  121. package/coverage/base.css +0 -224
  122. package/coverage/block-navigation.js +0 -87
  123. package/coverage/coverage-final.json +0 -51
  124. package/coverage/favicon.png +0 -0
  125. package/coverage/index.html +0 -251
  126. package/coverage/prettify.css +0 -1
  127. package/coverage/prettify.js +0 -2
  128. package/coverage/sort-arrow-sprite.png +0 -0
  129. package/coverage/sorter.js +0 -210
  130. package/coverage/src/config/index.html +0 -191
  131. package/coverage/src/config/index.ts.html +0 -442
  132. package/coverage/src/config/interpolate.ts.html +0 -652
  133. package/coverage/src/config/loader.ts.html +0 -1501
  134. package/coverage/src/config/merge.ts.html +0 -823
  135. package/coverage/src/config/parser.ts.html +0 -1213
  136. package/coverage/src/config/schema.ts.html +0 -1123
  137. package/coverage/src/fleet-manager/errors.ts.html +0 -2326
  138. package/coverage/src/fleet-manager/event-types.ts.html +0 -1219
  139. package/coverage/src/fleet-manager/fleet-manager.ts.html +0 -7030
  140. package/coverage/src/fleet-manager/index.html +0 -206
  141. package/coverage/src/fleet-manager/index.ts.html +0 -469
  142. package/coverage/src/fleet-manager/job-manager.ts.html +0 -2074
  143. package/coverage/src/fleet-manager/job-queue.ts.html +0 -2479
  144. package/coverage/src/fleet-manager/types.ts.html +0 -2602
  145. package/coverage/src/index.html +0 -116
  146. package/coverage/src/index.ts.html +0 -181
  147. package/coverage/src/runner/errors.ts.html +0 -1006
  148. package/coverage/src/runner/index.html +0 -191
  149. package/coverage/src/runner/index.ts.html +0 -256
  150. package/coverage/src/runner/job-executor.ts.html +0 -1429
  151. package/coverage/src/runner/message-processor.ts.html +0 -1150
  152. package/coverage/src/runner/sdk-adapter.ts.html +0 -658
  153. package/coverage/src/runner/types.ts.html +0 -559
  154. package/coverage/src/scheduler/errors.ts.html +0 -388
  155. package/coverage/src/scheduler/index.html +0 -206
  156. package/coverage/src/scheduler/index.ts.html +0 -244
  157. package/coverage/src/scheduler/interval.ts.html +0 -652
  158. package/coverage/src/scheduler/schedule-runner.ts.html +0 -1411
  159. package/coverage/src/scheduler/schedule-state.ts.html +0 -718
  160. package/coverage/src/scheduler/scheduler.ts.html +0 -1795
  161. package/coverage/src/scheduler/types.ts.html +0 -733
  162. package/coverage/src/state/directory.ts.html +0 -736
  163. package/coverage/src/state/errors.ts.html +0 -376
  164. package/coverage/src/state/fleet-state.ts.html +0 -937
  165. package/coverage/src/state/index.html +0 -221
  166. package/coverage/src/state/index.ts.html +0 -322
  167. package/coverage/src/state/job-metadata.ts.html +0 -1420
  168. package/coverage/src/state/job-output.ts.html +0 -1033
  169. package/coverage/src/state/schemas/fleet-state.ts.html +0 -445
  170. package/coverage/src/state/schemas/index.html +0 -176
  171. package/coverage/src/state/schemas/index.ts.html +0 -286
  172. package/coverage/src/state/schemas/job-metadata.ts.html +0 -628
  173. package/coverage/src/state/schemas/job-output.ts.html +0 -616
  174. package/coverage/src/state/schemas/session-info.ts.html +0 -361
  175. package/coverage/src/state/session.ts.html +0 -844
  176. package/coverage/src/state/types.ts.html +0 -262
  177. package/coverage/src/state/utils/atomic.ts.html +0 -748
  178. package/coverage/src/state/utils/index.html +0 -146
  179. package/coverage/src/state/utils/index.ts.html +0 -103
  180. package/coverage/src/state/utils/reads.ts.html +0 -1621
  181. package/coverage/src/work-sources/adapters/github.ts.html +0 -3583
  182. package/coverage/src/work-sources/adapters/index.html +0 -131
  183. package/coverage/src/work-sources/adapters/index.ts.html +0 -277
  184. package/coverage/src/work-sources/errors.ts.html +0 -298
  185. package/coverage/src/work-sources/index.html +0 -176
  186. package/coverage/src/work-sources/index.ts.html +0 -529
  187. package/coverage/src/work-sources/manager.ts.html +0 -1324
  188. package/coverage/src/work-sources/registry.ts.html +0 -619
  189. package/coverage/src/work-sources/types.ts.html +0 -568
  190. package/dist/fleet-manager/__tests__/event-helpers.test.d.ts +0 -7
  191. package/dist/fleet-manager/__tests__/event-helpers.test.d.ts.map +0 -1
  192. package/dist/fleet-manager/__tests__/event-helpers.test.js +0 -368
  193. package/dist/fleet-manager/__tests__/event-helpers.test.js.map +0 -1
  194. package/src/config/__tests__/agent.test.ts +0 -864
  195. package/src/config/__tests__/interpolate.test.ts +0 -644
  196. package/src/config/__tests__/loader.test.ts +0 -784
  197. package/src/config/__tests__/merge.test.ts +0 -751
  198. package/src/config/__tests__/parser.test.ts +0 -533
  199. package/src/config/__tests__/schema.test.ts +0 -873
  200. package/src/config/index.ts +0 -119
  201. package/src/config/interpolate.ts +0 -189
  202. package/src/config/loader.ts +0 -472
  203. package/src/config/merge.ts +0 -246
  204. package/src/config/parser.ts +0 -376
  205. package/src/config/schema.ts +0 -346
  206. package/src/fleet-manager/__tests__/coverage.test.ts +0 -2869
  207. package/src/fleet-manager/__tests__/errors.test.ts +0 -660
  208. package/src/fleet-manager/__tests__/event-helpers.test.ts +0 -448
  209. package/src/fleet-manager/__tests__/integration.test.ts +0 -1209
  210. package/src/fleet-manager/__tests__/job-control.test.ts +0 -283
  211. package/src/fleet-manager/__tests__/job-manager.test.ts +0 -869
  212. package/src/fleet-manager/__tests__/job-queue.test.ts +0 -401
  213. package/src/fleet-manager/__tests__/reload.test.ts +0 -751
  214. package/src/fleet-manager/__tests__/status-queries.test.ts +0 -595
  215. package/src/fleet-manager/__tests__/trigger.test.ts +0 -601
  216. package/src/fleet-manager/errors.ts +0 -747
  217. package/src/fleet-manager/event-types.ts +0 -378
  218. package/src/fleet-manager/fleet-manager.ts +0 -2315
  219. package/src/fleet-manager/index.ts +0 -128
  220. package/src/fleet-manager/job-manager.ts +0 -663
  221. package/src/fleet-manager/job-queue.ts +0 -798
  222. package/src/fleet-manager/types.ts +0 -839
  223. package/src/index.ts +0 -32
  224. package/src/runner/__tests__/errors.test.ts +0 -382
  225. package/src/runner/__tests__/job-executor.test.ts +0 -1708
  226. package/src/runner/__tests__/message-processor.test.ts +0 -960
  227. package/src/runner/__tests__/sdk-adapter.test.ts +0 -626
  228. package/src/runner/errors.ts +0 -307
  229. package/src/runner/index.ts +0 -57
  230. package/src/runner/job-executor.ts +0 -448
  231. package/src/runner/message-processor.ts +0 -355
  232. package/src/runner/sdk-adapter.ts +0 -191
  233. package/src/runner/types.ts +0 -158
  234. package/src/scheduler/__tests__/errors.test.ts +0 -159
  235. package/src/scheduler/__tests__/interval.test.ts +0 -515
  236. package/src/scheduler/__tests__/schedule-runner.test.ts +0 -798
  237. package/src/scheduler/__tests__/schedule-state.test.ts +0 -671
  238. package/src/scheduler/__tests__/scheduler.test.ts +0 -1280
  239. package/src/scheduler/errors.ts +0 -101
  240. package/src/scheduler/index.ts +0 -53
  241. package/src/scheduler/interval.ts +0 -189
  242. package/src/scheduler/schedule-runner.ts +0 -442
  243. package/src/scheduler/schedule-state.ts +0 -211
  244. package/src/scheduler/scheduler.ts +0 -570
  245. package/src/scheduler/types.ts +0 -216
  246. package/src/state/__tests__/directory.test.ts +0 -595
  247. package/src/state/__tests__/fleet-state.test.ts +0 -868
  248. package/src/state/__tests__/job-metadata-schema.test.ts +0 -414
  249. package/src/state/__tests__/job-metadata.test.ts +0 -831
  250. package/src/state/__tests__/job-output.test.ts +0 -856
  251. package/src/state/__tests__/session-schema.test.ts +0 -378
  252. package/src/state/__tests__/session.test.ts +0 -604
  253. package/src/state/directory.ts +0 -217
  254. package/src/state/errors.ts +0 -97
  255. package/src/state/fleet-state.ts +0 -284
  256. package/src/state/index.ts +0 -79
  257. package/src/state/job-metadata.ts +0 -445
  258. package/src/state/job-output.ts +0 -316
  259. package/src/state/schemas/__tests__/job-output.test.ts +0 -338
  260. package/src/state/schemas/fleet-state.ts +0 -120
  261. package/src/state/schemas/index.ts +0 -67
  262. package/src/state/schemas/job-metadata.ts +0 -181
  263. package/src/state/schemas/job-output.ts +0 -177
  264. package/src/state/schemas/session-info.ts +0 -92
  265. package/src/state/session.ts +0 -253
  266. package/src/state/types.ts +0 -59
  267. package/src/state/utils/__tests__/atomic.test.ts +0 -723
  268. package/src/state/utils/__tests__/reads.test.ts +0 -1071
  269. package/src/state/utils/atomic.ts +0 -221
  270. package/src/state/utils/index.ts +0 -6
  271. package/src/state/utils/reads.ts +0 -512
  272. package/src/work-sources/__tests__/github.test.ts +0 -1800
  273. package/src/work-sources/__tests__/manager.test.ts +0 -529
  274. package/src/work-sources/__tests__/registry.test.ts +0 -477
  275. package/src/work-sources/__tests__/types.test.ts +0 -479
  276. package/src/work-sources/adapters/github.ts +0 -1166
  277. package/src/work-sources/adapters/index.ts +0 -64
  278. package/src/work-sources/errors.ts +0 -71
  279. package/src/work-sources/index.ts +0 -148
  280. package/src/work-sources/manager.ts +0 -413
  281. package/src/work-sources/registry.ts +0 -178
  282. package/src/work-sources/types.ts +0 -161
  283. package/tsconfig.json +0 -9
  284. package/vitest.config.ts +0 -19
@@ -1,376 +0,0 @@
1
- /**
2
- * YAML configuration parser for herdctl
3
- *
4
- * Parses herdctl.yaml files and validates them against the FleetConfig schema
5
- */
6
-
7
- import { parse as parseYaml, YAMLParseError } from "yaml";
8
- import { ZodError } from "zod";
9
- import {
10
- FleetConfigSchema,
11
- AgentConfigSchema,
12
- type FleetConfig,
13
- type AgentConfig,
14
- } from "./schema.js";
15
- import { readFile } from "node:fs/promises";
16
- import { resolve, dirname } from "node:path";
17
-
18
- // =============================================================================
19
- // Error Classes
20
- // =============================================================================
21
-
22
- /**
23
- * Base error class for configuration errors
24
- */
25
- export class ConfigError extends Error {
26
- constructor(message: string) {
27
- super(message);
28
- this.name = "ConfigError";
29
- }
30
- }
31
-
32
- /**
33
- * Error thrown when YAML syntax is invalid
34
- */
35
- export class YamlSyntaxError extends ConfigError {
36
- public readonly line?: number;
37
- public readonly column?: number;
38
- public readonly originalError: YAMLParseError;
39
-
40
- constructor(error: YAMLParseError) {
41
- const position = error.linePos?.[0];
42
- const locationInfo = position
43
- ? ` at line ${position.line}, column ${position.col}`
44
- : "";
45
-
46
- super(`Invalid YAML syntax${locationInfo}: ${error.message}`);
47
- this.name = "YamlSyntaxError";
48
- this.line = position?.line;
49
- this.column = position?.col;
50
- this.originalError = error;
51
- }
52
- }
53
-
54
- /**
55
- * Error thrown when schema validation fails
56
- */
57
- export class SchemaValidationError extends ConfigError {
58
- public readonly issues: SchemaIssue[];
59
-
60
- constructor(error: ZodError) {
61
- const issues = error.issues.map((issue) => ({
62
- path: issue.path.join(".") || "(root)",
63
- message: issue.message,
64
- code: issue.code,
65
- }));
66
-
67
- const issueMessages = issues
68
- .map((i) => ` - ${i.path}: ${i.message}`)
69
- .join("\n");
70
-
71
- super(`Configuration validation failed:\n${issueMessages}`);
72
- this.name = "SchemaValidationError";
73
- this.issues = issues;
74
- }
75
- }
76
-
77
- export interface SchemaIssue {
78
- path: string;
79
- message: string;
80
- code: string;
81
- }
82
-
83
- /**
84
- * Error thrown when a file cannot be read
85
- */
86
- export class FileReadError extends ConfigError {
87
- public readonly filePath: string;
88
-
89
- constructor(filePath: string, cause?: Error) {
90
- const message = cause
91
- ? `Failed to read file '${filePath}': ${cause.message}`
92
- : `Failed to read file '${filePath}'`;
93
- super(message);
94
- this.name = "FileReadError";
95
- this.filePath = filePath;
96
- this.cause = cause;
97
- }
98
- }
99
-
100
- /**
101
- * Error thrown when agent configuration validation fails
102
- */
103
- export class AgentValidationError extends ConfigError {
104
- public readonly issues: SchemaIssue[];
105
- public readonly filePath: string;
106
-
107
- constructor(error: ZodError, filePath: string) {
108
- const issues = error.issues.map((issue) => ({
109
- path: issue.path.join(".") || "(root)",
110
- message: issue.message,
111
- code: issue.code,
112
- }));
113
-
114
- const issueMessages = issues
115
- .map((i) => ` - ${i.path}: ${i.message}`)
116
- .join("\n");
117
-
118
- super(`Agent configuration validation failed in '${filePath}':\n${issueMessages}`);
119
- this.name = "AgentValidationError";
120
- this.issues = issues;
121
- this.filePath = filePath;
122
- }
123
- }
124
-
125
- /**
126
- * Error thrown when agent YAML syntax is invalid
127
- */
128
- export class AgentYamlSyntaxError extends ConfigError {
129
- public readonly line?: number;
130
- public readonly column?: number;
131
- public readonly filePath: string;
132
- public readonly originalError: YAMLParseError;
133
-
134
- constructor(error: YAMLParseError, filePath: string) {
135
- const position = error.linePos?.[0];
136
- const locationInfo = position
137
- ? ` at line ${position.line}, column ${position.col}`
138
- : "";
139
-
140
- super(`Invalid YAML syntax in '${filePath}'${locationInfo}: ${error.message}`);
141
- this.name = "AgentYamlSyntaxError";
142
- this.line = position?.line;
143
- this.column = position?.col;
144
- this.filePath = filePath;
145
- this.originalError = error;
146
- }
147
- }
148
-
149
- // =============================================================================
150
- // Parser Functions
151
- // =============================================================================
152
-
153
- /**
154
- * Parse a YAML string into a FleetConfig object
155
- *
156
- * @param yamlContent - The raw YAML string to parse
157
- * @returns A validated FleetConfig object
158
- * @throws {YamlSyntaxError} If the YAML syntax is invalid
159
- * @throws {SchemaValidationError} If the configuration fails schema validation
160
- */
161
- export function parseFleetConfig(yamlContent: string): FleetConfig {
162
- // Parse YAML
163
- let rawConfig: unknown;
164
- try {
165
- rawConfig = parseYaml(yamlContent);
166
- } catch (error) {
167
- if (error instanceof YAMLParseError) {
168
- throw new YamlSyntaxError(error);
169
- }
170
- throw error;
171
- }
172
-
173
- // Handle empty files
174
- if (rawConfig === null || rawConfig === undefined) {
175
- rawConfig = {};
176
- }
177
-
178
- // Validate against schema
179
- try {
180
- return FleetConfigSchema.parse(rawConfig);
181
- } catch (error) {
182
- if (error instanceof ZodError) {
183
- throw new SchemaValidationError(error);
184
- }
185
- throw error;
186
- }
187
- }
188
-
189
- /**
190
- * Validate a configuration object without parsing YAML
191
- *
192
- * @param config - The configuration object to validate
193
- * @returns A validated FleetConfig object
194
- * @throws {SchemaValidationError} If the configuration fails schema validation
195
- */
196
- export function validateFleetConfig(config: unknown): FleetConfig {
197
- try {
198
- return FleetConfigSchema.parse(config);
199
- } catch (error) {
200
- if (error instanceof ZodError) {
201
- throw new SchemaValidationError(error);
202
- }
203
- throw error;
204
- }
205
- }
206
-
207
- /**
208
- * Check if a configuration is valid without throwing
209
- *
210
- * @param yamlContent - The raw YAML string to check
211
- * @returns An object with success status and either the config or error
212
- */
213
- export function safeParseFleetConfig(yamlContent: string):
214
- | { success: true; data: FleetConfig }
215
- | { success: false; error: ConfigError } {
216
- try {
217
- const config = parseFleetConfig(yamlContent);
218
- return { success: true, data: config };
219
- } catch (error) {
220
- if (error instanceof ConfigError) {
221
- return { success: false, error };
222
- }
223
- return {
224
- success: false,
225
- error: new ConfigError(
226
- error instanceof Error ? error.message : String(error)
227
- ),
228
- };
229
- }
230
- }
231
-
232
- // =============================================================================
233
- // Agent Config Parser Functions
234
- // =============================================================================
235
-
236
- /**
237
- * Parse a YAML string into an AgentConfig object
238
- *
239
- * @param yamlContent - The raw YAML string to parse
240
- * @param filePath - The file path for error context (optional)
241
- * @returns A validated AgentConfig object
242
- * @throws {AgentYamlSyntaxError} If the YAML syntax is invalid
243
- * @throws {AgentValidationError} If the configuration fails schema validation
244
- */
245
- export function parseAgentConfig(
246
- yamlContent: string,
247
- filePath: string = "<unknown>"
248
- ): AgentConfig {
249
- // Parse YAML
250
- let rawConfig: unknown;
251
- try {
252
- rawConfig = parseYaml(yamlContent);
253
- } catch (error) {
254
- if (error instanceof YAMLParseError) {
255
- throw new AgentYamlSyntaxError(error, filePath);
256
- }
257
- throw error;
258
- }
259
-
260
- // Handle empty files - let Zod handle validation since 'name' is required
261
- if (rawConfig === null || rawConfig === undefined) {
262
- rawConfig = {};
263
- }
264
-
265
- // Validate against schema
266
- try {
267
- return AgentConfigSchema.parse(rawConfig);
268
- } catch (error) {
269
- if (error instanceof ZodError) {
270
- throw new AgentValidationError(error, filePath);
271
- }
272
- throw error;
273
- }
274
- }
275
-
276
- /**
277
- * Validate an agent configuration object without parsing YAML
278
- *
279
- * @param config - The configuration object to validate
280
- * @param filePath - The file path for error context (optional)
281
- * @returns A validated AgentConfig object
282
- * @throws {AgentValidationError} If the configuration fails schema validation
283
- */
284
- export function validateAgentConfig(
285
- config: unknown,
286
- filePath: string = "<unknown>"
287
- ): AgentConfig {
288
- try {
289
- return AgentConfigSchema.parse(config);
290
- } catch (error) {
291
- if (error instanceof ZodError) {
292
- throw new AgentValidationError(error, filePath);
293
- }
294
- throw error;
295
- }
296
- }
297
-
298
- /**
299
- * Check if an agent configuration is valid without throwing
300
- *
301
- * @param yamlContent - The raw YAML string to check
302
- * @param filePath - The file path for error context (optional)
303
- * @returns An object with success status and either the config or error
304
- */
305
- export function safeParseAgentConfig(
306
- yamlContent: string,
307
- filePath: string = "<unknown>"
308
- ):
309
- | { success: true; data: AgentConfig }
310
- | { success: false; error: ConfigError } {
311
- try {
312
- const config = parseAgentConfig(yamlContent, filePath);
313
- return { success: true, data: config };
314
- } catch (error) {
315
- if (error instanceof ConfigError) {
316
- return { success: false, error };
317
- }
318
- return {
319
- success: false,
320
- error: new ConfigError(
321
- error instanceof Error ? error.message : String(error)
322
- ),
323
- };
324
- }
325
- }
326
-
327
- /**
328
- * Resolve an agent file path relative to a base path (typically fleet config location)
329
- *
330
- * @param agentPath - The agent path from fleet config (can be relative or absolute)
331
- * @param basePath - The base path to resolve from (typically the fleet config directory)
332
- * @returns The resolved absolute path
333
- */
334
- export function resolveAgentPath(agentPath: string, basePath: string): string {
335
- // If the agent path is already absolute, return it as-is
336
- if (agentPath.startsWith("/")) {
337
- return agentPath;
338
- }
339
-
340
- // Resolve relative path from the base path
341
- return resolve(basePath, agentPath);
342
- }
343
-
344
- /**
345
- * Load and parse an agent configuration file
346
- *
347
- * @param agentPath - Path to the agent YAML file
348
- * @param fleetConfigPath - Path to the fleet config file (for resolving relative paths)
349
- * @returns A validated AgentConfig object
350
- * @throws {FileReadError} If the file cannot be read
351
- * @throws {AgentYamlSyntaxError} If the YAML syntax is invalid
352
- * @throws {AgentValidationError} If the configuration fails schema validation
353
- */
354
- export async function loadAgentConfig(
355
- agentPath: string,
356
- fleetConfigPath?: string
357
- ): Promise<AgentConfig> {
358
- // Resolve the path if a fleet config path is provided
359
- const resolvedPath = fleetConfigPath
360
- ? resolveAgentPath(agentPath, dirname(fleetConfigPath))
361
- : agentPath;
362
-
363
- // Read the file
364
- let content: string;
365
- try {
366
- content = await readFile(resolvedPath, "utf-8");
367
- } catch (error) {
368
- throw new FileReadError(
369
- resolvedPath,
370
- error instanceof Error ? error : undefined
371
- );
372
- }
373
-
374
- // Parse and validate
375
- return parseAgentConfig(content, resolvedPath);
376
- }