agentcn 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.
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const node_fs_1 = require("node:fs");
8
+ const node_os_1 = require("node:os");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const node_test_1 = __importDefault(require("node:test"));
11
+ const add_js_1 = require("../commands/add.js");
12
+ function createRegistry(registryDir) {
13
+ (0, node_fs_1.mkdirSync)(registryDir, { recursive: true });
14
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(registryDir, "index.json"), JSON.stringify({
15
+ schemaVersion: 1,
16
+ name: "agentcn",
17
+ items: [{ name: "file-agent", description: "File agent" }],
18
+ }, null, 2), "utf-8");
19
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(registryDir, "file-agent.json"), JSON.stringify({
20
+ schemaVersion: 1,
21
+ name: "file-agent",
22
+ type: "registry:agent",
23
+ description: "File agent",
24
+ dependencies: [],
25
+ envVars: { ANTHROPIC_API_KEY: "" },
26
+ files: [
27
+ {
28
+ path: "ai/agents/file-agent/index.ts",
29
+ type: "registry:agent",
30
+ content: "export const ok = true;\n",
31
+ },
32
+ ],
33
+ }, null, 2), "utf-8");
34
+ }
35
+ (0, node_test_1.default)("runAddCommand applies files for local path registry", async () => {
36
+ const root = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-add-local-"));
37
+ const projectDir = node_path_1.default.join(root, "project");
38
+ const registryDir = node_path_1.default.join(root, "registry");
39
+ (0, node_fs_1.mkdirSync)(projectDir, { recursive: true });
40
+ createRegistry(registryDir);
41
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(projectDir, "tsconfig.json"), "{}", "utf-8");
42
+ try {
43
+ await (0, add_js_1.runAddCommand)("file-agent", {
44
+ registry: registryDir,
45
+ cwd: projectDir,
46
+ yes: true,
47
+ });
48
+ const target = node_path_1.default.join(projectDir, "ai/agents/file-agent/index.ts");
49
+ const content = (0, node_fs_1.readFileSync)(target, "utf-8");
50
+ strict_1.default.equal(content.includes("ok = true"), true);
51
+ }
52
+ finally {
53
+ (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
54
+ }
55
+ });
56
+ (0, node_test_1.default)("runAddCommand dry-run does not write files", async () => {
57
+ const root = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-add-dry-"));
58
+ const projectDir = node_path_1.default.join(root, "project");
59
+ const registryDir = node_path_1.default.join(root, "registry");
60
+ (0, node_fs_1.mkdirSync)(projectDir, { recursive: true });
61
+ createRegistry(registryDir);
62
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(projectDir, "tsconfig.json"), "{}", "utf-8");
63
+ try {
64
+ await (0, add_js_1.runAddCommand)("file-agent", {
65
+ registry: registryDir,
66
+ cwd: projectDir,
67
+ dryRun: true,
68
+ yes: true,
69
+ });
70
+ const target = node_path_1.default.join(projectDir, "ai/agents/file-agent/index.ts");
71
+ strict_1.default.equal((() => {
72
+ try {
73
+ (0, node_fs_1.readFileSync)(target, "utf-8");
74
+ return true;
75
+ }
76
+ catch {
77
+ return false;
78
+ }
79
+ })(), false);
80
+ }
81
+ finally {
82
+ (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
83
+ }
84
+ });
85
+ (0, node_test_1.default)("runAddCommand supports alias agent name", async () => {
86
+ const root = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-add-alias-"));
87
+ const projectDir = node_path_1.default.join(root, "project");
88
+ const registryDir = node_path_1.default.join(root, "registry");
89
+ (0, node_fs_1.mkdirSync)(projectDir, { recursive: true });
90
+ createRegistry(registryDir);
91
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(projectDir, "tsconfig.json"), "{}", "utf-8");
92
+ try {
93
+ await (0, add_js_1.runAddCommand)("fileagent", {
94
+ registry: registryDir,
95
+ cwd: projectDir,
96
+ yes: true,
97
+ });
98
+ const target = node_path_1.default.join(projectDir, "ai/agents/file-agent/index.ts");
99
+ const content = (0, node_fs_1.readFileSync)(target, "utf-8");
100
+ strict_1.default.equal(content.includes("ok = true"), true);
101
+ }
102
+ finally {
103
+ (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
104
+ }
105
+ });
106
+ (0, node_test_1.default)("runAddCommand in --yes mode skips interactive prompts", async () => {
107
+ const root = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-add-yes-"));
108
+ const projectDir = node_path_1.default.join(root, "project");
109
+ const registryDir = node_path_1.default.join(root, "registry");
110
+ (0, node_fs_1.mkdirSync)(projectDir, { recursive: true });
111
+ createRegistry(registryDir);
112
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(projectDir, "tsconfig.json"), "{}", "utf-8");
113
+ const existingTarget = node_path_1.default.join(projectDir, "ai/agents/file-agent/index.ts");
114
+ (0, node_fs_1.mkdirSync)(node_path_1.default.dirname(existingTarget), { recursive: true });
115
+ (0, node_fs_1.writeFileSync)(existingTarget, "export const existing = true;\n", "utf-8");
116
+ let promptCalls = 0;
117
+ const confirm = async () => {
118
+ promptCalls += 1;
119
+ return false;
120
+ };
121
+ try {
122
+ await (0, add_js_1.runAddCommand)("file-agent", {
123
+ registry: registryDir,
124
+ cwd: projectDir,
125
+ dryRun: true,
126
+ yes: true,
127
+ }, { confirm });
128
+ strict_1.default.equal(promptCalls, 0);
129
+ }
130
+ finally {
131
+ (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
132
+ }
133
+ });
134
+ (0, node_test_1.default)("runAddCommand prompts for overwrite when conflicts exist", async () => {
135
+ const root = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-add-prompt-"));
136
+ const projectDir = node_path_1.default.join(root, "project");
137
+ const registryDir = node_path_1.default.join(root, "registry");
138
+ (0, node_fs_1.mkdirSync)(projectDir, { recursive: true });
139
+ createRegistry(registryDir);
140
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(projectDir, "tsconfig.json"), "{}", "utf-8");
141
+ const existingTarget = node_path_1.default.join(projectDir, "ai/agents/file-agent/index.ts");
142
+ (0, node_fs_1.mkdirSync)(node_path_1.default.dirname(existingTarget), { recursive: true });
143
+ (0, node_fs_1.writeFileSync)(existingTarget, "export const existing = true;\n", "utf-8");
144
+ const prompts = [];
145
+ const confirm = async (message) => {
146
+ prompts.push(message);
147
+ return false;
148
+ };
149
+ try {
150
+ await (0, add_js_1.runAddCommand)("file-agent", {
151
+ registry: registryDir,
152
+ cwd: projectDir,
153
+ }, { confirm });
154
+ strict_1.default.equal(prompts.some((message) => message.includes("Overwrite")), true);
155
+ }
156
+ finally {
157
+ (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
158
+ }
159
+ });
160
+ (0, node_test_1.default)("runAddCommand prints structured output sections", async () => {
161
+ const root = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-add-output-"));
162
+ const projectDir = node_path_1.default.join(root, "project");
163
+ const registryDir = node_path_1.default.join(root, "registry");
164
+ (0, node_fs_1.mkdirSync)(projectDir, { recursive: true });
165
+ createRegistry(registryDir);
166
+ (0, node_fs_1.writeFileSync)(node_path_1.default.join(projectDir, "tsconfig.json"), "{}", "utf-8");
167
+ const logs = [];
168
+ const originalLog = console.log;
169
+ console.log = (...args) => {
170
+ logs.push(args.map(String).join(" "));
171
+ };
172
+ try {
173
+ await (0, add_js_1.runAddCommand)("file-agent", {
174
+ registry: registryDir,
175
+ cwd: projectDir,
176
+ dryRun: true,
177
+ yes: true,
178
+ });
179
+ const output = logs.join("\n");
180
+ strict_1.default.equal(output.includes("Resolving registry"), true);
181
+ strict_1.default.equal(output.includes("Plan summary"), true);
182
+ strict_1.default.equal(output.includes("Config updates"), true);
183
+ strict_1.default.equal(output.includes("Installing dependencies"), true);
184
+ strict_1.default.equal(output.includes("Next steps:"), true);
185
+ }
186
+ finally {
187
+ console.log = originalLog;
188
+ (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
189
+ }
190
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const node_fs_1 = require("node:fs");
8
+ const node_os_1 = require("node:os");
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ const node_test_1 = __importDefault(require("node:test"));
11
+ const config_js_1 = require("../lib/config.js");
12
+ (0, node_test_1.default)("mergeEnvContent appends only missing env keys", () => {
13
+ const existing = "EXISTING_KEY=value\nANTHROPIC_API_KEY=already";
14
+ const { content, added } = (0, config_js_1.mergeEnvContent)(existing, {
15
+ ANTHROPIC_API_KEY: "",
16
+ NEW_KEY: "abc",
17
+ });
18
+ strict_1.default.deepEqual(added, ["NEW_KEY"]);
19
+ strict_1.default.equal(content.includes("NEW_KEY=abc"), true);
20
+ strict_1.default.equal(content.includes("ANTHROPIC_API_KEY=already"), true);
21
+ });
22
+ (0, node_test_1.default)("updateTsconfigPaths adds ai aliases", () => {
23
+ const dir = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-tsconfig-"));
24
+ try {
25
+ const tsconfigPath = node_path_1.default.join(dir, "tsconfig.json");
26
+ (0, node_fs_1.writeFileSync)(tsconfigPath, JSON.stringify({ compilerOptions: { strict: true } }, null, 2), "utf-8");
27
+ const changed = (0, config_js_1.updateTsconfigPaths)(dir, { dryRun: false });
28
+ strict_1.default.equal(changed, true);
29
+ const updated = JSON.parse((0, node_fs_1.readFileSync)(tsconfigPath, "utf-8"));
30
+ strict_1.default.deepEqual(updated.compilerOptions.paths["@/agents/*"], [
31
+ "./ai/agents/*",
32
+ ]);
33
+ strict_1.default.deepEqual(updated.compilerOptions.paths["@/tools/*"], [
34
+ "./ai/tools/*",
35
+ ]);
36
+ }
37
+ finally {
38
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
39
+ }
40
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const node_test_1 = __importDefault(require("node:test"));
8
+ const deps_js_1 = require("../lib/deps.js");
9
+ (0, node_test_1.default)("getExecErrorOutput includes stdout and stderr", () => {
10
+ const message = (0, deps_js_1.getExecErrorOutput)({
11
+ message: "Command failed",
12
+ stdout: "ERR_PNPM_ADDING_TO_ROOT",
13
+ stderr: "",
14
+ });
15
+ strict_1.default.equal(message.includes("Command failed"), true);
16
+ strict_1.default.equal(message.includes("ERR_PNPM_ADDING_TO_ROOT"), true);
17
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const node_fs_1 = require("node:fs");
8
+ const node_http_1 = require("node:http");
9
+ const node_os_1 = require("node:os");
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const node_test_1 = __importDefault(require("node:test"));
12
+ const registry_js_1 = require("../lib/registry.js");
13
+ (0, node_test_1.default)("loads registry index and item from URL", async () => {
14
+ const index = {
15
+ schemaVersion: 1,
16
+ name: "agentcn",
17
+ items: [{ name: "file-agent", description: "File agent" }],
18
+ };
19
+ const item = {
20
+ schemaVersion: 1,
21
+ name: "file-agent",
22
+ type: "registry:agent",
23
+ description: "File agent",
24
+ files: [],
25
+ };
26
+ const server = (0, node_http_1.createServer)((req, res) => {
27
+ res.setHeader("Content-Type", "application/json");
28
+ if (req.url === "/index.json") {
29
+ res.end(JSON.stringify(index));
30
+ return;
31
+ }
32
+ if (req.url === "/file-agent.json") {
33
+ res.end(JSON.stringify(item));
34
+ return;
35
+ }
36
+ res.statusCode = 404;
37
+ res.end("{}");
38
+ });
39
+ await new Promise((resolve) => server.listen(0, resolve));
40
+ const address = server.address();
41
+ if (!address || typeof address === "string") {
42
+ server.close();
43
+ throw new Error("Failed to get server port");
44
+ }
45
+ const baseUrl = `http://127.0.0.1:${address.port}`;
46
+ try {
47
+ const loadedIndex = await (0, registry_js_1.loadRegistryIndex)(baseUrl);
48
+ const loadedItem = await (0, registry_js_1.loadRegistryItem)("file-agent", baseUrl);
49
+ strict_1.default.equal(loadedIndex.items.length, 1);
50
+ strict_1.default.equal(loadedItem.name, "file-agent");
51
+ }
52
+ finally {
53
+ server.close();
54
+ }
55
+ });
56
+ (0, node_test_1.default)("uses env registry URL when provided", () => {
57
+ const previous = process.env.AGENTCN_REGISTRY_URL;
58
+ process.env.AGENTCN_REGISTRY_URL = "http://localhost:3000/r";
59
+ try {
60
+ const source = (0, registry_js_1.resolveRegistrySource)(undefined, process.cwd());
61
+ strict_1.default.equal(source, "http://localhost:3000/r");
62
+ }
63
+ finally {
64
+ if (previous === undefined) {
65
+ delete process.env.AGENTCN_REGISTRY_URL;
66
+ }
67
+ else {
68
+ process.env.AGENTCN_REGISTRY_URL = previous;
69
+ }
70
+ }
71
+ });
72
+ (0, node_test_1.default)("registry arg path takes precedence over env", () => {
73
+ const previous = process.env.AGENTCN_REGISTRY_URL;
74
+ const tempDir = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), "agentcn-registry-"));
75
+ process.env.AGENTCN_REGISTRY_URL = "https://agentcn.dev/r";
76
+ try {
77
+ const source = (0, registry_js_1.resolveRegistrySource)(tempDir, process.cwd());
78
+ strict_1.default.equal(source, tempDir);
79
+ }
80
+ finally {
81
+ (0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
82
+ if (previous === undefined) {
83
+ delete process.env.AGENTCN_REGISTRY_URL;
84
+ }
85
+ else {
86
+ process.env.AGENTCN_REGISTRY_URL = previous;
87
+ }
88
+ }
89
+ });
90
+ (0, node_test_1.default)("uses local bundled registry path or production fallback", () => {
91
+ const previous = process.env.AGENTCN_REGISTRY_URL;
92
+ delete process.env.AGENTCN_REGISTRY_URL;
93
+ try {
94
+ const source = (0, registry_js_1.resolveRegistrySource)(undefined, process.cwd());
95
+ strict_1.default.ok(source === "https://agentcn.dev/r" ||
96
+ source.endsWith("/apps/web/public/r"));
97
+ }
98
+ finally {
99
+ if (previous !== undefined) {
100
+ process.env.AGENTCN_REGISTRY_URL = previous;
101
+ }
102
+ }
103
+ });
104
+ (0, node_test_1.default)("throws on schema mismatch", async () => {
105
+ const server = (0, node_http_1.createServer)((_req, res) => {
106
+ res.setHeader("Content-Type", "application/json");
107
+ res.end(JSON.stringify({
108
+ schemaVersion: 2,
109
+ name: "agentcn",
110
+ items: [],
111
+ }));
112
+ });
113
+ await new Promise((resolve) => server.listen(0, resolve));
114
+ const address = server.address();
115
+ if (!address || typeof address === "string") {
116
+ server.close();
117
+ throw new Error("Failed to get server port");
118
+ }
119
+ try {
120
+ await strict_1.default.rejects(() => (0, registry_js_1.loadRegistryIndex)(`http://127.0.0.1:${address.port}`), /Registry schema mismatch/);
121
+ }
122
+ finally {
123
+ server.close();
124
+ }
125
+ });
126
+ (0, node_test_1.default)("throws on malformed index payload", async () => {
127
+ const server = (0, node_http_1.createServer)((_req, res) => {
128
+ res.setHeader("Content-Type", "application/json");
129
+ res.end(JSON.stringify({ schemaVersion: 1 }));
130
+ });
131
+ await new Promise((resolve) => server.listen(0, resolve));
132
+ const address = server.address();
133
+ if (!address || typeof address === "string") {
134
+ server.close();
135
+ throw new Error("Failed to get server port");
136
+ }
137
+ try {
138
+ await strict_1.default.rejects(() => (0, registry_js_1.loadRegistryIndex)(`http://127.0.0.1:${address.port}`), /name|items/);
139
+ }
140
+ finally {
141
+ server.close();
142
+ }
143
+ });
@@ -0,0 +1,51 @@
1
+ export type RegistryFile = {
2
+ path: string;
3
+ type: string;
4
+ target?: string;
5
+ content: string;
6
+ };
7
+ export type RegistryItem = {
8
+ schemaVersion: number;
9
+ name: string;
10
+ type: string;
11
+ description: string;
12
+ title?: string;
13
+ categories?: string[];
14
+ dependencies?: string[];
15
+ envVars?: Record<string, string>;
16
+ files: RegistryFile[];
17
+ };
18
+ export type RegistryIndexItem = {
19
+ name: string;
20
+ description: string;
21
+ categories?: string[];
22
+ };
23
+ export type RegistryIndex = {
24
+ schemaVersion: number;
25
+ name: string;
26
+ homepage?: string;
27
+ items: RegistryIndexItem[];
28
+ };
29
+ export type AddOptionsInput = {
30
+ registry?: string;
31
+ dryRun?: boolean;
32
+ overwrite?: boolean;
33
+ yes?: boolean;
34
+ verbose?: boolean;
35
+ cwd?: string;
36
+ };
37
+ export type AddOptions = {
38
+ registry?: string;
39
+ dryRun: boolean;
40
+ overwrite: boolean;
41
+ yes: boolean;
42
+ verbose: boolean;
43
+ cwd: string;
44
+ };
45
+ export type PlannedFileAction = {
46
+ sourcePath: string;
47
+ targetPath: string;
48
+ absoluteTargetPath: string;
49
+ content: string;
50
+ action: "create" | "update" | "skip";
51
+ };
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export declare const logger: {
2
+ error(...args: unknown[]): void;
3
+ warn(...args: unknown[]): void;
4
+ info(...args: unknown[]): void;
5
+ success(...args: unknown[]): void;
6
+ break(): void;
7
+ };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logger = void 0;
4
+ exports.logger = {
5
+ error(...args) {
6
+ console.error(args.join(" "));
7
+ },
8
+ warn(...args) {
9
+ console.warn(args.join(" "));
10
+ },
11
+ info(...args) {
12
+ console.log(args.join(" "));
13
+ },
14
+ success(...args) {
15
+ console.log(args.join(" "));
16
+ },
17
+ break() {
18
+ console.log("");
19
+ },
20
+ };
@@ -0,0 +1 @@
1
+ export declare function confirmAction(message: string, defaultValue?: boolean): Promise<boolean>;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.confirmAction = confirmAction;
4
+ const promises_1 = require("node:readline/promises");
5
+ const node_process_1 = require("node:process");
6
+ async function confirmAction(message, defaultValue = true) {
7
+ const suffix = defaultValue ? "Y/n" : "y/N";
8
+ const rl = (0, promises_1.createInterface)({ input: node_process_1.stdin, output: node_process_1.stdout });
9
+ try {
10
+ const answer = (await rl.question(`${message} (${suffix}) `))
11
+ .trim()
12
+ .toLowerCase();
13
+ if (!answer)
14
+ return defaultValue;
15
+ return answer === "y" || answer === "yes";
16
+ }
17
+ finally {
18
+ rl.close();
19
+ }
20
+ }
@@ -0,0 +1,2 @@
1
+ import { type Options } from "ora";
2
+ export declare function spinner(text: Options["text"]): import("ora", { with: { "resolution-mode": "import" } }).Ora;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.spinner = spinner;
7
+ const ora_1 = __importDefault(require("ora"));
8
+ function spinner(text) {
9
+ return (0, ora_1.default)({ text });
10
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "agentcn",
3
+ "version": "0.1.0",
4
+ "description": "CLI to install AI agents into your project",
5
+ "bin": {
6
+ "agentcn": "dist/index.js"
7
+ },
8
+ "main": "dist/index.js",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "dependencies": {
13
+ "commander": "^12.1.0",
14
+ "ora": "^8.2.0",
15
+ "path-exists": "^5.0.0",
16
+ "zod": "^3.25.76"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^20.17.0",
20
+ "typescript": "~5.9.2"
21
+ },
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "dev": "tsc --watch",
31
+ "test": "pnpm run build && node --test dist/tests/**/*.test.js",
32
+ "pack:smoke": "pnpm run build && pnpm pack --pack-destination ./.artifacts"
33
+ }
34
+ }