@herdctl/core 5.5.0 → 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 (119) hide show
  1. package/dist/config/index.d.ts +1 -1
  2. package/dist/config/index.d.ts.map +1 -1
  3. package/dist/config/index.js +3 -1
  4. package/dist/config/index.js.map +1 -1
  5. package/dist/distribution/__tests__/agent-discovery.test.d.ts +7 -0
  6. package/dist/distribution/__tests__/agent-discovery.test.d.ts.map +1 -0
  7. package/dist/distribution/__tests__/agent-discovery.test.js +443 -0
  8. package/dist/distribution/__tests__/agent-discovery.test.js.map +1 -0
  9. package/dist/distribution/__tests__/agent-info.test.d.ts +7 -0
  10. package/dist/distribution/__tests__/agent-info.test.d.ts.map +1 -0
  11. package/dist/distribution/__tests__/agent-info.test.js +568 -0
  12. package/dist/distribution/__tests__/agent-info.test.js.map +1 -0
  13. package/dist/distribution/__tests__/agent-remover.test.d.ts +7 -0
  14. package/dist/distribution/__tests__/agent-remover.test.d.ts.map +1 -0
  15. package/dist/distribution/__tests__/agent-remover.test.js +498 -0
  16. package/dist/distribution/__tests__/agent-remover.test.js.map +1 -0
  17. package/dist/distribution/__tests__/agent-repo-metadata.test.d.ts +5 -0
  18. package/dist/distribution/__tests__/agent-repo-metadata.test.d.ts.map +1 -0
  19. package/dist/distribution/__tests__/agent-repo-metadata.test.js +500 -0
  20. package/dist/distribution/__tests__/agent-repo-metadata.test.js.map +1 -0
  21. package/dist/distribution/__tests__/env-scanner.test.d.ts +5 -0
  22. package/dist/distribution/__tests__/env-scanner.test.d.ts.map +1 -0
  23. package/dist/distribution/__tests__/env-scanner.test.js +576 -0
  24. package/dist/distribution/__tests__/env-scanner.test.js.map +1 -0
  25. package/dist/distribution/__tests__/file-installer.test.d.ts +7 -0
  26. package/dist/distribution/__tests__/file-installer.test.d.ts.map +1 -0
  27. package/dist/distribution/__tests__/file-installer.test.js +714 -0
  28. package/dist/distribution/__tests__/file-installer.test.js.map +1 -0
  29. package/dist/distribution/__tests__/fleet-config-updater.test.d.ts +7 -0
  30. package/dist/distribution/__tests__/fleet-config-updater.test.d.ts.map +1 -0
  31. package/dist/distribution/__tests__/fleet-config-updater.test.js +531 -0
  32. package/dist/distribution/__tests__/fleet-config-updater.test.js.map +1 -0
  33. package/dist/distribution/__tests__/installation-metadata.test.d.ts +2 -0
  34. package/dist/distribution/__tests__/installation-metadata.test.d.ts.map +1 -0
  35. package/dist/distribution/__tests__/installation-metadata.test.js +292 -0
  36. package/dist/distribution/__tests__/installation-metadata.test.js.map +1 -0
  37. package/dist/distribution/__tests__/integration.test.d.ts +10 -0
  38. package/dist/distribution/__tests__/integration.test.d.ts.map +1 -0
  39. package/dist/distribution/__tests__/integration.test.js +522 -0
  40. package/dist/distribution/__tests__/integration.test.js.map +1 -0
  41. package/dist/distribution/__tests__/repository-fetcher.test.d.ts +5 -0
  42. package/dist/distribution/__tests__/repository-fetcher.test.d.ts.map +1 -0
  43. package/dist/distribution/__tests__/repository-fetcher.test.js +386 -0
  44. package/dist/distribution/__tests__/repository-fetcher.test.js.map +1 -0
  45. package/dist/distribution/__tests__/repository-validator.test.d.ts +7 -0
  46. package/dist/distribution/__tests__/repository-validator.test.d.ts.map +1 -0
  47. package/dist/distribution/__tests__/repository-validator.test.js +447 -0
  48. package/dist/distribution/__tests__/repository-validator.test.js.map +1 -0
  49. package/dist/distribution/__tests__/source-specifier.test.d.ts +5 -0
  50. package/dist/distribution/__tests__/source-specifier.test.d.ts.map +1 -0
  51. package/dist/distribution/__tests__/source-specifier.test.js +533 -0
  52. package/dist/distribution/__tests__/source-specifier.test.js.map +1 -0
  53. package/dist/distribution/agent-discovery.d.ts +81 -0
  54. package/dist/distribution/agent-discovery.d.ts.map +1 -0
  55. package/dist/distribution/agent-discovery.js +264 -0
  56. package/dist/distribution/agent-discovery.js.map +1 -0
  57. package/dist/distribution/agent-info.d.ts +86 -0
  58. package/dist/distribution/agent-info.d.ts.map +1 -0
  59. package/dist/distribution/agent-info.js +225 -0
  60. package/dist/distribution/agent-info.js.map +1 -0
  61. package/dist/distribution/agent-remover.d.ts +83 -0
  62. package/dist/distribution/agent-remover.d.ts.map +1 -0
  63. package/dist/distribution/agent-remover.js +222 -0
  64. package/dist/distribution/agent-remover.js.map +1 -0
  65. package/dist/distribution/agent-repo-metadata.d.ts +181 -0
  66. package/dist/distribution/agent-repo-metadata.d.ts.map +1 -0
  67. package/dist/distribution/agent-repo-metadata.js +143 -0
  68. package/dist/distribution/agent-repo-metadata.js.map +1 -0
  69. package/dist/distribution/env-scanner.d.ts +78 -0
  70. package/dist/distribution/env-scanner.d.ts.map +1 -0
  71. package/dist/distribution/env-scanner.js +144 -0
  72. package/dist/distribution/env-scanner.js.map +1 -0
  73. package/dist/distribution/file-installer.d.ts +80 -0
  74. package/dist/distribution/file-installer.d.ts.map +1 -0
  75. package/dist/distribution/file-installer.js +268 -0
  76. package/dist/distribution/file-installer.js.map +1 -0
  77. package/dist/distribution/fleet-config-updater.d.ts +96 -0
  78. package/dist/distribution/fleet-config-updater.d.ts.map +1 -0
  79. package/dist/distribution/fleet-config-updater.js +266 -0
  80. package/dist/distribution/fleet-config-updater.js.map +1 -0
  81. package/dist/distribution/index.d.ts +23 -0
  82. package/dist/distribution/index.d.ts.map +1 -0
  83. package/dist/distribution/index.js +42 -0
  84. package/dist/distribution/index.js.map +1 -0
  85. package/dist/distribution/installation-metadata.d.ts +191 -0
  86. package/dist/distribution/installation-metadata.d.ts.map +1 -0
  87. package/dist/distribution/installation-metadata.js +100 -0
  88. package/dist/distribution/installation-metadata.js.map +1 -0
  89. package/dist/distribution/repository-fetcher.d.ts +104 -0
  90. package/dist/distribution/repository-fetcher.d.ts.map +1 -0
  91. package/dist/distribution/repository-fetcher.js +246 -0
  92. package/dist/distribution/repository-fetcher.js.map +1 -0
  93. package/dist/distribution/repository-validator.d.ts +86 -0
  94. package/dist/distribution/repository-validator.d.ts.map +1 -0
  95. package/dist/distribution/repository-validator.js +296 -0
  96. package/dist/distribution/repository-validator.js.map +1 -0
  97. package/dist/distribution/source-specifier.d.ts +106 -0
  98. package/dist/distribution/source-specifier.d.ts.map +1 -0
  99. package/dist/distribution/source-specifier.js +247 -0
  100. package/dist/distribution/source-specifier.js.map +1 -0
  101. package/dist/fleet-manager/errors.d.ts +15 -0
  102. package/dist/fleet-manager/errors.d.ts.map +1 -1
  103. package/dist/fleet-manager/errors.js +16 -0
  104. package/dist/fleet-manager/errors.js.map +1 -1
  105. package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
  106. package/dist/fleet-manager/fleet-manager.js +31 -9
  107. package/dist/fleet-manager/fleet-manager.js.map +1 -1
  108. package/dist/index.d.ts +1 -0
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js +2 -0
  111. package/dist/index.js.map +1 -1
  112. package/dist/runner/message-processor.d.ts.map +1 -1
  113. package/dist/runner/message-processor.js +7 -2
  114. package/dist/runner/message-processor.js.map +1 -1
  115. package/dist/runner/runtime/container-manager.js +1 -1
  116. package/dist/runner/runtime/container-manager.js.map +1 -1
  117. package/dist/scheduler/errors.d.ts +15 -0
  118. package/dist/scheduler/errors.d.ts.map +1 -1
  119. package/package.json +1 -1
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Agent Remover for herdctl
3
+ *
4
+ * Handles the filesystem and config operations for removing an installed agent.
5
+ * This includes:
6
+ * - Deleting the agent directory (optionally preserving workspace)
7
+ * - Removing the agent reference from herdctl.yaml
8
+ * - Scanning for env variables to report back to the user
9
+ */
10
+ import { FleetManagerError, type FleetManagerErrorCode } from "../fleet-manager/errors.js";
11
+ import { type EnvScanResult } from "./env-scanner.js";
12
+ /**
13
+ * Options for removing an agent
14
+ */
15
+ export interface RemoveOptions {
16
+ /** Agent name to remove */
17
+ name: string;
18
+ /** Path to herdctl.yaml */
19
+ configPath: string;
20
+ /** Base directory of the project (defaults to dirname of configPath) */
21
+ baseDir?: string;
22
+ /** If true, preserve workspace/ directory contents */
23
+ keepWorkspace?: boolean;
24
+ }
25
+ /**
26
+ * Result of removing an agent
27
+ */
28
+ export interface RemoveResult {
29
+ /** The agent name that was removed */
30
+ agentName: string;
31
+ /** The path that was removed */
32
+ removedPath: string;
33
+ /** Whether files were actually deleted */
34
+ filesRemoved: boolean;
35
+ /** Whether the fleet config was updated */
36
+ configUpdated: boolean;
37
+ /** Environment variables that were used by this agent (for user reference) */
38
+ envVariables?: EnvScanResult;
39
+ /** Whether workspace was preserved */
40
+ workspacePreserved: boolean;
41
+ }
42
+ /** Error code: Agent not found in fleet config */
43
+ export declare const AGENT_NOT_FOUND: FleetManagerErrorCode;
44
+ /**
45
+ * Error thrown when agent removal fails
46
+ */
47
+ export declare class AgentRemoveError extends FleetManagerError {
48
+ constructor(message: string, code: FleetManagerErrorCode);
49
+ }
50
+ /**
51
+ * Remove an agent from the fleet
52
+ *
53
+ * This function:
54
+ * 1. Uses discoverAgents() to find the agent by name
55
+ * 2. Scans agent.yaml for env variables (before deleting!) to report them
56
+ * 3. Deletes the agent directory (optionally preserving workspace/)
57
+ * 4. Removes the agent reference from herdctl.yaml
58
+ *
59
+ * @param options - Remove options including agent name and config path
60
+ * @returns Result indicating what was removed
61
+ * @throws {AgentRemoveError} When the agent is not found
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const result = await removeAgent({
66
+ * name: "my-agent",
67
+ * configPath: "/path/to/herdctl.yaml"
68
+ * });
69
+ *
70
+ * if (result.filesRemoved) {
71
+ * console.log(`Deleted: ${result.removedPath}`);
72
+ * }
73
+ *
74
+ * if (result.envVariables?.variables.length > 0) {
75
+ * console.log("You may want to clean up these env vars:");
76
+ * for (const v of result.envVariables.variables) {
77
+ * console.log(` ${v.name}`);
78
+ * }
79
+ * }
80
+ * ```
81
+ */
82
+ export declare function removeAgent(options: RemoveOptions): Promise<RemoveResult>;
83
+ //# sourceMappingURL=agent-remover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-remover.d.ts","sourceRoot":"","sources":["../../src/distribution/agent-remover.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAE,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAG3F,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,kBAAkB,CAAC;AASxE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,YAAY,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,sCAAsC;IACtC,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAMD,kDAAkD;AAClD,eAAO,MAAM,eAAe,EAAE,qBAAyC,CAAC;AAExE;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,iBAAiB;gBACzC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB;CAIzD;AAiFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA6G/E"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Agent Remover for herdctl
3
+ *
4
+ * Handles the filesystem and config operations for removing an installed agent.
5
+ * This includes:
6
+ * - Deleting the agent directory (optionally preserving workspace)
7
+ * - Removing the agent reference from herdctl.yaml
8
+ * - Scanning for env variables to report back to the user
9
+ */
10
+ import * as fs from "node:fs/promises";
11
+ import { dirname, join } from "node:path";
12
+ import { FleetManagerError } from "../fleet-manager/errors.js";
13
+ import { createLogger } from "../utils/logger.js";
14
+ import { discoverAgents } from "./agent-discovery.js";
15
+ import { scanEnvVariables } from "./env-scanner.js";
16
+ import { FleetConfigError, removeAgentFromFleetConfig } from "./fleet-config-updater.js";
17
+ const logger = createLogger("distribution:remover");
18
+ // =============================================================================
19
+ // Error Classes
20
+ // =============================================================================
21
+ /** Error code: Agent not found in fleet config */
22
+ export const AGENT_NOT_FOUND = "AGENT_NOT_FOUND";
23
+ /**
24
+ * Error thrown when agent removal fails
25
+ */
26
+ export class AgentRemoveError extends FleetManagerError {
27
+ constructor(message, code) {
28
+ super(message, { code });
29
+ this.name = "AgentRemoveError";
30
+ }
31
+ }
32
+ // =============================================================================
33
+ // Helper Functions
34
+ // =============================================================================
35
+ /**
36
+ * Check if a path exists
37
+ */
38
+ async function pathExists(filePath) {
39
+ try {
40
+ await fs.access(filePath);
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ /**
48
+ * Safely read a file's contents
49
+ */
50
+ async function readFileContent(filePath) {
51
+ try {
52
+ return await fs.readFile(filePath, "utf-8");
53
+ }
54
+ catch {
55
+ return null;
56
+ }
57
+ }
58
+ /**
59
+ * Delete a directory and all its contents, optionally preserving the workspace subdirectory
60
+ */
61
+ async function deleteAgentDirectory(agentDir, keepWorkspace) {
62
+ // Check if directory exists
63
+ if (!(await pathExists(agentDir))) {
64
+ logger.debug("Agent directory does not exist, nothing to delete", { path: agentDir });
65
+ return { deleted: false, workspacePreserved: false };
66
+ }
67
+ const workspacePath = join(agentDir, "workspace");
68
+ const hasWorkspace = await pathExists(workspacePath);
69
+ if (keepWorkspace && hasWorkspace) {
70
+ // Delete everything except workspace/
71
+ logger.debug("Preserving workspace, deleting other files", { path: agentDir });
72
+ const entries = await fs.readdir(agentDir, { withFileTypes: true });
73
+ for (const entry of entries) {
74
+ if (entry.name === "workspace") {
75
+ continue;
76
+ }
77
+ const entryPath = join(agentDir, entry.name);
78
+ await fs.rm(entryPath, { recursive: true, force: true });
79
+ logger.debug("Deleted entry", { path: entryPath });
80
+ }
81
+ return { deleted: true, workspacePreserved: true };
82
+ }
83
+ else {
84
+ // Delete the entire directory
85
+ logger.debug("Deleting entire agent directory", { path: agentDir });
86
+ await fs.rm(agentDir, { recursive: true, force: true });
87
+ return { deleted: true, workspacePreserved: false };
88
+ }
89
+ }
90
+ /**
91
+ * Find an agent by name in the discovery result
92
+ */
93
+ function findAgentByName(agents, name) {
94
+ return agents.find((agent) => agent.name === name);
95
+ }
96
+ // =============================================================================
97
+ // Main Function
98
+ // =============================================================================
99
+ /**
100
+ * Remove an agent from the fleet
101
+ *
102
+ * This function:
103
+ * 1. Uses discoverAgents() to find the agent by name
104
+ * 2. Scans agent.yaml for env variables (before deleting!) to report them
105
+ * 3. Deletes the agent directory (optionally preserving workspace/)
106
+ * 4. Removes the agent reference from herdctl.yaml
107
+ *
108
+ * @param options - Remove options including agent name and config path
109
+ * @returns Result indicating what was removed
110
+ * @throws {AgentRemoveError} When the agent is not found
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * const result = await removeAgent({
115
+ * name: "my-agent",
116
+ * configPath: "/path/to/herdctl.yaml"
117
+ * });
118
+ *
119
+ * if (result.filesRemoved) {
120
+ * console.log(`Deleted: ${result.removedPath}`);
121
+ * }
122
+ *
123
+ * if (result.envVariables?.variables.length > 0) {
124
+ * console.log("You may want to clean up these env vars:");
125
+ * for (const v of result.envVariables.variables) {
126
+ * console.log(` ${v.name}`);
127
+ * }
128
+ * }
129
+ * ```
130
+ */
131
+ export async function removeAgent(options) {
132
+ const { name, configPath, keepWorkspace = false } = options;
133
+ const baseDir = options.baseDir ?? dirname(configPath);
134
+ logger.info("Removing agent", { name, configPath, keepWorkspace });
135
+ // ==========================================================================
136
+ // Step 1: Discover agents to find the one we want to remove
137
+ // ==========================================================================
138
+ const discoveryResult = await discoverAgents({ configPath, baseDir });
139
+ const agent = findAgentByName(discoveryResult.agents, name);
140
+ if (!agent) {
141
+ throw new AgentRemoveError(`Agent '${name}' not found in fleet configuration. Run 'herdctl agent list' to see available agents.`, AGENT_NOT_FOUND);
142
+ }
143
+ logger.debug("Found agent to remove", {
144
+ name: agent.name,
145
+ path: agent.path,
146
+ configPath: agent.configPath,
147
+ });
148
+ // ==========================================================================
149
+ // Step 2: Scan for env variables BEFORE deleting (for user reference)
150
+ // ==========================================================================
151
+ let envVariables;
152
+ const agentYamlPath = join(agent.path, "agent.yaml");
153
+ const agentYamlContent = await readFileContent(agentYamlPath);
154
+ if (agentYamlContent) {
155
+ envVariables = scanEnvVariables(agentYamlContent);
156
+ logger.debug("Scanned env variables", {
157
+ total: envVariables.variables.length,
158
+ required: envVariables.required.length,
159
+ optional: envVariables.optional.length,
160
+ });
161
+ }
162
+ // ==========================================================================
163
+ // Step 3: Delete the agent directory
164
+ // ==========================================================================
165
+ const { deleted: filesRemoved, workspacePreserved } = await deleteAgentDirectory(agent.path, keepWorkspace);
166
+ logger.debug("Directory deletion result", {
167
+ filesRemoved,
168
+ workspacePreserved,
169
+ path: agent.path,
170
+ });
171
+ // ==========================================================================
172
+ // Step 4: Remove the agent reference from herdctl.yaml
173
+ // ==========================================================================
174
+ let configUpdated = false;
175
+ try {
176
+ const configResult = await removeAgentFromFleetConfig({
177
+ configPath,
178
+ agentPath: agent.configPath,
179
+ });
180
+ configUpdated = configResult.modified;
181
+ if (configResult.modified) {
182
+ logger.info("Removed agent from fleet config", { agentPath: agent.configPath });
183
+ }
184
+ else if (!configResult.alreadyExists) {
185
+ logger.debug("Agent was not in fleet config", { agentPath: agent.configPath });
186
+ }
187
+ }
188
+ catch (error) {
189
+ // Config update failure shouldn't fail the overall operation
190
+ // (files are already deleted at this point)
191
+ if (error instanceof FleetConfigError) {
192
+ logger.warn("Failed to update fleet config, but files were removed", {
193
+ error: error.message,
194
+ code: error.code,
195
+ });
196
+ }
197
+ else {
198
+ logger.warn("Unexpected error updating fleet config", {
199
+ error: error instanceof Error ? error.message : String(error),
200
+ });
201
+ }
202
+ }
203
+ // ==========================================================================
204
+ // Return result
205
+ // ==========================================================================
206
+ const result = {
207
+ agentName: agent.name,
208
+ removedPath: agent.path,
209
+ filesRemoved,
210
+ configUpdated,
211
+ envVariables,
212
+ workspacePreserved,
213
+ };
214
+ logger.info("Agent removal complete", {
215
+ agentName: result.agentName,
216
+ filesRemoved: result.filesRemoved,
217
+ configUpdated: result.configUpdated,
218
+ workspacePreserved: result.workspacePreserved,
219
+ });
220
+ return result;
221
+ }
222
+ //# sourceMappingURL=agent-remover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-remover.js","sourceRoot":"","sources":["../../src/distribution/agent-remover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Agent Repository Metadata Schema (`herdctl.json`)
3
+ *
4
+ * Validates the metadata file that agent authors include in their repositories
5
+ * to describe their agent for registry listing and installation validation.
6
+ *
7
+ * This file is found at the root of an agent repository and provides:
8
+ * - Basic info: name, version, description, author
9
+ * - Source info: repository, homepage, license
10
+ * - Discovery: keywords, category, tags
11
+ * - Requirements: herdctl version, runtime, env vars, workspace, docker
12
+ * - Presentation: screenshots, examples
13
+ */
14
+ import { z } from "zod";
15
+ import { AGENT_NAME_PATTERN } from "../config/schema.js";
16
+ /**
17
+ * Requirements schema for agent dependencies and constraints.
18
+ *
19
+ * Specifies what the agent needs to run properly:
20
+ * - herdctl version compatibility
21
+ * - Runtime backend (cli, sdk)
22
+ * - Required environment variables
23
+ * - Workspace requirement
24
+ * - Docker requirement
25
+ */
26
+ export declare const AgentRequiresSchema: z.ZodObject<{
27
+ /** Minimum herdctl version required (semver range, e.g., ">=0.1.0") */
28
+ herdctl: z.ZodOptional<z.ZodString>;
29
+ /** Runtime backend required (e.g., "cli" for Claude CLI) */
30
+ runtime: z.ZodOptional<z.ZodString>;
31
+ /** Required environment variable names (user must set these) */
32
+ env: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
33
+ /** Whether the agent requires a workspace directory */
34
+ workspace: z.ZodOptional<z.ZodBoolean>;
35
+ /** Whether the agent requires Docker */
36
+ docker: z.ZodOptional<z.ZodBoolean>;
37
+ }, "strict", z.ZodTypeAny, {
38
+ env?: string[] | undefined;
39
+ docker?: boolean | undefined;
40
+ runtime?: string | undefined;
41
+ workspace?: boolean | undefined;
42
+ herdctl?: string | undefined;
43
+ }, {
44
+ env?: string[] | undefined;
45
+ docker?: boolean | undefined;
46
+ runtime?: string | undefined;
47
+ workspace?: boolean | undefined;
48
+ herdctl?: string | undefined;
49
+ }>;
50
+ export type AgentRequires = z.infer<typeof AgentRequiresSchema>;
51
+ /**
52
+ * Schema for `herdctl.json` metadata files in agent repositories.
53
+ *
54
+ * This metadata is used for:
55
+ * - Registry listing and search
56
+ * - Installation validation
57
+ * - Displaying agent information
58
+ *
59
+ * @example
60
+ * ```json
61
+ * {
62
+ * "$schema": "https://herdctl.dev/schemas/agent-metadata.json",
63
+ * "name": "website-monitor",
64
+ * "version": "1.0.0",
65
+ * "description": "Monitor website uptime and send Discord alerts",
66
+ * "author": "herdctl-examples",
67
+ * "repository": "github:herdctl-examples/website-monitor-agent",
68
+ * "license": "MIT",
69
+ * "keywords": ["monitoring", "uptime", "alerts"],
70
+ * "requires": {
71
+ * "herdctl": ">=0.1.0",
72
+ * "runtime": "cli",
73
+ * "env": ["WEBSITES", "DISCORD_WEBHOOK_URL"],
74
+ * "workspace": true
75
+ * },
76
+ * "category": "operations",
77
+ * "tags": ["monitoring", "automation"]
78
+ * }
79
+ * ```
80
+ */
81
+ export declare const AgentRepoMetadataSchema: z.ZodObject<{
82
+ /** JSON schema URL for IDE validation (optional) */
83
+ $schema: z.ZodOptional<z.ZodString>;
84
+ /**
85
+ * Agent name - must match AGENT_NAME_PATTERN.
86
+ * This should match the `name` field in the agent's `agent.yaml`.
87
+ */
88
+ name: z.ZodString;
89
+ /** Agent version (semver format, e.g., "1.0.0") */
90
+ version: z.ZodString;
91
+ /** Human-readable description of what the agent does */
92
+ description: z.ZodString;
93
+ /** Author name or organization */
94
+ author: z.ZodString;
95
+ /** Source repository specifier (e.g., "github:user/repo") */
96
+ repository: z.ZodOptional<z.ZodString>;
97
+ /** Homepage URL */
98
+ homepage: z.ZodOptional<z.ZodString>;
99
+ /** SPDX license identifier (e.g., "MIT", "Apache-2.0") */
100
+ license: z.ZodOptional<z.ZodString>;
101
+ /** Keywords for search and discovery */
102
+ keywords: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
103
+ /** Requirements and dependencies */
104
+ requires: z.ZodOptional<z.ZodObject<{
105
+ /** Minimum herdctl version required (semver range, e.g., ">=0.1.0") */
106
+ herdctl: z.ZodOptional<z.ZodString>;
107
+ /** Runtime backend required (e.g., "cli" for Claude CLI) */
108
+ runtime: z.ZodOptional<z.ZodString>;
109
+ /** Required environment variable names (user must set these) */
110
+ env: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
111
+ /** Whether the agent requires a workspace directory */
112
+ workspace: z.ZodOptional<z.ZodBoolean>;
113
+ /** Whether the agent requires Docker */
114
+ docker: z.ZodOptional<z.ZodBoolean>;
115
+ }, "strict", z.ZodTypeAny, {
116
+ env?: string[] | undefined;
117
+ docker?: boolean | undefined;
118
+ runtime?: string | undefined;
119
+ workspace?: boolean | undefined;
120
+ herdctl?: string | undefined;
121
+ }, {
122
+ env?: string[] | undefined;
123
+ docker?: boolean | undefined;
124
+ runtime?: string | undefined;
125
+ workspace?: boolean | undefined;
126
+ herdctl?: string | undefined;
127
+ }>>;
128
+ /** Agent category for browsing (e.g., "operations", "development", "data") */
129
+ category: z.ZodOptional<z.ZodString>;
130
+ /** Tags for filtering (similar to keywords but for categorization) */
131
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
132
+ /** URLs to screenshot images for showcase */
133
+ screenshots: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
134
+ /** Example use cases as name-description pairs */
135
+ examples: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
136
+ }, "strict", z.ZodTypeAny, {
137
+ name: string;
138
+ description: string;
139
+ version: string;
140
+ author: string;
141
+ $schema?: string | undefined;
142
+ repository?: string | undefined;
143
+ homepage?: string | undefined;
144
+ license?: string | undefined;
145
+ keywords?: string[] | undefined;
146
+ requires?: {
147
+ env?: string[] | undefined;
148
+ docker?: boolean | undefined;
149
+ runtime?: string | undefined;
150
+ workspace?: boolean | undefined;
151
+ herdctl?: string | undefined;
152
+ } | undefined;
153
+ category?: string | undefined;
154
+ tags?: string[] | undefined;
155
+ screenshots?: string[] | undefined;
156
+ examples?: Record<string, string> | undefined;
157
+ }, {
158
+ name: string;
159
+ description: string;
160
+ version: string;
161
+ author: string;
162
+ $schema?: string | undefined;
163
+ repository?: string | undefined;
164
+ homepage?: string | undefined;
165
+ license?: string | undefined;
166
+ keywords?: string[] | undefined;
167
+ requires?: {
168
+ env?: string[] | undefined;
169
+ docker?: boolean | undefined;
170
+ runtime?: string | undefined;
171
+ workspace?: boolean | undefined;
172
+ herdctl?: string | undefined;
173
+ } | undefined;
174
+ category?: string | undefined;
175
+ tags?: string[] | undefined;
176
+ screenshots?: string[] | undefined;
177
+ examples?: Record<string, string> | undefined;
178
+ }>;
179
+ export type AgentRepoMetadata = z.infer<typeof AgentRepoMetadataSchema>;
180
+ export { AGENT_NAME_PATTERN };
181
+ //# sourceMappingURL=agent-repo-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-repo-metadata.d.ts","sourceRoot":"","sources":["../../src/distribution/agent-repo-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AA4BzD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;IAE5B,uEAAuE;;IAQvE,4DAA4D;;IAG5D,gEAAgE;;IAGhE,uDAAuD;;IAGvD,wCAAwC;;;;;;;;;;;;;;EAGjC,CAAC;AAEZ,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAMhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,uBAAuB;IAEhC,oDAAoD;;IAGpD;;;OAGG;;IAMH,mDAAmD;;IAKnD,wDAAwD;;IAGxD,kCAAkC;;IAGlC,6DAA6D;;IAG7D,mBAAmB;;IAGnB,0DAA0D;;IAG1D,wCAAwC;;IAGxC,oCAAoC;;QA/FpC,uEAAuE;;QAQvE,4DAA4D;;QAG5D,gEAAgE;;QAGhE,uDAAuD;;QAGvD,wCAAwC;;;;;;;;;;;;;;;IAiFxC,8EAA8E;;IAG9E,sEAAsE;;IAGtE,6CAA6C;;IAK7C,kDAAkD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG3C,CAAC;AAEZ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAMxE,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Agent Repository Metadata Schema (`herdctl.json`)
3
+ *
4
+ * Validates the metadata file that agent authors include in their repositories
5
+ * to describe their agent for registry listing and installation validation.
6
+ *
7
+ * This file is found at the root of an agent repository and provides:
8
+ * - Basic info: name, version, description, author
9
+ * - Source info: repository, homepage, license
10
+ * - Discovery: keywords, category, tags
11
+ * - Requirements: herdctl version, runtime, env vars, workspace, docker
12
+ * - Presentation: screenshots, examples
13
+ */
14
+ import { z } from "zod";
15
+ import { AGENT_NAME_PATTERN } from "../config/schema.js";
16
+ // =============================================================================
17
+ // Constants
18
+ // =============================================================================
19
+ /**
20
+ * Semver pattern for version validation.
21
+ * Matches versions like "1.0.0", "2.3.4-beta.1", "1.0.0+build.123"
22
+ */
23
+ const SEMVER_PATTERN = /^\d+\.\d+\.\d+(?:-[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?(?:\+[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?$/;
24
+ /**
25
+ * Semver range pattern for version constraints.
26
+ * Matches ranges like ">=1.0.0", "^2.0.0", "~1.2.3", "1.x", "*", ">=1.0.0 <2.0.0"
27
+ *
28
+ * This is a permissive pattern that accepts common semver range formats.
29
+ * Full semver range validation is complex; this pattern catches obvious errors
30
+ * while allowing valid npm-style version ranges.
31
+ */
32
+ const SEMVER_RANGE_PATTERN = /^(?:[~^<>=]*\d+(?:\.\d+(?:\.\d+)?)?(?:-[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?(?:\s+[<>=]+\d+(?:\.\d+(?:\.\d+)?)?(?:-[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?)*|\d+(?:\.\d+)?\.x(?:\.x)?|\*)$/;
33
+ // =============================================================================
34
+ // Requirements Schema
35
+ // =============================================================================
36
+ /**
37
+ * Requirements schema for agent dependencies and constraints.
38
+ *
39
+ * Specifies what the agent needs to run properly:
40
+ * - herdctl version compatibility
41
+ * - Runtime backend (cli, sdk)
42
+ * - Required environment variables
43
+ * - Workspace requirement
44
+ * - Docker requirement
45
+ */
46
+ export const AgentRequiresSchema = z
47
+ .object({
48
+ /** Minimum herdctl version required (semver range, e.g., ">=0.1.0") */
49
+ herdctl: z
50
+ .string()
51
+ .regex(SEMVER_RANGE_PATTERN, {
52
+ message: "herdctl version must be a valid semver range (e.g., '>=0.1.0', '^1.0.0')",
53
+ })
54
+ .optional(),
55
+ /** Runtime backend required (e.g., "cli" for Claude CLI) */
56
+ runtime: z.string().optional(),
57
+ /** Required environment variable names (user must set these) */
58
+ env: z.array(z.string()).optional(),
59
+ /** Whether the agent requires a workspace directory */
60
+ workspace: z.boolean().optional(),
61
+ /** Whether the agent requires Docker */
62
+ docker: z.boolean().optional(),
63
+ })
64
+ .strict();
65
+ // =============================================================================
66
+ // Agent Repository Metadata Schema
67
+ // =============================================================================
68
+ /**
69
+ * Schema for `herdctl.json` metadata files in agent repositories.
70
+ *
71
+ * This metadata is used for:
72
+ * - Registry listing and search
73
+ * - Installation validation
74
+ * - Displaying agent information
75
+ *
76
+ * @example
77
+ * ```json
78
+ * {
79
+ * "$schema": "https://herdctl.dev/schemas/agent-metadata.json",
80
+ * "name": "website-monitor",
81
+ * "version": "1.0.0",
82
+ * "description": "Monitor website uptime and send Discord alerts",
83
+ * "author": "herdctl-examples",
84
+ * "repository": "github:herdctl-examples/website-monitor-agent",
85
+ * "license": "MIT",
86
+ * "keywords": ["monitoring", "uptime", "alerts"],
87
+ * "requires": {
88
+ * "herdctl": ">=0.1.0",
89
+ * "runtime": "cli",
90
+ * "env": ["WEBSITES", "DISCORD_WEBHOOK_URL"],
91
+ * "workspace": true
92
+ * },
93
+ * "category": "operations",
94
+ * "tags": ["monitoring", "automation"]
95
+ * }
96
+ * ```
97
+ */
98
+ export const AgentRepoMetadataSchema = z
99
+ .object({
100
+ /** JSON schema URL for IDE validation (optional) */
101
+ $schema: z.string().optional(),
102
+ /**
103
+ * Agent name - must match AGENT_NAME_PATTERN.
104
+ * This should match the `name` field in the agent's `agent.yaml`.
105
+ */
106
+ name: z.string().regex(AGENT_NAME_PATTERN, {
107
+ message: "Agent name must start with a letter or number and contain only letters, numbers, underscores, and hyphens",
108
+ }),
109
+ /** Agent version (semver format, e.g., "1.0.0") */
110
+ version: z.string().regex(SEMVER_PATTERN, {
111
+ message: "Version must be a valid semver string (e.g., '1.0.0', '2.3.4-beta.1')",
112
+ }),
113
+ /** Human-readable description of what the agent does */
114
+ description: z.string().min(1, { message: "Description cannot be empty" }),
115
+ /** Author name or organization */
116
+ author: z.string().min(1, { message: "Author cannot be empty" }),
117
+ /** Source repository specifier (e.g., "github:user/repo") */
118
+ repository: z.string().optional(),
119
+ /** Homepage URL */
120
+ homepage: z.string().url({ message: "Homepage must be a valid URL" }).optional(),
121
+ /** SPDX license identifier (e.g., "MIT", "Apache-2.0") */
122
+ license: z.string().optional(),
123
+ /** Keywords for search and discovery */
124
+ keywords: z.array(z.string()).optional(),
125
+ /** Requirements and dependencies */
126
+ requires: AgentRequiresSchema.optional(),
127
+ /** Agent category for browsing (e.g., "operations", "development", "data") */
128
+ category: z.string().optional(),
129
+ /** Tags for filtering (similar to keywords but for categorization) */
130
+ tags: z.array(z.string()).optional(),
131
+ /** URLs to screenshot images for showcase */
132
+ screenshots: z
133
+ .array(z.string().url({ message: "Screenshot URLs must be valid URLs" }))
134
+ .optional(),
135
+ /** Example use cases as name-description pairs */
136
+ examples: z.record(z.string(), z.string()).optional(),
137
+ })
138
+ .strict();
139
+ // =============================================================================
140
+ // Re-export AGENT_NAME_PATTERN for convenience
141
+ // =============================================================================
142
+ export { AGENT_NAME_PATTERN };
143
+ //# sourceMappingURL=agent-repo-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-repo-metadata.js","sourceRoot":"","sources":["../../src/distribution/agent-repo-metadata.ts"],"names":[],"mappings":"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"}