@neurcode-ai/cli 0.9.5 ā 0.9.7
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 +6 -0
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +38 -14
- package/dist/api-client.js.map +1 -1
- package/dist/commands/apply.d.ts.map +1 -1
- package/dist/commands/apply.js +2 -1
- package/dist/commands/apply.js.map +1 -1
- package/dist/commands/init.d.ts +5 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +45 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +3 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +26 -7
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.d.ts +8 -2
- package/dist/commands/logout.d.ts.map +1 -1
- package/dist/commands/logout.js +30 -13
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/map.d.ts.map +1 -1
- package/dist/commands/map.js +6 -3
- package/dist/commands/map.js.map +1 -1
- package/dist/commands/plan.d.ts +1 -0
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +192 -29
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/prompt.d.ts.map +1 -1
- package/dist/commands/prompt.js +2 -1
- package/dist/commands/prompt.js.map +1 -1
- package/dist/commands/revert.d.ts.map +1 -1
- package/dist/commands/revert.js +5 -2
- package/dist/commands/revert.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +4 -2
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +2 -1
- package/dist/commands/watch.js.map +1 -1
- package/dist/config.d.ts +9 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +235 -133
- package/dist/config.js.map +1 -1
- package/dist/index.js +15 -6
- package/dist/index.js.map +1 -1
- package/dist/services/watch/CommandPoller.d.ts.map +1 -1
- package/dist/services/watch/CommandPoller.js +5 -0
- package/dist/services/watch/CommandPoller.js.map +1 -1
- package/dist/services/watch/Syncer.d.ts.map +1 -1
- package/dist/services/watch/Syncer.js +3 -0
- package/dist/services/watch/Syncer.js.map +1 -1
- package/dist/utils/gitignore.d.ts.map +1 -1
- package/dist/utils/gitignore.js +29 -7
- package/dist/utils/gitignore.js.map +1 -1
- package/dist/utils/neurcode-context.d.ts +24 -0
- package/dist/utils/neurcode-context.d.ts.map +1 -0
- package/dist/utils/neurcode-context.js +252 -0
- package/dist/utils/neurcode-context.js.map +1 -0
- package/dist/utils/plan-cache.d.ts +44 -0
- package/dist/utils/plan-cache.d.ts.map +1 -0
- package/dist/utils/plan-cache.js +227 -0
- package/dist/utils/plan-cache.js.map +1 -0
- package/dist/utils/project-root.d.ts +18 -0
- package/dist/utils/project-root.d.ts.map +1 -0
- package/dist/utils/project-root.js +44 -0
- package/dist/utils/project-root.js.map +1 -0
- package/dist/utils/secret-masking.d.ts +12 -0
- package/dist/utils/secret-masking.d.ts.map +1 -0
- package/dist/utils/secret-masking.js +34 -0
- package/dist/utils/secret-masking.js.map +1 -0
- package/dist/utils/state.d.ts.map +1 -1
- package/dist/utils/state.js +6 -5
- package/dist/utils/state.js.map +1 -1
- package/dist/utils/tier.d.ts.map +1 -1
- package/dist/utils/tier.js +7 -3
- package/dist/utils/tier.js.map +1 -1
- package/package.json +2 -2
package/dist/commands/login.js
CHANGED
|
@@ -43,18 +43,31 @@ exports.loginCommand = loginCommand;
|
|
|
43
43
|
const config_1 = require("../config");
|
|
44
44
|
const api_client_1 = require("../api-client");
|
|
45
45
|
const user_context_1 = require("../utils/user-context");
|
|
46
|
+
const state_1 = require("../utils/state");
|
|
46
47
|
const messages_1 = require("../utils/messages");
|
|
47
48
|
const POLL_INTERVAL = 3000; // 3 seconds
|
|
48
49
|
const MAX_POLL_ATTEMPTS = 100; // 5 minutes total (100 * 3s)
|
|
49
|
-
async function loginCommand() {
|
|
50
|
+
async function loginCommand(options) {
|
|
50
51
|
try {
|
|
51
52
|
const config = (0, config_1.loadConfig)();
|
|
52
53
|
const apiUrl = config.apiUrl || config_1.DEFAULT_API_URL;
|
|
53
|
-
//
|
|
54
|
-
const
|
|
54
|
+
// If we're in a linked directory, prefer org-scoped auth for that org.
|
|
55
|
+
const isUuid = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
|
|
56
|
+
const orgArgRaw = options?.orgId?.trim();
|
|
57
|
+
const desiredOrgIdFromArg = orgArgRaw ? orgArgRaw : undefined;
|
|
58
|
+
if (desiredOrgIdFromArg && !isUuid(desiredOrgIdFromArg)) {
|
|
59
|
+
(0, messages_1.printError)('Invalid organization ID', `Expected an internal UUID. Got: ${desiredOrgIdFromArg}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
const desiredOrgIdFromState = (0, state_1.getOrgId)() || undefined;
|
|
63
|
+
const desiredOrgId = desiredOrgIdFromArg || desiredOrgIdFromState;
|
|
64
|
+
const desiredOrgName = desiredOrgId && desiredOrgId === desiredOrgIdFromState ? (0, state_1.getOrgName)() : undefined;
|
|
65
|
+
// Check if user is already logged in (for this org, if applicable)
|
|
66
|
+
const existingApiKey = desiredOrgId ? (0, config_1.getApiKey)(desiredOrgId) : (0, config_1.getApiKey)();
|
|
55
67
|
if (existingApiKey) {
|
|
56
68
|
try {
|
|
57
69
|
// Validate the existing API key by fetching user info
|
|
70
|
+
config.apiKey = existingApiKey;
|
|
58
71
|
const client = new api_client_1.ApiClient(config);
|
|
59
72
|
const user = await client.getCurrentUser();
|
|
60
73
|
const userInfo = await (0, user_context_1.getUserInfo)();
|
|
@@ -74,6 +87,9 @@ async function loginCommand() {
|
|
|
74
87
|
}
|
|
75
88
|
await (0, messages_1.printSuccessBanner)('Neurcode CLI Authentication');
|
|
76
89
|
(0, messages_1.printInfo)('We\'ll open your browser to securely authenticate your account.');
|
|
90
|
+
if (desiredOrgId) {
|
|
91
|
+
(0, messages_1.printInfo)('Organization Scope', `This login will mint an API key for: ${desiredOrgName || desiredOrgId}`);
|
|
92
|
+
}
|
|
77
93
|
// Step 1: Initialize device flow
|
|
78
94
|
const initUrl = `${apiUrl}/cli/auth/init`;
|
|
79
95
|
let initResponse;
|
|
@@ -83,7 +99,9 @@ async function loginCommand() {
|
|
|
83
99
|
headers: {
|
|
84
100
|
'Content-Type': 'application/json',
|
|
85
101
|
},
|
|
86
|
-
body: JSON.stringify({
|
|
102
|
+
body: JSON.stringify({
|
|
103
|
+
organizationId: desiredOrgId || undefined,
|
|
104
|
+
}), // Fastify requires a body when Content-Type is application/json
|
|
87
105
|
});
|
|
88
106
|
}
|
|
89
107
|
catch (error) {
|
|
@@ -96,7 +114,7 @@ async function loginCommand() {
|
|
|
96
114
|
process.exit(1);
|
|
97
115
|
}
|
|
98
116
|
const initData = await initResponse.json();
|
|
99
|
-
const { deviceCode, userCode, verificationUrl
|
|
117
|
+
const { deviceCode, userCode, verificationUrl } = initData;
|
|
100
118
|
const openInBrowser = async () => {
|
|
101
119
|
(0, messages_1.printInfo)('Opening your browser for authentication...');
|
|
102
120
|
(0, messages_1.printWaiting)('Waiting for your approval', false);
|
|
@@ -164,13 +182,14 @@ async function loginCommand() {
|
|
|
164
182
|
const pollData = await pollResponse.json();
|
|
165
183
|
if (pollData.status === 'approved') {
|
|
166
184
|
if (pollData.apiKey) {
|
|
185
|
+
const savedOrgId = pollData.organizationId || desiredOrgId || undefined;
|
|
167
186
|
// Save API key to global config
|
|
168
|
-
(0, config_1.saveGlobalAuth)(pollData.apiKey, apiUrl);
|
|
187
|
+
(0, config_1.saveGlobalAuth)(pollData.apiKey, apiUrl, savedOrgId);
|
|
169
188
|
// Get user info for personalized message
|
|
170
189
|
const userInfo = await (0, user_context_1.getUserInfo)();
|
|
171
190
|
const userName = userInfo?.displayName || userInfo?.email || 'there';
|
|
172
191
|
await (0, messages_1.printSuccessBanner)('Authentication Successful!', `Welcome to Neurcode, ${userName}!`);
|
|
173
|
-
(0, messages_1.printSuccess)('Your CLI is now authenticated', `API key saved securely to ~/.neurcoderc\n You're all set to use Neurcode commands!`);
|
|
192
|
+
(0, messages_1.printSuccess)('Your CLI is now authenticated', `API key saved securely to ~/.neurcoderc${savedOrgId ? ` (org: ${savedOrgId.substring(0, 8)}...)` : ''}\n You're all set to use Neurcode commands!`);
|
|
174
193
|
(0, messages_1.printInfo)('Getting started', 'Try running: neurcode init (to set up your first project)');
|
|
175
194
|
approved = true;
|
|
176
195
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Logout Command
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* In a multi-tenant world, API keys are org-scoped.
|
|
5
|
+
* Default behavior:
|
|
6
|
+
* - If you're in a linked project directory (has orgId): remove the key for that org only.
|
|
7
|
+
* - Otherwise: remove all saved keys.
|
|
5
8
|
*/
|
|
6
|
-
export declare function logoutCommand(
|
|
9
|
+
export declare function logoutCommand(options?: {
|
|
10
|
+
all?: boolean;
|
|
11
|
+
orgId?: string;
|
|
12
|
+
}): Promise<void>;
|
|
7
13
|
//# sourceMappingURL=logout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAsBH,wBAAsB,aAAa,CAAC,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,iBA4D9E"}
|
package/dist/commands/logout.js
CHANGED
|
@@ -2,12 +2,16 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Logout Command
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* In a multi-tenant world, API keys are org-scoped.
|
|
6
|
+
* Default behavior:
|
|
7
|
+
* - If you're in a linked project directory (has orgId): remove the key for that org only.
|
|
8
|
+
* - Otherwise: remove all saved keys.
|
|
6
9
|
*/
|
|
7
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
11
|
exports.logoutCommand = logoutCommand;
|
|
9
12
|
const config_1 = require("../config");
|
|
10
13
|
const user_context_1 = require("../utils/user-context");
|
|
14
|
+
const state_1 = require("../utils/state");
|
|
11
15
|
// Import chalk with fallback
|
|
12
16
|
let chalk;
|
|
13
17
|
try {
|
|
@@ -24,22 +28,29 @@ catch {
|
|
|
24
28
|
white: (str) => str,
|
|
25
29
|
};
|
|
26
30
|
}
|
|
27
|
-
async function logoutCommand() {
|
|
31
|
+
async function logoutCommand(options) {
|
|
28
32
|
try {
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
console.log(chalk.dim(' No API key found in configuration files.\n'));
|
|
34
|
-
console.log(chalk.dim(' Run "neurcode login" to authenticate.\n'));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
33
|
+
const inferredOrgId = (0, state_1.getOrgId)();
|
|
34
|
+
const inferredOrgName = (0, state_1.getOrgName)();
|
|
35
|
+
const targetOrgId = options?.orgId || inferredOrgId || undefined;
|
|
36
|
+
const removeAll = options?.all === true || !targetOrgId;
|
|
37
37
|
// Delete API key from all file-based sources
|
|
38
|
-
const result = (0, config_1.deleteApiKeyFromAllSources)(
|
|
38
|
+
const result = (0, config_1.deleteApiKeyFromAllSources)({
|
|
39
|
+
all: removeAll,
|
|
40
|
+
orgId: removeAll ? undefined : targetOrgId,
|
|
41
|
+
});
|
|
39
42
|
(0, user_context_1.clearUserCache)();
|
|
40
43
|
if (!result.removedFromGlobal && !result.removedFromLocal) {
|
|
41
|
-
|
|
42
|
-
|
|
44
|
+
if (!removeAll && targetOrgId) {
|
|
45
|
+
console.log(chalk.yellow('\nā ļø No API key found for this organization.\n'));
|
|
46
|
+
console.log(chalk.dim(` Org: ${inferredOrgName || targetOrgId}`));
|
|
47
|
+
console.log(chalk.dim(' Run "neurcode login" to authenticate for this org.\n'));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.log(chalk.yellow('\nā ļø You are not currently logged in.\n'));
|
|
51
|
+
console.log(chalk.dim(' No API key found in configuration files.\n'));
|
|
52
|
+
console.log(chalk.dim(' Run "neurcode login" to authenticate.\n'));
|
|
53
|
+
}
|
|
43
54
|
return;
|
|
44
55
|
}
|
|
45
56
|
console.log(chalk.green('\nā
Successfully logged out!\n'));
|
|
@@ -53,6 +64,12 @@ async function logoutCommand() {
|
|
|
53
64
|
if (removedFrom.length > 0) {
|
|
54
65
|
console.log(chalk.dim(` API key removed from: ${removedFrom.join(', ')}`));
|
|
55
66
|
}
|
|
67
|
+
if (!removeAll && targetOrgId) {
|
|
68
|
+
console.log(chalk.dim(` Org scope removed: ${targetOrgId}`));
|
|
69
|
+
}
|
|
70
|
+
else if (removeAll && result.removedOrgIds && result.removedOrgIds.length > 0) {
|
|
71
|
+
console.log(chalk.dim(` Removed ${result.removedOrgIds.length} org-scoped key(s)`));
|
|
72
|
+
}
|
|
56
73
|
console.log(chalk.dim(' You can log in again with: neurcode login\n'));
|
|
57
74
|
}
|
|
58
75
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/commands/map.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,UAAU,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/commands/map.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,UAAU,EAAE,MAAM,mCAAmC,CAAC;AA+B/E;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAsB,GAAG,UAAU,GAAG,IAAI,CAe/E;AAkBD;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,iBAmDhD"}
|
package/dist/commands/map.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.mapCommand = mapCommand;
|
|
|
5
5
|
const fs_1 = require("fs");
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const ProjectScanner_1 = require("../services/mapper/ProjectScanner");
|
|
8
|
+
const project_root_1 = require("../utils/project-root");
|
|
8
9
|
// Import chalk with fallback for plain strings if not available
|
|
9
10
|
let chalk;
|
|
10
11
|
try {
|
|
@@ -35,7 +36,8 @@ function hideSpinner() {
|
|
|
35
36
|
* Load existing asset map if it exists
|
|
36
37
|
*/
|
|
37
38
|
function loadAssetMap(rootDir = process.cwd()) {
|
|
38
|
-
const
|
|
39
|
+
const resolvedRoot = rootDir ? (0, path_1.resolve)(rootDir) : (0, project_root_1.resolveNeurcodeProjectRoot)(process.cwd());
|
|
40
|
+
const mapPath = (0, path_1.join)(resolvedRoot, '.neurcode', 'asset-map.json');
|
|
39
41
|
if (!(0, fs_1.existsSync)(mapPath)) {
|
|
40
42
|
return null;
|
|
41
43
|
}
|
|
@@ -52,7 +54,8 @@ function loadAssetMap(rootDir = process.cwd()) {
|
|
|
52
54
|
* Save asset map to .neurcode/asset-map.json
|
|
53
55
|
*/
|
|
54
56
|
function saveAssetMap(map, rootDir = process.cwd()) {
|
|
55
|
-
const
|
|
57
|
+
const resolvedRoot = rootDir ? (0, path_1.resolve)(rootDir) : (0, project_root_1.resolveNeurcodeProjectRoot)(process.cwd());
|
|
58
|
+
const neurcodeDir = (0, path_1.join)(resolvedRoot, '.neurcode');
|
|
56
59
|
// Ensure .neurcode directory exists
|
|
57
60
|
if (!(0, fs_1.existsSync)(neurcodeDir)) {
|
|
58
61
|
(0, fs_1.mkdirSync)(neurcodeDir, { recursive: true });
|
|
@@ -65,7 +68,7 @@ function saveAssetMap(map, rootDir = process.cwd()) {
|
|
|
65
68
|
*/
|
|
66
69
|
async function mapCommand(rootDir) {
|
|
67
70
|
try {
|
|
68
|
-
const cwd = rootDir ? (0, path_1.resolve)(rootDir) : process.cwd();
|
|
71
|
+
const cwd = rootDir ? (0, path_1.resolve)(rootDir) : (0, project_root_1.resolveNeurcodeProjectRoot)(process.cwd());
|
|
69
72
|
showSpinner('Scanning codebase');
|
|
70
73
|
const scanner = new ProjectScanner_1.ProjectScanner(cwd);
|
|
71
74
|
const map = await scanner.scan();
|
package/dist/commands/map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/commands/map.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/commands/map.ts"],"names":[],"mappings":";;AAoCA,oCAeC;AAqBD,gCAmDC;AA3HD,2BAA0D;AAC1D,+BAAqC;AACrC,sEAA+E;AAC/E,wDAAmE;AAEnE,gEAAgE;AAChE,IAAI,KAAU,CAAC;AACf,IAAI,CAAC;IACH,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAAC,MAAM,CAAC;IACP,kEAAkE;IAClE,KAAK,GAAG;QACN,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QAC3B,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QAC5B,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QACzB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QAC1B,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QACzB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;QAC1B,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG;KAC5B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,UAAkB,OAAO,CAAC,GAAG,EAAE;IAC1D,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAA,yCAA0B,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5F,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,YAAY,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAElE,IAAI,CAAC,IAAA,eAAU,EAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAe,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,GAAe,EAAE,UAAkB,OAAO,CAAC,GAAG,EAAE;IACpE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAA,yCAA0B,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5F,MAAM,WAAW,GAAG,IAAA,WAAI,EAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAEpD,oCAAoC;IACpC,IAAI,CAAC,IAAA,eAAU,EAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,IAAA,cAAS,EAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IACpD,IAAA,kBAAa,EAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,UAAU,CAAC,OAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAA,yCAA0B,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAEnF,WAAW,CAAC,mBAAmB,CAAC,CAAC;QAEjC,MAAM,OAAO,GAAG,IAAI,+BAAc,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAEjC,WAAW,EAAE,CAAC;QAEd,eAAe;QACf,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAEvB,kBAAkB;QAClB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QAChD,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC;QAE7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,SAAS,cAAc,WAAW,mBAAmB,CAAC,CAAC,CAAC;QAC9F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC,CAAC;QAE1E,eAAe;QACf,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC1D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACzC,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAA4B,CAAC,CAAC;QAEjC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAChD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;QAExD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAExC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/commands/plan.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"AA4CA,UAAU,WAAW;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA0KD,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,iBA+vBrE"}
|
package/dist/commands/plan.js
CHANGED
|
@@ -43,6 +43,9 @@ const map_1 = require("./map");
|
|
|
43
43
|
const state_1 = require("../utils/state");
|
|
44
44
|
const ROILogger_1 = require("../utils/ROILogger");
|
|
45
45
|
const toolbox_service_1 = require("../services/toolbox-service");
|
|
46
|
+
const plan_cache_1 = require("../utils/plan-cache");
|
|
47
|
+
const neurcode_context_1 = require("../utils/neurcode-context");
|
|
48
|
+
const project_root_1 = require("../utils/project-root");
|
|
46
49
|
// Import chalk with fallback for plain strings if not available
|
|
47
50
|
let chalk;
|
|
48
51
|
try {
|
|
@@ -232,6 +235,65 @@ async function planCommand(intent, options) {
|
|
|
232
235
|
}
|
|
233
236
|
// Initialize API client (needed for TicketService)
|
|
234
237
|
const client = new api_client_1.ApiClient(config);
|
|
238
|
+
// āāā Fast Path: Local Plan Cache (Multi-Tenant Safe) āāāāāāāāāāāāāāāā
|
|
239
|
+
// If the same user/org/project runs the same intent against the same repo snapshot,
|
|
240
|
+
// return the cached plan immediately (no network, no file scanning).
|
|
241
|
+
const cwd = (0, project_root_1.resolveNeurcodeProjectRoot)(process.cwd());
|
|
242
|
+
const orgId = (0, state_1.getOrgId)();
|
|
243
|
+
const stateProjectId = (0, state_1.getProjectId)();
|
|
244
|
+
const finalProjectIdEarly = options.projectId || stateProjectId || config.projectId;
|
|
245
|
+
const shouldUseCache = options.cache !== false && process.env.NEURCODE_PLAN_NO_CACHE !== '1';
|
|
246
|
+
const staticContextEarly = (0, neurcode_context_1.loadStaticNeurcodeContext)(cwd, orgId && finalProjectIdEarly ? { orgId, projectId: finalProjectIdEarly } : undefined);
|
|
247
|
+
const ticketRef = options.issue
|
|
248
|
+
? `github_issue:${options.issue}`
|
|
249
|
+
: options.pr
|
|
250
|
+
? `github_pr:${options.pr}`
|
|
251
|
+
: options.ticket
|
|
252
|
+
? `ticket:${options.ticket}`
|
|
253
|
+
: undefined;
|
|
254
|
+
const gitFingerprint = (0, plan_cache_1.getGitRepoFingerprint)(cwd);
|
|
255
|
+
if (shouldUseCache && orgId && finalProjectIdEarly && gitFingerprint) {
|
|
256
|
+
const key = (0, plan_cache_1.computePlanCacheKey)({
|
|
257
|
+
schemaVersion: 1,
|
|
258
|
+
apiUrl: (config.apiUrl || '').replace(/\/$/, ''),
|
|
259
|
+
orgId,
|
|
260
|
+
projectId: finalProjectIdEarly,
|
|
261
|
+
intent: (0, plan_cache_1.normalizeIntent)(intent),
|
|
262
|
+
ticketRef,
|
|
263
|
+
contextHash: staticContextEarly.hash,
|
|
264
|
+
repo: gitFingerprint,
|
|
265
|
+
});
|
|
266
|
+
const cached = (0, plan_cache_1.readCachedPlan)(cwd, key);
|
|
267
|
+
if (cached) {
|
|
268
|
+
console.log(chalk.dim(`ā” Using cached plan (created: ${new Date(cached.createdAt).toLocaleString()})\n`));
|
|
269
|
+
displayPlan(cached.response.plan);
|
|
270
|
+
console.log(chalk.dim(`\nGenerated at: ${new Date(cached.response.timestamp).toLocaleString()} (cached)`));
|
|
271
|
+
if (cached.response.planId && cached.response.planId !== 'unknown') {
|
|
272
|
+
console.log(chalk.bold.cyan(`\nš Plan ID: ${cached.response.planId} (Cached)`));
|
|
273
|
+
console.log(chalk.dim(' Run \'neurcode prompt\' to generate a Cursor/AI prompt.'));
|
|
274
|
+
}
|
|
275
|
+
// Maintain the same state side-effects as a fresh plan.
|
|
276
|
+
try {
|
|
277
|
+
if (cached.response.planId && cached.response.planId !== 'unknown') {
|
|
278
|
+
(0, state_1.setActivePlanId)(cached.response.planId);
|
|
279
|
+
(0, state_1.setLastPlanGeneratedAt)(new Date().toISOString());
|
|
280
|
+
}
|
|
281
|
+
if (cached.response.sessionId) {
|
|
282
|
+
(0, state_1.setSessionId)(cached.response.sessionId);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
// ignore state write errors
|
|
287
|
+
}
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Create a local, gitignored context file scaffold (similar to CLAUDE.md workflows),
|
|
292
|
+
// so teams/users have a predictable place to add project-specific guidance.
|
|
293
|
+
// This runs only on interactive terminals to avoid polluting CI checkouts.
|
|
294
|
+
if (process.stdout.isTTY && !process.env.CI) {
|
|
295
|
+
(0, neurcode_context_1.ensureDefaultLocalContextFile)(cwd);
|
|
296
|
+
}
|
|
235
297
|
// Initialize Security Guard, Ticket Service, and Project Knowledge Service
|
|
236
298
|
const { SecurityGuard } = await Promise.resolve().then(() => __importStar(require('../services/security/SecurityGuard')));
|
|
237
299
|
const { TicketService } = await Promise.resolve().then(() => __importStar(require('../services/integrations/TicketService')));
|
|
@@ -241,7 +303,6 @@ async function planCommand(intent, options) {
|
|
|
241
303
|
const projectKnowledgeService = new ProjectKnowledgeService();
|
|
242
304
|
let enrichedIntent = intent.trim();
|
|
243
305
|
let ticketMetadata;
|
|
244
|
-
const cwd = process.cwd();
|
|
245
306
|
// Step 1: Fetch ticket context if --issue, --pr, or --ticket is provided
|
|
246
307
|
if (options.issue) {
|
|
247
308
|
try {
|
|
@@ -302,8 +363,7 @@ async function planCommand(intent, options) {
|
|
|
302
363
|
}
|
|
303
364
|
// CRITICAL: Check state file FIRST for headless workflow support
|
|
304
365
|
// Priority: state file (.neurcode/config.json) > config > auto-detection
|
|
305
|
-
|
|
306
|
-
let projectId = getProjectId(); // Priority 1: State file (headless-friendly)
|
|
366
|
+
let projectId = (0, state_1.getProjectId)(); // Priority 1: State file (headless-friendly)
|
|
307
367
|
// Fallback to config if state file doesn't have projectId
|
|
308
368
|
if (!projectId) {
|
|
309
369
|
projectId = config.projectId || null;
|
|
@@ -356,21 +416,113 @@ async function planCommand(intent, options) {
|
|
|
356
416
|
process.exit(1);
|
|
357
417
|
}
|
|
358
418
|
console.log(chalk.dim(`Found ${fileTree.length} files in project`));
|
|
359
|
-
//
|
|
419
|
+
// Load Neurcode static context (repo + local + org/project) early so it can:
|
|
420
|
+
// - influence plan generation
|
|
421
|
+
// - participate in the cache key (avoid stale cached plans after context edits)
|
|
422
|
+
const staticContext = (0, neurcode_context_1.loadStaticNeurcodeContext)(cwd, orgId && finalProjectIdForGuard ? { orgId, projectId: finalProjectIdForGuard } : undefined);
|
|
423
|
+
// If we couldn't use the git-based fast path (non-git projects), try a filesystem-based cache hit
|
|
424
|
+
// after we have the file tree fingerprint.
|
|
425
|
+
if (shouldUseCache && orgId && finalProjectIdForGuard && !gitFingerprint) {
|
|
426
|
+
const fsFingerprint = (0, plan_cache_1.getFilesystemFingerprintFromTree)(fileTree);
|
|
427
|
+
const key = (0, plan_cache_1.computePlanCacheKey)({
|
|
428
|
+
schemaVersion: 1,
|
|
429
|
+
apiUrl: (config.apiUrl || '').replace(/\/$/, ''),
|
|
430
|
+
orgId,
|
|
431
|
+
projectId: finalProjectIdForGuard,
|
|
432
|
+
intent: (0, plan_cache_1.normalizeIntent)(intent),
|
|
433
|
+
ticketRef,
|
|
434
|
+
contextHash: staticContext.hash,
|
|
435
|
+
repo: fsFingerprint,
|
|
436
|
+
});
|
|
437
|
+
const cached = (0, plan_cache_1.readCachedPlan)(cwd, key);
|
|
438
|
+
if (cached) {
|
|
439
|
+
console.log(chalk.dim(`ā” Using cached plan (created: ${new Date(cached.createdAt).toLocaleString()})\n`));
|
|
440
|
+
displayPlan(cached.response.plan);
|
|
441
|
+
console.log(chalk.dim(`\nGenerated at: ${new Date(cached.response.timestamp).toLocaleString()} (cached)`));
|
|
442
|
+
if (cached.response.planId && cached.response.planId !== 'unknown') {
|
|
443
|
+
console.log(chalk.bold.cyan(`\nš Plan ID: ${cached.response.planId} (Cached)`));
|
|
444
|
+
console.log(chalk.dim(' Run \'neurcode prompt\' to generate a Cursor/AI prompt.'));
|
|
445
|
+
}
|
|
446
|
+
try {
|
|
447
|
+
if (cached.response.planId && cached.response.planId !== 'unknown') {
|
|
448
|
+
(0, state_1.setActivePlanId)(cached.response.planId);
|
|
449
|
+
(0, state_1.setLastPlanGeneratedAt)(new Date().toISOString());
|
|
450
|
+
}
|
|
451
|
+
if (cached.response.sessionId) {
|
|
452
|
+
(0, state_1.setSessionId)(cached.response.sessionId);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
// ignore
|
|
457
|
+
}
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
// Step 2: Build enhanced intent with static context + org/project memory (before any LLM call)
|
|
462
|
+
let enhancedIntent = enrichedIntent;
|
|
463
|
+
if (staticContext.text) {
|
|
464
|
+
enhancedIntent = `${enhancedIntent}\n\n${staticContext.text}`;
|
|
465
|
+
}
|
|
466
|
+
if (orgId && finalProjectIdForGuard) {
|
|
467
|
+
const memoryTail = (0, neurcode_context_1.loadOrgProjectMemoryTail)(cwd, orgId, finalProjectIdForGuard);
|
|
468
|
+
if (memoryTail) {
|
|
469
|
+
enhancedIntent = `${enhancedIntent}\n\n${memoryTail}`;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
// Step 3: Load or create asset map for context injection (toolbox summary)
|
|
473
|
+
try {
|
|
474
|
+
const map = await ensureAssetMap(cwd);
|
|
475
|
+
if (map && map.globalExports.length > 0) {
|
|
476
|
+
// Pass intent to generateToolboxSummary for relevance filtering
|
|
477
|
+
const toolboxSummary = (0, toolbox_service_1.generateToolboxSummary)(map, enrichedIntent);
|
|
478
|
+
if (toolboxSummary) {
|
|
479
|
+
// Inject toolbox summary into intent (append; do not override context blocks)
|
|
480
|
+
enhancedIntent = `${enhancedIntent}\n\n${toolboxSummary}\n\nIMPORTANT: The "Available Tools" list above shows existing code that CAN be reused. Only reference tools from this list if they are directly relevant to the user's intent. Do not create new files, functions, or features unless the user explicitly requested them. The list is for reference only - not a requirement to use everything.`;
|
|
481
|
+
console.log(chalk.dim(`š¦ Loaded ${map.globalExports.length} exported assets, showing top 20 most relevant`));
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
catch (error) {
|
|
486
|
+
// If asset map loading fails, continue without it (graceful degradation)
|
|
487
|
+
if (process.env.DEBUG) {
|
|
488
|
+
console.warn(chalk.yellow(`ā ļø Could not load asset map: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// Retrieval augmentation: include summaries from similar cached plans (org+project scoped)
|
|
492
|
+
if (shouldUseCache && orgId && finalProjectIdForGuard) {
|
|
493
|
+
const similar = (0, plan_cache_1.findSimilarCachedPlans)(cwd, { orgId, projectId: finalProjectIdForGuard }, (0, plan_cache_1.normalizeIntent)(intent), 3);
|
|
494
|
+
if (similar.length > 0) {
|
|
495
|
+
const memoryLines = [];
|
|
496
|
+
memoryLines.push('PROJECT MEMORY (recent Neurcode plans in this repo; use only if relevant):');
|
|
497
|
+
similar.forEach((p, idx) => {
|
|
498
|
+
const summary = (p.response.plan.summary || '').trim().slice(0, 600);
|
|
499
|
+
const files = p.response.plan.files?.slice(0, 12).map(f => `${f.action}:${f.path}`).join(', ') || '';
|
|
500
|
+
memoryLines.push(`${idx + 1}) intent=\"${p.input.intent}\"`);
|
|
501
|
+
if (summary)
|
|
502
|
+
memoryLines.push(` summary=\"${summary}\"`);
|
|
503
|
+
if (files)
|
|
504
|
+
memoryLines.push(` files=${files}`);
|
|
505
|
+
if (p.response.planId && p.response.planId !== 'unknown')
|
|
506
|
+
memoryLines.push(` planId=${p.response.planId}`);
|
|
507
|
+
});
|
|
508
|
+
memoryLines.push('');
|
|
509
|
+
enhancedIntent = `${enhancedIntent}\n\n${memoryLines.join('\n')}`;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// Step 4: Pre-Flight Security Check - Scan for secrets (on full enhanced intent)
|
|
360
513
|
console.log(chalk.dim('š”ļø Running security scan...'));
|
|
361
|
-
const scanResult = await securityGuard.scanAndMask(
|
|
514
|
+
const scanResult = await securityGuard.scanAndMask(enhancedIntent, fileTree, cwd);
|
|
362
515
|
if (scanResult.hasSecrets) {
|
|
363
516
|
const secretCount = scanResult.secrets.length;
|
|
364
517
|
const secretFiles = new Set(scanResult.secrets.map(s => s.location));
|
|
365
518
|
// Log ROI event for secret interception (non-blocking)
|
|
366
519
|
try {
|
|
367
|
-
const finalProjectId = options.projectId || projectId || config.projectId;
|
|
368
520
|
(0, ROILogger_1.logROIEvent)('SECRET_INTERCEPTED', {
|
|
369
521
|
secretCount,
|
|
370
522
|
secretTypes: Array.from(new Set(scanResult.secrets.map(s => s.type))),
|
|
371
523
|
locations: Array.from(secretFiles),
|
|
372
524
|
masked: options.mask !== false,
|
|
373
|
-
},
|
|
525
|
+
}, finalProjectIdForGuard || null).catch(() => {
|
|
374
526
|
// Silently ignore - ROI logging should never block user workflows
|
|
375
527
|
});
|
|
376
528
|
}
|
|
@@ -383,9 +535,8 @@ async function planCommand(intent, options) {
|
|
|
383
535
|
scanResult.secrets.forEach(secret => {
|
|
384
536
|
console.log(chalk.yellow(` ${secret.severity.toUpperCase()}: ${secret.type} in ${secret.location}`));
|
|
385
537
|
});
|
|
386
|
-
// Use masked intent and files
|
|
387
538
|
if (scanResult.maskedIntent) {
|
|
388
|
-
|
|
539
|
+
enhancedIntent = scanResult.maskedIntent;
|
|
389
540
|
}
|
|
390
541
|
console.log(chalk.green('\nā
Secrets masked - proceeding with plan generation'));
|
|
391
542
|
}
|
|
@@ -404,26 +555,6 @@ async function planCommand(intent, options) {
|
|
|
404
555
|
else {
|
|
405
556
|
console.log(chalk.green('ā
Security scan passed - no secrets detected'));
|
|
406
557
|
}
|
|
407
|
-
// Step 3: Load or create asset map for context injection
|
|
408
|
-
let enhancedIntent = enrichedIntent; // Start with ticket-enriched intent (or original if no ticket)
|
|
409
|
-
try {
|
|
410
|
-
const map = await ensureAssetMap(cwd);
|
|
411
|
-
if (map && map.globalExports.length > 0) {
|
|
412
|
-
// Pass intent to generateToolboxSummary for relevance filtering
|
|
413
|
-
const toolboxSummary = (0, toolbox_service_1.generateToolboxSummary)(map, enrichedIntent);
|
|
414
|
-
if (toolboxSummary) {
|
|
415
|
-
// Inject toolbox summary into intent (append to enriched intent)
|
|
416
|
-
enhancedIntent = `${enrichedIntent}\n\n${toolboxSummary}\n\nIMPORTANT: The "Available Tools" list above shows existing code that CAN be reused. Only reference tools from this list if they are directly relevant to the user's intent. Do not create new files, functions, or features unless the user explicitly requested them. The list is for reference only - not a requirement to use everything.`;
|
|
417
|
-
console.log(chalk.dim(`š¦ Loaded ${map.globalExports.length} exported assets, showing top 20 most relevant`));
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
catch (error) {
|
|
422
|
-
// If asset map loading fails, continue without it (graceful degradation)
|
|
423
|
-
if (process.env.DEBUG) {
|
|
424
|
-
console.warn(chalk.yellow(`ā ļø Could not load asset map: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
558
|
// Check for active sessions before creating a new one
|
|
428
559
|
const finalProjectId = options.projectId || projectId || config.projectId;
|
|
429
560
|
if (finalProjectId && process.stdout.isTTY && !process.env.CI) {
|
|
@@ -528,6 +659,38 @@ async function planCommand(intent, options) {
|
|
|
528
659
|
// Step E: Pass 2 - The Architect (generate plan with selected files)
|
|
529
660
|
console.log(chalk.dim('š¤ Generating plan with selected files...\n'));
|
|
530
661
|
const response = await client.generatePlan(enhancedIntent, filesToUse, finalProjectId, ticketMetadata, projectSummary);
|
|
662
|
+
// Persist in local cache for instant repeat plans.
|
|
663
|
+
if (shouldUseCache && orgId && finalProjectIdForGuard) {
|
|
664
|
+
const repo = gitFingerprint || (0, plan_cache_1.getFilesystemFingerprintFromTree)(fileTree);
|
|
665
|
+
const key = (0, plan_cache_1.computePlanCacheKey)({
|
|
666
|
+
schemaVersion: 1,
|
|
667
|
+
apiUrl: (config.apiUrl || '').replace(/\/$/, ''),
|
|
668
|
+
orgId,
|
|
669
|
+
projectId: finalProjectIdForGuard,
|
|
670
|
+
intent: (0, plan_cache_1.normalizeIntent)(intent),
|
|
671
|
+
ticketRef,
|
|
672
|
+
contextHash: staticContext.hash,
|
|
673
|
+
repo,
|
|
674
|
+
});
|
|
675
|
+
(0, plan_cache_1.writeCachedPlan)(cwd, {
|
|
676
|
+
key,
|
|
677
|
+
input: {
|
|
678
|
+
schemaVersion: 1,
|
|
679
|
+
apiUrl: (config.apiUrl || '').replace(/\/$/, ''),
|
|
680
|
+
orgId,
|
|
681
|
+
projectId: finalProjectIdForGuard,
|
|
682
|
+
intent: (0, plan_cache_1.normalizeIntent)(intent),
|
|
683
|
+
ticketRef,
|
|
684
|
+
contextHash: staticContext.hash,
|
|
685
|
+
repo,
|
|
686
|
+
},
|
|
687
|
+
response,
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
// Persist org+project scoped memory (multi-tenant safe, local-only).
|
|
691
|
+
if (orgId && finalProjectIdForGuard) {
|
|
692
|
+
(0, neurcode_context_1.appendPlanToOrgProjectMemory)(cwd, orgId, finalProjectIdForGuard, intent, response);
|
|
693
|
+
}
|
|
531
694
|
// Pre-Flight Snapshot: Capture current state of files that will be MODIFIED
|
|
532
695
|
// This ensures we have a baseline to revert to if AI destroys files
|
|
533
696
|
const modifyFiles = response.plan.files.filter(f => f.action === 'MODIFY');
|