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.
@@ -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 };