codeant-cli 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 +226 -0
- package/package.json +28 -0
- package/src/commands/getBaseUrl.js +25 -0
- package/src/commands/login.js +124 -0
- package/src/commands/logout.js +30 -0
- package/src/commands/secrets.js +251 -0
- package/src/commands/setBaseUrl.js +37 -0
- package/src/index.js +62 -0
- package/src/utils/config.js +42 -0
- package/src/utils/fetchApi.js +42 -0
- package/src/utils/gitDiffHelper.js +762 -0
- package/src/utils/secretsApiHelper.js +127 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { Text, Box, useApp } from 'ink';
|
|
3
|
+
import { setConfigValue, CONFIG_FILE } from '../utils/config.js';
|
|
4
|
+
|
|
5
|
+
export default function SetBaseUrl({ url }) {
|
|
6
|
+
const { exit } = useApp();
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!url) {
|
|
10
|
+
exit(new Error('URL is required'));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
setConfigValue('baseUrl', url);
|
|
16
|
+
exit();
|
|
17
|
+
} catch (err) {
|
|
18
|
+
exit(err);
|
|
19
|
+
}
|
|
20
|
+
}, []);
|
|
21
|
+
|
|
22
|
+
if (!url) {
|
|
23
|
+
return React.createElement(
|
|
24
|
+
Box,
|
|
25
|
+
{ flexDirection: 'column', padding: 1 },
|
|
26
|
+
React.createElement(Text, { color: 'red' }, '✗ Error: URL is required'),
|
|
27
|
+
React.createElement(Text, { color: 'gray' }, 'Usage: codeant set-base-url <url>')
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return React.createElement(
|
|
32
|
+
Box,
|
|
33
|
+
{ flexDirection: 'column', padding: 1 },
|
|
34
|
+
React.createElement(Text, { color: 'green' }, '✓ Base URL set to: ', url),
|
|
35
|
+
React.createElement(Text, { color: 'gray' }, 'Saved to: ', CONFIG_FILE)
|
|
36
|
+
);
|
|
37
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import { render } from 'ink';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import Secrets from './commands/secrets.js';
|
|
7
|
+
import SetBaseUrl from './commands/setBaseUrl.js';
|
|
8
|
+
import GetBaseUrl from './commands/getBaseUrl.js';
|
|
9
|
+
import Login from './commands/login.js';
|
|
10
|
+
import Logout from './commands/logout.js';
|
|
11
|
+
|
|
12
|
+
program
|
|
13
|
+
.name('codeant')
|
|
14
|
+
.description('Code review CLI tool')
|
|
15
|
+
.version('0.1.0');
|
|
16
|
+
|
|
17
|
+
program
|
|
18
|
+
.command('secrets')
|
|
19
|
+
.description('Scan for secrets in your code')
|
|
20
|
+
.option('--staged', 'Scan only staged files (default)')
|
|
21
|
+
.option('--all', 'Scan all changed files')
|
|
22
|
+
.option('--uncommitted', 'Scan uncommitted changes')
|
|
23
|
+
.option('--last-commit', 'Scan last commit')
|
|
24
|
+
.option('--fail-on <level>', 'Fail only on HIGH, MEDIUM, or all (default: HIGH)', 'HIGH')
|
|
25
|
+
.action((options) => {
|
|
26
|
+
let scanType = 'staged-only';
|
|
27
|
+
if (options.all) scanType = 'branch-diff';
|
|
28
|
+
else if (options.uncommitted) scanType = 'uncommitted';
|
|
29
|
+
else if (options.lastCommit) scanType = 'last-commit';
|
|
30
|
+
|
|
31
|
+
render(React.createElement(Secrets, { scanType, failOn: options.failOn }));
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
program
|
|
35
|
+
.command('set-base-url <url>')
|
|
36
|
+
.description('Set the API base URL')
|
|
37
|
+
.action((url) => {
|
|
38
|
+
render(React.createElement(SetBaseUrl, { url }));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
program
|
|
42
|
+
.command('get-base-url')
|
|
43
|
+
.description('Show the current API base URL')
|
|
44
|
+
.action(() => {
|
|
45
|
+
render(React.createElement(GetBaseUrl));
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
program
|
|
49
|
+
.command('login')
|
|
50
|
+
.description('Login to CodeAnt')
|
|
51
|
+
.action(() => {
|
|
52
|
+
render(React.createElement(Login));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
program
|
|
56
|
+
.command('logout')
|
|
57
|
+
.description('Logout from CodeAnt')
|
|
58
|
+
.action(() => {
|
|
59
|
+
render(React.createElement(Logout));
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
program.parse();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
|
|
5
|
+
const CONFIG_DIR = path.join(os.homedir(), '.codeant');
|
|
6
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
7
|
+
|
|
8
|
+
const ensureConfigDir = () => {
|
|
9
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
10
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const loadConfig = () => {
|
|
15
|
+
try {
|
|
16
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
17
|
+
const data = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
18
|
+
return JSON.parse(data);
|
|
19
|
+
}
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error('Error loading config:', err.message);
|
|
22
|
+
}
|
|
23
|
+
return {};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const saveConfig = (config) => {
|
|
27
|
+
ensureConfigDir();
|
|
28
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const getConfigValue = (key) => {
|
|
32
|
+
const config = loadConfig();
|
|
33
|
+
return config[key];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const setConfigValue = (key, value) => {
|
|
37
|
+
const config = loadConfig();
|
|
38
|
+
config[key] = value;
|
|
39
|
+
saveConfig(config);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { loadConfig, saveConfig, getConfigValue, setConfigValue, CONFIG_FILE };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { getConfigValue } from './config.js';
|
|
2
|
+
|
|
3
|
+
const getBaseUrl = () => {
|
|
4
|
+
return process.env.CODEANT_API_URL || getConfigValue('baseUrl') || 'https://api.codeant.ai';
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const fetchApi = async (endpoint, method = 'GET', body = null) => {
|
|
8
|
+
const url = endpoint.startsWith('http') ? endpoint : `${getBaseUrl()}${endpoint}`;
|
|
9
|
+
|
|
10
|
+
const options = {
|
|
11
|
+
method,
|
|
12
|
+
headers: {
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Add auth token from config or env
|
|
18
|
+
const token = process.env.CODEANT_API_TOKEN || getConfigValue('apiKey');
|
|
19
|
+
if (token) {
|
|
20
|
+
options.headers['Authorization'] = `Bearer ${token}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (body && method !== 'GET') {
|
|
24
|
+
options.body = JSON.stringify(body);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(url, options);
|
|
29
|
+
const data = await response.json();
|
|
30
|
+
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new Error(data.message || `HTTP error ${response.status}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return data;
|
|
36
|
+
} catch (err) {
|
|
37
|
+
console.error(`API Error: ${err.message}`);
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { fetchApi };
|