@neurcode-ai/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 +92 -0
- package/dist/api-client.d.ts +63 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +88 -0
- package/dist/api-client.js.map +1 -0
- package/dist/commands/check.d.ts +12 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.integration.test.d.ts +7 -0
- package/dist/commands/check.integration.test.d.ts.map +1 -0
- package/dist/commands/check.integration.test.js +157 -0
- package/dist/commands/check.integration.test.js.map +1 -0
- package/dist/commands/check.js +200 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +42 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/rules.d.ts +13 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +21 -0
- package/dist/rules.js.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Neurcode CLI
|
|
2
|
+
|
|
3
|
+
AI-powered code governance and diff analysis tool.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Option 1: Link locally (for development)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# From the monorepo root
|
|
11
|
+
pnpm install
|
|
12
|
+
pnpm --filter @neurcode/cli build
|
|
13
|
+
|
|
14
|
+
# Link globally
|
|
15
|
+
cd packages/cli
|
|
16
|
+
pnpm link --global
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Option 2: Use via pnpm (from monorepo)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# From monorepo root
|
|
23
|
+
pnpm cli check --help
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
Create a `neurcode.config.json` file in your project root or home directory:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"apiUrl": "https://api.neurcode.com",
|
|
33
|
+
"apiKey": "nk_live_YOUR_API_KEY_HERE",
|
|
34
|
+
"projectId": "optional-project-id"
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Or set environment variables:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
export NEURCODE_API_URL="https://api.neurcode.com"
|
|
42
|
+
export NEURCODE_API_KEY="nk_live_YOUR_API_KEY_HERE"
|
|
43
|
+
export NEURCODE_PROJECT_ID="optional-project-id"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
### Basic Check (Local Rules)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Check staged changes
|
|
52
|
+
neurcode check --staged
|
|
53
|
+
|
|
54
|
+
# Check changes against HEAD
|
|
55
|
+
neurcode check --head
|
|
56
|
+
|
|
57
|
+
# Check against specific base
|
|
58
|
+
neurcode check --base main
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Online Check (Rule-Based Analysis)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Send diff to API for rule-based analysis
|
|
65
|
+
neurcode check --staged --online
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### AI-Powered Analysis (with Session Tracking)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# AI analysis with automatic session creation
|
|
72
|
+
neurcode check --staged --online --ai --intent "Fix login bug"
|
|
73
|
+
|
|
74
|
+
# Use existing session
|
|
75
|
+
neurcode check --staged --online --ai --intent "Add feature" --session-id "session_123"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Getting Your API Key
|
|
79
|
+
|
|
80
|
+
1. Go to https://neurcode.com/dashboard/api-keys
|
|
81
|
+
2. Create a new API key
|
|
82
|
+
3. Copy the key (starts with `nk_live_`)
|
|
83
|
+
4. Add it to your config file or environment variables
|
|
84
|
+
|
|
85
|
+
## Viewing Sessions
|
|
86
|
+
|
|
87
|
+
After running AI analysis, you'll get a session ID. View it in the dashboard:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
https://neurcode.com/dashboard/sessions/{sessionId}
|
|
91
|
+
```
|
|
92
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { NeurcodeConfig } from './config';
|
|
2
|
+
export interface AnalyzeDiffRequest {
|
|
3
|
+
diff: string;
|
|
4
|
+
projectId?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface AnalyzeDiffResponse {
|
|
7
|
+
logId: string;
|
|
8
|
+
decision: 'allow' | 'warn' | 'block';
|
|
9
|
+
violations: Array<{
|
|
10
|
+
rule: string;
|
|
11
|
+
file: string;
|
|
12
|
+
severity: 'allow' | 'warn' | 'block';
|
|
13
|
+
message?: string;
|
|
14
|
+
}>;
|
|
15
|
+
summary: {
|
|
16
|
+
totalFiles: number;
|
|
17
|
+
totalAdded: number;
|
|
18
|
+
totalRemoved: number;
|
|
19
|
+
files: Array<{
|
|
20
|
+
path: string;
|
|
21
|
+
changeType: 'add' | 'delete' | 'modify' | 'rename';
|
|
22
|
+
added: number;
|
|
23
|
+
removed: number;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface AnalyzeBloatResponse {
|
|
28
|
+
analysis: {
|
|
29
|
+
redundancy: {
|
|
30
|
+
originalLines: number;
|
|
31
|
+
suggestedLines: number;
|
|
32
|
+
redundancyPercentage: number;
|
|
33
|
+
redundantBlocks: Array<{
|
|
34
|
+
lines: [number, number];
|
|
35
|
+
reason: string;
|
|
36
|
+
suggestion: string;
|
|
37
|
+
}>;
|
|
38
|
+
tokenSavings: number;
|
|
39
|
+
costSavings: number;
|
|
40
|
+
};
|
|
41
|
+
intentMatch: {
|
|
42
|
+
matches: boolean;
|
|
43
|
+
confidence: number;
|
|
44
|
+
explanation: string;
|
|
45
|
+
mismatches: Array<{
|
|
46
|
+
file: string;
|
|
47
|
+
reason: string;
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
recommendation: 'block' | 'warn' | 'allow';
|
|
51
|
+
summary: string;
|
|
52
|
+
};
|
|
53
|
+
sessionId: string;
|
|
54
|
+
timestamp: string;
|
|
55
|
+
}
|
|
56
|
+
export declare class ApiClient {
|
|
57
|
+
private apiUrl;
|
|
58
|
+
private apiKey?;
|
|
59
|
+
constructor(config: NeurcodeConfig);
|
|
60
|
+
analyzeDiff(diff: string, projectId?: string): Promise<AnalyzeDiffResponse>;
|
|
61
|
+
analyzeBloat(diff: string, intent?: string, projectId?: string, sessionId?: string): Promise<AnalyzeBloatResponse>;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,UAAU,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;QACrC,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,KAAK,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;YACnD,KAAK,EAAE,MAAM,CAAC;YACd,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE;QACR,UAAU,EAAE;YACV,aAAa,EAAE,MAAM,CAAC;YACtB,cAAc,EAAE,MAAM,CAAC;YACvB,oBAAoB,EAAE,MAAM,CAAC;YAC7B,eAAe,EAAE,KAAK,CAAC;gBACrB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACxB,MAAM,EAAE,MAAM,CAAC;gBACf,UAAU,EAAE,MAAM,CAAC;aACpB,CAAC,CAAC;YACH,YAAY,EAAE,MAAM,CAAC;YACrB,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,WAAW,EAAE;YACX,OAAO,EAAE,OAAO,CAAC;YACjB,UAAU,EAAE,MAAM,CAAC;YACnB,WAAW,EAAE,MAAM,CAAC;YACpB,UAAU,EAAE,KAAK,CAAC;gBAChB,IAAI,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,MAAM,CAAC;aAChB,CAAC,CAAC;SACJ,CAAC;QACF,cAAc,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;QAC3C,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,MAAM,EAAE,cAAc;IAQ5B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA0C3E,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA2CzH"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiClient = void 0;
|
|
4
|
+
class ApiClient {
|
|
5
|
+
apiUrl;
|
|
6
|
+
apiKey;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
if (!config.apiUrl) {
|
|
9
|
+
throw new Error('API URL not configured. Set NEURCODE_API_URL env var or add to neurcode.config.json');
|
|
10
|
+
}
|
|
11
|
+
this.apiUrl = config.apiUrl.replace(/\/$/, ''); // Remove trailing slash
|
|
12
|
+
this.apiKey = config.apiKey;
|
|
13
|
+
}
|
|
14
|
+
async analyzeDiff(diff, projectId) {
|
|
15
|
+
const url = `${this.apiUrl}/api/v1/analyze-diff`;
|
|
16
|
+
const headers = {
|
|
17
|
+
'Content-Type': 'application/json'
|
|
18
|
+
};
|
|
19
|
+
if (this.apiKey) {
|
|
20
|
+
// Support both "Bearer nk_live_..." and just "nk_live_..."
|
|
21
|
+
const key = this.apiKey.startsWith('Bearer ') ? this.apiKey : `Bearer ${this.apiKey}`;
|
|
22
|
+
headers['Authorization'] = key;
|
|
23
|
+
}
|
|
24
|
+
const response = await fetch(url, {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers,
|
|
27
|
+
body: JSON.stringify({
|
|
28
|
+
diff,
|
|
29
|
+
projectId
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
const errorText = await response.text();
|
|
34
|
+
let errorMessage = `API request failed with status ${response.status}`;
|
|
35
|
+
try {
|
|
36
|
+
const errorJson = JSON.parse(errorText);
|
|
37
|
+
errorMessage = errorJson.error || errorMessage;
|
|
38
|
+
if (errorJson.message) {
|
|
39
|
+
errorMessage += `: ${errorJson.message}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
errorMessage += `: ${errorText}`;
|
|
44
|
+
}
|
|
45
|
+
throw new Error(errorMessage);
|
|
46
|
+
}
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
async analyzeBloat(diff, intent, projectId, sessionId) {
|
|
50
|
+
const url = `${this.apiUrl}/api/v1/analyze-bloat`;
|
|
51
|
+
const headers = {
|
|
52
|
+
'Content-Type': 'application/json'
|
|
53
|
+
};
|
|
54
|
+
if (this.apiKey) {
|
|
55
|
+
// Support both "Bearer nk_live_..." and just "nk_live_..."
|
|
56
|
+
const key = this.apiKey.startsWith('Bearer ') ? this.apiKey : `Bearer ${this.apiKey}`;
|
|
57
|
+
headers['Authorization'] = key;
|
|
58
|
+
}
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers,
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
diff,
|
|
64
|
+
intent,
|
|
65
|
+
projectId,
|
|
66
|
+
sessionId
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
const errorText = await response.text();
|
|
71
|
+
let errorMessage = `API request failed with status ${response.status}`;
|
|
72
|
+
try {
|
|
73
|
+
const errorJson = JSON.parse(errorText);
|
|
74
|
+
errorMessage = errorJson.error || errorMessage;
|
|
75
|
+
if (errorJson.message) {
|
|
76
|
+
errorMessage += `: ${errorJson.message}`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
errorMessage += `: ${errorText}`;
|
|
81
|
+
}
|
|
82
|
+
throw new Error(errorMessage);
|
|
83
|
+
}
|
|
84
|
+
return response.json();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.ApiClient = ApiClient;
|
|
88
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface CheckOptions {
|
|
2
|
+
staged?: boolean;
|
|
3
|
+
head?: boolean;
|
|
4
|
+
base?: string;
|
|
5
|
+
online?: boolean;
|
|
6
|
+
ai?: boolean;
|
|
7
|
+
intent?: string;
|
|
8
|
+
sessionId?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkCommand(options: CheckOptions): Promise<void>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAMA,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,iBA8JvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.integration.test.d.ts","sourceRoot":"","sources":["../../src/commands/check.integration.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Integration Tests for CLI → API Flow
|
|
4
|
+
*
|
|
5
|
+
* Tests the complete flow: CLI → API → Database → Response
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
const vitest_1 = require("vitest");
|
|
42
|
+
const child_process_1 = require("child_process");
|
|
43
|
+
const path_1 = require("path");
|
|
44
|
+
const index_1 = require("../../../services/api/src/index");
|
|
45
|
+
const db_1 = require("../../../services/api/src/db");
|
|
46
|
+
const api_keys_1 = require("../../../services/api/src/lib/api-keys");
|
|
47
|
+
(0, vitest_1.describe)('CLI → API Integration Tests', () => {
|
|
48
|
+
let server;
|
|
49
|
+
let apiKey;
|
|
50
|
+
let apiUrl;
|
|
51
|
+
let organizationId;
|
|
52
|
+
let cliPath;
|
|
53
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
54
|
+
// Initialize database
|
|
55
|
+
await (0, db_1.initDatabase)(process.env.DATABASE_URL || 'postgresql://neurcode:neurcode@localhost:5432/neurcode');
|
|
56
|
+
// Build server
|
|
57
|
+
server = await (0, index_1.buildServer)();
|
|
58
|
+
await server.ready();
|
|
59
|
+
// Get server URL
|
|
60
|
+
const address = server.server.address();
|
|
61
|
+
if (typeof address === 'string') {
|
|
62
|
+
apiUrl = address;
|
|
63
|
+
}
|
|
64
|
+
else if (address) {
|
|
65
|
+
apiUrl = `http://localhost:${address.port}`;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
apiUrl = 'http://localhost:3000';
|
|
69
|
+
}
|
|
70
|
+
// Create test organization and API key
|
|
71
|
+
const orgResult = await (0, db_1.query)(`
|
|
72
|
+
INSERT INTO organizations (id, name, slug)
|
|
73
|
+
VALUES (gen_random_uuid(), 'Test Org', 'test-org-cli')
|
|
74
|
+
ON CONFLICT (slug) DO UPDATE SET name = EXCLUDED.name
|
|
75
|
+
RETURNING id
|
|
76
|
+
`);
|
|
77
|
+
organizationId = orgResult.rows[0].id;
|
|
78
|
+
const keyData = await (0, api_keys_1.createApiKey)(organizationId, null, 'CLI Test Key');
|
|
79
|
+
apiKey = keyData.key;
|
|
80
|
+
// Build CLI
|
|
81
|
+
const cliDir = (0, path_1.join)(__dirname, '..', '..');
|
|
82
|
+
(0, child_process_1.execSync)('pnpm build', { cwd: cliDir, stdio: 'inherit' });
|
|
83
|
+
cliPath = (0, path_1.join)(cliDir, 'dist', 'index.js');
|
|
84
|
+
}, 30000);
|
|
85
|
+
(0, vitest_1.afterAll)(async () => {
|
|
86
|
+
await server.close();
|
|
87
|
+
await (0, db_1.closeDatabase)();
|
|
88
|
+
});
|
|
89
|
+
(0, vitest_1.describe)('CLI online mode', () => {
|
|
90
|
+
(0, vitest_1.it)('should send diff to API and get response', async () => {
|
|
91
|
+
// Create a test git repo with a diff
|
|
92
|
+
const testDir = '/tmp/neurcode-cli-test';
|
|
93
|
+
try {
|
|
94
|
+
(0, child_process_1.execSync)('rm -rf ' + testDir, { stdio: 'ignore' });
|
|
95
|
+
(0, child_process_1.execSync)('mkdir -p ' + testDir, { stdio: 'ignore' });
|
|
96
|
+
(0, child_process_1.execSync)('git init', { cwd: testDir, stdio: 'ignore' });
|
|
97
|
+
(0, child_process_1.execSync)('git config user.email "test@test.com"', { cwd: testDir, stdio: 'ignore' });
|
|
98
|
+
(0, child_process_1.execSync)('git config user.name "Test User"', { cwd: testDir, stdio: 'ignore' });
|
|
99
|
+
// Create a test file
|
|
100
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
101
|
+
fs.writeFileSync((0, path_1.join)(testDir, 'test.js'), 'console.log("test");\n');
|
|
102
|
+
(0, child_process_1.execSync)('git add test.js', { cwd: testDir, stdio: 'ignore' });
|
|
103
|
+
(0, child_process_1.execSync)('git commit -m "Initial commit"', { cwd: testDir, stdio: 'ignore' });
|
|
104
|
+
// Make a change
|
|
105
|
+
fs.writeFileSync((0, path_1.join)(testDir, 'test.js'), 'console.log("test");\nconst x = 1;\n');
|
|
106
|
+
(0, child_process_1.execSync)('git add test.js', { cwd: testDir, stdio: 'ignore' });
|
|
107
|
+
// Run CLI with online mode
|
|
108
|
+
const result = (0, child_process_1.execSync)(`node ${cliPath} check --online --staged`, {
|
|
109
|
+
cwd: testDir,
|
|
110
|
+
env: {
|
|
111
|
+
...process.env,
|
|
112
|
+
NEURCODE_API_URL: apiUrl,
|
|
113
|
+
NEURCODE_API_KEY: apiKey,
|
|
114
|
+
},
|
|
115
|
+
encoding: 'utf-8',
|
|
116
|
+
});
|
|
117
|
+
// Should not throw and should contain analysis results
|
|
118
|
+
(0, vitest_1.expect)(result).toBeDefined();
|
|
119
|
+
(0, vitest_1.expect)(result.length).toBeGreaterThan(0);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
(0, child_process_1.execSync)('rm -rf ' + testDir, { stdio: 'ignore' });
|
|
123
|
+
}
|
|
124
|
+
}, 60000);
|
|
125
|
+
(0, vitest_1.it)('should handle API errors gracefully', async () => {
|
|
126
|
+
const testDir = '/tmp/neurcode-cli-test-error';
|
|
127
|
+
try {
|
|
128
|
+
(0, child_process_1.execSync)('rm -rf ' + testDir, { stdio: 'ignore' });
|
|
129
|
+
(0, child_process_1.execSync)('mkdir -p ' + testDir, { stdio: 'ignore' });
|
|
130
|
+
(0, child_process_1.execSync)('git init', { cwd: testDir, stdio: 'ignore' });
|
|
131
|
+
(0, child_process_1.execSync)('git config user.email "test@test.com"', { cwd: testDir, stdio: 'ignore' });
|
|
132
|
+
(0, child_process_1.execSync)('git config user.name "Test User"', { cwd: testDir, stdio: 'ignore' });
|
|
133
|
+
// Use invalid API key
|
|
134
|
+
try {
|
|
135
|
+
(0, child_process_1.execSync)(`node ${cliPath} check --online --staged`, {
|
|
136
|
+
cwd: testDir,
|
|
137
|
+
env: {
|
|
138
|
+
...process.env,
|
|
139
|
+
NEURCODE_API_URL: apiUrl,
|
|
140
|
+
NEURCODE_API_KEY: 'invalid_key',
|
|
141
|
+
},
|
|
142
|
+
encoding: 'utf-8',
|
|
143
|
+
stdio: 'pipe',
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
// Should fail with error message
|
|
148
|
+
(0, vitest_1.expect)(error.message).toBeDefined();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
(0, child_process_1.execSync)('rm -rf ' + testDir, { stdio: 'ignore' });
|
|
153
|
+
}
|
|
154
|
+
}, 30000);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=check.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.integration.test.js","sourceRoot":"","sources":["../../src/commands/check.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkCommand = checkCommand;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const diff_parser_1 = require("@neurcode-ai/diff-parser");
|
|
6
|
+
const rules_1 = require("../rules");
|
|
7
|
+
const config_1 = require("../config");
|
|
8
|
+
const api_client_1 = require("../api-client");
|
|
9
|
+
async function checkCommand(options) {
|
|
10
|
+
try {
|
|
11
|
+
// Determine which diff to capture
|
|
12
|
+
let diffText;
|
|
13
|
+
if (options.staged) {
|
|
14
|
+
diffText = (0, child_process_1.execSync)('git diff --staged', { encoding: 'utf-8' });
|
|
15
|
+
}
|
|
16
|
+
else if (options.base) {
|
|
17
|
+
diffText = (0, child_process_1.execSync)(`git diff ${options.base}`, { encoding: 'utf-8' });
|
|
18
|
+
}
|
|
19
|
+
else if (options.head) {
|
|
20
|
+
diffText = (0, child_process_1.execSync)('git diff HEAD', { encoding: 'utf-8' });
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// Default: check staged, fallback to HEAD
|
|
24
|
+
try {
|
|
25
|
+
diffText = (0, child_process_1.execSync)('git diff --staged', { encoding: 'utf-8' });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
diffText = (0, child_process_1.execSync)('git diff HEAD', { encoding: 'utf-8' });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (!diffText.trim()) {
|
|
32
|
+
console.log('✓ No changes detected');
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
// Try online mode if requested
|
|
36
|
+
if (options.online || options.ai) {
|
|
37
|
+
try {
|
|
38
|
+
const config = (0, config_1.loadConfig)();
|
|
39
|
+
const client = new api_client_1.ApiClient(config);
|
|
40
|
+
const projectId = config.projectId;
|
|
41
|
+
if (options.ai) {
|
|
42
|
+
// AI-powered analysis with session tracking
|
|
43
|
+
console.log('🤖 Sending diff to Neurcode AI Analysis...');
|
|
44
|
+
const aiResult = await client.analyzeBloat(diffText, options.intent, projectId, options.sessionId);
|
|
45
|
+
// Display AI analysis results
|
|
46
|
+
console.log('\n📊 AI Analysis Results:');
|
|
47
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
48
|
+
console.log(`\n🎯 Session ID: ${aiResult.sessionId}`);
|
|
49
|
+
console.log(` View in dashboard: https://neurcode.com/dashboard/sessions/${aiResult.sessionId}`);
|
|
50
|
+
console.log(`\n📈 Redundancy Analysis:`);
|
|
51
|
+
console.log(` Original Lines: ${aiResult.analysis.redundancy.originalLines}`);
|
|
52
|
+
console.log(` Suggested Lines: ${aiResult.analysis.redundancy.suggestedLines}`);
|
|
53
|
+
console.log(` Redundancy: ${aiResult.analysis.redundancy.redundancyPercentage}%`);
|
|
54
|
+
console.log(` Token Savings: ${aiResult.analysis.redundancy.tokenSavings.toLocaleString()}`);
|
|
55
|
+
console.log(` Cost Savings: $${aiResult.analysis.redundancy.costSavings.toFixed(2)}`);
|
|
56
|
+
if (aiResult.analysis.redundancy.redundantBlocks.length > 0) {
|
|
57
|
+
console.log(`\n⚠️ Redundant Blocks Found:`);
|
|
58
|
+
aiResult.analysis.redundancy.redundantBlocks.forEach((block, i) => {
|
|
59
|
+
console.log(` ${i + 1}. Lines ${block.lines[0]}-${block.lines[1]}: ${block.reason}`);
|
|
60
|
+
console.log(` Suggestion: ${block.suggestion}`);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
console.log(`\n🎯 Intent Match:`);
|
|
64
|
+
console.log(` Matches: ${aiResult.analysis.intentMatch.matches ? '✅ Yes' : '❌ No'}`);
|
|
65
|
+
console.log(` Confidence: ${aiResult.analysis.intentMatch.confidence}%`);
|
|
66
|
+
console.log(` Explanation: ${aiResult.analysis.intentMatch.explanation}`);
|
|
67
|
+
if (aiResult.analysis.intentMatch.mismatches.length > 0) {
|
|
68
|
+
console.log(`\n⚠️ Intent Mismatches:`);
|
|
69
|
+
aiResult.analysis.intentMatch.mismatches.forEach((mismatch) => {
|
|
70
|
+
console.log(` - ${mismatch.file}: ${mismatch.reason}`);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
console.log(`\n💡 Recommendation: ${aiResult.analysis.recommendation.toUpperCase()}`);
|
|
74
|
+
console.log(`\n${aiResult.analysis.summary}`);
|
|
75
|
+
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
76
|
+
// Exit with appropriate code based on recommendation
|
|
77
|
+
if (aiResult.analysis.recommendation === 'block') {
|
|
78
|
+
process.exit(2);
|
|
79
|
+
}
|
|
80
|
+
else if (aiResult.analysis.recommendation === 'warn') {
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Basic rule-based analysis
|
|
89
|
+
console.log('🌐 Sending diff to Neurcode API...');
|
|
90
|
+
const apiResult = await client.analyzeDiff(diffText, projectId);
|
|
91
|
+
// Display results from API
|
|
92
|
+
displayResults(apiResult.summary, {
|
|
93
|
+
decision: apiResult.decision,
|
|
94
|
+
violations: apiResult.violations
|
|
95
|
+
}, apiResult.logId);
|
|
96
|
+
// Exit with appropriate code
|
|
97
|
+
if (apiResult.decision === 'block') {
|
|
98
|
+
process.exit(2);
|
|
99
|
+
}
|
|
100
|
+
else if (apiResult.decision === 'warn') {
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error instanceof Error) {
|
|
110
|
+
console.error('❌ Online mode failed:', error.message);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
console.error('❌ Online mode failed:', error);
|
|
114
|
+
}
|
|
115
|
+
console.log('⚠️ Falling back to local mode...\n');
|
|
116
|
+
// Fall through to local mode
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Local mode (default or fallback)
|
|
120
|
+
// Parse the diff
|
|
121
|
+
const diffFiles = (0, diff_parser_1.parseDiff)(diffText);
|
|
122
|
+
if (diffFiles.length === 0) {
|
|
123
|
+
console.log('✓ No file changes detected');
|
|
124
|
+
process.exit(0);
|
|
125
|
+
}
|
|
126
|
+
// Get summary
|
|
127
|
+
const summary = (0, diff_parser_1.getDiffSummary)(diffFiles);
|
|
128
|
+
// Evaluate rules
|
|
129
|
+
const result = (0, rules_1.evaluateRules)(diffFiles);
|
|
130
|
+
// Display results
|
|
131
|
+
displayResults(summary, result);
|
|
132
|
+
// Exit with appropriate code
|
|
133
|
+
if (result.decision === 'block') {
|
|
134
|
+
process.exit(2);
|
|
135
|
+
}
|
|
136
|
+
else if (result.decision === 'warn') {
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
process.exit(0);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error instanceof Error) {
|
|
145
|
+
console.error('❌ Error:', error.message);
|
|
146
|
+
// Check if it's a git error
|
|
147
|
+
if (error.message.includes('not a git repository')) {
|
|
148
|
+
console.error(' This command must be run in a git repository');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.error('❌ Unknown error:', error);
|
|
153
|
+
}
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Display analysis results
|
|
159
|
+
*/
|
|
160
|
+
function displayResults(summary, result, logId) {
|
|
161
|
+
// Print results
|
|
162
|
+
console.log('\n📊 Diff Analysis Summary');
|
|
163
|
+
if (logId) {
|
|
164
|
+
console.log(`Log ID: ${logId}`);
|
|
165
|
+
}
|
|
166
|
+
console.log('─'.repeat(50));
|
|
167
|
+
console.log(`Files changed: ${summary.totalFiles}`);
|
|
168
|
+
console.log(`Lines added: ${summary.totalAdded}`);
|
|
169
|
+
console.log(`Lines removed: ${summary.totalRemoved}`);
|
|
170
|
+
console.log(`Net change: ${summary.totalAdded - summary.totalRemoved > 0 ? '+' : ''}${summary.totalAdded - summary.totalRemoved}`);
|
|
171
|
+
// Print file list
|
|
172
|
+
console.log('\n📁 Changed Files:');
|
|
173
|
+
summary.files.forEach(file => {
|
|
174
|
+
const changeIcon = file.changeType === 'add' ? '➕' :
|
|
175
|
+
file.changeType === 'delete' ? '➖' :
|
|
176
|
+
file.changeType === 'rename' ? '🔄' : '✏️';
|
|
177
|
+
console.log(` ${changeIcon} ${file.path} (${file.changeType})`);
|
|
178
|
+
});
|
|
179
|
+
// Print rule violations
|
|
180
|
+
if (result.violations.length > 0) {
|
|
181
|
+
console.log('\n⚠️ Rule Violations:');
|
|
182
|
+
result.violations.forEach(violation => {
|
|
183
|
+
const severityIcon = violation.severity === 'block' ? '🚫' : '⚠️';
|
|
184
|
+
console.log(` ${severityIcon} [${violation.severity.toUpperCase()}] ${violation.rule}`);
|
|
185
|
+
console.log(` File: ${violation.file}`);
|
|
186
|
+
if (violation.message) {
|
|
187
|
+
console.log(` ${violation.message}`);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
console.log('\n✓ No rule violations detected');
|
|
193
|
+
}
|
|
194
|
+
// Print decision
|
|
195
|
+
console.log('\n' + '─'.repeat(50));
|
|
196
|
+
const decisionIcon = result.decision === 'allow' ? '✓' :
|
|
197
|
+
result.decision === 'warn' ? '⚠️' : '🚫';
|
|
198
|
+
console.log(`Decision: ${decisionIcon} ${result.decision.toUpperCase()}`);
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface NeurcodeConfig {
|
|
2
|
+
apiUrl?: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
projectId?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Load configuration from neurcode.config.json or environment variables
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadConfig(): NeurcodeConfig;
|
|
10
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,cAAc,CAmC3C"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
/**
|
|
7
|
+
* Load configuration from neurcode.config.json or environment variables
|
|
8
|
+
*/
|
|
9
|
+
function loadConfig() {
|
|
10
|
+
const config = {};
|
|
11
|
+
// Try to load from config file
|
|
12
|
+
const configPaths = [
|
|
13
|
+
(0, path_1.join)(process.cwd(), 'neurcode.config.json'),
|
|
14
|
+
(0, path_1.join)(process.cwd(), '.neurcode.json'),
|
|
15
|
+
(0, path_1.join)(process.env.HOME || '', '.neurcode.json')
|
|
16
|
+
];
|
|
17
|
+
for (const configPath of configPaths) {
|
|
18
|
+
if ((0, fs_1.existsSync)(configPath)) {
|
|
19
|
+
try {
|
|
20
|
+
const fileContent = (0, fs_1.readFileSync)(configPath, 'utf-8');
|
|
21
|
+
const fileConfig = JSON.parse(fileContent);
|
|
22
|
+
Object.assign(config, fileConfig);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
// Ignore parse errors, fall through to env vars
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Override with environment variables
|
|
31
|
+
if (process.env.NEURCODE_API_URL) {
|
|
32
|
+
config.apiUrl = process.env.NEURCODE_API_URL;
|
|
33
|
+
}
|
|
34
|
+
if (process.env.NEURCODE_API_KEY) {
|
|
35
|
+
config.apiKey = process.env.NEURCODE_API_KEY;
|
|
36
|
+
}
|
|
37
|
+
if (process.env.NEURCODE_PROJECT_ID) {
|
|
38
|
+
config.projectId = process.env.NEURCODE_PROJECT_ID;
|
|
39
|
+
}
|
|
40
|
+
return config;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAYA,gCAmCC;AA/CD,2BAA8C;AAC9C,+BAA4B;AAQ5B;;GAEG;AACH,SAAgB,UAAU;IACxB,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,+BAA+B;IAC/B,MAAM,WAAW,GAAG;QAClB,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,sBAAsB,CAAC;QAC3C,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC;QACrC,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,gBAAgB,CAAC;KAC/C,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBACtD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAC3C,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAClC,MAAM;YACR,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,gDAAgD;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACjC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QACpC,MAAM,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACrD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const check_1 = require("./commands/check");
|
|
6
|
+
const program = new commander_1.Command();
|
|
7
|
+
program
|
|
8
|
+
.name('neurcode')
|
|
9
|
+
.description('AI-powered code governance and diff analysis')
|
|
10
|
+
.version('0.1.0');
|
|
11
|
+
program
|
|
12
|
+
.command('check')
|
|
13
|
+
.description('Analyze git diff for risky changes')
|
|
14
|
+
.option('--staged', 'Check staged changes (git diff --staged)')
|
|
15
|
+
.option('--head', 'Check changes against HEAD (git diff HEAD)')
|
|
16
|
+
.option('--base <ref>', 'Check changes against a specific base ref')
|
|
17
|
+
.option('--online', 'Send diff to Neurcode API for analysis')
|
|
18
|
+
.option('--ai', 'Use AI-powered analysis (redundancy, bloat, intent matching)')
|
|
19
|
+
.option('--intent <description>', 'Describe what you intended to do (for AI analysis)')
|
|
20
|
+
.option('--session-id <id>', 'Use existing session ID (for AI analysis)')
|
|
21
|
+
.action(check_1.checkCommand);
|
|
22
|
+
program.parse();
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,4CAAgD;AAEhD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,UAAU,EAAE,0CAA0C,CAAC;KAC9D,MAAM,CAAC,QAAQ,EAAE,4CAA4C,CAAC;KAC9D,MAAM,CAAC,cAAc,EAAE,2CAA2C,CAAC;KACnE,MAAM,CAAC,UAAU,EAAE,wCAAwC,CAAC;KAC5D,MAAM,CAAC,MAAM,EAAE,8DAA8D,CAAC;KAC9E,MAAM,CAAC,wBAAwB,EAAE,oDAAoD,CAAC;KACtF,MAAM,CAAC,mBAAmB,EAAE,2CAA2C,CAAC;KACxE,MAAM,CAAC,oBAAY,CAAC,CAAC;AAExB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/rules.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export types and functions from policy engine
|
|
3
|
+
* This maintains backward compatibility while using the shared package
|
|
4
|
+
*/
|
|
5
|
+
import { DiffFile } from '@neurcode-ai/diff-parser';
|
|
6
|
+
import { type RuleResult } from '@neurcode-ai/policy-engine';
|
|
7
|
+
export { type RuleViolation, type RuleResult, type Decision, type Severity, createDefaultPolicy, defaultRules, } from '@neurcode-ai/policy-engine';
|
|
8
|
+
/**
|
|
9
|
+
* Evaluate rules using default policy
|
|
10
|
+
* This maintains backward compatibility with existing CLI code
|
|
11
|
+
*/
|
|
12
|
+
export declare function evaluateRules(diffFiles: DiffFile[]): RuleResult;
|
|
13
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAyE,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAEpI,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,mBAAmB,EACnB,YAAY,GACb,MAAM,4BAA4B,CAAC;AAEpC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,UAAU,CAG/D"}
|
package/dist/rules.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Re-export types and functions from policy engine
|
|
4
|
+
* This maintains backward compatibility while using the shared package
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.defaultRules = exports.createDefaultPolicy = void 0;
|
|
8
|
+
exports.evaluateRules = evaluateRules;
|
|
9
|
+
const policy_engine_1 = require("@neurcode-ai/policy-engine");
|
|
10
|
+
var policy_engine_2 = require("@neurcode-ai/policy-engine");
|
|
11
|
+
Object.defineProperty(exports, "createDefaultPolicy", { enumerable: true, get: function () { return policy_engine_2.createDefaultPolicy; } });
|
|
12
|
+
Object.defineProperty(exports, "defaultRules", { enumerable: true, get: function () { return policy_engine_2.defaultRules; } });
|
|
13
|
+
/**
|
|
14
|
+
* Evaluate rules using default policy
|
|
15
|
+
* This maintains backward compatibility with existing CLI code
|
|
16
|
+
*/
|
|
17
|
+
function evaluateRules(diffFiles) {
|
|
18
|
+
const defaultPolicy = (0, policy_engine_1.createDefaultPolicy)();
|
|
19
|
+
return (0, policy_engine_1.evaluateRules)(diffFiles, defaultPolicy.rules);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAkBH,sCAGC;AAlBD,8DAAoI;AAEpI,4DAOoC;AAFlC,oHAAA,mBAAmB,OAAA;AACnB,6GAAA,YAAY,OAAA;AAGd;;;GAGG;AACH,SAAgB,aAAa,CAAC,SAAqB;IACjD,MAAM,aAAa,GAAG,IAAA,mCAAmB,GAAE,CAAC;IAC5C,OAAO,IAAA,6BAAiB,EAAC,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;AAC3D,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neurcode-ai/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Neurcode CLI - AI code governance and diff analysis",
|
|
5
|
+
"bin": {
|
|
6
|
+
"neurcode": "./dist/index.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"prepublishOnly": "pnpm build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"cli",
|
|
22
|
+
"code-governance",
|
|
23
|
+
"diff-analysis",
|
|
24
|
+
"ai-safety",
|
|
25
|
+
"neurcode",
|
|
26
|
+
"ai-code-review",
|
|
27
|
+
"code-quality"
|
|
28
|
+
],
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"author": "Neurcode",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/sujit-jaunjal/neurcode.git",
|
|
34
|
+
"directory": "packages/cli"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@neurcode-ai/diff-parser": "workspace:*",
|
|
41
|
+
"@neurcode-ai/policy-engine": "workspace:*",
|
|
42
|
+
"commander": "^11.1.0"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^20.10.0",
|
|
49
|
+
"typescript": "^5.3.0"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|