@herdctl/core 5.4.3 → 5.6.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 (148) hide show
  1. package/dist/config/__tests__/schema.test.js +19 -0
  2. package/dist/config/__tests__/schema.test.js.map +1 -1
  3. package/dist/config/index.d.ts +1 -1
  4. package/dist/config/index.d.ts.map +1 -1
  5. package/dist/config/index.js +3 -1
  6. package/dist/config/index.js.map +1 -1
  7. package/dist/config/schema.d.ts +10 -18
  8. package/dist/config/schema.d.ts.map +1 -1
  9. package/dist/config/schema.js +4 -2
  10. package/dist/config/schema.js.map +1 -1
  11. package/dist/distribution/__tests__/agent-discovery.test.d.ts +7 -0
  12. package/dist/distribution/__tests__/agent-discovery.test.d.ts.map +1 -0
  13. package/dist/distribution/__tests__/agent-discovery.test.js +443 -0
  14. package/dist/distribution/__tests__/agent-discovery.test.js.map +1 -0
  15. package/dist/distribution/__tests__/agent-info.test.d.ts +7 -0
  16. package/dist/distribution/__tests__/agent-info.test.d.ts.map +1 -0
  17. package/dist/distribution/__tests__/agent-info.test.js +568 -0
  18. package/dist/distribution/__tests__/agent-info.test.js.map +1 -0
  19. package/dist/distribution/__tests__/agent-remover.test.d.ts +7 -0
  20. package/dist/distribution/__tests__/agent-remover.test.d.ts.map +1 -0
  21. package/dist/distribution/__tests__/agent-remover.test.js +498 -0
  22. package/dist/distribution/__tests__/agent-remover.test.js.map +1 -0
  23. package/dist/distribution/__tests__/agent-repo-metadata.test.d.ts +5 -0
  24. package/dist/distribution/__tests__/agent-repo-metadata.test.d.ts.map +1 -0
  25. package/dist/distribution/__tests__/agent-repo-metadata.test.js +500 -0
  26. package/dist/distribution/__tests__/agent-repo-metadata.test.js.map +1 -0
  27. package/dist/distribution/__tests__/env-scanner.test.d.ts +5 -0
  28. package/dist/distribution/__tests__/env-scanner.test.d.ts.map +1 -0
  29. package/dist/distribution/__tests__/env-scanner.test.js +576 -0
  30. package/dist/distribution/__tests__/env-scanner.test.js.map +1 -0
  31. package/dist/distribution/__tests__/file-installer.test.d.ts +7 -0
  32. package/dist/distribution/__tests__/file-installer.test.d.ts.map +1 -0
  33. package/dist/distribution/__tests__/file-installer.test.js +714 -0
  34. package/dist/distribution/__tests__/file-installer.test.js.map +1 -0
  35. package/dist/distribution/__tests__/fleet-config-updater.test.d.ts +7 -0
  36. package/dist/distribution/__tests__/fleet-config-updater.test.d.ts.map +1 -0
  37. package/dist/distribution/__tests__/fleet-config-updater.test.js +531 -0
  38. package/dist/distribution/__tests__/fleet-config-updater.test.js.map +1 -0
  39. package/dist/distribution/__tests__/installation-metadata.test.d.ts +2 -0
  40. package/dist/distribution/__tests__/installation-metadata.test.d.ts.map +1 -0
  41. package/dist/distribution/__tests__/installation-metadata.test.js +292 -0
  42. package/dist/distribution/__tests__/installation-metadata.test.js.map +1 -0
  43. package/dist/distribution/__tests__/integration.test.d.ts +10 -0
  44. package/dist/distribution/__tests__/integration.test.d.ts.map +1 -0
  45. package/dist/distribution/__tests__/integration.test.js +522 -0
  46. package/dist/distribution/__tests__/integration.test.js.map +1 -0
  47. package/dist/distribution/__tests__/repository-fetcher.test.d.ts +5 -0
  48. package/dist/distribution/__tests__/repository-fetcher.test.d.ts.map +1 -0
  49. package/dist/distribution/__tests__/repository-fetcher.test.js +386 -0
  50. package/dist/distribution/__tests__/repository-fetcher.test.js.map +1 -0
  51. package/dist/distribution/__tests__/repository-validator.test.d.ts +7 -0
  52. package/dist/distribution/__tests__/repository-validator.test.d.ts.map +1 -0
  53. package/dist/distribution/__tests__/repository-validator.test.js +447 -0
  54. package/dist/distribution/__tests__/repository-validator.test.js.map +1 -0
  55. package/dist/distribution/__tests__/source-specifier.test.d.ts +5 -0
  56. package/dist/distribution/__tests__/source-specifier.test.d.ts.map +1 -0
  57. package/dist/distribution/__tests__/source-specifier.test.js +533 -0
  58. package/dist/distribution/__tests__/source-specifier.test.js.map +1 -0
  59. package/dist/distribution/agent-discovery.d.ts +81 -0
  60. package/dist/distribution/agent-discovery.d.ts.map +1 -0
  61. package/dist/distribution/agent-discovery.js +264 -0
  62. package/dist/distribution/agent-discovery.js.map +1 -0
  63. package/dist/distribution/agent-info.d.ts +86 -0
  64. package/dist/distribution/agent-info.d.ts.map +1 -0
  65. package/dist/distribution/agent-info.js +225 -0
  66. package/dist/distribution/agent-info.js.map +1 -0
  67. package/dist/distribution/agent-remover.d.ts +83 -0
  68. package/dist/distribution/agent-remover.d.ts.map +1 -0
  69. package/dist/distribution/agent-remover.js +222 -0
  70. package/dist/distribution/agent-remover.js.map +1 -0
  71. package/dist/distribution/agent-repo-metadata.d.ts +181 -0
  72. package/dist/distribution/agent-repo-metadata.d.ts.map +1 -0
  73. package/dist/distribution/agent-repo-metadata.js +143 -0
  74. package/dist/distribution/agent-repo-metadata.js.map +1 -0
  75. package/dist/distribution/env-scanner.d.ts +78 -0
  76. package/dist/distribution/env-scanner.d.ts.map +1 -0
  77. package/dist/distribution/env-scanner.js +144 -0
  78. package/dist/distribution/env-scanner.js.map +1 -0
  79. package/dist/distribution/file-installer.d.ts +80 -0
  80. package/dist/distribution/file-installer.d.ts.map +1 -0
  81. package/dist/distribution/file-installer.js +268 -0
  82. package/dist/distribution/file-installer.js.map +1 -0
  83. package/dist/distribution/fleet-config-updater.d.ts +96 -0
  84. package/dist/distribution/fleet-config-updater.d.ts.map +1 -0
  85. package/dist/distribution/fleet-config-updater.js +266 -0
  86. package/dist/distribution/fleet-config-updater.js.map +1 -0
  87. package/dist/distribution/index.d.ts +23 -0
  88. package/dist/distribution/index.d.ts.map +1 -0
  89. package/dist/distribution/index.js +42 -0
  90. package/dist/distribution/index.js.map +1 -0
  91. package/dist/distribution/installation-metadata.d.ts +191 -0
  92. package/dist/distribution/installation-metadata.d.ts.map +1 -0
  93. package/dist/distribution/installation-metadata.js +100 -0
  94. package/dist/distribution/installation-metadata.js.map +1 -0
  95. package/dist/distribution/repository-fetcher.d.ts +104 -0
  96. package/dist/distribution/repository-fetcher.d.ts.map +1 -0
  97. package/dist/distribution/repository-fetcher.js +246 -0
  98. package/dist/distribution/repository-fetcher.js.map +1 -0
  99. package/dist/distribution/repository-validator.d.ts +86 -0
  100. package/dist/distribution/repository-validator.d.ts.map +1 -0
  101. package/dist/distribution/repository-validator.js +296 -0
  102. package/dist/distribution/repository-validator.js.map +1 -0
  103. package/dist/distribution/source-specifier.d.ts +106 -0
  104. package/dist/distribution/source-specifier.d.ts.map +1 -0
  105. package/dist/distribution/source-specifier.js +247 -0
  106. package/dist/distribution/source-specifier.js.map +1 -0
  107. package/dist/fleet-manager/errors.d.ts +15 -0
  108. package/dist/fleet-manager/errors.d.ts.map +1 -1
  109. package/dist/fleet-manager/errors.js +16 -0
  110. package/dist/fleet-manager/errors.js.map +1 -1
  111. package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
  112. package/dist/fleet-manager/fleet-manager.js +32 -9
  113. package/dist/fleet-manager/fleet-manager.js.map +1 -1
  114. package/dist/hooks/types.d.ts +2 -3
  115. package/dist/hooks/types.d.ts.map +1 -1
  116. package/dist/index.d.ts +1 -0
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +2 -0
  119. package/dist/index.js.map +1 -1
  120. package/dist/runner/job-executor.js +10 -10
  121. package/dist/runner/job-executor.js.map +1 -1
  122. package/dist/runner/message-processor.d.ts.map +1 -1
  123. package/dist/runner/message-processor.js +7 -2
  124. package/dist/runner/message-processor.js.map +1 -1
  125. package/dist/runner/runtime/cli-runtime.d.ts +3 -2
  126. package/dist/runner/runtime/cli-runtime.d.ts.map +1 -1
  127. package/dist/runner/runtime/cli-session-path.d.ts +0 -20
  128. package/dist/runner/runtime/cli-session-path.d.ts.map +1 -1
  129. package/dist/runner/runtime/cli-session-path.js +1 -1
  130. package/dist/runner/runtime/cli-session-path.js.map +1 -1
  131. package/dist/runner/runtime/container-manager.js +1 -1
  132. package/dist/runner/runtime/container-manager.js.map +1 -1
  133. package/dist/runner/runtime/container-runner.d.ts.map +1 -1
  134. package/dist/runner/runtime/container-runner.js +5 -1
  135. package/dist/runner/runtime/container-runner.js.map +1 -1
  136. package/dist/runner/runtime/factory.d.ts +2 -1
  137. package/dist/runner/runtime/factory.d.ts.map +1 -1
  138. package/dist/runner/runtime/index.d.ts +4 -10
  139. package/dist/runner/runtime/index.d.ts.map +1 -1
  140. package/dist/runner/runtime/index.js +4 -13
  141. package/dist/runner/runtime/index.js.map +1 -1
  142. package/dist/scheduler/errors.d.ts +15 -0
  143. package/dist/scheduler/errors.d.ts.map +1 -1
  144. package/dist/state/schemas/session-info.d.ts +2 -1
  145. package/dist/state/schemas/session-info.d.ts.map +1 -1
  146. package/dist/state/schemas/session-info.js +1 -1
  147. package/dist/state/schemas/session-info.js.map +1 -1
  148. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-discovery.d.ts","sourceRoot":"","sources":["../../src/distribution/agent-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAE3F,OAAO,EAAE,KAAK,oBAAoB,EAA8B,MAAM,4BAA4B,CAAC;AAQnG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,SAAS,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAMD,6CAA6C;AAC7C,eAAO,MAAM,0BAA0B,EAAE,qBAAoD,CAAC;AAE9F,0CAA0C;AAC1C,eAAO,MAAM,wBAAwB,EAAE,qBAAkD,CAAC;AAE1F;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,iBAAiB;gBAC5C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB;CAIzD;AAkID;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyHxF"}
@@ -0,0 +1,264 @@
1
+ /**
2
+ * Agent Discovery for herdctl
3
+ *
4
+ * Scans the filesystem to discover agents referenced in herdctl.yaml.
5
+ * Identifies which agents were installed via `herdctl agent add` (have metadata.json)
6
+ * vs manually created agents.
7
+ */
8
+ import * as fs from "node:fs/promises";
9
+ import { dirname, join, resolve } from "node:path";
10
+ import { parse as parseYaml } from "yaml";
11
+ import { FleetManagerError } from "../fleet-manager/errors.js";
12
+ import { createLogger } from "../utils/logger.js";
13
+ import { InstallationMetadataSchema } from "./installation-metadata.js";
14
+ const logger = createLogger("distribution:discovery");
15
+ // =============================================================================
16
+ // Error Classes
17
+ // =============================================================================
18
+ /** Error code: herdctl.yaml doesn't exist */
19
+ export const DISCOVERY_CONFIG_NOT_FOUND = "DISCOVERY_CONFIG_NOT_FOUND";
20
+ /** Error code: herdctl.yaml is invalid */
21
+ export const DISCOVERY_CONFIG_INVALID = "DISCOVERY_CONFIG_INVALID";
22
+ /**
23
+ * Error thrown when agent discovery fails
24
+ */
25
+ export class AgentDiscoveryError extends FleetManagerError {
26
+ constructor(message, code) {
27
+ super(message, { code });
28
+ this.name = "AgentDiscoveryError";
29
+ }
30
+ }
31
+ // =============================================================================
32
+ // Helper Functions
33
+ // =============================================================================
34
+ /**
35
+ * Check if a path exists
36
+ */
37
+ async function pathExists(filePath) {
38
+ try {
39
+ await fs.access(filePath);
40
+ return true;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ /**
47
+ * Safely read and parse a JSON file
48
+ */
49
+ async function readJsonFile(filePath) {
50
+ try {
51
+ const content = await fs.readFile(filePath, "utf-8");
52
+ return JSON.parse(content);
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ /**
59
+ * Safely read and parse a YAML file
60
+ */
61
+ async function readYamlFile(filePath) {
62
+ try {
63
+ const content = await fs.readFile(filePath, "utf-8");
64
+ const parsed = parseYaml(content);
65
+ if (parsed && typeof parsed === "object") {
66
+ return parsed;
67
+ }
68
+ return null;
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ /**
75
+ * Parse agent reference from fleet config
76
+ *
77
+ * Fleet config agents can be:
78
+ * - Object form: { path: "./agents/my-agent/agent.yaml" }
79
+ * - String form: "./agents/my-agent/agent.yaml" (less common)
80
+ */
81
+ function parseAgentReference(entry) {
82
+ if (typeof entry === "string") {
83
+ return entry;
84
+ }
85
+ if (entry && typeof entry === "object" && "path" in entry) {
86
+ const pathValue = entry.path;
87
+ if (typeof pathValue === "string") {
88
+ return pathValue;
89
+ }
90
+ }
91
+ return null;
92
+ }
93
+ function extractAgentYamlInfo(parsed) {
94
+ const name = parsed.name;
95
+ if (typeof name !== "string" || name.trim() === "") {
96
+ return null;
97
+ }
98
+ const result = { name };
99
+ // Extract description if present
100
+ const description = parsed.description;
101
+ if (typeof description === "string" && description.trim() !== "") {
102
+ result.description = description;
103
+ }
104
+ return result;
105
+ }
106
+ /**
107
+ * Read and validate installation metadata from metadata.json
108
+ */
109
+ async function readInstallationMetadata(agentDir) {
110
+ const metadataPath = join(agentDir, "metadata.json");
111
+ const raw = await readJsonFile(metadataPath);
112
+ if (!raw) {
113
+ return null;
114
+ }
115
+ // Validate with Zod schema
116
+ const result = InstallationMetadataSchema.safeParse(raw);
117
+ if (!result.success) {
118
+ logger.debug("Invalid metadata.json, skipping", { path: metadataPath });
119
+ return null;
120
+ }
121
+ return result.data;
122
+ }
123
+ /**
124
+ * Read version from herdctl.json if present
125
+ */
126
+ async function readHerdctlJsonVersion(agentDir) {
127
+ const herdctlJsonPath = join(agentDir, "herdctl.json");
128
+ const parsed = await readJsonFile(herdctlJsonPath);
129
+ if (parsed && typeof parsed.version === "string") {
130
+ return parsed.version;
131
+ }
132
+ return undefined;
133
+ }
134
+ // =============================================================================
135
+ // Main Discovery Function
136
+ // =============================================================================
137
+ /**
138
+ * Discover agents referenced in the fleet configuration
139
+ *
140
+ * This function:
141
+ * 1. Reads herdctl.yaml and extracts agent references
142
+ * 2. For each reference, checks if the agent directory exists
143
+ * 3. Reads agent.yaml to get name and description
144
+ * 4. Checks for metadata.json to determine if installed via herdctl
145
+ * 5. Returns all discovered agents sorted by name
146
+ *
147
+ * @param options - Discovery options including config path
148
+ * @returns Discovery result with list of agents
149
+ * @throws {AgentDiscoveryError} When discovery fails
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * const result = await discoverAgents({
154
+ * configPath: "/path/to/herdctl.yaml"
155
+ * });
156
+ *
157
+ * for (const agent of result.agents) {
158
+ * console.log(`${agent.name}: ${agent.installed ? 'installed' : 'manual'}`);
159
+ * }
160
+ * ```
161
+ */
162
+ export async function discoverAgents(options) {
163
+ const { configPath } = options;
164
+ const baseDir = options.baseDir ?? dirname(configPath);
165
+ logger.debug("Starting agent discovery", { configPath, baseDir });
166
+ // ==========================================================================
167
+ // Step 1: Read fleet config
168
+ // ==========================================================================
169
+ if (!(await pathExists(configPath))) {
170
+ throw new AgentDiscoveryError(`Fleet config not found at ${configPath}. Run 'herdctl init fleet' to create one.`, DISCOVERY_CONFIG_NOT_FOUND);
171
+ }
172
+ const fleetConfig = await readYamlFile(configPath);
173
+ if (!fleetConfig) {
174
+ throw new AgentDiscoveryError(`Failed to parse fleet config at ${configPath}`, DISCOVERY_CONFIG_INVALID);
175
+ }
176
+ // ==========================================================================
177
+ // Step 2: Extract agent references
178
+ // ==========================================================================
179
+ const agentsArray = fleetConfig.agents;
180
+ if (!Array.isArray(agentsArray)) {
181
+ logger.debug("No agents array in fleet config, returning empty result");
182
+ return { agents: [] };
183
+ }
184
+ const agents = [];
185
+ // ==========================================================================
186
+ // Step 3: Process each agent reference
187
+ // ==========================================================================
188
+ for (const entry of agentsArray) {
189
+ const agentPath = parseAgentReference(entry);
190
+ if (!agentPath) {
191
+ logger.debug("Skipping invalid agent reference", { entry });
192
+ continue;
193
+ }
194
+ // Resolve the agent.yaml path relative to baseDir
195
+ const absoluteAgentYamlPath = resolve(baseDir, agentPath);
196
+ const agentDir = dirname(absoluteAgentYamlPath);
197
+ // Check if agent directory exists
198
+ if (!(await pathExists(agentDir))) {
199
+ logger.debug("Agent directory not found, skipping", { path: agentDir });
200
+ continue;
201
+ }
202
+ // Read agent.yaml
203
+ const agentYaml = await readYamlFile(absoluteAgentYamlPath);
204
+ let name;
205
+ let description;
206
+ if (agentYaml) {
207
+ const info = extractAgentYamlInfo(agentYaml);
208
+ if (info) {
209
+ name = info.name;
210
+ description = info.description;
211
+ }
212
+ else {
213
+ // Fallback to directory name if agent.yaml doesn't have valid name
214
+ name = dirname(agentPath).split("/").pop() ?? "unknown";
215
+ logger.debug("agent.yaml missing name, using directory name", { name, path: agentPath });
216
+ }
217
+ }
218
+ else {
219
+ // agent.yaml doesn't exist or is invalid, use directory name
220
+ name = dirname(agentPath).split("/").pop() ?? "unknown";
221
+ logger.debug("agent.yaml not found or invalid, using directory name", {
222
+ name,
223
+ path: agentPath,
224
+ });
225
+ }
226
+ // Check for metadata.json (indicates installed via herdctl)
227
+ const metadata = await readInstallationMetadata(agentDir);
228
+ const installed = metadata !== null;
229
+ // Get version from metadata or herdctl.json
230
+ let version;
231
+ if (metadata?.source?.version) {
232
+ version = metadata.source.version;
233
+ }
234
+ else {
235
+ version = await readHerdctlJsonVersion(agentDir);
236
+ }
237
+ agents.push({
238
+ name,
239
+ installed,
240
+ metadata: metadata ?? undefined,
241
+ path: agentDir,
242
+ configPath: agentPath,
243
+ description,
244
+ version,
245
+ });
246
+ logger.debug("Discovered agent", {
247
+ name,
248
+ installed,
249
+ path: agentDir,
250
+ version,
251
+ });
252
+ }
253
+ // ==========================================================================
254
+ // Step 4: Sort by name and return
255
+ // ==========================================================================
256
+ agents.sort((a, b) => a.name.localeCompare(b.name));
257
+ logger.info("Agent discovery complete", {
258
+ total: agents.length,
259
+ installed: agents.filter((a) => a.installed).length,
260
+ manual: agents.filter((a) => !a.installed).length,
261
+ });
262
+ return { agents };
263
+ }
264
+ //# sourceMappingURL=agent-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-discovery.js","sourceRoot":"","sources":["../../src/distribution/agent-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Agent Information Module
3
+ *
4
+ * Provides detailed information about a specific agent in the fleet.
5
+ * Gathers data from multiple sources:
6
+ * - agent.yaml (name, description, schedules)
7
+ * - metadata.json (installation info for installed agents)
8
+ * - herdctl.json (repository metadata)
9
+ * - Environment variable scanning
10
+ * - File listing
11
+ */
12
+ import { type AgentRepoMetadata } from "./agent-repo-metadata.js";
13
+ import { type EnvScanResult } from "./env-scanner.js";
14
+ import type { InstallationMetadata } from "./installation-metadata.js";
15
+ /**
16
+ * Detailed information about an agent
17
+ */
18
+ export interface AgentDetailedInfo {
19
+ /** Agent name */
20
+ name: string;
21
+ /** Agent description (from agent.yaml) */
22
+ description?: string;
23
+ /** Whether installed via herdctl agent add */
24
+ installed: boolean;
25
+ /** Full installation metadata (source, timestamp, etc.) */
26
+ metadata?: InstallationMetadata;
27
+ /** Full path to agent directory */
28
+ path: string;
29
+ /** Relative config path (e.g., ./agents/my-agent/agent.yaml) */
30
+ configPath: string;
31
+ /** Version (from metadata source or herdctl.json) */
32
+ version?: string;
33
+ /** herdctl.json metadata if present */
34
+ repoMetadata?: AgentRepoMetadata;
35
+ /** Environment variables scanned from agent.yaml */
36
+ envVariables?: EnvScanResult;
37
+ /** Schedules configured in agent.yaml (record of name -> schedule config) */
38
+ schedules?: Record<string, unknown>;
39
+ /** Whether a workspace directory exists */
40
+ hasWorkspace: boolean;
41
+ /** List of files in the agent directory */
42
+ files: string[];
43
+ }
44
+ /**
45
+ * Options for getting agent information
46
+ */
47
+ export interface AgentInfoOptions {
48
+ /** Agent name to look up */
49
+ name: string;
50
+ /** Path to herdctl.yaml */
51
+ configPath: string;
52
+ /** Base directory of the project */
53
+ baseDir?: string;
54
+ }
55
+ /**
56
+ * Get detailed information about a specific agent
57
+ *
58
+ * This function:
59
+ * 1. Uses discoverAgents() to find the agent by name
60
+ * 2. If not found, returns null
61
+ * 3. If found, gathers additional details:
62
+ * - Scans agent.yaml for environment variables
63
+ * - Extracts schedules from agent.yaml
64
+ * - Reads herdctl.json if present
65
+ * - Checks for workspace directory
66
+ * - Lists all files in the agent directory
67
+ *
68
+ * @param options - Options including agent name and config path
69
+ * @returns Detailed agent information or null if not found
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * const info = await getAgentInfo({
74
+ * name: "website-monitor",
75
+ * configPath: "/path/to/herdctl.yaml"
76
+ * });
77
+ *
78
+ * if (info) {
79
+ * console.log(`Agent: ${info.name}`);
80
+ * console.log(`Installed: ${info.installed}`);
81
+ * console.log(`Has workspace: ${info.hasWorkspace}`);
82
+ * }
83
+ * ```
84
+ */
85
+ export declare function getAgentInfo(options: AgentInfoOptions): Promise<AgentDetailedInfo | null>;
86
+ //# sourceMappingURL=agent-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-info.d.ts","sourceRoot":"","sources":["../../src/distribution/agent-info.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,EAAE,KAAK,iBAAiB,EAA2B,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAQvE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,oDAAoD;IACpD,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,2CAA2C;IAC3C,YAAY,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA2FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA2G/F"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Agent Information Module
3
+ *
4
+ * Provides detailed information about a specific agent in the fleet.
5
+ * Gathers data from multiple sources:
6
+ * - agent.yaml (name, description, schedules)
7
+ * - metadata.json (installation info for installed agents)
8
+ * - herdctl.json (repository metadata)
9
+ * - Environment variable scanning
10
+ * - File listing
11
+ */
12
+ import * as fs from "node:fs/promises";
13
+ import { join, relative } from "node:path";
14
+ import { parse as parseYaml } from "yaml";
15
+ import { createLogger } from "../utils/logger.js";
16
+ import { discoverAgents } from "./agent-discovery.js";
17
+ import { AgentRepoMetadataSchema } from "./agent-repo-metadata.js";
18
+ import { scanEnvVariables } from "./env-scanner.js";
19
+ const logger = createLogger("distribution:agent-info");
20
+ // =============================================================================
21
+ // Helper Functions
22
+ // =============================================================================
23
+ /**
24
+ * Check if a path exists
25
+ */
26
+ async function pathExists(filePath) {
27
+ try {
28
+ await fs.access(filePath);
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Read a file as text, returning null if it fails
37
+ */
38
+ async function readTextFile(filePath) {
39
+ try {
40
+ return await fs.readFile(filePath, "utf-8");
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * Safely read and parse a JSON file
48
+ */
49
+ async function readJsonFile(filePath) {
50
+ try {
51
+ const content = await fs.readFile(filePath, "utf-8");
52
+ return JSON.parse(content);
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ /**
59
+ * Recursively list files in a directory
60
+ * Excludes .git and node_modules directories
61
+ */
62
+ async function listFilesRecursive(dir, baseDir = dir, excludeDirs = new Set([".git", "node_modules"])) {
63
+ const files = [];
64
+ try {
65
+ const entries = await fs.readdir(dir, { withFileTypes: true });
66
+ for (const entry of entries) {
67
+ const fullPath = join(dir, entry.name);
68
+ const relativePath = relative(baseDir, fullPath);
69
+ if (entry.isDirectory()) {
70
+ if (!excludeDirs.has(entry.name)) {
71
+ const subFiles = await listFilesRecursive(fullPath, baseDir, excludeDirs);
72
+ files.push(...subFiles);
73
+ }
74
+ }
75
+ else if (entry.isFile()) {
76
+ files.push(relativePath);
77
+ }
78
+ }
79
+ }
80
+ catch {
81
+ // Directory might not exist or be readable
82
+ return [];
83
+ }
84
+ return files.sort();
85
+ }
86
+ /**
87
+ * Extract schedules from parsed agent.yaml
88
+ */
89
+ function extractSchedules(agentYaml) {
90
+ const schedules = agentYaml.schedules;
91
+ if (!schedules || typeof schedules !== "object") {
92
+ return undefined;
93
+ }
94
+ return schedules;
95
+ }
96
+ // =============================================================================
97
+ // Main Function
98
+ // =============================================================================
99
+ /**
100
+ * Get detailed information about a specific agent
101
+ *
102
+ * This function:
103
+ * 1. Uses discoverAgents() to find the agent by name
104
+ * 2. If not found, returns null
105
+ * 3. If found, gathers additional details:
106
+ * - Scans agent.yaml for environment variables
107
+ * - Extracts schedules from agent.yaml
108
+ * - Reads herdctl.json if present
109
+ * - Checks for workspace directory
110
+ * - Lists all files in the agent directory
111
+ *
112
+ * @param options - Options including agent name and config path
113
+ * @returns Detailed agent information or null if not found
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const info = await getAgentInfo({
118
+ * name: "website-monitor",
119
+ * configPath: "/path/to/herdctl.yaml"
120
+ * });
121
+ *
122
+ * if (info) {
123
+ * console.log(`Agent: ${info.name}`);
124
+ * console.log(`Installed: ${info.installed}`);
125
+ * console.log(`Has workspace: ${info.hasWorkspace}`);
126
+ * }
127
+ * ```
128
+ */
129
+ export async function getAgentInfo(options) {
130
+ const { name, configPath, baseDir } = options;
131
+ logger.debug("Getting agent info", { name, configPath });
132
+ // ==========================================================================
133
+ // Step 1: Find the agent using discovery
134
+ // ==========================================================================
135
+ let discoveryResult;
136
+ try {
137
+ discoveryResult = await discoverAgents({ configPath, baseDir });
138
+ }
139
+ catch (error) {
140
+ logger.debug("Discovery failed", { error });
141
+ return null;
142
+ }
143
+ // Find the agent by name
144
+ const agent = discoveryResult.agents.find((a) => a.name === name);
145
+ if (!agent) {
146
+ logger.debug("Agent not found", { name });
147
+ return null;
148
+ }
149
+ logger.debug("Agent found, gathering additional info", { name, path: agent.path });
150
+ // ==========================================================================
151
+ // Step 2: Read agent.yaml for env vars and schedules
152
+ // ==========================================================================
153
+ const agentYamlPath = join(agent.path, "agent.yaml");
154
+ const agentYamlContent = await readTextFile(agentYamlPath);
155
+ let envVariables;
156
+ let schedules;
157
+ if (agentYamlContent) {
158
+ // Scan for environment variables
159
+ envVariables = scanEnvVariables(agentYamlContent);
160
+ if (envVariables.variables.length === 0) {
161
+ envVariables = undefined;
162
+ }
163
+ // Parse YAML to extract schedules
164
+ try {
165
+ const parsed = parseYaml(agentYamlContent);
166
+ if (parsed && typeof parsed === "object") {
167
+ schedules = extractSchedules(parsed);
168
+ }
169
+ }
170
+ catch {
171
+ logger.debug("Failed to parse agent.yaml for schedules", { path: agentYamlPath });
172
+ }
173
+ }
174
+ // ==========================================================================
175
+ // Step 3: Read herdctl.json if present
176
+ // ==========================================================================
177
+ const herdctlJsonPath = join(agent.path, "herdctl.json");
178
+ let repoMetadata;
179
+ const herdctlJsonRaw = await readJsonFile(herdctlJsonPath);
180
+ if (herdctlJsonRaw) {
181
+ const result = AgentRepoMetadataSchema.safeParse(herdctlJsonRaw);
182
+ if (result.success) {
183
+ repoMetadata = result.data;
184
+ }
185
+ else {
186
+ logger.debug("herdctl.json failed schema validation", { path: herdctlJsonPath });
187
+ }
188
+ }
189
+ // ==========================================================================
190
+ // Step 4: Check for workspace directory
191
+ // ==========================================================================
192
+ const workspacePath = join(agent.path, "workspace");
193
+ const hasWorkspace = await pathExists(workspacePath);
194
+ // ==========================================================================
195
+ // Step 5: List files in agent directory
196
+ // ==========================================================================
197
+ const files = await listFilesRecursive(agent.path);
198
+ // ==========================================================================
199
+ // Step 6: Assemble and return the result
200
+ // ==========================================================================
201
+ const info = {
202
+ name: agent.name,
203
+ description: agent.description,
204
+ installed: agent.installed,
205
+ metadata: agent.metadata,
206
+ path: agent.path,
207
+ configPath: agent.configPath,
208
+ version: agent.version,
209
+ repoMetadata,
210
+ envVariables,
211
+ schedules,
212
+ hasWorkspace,
213
+ files,
214
+ };
215
+ logger.debug("Agent info gathered", {
216
+ name: info.name,
217
+ installed: info.installed,
218
+ hasWorkspace: info.hasWorkspace,
219
+ fileCount: info.files.length,
220
+ hasEnvVars: !!info.envVariables,
221
+ hasSchedules: !!info.schedules,
222
+ });
223
+ return info;
224
+ }
225
+ //# sourceMappingURL=agent-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-info.js","sourceRoot":"","sources":["../../src/distribution/agent-info.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAW,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAwB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAA0B,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAsB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGxE,MAAM,MAAM,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;AAgDvD,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC1C,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CAAI,QAAgB;IAC7C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,kBAAkB,CAC/B,GAAW,EACX,UAAkB,GAAG,EACrB,cAA2B,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAE5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAEjD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjC,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;oBAC1E,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;QAC3C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,SAAkC;IAC1D,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;IACtC,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,SAAoC,CAAC;AAC9C,CAAC;AAED,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAyB;IAC1D,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE9C,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAEzD,6EAA6E;IAC7E,yCAAyC;IACzC,6EAA6E;IAC7E,IAAI,eAAe,CAAC;IACpB,IAAI,CAAC;QACH,eAAe,GAAG,MAAM,cAAc,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yBAAyB;IACzB,MAAM,KAAK,GAAgC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC/F,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAEnF,6EAA6E;IAC7E,qDAAqD;IACrD,6EAA6E;IAC7E,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACrD,MAAM,gBAAgB,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,CAAC;IAE3D,IAAI,YAAuC,CAAC;IAC5C,IAAI,SAA8C,CAAC;IAEnD,IAAI,gBAAgB,EAAE,CAAC;QACrB,iCAAiC;QACjC,YAAY,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;QAClD,IAAI,YAAY,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,YAAY,GAAG,SAAS,CAAC;QAC3B,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAC3C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACzC,SAAS,GAAG,gBAAgB,CAAC,MAAiC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,uCAAuC;IACvC,6EAA6E;IAC7E,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACzD,IAAI,YAA2C,CAAC;IAEhD,MAAM,cAAc,GAAG,MAAM,YAAY,CAAU,eAAe,CAAC,CAAC;IACpE,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,uBAAuB,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,wCAAwC;IACxC,6EAA6E;IAC7E,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;IAErD,6EAA6E;IAC7E,wCAAwC;IACxC,6EAA6E;IAC7E,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEnD,6EAA6E;IAC7E,yCAAyC;IACzC,6EAA6E;IAC7E,MAAM,IAAI,GAAsB;QAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY;QACZ,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,KAAK;KACN,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE;QAClC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;QAC5B,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY;QAC/B,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS;KAC/B,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AACd,CAAC"}