agent-army 0.1.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/README.md +162 -0
- package/dist/adapters/api-adapter.d.ts +76 -0
- package/dist/adapters/api-adapter.js +251 -0
- package/dist/adapters/api-adapter.js.map +1 -0
- package/dist/adapters/cli-adapter.d.ts +15 -0
- package/dist/adapters/cli-adapter.js +207 -0
- package/dist/adapters/cli-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +22 -0
- package/dist/adapters/index.js +32 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/types.d.ts +135 -0
- package/dist/adapters/types.js +14 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/bin.d.ts +8 -0
- package/dist/bin.js +83 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/deploy.d.ts +7 -0
- package/dist/commands/deploy.js +13 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.d.ts +7 -0
- package/dist/commands/destroy.js +13 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.js +538 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +8 -0
- package/dist/commands/list.js +42 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/ssh.d.ts +9 -0
- package/dist/commands/ssh.js +101 -0
- package/dist/commands/ssh.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +13 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/validate.d.ts +7 -0
- package/dist/commands/validate.js +13 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/lib/config.d.ts +66 -0
- package/dist/lib/config.js +239 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +147 -0
- package/dist/lib/constants.js +307 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/exec.d.ts +22 -0
- package/dist/lib/exec.js +60 -0
- package/dist/lib/exec.js.map +1 -0
- package/dist/lib/prerequisites.d.ts +8 -0
- package/dist/lib/prerequisites.js +124 -0
- package/dist/lib/prerequisites.js.map +1 -0
- package/dist/lib/process.d.ts +18 -0
- package/dist/lib/process.js +37 -0
- package/dist/lib/process.js.map +1 -0
- package/dist/lib/pulumi.d.ts +39 -0
- package/dist/lib/pulumi.js +87 -0
- package/dist/lib/pulumi.js.map +1 -0
- package/dist/lib/tailscale.d.ts +24 -0
- package/dist/lib/tailscale.js +71 -0
- package/dist/lib/tailscale.js.map +1 -0
- package/dist/lib/ui.d.ts +27 -0
- package/dist/lib/ui.js +89 -0
- package/dist/lib/ui.js.map +1 -0
- package/dist/tools/deploy.d.ts +16 -0
- package/dist/tools/deploy.js +133 -0
- package/dist/tools/deploy.js.map +1 -0
- package/dist/tools/destroy.d.ts +16 -0
- package/dist/tools/destroy.js +186 -0
- package/dist/tools/destroy.js.map +1 -0
- package/dist/tools/index.d.ts +17 -0
- package/dist/tools/index.js +28 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/status.d.ts +16 -0
- package/dist/tools/status.js +213 -0
- package/dist/tools/status.js.map +1 -0
- package/dist/tools/validate.d.ts +16 -0
- package/dist/tools/validate.js +215 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/types.d.ts +50 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +32 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* agent-army ssh — SSH to agent by name/alias
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.sshCommand = sshCommand;
|
|
40
|
+
const p = __importStar(require("@clack/prompts"));
|
|
41
|
+
const config_1 = require("../lib/config");
|
|
42
|
+
const pulumi_1 = require("../lib/pulumi");
|
|
43
|
+
const constants_1 = require("../lib/constants");
|
|
44
|
+
const ui_1 = require("../lib/ui");
|
|
45
|
+
const child_process_1 = require("child_process");
|
|
46
|
+
async function sshCommand(agentNameOrAlias, commandArgs, opts) {
|
|
47
|
+
// Check for legacy config and offer migration
|
|
48
|
+
await (0, config_1.checkAndMigrateLegacy)();
|
|
49
|
+
// Resolve config name
|
|
50
|
+
let configName;
|
|
51
|
+
try {
|
|
52
|
+
configName = (0, config_1.resolveConfigName)(opts.config);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
(0, ui_1.exitWithError)(err.message);
|
|
56
|
+
}
|
|
57
|
+
// Load manifest
|
|
58
|
+
const manifest = (0, config_1.loadManifest)(configName);
|
|
59
|
+
if (!manifest) {
|
|
60
|
+
(0, ui_1.exitWithError)(`Config '${configName}' could not be loaded.`);
|
|
61
|
+
}
|
|
62
|
+
// Select stack
|
|
63
|
+
const stackResult = (0, pulumi_1.selectOrCreateStack)(manifest.stackName);
|
|
64
|
+
if (!stackResult.ok) {
|
|
65
|
+
(0, ui_1.exitWithError)(`Could not select Pulumi stack "${manifest.stackName}".`);
|
|
66
|
+
}
|
|
67
|
+
// Resolve agent name/alias
|
|
68
|
+
const query = agentNameOrAlias.toLowerCase();
|
|
69
|
+
const resolvedRole = constants_1.AGENT_ALIASES[query] ?? query;
|
|
70
|
+
// Find agent in manifest
|
|
71
|
+
const agent = manifest.agents.find((a) => a.role === resolvedRole ||
|
|
72
|
+
a.name === query ||
|
|
73
|
+
a.name === `agent-${query}` ||
|
|
74
|
+
a.displayName.toLowerCase() === query);
|
|
75
|
+
if (!agent) {
|
|
76
|
+
const validNames = manifest.agents
|
|
77
|
+
.map((a) => `${a.role}, ${a.displayName.toLowerCase()}, ${a.name}`)
|
|
78
|
+
.join("\n ");
|
|
79
|
+
(0, ui_1.exitWithError)(`Unknown agent: "${agentNameOrAlias}"\nValid identifiers (any of these work):\n ${validNames}`);
|
|
80
|
+
}
|
|
81
|
+
// Get tailnet DNS name
|
|
82
|
+
const tailnetDnsName = (0, pulumi_1.getConfig)("tailnetDnsName");
|
|
83
|
+
if (!tailnetDnsName) {
|
|
84
|
+
(0, ui_1.exitWithError)("Could not determine tailnet DNS name from Pulumi config.");
|
|
85
|
+
}
|
|
86
|
+
const tsHost = (0, constants_1.tailscaleHostname)(manifest.stackName, agent.name);
|
|
87
|
+
const sshHost = `${tsHost}.${tailnetDnsName}`;
|
|
88
|
+
const user = opts.user ?? constants_1.SSH_USER;
|
|
89
|
+
p.log.info(`Connecting to ${agent.displayName} (${sshHost})...`);
|
|
90
|
+
// Build SSH command
|
|
91
|
+
const sshArgs = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", `${user}@${sshHost}`];
|
|
92
|
+
if (commandArgs.length > 0) {
|
|
93
|
+
sshArgs.push(commandArgs.join(" "));
|
|
94
|
+
}
|
|
95
|
+
// Spawn interactive SSH
|
|
96
|
+
const child = (0, child_process_1.spawn)("ssh", sshArgs, { stdio: "inherit" });
|
|
97
|
+
child.on("close", (code) => {
|
|
98
|
+
process.exit(code ?? 0);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=ssh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../commands/ssh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-army status — Show agent statuses from stack outputs
|
|
3
|
+
*
|
|
4
|
+
* This command wraps the platform-agnostic statusTool with the CLI adapter.
|
|
5
|
+
*/
|
|
6
|
+
import { type StatusOptions } from "../tools";
|
|
7
|
+
export declare function statusCommand(opts: StatusOptions): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* agent-army status — Show agent statuses from stack outputs
|
|
4
|
+
*
|
|
5
|
+
* This command wraps the platform-agnostic statusTool with the CLI adapter.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.statusCommand = statusCommand;
|
|
9
|
+
const tools_1 = require("../tools");
|
|
10
|
+
async function statusCommand(opts) {
|
|
11
|
+
await (0, tools_1.statusTool)((0, tools_1.createCLIAdapter)(), opts);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../commands/status.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAIH,sCAEC;AAJD,oCAA4E;AAErE,KAAK,UAAU,aAAa,CAAC,IAAmB;IACrD,MAAM,IAAA,kBAAU,EAAC,IAAA,wBAAgB,GAAE,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-army validate — Health check agents via Tailscale SSH
|
|
3
|
+
*
|
|
4
|
+
* This command wraps the platform-agnostic validateTool with the CLI adapter.
|
|
5
|
+
*/
|
|
6
|
+
import { type ValidateOptions } from "../tools";
|
|
7
|
+
export declare function validateCommand(opts: ValidateOptions): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* agent-army validate — Health check agents via Tailscale SSH
|
|
4
|
+
*
|
|
5
|
+
* This command wraps the platform-agnostic validateTool with the CLI adapter.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.validateCommand = validateCommand;
|
|
9
|
+
const tools_1 = require("../tools");
|
|
10
|
+
async function validateCommand(opts) {
|
|
11
|
+
await (0, tools_1.validateTool)((0, tools_1.createCLIAdapter)(), opts);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../commands/validate.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAIH,0CAEC;AAJD,oCAAgF;AAEzE,KAAK,UAAU,eAAe,CAAC,IAAqB;IACzD,MAAM,IAAA,oBAAY,EAAC,IAAA,wBAAgB,GAAE,EAAE,IAAI,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load/save agent-army manifests from ~/.agent-army/configs/
|
|
3
|
+
*/
|
|
4
|
+
import type { ArmyManifest } from "../types";
|
|
5
|
+
/**
|
|
6
|
+
* Get the configs directory path (~/.agent-army/configs/)
|
|
7
|
+
*/
|
|
8
|
+
export declare function configsDir(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Ensure the configs directory exists
|
|
11
|
+
*/
|
|
12
|
+
export declare function ensureConfigsDir(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Get the path to a config file by name
|
|
15
|
+
*/
|
|
16
|
+
export declare function configPath(name: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Get the legacy manifest path (./agent-army.json in CWD)
|
|
19
|
+
*/
|
|
20
|
+
export declare function legacyManifestPath(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Copy a named config to ./agent-army.json so the Pulumi program can read it.
|
|
23
|
+
* The Pulumi program (index.ts) always reads from the project root manifest.
|
|
24
|
+
*/
|
|
25
|
+
export declare function syncManifestToProject(name: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Check if a legacy manifest exists in CWD
|
|
28
|
+
*/
|
|
29
|
+
export declare function legacyManifestExists(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Load a legacy manifest from CWD
|
|
32
|
+
*/
|
|
33
|
+
export declare function loadLegacyManifest(): ArmyManifest | null;
|
|
34
|
+
/**
|
|
35
|
+
* Check for legacy manifest and offer migration.
|
|
36
|
+
* Returns the migrated config name if migration occurred, null otherwise.
|
|
37
|
+
*/
|
|
38
|
+
export declare function checkAndMigrateLegacy(): Promise<string | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a config exists by name
|
|
41
|
+
*/
|
|
42
|
+
export declare function manifestExists(name: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Load a manifest by name. Returns null if not found or invalid.
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadManifest(name: string): ArmyManifest | null;
|
|
47
|
+
/**
|
|
48
|
+
* Save a manifest by name
|
|
49
|
+
*/
|
|
50
|
+
export declare function saveManifest(name: string, manifest: ArmyManifest): void;
|
|
51
|
+
/**
|
|
52
|
+
* List all saved config names
|
|
53
|
+
*/
|
|
54
|
+
export declare function listManifests(): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Delete a config by name. Returns true if deleted, false if not found.
|
|
57
|
+
*/
|
|
58
|
+
export declare function deleteManifest(name: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Resolve a config name: auto-selects if only one config exists,
|
|
61
|
+
* errors with list if ambiguous or none found.
|
|
62
|
+
* @param name Optional explicit config name
|
|
63
|
+
* @returns The resolved config name
|
|
64
|
+
* @throws Error if no configs exist or multiple configs exist without explicit name
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveConfigName(name?: string): string;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Load/save agent-army manifests from ~/.agent-army/configs/
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.configsDir = configsDir;
|
|
40
|
+
exports.ensureConfigsDir = ensureConfigsDir;
|
|
41
|
+
exports.configPath = configPath;
|
|
42
|
+
exports.legacyManifestPath = legacyManifestPath;
|
|
43
|
+
exports.syncManifestToProject = syncManifestToProject;
|
|
44
|
+
exports.legacyManifestExists = legacyManifestExists;
|
|
45
|
+
exports.loadLegacyManifest = loadLegacyManifest;
|
|
46
|
+
exports.checkAndMigrateLegacy = checkAndMigrateLegacy;
|
|
47
|
+
exports.manifestExists = manifestExists;
|
|
48
|
+
exports.loadManifest = loadManifest;
|
|
49
|
+
exports.saveManifest = saveManifest;
|
|
50
|
+
exports.listManifests = listManifests;
|
|
51
|
+
exports.deleteManifest = deleteManifest;
|
|
52
|
+
exports.resolveConfigName = resolveConfigName;
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const path = __importStar(require("path"));
|
|
55
|
+
const os = __importStar(require("os"));
|
|
56
|
+
const readline = __importStar(require("readline"));
|
|
57
|
+
const constants_1 = require("./constants");
|
|
58
|
+
/**
|
|
59
|
+
* Get the configs directory path (~/.agent-army/configs/)
|
|
60
|
+
*/
|
|
61
|
+
function configsDir() {
|
|
62
|
+
return path.join(os.homedir(), constants_1.CONFIG_DIR);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Ensure the configs directory exists
|
|
66
|
+
*/
|
|
67
|
+
function ensureConfigsDir() {
|
|
68
|
+
const dir = configsDir();
|
|
69
|
+
if (!fs.existsSync(dir)) {
|
|
70
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the path to a config file by name
|
|
75
|
+
*/
|
|
76
|
+
function configPath(name) {
|
|
77
|
+
return path.join(configsDir(), `${name}.json`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the legacy manifest path (./agent-army.json in CWD)
|
|
81
|
+
*/
|
|
82
|
+
function legacyManifestPath() {
|
|
83
|
+
return path.join(process.cwd(), constants_1.MANIFEST_FILE);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Copy a named config to ./agent-army.json so the Pulumi program can read it.
|
|
87
|
+
* The Pulumi program (index.ts) always reads from the project root manifest.
|
|
88
|
+
*/
|
|
89
|
+
function syncManifestToProject(name) {
|
|
90
|
+
const src = configPath(name);
|
|
91
|
+
const dest = legacyManifestPath();
|
|
92
|
+
fs.copyFileSync(src, dest);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if a legacy manifest exists in CWD
|
|
96
|
+
*/
|
|
97
|
+
function legacyManifestExists() {
|
|
98
|
+
return fs.existsSync(legacyManifestPath());
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Load a legacy manifest from CWD
|
|
102
|
+
*/
|
|
103
|
+
function loadLegacyManifest() {
|
|
104
|
+
const filePath = legacyManifestPath();
|
|
105
|
+
if (!fs.existsSync(filePath))
|
|
106
|
+
return null;
|
|
107
|
+
try {
|
|
108
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
109
|
+
return JSON.parse(raw);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
console.warn(`[config] Failed to load legacy manifest at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Prompt user for yes/no confirmation
|
|
118
|
+
*/
|
|
119
|
+
async function confirm(message) {
|
|
120
|
+
const rl = readline.createInterface({
|
|
121
|
+
input: process.stdin,
|
|
122
|
+
output: process.stdout,
|
|
123
|
+
});
|
|
124
|
+
return new Promise((resolve) => {
|
|
125
|
+
rl.question(`${message} [y/N] `, (answer) => {
|
|
126
|
+
rl.close();
|
|
127
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Check for legacy manifest and offer migration.
|
|
133
|
+
* Returns the migrated config name if migration occurred, null otherwise.
|
|
134
|
+
*/
|
|
135
|
+
async function checkAndMigrateLegacy() {
|
|
136
|
+
if (!legacyManifestExists())
|
|
137
|
+
return null;
|
|
138
|
+
const legacy = loadLegacyManifest();
|
|
139
|
+
if (!legacy)
|
|
140
|
+
return null;
|
|
141
|
+
console.log(`\nFound legacy config at ${legacyManifestPath()}`);
|
|
142
|
+
console.log(` Stack: ${legacy.stackName}`);
|
|
143
|
+
console.log(` Region: ${legacy.region}`);
|
|
144
|
+
console.log(` Agents: ${legacy.agents.length}`);
|
|
145
|
+
const shouldMigrate = await confirm("\nMigrate this config to ~/.agent-army/configs/?");
|
|
146
|
+
if (!shouldMigrate) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const configName = legacy.stackName;
|
|
150
|
+
saveManifest(configName, legacy);
|
|
151
|
+
console.log(`\nMigrated to: ${configPath(configName)}`);
|
|
152
|
+
const shouldDelete = await confirm("Delete the old ./agent-army.json file?");
|
|
153
|
+
if (shouldDelete) {
|
|
154
|
+
fs.unlinkSync(legacyManifestPath());
|
|
155
|
+
console.log("Deleted legacy config.");
|
|
156
|
+
}
|
|
157
|
+
return configName;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check if a config exists by name
|
|
161
|
+
*/
|
|
162
|
+
function manifestExists(name) {
|
|
163
|
+
return fs.existsSync(configPath(name));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Load a manifest by name. Returns null if not found or invalid.
|
|
167
|
+
*/
|
|
168
|
+
function loadManifest(name) {
|
|
169
|
+
const filePath = configPath(name);
|
|
170
|
+
if (!fs.existsSync(filePath))
|
|
171
|
+
return null;
|
|
172
|
+
try {
|
|
173
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
174
|
+
return JSON.parse(raw);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
console.warn(`[config] Failed to load manifest '${name}' at ${filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Save a manifest by name
|
|
183
|
+
*/
|
|
184
|
+
function saveManifest(name, manifest) {
|
|
185
|
+
ensureConfigsDir();
|
|
186
|
+
const filePath = configPath(name);
|
|
187
|
+
fs.writeFileSync(filePath, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* List all saved config names
|
|
191
|
+
*/
|
|
192
|
+
function listManifests() {
|
|
193
|
+
const dir = configsDir();
|
|
194
|
+
if (!fs.existsSync(dir))
|
|
195
|
+
return [];
|
|
196
|
+
return fs
|
|
197
|
+
.readdirSync(dir)
|
|
198
|
+
.filter((f) => f.endsWith(".json"))
|
|
199
|
+
.map((f) => f.replace(/\.json$/, ""))
|
|
200
|
+
.sort();
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Delete a config by name. Returns true if deleted, false if not found.
|
|
204
|
+
*/
|
|
205
|
+
function deleteManifest(name) {
|
|
206
|
+
const filePath = configPath(name);
|
|
207
|
+
if (!fs.existsSync(filePath))
|
|
208
|
+
return false;
|
|
209
|
+
fs.unlinkSync(filePath);
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Resolve a config name: auto-selects if only one config exists,
|
|
214
|
+
* errors with list if ambiguous or none found.
|
|
215
|
+
* @param name Optional explicit config name
|
|
216
|
+
* @returns The resolved config name
|
|
217
|
+
* @throws Error if no configs exist or multiple configs exist without explicit name
|
|
218
|
+
*/
|
|
219
|
+
function resolveConfigName(name) {
|
|
220
|
+
if (name) {
|
|
221
|
+
if (!manifestExists(name)) {
|
|
222
|
+
const available = listManifests();
|
|
223
|
+
if (available.length === 0) {
|
|
224
|
+
throw new Error(`Config '${name}' not found. No configs exist. Run 'agent-army init' to create one.`);
|
|
225
|
+
}
|
|
226
|
+
throw new Error(`Config '${name}' not found. Available configs:\n ${available.join("\n ")}`);
|
|
227
|
+
}
|
|
228
|
+
return name;
|
|
229
|
+
}
|
|
230
|
+
const configs = listManifests();
|
|
231
|
+
if (configs.length === 0) {
|
|
232
|
+
throw new Error("No configs found. Run 'agent-army init' to create one.");
|
|
233
|
+
}
|
|
234
|
+
if (configs.length === 1) {
|
|
235
|
+
return configs[0];
|
|
236
|
+
}
|
|
237
|
+
throw new Error(`Multiple configs found. Specify one with --config:\n ${configs.join("\n ")}`);
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants, preset definitions, aliases, and defaults
|
|
3
|
+
*/
|
|
4
|
+
/** Available preset agents */
|
|
5
|
+
export declare const PRESETS: {
|
|
6
|
+
readonly pm: {
|
|
7
|
+
readonly name: "agent-pm";
|
|
8
|
+
readonly displayName: "Juno";
|
|
9
|
+
readonly role: "pm";
|
|
10
|
+
readonly preset: "pm";
|
|
11
|
+
readonly volumeSize: 30;
|
|
12
|
+
readonly description: "Break down tickets, research, plan and sequence work, track progress, unblock teams";
|
|
13
|
+
};
|
|
14
|
+
readonly eng: {
|
|
15
|
+
readonly name: "agent-eng";
|
|
16
|
+
readonly displayName: "Titus";
|
|
17
|
+
readonly role: "eng";
|
|
18
|
+
readonly preset: "eng";
|
|
19
|
+
readonly volumeSize: 50;
|
|
20
|
+
readonly description: "Lead engineering, coding, shipping";
|
|
21
|
+
};
|
|
22
|
+
readonly tester: {
|
|
23
|
+
readonly name: "agent-tester";
|
|
24
|
+
readonly displayName: "Scout";
|
|
25
|
+
readonly role: "tester";
|
|
26
|
+
readonly preset: "tester";
|
|
27
|
+
readonly volumeSize: 30;
|
|
28
|
+
readonly description: "Quality assurance, verification, bug hunting";
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/** Map agent aliases to role keys */
|
|
32
|
+
export declare const AGENT_ALIASES: Record<string, string>;
|
|
33
|
+
/** Available cloud providers */
|
|
34
|
+
export declare const PROVIDERS: readonly [{
|
|
35
|
+
readonly value: "aws";
|
|
36
|
+
readonly label: "AWS";
|
|
37
|
+
readonly hint: "Amazon Web Services EC2 instances";
|
|
38
|
+
}, {
|
|
39
|
+
readonly value: "hetzner";
|
|
40
|
+
readonly label: "Hetzner";
|
|
41
|
+
readonly hint: "Hetzner Cloud servers (EU/US)";
|
|
42
|
+
}];
|
|
43
|
+
/** Common AWS regions for selection */
|
|
44
|
+
export declare const AWS_REGIONS: {
|
|
45
|
+
value: string;
|
|
46
|
+
label: string;
|
|
47
|
+
}[];
|
|
48
|
+
/** Hetzner Cloud locations */
|
|
49
|
+
export declare const HETZNER_LOCATIONS: {
|
|
50
|
+
value: string;
|
|
51
|
+
label: string;
|
|
52
|
+
}[];
|
|
53
|
+
/** Instance type options (AWS) */
|
|
54
|
+
export declare const INSTANCE_TYPES: {
|
|
55
|
+
value: string;
|
|
56
|
+
label: string;
|
|
57
|
+
}[];
|
|
58
|
+
/** Hetzner server types — EU locations (cx shared vCPU) */
|
|
59
|
+
export declare const HETZNER_SERVER_TYPES_EU: {
|
|
60
|
+
value: string;
|
|
61
|
+
label: string;
|
|
62
|
+
}[];
|
|
63
|
+
/** Hetzner server types — US locations (cpx shared vCPU, cx not available) */
|
|
64
|
+
export declare const HETZNER_SERVER_TYPES_US: {
|
|
65
|
+
value: string;
|
|
66
|
+
label: string;
|
|
67
|
+
}[];
|
|
68
|
+
/** US Hetzner locations (cx types not available) */
|
|
69
|
+
export declare const HETZNER_US_LOCATIONS: string[];
|
|
70
|
+
/** Get server type options for a Hetzner location */
|
|
71
|
+
export declare function hetznerServerTypes(location: string): {
|
|
72
|
+
value: string;
|
|
73
|
+
label: string;
|
|
74
|
+
}[];
|
|
75
|
+
/** Default SSH user for agent instances (Ubuntu 24.04 AMI default) */
|
|
76
|
+
export declare const SSH_USER = "ubuntu";
|
|
77
|
+
/** Estimated monthly cost per instance type (AWS) */
|
|
78
|
+
export declare const COST_ESTIMATES: Record<string, number>;
|
|
79
|
+
/** Estimated monthly cost per server type (Hetzner) */
|
|
80
|
+
export declare const HETZNER_COST_ESTIMATES: Record<string, number>;
|
|
81
|
+
/** Manifest filename */
|
|
82
|
+
export declare const MANIFEST_FILE = "agent-army.json";
|
|
83
|
+
/** Config directory under home (~/.agent-army/configs/) */
|
|
84
|
+
export declare const CONFIG_DIR = ".agent-army/configs";
|
|
85
|
+
/**
|
|
86
|
+
* Supported model providers with their API key prefixes and available models
|
|
87
|
+
*/
|
|
88
|
+
export declare const MODEL_PROVIDERS: {
|
|
89
|
+
readonly anthropic: {
|
|
90
|
+
readonly name: "Anthropic";
|
|
91
|
+
readonly envVar: "ANTHROPIC_API_KEY";
|
|
92
|
+
readonly keyPrefix: "sk-ant-";
|
|
93
|
+
readonly models: readonly [{
|
|
94
|
+
readonly value: "anthropic/claude-opus-4-6";
|
|
95
|
+
readonly label: "Claude Opus 4.6 (Recommended)";
|
|
96
|
+
}, {
|
|
97
|
+
readonly value: "anthropic/claude-sonnet-4-5";
|
|
98
|
+
readonly label: "Claude Sonnet 4.5";
|
|
99
|
+
}, {
|
|
100
|
+
readonly value: "anthropic/claude-haiku-4-5";
|
|
101
|
+
readonly label: "Claude Haiku 4.5";
|
|
102
|
+
}];
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Build the Tailscale hostname for an agent.
|
|
107
|
+
* Includes the stack name to avoid conflicts across deployments.
|
|
108
|
+
* Example: "dev-agent-pm", "prod-agent-eng"
|
|
109
|
+
*/
|
|
110
|
+
export declare function tailscaleHostname(stackName: string, agentName: string): string;
|
|
111
|
+
/** Key instructions for onboarding prompts */
|
|
112
|
+
export declare const KEY_INSTRUCTIONS: {
|
|
113
|
+
readonly anthropicApiKey: {
|
|
114
|
+
readonly title: "Anthropic API Key";
|
|
115
|
+
readonly steps: readonly ["To get your Anthropic API key:", "1. Go to https://console.anthropic.com/account/keys", "2. Click \"Create Key\"", "3. Copy the key (starts with sk-ant-)"];
|
|
116
|
+
};
|
|
117
|
+
readonly tailscaleAuthKey: {
|
|
118
|
+
readonly title: "Tailscale Auth Key";
|
|
119
|
+
readonly steps: readonly ["To get your Tailscale auth key:", "1. Go to https://login.tailscale.com/admin/settings/keys", "2. Click \"Generate auth key\"", "3. Enable \"Reusable\" AND \"Ephemeral\" — ephemeral nodes auto-remove when offline", "4. Copy the key (starts with tskey-auth-)"];
|
|
120
|
+
};
|
|
121
|
+
readonly tailscaleApiKey: {
|
|
122
|
+
readonly title: "Tailscale API Key (optional)";
|
|
123
|
+
readonly steps: readonly ["For reliable cleanup of Tailscale devices during destroy:", "1. Go to https://login.tailscale.com/admin/settings/keys", "2. Under \"API access tokens\", click \"Generate access token\"", "3. Copy the key (starts with tskey-api-)", "4. This is optional but recommended for clean teardowns"];
|
|
124
|
+
};
|
|
125
|
+
readonly tailnetDnsName: {
|
|
126
|
+
readonly title: "Tailnet DNS Name";
|
|
127
|
+
readonly steps: readonly ["To find your Tailnet DNS name:", "1. Go to https://login.tailscale.com/admin/dns", "2. Look for your tailnet name at the top", "3. It looks like \"tailXXXXX.ts.net\" or a custom domain"];
|
|
128
|
+
};
|
|
129
|
+
readonly slackCredentials: {
|
|
130
|
+
readonly title: "Slack App Setup";
|
|
131
|
+
readonly steps: readonly ["Create a Slack app for each agent using the manifest shown below:", "1. Go to https://api.slack.com/apps → \"Create New App\" → \"From a manifest\"", "2. Select your workspace, paste the JSON manifest, and create the app", "3. Go to \"OAuth & Permissions\" — copy the Bot Token (xoxb-...)", "4. Under \"Basic Information\" → \"App-Level Tokens\", generate a token", " with the connections:write scope — copy it (xapp-...)"];
|
|
132
|
+
};
|
|
133
|
+
readonly linearApiKey: {
|
|
134
|
+
readonly title: "Linear API Key";
|
|
135
|
+
readonly steps: readonly ["Create a separate Linear account for each agent:", "1. Invite you+agentname@domain.com to your Linear workspace", " (plus-addressing forwards to your inbox — no new email needed)", " Follow the link in the invite email to create the account and join the org", "2. Go to Settings → Security & Access → Personal API keys → \"New API key\"", "3. Copy the key (starts with lin_api_)"];
|
|
136
|
+
};
|
|
137
|
+
readonly githubToken: {
|
|
138
|
+
readonly title: "GitHub Token";
|
|
139
|
+
readonly steps: readonly ["To get a GitHub personal access token for gh CLI:", "1. Go to https://github.com/settings/tokens?type=beta", "2. Click \"Generate new token\" → Fine-grained token", "3. Select repositories, set expiration, and permissions (e.g., repo, read:org)", "4. Copy the token (starts with github_pat_ or ghp_)"];
|
|
140
|
+
};
|
|
141
|
+
readonly hcloudToken: {
|
|
142
|
+
readonly title: "Hetzner Cloud API Token";
|
|
143
|
+
readonly steps: readonly ["To get your Hetzner Cloud API token:", "1. Go to https://console.hetzner.cloud/", "2. Select your project (or create one)", "3. Go to Security → API Tokens", "4. Click \"Generate API Token\" with Read & Write permissions", "5. Copy the token"];
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
/** Generate a Slack app manifest JSON for a given agent */
|
|
147
|
+
export declare function slackAppManifest(agentName: string): string;
|