@annexfour/cli 1.0.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/bin/index.js +104 -0
- package/package.json +24 -0
package/bin/index.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
|
|
10
|
+
const CONFIG_DIR = path.join(os.homedir(), '.config', 'ai-act-check');
|
|
11
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name('annexfour')
|
|
15
|
+
.description('AnnexFour Compliance Scanner Wrapper')
|
|
16
|
+
.version('1.0.0');
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command('login')
|
|
20
|
+
.description('Authenticate with Annexfour Platform')
|
|
21
|
+
.action(async () => {
|
|
22
|
+
console.log("--- Annexfour Global Login ---");
|
|
23
|
+
console.log("Please paste your API Token (generated in Settings -> Developer).");
|
|
24
|
+
|
|
25
|
+
// Check if inquirer supports password masks correctly in this environment, otherwise fallback
|
|
26
|
+
const answers = await inquirer.prompt([
|
|
27
|
+
{
|
|
28
|
+
type: 'password',
|
|
29
|
+
name: 'token',
|
|
30
|
+
message: 'API Token:',
|
|
31
|
+
mask: '*',
|
|
32
|
+
validate: (input) => input.startsWith('anx_') ? true : "Token must start with 'anx_'"
|
|
33
|
+
}
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
38
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify({ token: answers.token }, null, 2));
|
|
41
|
+
console.log(`\n[+] Success! Token saved to ${CONFIG_FILE}`);
|
|
42
|
+
console.log("You can now run 'npx @annexfour/cli scan' without arguments.");
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error("Error saving config:", error.message);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
program
|
|
50
|
+
.command('scan [path]')
|
|
51
|
+
.description('Run compliance scan on the current or specified directory')
|
|
52
|
+
.option('-t, --token <token>', 'API Token (overrides config)')
|
|
53
|
+
.option('-p, --project-name <name>', 'Project Name')
|
|
54
|
+
.action(async (targetPath, options) => {
|
|
55
|
+
// 1. Check for Docker
|
|
56
|
+
try {
|
|
57
|
+
await new Promise((resolve, reject) => {
|
|
58
|
+
const check = spawn('docker', ['--version']);
|
|
59
|
+
check.on('close', (code) => code === 0 ? resolve() : reject());
|
|
60
|
+
check.on('error', reject);
|
|
61
|
+
});
|
|
62
|
+
} catch (e) {
|
|
63
|
+
console.error("Error: Docker is not installed or not running.");
|
|
64
|
+
console.error("Please install Docker to use this tool: https://docs.docker.com/get-docker/");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const scanPath = targetPath ? path.resolve(targetPath) : process.cwd();
|
|
69
|
+
|
|
70
|
+
// Construct Docker arguments
|
|
71
|
+
const dockerArgs = [
|
|
72
|
+
'run', '--rm', '-i',
|
|
73
|
+
'-v', `${scanPath}:/code`,
|
|
74
|
+
// Mount config read-only so the container picks up the token we just saved
|
|
75
|
+
'-v', `${CONFIG_DIR}:/root/.config/ai-act-check:ro`,
|
|
76
|
+
// Forward Env Vars if present
|
|
77
|
+
process.env.ANNEXFOUR_API_URL ? '-e' : '',
|
|
78
|
+
process.env.ANNEXFOUR_API_URL ? `ANNEXFOUR_API_URL=${process.env.ANNEXFOUR_API_URL}` : '',
|
|
79
|
+
'annexfour/ai-act-check',
|
|
80
|
+
'scan', '/code'
|
|
81
|
+
].filter(Boolean); // Remove empty strings
|
|
82
|
+
|
|
83
|
+
// Pass CLI arguments to container
|
|
84
|
+
if (options.token) {
|
|
85
|
+
dockerArgs.push('--token', options.token);
|
|
86
|
+
}
|
|
87
|
+
if (options.projectName) {
|
|
88
|
+
dockerArgs.push('--project-name', options.projectName);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.log(`[*] Launching Scanner via Docker...`);
|
|
92
|
+
// console.log(`DEBUG: docker ${dockerArgs.join(' ')}`);
|
|
93
|
+
|
|
94
|
+
const child = spawn('docker', dockerArgs, { stdio: 'inherit' });
|
|
95
|
+
|
|
96
|
+
child.on('close', (code) => {
|
|
97
|
+
if (code !== 0) {
|
|
98
|
+
console.log("\n[!] Scan container exited with error.");
|
|
99
|
+
}
|
|
100
|
+
process.exit(code);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@annexfour/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AnnexFour Compliance Scanner CLI Wrapper",
|
|
5
|
+
"main": "bin/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"annexfour": "./bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"ai-act",
|
|
14
|
+
"compliance",
|
|
15
|
+
"security"
|
|
16
|
+
],
|
|
17
|
+
"author": "AnnexFour",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"commander": "^11.0.0",
|
|
21
|
+
"inquirer": "^9.0.0"
|
|
22
|
+
},
|
|
23
|
+
"type": "module"
|
|
24
|
+
}
|