@neurcode-ai/cli 0.9.5 → 0.9.6

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.
Files changed (48) hide show
  1. package/dist/api-client.d.ts +6 -0
  2. package/dist/api-client.d.ts.map +1 -1
  3. package/dist/api-client.js +38 -14
  4. package/dist/api-client.js.map +1 -1
  5. package/dist/commands/init.d.ts +5 -1
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +45 -6
  8. package/dist/commands/init.js.map +1 -1
  9. package/dist/commands/login.d.ts +3 -1
  10. package/dist/commands/login.d.ts.map +1 -1
  11. package/dist/commands/login.js +26 -7
  12. package/dist/commands/login.js.map +1 -1
  13. package/dist/commands/logout.d.ts +8 -2
  14. package/dist/commands/logout.d.ts.map +1 -1
  15. package/dist/commands/logout.js +30 -13
  16. package/dist/commands/logout.js.map +1 -1
  17. package/dist/commands/plan.d.ts +1 -0
  18. package/dist/commands/plan.d.ts.map +1 -1
  19. package/dist/commands/plan.js +191 -29
  20. package/dist/commands/plan.js.map +1 -1
  21. package/dist/config.d.ts +9 -13
  22. package/dist/config.d.ts.map +1 -1
  23. package/dist/config.js +230 -130
  24. package/dist/config.js.map +1 -1
  25. package/dist/index.js +15 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/services/watch/CommandPoller.d.ts.map +1 -1
  28. package/dist/services/watch/CommandPoller.js +5 -0
  29. package/dist/services/watch/CommandPoller.js.map +1 -1
  30. package/dist/services/watch/Syncer.d.ts.map +1 -1
  31. package/dist/services/watch/Syncer.js +3 -0
  32. package/dist/services/watch/Syncer.js.map +1 -1
  33. package/dist/utils/gitignore.d.ts.map +1 -1
  34. package/dist/utils/gitignore.js +29 -7
  35. package/dist/utils/gitignore.js.map +1 -1
  36. package/dist/utils/neurcode-context.d.ts +24 -0
  37. package/dist/utils/neurcode-context.d.ts.map +1 -0
  38. package/dist/utils/neurcode-context.js +252 -0
  39. package/dist/utils/neurcode-context.js.map +1 -0
  40. package/dist/utils/plan-cache.d.ts +44 -0
  41. package/dist/utils/plan-cache.d.ts.map +1 -0
  42. package/dist/utils/plan-cache.js +227 -0
  43. package/dist/utils/plan-cache.js.map +1 -0
  44. package/dist/utils/secret-masking.d.ts +12 -0
  45. package/dist/utils/secret-masking.d.ts.map +1 -0
  46. package/dist/utils/secret-masking.js +34 -0
  47. package/dist/utils/secret-masking.js.map +1 -0
  48. package/package.json +2 -2
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeIntent = normalizeIntent;
4
+ exports.getPlanCachePath = getPlanCachePath;
5
+ exports.computePlanCacheKey = computePlanCacheKey;
6
+ exports.getGitRepoFingerprint = getGitRepoFingerprint;
7
+ exports.getFilesystemFingerprintFromTree = getFilesystemFingerprintFromTree;
8
+ exports.readCachedPlan = readCachedPlan;
9
+ exports.writeCachedPlan = writeCachedPlan;
10
+ exports.findSimilarCachedPlans = findSimilarCachedPlans;
11
+ const child_process_1 = require("child_process");
12
+ const crypto_1 = require("crypto");
13
+ const fs_1 = require("fs");
14
+ const path_1 = require("path");
15
+ const secret_masking_1 = require("./secret-masking");
16
+ const CACHE_SCHEMA_VERSION = 1;
17
+ const CACHE_FILE_NAME = 'plan-cache.json';
18
+ const MAX_ENTRIES = 50;
19
+ function sha256Hex(input) {
20
+ return (0, crypto_1.createHash)('sha256').update(input).digest('hex');
21
+ }
22
+ function normalizeIntent(intent) {
23
+ return intent
24
+ .trim()
25
+ .replace(/\s+/g, ' ')
26
+ .toLowerCase();
27
+ }
28
+ function getPlanCachePath(cwd) {
29
+ return (0, path_1.join)(cwd, '.neurcode', CACHE_FILE_NAME);
30
+ }
31
+ function ensureNeurcodeDir(cwd) {
32
+ const dir = (0, path_1.join)(cwd, '.neurcode');
33
+ if (!(0, fs_1.existsSync)(dir)) {
34
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
35
+ }
36
+ }
37
+ function safeReadCacheFile(cachePath) {
38
+ if (!(0, fs_1.existsSync)(cachePath)) {
39
+ return { schemaVersion: CACHE_SCHEMA_VERSION, entries: {} };
40
+ }
41
+ try {
42
+ const raw = (0, fs_1.readFileSync)(cachePath, 'utf-8');
43
+ const parsed = JSON.parse(raw);
44
+ if (parsed.schemaVersion !== CACHE_SCHEMA_VERSION || !parsed.entries || typeof parsed.entries !== 'object') {
45
+ throw new Error('Invalid cache schema');
46
+ }
47
+ const cache = parsed;
48
+ // Best-effort: avoid persisting secrets in cached intents (older caches may include them).
49
+ // This does not affect cache keys (they remain stable), it only sanitizes the stored intent text.
50
+ try {
51
+ for (const entry of Object.values(cache.entries)) {
52
+ if (!entry?.input?.intent)
53
+ continue;
54
+ entry.input.intent = (0, secret_masking_1.maskSecretsInText)(entry.input.intent).masked;
55
+ }
56
+ }
57
+ catch {
58
+ // ignore
59
+ }
60
+ return cache;
61
+ }
62
+ catch {
63
+ // Preserve the corrupted file for debugging, but do not block the command.
64
+ try {
65
+ const corruptPath = cachePath.replace(/\.json$/, `.corrupt-${Date.now()}.json`);
66
+ (0, fs_1.renameSync)(cachePath, corruptPath);
67
+ }
68
+ catch {
69
+ // ignore
70
+ }
71
+ return { schemaVersion: CACHE_SCHEMA_VERSION, entries: {} };
72
+ }
73
+ }
74
+ function atomicWrite(cachePath, data) {
75
+ const tmpPath = `${cachePath}.tmp`;
76
+ (0, fs_1.writeFileSync)(tmpPath, data, 'utf-8');
77
+ (0, fs_1.renameSync)(tmpPath, cachePath);
78
+ }
79
+ function prune(cache) {
80
+ const keys = Object.keys(cache.entries);
81
+ if (keys.length <= MAX_ENTRIES)
82
+ return;
83
+ const sorted = keys
84
+ .map((k) => cache.entries[k])
85
+ .filter(Boolean)
86
+ .sort((a, b) => {
87
+ const aTime = Date.parse(a.lastUsedAt) || 0;
88
+ const bTime = Date.parse(b.lastUsedAt) || 0;
89
+ return aTime - bTime;
90
+ });
91
+ const toRemove = sorted.slice(0, Math.max(0, sorted.length - MAX_ENTRIES));
92
+ for (const entry of toRemove) {
93
+ delete cache.entries[entry.key];
94
+ }
95
+ }
96
+ function computePlanCacheKey(input) {
97
+ const safeIntent = (0, secret_masking_1.maskSecretsInText)(input.intent).masked;
98
+ // Use an explicit, stable string rather than JSON.stringify of arbitrary objects.
99
+ const payload = [
100
+ `v=${input.schemaVersion}`,
101
+ `apiUrl=${input.apiUrl}`,
102
+ `orgId=${input.orgId}`,
103
+ `projectId=${input.projectId}`,
104
+ `intent=${safeIntent}`,
105
+ `ticketRef=${input.ticketRef || ''}`,
106
+ `contextHash=${input.contextHash || ''}`,
107
+ `repo.kind=${input.repo.kind}`,
108
+ input.repo.kind === 'git'
109
+ ? `repo.headSha=${input.repo.headSha};repo.headTreeSha=${input.repo.headTreeSha};repo.statusHash=${input.repo.statusHash}`
110
+ : `repo.fileTreeHash=${input.repo.fileTreeHash}`,
111
+ ].join('\n');
112
+ return sha256Hex(payload);
113
+ }
114
+ function getGitRepoFingerprint(cwd) {
115
+ try {
116
+ const inside = (0, child_process_1.execSync)('git rev-parse --is-inside-work-tree', { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] })
117
+ .trim()
118
+ .toLowerCase();
119
+ if (inside !== 'true')
120
+ return null;
121
+ const headSha = (0, child_process_1.execSync)('git rev-parse HEAD', { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
122
+ const headTreeSha = (0, child_process_1.execSync)('git rev-parse HEAD^{tree}', { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
123
+ const status = (0, child_process_1.execSync)('git status --porcelain', { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
124
+ const statusHash = sha256Hex(status);
125
+ return { kind: 'git', headSha, headTreeSha, statusHash };
126
+ }
127
+ catch {
128
+ return null;
129
+ }
130
+ }
131
+ function getFilesystemFingerprintFromTree(fileTree) {
132
+ // Normalize ordering so the hash is stable even if scanning order changes.
133
+ const normalized = [...fileTree].sort().join('\n');
134
+ return { kind: 'filesystem', fileTreeHash: sha256Hex(normalized) };
135
+ }
136
+ function readCachedPlan(cwd, key) {
137
+ try {
138
+ const cachePath = getPlanCachePath(cwd);
139
+ const cache = safeReadCacheFile(cachePath);
140
+ const entry = cache.entries[key];
141
+ if (!entry)
142
+ return null;
143
+ // Update LRU metadata.
144
+ const now = new Date().toISOString();
145
+ entry.lastUsedAt = now;
146
+ entry.useCount = (entry.useCount || 0) + 1;
147
+ cache.entries[key] = entry;
148
+ prune(cache);
149
+ atomicWrite(cachePath, JSON.stringify(cache, null, 2) + '\n');
150
+ return entry;
151
+ }
152
+ catch {
153
+ return null;
154
+ }
155
+ }
156
+ function writeCachedPlan(cwd, entry) {
157
+ try {
158
+ ensureNeurcodeDir(cwd);
159
+ const cachePath = getPlanCachePath(cwd);
160
+ const cache = safeReadCacheFile(cachePath);
161
+ const now = new Date().toISOString();
162
+ const existing = cache.entries[entry.key];
163
+ const next = {
164
+ ...entry,
165
+ createdAt: existing?.createdAt || now,
166
+ lastUsedAt: now,
167
+ useCount: (existing?.useCount || 0) + 1,
168
+ };
169
+ // Best-effort: do not persist secrets in the on-disk cache.
170
+ try {
171
+ if (next.input?.intent) {
172
+ next.input.intent = (0, secret_masking_1.maskSecretsInText)(next.input.intent).masked;
173
+ }
174
+ }
175
+ catch {
176
+ // ignore
177
+ }
178
+ cache.entries[entry.key] = next;
179
+ prune(cache);
180
+ atomicWrite(cachePath, JSON.stringify(cache, null, 2) + '\n');
181
+ }
182
+ catch {
183
+ // Cache failures should never block plan generation.
184
+ }
185
+ }
186
+ function tokenize(text) {
187
+ return text
188
+ .toLowerCase()
189
+ .replace(/[^\w\s]/g, ' ')
190
+ .split(/\s+/)
191
+ .filter((t) => t.length >= 3);
192
+ }
193
+ function jaccard(a, b) {
194
+ if (a.size === 0 || b.size === 0)
195
+ return 0;
196
+ let inter = 0;
197
+ for (const x of a) {
198
+ if (b.has(x))
199
+ inter++;
200
+ }
201
+ const union = a.size + b.size - inter;
202
+ return union === 0 ? 0 : inter / union;
203
+ }
204
+ function findSimilarCachedPlans(cwd, filter, intent, k = 3) {
205
+ try {
206
+ const cachePath = getPlanCachePath(cwd);
207
+ const cache = safeReadCacheFile(cachePath);
208
+ const entries = Object.values(cache.entries);
209
+ const queryTokens = new Set(tokenize(intent));
210
+ const scored = entries
211
+ .filter((e) => e.input.orgId === filter.orgId && e.input.projectId === filter.projectId)
212
+ .map((e) => {
213
+ const eTokens = new Set(tokenize(e.input.intent));
214
+ const score = jaccard(queryTokens, eTokens);
215
+ return { entry: e, score };
216
+ })
217
+ .filter((s) => s.score > 0)
218
+ .sort((a, b) => b.score - a.score)
219
+ .slice(0, k)
220
+ .map((s) => s.entry);
221
+ return scored;
222
+ }
223
+ catch {
224
+ return [];
225
+ }
226
+ }
227
+ //# sourceMappingURL=plan-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-cache.js","sourceRoot":"","sources":["../../src/utils/plan-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Lightweight secret masking for local persistence (cache/memory files).
3
+ *
4
+ * This intentionally avoids importing the full SecurityGuard (ts-morph heavy),
5
+ * while still masking the most common secret patterns that users may paste into
6
+ * CLI intents or context files.
7
+ */
8
+ export declare function maskSecretsInText(text: string): {
9
+ masked: string;
10
+ changed: boolean;
11
+ };
12
+ //# sourceMappingURL=secret-masking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-masking.d.ts","sourceRoot":"","sources":["../../src/utils/secret-masking.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAyCpF"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.maskSecretsInText = maskSecretsInText;
4
+ const REDACTION_PLACEHOLDER = '[REDACTED_BY_NEURCODE]';
5
+ /**
6
+ * Lightweight secret masking for local persistence (cache/memory files).
7
+ *
8
+ * This intentionally avoids importing the full SecurityGuard (ts-morph heavy),
9
+ * while still masking the most common secret patterns that users may paste into
10
+ * CLI intents or context files.
11
+ */
12
+ function maskSecretsInText(text) {
13
+ if (!text)
14
+ return { masked: text, changed: false };
15
+ let masked = text;
16
+ const before = masked;
17
+ // Direct token patterns
18
+ masked = masked.replace(/\bAKIA[0-9A-Z]{16}\b/gi, REDACTION_PLACEHOLDER); // AWS access key id
19
+ masked = masked.replace(/\b(ghp|gho|ghu|ghs|ghr)_[a-zA-Z0-9]{36,}\b/gi, REDACTION_PLACEHOLDER); // GitHub tokens
20
+ // JWTs (common shape)
21
+ masked = masked.replace(/\beyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}\b/g, REDACTION_PLACEHOLDER);
22
+ // Connection strings / URLs with credentials
23
+ masked = masked.replace(/\b((?:postgresql?|mysql|mongodb(?:\+srv)?|redis):\/\/)([^\s]+)/gi, `$1${REDACTION_PLACEHOLDER}`);
24
+ // sshpass password inline
25
+ masked = masked.replace(/\b(sshpass\s+-p\s+)(['"])([^'"]+)\2/gi, `$1$2${REDACTION_PLACEHOLDER}$2`);
26
+ // bearer/token/apikey style assignments (keep the left side; redact the value)
27
+ masked = masked.replace(/\b((?:bearer|token|apikey)\s*[:=]\s*['"]?)([a-zA-Z0-9_\-]{32,})(['"]?)/gi, `$1${REDACTION_PLACEHOLDER}$3`);
28
+ // generic secret-like assignments (keep the left side; redact the value)
29
+ masked = masked.replace(/\b((?:password|secret|key|api[_-]?key|private[_-]?key|access[_-]?token|auth[_-]?token)\s*[:=]\s*['"]?)([a-zA-Z0-9_\-+/=]{20,})(['"]?)/gi, `$1${REDACTION_PLACEHOLDER}$3`);
30
+ // PEM private keys (multi-line)
31
+ masked = masked.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g, REDACTION_PLACEHOLDER);
32
+ return { masked, changed: masked !== before };
33
+ }
34
+ //# sourceMappingURL=secret-masking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-masking.js","sourceRoot":"","sources":["../../src/utils/secret-masking.ts"],"names":[],"mappings":";;AASA,8CAyCC;AAlDD,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAEvD;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAEnD,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,MAAM,MAAM,GAAG,MAAM,CAAC;IAEtB,wBAAwB;IACxB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,wBAAwB,EAAE,qBAAqB,CAAC,CAAC,CAAC,oBAAoB;IAC9F,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,8CAA8C,EAAE,qBAAqB,CAAC,CAAC,CAAC,gBAAgB;IAEhH,sBAAsB;IACtB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,oEAAoE,EAAE,qBAAqB,CAAC,CAAC;IAErH,6CAA6C;IAC7C,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,kEAAkE,EAClE,KAAK,qBAAqB,EAAE,CAC7B,CAAC;IAEF,0BAA0B;IAC1B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,uCAAuC,EAAE,OAAO,qBAAqB,IAAI,CAAC,CAAC;IAEnG,+EAA+E;IAC/E,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,0EAA0E,EAC1E,KAAK,qBAAqB,IAAI,CAC/B,CAAC;IAEF,yEAAyE;IACzE,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,yIAAyI,EACzI,KAAK,qBAAqB,IAAI,CAC/B,CAAC;IAEF,gCAAgC;IAChC,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,6EAA6E,EAC7E,qBAAqB,CACtB,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;AAChD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neurcode-ai/cli",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Neurcode CLI - AI code governance and diff analysis",
5
5
  "bin": {
6
6
  "neurcode": "./dist/index.js"
@@ -61,4 +61,4 @@
61
61
  "@types/uuid": "^9.0.8",
62
62
  "typescript": "^5.3.0"
63
63
  }
64
- }
64
+ }