@nestbox-ai/cli 1.0.19 → 1.0.21
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/.github/workflows/generate-client.yml +34 -6
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/utils/agent.d.ts +0 -1
- package/dist/utils/agent.js +0 -48
- package/dist/utils/agent.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +9 -2
- package/src/utils/agent.ts +0 -57
- package/test/README.md +52 -0
- package/test/agent.test.ts +140 -0
- package/test/auth.test.ts +71 -0
- package/test/compute.test.ts +135 -0
- package/test/document.test.ts +217 -0
- package/test/image.test.ts +107 -0
- package/test/mocks.ts +122 -0
- package/test/projects.test.ts +108 -0
- package/test/setup.ts +121 -0
- package/tsconfig.json +3 -1
- package/vitest.config.d.ts +2 -0
- package/vitest.config.js +23 -0
- package/vitest.config.js.map +1 -0
- package/vitest.config.ts +21 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Test, Build and Publish Nestbox AI CLI Tools
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
@@ -9,7 +9,7 @@ permissions:
|
|
|
9
9
|
contents: write
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
|
-
|
|
12
|
+
test-and-publish:
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
|
|
15
15
|
steps:
|
|
@@ -21,6 +21,7 @@ jobs:
|
|
|
21
21
|
uses: actions/setup-node@v4
|
|
22
22
|
with:
|
|
23
23
|
node-version: '20'
|
|
24
|
+
cache: 'npm'
|
|
24
25
|
|
|
25
26
|
- name: Setup Node.js for npm Publish
|
|
26
27
|
uses: actions/setup-node@v4
|
|
@@ -28,15 +29,42 @@ jobs:
|
|
|
28
29
|
node-version: '20.x'
|
|
29
30
|
registry-url: 'https://registry.npmjs.org'
|
|
30
31
|
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: |
|
|
34
|
+
npm install --prefer-offline --no-audit
|
|
35
|
+
|
|
36
|
+
- name: Install platform-specific dependencies
|
|
37
|
+
run: |
|
|
38
|
+
# Install Linux-specific Rollup binary for vitest
|
|
39
|
+
npm install @rollup/rollup-linux-x64-gnu --no-save || echo "Warning: Could not install platform-specific Rollup binary"
|
|
40
|
+
continue-on-error: true
|
|
41
|
+
|
|
42
|
+
- name: Verify installation
|
|
43
|
+
run: |
|
|
44
|
+
npm list vitest --depth=0
|
|
45
|
+
node --version
|
|
46
|
+
npm --version
|
|
47
|
+
|
|
48
|
+
- name: Run tests
|
|
49
|
+
run: |
|
|
50
|
+
echo "Running tests..."
|
|
51
|
+
echo "Node.js version: $(node --version)"
|
|
52
|
+
echo "NPM version: $(npm --version)"
|
|
53
|
+
echo "Checking if vitest is available..."
|
|
54
|
+
npx vitest --version || echo "Vitest not found via npx"
|
|
55
|
+
npm run test:ci
|
|
56
|
+
echo "All tests passed! ✅"
|
|
57
|
+
|
|
31
58
|
- name: Update package version
|
|
32
59
|
run: |
|
|
33
60
|
new_version="1.0.${{ github.run_number }}"
|
|
34
61
|
jq ".version = \"$new_version\"" package.json > temp.json && mv temp.json package.json
|
|
35
62
|
echo "Updated version to $new_version"
|
|
36
63
|
|
|
37
|
-
- name: Build
|
|
38
|
-
run:
|
|
39
|
-
|
|
40
|
-
|
|
64
|
+
- name: Build project
|
|
65
|
+
run: npm run build
|
|
66
|
+
|
|
67
|
+
- name: Publish to npm
|
|
68
|
+
run: npm publish --access public --registry=https://registry.npmjs.org
|
|
41
69
|
env:
|
|
42
70
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/dist/index.js
CHANGED
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
5
7
|
const auth_1 = require("./commands/auth");
|
|
6
8
|
const projects_1 = require("./commands/projects");
|
|
7
9
|
const compute_1 = require("./commands/compute");
|
|
8
|
-
const agent_1 = require("./commands/agent");
|
|
9
10
|
const document_1 = require("./commands/document");
|
|
10
11
|
const image_1 = require("./commands/image");
|
|
12
|
+
const agent_1 = require("./commands/agent");
|
|
13
|
+
// Read version from package.json
|
|
14
|
+
const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../package.json'), 'utf8'));
|
|
11
15
|
// Setup the CLI program
|
|
12
16
|
const program = new commander_1.Command();
|
|
13
17
|
program
|
|
14
18
|
.name('nestbox')
|
|
15
19
|
.description('CLI tool for the Nestbox AI platform')
|
|
16
|
-
.version(
|
|
20
|
+
.version(packageJson.version);
|
|
17
21
|
// Register command groups
|
|
18
22
|
(0, auth_1.registerAuthCommands)(program);
|
|
19
23
|
(0, projects_1.registerProjectCommands)(program);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,2BAAkC;AAClC,+BAA4B;AAC5B,0CAAuD;AACvD,kDAA8D;AAC9D,gDAA4D;AAC5D,kDAA+D;AAC/D,4CAAyD;AACzD,4CAAyD;AAEzD,iCAAiC;AACjC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzF,wBAAwB;AACxB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,0BAA0B;AAC1B,IAAA,2BAAoB,EAAC,OAAO,CAAC,CAAC;AAC9B,IAAA,kCAAuB,EAAC,OAAO,CAAC,CAAC;AACjC,IAAA,gCAAsB,EAAC,OAAO,CAAC,CAAC;AAChC,IAAA,6BAAqB,EAAC,OAAO,CAAC,CAAC;AAC/B,IAAA,mCAAwB,EAAC,OAAO,CAAC,CAAC;AAClC,IAAA,6BAAqB,EAAC,OAAO,CAAC,CAAC;AAE/B,+BAA+B;AAC/B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5B,+CAA+C;AAC/C,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC"}
|
package/dist/utils/agent.d.ts
CHANGED
|
@@ -11,6 +11,5 @@ export interface TemplateInfo {
|
|
|
11
11
|
type: string;
|
|
12
12
|
}
|
|
13
13
|
export declare const TEMPLATES: Record<string, TemplateInfo>;
|
|
14
|
-
export declare function downloadFromGoogleDrive(fileId: string, outputPath: string): Promise<void>;
|
|
15
14
|
export declare function extractZip(zipPath: string, extractPath: string): void;
|
|
16
15
|
export declare function createNestboxConfig(projectPath: string, isTypeScript: boolean): void;
|
package/dist/utils/agent.js
CHANGED
|
@@ -51,7 +51,6 @@ exports.loadNestboxConfig = loadNestboxConfig;
|
|
|
51
51
|
exports.isTypeScriptProject = isTypeScriptProject;
|
|
52
52
|
exports.runPredeployScripts = runPredeployScripts;
|
|
53
53
|
exports.createZipFromDirectory = createZipFromDirectory;
|
|
54
|
-
exports.downloadFromGoogleDrive = downloadFromGoogleDrive;
|
|
55
54
|
exports.extractZip = extractZip;
|
|
56
55
|
exports.createNestboxConfig = createNestboxConfig;
|
|
57
56
|
const path_1 = __importDefault(require("path"));
|
|
@@ -62,7 +61,6 @@ const util_1 = require("util");
|
|
|
62
61
|
const child_process_1 = require("child_process");
|
|
63
62
|
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
64
63
|
const os = __importStar(require("os"));
|
|
65
|
-
const axios_1 = __importDefault(require("axios"));
|
|
66
64
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
67
65
|
function findProjectRoot() {
|
|
68
66
|
return __awaiter(this, arguments, void 0, function* (startDir = process.cwd()) {
|
|
@@ -129,36 +127,6 @@ function runPredeployScripts(scripts, projectRoot) {
|
|
|
129
127
|
}
|
|
130
128
|
});
|
|
131
129
|
}
|
|
132
|
-
// Function to create zip from directory excluding node_modules
|
|
133
|
-
// export function createZipFromDirectory(dirPath: any, excludePatterns = ['node_modules']) {
|
|
134
|
-
// const dirName = path.basename(dirPath);
|
|
135
|
-
// const zipFilePath = path.join(os.tmpdir(), `${dirName}_${Date.now()}.zip`);
|
|
136
|
-
// const zip = new AdmZip();
|
|
137
|
-
// // Function to recursively add files to zip
|
|
138
|
-
// function addFilesToZip(currentPath: any, relativePath = '') {
|
|
139
|
-
// const items = fs.readdirSync(currentPath);
|
|
140
|
-
// for (const item of items) {
|
|
141
|
-
// const itemPath = path.join(currentPath, item);
|
|
142
|
-
// const itemRelativePath = path.join(relativePath, item);
|
|
143
|
-
// // Check if item should be excluded
|
|
144
|
-
// if (excludePatterns.some(pattern =>
|
|
145
|
-
// typeof pattern === 'string' ? itemRelativePath === pattern || item === pattern :
|
|
146
|
-
// pattern.test(itemRelativePath)
|
|
147
|
-
// )) {
|
|
148
|
-
// continue;
|
|
149
|
-
// }
|
|
150
|
-
// const stats = fs.statSync(itemPath);
|
|
151
|
-
// if (stats.isDirectory()) {
|
|
152
|
-
// addFilesToZip(itemPath, itemRelativePath);
|
|
153
|
-
// } else {
|
|
154
|
-
// zip.addLocalFile(itemPath, path.dirname(itemRelativePath));
|
|
155
|
-
// }
|
|
156
|
-
// }
|
|
157
|
-
// }
|
|
158
|
-
// addFilesToZip(dirPath);
|
|
159
|
-
// zip.writeZip(zipFilePath);
|
|
160
|
-
// return zipFilePath;
|
|
161
|
-
// }
|
|
162
130
|
function createZipFromDirectory(dirPath, excludePatterns = ['node_modules', 'pnpm-lock.yaml', 'package-lock.json', 'yarn.lock']) {
|
|
163
131
|
const dirName = path_1.default.basename(dirPath);
|
|
164
132
|
const timestamp = Date.now();
|
|
@@ -224,22 +192,6 @@ exports.TEMPLATES = {
|
|
|
224
192
|
type: 'chatbot'
|
|
225
193
|
}
|
|
226
194
|
};
|
|
227
|
-
function downloadFromGoogleDrive(fileId, outputPath) {
|
|
228
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
229
|
-
const url = `https://drive.google.com/uc?export=download&id=${fileId}`;
|
|
230
|
-
const response = yield (0, axios_1.default)({
|
|
231
|
-
method: 'GET',
|
|
232
|
-
url: url,
|
|
233
|
-
responseType: 'stream',
|
|
234
|
-
});
|
|
235
|
-
const writer = fs_1.default.createWriteStream(outputPath);
|
|
236
|
-
response.data.pipe(writer);
|
|
237
|
-
return new Promise((resolve, reject) => {
|
|
238
|
-
writer.on('finish', resolve);
|
|
239
|
-
writer.on('error', reject);
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
195
|
// Helper function to extract zip file
|
|
244
196
|
function extractZip(zipPath, extractPath) {
|
|
245
197
|
const zip = new adm_zip_1.default(zipPath);
|
package/dist/utils/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,0CAeC;AAGD,8CAaC;AAGD,kDAaC;AAED,kDAqBC;
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestbox-ai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "The cli tools that helps developers to build agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"lint": "eslint src --ext .ts",
|
|
14
14
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
15
15
|
"test": "vitest",
|
|
16
|
+
"test:ci": "vitest run --reporter=verbose",
|
|
16
17
|
"coverage": "vitest run --coverage",
|
|
17
18
|
"clean": "rimraf dist"
|
|
18
19
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
|
|
2
3
|
import { Command } from 'commander';
|
|
4
|
+
import { readFileSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
3
6
|
import { registerAuthCommands } from './commands/auth';
|
|
4
7
|
import { registerProjectCommands } from './commands/projects';
|
|
5
8
|
import { registerComputeProgram } from './commands/compute';
|
|
6
|
-
import { registerAgentCommands } from './commands/agent';
|
|
7
9
|
import { registerDocumentCommands } from './commands/document';
|
|
8
10
|
import { registerImageCommands } from './commands/image';
|
|
11
|
+
import { registerAgentCommands } from './commands/agent';
|
|
12
|
+
|
|
13
|
+
// Read version from package.json
|
|
14
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
9
15
|
|
|
10
16
|
// Setup the CLI program
|
|
11
17
|
const program = new Command();
|
|
12
18
|
program
|
|
13
19
|
.name('nestbox')
|
|
14
20
|
.description('CLI tool for the Nestbox AI platform')
|
|
15
|
-
.version(
|
|
21
|
+
.version(packageJson.version);
|
|
16
22
|
|
|
17
23
|
// Register command groups
|
|
18
24
|
registerAuthCommands(program);
|
|
@@ -24,6 +30,7 @@ registerImageCommands(program);
|
|
|
24
30
|
|
|
25
31
|
// Parse command line arguments
|
|
26
32
|
program.parse(process.argv);
|
|
33
|
+
|
|
27
34
|
// Only show help if no arguments were provided
|
|
28
35
|
if (process.argv.length === 2) {
|
|
29
36
|
program.help();
|
package/src/utils/agent.ts
CHANGED
|
@@ -83,45 +83,6 @@ export async function runPredeployScripts(scripts: any, projectRoot: any) {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
// Function to create zip from directory excluding node_modules
|
|
87
|
-
// export function createZipFromDirectory(dirPath: any, excludePatterns = ['node_modules']) {
|
|
88
|
-
// const dirName = path.basename(dirPath);
|
|
89
|
-
// const zipFilePath = path.join(os.tmpdir(), `${dirName}_${Date.now()}.zip`);
|
|
90
|
-
|
|
91
|
-
// const zip = new AdmZip();
|
|
92
|
-
|
|
93
|
-
// // Function to recursively add files to zip
|
|
94
|
-
// function addFilesToZip(currentPath: any, relativePath = '') {
|
|
95
|
-
// const items = fs.readdirSync(currentPath);
|
|
96
|
-
|
|
97
|
-
// for (const item of items) {
|
|
98
|
-
// const itemPath = path.join(currentPath, item);
|
|
99
|
-
// const itemRelativePath = path.join(relativePath, item);
|
|
100
|
-
|
|
101
|
-
// // Check if item should be excluded
|
|
102
|
-
// if (excludePatterns.some(pattern =>
|
|
103
|
-
// typeof pattern === 'string' ? itemRelativePath === pattern || item === pattern :
|
|
104
|
-
// pattern.test(itemRelativePath)
|
|
105
|
-
// )) {
|
|
106
|
-
// continue;
|
|
107
|
-
// }
|
|
108
|
-
|
|
109
|
-
// const stats = fs.statSync(itemPath);
|
|
110
|
-
|
|
111
|
-
// if (stats.isDirectory()) {
|
|
112
|
-
// addFilesToZip(itemPath, itemRelativePath);
|
|
113
|
-
// } else {
|
|
114
|
-
// zip.addLocalFile(itemPath, path.dirname(itemRelativePath));
|
|
115
|
-
// }
|
|
116
|
-
// }
|
|
117
|
-
// }
|
|
118
|
-
|
|
119
|
-
// addFilesToZip(dirPath);
|
|
120
|
-
// zip.writeZip(zipFilePath);
|
|
121
|
-
|
|
122
|
-
// return zipFilePath;
|
|
123
|
-
// }
|
|
124
|
-
|
|
125
86
|
export function createZipFromDirectory(dirPath: any, excludePatterns = ['node_modules', 'pnpm-lock.yaml', 'package-lock.json', 'yarn.lock']) {
|
|
126
87
|
const dirName = path.basename(dirPath);
|
|
127
88
|
const timestamp = Date.now();
|
|
@@ -209,24 +170,6 @@ export const TEMPLATES: Record<string, TemplateInfo> = {
|
|
|
209
170
|
}
|
|
210
171
|
};
|
|
211
172
|
|
|
212
|
-
export async function downloadFromGoogleDrive(fileId: string, outputPath: string): Promise<void> {
|
|
213
|
-
const url = `https://drive.google.com/uc?export=download&id=${fileId}`;
|
|
214
|
-
|
|
215
|
-
const response = await axios({
|
|
216
|
-
method: 'GET',
|
|
217
|
-
url: url,
|
|
218
|
-
responseType: 'stream',
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
const writer = fs.createWriteStream(outputPath);
|
|
222
|
-
response.data.pipe(writer);
|
|
223
|
-
|
|
224
|
-
return new Promise((resolve, reject) => {
|
|
225
|
-
writer.on('finish', resolve);
|
|
226
|
-
writer.on('error', reject);
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
173
|
// Helper function to extract zip file
|
|
231
174
|
export function extractZip(zipPath: string, extractPath: string): void {
|
|
232
175
|
const zip = new AdmZip(zipPath);
|
package/test/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Test Suite Summary
|
|
2
|
+
|
|
3
|
+
This directory contains comprehensive unit tests for all CLI commands in the nestbox-ai-cli-tools project.
|
|
4
|
+
|
|
5
|
+
## Test Files Created
|
|
6
|
+
|
|
7
|
+
- **auth.test.ts** - Tests for authentication commands (login, logout)
|
|
8
|
+
- **projects.test.ts** - Tests for project management commands (project use, project add, list)
|
|
9
|
+
- **compute.test.ts** - Tests for compute instance management commands (compute list, create, delete)
|
|
10
|
+
- **document.test.ts** - Tests for document management commands (doc and collection subcommands)
|
|
11
|
+
- **image.test.ts** - Tests for image management commands (image list)
|
|
12
|
+
- **agent.test.ts** - Tests for agent management commands (agent list, remove, deploy, generate, create)
|
|
13
|
+
|
|
14
|
+
## What the Tests Cover
|
|
15
|
+
|
|
16
|
+
Each test file verifies:
|
|
17
|
+
|
|
18
|
+
1. **Command Registration** - Ensures all commands and subcommands are properly registered
|
|
19
|
+
2. **Command Structure** - Validates command names, descriptions, and hierarchy
|
|
20
|
+
3. **Options and Arguments** - Checks that expected command-line options are available
|
|
21
|
+
4. **Action Functions** - Verifies that action handlers are properly attached
|
|
22
|
+
|
|
23
|
+
## Test Strategy
|
|
24
|
+
|
|
25
|
+
The tests focus on **command registration and structure validation** rather than execution logic. This approach:
|
|
26
|
+
|
|
27
|
+
- Ensures the CLI interface remains stable
|
|
28
|
+
- Validates command-line argument parsing
|
|
29
|
+
- Verifies help text and descriptions
|
|
30
|
+
- Doesn't require mocking complex external APIs
|
|
31
|
+
- Runs quickly and reliably
|
|
32
|
+
|
|
33
|
+
## Running Tests
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Run all tests
|
|
37
|
+
npm test
|
|
38
|
+
|
|
39
|
+
# Run tests with coverage
|
|
40
|
+
npm run coverage
|
|
41
|
+
|
|
42
|
+
# Run specific test file
|
|
43
|
+
npm test auth.test.ts
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Test Framework
|
|
47
|
+
|
|
48
|
+
- **Vitest** - Fast unit test runner with TypeScript support
|
|
49
|
+
- **Commander.js** - CLI framework being tested
|
|
50
|
+
- **Mock Strategy** - External dependencies are mocked to isolate command registration logic
|
|
51
|
+
|
|
52
|
+
All tests are passing and provide confidence that the CLI command structure is working correctly.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { registerAgentCommands } from '../src/commands/agent';
|
|
4
|
+
|
|
5
|
+
describe('Agent Commands', () => {
|
|
6
|
+
let program: Command;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
program = new Command();
|
|
10
|
+
vi.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('registerAgentCommands', () => {
|
|
14
|
+
it('should register agent command group', () => {
|
|
15
|
+
registerAgentCommands(program);
|
|
16
|
+
|
|
17
|
+
const commands = program.commands;
|
|
18
|
+
const agentCommand = commands.find(cmd => cmd.name() === 'agent');
|
|
19
|
+
|
|
20
|
+
expect(agentCommand).toBeDefined();
|
|
21
|
+
expect(agentCommand?.description()).toBe('Manage Nestbox agents');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should register agent list subcommand', () => {
|
|
25
|
+
registerAgentCommands(program);
|
|
26
|
+
|
|
27
|
+
const agentCommand = program.commands.find(cmd => cmd.name() === 'agent');
|
|
28
|
+
const subCommands = agentCommand?.commands || [];
|
|
29
|
+
const listCommand = subCommands.find(cmd => cmd.name() === 'list');
|
|
30
|
+
|
|
31
|
+
expect(listCommand).toBeDefined();
|
|
32
|
+
expect(listCommand?.description()).toBe('List all AI agents associated with the authenticated user');
|
|
33
|
+
|
|
34
|
+
// Check options
|
|
35
|
+
const options = listCommand?.options || [];
|
|
36
|
+
const projectOption = options.find(opt => opt.long === '--project');
|
|
37
|
+
expect(projectOption).toBeDefined();
|
|
38
|
+
expect(projectOption?.description).toBe('Project name (defaults to the current project)');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should register agent remove subcommand', () => {
|
|
42
|
+
registerAgentCommands(program);
|
|
43
|
+
|
|
44
|
+
const agentCommand = program.commands.find(cmd => cmd.name() === 'agent');
|
|
45
|
+
const subCommands = agentCommand?.commands || [];
|
|
46
|
+
const removeCommand = subCommands.find(cmd => cmd.name() === 'remove');
|
|
47
|
+
|
|
48
|
+
expect(removeCommand).toBeDefined();
|
|
49
|
+
expect(removeCommand?.description()).toBe('Remove an AI agent');
|
|
50
|
+
|
|
51
|
+
// Check options
|
|
52
|
+
const options = removeCommand?.options || [];
|
|
53
|
+
const agentOption = options.find(opt => opt.long === '--agent');
|
|
54
|
+
const projectOption = options.find(opt => opt.long === '--project');
|
|
55
|
+
|
|
56
|
+
expect(agentOption).toBeDefined();
|
|
57
|
+
expect(projectOption).toBeDefined();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should register agent deploy subcommand', () => {
|
|
61
|
+
registerAgentCommands(program);
|
|
62
|
+
|
|
63
|
+
const agentCommand = program.commands.find(cmd => cmd.name() === 'agent');
|
|
64
|
+
const subCommands = agentCommand?.commands || [];
|
|
65
|
+
const deployCommand = subCommands.find(cmd => cmd.name() === 'deploy');
|
|
66
|
+
|
|
67
|
+
expect(deployCommand).toBeDefined();
|
|
68
|
+
expect(deployCommand?.description()).toBe('Deploy an AI agent to the Nestbox platform');
|
|
69
|
+
|
|
70
|
+
// Check options
|
|
71
|
+
const options = deployCommand?.options || [];
|
|
72
|
+
const projectOption = options.find(opt => opt.long === '--project');
|
|
73
|
+
const agentOption = options.find(opt => opt.long === '--agent');
|
|
74
|
+
const instanceOption = options.find(opt => opt.long === '--instance');
|
|
75
|
+
|
|
76
|
+
expect(projectOption).toBeDefined();
|
|
77
|
+
expect(agentOption).toBeDefined();
|
|
78
|
+
expect(instanceOption).toBeDefined();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should register agent generate subcommand', () => {
|
|
82
|
+
registerAgentCommands(program);
|
|
83
|
+
|
|
84
|
+
const agentCommand = program.commands.find(cmd => cmd.name() === 'agent');
|
|
85
|
+
const subCommands = agentCommand?.commands || [];
|
|
86
|
+
const generateCommand = subCommands.find(cmd => cmd.name() === 'generate');
|
|
87
|
+
|
|
88
|
+
expect(generateCommand).toBeDefined();
|
|
89
|
+
expect(generateCommand?.description()).toBe('Generate a new project from templates');
|
|
90
|
+
|
|
91
|
+
// Check that folder is an argument (it's in command name: "generate <folder>")
|
|
92
|
+
expect(generateCommand?.name()).toBe('generate');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should register agent create subcommand', () => {
|
|
96
|
+
registerAgentCommands(program);
|
|
97
|
+
|
|
98
|
+
const agentCommand = program.commands.find(cmd => cmd.name() === 'agent');
|
|
99
|
+
const subCommands = agentCommand?.commands || [];
|
|
100
|
+
const createCommand = subCommands.find(cmd => cmd.name() === 'create');
|
|
101
|
+
|
|
102
|
+
expect(createCommand).toBeDefined();
|
|
103
|
+
expect(createCommand?.description()).toBe('Create multiple agents from a YAML configuration file');
|
|
104
|
+
|
|
105
|
+
// Check that it has optional arguments (in command name: "create [firstArg] [secondArg]")
|
|
106
|
+
expect(createCommand?.name()).toBe('create');
|
|
107
|
+
|
|
108
|
+
// Check options
|
|
109
|
+
const options = createCommand?.options || [];
|
|
110
|
+
const projectOption = options.find(opt => opt.long === '--project');
|
|
111
|
+
|
|
112
|
+
expect(projectOption).toBeDefined();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should have all expected agent subcommands', () => {
|
|
116
|
+
registerAgentCommands(program);
|
|
117
|
+
|
|
118
|
+
const agentCommand = program.commands.find(cmd => cmd.name() === 'agent');
|
|
119
|
+
const subCommandNames = agentCommand?.commands.map(cmd => cmd.name()) || [];
|
|
120
|
+
|
|
121
|
+
expect(subCommandNames).toContain('list');
|
|
122
|
+
expect(subCommandNames).toContain('remove');
|
|
123
|
+
expect(subCommandNames).toContain('deploy');
|
|
124
|
+
expect(subCommandNames).toContain('generate');
|
|
125
|
+
expect(subCommandNames).toContain('create');
|
|
126
|
+
expect(subCommandNames).toHaveLength(5);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should have proper action functions for all subcommands', () => {
|
|
130
|
+
registerAgentCommands(program);
|
|
131
|
+
|
|
132
|
+
const agentCommand = program.commands.find(cmd => cmd.name() === 'agent');
|
|
133
|
+
const subCommands = agentCommand?.commands || [];
|
|
134
|
+
|
|
135
|
+
subCommands.forEach(cmd => {
|
|
136
|
+
expect(typeof cmd.action).toBe('function');
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { registerAuthCommands } from '../src/commands/auth';
|
|
4
|
+
|
|
5
|
+
describe('Auth Commands', () => {
|
|
6
|
+
let program: Command;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
program = new Command();
|
|
10
|
+
vi.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('registerAuthCommands', () => {
|
|
14
|
+
it('should register login command with correct parameters', () => {
|
|
15
|
+
registerAuthCommands(program);
|
|
16
|
+
|
|
17
|
+
const commands = program.commands;
|
|
18
|
+
const loginCommand = commands.find(cmd => cmd.name() === 'login');
|
|
19
|
+
|
|
20
|
+
expect(loginCommand).toBeDefined();
|
|
21
|
+
expect(loginCommand?.description()).toBe('Login using Google SSO');
|
|
22
|
+
|
|
23
|
+
// Check if the command expects a domain argument (it's in the command name)
|
|
24
|
+
expect(loginCommand?.name()).toBe('login');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should register logout command with correct parameters', () => {
|
|
28
|
+
registerAuthCommands(program);
|
|
29
|
+
|
|
30
|
+
const commands = program.commands;
|
|
31
|
+
const logoutCommand = commands.find(cmd => cmd.name() === 'logout');
|
|
32
|
+
|
|
33
|
+
expect(logoutCommand).toBeDefined();
|
|
34
|
+
expect(logoutCommand?.description()).toBe('Logout from Nestbox platform');
|
|
35
|
+
|
|
36
|
+
// Check if the command has an optional domain argument (it's in the command name)
|
|
37
|
+
expect(logoutCommand?.name()).toBe('logout');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should register all expected auth commands', () => {
|
|
41
|
+
registerAuthCommands(program);
|
|
42
|
+
|
|
43
|
+
const commandNames = program.commands.map(cmd => cmd.name());
|
|
44
|
+
expect(commandNames).toContain('login');
|
|
45
|
+
expect(commandNames).toContain('logout');
|
|
46
|
+
expect(commandNames).toHaveLength(2);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should have proper command structure for login', () => {
|
|
50
|
+
registerAuthCommands(program);
|
|
51
|
+
|
|
52
|
+
const loginCommand = program.commands.find(cmd => cmd.name() === 'login');
|
|
53
|
+
|
|
54
|
+
// Verify command properties
|
|
55
|
+
expect(loginCommand?.name()).toBe('login');
|
|
56
|
+
expect(loginCommand?.description()).toBe('Login using Google SSO');
|
|
57
|
+
expect(typeof loginCommand?.action).toBe('function');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should have proper command structure for logout', () => {
|
|
61
|
+
registerAuthCommands(program);
|
|
62
|
+
|
|
63
|
+
const logoutCommand = program.commands.find(cmd => cmd.name() === 'logout');
|
|
64
|
+
|
|
65
|
+
// Verify command properties
|
|
66
|
+
expect(logoutCommand?.name()).toBe('logout');
|
|
67
|
+
expect(logoutCommand?.description()).toBe('Logout from Nestbox platform');
|
|
68
|
+
expect(typeof logoutCommand?.action).toBe('function');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|