@herdctl/core 5.5.0 → 5.7.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.
- package/dist/config/__tests__/merge.test.js +1 -1
- package/dist/config/__tests__/merge.test.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +10 -2
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +6 -2
- package/dist/config/schema.js.map +1 -1
- package/dist/distribution/__tests__/agent-discovery.test.d.ts +7 -0
- package/dist/distribution/__tests__/agent-discovery.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/agent-discovery.test.js +443 -0
- package/dist/distribution/__tests__/agent-discovery.test.js.map +1 -0
- package/dist/distribution/__tests__/agent-info.test.d.ts +7 -0
- package/dist/distribution/__tests__/agent-info.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/agent-info.test.js +568 -0
- package/dist/distribution/__tests__/agent-info.test.js.map +1 -0
- package/dist/distribution/__tests__/agent-remover.test.d.ts +7 -0
- package/dist/distribution/__tests__/agent-remover.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/agent-remover.test.js +498 -0
- package/dist/distribution/__tests__/agent-remover.test.js.map +1 -0
- package/dist/distribution/__tests__/agent-repo-metadata.test.d.ts +5 -0
- package/dist/distribution/__tests__/agent-repo-metadata.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/agent-repo-metadata.test.js +500 -0
- package/dist/distribution/__tests__/agent-repo-metadata.test.js.map +1 -0
- package/dist/distribution/__tests__/env-scanner.test.d.ts +5 -0
- package/dist/distribution/__tests__/env-scanner.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/env-scanner.test.js +576 -0
- package/dist/distribution/__tests__/env-scanner.test.js.map +1 -0
- package/dist/distribution/__tests__/file-installer.test.d.ts +7 -0
- package/dist/distribution/__tests__/file-installer.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/file-installer.test.js +714 -0
- package/dist/distribution/__tests__/file-installer.test.js.map +1 -0
- package/dist/distribution/__tests__/fleet-config-updater.test.d.ts +7 -0
- package/dist/distribution/__tests__/fleet-config-updater.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/fleet-config-updater.test.js +531 -0
- package/dist/distribution/__tests__/fleet-config-updater.test.js.map +1 -0
- package/dist/distribution/__tests__/installation-metadata.test.d.ts +2 -0
- package/dist/distribution/__tests__/installation-metadata.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/installation-metadata.test.js +292 -0
- package/dist/distribution/__tests__/installation-metadata.test.js.map +1 -0
- package/dist/distribution/__tests__/integration.test.d.ts +10 -0
- package/dist/distribution/__tests__/integration.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/integration.test.js +522 -0
- package/dist/distribution/__tests__/integration.test.js.map +1 -0
- package/dist/distribution/__tests__/repository-fetcher.test.d.ts +5 -0
- package/dist/distribution/__tests__/repository-fetcher.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/repository-fetcher.test.js +386 -0
- package/dist/distribution/__tests__/repository-fetcher.test.js.map +1 -0
- package/dist/distribution/__tests__/repository-validator.test.d.ts +7 -0
- package/dist/distribution/__tests__/repository-validator.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/repository-validator.test.js +447 -0
- package/dist/distribution/__tests__/repository-validator.test.js.map +1 -0
- package/dist/distribution/__tests__/source-specifier.test.d.ts +5 -0
- package/dist/distribution/__tests__/source-specifier.test.d.ts.map +1 -0
- package/dist/distribution/__tests__/source-specifier.test.js +533 -0
- package/dist/distribution/__tests__/source-specifier.test.js.map +1 -0
- package/dist/distribution/agent-discovery.d.ts +81 -0
- package/dist/distribution/agent-discovery.d.ts.map +1 -0
- package/dist/distribution/agent-discovery.js +264 -0
- package/dist/distribution/agent-discovery.js.map +1 -0
- package/dist/distribution/agent-info.d.ts +86 -0
- package/dist/distribution/agent-info.d.ts.map +1 -0
- package/dist/distribution/agent-info.js +225 -0
- package/dist/distribution/agent-info.js.map +1 -0
- package/dist/distribution/agent-remover.d.ts +83 -0
- package/dist/distribution/agent-remover.d.ts.map +1 -0
- package/dist/distribution/agent-remover.js +222 -0
- package/dist/distribution/agent-remover.js.map +1 -0
- package/dist/distribution/agent-repo-metadata.d.ts +181 -0
- package/dist/distribution/agent-repo-metadata.d.ts.map +1 -0
- package/dist/distribution/agent-repo-metadata.js +143 -0
- package/dist/distribution/agent-repo-metadata.js.map +1 -0
- package/dist/distribution/env-scanner.d.ts +78 -0
- package/dist/distribution/env-scanner.d.ts.map +1 -0
- package/dist/distribution/env-scanner.js +144 -0
- package/dist/distribution/env-scanner.js.map +1 -0
- package/dist/distribution/file-installer.d.ts +80 -0
- package/dist/distribution/file-installer.d.ts.map +1 -0
- package/dist/distribution/file-installer.js +268 -0
- package/dist/distribution/file-installer.js.map +1 -0
- package/dist/distribution/fleet-config-updater.d.ts +96 -0
- package/dist/distribution/fleet-config-updater.d.ts.map +1 -0
- package/dist/distribution/fleet-config-updater.js +266 -0
- package/dist/distribution/fleet-config-updater.js.map +1 -0
- package/dist/distribution/index.d.ts +23 -0
- package/dist/distribution/index.d.ts.map +1 -0
- package/dist/distribution/index.js +42 -0
- package/dist/distribution/index.js.map +1 -0
- package/dist/distribution/installation-metadata.d.ts +191 -0
- package/dist/distribution/installation-metadata.d.ts.map +1 -0
- package/dist/distribution/installation-metadata.js +100 -0
- package/dist/distribution/installation-metadata.js.map +1 -0
- package/dist/distribution/repository-fetcher.d.ts +104 -0
- package/dist/distribution/repository-fetcher.d.ts.map +1 -0
- package/dist/distribution/repository-fetcher.js +246 -0
- package/dist/distribution/repository-fetcher.js.map +1 -0
- package/dist/distribution/repository-validator.d.ts +86 -0
- package/dist/distribution/repository-validator.d.ts.map +1 -0
- package/dist/distribution/repository-validator.js +296 -0
- package/dist/distribution/repository-validator.js.map +1 -0
- package/dist/distribution/source-specifier.d.ts +106 -0
- package/dist/distribution/source-specifier.d.ts.map +1 -0
- package/dist/distribution/source-specifier.js +247 -0
- package/dist/distribution/source-specifier.js.map +1 -0
- package/dist/fleet-manager/errors.d.ts +15 -0
- package/dist/fleet-manager/errors.d.ts.map +1 -1
- package/dist/fleet-manager/errors.js +16 -0
- package/dist/fleet-manager/errors.js.map +1 -1
- package/dist/fleet-manager/fleet-manager.d.ts.map +1 -1
- package/dist/fleet-manager/fleet-manager.js +31 -9
- package/dist/fleet-manager/fleet-manager.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/runner/message-processor.d.ts.map +1 -1
- package/dist/runner/message-processor.js +7 -2
- package/dist/runner/message-processor.js.map +1 -1
- package/dist/runner/runtime/container-manager.js +1 -1
- package/dist/runner/runtime/container-manager.js.map +1 -1
- package/dist/scheduler/errors.d.ts +15 -0
- package/dist/scheduler/errors.d.ts.map +1 -1
- package/dist/scheduler/schedule-runner.d.ts.map +1 -1
- package/dist/scheduler/schedule-runner.js +6 -5
- package/dist/scheduler/schedule-runner.js.map +1 -1
- package/dist/state/__tests__/jsonl-parser.test.d.ts +5 -0
- package/dist/state/__tests__/jsonl-parser.test.d.ts.map +1 -0
- package/dist/state/__tests__/jsonl-parser.test.js +307 -0
- package/dist/state/__tests__/jsonl-parser.test.js.map +1 -0
- package/dist/state/__tests__/session-attribution.test.d.ts +2 -0
- package/dist/state/__tests__/session-attribution.test.d.ts.map +1 -0
- package/dist/state/__tests__/session-attribution.test.js +567 -0
- package/dist/state/__tests__/session-attribution.test.js.map +1 -0
- package/dist/state/__tests__/session-discovery.test.d.ts +2 -0
- package/dist/state/__tests__/session-discovery.test.d.ts.map +1 -0
- package/dist/state/__tests__/session-discovery.test.js +941 -0
- package/dist/state/__tests__/session-discovery.test.js.map +1 -0
- package/dist/state/__tests__/session-metadata.test.d.ts +2 -0
- package/dist/state/__tests__/session-metadata.test.d.ts.map +1 -0
- package/dist/state/__tests__/session-metadata.test.js +422 -0
- package/dist/state/__tests__/session-metadata.test.js.map +1 -0
- package/dist/state/__tests__/tool-parsing.test.d.ts +5 -0
- package/dist/state/__tests__/tool-parsing.test.d.ts.map +1 -0
- package/dist/state/__tests__/tool-parsing.test.js +315 -0
- package/dist/state/__tests__/tool-parsing.test.js.map +1 -0
- package/dist/state/index.d.ts +5 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +10 -0
- package/dist/state/index.js.map +1 -1
- package/dist/state/jsonl-parser.d.ts +115 -0
- package/dist/state/jsonl-parser.d.ts.map +1 -0
- package/dist/state/jsonl-parser.js +437 -0
- package/dist/state/jsonl-parser.js.map +1 -0
- package/dist/state/session-attribution.d.ts +35 -0
- package/dist/state/session-attribution.d.ts.map +1 -0
- package/dist/state/session-attribution.js +179 -0
- package/dist/state/session-attribution.js.map +1 -0
- package/dist/state/session-discovery.d.ts +188 -0
- package/dist/state/session-discovery.d.ts.map +1 -0
- package/dist/state/session-discovery.js +513 -0
- package/dist/state/session-discovery.js.map +1 -0
- package/dist/state/session-metadata.d.ts +186 -0
- package/dist/state/session-metadata.d.ts.map +1 -0
- package/dist/state/session-metadata.js +297 -0
- package/dist/state/session-metadata.js.map +1 -0
- package/dist/state/tool-parsing.d.ts +88 -0
- package/dist/state/tool-parsing.d.ts.map +1 -0
- package/dist/state/tool-parsing.js +199 -0
- package/dist/state/tool-parsing.js.map +1 -0
- 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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"}
|