@neurcode-ai/cli 0.4.0 → 0.4.1
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/dist/api-client.d.ts +105 -17
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +388 -85
- package/dist/api-client.js.map +1 -1
- package/dist/commands/allow.d.ts.map +1 -1
- package/dist/commands/allow.js +6 -33
- package/dist/commands/allow.js.map +1 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +56 -13
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +134 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +365 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +8 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +209 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +7 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +70 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +210 -57
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/prompt.d.ts +6 -0
- package/dist/commands/prompt.d.ts.map +1 -0
- package/dist/commands/prompt.js +254 -0
- package/dist/commands/prompt.js.map +1 -0
- package/dist/commands/revert.d.ts.map +1 -1
- package/dist/commands/revert.js +10 -0
- package/dist/commands/revert.js.map +1 -1
- package/dist/commands/session.d.ts +29 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +382 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +127 -13
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/watch.d.ts +8 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +78 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config.d.ts +29 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +186 -21
- package/dist/config.js.map +1 -1
- package/dist/index.js +120 -3
- package/dist/index.js.map +1 -1
- package/dist/services/integrations/TicketService.d.ts +68 -0
- package/dist/services/integrations/TicketService.d.ts.map +1 -0
- package/dist/services/integrations/TicketService.js +151 -0
- package/dist/services/integrations/TicketService.js.map +1 -0
- package/dist/services/security/SecurityGuard.d.ts +80 -0
- package/dist/services/security/SecurityGuard.d.ts.map +1 -0
- package/dist/services/security/SecurityGuard.js +410 -0
- package/dist/services/security/SecurityGuard.js.map +1 -0
- package/dist/services/watch/BlobStore.d.ts +33 -0
- package/dist/services/watch/BlobStore.d.ts.map +1 -0
- package/dist/services/watch/BlobStore.js +108 -0
- package/dist/services/watch/BlobStore.js.map +1 -0
- package/dist/services/watch/CommandPoller.d.ts +76 -0
- package/dist/services/watch/CommandPoller.d.ts.map +1 -0
- package/dist/services/watch/CommandPoller.js +298 -0
- package/dist/services/watch/CommandPoller.js.map +1 -0
- package/dist/services/watch/Journal.d.ts +58 -0
- package/dist/services/watch/Journal.d.ts.map +1 -0
- package/dist/services/watch/Journal.js +144 -0
- package/dist/services/watch/Journal.js.map +1 -0
- package/dist/services/watch/Sentinel.d.ts +49 -0
- package/dist/services/watch/Sentinel.d.ts.map +1 -0
- package/dist/services/watch/Sentinel.js +205 -0
- package/dist/services/watch/Sentinel.js.map +1 -0
- package/dist/services/watch/Syncer.d.ts +55 -0
- package/dist/services/watch/Syncer.d.ts.map +1 -0
- package/dist/services/watch/Syncer.js +231 -0
- package/dist/services/watch/Syncer.js.map +1 -0
- package/dist/utils/ROILogger.d.ts +16 -0
- package/dist/utils/ROILogger.d.ts.map +1 -0
- package/dist/utils/ROILogger.js +45 -0
- package/dist/utils/ROILogger.js.map +1 -0
- package/dist/utils/box.d.ts +16 -0
- package/dist/utils/box.d.ts.map +1 -0
- package/dist/utils/box.js +85 -0
- package/dist/utils/box.js.map +1 -0
- package/dist/utils/gitignore.d.ts +10 -0
- package/dist/utils/gitignore.d.ts.map +1 -0
- package/dist/utils/gitignore.js +34 -0
- package/dist/utils/gitignore.js.map +1 -0
- package/dist/utils/messages.d.ts +81 -0
- package/dist/utils/messages.d.ts.map +1 -0
- package/dist/utils/messages.js +306 -0
- package/dist/utils/messages.js.map +1 -0
- package/dist/utils/restore.d.ts +14 -0
- package/dist/utils/restore.d.ts.map +1 -0
- package/dist/utils/restore.js +89 -0
- package/dist/utils/restore.js.map +1 -0
- package/dist/utils/state.d.ts +69 -0
- package/dist/utils/state.d.ts.map +1 -0
- package/dist/utils/state.js +151 -0
- package/dist/utils/state.js.map +1 -0
- package/dist/utils/user-context.d.ts +28 -0
- package/dist/utils/user-context.d.ts.map +1 -0
- package/dist/utils/user-context.js +68 -0
- package/dist/utils/user-context.js.map +1 -0
- package/package.json +11 -4
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Session Management Command
|
|
4
|
+
*
|
|
5
|
+
* Manages AI coding sessions - list, end, and view session status.
|
|
6
|
+
*
|
|
7
|
+
* Commands:
|
|
8
|
+
* - neurcode session list - List all sessions
|
|
9
|
+
* - neurcode session end - End the current or specified session
|
|
10
|
+
* - neurcode session status - Show status of current session
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.listSessionsCommand = listSessionsCommand;
|
|
47
|
+
exports.endSessionCommand = endSessionCommand;
|
|
48
|
+
exports.sessionStatusCommand = sessionStatusCommand;
|
|
49
|
+
const config_1 = require("../config");
|
|
50
|
+
const api_client_1 = require("../api-client");
|
|
51
|
+
const state_1 = require("../utils/state");
|
|
52
|
+
const messages_1 = require("../utils/messages");
|
|
53
|
+
const readline = __importStar(require("readline"));
|
|
54
|
+
// Import chalk with fallback
|
|
55
|
+
let chalk;
|
|
56
|
+
try {
|
|
57
|
+
chalk = require('chalk');
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
chalk = {
|
|
61
|
+
green: (str) => str,
|
|
62
|
+
yellow: (str) => str,
|
|
63
|
+
red: (str) => str,
|
|
64
|
+
bold: (str) => str,
|
|
65
|
+
dim: (str) => str,
|
|
66
|
+
cyan: (str) => str,
|
|
67
|
+
white: (str) => str,
|
|
68
|
+
blue: (str) => str,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Prompt user for input
|
|
73
|
+
*/
|
|
74
|
+
function promptUser(question) {
|
|
75
|
+
const rl = readline.createInterface({
|
|
76
|
+
input: process.stdin,
|
|
77
|
+
output: process.stdout,
|
|
78
|
+
});
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
rl.question(question, (answer) => {
|
|
81
|
+
rl.close();
|
|
82
|
+
resolve(answer.trim());
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* List all sessions
|
|
88
|
+
*/
|
|
89
|
+
async function listSessionsCommand(options) {
|
|
90
|
+
try {
|
|
91
|
+
const config = (0, config_1.loadConfig)();
|
|
92
|
+
if (!config.apiKey) {
|
|
93
|
+
config.apiKey = (0, config_1.requireApiKey)();
|
|
94
|
+
}
|
|
95
|
+
const client = new api_client_1.ApiClient(config);
|
|
96
|
+
const projectId = options.projectId || config.projectId;
|
|
97
|
+
(0, messages_1.printSection)('Session History');
|
|
98
|
+
(0, messages_1.printInfo)('Fetching sessions', projectId ? `Project: ${projectId}` : 'All projects');
|
|
99
|
+
const sessions = await client.getSessions(projectId, options.all ? 100 : 20);
|
|
100
|
+
if (sessions.length === 0) {
|
|
101
|
+
(0, messages_1.printInfo)('No Sessions Found', 'You haven\'t created any sessions yet.\n Start one with: neurcode plan "<your intent>"');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Group sessions by status
|
|
105
|
+
const activeSessions = sessions.filter(s => s.status === 'active');
|
|
106
|
+
const completedSessions = sessions.filter(s => s.status === 'completed');
|
|
107
|
+
const cancelledSessions = sessions.filter(s => s.status === 'cancelled');
|
|
108
|
+
if (activeSessions.length > 0) {
|
|
109
|
+
(0, messages_1.printSection)('Active Sessions');
|
|
110
|
+
const tableRows = [
|
|
111
|
+
['Session ID', 'Title/Intent', 'Created', 'Files Changed']
|
|
112
|
+
];
|
|
113
|
+
for (const session of activeSessions) {
|
|
114
|
+
const title = session.title || session.intentDescription || 'Untitled';
|
|
115
|
+
const shortId = session.sessionId.substring(0, 16) + '...';
|
|
116
|
+
const created = new Date(session.createdAt).toLocaleDateString();
|
|
117
|
+
tableRows.push([
|
|
118
|
+
shortId,
|
|
119
|
+
title.length > 40 ? title.substring(0, 40) + '...' : title,
|
|
120
|
+
created,
|
|
121
|
+
'—' // Files changed would need additional API call
|
|
122
|
+
]);
|
|
123
|
+
}
|
|
124
|
+
(0, messages_1.printTable)(tableRows);
|
|
125
|
+
}
|
|
126
|
+
if (completedSessions.length > 0) {
|
|
127
|
+
(0, messages_1.printSection)('Completed Sessions');
|
|
128
|
+
console.log(chalk.dim(` ${completedSessions.length} completed session(s)`));
|
|
129
|
+
if (!options.all && completedSessions.length > 5) {
|
|
130
|
+
console.log(chalk.dim(' (Showing most recent. Use --all to see all)'));
|
|
131
|
+
}
|
|
132
|
+
console.log('');
|
|
133
|
+
}
|
|
134
|
+
if (cancelledSessions.length > 0) {
|
|
135
|
+
(0, messages_1.printSection)('Cancelled Sessions');
|
|
136
|
+
console.log(chalk.dim(` ${cancelledSessions.length} cancelled session(s)`));
|
|
137
|
+
console.log('');
|
|
138
|
+
}
|
|
139
|
+
(0, messages_1.printInfo)('Session Management', [
|
|
140
|
+
`Active: ${activeSessions.length} | Completed: ${completedSessions.length} | Cancelled: ${cancelledSessions.length}`,
|
|
141
|
+
'End a session: neurcode session end [session-id]',
|
|
142
|
+
'View session details: neurcode session status [session-id]'
|
|
143
|
+
].join('\n • '));
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (error instanceof Error) {
|
|
147
|
+
if (error.message.includes('401') || error.message.includes('403')) {
|
|
148
|
+
await (0, messages_1.printAuthError)(error);
|
|
149
|
+
}
|
|
150
|
+
else if (error.message.includes('project') || error.message.includes('404')) {
|
|
151
|
+
(0, messages_1.printProjectError)(error, options.projectId);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
(0, messages_1.printError)('Failed to List Sessions', error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
(0, messages_1.printError)('Failed to List Sessions', String(error));
|
|
159
|
+
}
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* End a session
|
|
165
|
+
*/
|
|
166
|
+
async function endSessionCommand(options) {
|
|
167
|
+
try {
|
|
168
|
+
const config = (0, config_1.loadConfig)();
|
|
169
|
+
if (!config.apiKey) {
|
|
170
|
+
config.apiKey = (0, config_1.requireApiKey)();
|
|
171
|
+
}
|
|
172
|
+
const client = new api_client_1.ApiClient(config);
|
|
173
|
+
let sessionId = options.sessionId;
|
|
174
|
+
// If no session ID provided, try to get from state
|
|
175
|
+
if (!sessionId) {
|
|
176
|
+
const stateSessionId = (0, state_1.getSessionId)();
|
|
177
|
+
sessionId = stateSessionId || undefined;
|
|
178
|
+
if (!sessionId) {
|
|
179
|
+
// List active sessions and let user choose
|
|
180
|
+
(0, messages_1.printInfo)('No Active Session', 'Looking for active sessions...');
|
|
181
|
+
const sessions = await client.getSessions(config.projectId, 10);
|
|
182
|
+
const activeSessions = sessions.filter(s => s.status === 'active');
|
|
183
|
+
if (activeSessions.length === 0) {
|
|
184
|
+
(0, messages_1.printInfo)('No Active Sessions', 'There are no active sessions to end.');
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (activeSessions.length === 1) {
|
|
188
|
+
sessionId = activeSessions[0].sessionId;
|
|
189
|
+
const title = activeSessions[0].title || activeSessions[0].intentDescription || 'Untitled';
|
|
190
|
+
(0, messages_1.printInfo)('Found Active Session', `Ending: ${title}`);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
// Multiple active sessions - let user choose
|
|
194
|
+
(0, messages_1.printSection)('Multiple Active Sessions');
|
|
195
|
+
activeSessions.forEach((session, index) => {
|
|
196
|
+
const title = session.title || session.intentDescription || 'Untitled';
|
|
197
|
+
console.log(chalk.cyan(` ${index + 1}.`), chalk.white(title));
|
|
198
|
+
console.log(chalk.dim(` ${session.sessionId.substring(0, 20)}...`));
|
|
199
|
+
});
|
|
200
|
+
console.log('');
|
|
201
|
+
const answer = await promptUser(chalk.bold('Select session to end (1-' + activeSessions.length + '): '));
|
|
202
|
+
const choice = parseInt(answer, 10);
|
|
203
|
+
if (choice >= 1 && choice <= activeSessions.length) {
|
|
204
|
+
sessionId = activeSessions[choice - 1].sessionId;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
(0, messages_1.printError)('Invalid Selection', undefined, ['Please run the command again and select a valid number']);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (!sessionId) {
|
|
214
|
+
(0, messages_1.printError)('No Session Specified', undefined, [
|
|
215
|
+
'No session ID provided and no active session found',
|
|
216
|
+
'Usage: neurcode session end [session-id]',
|
|
217
|
+
'Or set a session: neurcode init'
|
|
218
|
+
]);
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
// Get session details first
|
|
222
|
+
try {
|
|
223
|
+
const sessionData = await client.getSession(sessionId);
|
|
224
|
+
const session = sessionData.session;
|
|
225
|
+
if (session.status === 'completed') {
|
|
226
|
+
(0, messages_1.printWarning)('Session Already Completed', `Session "${session.title || session.intentDescription || sessionId}" is already ended.`);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (session.status === 'cancelled') {
|
|
230
|
+
(0, messages_1.printWarning)('Session Already Cancelled', `Session "${session.title || session.intentDescription || sessionId}" was already cancelled.`);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// Show session summary
|
|
234
|
+
const title = session.title || session.intentDescription || 'Untitled Session';
|
|
235
|
+
const filesCount = sessionData.files?.length || 0;
|
|
236
|
+
(0, messages_1.printSection)('Session Summary');
|
|
237
|
+
console.log(chalk.white(` Title: ${title}`));
|
|
238
|
+
console.log(chalk.white(` Files Changed: ${filesCount}`));
|
|
239
|
+
console.log(chalk.dim(` Session ID: ${sessionId}`));
|
|
240
|
+
console.log('');
|
|
241
|
+
// Confirm before ending
|
|
242
|
+
const confirm = await promptUser(chalk.bold('End this session? (y/n): '));
|
|
243
|
+
if (confirm.toLowerCase() !== 'y' && confirm.toLowerCase() !== 'yes') {
|
|
244
|
+
(0, messages_1.printInfo)('Cancelled', 'Session was not ended.');
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
await client.endSession(sessionId);
|
|
248
|
+
// Clear session ID from local state if it matches the ended session
|
|
249
|
+
try {
|
|
250
|
+
const currentSessionId = (0, state_1.getSessionId)();
|
|
251
|
+
if (currentSessionId === sessionId) {
|
|
252
|
+
const { clearSessionId } = await Promise.resolve().then(() => __importStar(require('../utils/state')));
|
|
253
|
+
clearSessionId();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// Non-critical - continue if state clearing fails
|
|
258
|
+
}
|
|
259
|
+
const firstName = await (0, messages_1.getUserFirstName)();
|
|
260
|
+
await (0, messages_1.printSuccessBanner)('Session Completed', `Great work, ${firstName}! Your session has been marked as complete.`);
|
|
261
|
+
(0, messages_1.printSuccess)('Session Ended Successfully', `"${title}" is now marked as completed.\n View in dashboard: dashboard.neurcode.com`);
|
|
262
|
+
// Display Session ROI Summary
|
|
263
|
+
try {
|
|
264
|
+
// Fetch ROI summary from API
|
|
265
|
+
const apiUrl = config.apiUrl || process.env.NEURCODE_API_URL || 'https://api.neurcode.ai';
|
|
266
|
+
const roiUrl = `${apiUrl}/api/v1/roi/summary?timeRange=7d`;
|
|
267
|
+
const roiResponse = await fetch(roiUrl, {
|
|
268
|
+
headers: {
|
|
269
|
+
'Authorization': `Bearer ${config.apiKey}`,
|
|
270
|
+
'Content-Type': 'application/json',
|
|
271
|
+
},
|
|
272
|
+
}).catch(() => null);
|
|
273
|
+
if (roiResponse && roiResponse.ok) {
|
|
274
|
+
const roiData = await roiResponse.json().catch(() => null);
|
|
275
|
+
if (roiData && roiData.totalCapitalSaved) {
|
|
276
|
+
const capitalSaved = typeof roiData.totalCapitalSaved === 'string'
|
|
277
|
+
? parseFloat(roiData.totalCapitalSaved)
|
|
278
|
+
: roiData.totalCapitalSaved;
|
|
279
|
+
const formattedAmount = capitalSaved.toFixed(2);
|
|
280
|
+
const dashboardUrl = 'https://dashboard.neurcode.ai/roi';
|
|
281
|
+
console.log('');
|
|
282
|
+
console.log(chalk.cyan('📊'), chalk.bold.white('Current Session ROI:'), chalk.green.bold(`+$${formattedAmount}`));
|
|
283
|
+
console.log(chalk.dim(` View full report: ${dashboardUrl}`));
|
|
284
|
+
console.log('');
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
// Silently fail - ROI summary is a nice-to-have
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
if (error.message?.includes('not found') || error.message?.includes('404')) {
|
|
294
|
+
(0, messages_1.printError)('Session Not Found', error, [
|
|
295
|
+
`Session "${sessionId}" could not be found`,
|
|
296
|
+
'List your sessions: neurcode session list',
|
|
297
|
+
'Verify the session ID is correct'
|
|
298
|
+
]);
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
if (error instanceof Error) {
|
|
307
|
+
if (error.message.includes('401') || error.message.includes('403')) {
|
|
308
|
+
await (0, messages_1.printAuthError)(error);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
(0, messages_1.printError)('Failed to End Session', error);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
(0, messages_1.printError)('Failed to End Session', String(error));
|
|
316
|
+
}
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Show session status
|
|
322
|
+
*/
|
|
323
|
+
async function sessionStatusCommand(options) {
|
|
324
|
+
try {
|
|
325
|
+
const config = (0, config_1.loadConfig)();
|
|
326
|
+
if (!config.apiKey) {
|
|
327
|
+
config.apiKey = (0, config_1.requireApiKey)();
|
|
328
|
+
}
|
|
329
|
+
const client = new api_client_1.ApiClient(config);
|
|
330
|
+
let sessionId = options.sessionId || (0, state_1.getSessionId)();
|
|
331
|
+
if (!sessionId) {
|
|
332
|
+
(0, messages_1.printError)('No Session Found', undefined, [
|
|
333
|
+
'No active session in this directory',
|
|
334
|
+
'Start a session: neurcode plan "<your intent>"',
|
|
335
|
+
'Or specify a session: neurcode session status <session-id>'
|
|
336
|
+
]);
|
|
337
|
+
process.exit(1);
|
|
338
|
+
}
|
|
339
|
+
const sessionData = await client.getSession(sessionId);
|
|
340
|
+
const session = sessionData.session;
|
|
341
|
+
await (0, messages_1.printSuccessBanner)('Session Status');
|
|
342
|
+
(0, messages_1.printSection)('Session Details');
|
|
343
|
+
console.log(chalk.white(` Title: ${session.title || session.intentDescription || 'Untitled'}`));
|
|
344
|
+
console.log(chalk.white(` Status: ${session.status === 'active' ? chalk.green('Active') : session.status === 'completed' ? chalk.dim('Completed') : chalk.yellow('Cancelled')}`));
|
|
345
|
+
console.log(chalk.white(` Created: ${new Date(session.createdAt).toLocaleString()}`));
|
|
346
|
+
if (session.endedAt) {
|
|
347
|
+
console.log(chalk.white(` Ended: ${new Date(session.endedAt).toLocaleString()}`));
|
|
348
|
+
}
|
|
349
|
+
console.log(chalk.white(` Files Changed: ${sessionData.files?.length || 0}`));
|
|
350
|
+
console.log(chalk.dim(` Session ID: ${sessionId}`));
|
|
351
|
+
console.log('');
|
|
352
|
+
if (session.status === 'active') {
|
|
353
|
+
(0, messages_1.printInfo)('Active Session', [
|
|
354
|
+
'This session is currently active',
|
|
355
|
+
'End it with: neurcode session end',
|
|
356
|
+
'Or continue working and end it when done'
|
|
357
|
+
].join('\n • '));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
if (error instanceof Error) {
|
|
362
|
+
if (error.message.includes('401') || error.message.includes('403')) {
|
|
363
|
+
await (0, messages_1.printAuthError)(error);
|
|
364
|
+
}
|
|
365
|
+
else if (error.message.includes('not found') || error.message.includes('404')) {
|
|
366
|
+
(0, messages_1.printError)('Session Not Found', error, [
|
|
367
|
+
`Session "${options.sessionId || 'unknown'}" could not be found`,
|
|
368
|
+
'List your sessions: neurcode session list',
|
|
369
|
+
'Start a new session: neurcode plan "<your intent>"'
|
|
370
|
+
]);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
(0, messages_1.printError)('Failed to Get Session Status', error);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
(0, messages_1.printError)('Failed to Get Session Status', String(error));
|
|
378
|
+
}
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/commands/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/commands/verify.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkCH,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA4DD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,iBAohBzD"}
|
package/dist/commands/verify.js
CHANGED
|
@@ -12,10 +12,17 @@ const config_1 = require("../config");
|
|
|
12
12
|
const api_client_1 = require("../api-client");
|
|
13
13
|
const path_1 = require("path");
|
|
14
14
|
const fs_1 = require("fs");
|
|
15
|
+
const state_1 = require("../utils/state");
|
|
16
|
+
const ROILogger_1 = require("../utils/ROILogger");
|
|
17
|
+
const box_1 = require("../utils/box");
|
|
15
18
|
// Import chalk with fallback
|
|
16
19
|
let chalk;
|
|
17
20
|
try {
|
|
18
21
|
chalk = require('chalk');
|
|
22
|
+
// Disable colors in CI environments for cleaner logs
|
|
23
|
+
if (process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true') {
|
|
24
|
+
chalk.level = 0;
|
|
25
|
+
}
|
|
19
26
|
}
|
|
20
27
|
catch {
|
|
21
28
|
chalk = {
|
|
@@ -28,6 +35,50 @@ catch {
|
|
|
28
35
|
white: (str) => str,
|
|
29
36
|
};
|
|
30
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if a file path should be excluded from verification analysis
|
|
40
|
+
* Excludes internal/system files that should not count towards plan adherence
|
|
41
|
+
*/
|
|
42
|
+
function isExcludedFile(filePath) {
|
|
43
|
+
// Normalize path separators (handle both / and \)
|
|
44
|
+
const normalizedPath = filePath.replace(/\\/g, '/');
|
|
45
|
+
// Check if path starts with any excluded prefix
|
|
46
|
+
const excludedPrefixes = [
|
|
47
|
+
'.neurcode/',
|
|
48
|
+
'.git/',
|
|
49
|
+
'node_modules/',
|
|
50
|
+
];
|
|
51
|
+
// Check prefixes
|
|
52
|
+
for (const prefix of excludedPrefixes) {
|
|
53
|
+
if (normalizedPath.startsWith(prefix)) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Check for .DS_Store file (macOS system file) - can appear at any directory level
|
|
58
|
+
if (normalizedPath === '.DS_Store' || normalizedPath.endsWith('/.DS_Store')) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
// Exclude common meta-configuration files (gitignore, npmignore, dockerignore, etc.)
|
|
62
|
+
// These are project configuration files and shouldn't be part of scope checking
|
|
63
|
+
const configFilePatterns = [
|
|
64
|
+
/^\.gitignore$/,
|
|
65
|
+
/\.gitignore$/,
|
|
66
|
+
/^\.npmignore$/,
|
|
67
|
+
/\.npmignore$/,
|
|
68
|
+
/^\.dockerignore$/,
|
|
69
|
+
/\.dockerignore$/,
|
|
70
|
+
/^\.prettierignore$/,
|
|
71
|
+
/\.prettierignore$/,
|
|
72
|
+
/^\.eslintignore$/,
|
|
73
|
+
/\.eslintignore$/,
|
|
74
|
+
];
|
|
75
|
+
for (const pattern of configFilePatterns) {
|
|
76
|
+
if (pattern.test(normalizedPath)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
31
82
|
async function verifyCommand(options) {
|
|
32
83
|
try {
|
|
33
84
|
// Load configuration
|
|
@@ -116,7 +167,15 @@ async function verifyCommand(options) {
|
|
|
116
167
|
process.exit(0);
|
|
117
168
|
}
|
|
118
169
|
// Parse the diff
|
|
119
|
-
const
|
|
170
|
+
const allDiffFiles = (0, diff_parser_1.parseDiff)(diffText);
|
|
171
|
+
// Filter out internal/system files before analysis
|
|
172
|
+
// This prevents self-interference where the tool flags its own files as bloat
|
|
173
|
+
const diffFiles = allDiffFiles.filter(file => {
|
|
174
|
+
// Check both path and oldPath (for renames) against exclusion list
|
|
175
|
+
const excludePath = isExcludedFile(file.path);
|
|
176
|
+
const excludeOldPath = file.oldPath ? isExcludedFile(file.oldPath) : false;
|
|
177
|
+
return !excludePath && !excludeOldPath;
|
|
178
|
+
});
|
|
120
179
|
const summary = (0, diff_parser_1.getDiffSummary)(diffFiles);
|
|
121
180
|
if (diffFiles.length === 0) {
|
|
122
181
|
if (!options.json) {
|
|
@@ -142,15 +201,35 @@ async function verifyCommand(options) {
|
|
|
142
201
|
console.log(chalk.dim(` Found ${summary.totalFiles} file(s) changed`));
|
|
143
202
|
console.log(chalk.dim(` ${summary.totalAdded} lines added, ${summary.totalRemoved} lines removed\n`));
|
|
144
203
|
}
|
|
145
|
-
// Get planId
|
|
204
|
+
// Get planId: Priority 1: options flag, Priority 2: state file (.neurcode/config.json), Priority 3: legacy config
|
|
146
205
|
let planId = options.planId;
|
|
147
206
|
if (!planId) {
|
|
148
|
-
// Try to get planId from
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
planId =
|
|
207
|
+
// Try to get planId from state file (.neurcode/config.json) - this is the canonical source
|
|
208
|
+
const activePlanId = (0, state_1.getActivePlanId)();
|
|
209
|
+
if (activePlanId) {
|
|
210
|
+
planId = activePlanId;
|
|
152
211
|
if (!options.json) {
|
|
153
|
-
console.log(chalk.dim(` Using plan from
|
|
212
|
+
console.log(chalk.dim(` Using active plan from state: ${activePlanId.substring(0, 8)}...`));
|
|
213
|
+
// Optional check: Warn if plan is older than 24 hours
|
|
214
|
+
const lastPlanGeneratedAt = (0, state_1.getLastPlanGeneratedAt)();
|
|
215
|
+
if (lastPlanGeneratedAt) {
|
|
216
|
+
const planAge = Date.now() - new Date(lastPlanGeneratedAt).getTime();
|
|
217
|
+
const hoursSinceGeneration = planAge / (1000 * 60 * 60);
|
|
218
|
+
if (hoursSinceGeneration > 24) {
|
|
219
|
+
console.log(chalk.yellow(` ⚠️ Warning: This plan was generated ${Math.round(hoursSinceGeneration)} hours ago`));
|
|
220
|
+
console.log(chalk.yellow(` You may be verifying against an old plan. Consider running 'neurcode plan' to generate a new one.`));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
// Fallback: Try legacy config file (neurcode.config.json) for backward compatibility
|
|
227
|
+
if (configData.lastPlanId && typeof configData.lastPlanId === 'string') {
|
|
228
|
+
planId = configData.lastPlanId;
|
|
229
|
+
if (!options.json) {
|
|
230
|
+
console.log(chalk.dim(` Using plan from legacy config: ${configData.lastPlanId.substring(0, 8)}...`));
|
|
231
|
+
console.log(chalk.yellow(` ⚠️ Consider running 'neurcode plan' to update state file`));
|
|
232
|
+
}
|
|
154
233
|
}
|
|
155
234
|
}
|
|
156
235
|
}
|
|
@@ -197,10 +276,10 @@ async function verifyCommand(options) {
|
|
|
197
276
|
const planFiles = planData.content.files
|
|
198
277
|
.filter(f => f.action === 'CREATE' || f.action === 'MODIFY')
|
|
199
278
|
.map(f => f.path);
|
|
200
|
-
// Get sessionId from
|
|
201
|
-
// Fallback to sessionId from plan if not in config
|
|
279
|
+
// Get sessionId from state file (.neurcode/state.json) first, then fallback to config
|
|
280
|
+
// Fallback to sessionId from plan if not in state/config
|
|
202
281
|
// This is the session_id string needed to fetch the session
|
|
203
|
-
let sessionIdString = configData.sessionId || configData.lastSessionId || null;
|
|
282
|
+
let sessionIdString = (0, state_1.getSessionId)() || configData.sessionId || configData.lastSessionId || null;
|
|
204
283
|
// Fallback: Use sessionId from plan if not in config
|
|
205
284
|
if (!sessionIdString && planData.sessionId) {
|
|
206
285
|
sessionIdString = planData.sessionId;
|
|
@@ -327,6 +406,20 @@ async function verifyCommand(options) {
|
|
|
327
406
|
let grade;
|
|
328
407
|
if (verifyResult.verdict === 'PASS') {
|
|
329
408
|
grade = 'A';
|
|
409
|
+
// Log ROI event for PASS verification (non-blocking)
|
|
410
|
+
try {
|
|
411
|
+
(0, ROILogger_1.logROIEvent)('VERIFY_PASS', {
|
|
412
|
+
planId: finalPlanId,
|
|
413
|
+
adherenceScore: verifyResult.adherenceScore,
|
|
414
|
+
plannedFilesModified: verifyResult.plannedFilesModified,
|
|
415
|
+
totalPlannedFiles: verifyResult.totalPlannedFiles,
|
|
416
|
+
}, projectId || null).catch(() => {
|
|
417
|
+
// Silently ignore - ROI logging should never block user workflows
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
catch {
|
|
421
|
+
// Silently ignore - ROI logging should never block user workflows
|
|
422
|
+
}
|
|
330
423
|
}
|
|
331
424
|
else if (verifyResult.verdict === 'WARN') {
|
|
332
425
|
grade = verifyResult.adherenceScore >= 70 ? 'B' : verifyResult.adherenceScore >= 50 ? 'C' : 'D';
|
|
@@ -627,9 +720,7 @@ async function reportVerification(grade, violations, verifyResult, apiKey, apiUr
|
|
|
627
720
|
* Display verification results in a formatted report card
|
|
628
721
|
*/
|
|
629
722
|
function displayVerifyResults(result) {
|
|
630
|
-
|
|
631
|
-
console.log('━'.repeat(50));
|
|
632
|
-
// Display grade/score
|
|
723
|
+
// Calculate grade/score
|
|
633
724
|
let grade;
|
|
634
725
|
let gradeColor;
|
|
635
726
|
if (result.verdict === 'PASS') {
|
|
@@ -644,6 +735,29 @@ function displayVerifyResults(result) {
|
|
|
644
735
|
grade = 'F';
|
|
645
736
|
gradeColor = chalk.red;
|
|
646
737
|
}
|
|
738
|
+
// Calculate estimated time saved (5 minutes per VERIFY_PASS)
|
|
739
|
+
const estimatedMinutesSaved = result.verdict === 'PASS' ? 5 : 0;
|
|
740
|
+
// Calculate policy compliance percentage
|
|
741
|
+
const policyCompliance = result.bloatCount === 0 ? 100 : Math.max(0, 100 - (result.bloatCount * 10));
|
|
742
|
+
// Display Governance Badge for PASS verdicts
|
|
743
|
+
if (result.verdict === 'PASS') {
|
|
744
|
+
console.log('\n');
|
|
745
|
+
const badgeContent = [
|
|
746
|
+
`${chalk.bold.white('Governance Badge')}`,
|
|
747
|
+
'',
|
|
748
|
+
`${chalk.cyan('Grade:')} ${chalk.green.bold(grade)} ${chalk.dim(`(${result.adherenceScore}%)`)}`,
|
|
749
|
+
`${chalk.cyan('Estimated Time Saved:')} ${chalk.green.bold(`${estimatedMinutesSaved}m`)}`,
|
|
750
|
+
`${chalk.cyan('Policy Compliance:')} ${chalk.green.bold(`${policyCompliance}%`)}`,
|
|
751
|
+
].join('\n');
|
|
752
|
+
console.log((0, box_1.createBox)(badgeContent, {
|
|
753
|
+
borderColor: 'green',
|
|
754
|
+
titleColor: 'white',
|
|
755
|
+
padding: 2,
|
|
756
|
+
}));
|
|
757
|
+
console.log('');
|
|
758
|
+
}
|
|
759
|
+
console.log(chalk.bold.cyan('📋 Plan Adherence Report\n'));
|
|
760
|
+
console.log('━'.repeat(50));
|
|
647
761
|
const scoreDisplay = gradeColor(`Grade: ${grade} (${result.adherenceScore}%)`);
|
|
648
762
|
if (result.verdict === 'PASS') {
|
|
649
763
|
console.log(chalk.green('✅'), scoreDisplay);
|