@tankpkg/cli 0.10.4 → 0.10.6
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/bin/tank.js +86 -1
- package/dist/bin/tank.js.map +1 -1
- package/dist/{debug-logger-hFhzviBs.js → debug-logger-Dr14Gtjr.js} +2 -2
- package/dist/{debug-logger-hFhzviBs.js.map → debug-logger-Dr14Gtjr.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/package.json +2 -1
- package/package.json +2 -1
package/dist/bin/tank.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as VERSION, c as getConfigDir, i as USER_AGENT, n as flushLogs, o as logger, s as getConfig, t as authFlowLog, u as setConfig } from "../debug-logger-
|
|
2
|
+
import { a as VERSION, c as getConfigDir, i as USER_AGENT, n as flushLogs, o as logger, s as getConfig, t as authFlowLog, u as setConfig } from "../debug-logger-Dr14Gtjr.js";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import fs from "node:fs";
|
|
@@ -13,6 +13,8 @@ import ora from "ora";
|
|
|
13
13
|
import { create, extract } from "tar";
|
|
14
14
|
import open from "open";
|
|
15
15
|
import ignore from "ignore";
|
|
16
|
+
import { spawn } from "node:child_process";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
16
18
|
process.env.TANK_REGISTRY_URL;
|
|
17
19
|
const MANIFEST_FILENAME = "tank.json";
|
|
18
20
|
const LEGACY_MANIFEST_FILENAME = "skills.json";
|
|
@@ -2543,6 +2545,75 @@ function getGlobalSkillDir(homedir, skillName) {
|
|
|
2543
2545
|
return path.join(globalDir, skillName);
|
|
2544
2546
|
}
|
|
2545
2547
|
//#endregion
|
|
2548
|
+
//#region src/commands/run.ts
|
|
2549
|
+
const AGENTS_MODULE = "@tankpkg/vault/src/runner/agents";
|
|
2550
|
+
const RUNNER_MODULE = "@tankpkg/vault/src/runner/run";
|
|
2551
|
+
const SERVER_MODULE = "@tankpkg/vault/src/proxy/server";
|
|
2552
|
+
const VAULT_MODULE = "@tankpkg/vault/src/tokenizer/vault";
|
|
2553
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
2554
|
+
const BOOTSTRAP_PATH = path.resolve(__dirname, "..", "..", "..", "vault", "src", "proxy", "bootstrap.cjs");
|
|
2555
|
+
const PLACEHOLDER_REQUIRE = "--require tank-vault-proxy-bootstrap.js";
|
|
2556
|
+
async function runCommand(options) {
|
|
2557
|
+
const [agentsModule, runnerModule, serverModule, vaultModule] = await Promise.all([
|
|
2558
|
+
import(AGENTS_MODULE),
|
|
2559
|
+
import(RUNNER_MODULE),
|
|
2560
|
+
import(SERVER_MODULE),
|
|
2561
|
+
import(VAULT_MODULE)
|
|
2562
|
+
]);
|
|
2563
|
+
const { getAgentConfig, getSupportedAgentIds } = agentsModule;
|
|
2564
|
+
const { buildAgentEnv } = runnerModule;
|
|
2565
|
+
const { startProxy } = serverModule;
|
|
2566
|
+
const { VaultStore } = vaultModule;
|
|
2567
|
+
const config = getAgentConfig(options.agent);
|
|
2568
|
+
if (!config) {
|
|
2569
|
+
const supported = getSupportedAgentIds().join(", ");
|
|
2570
|
+
console.error(chalk.red(`Unknown agent: ${options.agent}`));
|
|
2571
|
+
console.error(`Supported agents: ${supported}`);
|
|
2572
|
+
process.exit(1);
|
|
2573
|
+
}
|
|
2574
|
+
const vault = new VaultStore();
|
|
2575
|
+
const proxy = await startProxy(vault);
|
|
2576
|
+
console.log(`Vault proxy started on port ${proxy.port}`);
|
|
2577
|
+
console.log(`Agent: ${config.name} (${config.runtime})`);
|
|
2578
|
+
console.log("Credentials will be detected from traffic");
|
|
2579
|
+
const env = buildAgentEnv(config.strategy, proxy.url, process.env);
|
|
2580
|
+
const bootstrapRequire = `--require ${BOOTSTRAP_PATH}`;
|
|
2581
|
+
if (env.NODE_OPTIONS?.includes(PLACEHOLDER_REQUIRE)) env.NODE_OPTIONS = env.NODE_OPTIONS.replace(PLACEHOLDER_REQUIRE, bootstrapRequire);
|
|
2582
|
+
if (options.verbose) {
|
|
2583
|
+
console.log(`Bootstrap: ${BOOTSTRAP_PATH}`);
|
|
2584
|
+
console.log(`Proxy URL: ${proxy.url}`);
|
|
2585
|
+
}
|
|
2586
|
+
const child = spawn(config.command, options.agentArgs ?? [], {
|
|
2587
|
+
env,
|
|
2588
|
+
stdio: "inherit"
|
|
2589
|
+
});
|
|
2590
|
+
let cleaningUp = false;
|
|
2591
|
+
const cleanupAndExit = async (code) => {
|
|
2592
|
+
if (cleaningUp) return;
|
|
2593
|
+
cleaningUp = true;
|
|
2594
|
+
process.off("SIGINT", onSigint);
|
|
2595
|
+
process.off("SIGTERM", onSigterm);
|
|
2596
|
+
vault.clear();
|
|
2597
|
+
await proxy.close();
|
|
2598
|
+
process.exit(code);
|
|
2599
|
+
};
|
|
2600
|
+
const onSigint = () => {
|
|
2601
|
+
child.kill("SIGINT");
|
|
2602
|
+
};
|
|
2603
|
+
const onSigterm = () => {
|
|
2604
|
+
child.kill("SIGTERM");
|
|
2605
|
+
};
|
|
2606
|
+
process.on("SIGINT", onSigint);
|
|
2607
|
+
process.on("SIGTERM", onSigterm);
|
|
2608
|
+
child.once("error", async (error) => {
|
|
2609
|
+
console.error(chalk.red(`Failed to launch agent: ${error.message}`));
|
|
2610
|
+
await cleanupAndExit(1);
|
|
2611
|
+
});
|
|
2612
|
+
child.once("exit", async (code, signal) => {
|
|
2613
|
+
await cleanupAndExit(typeof code === "number" ? code : signal ? 1 : 0);
|
|
2614
|
+
});
|
|
2615
|
+
}
|
|
2616
|
+
//#endregion
|
|
2546
2617
|
//#region src/commands/scan.ts
|
|
2547
2618
|
function verdictColor(verdict) {
|
|
2548
2619
|
switch (verdict) {
|
|
@@ -3383,6 +3454,20 @@ program.command("audit").description("Display security audit results for install
|
|
|
3383
3454
|
process.exit(1);
|
|
3384
3455
|
}
|
|
3385
3456
|
});
|
|
3457
|
+
program.command("run").description("Launch an agent with credential protection (vault proxy)").argument("<agent>", "Agent ID to launch").allowUnknownOption(true).allowExcessArguments(true).option("--verbose", "Print verbose vault proxy details").action(async (agent, opts, cmd) => {
|
|
3458
|
+
try {
|
|
3459
|
+
const agentArgs = cmd.args.slice(1);
|
|
3460
|
+
await runCommand({
|
|
3461
|
+
agent,
|
|
3462
|
+
verbose: opts.verbose,
|
|
3463
|
+
agentArgs
|
|
3464
|
+
});
|
|
3465
|
+
} catch (err) {
|
|
3466
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3467
|
+
console.error(`Run failed: ${msg}`);
|
|
3468
|
+
process.exit(1);
|
|
3469
|
+
}
|
|
3470
|
+
});
|
|
3386
3471
|
program.command("scan").description("Scan a local skill for security issues without publishing").option("-d, --directory <path>", "Directory to scan (default: current directory)").action(async (opts) => {
|
|
3387
3472
|
try {
|
|
3388
3473
|
await scanCommand({ directory: opts.directory });
|