@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,355 +0,0 @@
1
- /**
2
- * Message processor for transforming SDK messages to job output format
3
- *
4
- * Handles all Claude SDK message types and converts them to the format
5
- * expected by the job output logging system. Includes robust handling
6
- * of malformed or unexpected SDK responses.
7
- */
8
-
9
- import type { SDKMessage, ProcessedMessage } from "./types.js";
10
- import type { JobOutputInput } from "../state/index.js";
11
-
12
- // =============================================================================
13
- // Validation Helpers
14
- // =============================================================================
15
-
16
- /**
17
- * Safely extract a string value from an unknown field
18
- */
19
- function safeString(value: unknown): string | undefined {
20
- if (typeof value === "string") {
21
- return value;
22
- }
23
- if (value === null || value === undefined) {
24
- return undefined;
25
- }
26
- // Convert other types to string for safety
27
- try {
28
- return String(value);
29
- } catch {
30
- return undefined;
31
- }
32
- }
33
-
34
- /**
35
- * Safely extract a boolean value from an unknown field
36
- */
37
- function safeBoolean(value: unknown): boolean | undefined {
38
- if (typeof value === "boolean") {
39
- return value;
40
- }
41
- return undefined;
42
- }
43
-
44
- /**
45
- * Check if a value is a valid SDK message type
46
- */
47
- function isValidMessageType(
48
- type: unknown
49
- ): type is "system" | "assistant" | "tool_use" | "tool_result" | "error" {
50
- return (
51
- type === "system" ||
52
- type === "assistant" ||
53
- type === "tool_use" ||
54
- type === "tool_result" ||
55
- type === "error"
56
- );
57
- }
58
-
59
- // =============================================================================
60
- // Message Type Handlers
61
- // =============================================================================
62
-
63
- /**
64
- * Process a system message from the SDK
65
- *
66
- * Session ID is specifically extracted from messages with subtype "init",
67
- * as this is when the Claude SDK provides the session identifier.
68
- */
69
- function processSystemMessage(message: SDKMessage): ProcessedMessage {
70
- const output: JobOutputInput = {
71
- type: "system",
72
- };
73
-
74
- if (message.content) {
75
- output.content = message.content;
76
- }
77
-
78
- if (message.subtype) {
79
- output.subtype = message.subtype;
80
- }
81
-
82
- // Extract session ID specifically from init messages
83
- // The Claude SDK provides session_id in the system message with subtype "init"
84
- const sessionId =
85
- message.subtype === "init" ? message.session_id : undefined;
86
-
87
- return {
88
- output,
89
- sessionId,
90
- };
91
- }
92
-
93
- /**
94
- * Process an assistant message from the SDK
95
- */
96
- function processAssistantMessage(message: SDKMessage): ProcessedMessage {
97
- const output: JobOutputInput = {
98
- type: "assistant",
99
- };
100
-
101
- if (message.content !== undefined) {
102
- output.content = message.content;
103
- }
104
-
105
- if (message.partial !== undefined) {
106
- output.partial = message.partial as boolean;
107
- }
108
-
109
- // Handle usage statistics
110
- if (message.usage) {
111
- const usage = message.usage as {
112
- input_tokens?: number;
113
- output_tokens?: number;
114
- };
115
- output.usage = {};
116
- if (usage.input_tokens !== undefined) {
117
- output.usage.input_tokens = usage.input_tokens;
118
- }
119
- if (usage.output_tokens !== undefined) {
120
- output.usage.output_tokens = usage.output_tokens;
121
- }
122
- }
123
-
124
- return { output };
125
- }
126
-
127
- /**
128
- * Process a tool use message from the SDK
129
- */
130
- function processToolUseMessage(message: SDKMessage): ProcessedMessage {
131
- // Tool name is required - try multiple possible field names
132
- const toolName = message.tool_name ?? message.name ?? "unknown";
133
-
134
- const output: JobOutputInput = {
135
- type: "tool_use",
136
- tool_name: toolName as string,
137
- };
138
-
139
- if (message.tool_use_id) {
140
- output.tool_use_id = message.tool_use_id;
141
- }
142
-
143
- if (message.input !== undefined) {
144
- output.input = message.input;
145
- }
146
-
147
- return { output };
148
- }
149
-
150
- /**
151
- * Process a tool result message from the SDK
152
- */
153
- function processToolResultMessage(message: SDKMessage): ProcessedMessage {
154
- const output: JobOutputInput = {
155
- type: "tool_result",
156
- };
157
-
158
- if (message.tool_use_id) {
159
- output.tool_use_id = message.tool_use_id;
160
- }
161
-
162
- if (message.result !== undefined) {
163
- output.result = message.result;
164
- }
165
-
166
- if (message.success !== undefined) {
167
- output.success = message.success as boolean;
168
- }
169
-
170
- if (message.error !== undefined) {
171
- output.error = message.error as string;
172
- }
173
-
174
- return { output };
175
- }
176
-
177
- /**
178
- * Process an error message from the SDK
179
- */
180
- function processErrorMessage(message: SDKMessage): ProcessedMessage {
181
- const output: JobOutputInput = {
182
- type: "error",
183
- message: (message.message as string) ?? "Unknown error",
184
- };
185
-
186
- if (message.code) {
187
- output.code = message.code;
188
- }
189
-
190
- if (message.stack) {
191
- output.stack = message.stack as string;
192
- }
193
-
194
- return {
195
- output,
196
- isFinal: true,
197
- };
198
- }
199
-
200
- // =============================================================================
201
- // Main Processing Function
202
- // =============================================================================
203
-
204
- /**
205
- * Process an SDK message into job output format
206
- *
207
- * Takes a message from the Claude Agent SDK and transforms it into
208
- * the format expected by the job output logging system. This function
209
- * handles malformed responses gracefully without crashing.
210
- *
211
- * @param message - The SDK message to process
212
- * @returns Processed message with output and optional metadata
213
- *
214
- * @example
215
- * ```typescript
216
- * const sdkMessage = { type: "assistant", content: "Hello!" };
217
- * const { output, sessionId } = processSDKMessage(sdkMessage);
218
- * await appendJobOutput(jobsDir, jobId, output);
219
- * ```
220
- */
221
- export function processSDKMessage(message: SDKMessage): ProcessedMessage {
222
- // Handle null/undefined messages - log as system warning, not error
223
- // to avoid terminating execution due to malformed SDK responses
224
- if (message === null || message === undefined) {
225
- return {
226
- output: {
227
- type: "system",
228
- content: "Received null or undefined SDK message",
229
- subtype: "malformed_message",
230
- },
231
- };
232
- }
233
-
234
- // Handle non-object messages - log as system warning
235
- if (typeof message !== "object") {
236
- return {
237
- output: {
238
- type: "system",
239
- content: `Expected object message, received ${typeof message}`,
240
- subtype: "malformed_message",
241
- },
242
- };
243
- }
244
-
245
- // Validate message type
246
- const messageType = message.type;
247
-
248
- if (!isValidMessageType(messageType)) {
249
- // Handle unknown or missing message types gracefully
250
- const unknownType = safeString(messageType) ?? "undefined";
251
- return {
252
- output: {
253
- type: "system",
254
- content: `Unknown message type: ${unknownType}`,
255
- subtype: "unknown_type",
256
- },
257
- };
258
- }
259
-
260
- // Process known message types
261
- switch (messageType) {
262
- case "system":
263
- return processSystemMessage(message);
264
-
265
- case "assistant":
266
- return processAssistantMessage(message);
267
-
268
- case "tool_use":
269
- return processToolUseMessage(message);
270
-
271
- case "tool_result":
272
- return processToolResultMessage(message);
273
-
274
- case "error":
275
- return processErrorMessage(message);
276
- }
277
- }
278
-
279
- /**
280
- * Check if a message indicates the end of execution
281
- *
282
- * @param message - The SDK message to check
283
- * @returns true if this is a terminal message
284
- */
285
- export function isTerminalMessage(message: SDKMessage): boolean {
286
- // Handle null/undefined/non-object messages - these are not terminal
287
- if (message === null || message === undefined || typeof message !== "object") {
288
- return false;
289
- }
290
-
291
- // Error messages are terminal
292
- if (message.type === "error") {
293
- return true;
294
- }
295
-
296
- // System messages with certain subtypes indicate completion
297
- if (message.type === "system") {
298
- const subtype = message.subtype as string | undefined;
299
- if (
300
- subtype === "end" ||
301
- subtype === "complete" ||
302
- subtype === "session_end"
303
- ) {
304
- return true;
305
- }
306
- }
307
-
308
- return false;
309
- }
310
-
311
- /** Maximum summary length in characters */
312
- const MAX_SUMMARY_LENGTH = 500;
313
-
314
- /**
315
- * Truncate a string to maximum length, adding ellipsis if truncated
316
- */
317
- function truncateSummary(text: string): string {
318
- if (text.length <= MAX_SUMMARY_LENGTH) {
319
- return text;
320
- }
321
- return text.slice(0, MAX_SUMMARY_LENGTH - 3) + "...";
322
- }
323
-
324
- /**
325
- * Extract the final summary from a message if present
326
- *
327
- * Looks for summaries in the following order:
328
- * 1. Explicit `summary` field on the message (truncated to 500 chars)
329
- * 2. Short assistant message content (≤500 chars, non-partial)
330
- *
331
- * @param message - The SDK message to extract summary from
332
- * @returns Summary string if present, undefined otherwise
333
- */
334
- export function extractSummary(message: SDKMessage): string | undefined {
335
- // Handle null/undefined/non-object messages
336
- if (message === null || message === undefined || typeof message !== "object") {
337
- return undefined;
338
- }
339
-
340
- // Check for explicit summary field (truncate if too long)
341
- if (message.summary) {
342
- const summaryStr = String(message.summary);
343
- return truncateSummary(summaryStr);
344
- }
345
-
346
- // For assistant messages, use content as potential summary
347
- if (message.type === "assistant" && message.content && !message.partial) {
348
- // Only use if it looks like a conclusion (short enough)
349
- if (message.content.length <= MAX_SUMMARY_LENGTH) {
350
- return message.content;
351
- }
352
- }
353
-
354
- return undefined;
355
- }
@@ -1,191 +0,0 @@
1
- /**
2
- * SDK Adapter for transforming agent configuration to SDK options
3
- *
4
- * Transforms ResolvedAgent configuration to the format expected by
5
- * the Claude Agent SDK's query function.
6
- */
7
-
8
- import type { ResolvedAgent, McpServer } from "../config/index.js";
9
- import type {
10
- SDKQueryOptions,
11
- SDKMcpServerConfig,
12
- SDKSystemPrompt,
13
- } from "./types.js";
14
-
15
- // =============================================================================
16
- // Constants
17
- // =============================================================================
18
-
19
- /**
20
- * Default permission mode when not specified in agent config
21
- */
22
- const DEFAULT_PERMISSION_MODE = "acceptEdits" as const;
23
-
24
- /**
25
- * Default setting sources for SDK initialization
26
- */
27
- const DEFAULT_SETTING_SOURCES = ["project", "local"] as const;
28
-
29
- /**
30
- * Default preset when no system prompt is specified
31
- */
32
- const DEFAULT_PRESET = "claude_code";
33
-
34
- // =============================================================================
35
- // MCP Server Transformation
36
- // =============================================================================
37
-
38
- /**
39
- * Transform a single MCP server configuration to SDK format
40
- *
41
- * @param server - MCP server configuration from agent config
42
- * @returns SDK-formatted MCP server configuration
43
- */
44
- export function transformMcpServer(server: McpServer): SDKMcpServerConfig {
45
- const result: SDKMcpServerConfig = {};
46
-
47
- // HTTP-based MCP server
48
- if (server.url) {
49
- result.type = "http";
50
- result.url = server.url;
51
- }
52
-
53
- // Process-based MCP server
54
- if (server.command) {
55
- result.command = server.command;
56
- }
57
-
58
- if (server.args && server.args.length > 0) {
59
- result.args = server.args;
60
- }
61
-
62
- if (server.env && Object.keys(server.env).length > 0) {
63
- result.env = server.env;
64
- }
65
-
66
- return result;
67
- }
68
-
69
- /**
70
- * Transform MCP servers configuration to SDK format
71
- *
72
- * @param mcpServers - MCP servers configuration from agent config
73
- * @returns SDK-formatted MCP servers map (empty object if no servers configured)
74
- */
75
- export function transformMcpServers(
76
- mcpServers: Record<string, McpServer> | undefined
77
- ): Record<string, SDKMcpServerConfig> {
78
- const result: Record<string, SDKMcpServerConfig> = {};
79
-
80
- if (!mcpServers) {
81
- return result;
82
- }
83
-
84
- for (const [name, server] of Object.entries(mcpServers)) {
85
- result[name] = transformMcpServer(server);
86
- }
87
-
88
- return result;
89
- }
90
-
91
- // =============================================================================
92
- // System Prompt Transformation
93
- // =============================================================================
94
-
95
- /**
96
- * Build the system prompt configuration for SDK
97
- *
98
- * @param agent - Resolved agent configuration
99
- * @returns System prompt configuration for SDK
100
- */
101
- export function buildSystemPrompt(agent: ResolvedAgent): SDKSystemPrompt {
102
- // If agent has a custom system prompt, use it
103
- if (agent.system_prompt) {
104
- return {
105
- type: "custom",
106
- content: agent.system_prompt,
107
- };
108
- }
109
-
110
- // Default to claude_code preset
111
- return {
112
- type: "preset",
113
- preset: DEFAULT_PRESET,
114
- };
115
- }
116
-
117
- // =============================================================================
118
- // Main Transformation Function
119
- // =============================================================================
120
-
121
- /**
122
- * Options for SDK transformation
123
- */
124
- export interface ToSDKOptionsParams {
125
- /** Session ID to resume */
126
- resume?: string;
127
- /** Whether to fork the session */
128
- fork?: boolean;
129
- }
130
-
131
- /**
132
- * Transform agent configuration to SDK query options
133
- *
134
- * This function converts a ResolvedAgent configuration to the format
135
- * expected by the Claude Agent SDK's query function.
136
- *
137
- * @param agent - Fully resolved agent configuration
138
- * @param options - Additional options for resume/fork
139
- * @returns SDK query options ready for use with the SDK
140
- *
141
- * @example
142
- * ```typescript
143
- * const agent = await loadConfig().then(c => c.agents[0]);
144
- * const sdkOptions = toSDKOptions(agent);
145
- *
146
- * for await (const message of query({ prompt, options: sdkOptions })) {
147
- * console.log(message);
148
- * }
149
- * ```
150
- */
151
- export function toSDKOptions(
152
- agent: ResolvedAgent,
153
- options: ToSDKOptionsParams = {}
154
- ): SDKQueryOptions {
155
- const result: SDKQueryOptions = {};
156
-
157
- // Permission mode (defaults to acceptEdits)
158
- result.permissionMode =
159
- agent.permissions?.mode ??
160
- agent.permission_mode ??
161
- DEFAULT_PERMISSION_MODE;
162
-
163
- // Allowed and denied tools
164
- if (agent.permissions?.allowed_tools?.length) {
165
- result.allowedTools = agent.permissions.allowed_tools;
166
- }
167
-
168
- if (agent.permissions?.denied_tools?.length) {
169
- result.deniedTools = agent.permissions.denied_tools;
170
- }
171
-
172
- // System prompt
173
- result.systemPrompt = buildSystemPrompt(agent);
174
-
175
- // Setting sources for proper settings discovery
176
- result.settingSources = [...DEFAULT_SETTING_SOURCES];
177
-
178
- // MCP servers (always include, even if empty)
179
- result.mcpServers = transformMcpServers(agent.mcp_servers);
180
-
181
- // Session resume/fork
182
- if (options.resume) {
183
- result.resume = options.resume;
184
- }
185
-
186
- if (options.fork) {
187
- result.forkSession = true;
188
- }
189
-
190
- return result;
191
- }
@@ -1,158 +0,0 @@
1
- /**
2
- * Type definitions for the agent runner module
3
- *
4
- * Defines options, results, and SDK-related types for agent execution
5
- */
6
-
7
- import type { ResolvedAgent } from "../config/index.js";
8
- import type { TriggerType, JobOutputInput } from "../state/index.js";
9
-
10
- // =============================================================================
11
- // Runner Options Types
12
- // =============================================================================
13
-
14
- /**
15
- * Options for running an agent
16
- */
17
- export interface RunnerOptions {
18
- /** Fully resolved agent configuration */
19
- agent: ResolvedAgent;
20
- /** The prompt to send to the agent */
21
- prompt: string;
22
- /** Path to the .herdctl directory */
23
- stateDir: string;
24
- /** How this run was triggered */
25
- triggerType?: TriggerType;
26
- /** Schedule name (if triggered by schedule) */
27
- schedule?: string;
28
- /** Session ID to resume (mutually exclusive with fork) */
29
- resume?: string;
30
- /** Fork from this session ID */
31
- fork?: string;
32
- /** Parent job ID when forking (used with fork option) */
33
- forkedFrom?: string;
34
- }
35
-
36
- /**
37
- * SDK message types (as received from Claude Agent SDK)
38
- */
39
- export interface SDKMessage {
40
- type: "system" | "assistant" | "tool_use" | "tool_result" | "error";
41
- subtype?: string;
42
- content?: string;
43
- session_id?: string;
44
- name?: string;
45
- input?: unknown;
46
- tool_use_id?: string;
47
- message?: string;
48
- code?: string;
49
- // Allow additional SDK-specific fields
50
- [key: string]: unknown;
51
- }
52
-
53
- /**
54
- * Callback for receiving messages during execution
55
- */
56
- export type MessageCallback = (message: SDKMessage) => void | Promise<void>;
57
-
58
- /**
59
- * Extended options including callbacks
60
- */
61
- export interface RunnerOptionsWithCallbacks extends RunnerOptions {
62
- /** Called for each message from the SDK */
63
- onMessage?: MessageCallback;
64
- }
65
-
66
- // =============================================================================
67
- // Runner Result Types
68
- // =============================================================================
69
-
70
- /**
71
- * Detailed error information for failed runs
72
- */
73
- export interface RunnerErrorDetails {
74
- /** The error message */
75
- message: string;
76
- /** Error code if available (e.g., ETIMEDOUT, ECONNREFUSED) */
77
- code?: string;
78
- /** The type of error (for categorization) */
79
- type?: "initialization" | "streaming" | "malformed_response" | "unknown";
80
- /** Whether this error is potentially recoverable (e.g., rate limit, network) */
81
- recoverable?: boolean;
82
- /** Number of messages received before error (for streaming errors) */
83
- messagesReceived?: number;
84
- /** Stack trace if available */
85
- stack?: string;
86
- }
87
-
88
- /**
89
- * Result of running an agent
90
- */
91
- export interface RunnerResult {
92
- /** Whether the run completed successfully */
93
- success: boolean;
94
- /** The job ID for this run */
95
- jobId: string;
96
- /** The session ID (for resume/fork) */
97
- sessionId?: string;
98
- /** Brief summary of what was accomplished */
99
- summary?: string;
100
- /** Error if the run failed */
101
- error?: Error;
102
- /** Detailed error information for programmatic access */
103
- errorDetails?: RunnerErrorDetails;
104
- /** Duration in seconds */
105
- durationSeconds?: number;
106
- }
107
-
108
- // =============================================================================
109
- // SDK Option Types
110
- // =============================================================================
111
-
112
- /**
113
- * MCP server configuration for SDK
114
- */
115
- export interface SDKMcpServerConfig {
116
- type?: "http";
117
- url?: string;
118
- command?: string;
119
- args?: string[];
120
- env?: Record<string, string>;
121
- }
122
-
123
- /**
124
- * System prompt configuration for SDK
125
- */
126
- export type SDKSystemPrompt =
127
- | { type: "preset"; preset: string }
128
- | { type: "custom"; content: string };
129
-
130
- /**
131
- * SDK query options (matching Claude Agent SDK types)
132
- */
133
- export interface SDKQueryOptions {
134
- allowedTools?: string[];
135
- deniedTools?: string[];
136
- permissionMode?: "default" | "acceptEdits" | "bypassPermissions" | "plan";
137
- systemPrompt?: SDKSystemPrompt;
138
- settingSources?: string[];
139
- mcpServers?: Record<string, SDKMcpServerConfig>;
140
- resume?: string;
141
- forkSession?: boolean;
142
- }
143
-
144
- // =============================================================================
145
- // Message Processing Types
146
- // =============================================================================
147
-
148
- /**
149
- * Result of processing an SDK message
150
- */
151
- export interface ProcessedMessage {
152
- /** The message transformed for job output */
153
- output: JobOutputInput;
154
- /** Session ID if this was an init message */
155
- sessionId?: string;
156
- /** Whether this is the final message */
157
- isFinal?: boolean;
158
- }