@herdctl/core 0.0.1 → 0.0.2

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 (275) hide show
  1. package/dist/config/__tests__/agent.test.js +31 -13
  2. package/dist/config/__tests__/agent.test.js.map +1 -1
  3. package/dist/config/__tests__/merge.test.js +9 -2
  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 +828 -24
  12. package/dist/config/schema.d.ts.map +1 -1
  13. package/dist/config/schema.js +118 -6
  14. package/dist/config/schema.js.map +1 -1
  15. package/dist/fleet-manager/__tests__/coverage.test.js +11 -332
  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 +109 -0
  20. package/dist/fleet-manager/__tests__/integration.test.js.map +1 -1
  21. package/dist/fleet-manager/__tests__/reload.test.js +1 -1
  22. package/dist/fleet-manager/__tests__/reload.test.js.map +1 -1
  23. package/dist/fleet-manager/config-reload.d.ts +164 -0
  24. package/dist/fleet-manager/config-reload.d.ts.map +1 -0
  25. package/dist/fleet-manager/config-reload.js +445 -0
  26. package/dist/fleet-manager/config-reload.js.map +1 -0
  27. package/dist/fleet-manager/context.d.ts +76 -0
  28. package/dist/fleet-manager/context.d.ts.map +1 -0
  29. package/dist/fleet-manager/context.js +11 -0
  30. package/dist/fleet-manager/context.js.map +1 -0
  31. package/dist/fleet-manager/errors.d.ts +0 -25
  32. package/dist/fleet-manager/errors.d.ts.map +1 -1
  33. package/dist/fleet-manager/errors.js +0 -38
  34. package/dist/fleet-manager/errors.js.map +1 -1
  35. package/dist/fleet-manager/event-emitters.d.ts +123 -0
  36. package/dist/fleet-manager/event-emitters.d.ts.map +1 -0
  37. package/dist/fleet-manager/event-emitters.js +136 -0
  38. package/dist/fleet-manager/event-emitters.js.map +1 -0
  39. package/dist/fleet-manager/event-types.d.ts +0 -15
  40. package/dist/fleet-manager/event-types.d.ts.map +1 -1
  41. package/dist/fleet-manager/fleet-manager.d.ts +40 -653
  42. package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
  43. package/dist/fleet-manager/fleet-manager.js +95 -1720
  44. package/dist/fleet-manager/fleet-manager.js.map +1 -1
  45. package/dist/fleet-manager/index.d.ts +13 -2
  46. package/dist/fleet-manager/index.d.ts.map +1 -1
  47. package/dist/fleet-manager/index.js +19 -6
  48. package/dist/fleet-manager/index.js.map +1 -1
  49. package/dist/fleet-manager/job-control.d.ts +64 -0
  50. package/dist/fleet-manager/job-control.d.ts.map +1 -0
  51. package/dist/fleet-manager/job-control.js +296 -0
  52. package/dist/fleet-manager/job-control.js.map +1 -0
  53. package/dist/fleet-manager/log-streaming.d.ts +171 -0
  54. package/dist/fleet-manager/log-streaming.d.ts.map +1 -0
  55. package/dist/fleet-manager/log-streaming.js +503 -0
  56. package/dist/fleet-manager/log-streaming.js.map +1 -0
  57. package/dist/fleet-manager/schedule-executor.d.ts +63 -0
  58. package/dist/fleet-manager/schedule-executor.d.ts.map +1 -0
  59. package/dist/fleet-manager/schedule-executor.js +209 -0
  60. package/dist/fleet-manager/schedule-executor.js.map +1 -0
  61. package/dist/fleet-manager/schedule-management.d.ts +71 -0
  62. package/dist/fleet-manager/schedule-management.d.ts.map +1 -0
  63. package/dist/fleet-manager/schedule-management.js +171 -0
  64. package/dist/fleet-manager/schedule-management.js.map +1 -0
  65. package/dist/fleet-manager/status-queries.d.ts +105 -0
  66. package/dist/fleet-manager/status-queries.d.ts.map +1 -0
  67. package/dist/fleet-manager/status-queries.js +247 -0
  68. package/dist/fleet-manager/status-queries.js.map +1 -0
  69. package/dist/fleet-manager/types.d.ts +0 -39
  70. package/dist/fleet-manager/types.d.ts.map +1 -1
  71. package/dist/runner/__tests__/job-executor.test.js +206 -1
  72. package/dist/runner/__tests__/job-executor.test.js.map +1 -1
  73. package/dist/runner/job-executor.d.ts +9 -0
  74. package/dist/runner/job-executor.d.ts.map +1 -1
  75. package/dist/runner/job-executor.js +78 -4
  76. package/dist/runner/job-executor.js.map +1 -1
  77. package/dist/runner/types.d.ts +2 -0
  78. package/dist/runner/types.d.ts.map +1 -1
  79. package/dist/scheduler/__tests__/cron.test.d.ts +2 -0
  80. package/dist/scheduler/__tests__/cron.test.d.ts.map +1 -0
  81. package/dist/scheduler/__tests__/cron.test.js +867 -0
  82. package/dist/scheduler/__tests__/cron.test.js.map +1 -0
  83. package/dist/scheduler/__tests__/scheduler.test.js +164 -5
  84. package/dist/scheduler/__tests__/scheduler.test.js.map +1 -1
  85. package/dist/scheduler/cron.d.ts +126 -0
  86. package/dist/scheduler/cron.d.ts.map +1 -0
  87. package/dist/scheduler/cron.js +390 -0
  88. package/dist/scheduler/cron.js.map +1 -0
  89. package/dist/scheduler/errors.d.ts +81 -1
  90. package/dist/scheduler/errors.d.ts.map +1 -1
  91. package/dist/scheduler/errors.js +81 -6
  92. package/dist/scheduler/errors.js.map +1 -1
  93. package/dist/scheduler/index.d.ts +1 -0
  94. package/dist/scheduler/index.d.ts.map +1 -1
  95. package/dist/scheduler/index.js +2 -0
  96. package/dist/scheduler/index.js.map +1 -1
  97. package/dist/scheduler/schedule-runner.d.ts +2 -2
  98. package/dist/scheduler/schedule-runner.d.ts.map +1 -1
  99. package/dist/scheduler/schedule-runner.js +20 -8
  100. package/dist/scheduler/schedule-runner.js.map +1 -1
  101. package/dist/scheduler/scheduler.d.ts +4 -4
  102. package/dist/scheduler/scheduler.d.ts.map +1 -1
  103. package/dist/scheduler/scheduler.js +86 -20
  104. package/dist/scheduler/scheduler.js.map +1 -1
  105. package/dist/scheduler/types.d.ts +1 -1
  106. package/dist/scheduler/types.d.ts.map +1 -1
  107. package/dist/state/schemas/job-metadata.d.ts +2 -2
  108. package/package.json +33 -8
  109. package/.turbo/turbo-build.log +0 -4
  110. package/.turbo/turbo-test.log +0 -219
  111. package/.turbo/turbo-typecheck.log +0 -4
  112. package/coverage/base.css +0 -224
  113. package/coverage/block-navigation.js +0 -87
  114. package/coverage/coverage-final.json +0 -51
  115. package/coverage/favicon.png +0 -0
  116. package/coverage/index.html +0 -251
  117. package/coverage/prettify.css +0 -1
  118. package/coverage/prettify.js +0 -2
  119. package/coverage/sort-arrow-sprite.png +0 -0
  120. package/coverage/sorter.js +0 -210
  121. package/coverage/src/config/index.html +0 -191
  122. package/coverage/src/config/index.ts.html +0 -442
  123. package/coverage/src/config/interpolate.ts.html +0 -652
  124. package/coverage/src/config/loader.ts.html +0 -1501
  125. package/coverage/src/config/merge.ts.html +0 -823
  126. package/coverage/src/config/parser.ts.html +0 -1213
  127. package/coverage/src/config/schema.ts.html +0 -1123
  128. package/coverage/src/fleet-manager/errors.ts.html +0 -2326
  129. package/coverage/src/fleet-manager/event-types.ts.html +0 -1219
  130. package/coverage/src/fleet-manager/fleet-manager.ts.html +0 -7030
  131. package/coverage/src/fleet-manager/index.html +0 -206
  132. package/coverage/src/fleet-manager/index.ts.html +0 -469
  133. package/coverage/src/fleet-manager/job-manager.ts.html +0 -2074
  134. package/coverage/src/fleet-manager/job-queue.ts.html +0 -2479
  135. package/coverage/src/fleet-manager/types.ts.html +0 -2602
  136. package/coverage/src/index.html +0 -116
  137. package/coverage/src/index.ts.html +0 -181
  138. package/coverage/src/runner/errors.ts.html +0 -1006
  139. package/coverage/src/runner/index.html +0 -191
  140. package/coverage/src/runner/index.ts.html +0 -256
  141. package/coverage/src/runner/job-executor.ts.html +0 -1429
  142. package/coverage/src/runner/message-processor.ts.html +0 -1150
  143. package/coverage/src/runner/sdk-adapter.ts.html +0 -658
  144. package/coverage/src/runner/types.ts.html +0 -559
  145. package/coverage/src/scheduler/errors.ts.html +0 -388
  146. package/coverage/src/scheduler/index.html +0 -206
  147. package/coverage/src/scheduler/index.ts.html +0 -244
  148. package/coverage/src/scheduler/interval.ts.html +0 -652
  149. package/coverage/src/scheduler/schedule-runner.ts.html +0 -1411
  150. package/coverage/src/scheduler/schedule-state.ts.html +0 -718
  151. package/coverage/src/scheduler/scheduler.ts.html +0 -1795
  152. package/coverage/src/scheduler/types.ts.html +0 -733
  153. package/coverage/src/state/directory.ts.html +0 -736
  154. package/coverage/src/state/errors.ts.html +0 -376
  155. package/coverage/src/state/fleet-state.ts.html +0 -937
  156. package/coverage/src/state/index.html +0 -221
  157. package/coverage/src/state/index.ts.html +0 -322
  158. package/coverage/src/state/job-metadata.ts.html +0 -1420
  159. package/coverage/src/state/job-output.ts.html +0 -1033
  160. package/coverage/src/state/schemas/fleet-state.ts.html +0 -445
  161. package/coverage/src/state/schemas/index.html +0 -176
  162. package/coverage/src/state/schemas/index.ts.html +0 -286
  163. package/coverage/src/state/schemas/job-metadata.ts.html +0 -628
  164. package/coverage/src/state/schemas/job-output.ts.html +0 -616
  165. package/coverage/src/state/schemas/session-info.ts.html +0 -361
  166. package/coverage/src/state/session.ts.html +0 -844
  167. package/coverage/src/state/types.ts.html +0 -262
  168. package/coverage/src/state/utils/atomic.ts.html +0 -748
  169. package/coverage/src/state/utils/index.html +0 -146
  170. package/coverage/src/state/utils/index.ts.html +0 -103
  171. package/coverage/src/state/utils/reads.ts.html +0 -1621
  172. package/coverage/src/work-sources/adapters/github.ts.html +0 -3583
  173. package/coverage/src/work-sources/adapters/index.html +0 -131
  174. package/coverage/src/work-sources/adapters/index.ts.html +0 -277
  175. package/coverage/src/work-sources/errors.ts.html +0 -298
  176. package/coverage/src/work-sources/index.html +0 -176
  177. package/coverage/src/work-sources/index.ts.html +0 -529
  178. package/coverage/src/work-sources/manager.ts.html +0 -1324
  179. package/coverage/src/work-sources/registry.ts.html +0 -619
  180. package/coverage/src/work-sources/types.ts.html +0 -568
  181. package/dist/fleet-manager/__tests__/event-helpers.test.d.ts +0 -7
  182. package/dist/fleet-manager/__tests__/event-helpers.test.d.ts.map +0 -1
  183. package/dist/fleet-manager/__tests__/event-helpers.test.js +0 -368
  184. package/dist/fleet-manager/__tests__/event-helpers.test.js.map +0 -1
  185. package/src/config/__tests__/agent.test.ts +0 -864
  186. package/src/config/__tests__/interpolate.test.ts +0 -644
  187. package/src/config/__tests__/loader.test.ts +0 -784
  188. package/src/config/__tests__/merge.test.ts +0 -751
  189. package/src/config/__tests__/parser.test.ts +0 -533
  190. package/src/config/__tests__/schema.test.ts +0 -873
  191. package/src/config/index.ts +0 -119
  192. package/src/config/interpolate.ts +0 -189
  193. package/src/config/loader.ts +0 -472
  194. package/src/config/merge.ts +0 -246
  195. package/src/config/parser.ts +0 -376
  196. package/src/config/schema.ts +0 -346
  197. package/src/fleet-manager/__tests__/coverage.test.ts +0 -2869
  198. package/src/fleet-manager/__tests__/errors.test.ts +0 -660
  199. package/src/fleet-manager/__tests__/event-helpers.test.ts +0 -448
  200. package/src/fleet-manager/__tests__/integration.test.ts +0 -1209
  201. package/src/fleet-manager/__tests__/job-control.test.ts +0 -283
  202. package/src/fleet-manager/__tests__/job-manager.test.ts +0 -869
  203. package/src/fleet-manager/__tests__/job-queue.test.ts +0 -401
  204. package/src/fleet-manager/__tests__/reload.test.ts +0 -751
  205. package/src/fleet-manager/__tests__/status-queries.test.ts +0 -595
  206. package/src/fleet-manager/__tests__/trigger.test.ts +0 -601
  207. package/src/fleet-manager/errors.ts +0 -747
  208. package/src/fleet-manager/event-types.ts +0 -378
  209. package/src/fleet-manager/fleet-manager.ts +0 -2315
  210. package/src/fleet-manager/index.ts +0 -128
  211. package/src/fleet-manager/job-manager.ts +0 -663
  212. package/src/fleet-manager/job-queue.ts +0 -798
  213. package/src/fleet-manager/types.ts +0 -839
  214. package/src/index.ts +0 -32
  215. package/src/runner/__tests__/errors.test.ts +0 -382
  216. package/src/runner/__tests__/job-executor.test.ts +0 -1708
  217. package/src/runner/__tests__/message-processor.test.ts +0 -960
  218. package/src/runner/__tests__/sdk-adapter.test.ts +0 -626
  219. package/src/runner/errors.ts +0 -307
  220. package/src/runner/index.ts +0 -57
  221. package/src/runner/job-executor.ts +0 -448
  222. package/src/runner/message-processor.ts +0 -355
  223. package/src/runner/sdk-adapter.ts +0 -191
  224. package/src/runner/types.ts +0 -158
  225. package/src/scheduler/__tests__/errors.test.ts +0 -159
  226. package/src/scheduler/__tests__/interval.test.ts +0 -515
  227. package/src/scheduler/__tests__/schedule-runner.test.ts +0 -798
  228. package/src/scheduler/__tests__/schedule-state.test.ts +0 -671
  229. package/src/scheduler/__tests__/scheduler.test.ts +0 -1280
  230. package/src/scheduler/errors.ts +0 -101
  231. package/src/scheduler/index.ts +0 -53
  232. package/src/scheduler/interval.ts +0 -189
  233. package/src/scheduler/schedule-runner.ts +0 -442
  234. package/src/scheduler/schedule-state.ts +0 -211
  235. package/src/scheduler/scheduler.ts +0 -570
  236. package/src/scheduler/types.ts +0 -216
  237. package/src/state/__tests__/directory.test.ts +0 -595
  238. package/src/state/__tests__/fleet-state.test.ts +0 -868
  239. package/src/state/__tests__/job-metadata-schema.test.ts +0 -414
  240. package/src/state/__tests__/job-metadata.test.ts +0 -831
  241. package/src/state/__tests__/job-output.test.ts +0 -856
  242. package/src/state/__tests__/session-schema.test.ts +0 -378
  243. package/src/state/__tests__/session.test.ts +0 -604
  244. package/src/state/directory.ts +0 -217
  245. package/src/state/errors.ts +0 -97
  246. package/src/state/fleet-state.ts +0 -284
  247. package/src/state/index.ts +0 -79
  248. package/src/state/job-metadata.ts +0 -445
  249. package/src/state/job-output.ts +0 -316
  250. package/src/state/schemas/__tests__/job-output.test.ts +0 -338
  251. package/src/state/schemas/fleet-state.ts +0 -120
  252. package/src/state/schemas/index.ts +0 -67
  253. package/src/state/schemas/job-metadata.ts +0 -181
  254. package/src/state/schemas/job-output.ts +0 -177
  255. package/src/state/schemas/session-info.ts +0 -92
  256. package/src/state/session.ts +0 -253
  257. package/src/state/types.ts +0 -59
  258. package/src/state/utils/__tests__/atomic.test.ts +0 -723
  259. package/src/state/utils/__tests__/reads.test.ts +0 -1071
  260. package/src/state/utils/atomic.ts +0 -221
  261. package/src/state/utils/index.ts +0 -6
  262. package/src/state/utils/reads.ts +0 -512
  263. package/src/work-sources/__tests__/github.test.ts +0 -1800
  264. package/src/work-sources/__tests__/manager.test.ts +0 -529
  265. package/src/work-sources/__tests__/registry.test.ts +0 -477
  266. package/src/work-sources/__tests__/types.test.ts +0 -479
  267. package/src/work-sources/adapters/github.ts +0 -1166
  268. package/src/work-sources/adapters/index.ts +0 -64
  269. package/src/work-sources/errors.ts +0 -71
  270. package/src/work-sources/index.ts +0 -148
  271. package/src/work-sources/manager.ts +0 -413
  272. package/src/work-sources/registry.ts +0 -178
  273. package/src/work-sources/types.ts +0 -161
  274. package/tsconfig.json +0 -9
  275. 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
- }