@pellux/goodvibes-sdk 0.18.23 → 0.18.25
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/_internal/platform/runtime/ecosystem/catalog.d.ts +4 -0
- package/dist/_internal/platform/runtime/ecosystem/catalog.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/ecosystem/catalog.js +59 -64
- package/dist/_internal/platform/tools/edit/core.js +1 -1
- package/dist/_internal/platform/tools/edit/match.d.ts +2 -2
- package/dist/_internal/platform/tools/edit/match.d.ts.map +1 -1
- package/dist/_internal/platform/tools/edit/match.js +15 -4
- package/dist/_internal/platform/tools/find/structural.d.ts.map +1 -1
- package/dist/_internal/platform/tools/find/structural.js +15 -3
- package/package.json +1 -1
|
@@ -2,6 +2,10 @@ export type EcosystemEntryKind = 'plugin' | 'skill' | 'hook-pack' | 'policy-pack
|
|
|
2
2
|
export interface EcosystemCatalogPathOptions {
|
|
3
3
|
readonly cwd: string;
|
|
4
4
|
readonly homeDir: string;
|
|
5
|
+
readonly projectCatalogRoot?: string;
|
|
6
|
+
readonly userCatalogRoot?: string;
|
|
7
|
+
readonly projectInstallRoot?: string;
|
|
8
|
+
readonly userInstallRoot?: string;
|
|
5
9
|
}
|
|
6
10
|
export interface EcosystemCatalogEntry {
|
|
7
11
|
readonly id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/runtime/ecosystem/catalog.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,aAAa,CAAC;AAClF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/runtime/ecosystem/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,21 +2,29 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
4
|
import { VERSION } from '../../version.js';
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
function resolveCatalogRoot(options, scope) {
|
|
6
|
+
if (scope === 'project') {
|
|
7
|
+
return options.projectCatalogRoot ?? join(options.cwd, '.goodvibes', 'ecosystem');
|
|
8
|
+
}
|
|
9
|
+
return options.userCatalogRoot ?? join(options.homeDir, '.goodvibes', 'ecosystem');
|
|
10
|
+
}
|
|
11
|
+
function catalogPath(kind, options, scope) {
|
|
12
|
+
return join(resolveCatalogRoot(options, scope), `${kind}s.json`);
|
|
9
13
|
}
|
|
10
|
-
function catalogPaths(kind,
|
|
14
|
+
function catalogPaths(kind, options) {
|
|
11
15
|
return [
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
catalogPath(kind, options, 'project'),
|
|
17
|
+
catalogPath(kind, options, 'user'),
|
|
14
18
|
];
|
|
15
19
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
function resolveInstallRoot(options, scope) {
|
|
21
|
+
if (scope === 'project') {
|
|
22
|
+
return options.projectInstallRoot ?? join(options.cwd, '.goodvibes');
|
|
23
|
+
}
|
|
24
|
+
return options.userInstallRoot ?? join(options.homeDir, '.goodvibes');
|
|
25
|
+
}
|
|
26
|
+
function installedRoot(kind, options, scope) {
|
|
27
|
+
const base = resolveInstallRoot(options, scope);
|
|
20
28
|
switch (kind) {
|
|
21
29
|
case 'plugin':
|
|
22
30
|
return join(base, 'plugins');
|
|
@@ -28,26 +36,24 @@ function installedRoot(kind, cwd, homeDir, scope) {
|
|
|
28
36
|
return join(base, 'policies', 'packs');
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
|
-
function installedReceiptsRoot(
|
|
32
|
-
return scope
|
|
33
|
-
? join(cwd, '.goodvibes', 'ecosystem', 'installed')
|
|
34
|
-
: join(homeDir, '.goodvibes', 'ecosystem', 'installed');
|
|
39
|
+
function installedReceiptsRoot(options, scope) {
|
|
40
|
+
return join(resolveCatalogRoot(options, scope), 'installed');
|
|
35
41
|
}
|
|
36
|
-
function receiptPath(kind, entryId,
|
|
37
|
-
const base = installedReceiptsRoot(
|
|
42
|
+
function receiptPath(kind, entryId, options, scope) {
|
|
43
|
+
const base = installedReceiptsRoot(options, scope);
|
|
38
44
|
return join(base, `${kind}-${entryId}.json`);
|
|
39
45
|
}
|
|
40
|
-
function backupRoot(
|
|
41
|
-
return join(installedReceiptsRoot(
|
|
46
|
+
function backupRoot(options, scope) {
|
|
47
|
+
return join(installedReceiptsRoot(options, scope), 'backups');
|
|
42
48
|
}
|
|
43
49
|
function backupPrefix(kind, entryId) {
|
|
44
50
|
return `${kind}-${entryId}`;
|
|
45
51
|
}
|
|
46
|
-
function backupMetaPath(kind, entryId, createdAt,
|
|
47
|
-
return join(backupRoot(
|
|
52
|
+
function backupMetaPath(kind, entryId, createdAt, options, scope) {
|
|
53
|
+
return join(backupRoot(options, scope), `${backupPrefix(kind, entryId)}-${createdAt}.json`);
|
|
48
54
|
}
|
|
49
|
-
function backupArchivePath(kind, entryId, createdAt,
|
|
50
|
-
return join(backupRoot(
|
|
55
|
+
function backupArchivePath(kind, entryId, createdAt, options, scope) {
|
|
56
|
+
return join(backupRoot(options, scope), `${backupPrefix(kind, entryId)}-${createdAt}`);
|
|
51
57
|
}
|
|
52
58
|
function loadReceipt(path) {
|
|
53
59
|
if (!existsSync(path))
|
|
@@ -71,9 +77,9 @@ function loadBackup(path) {
|
|
|
71
77
|
return null;
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
|
-
function createBackupFromReceipt(receipt, reason,
|
|
80
|
+
function createBackupFromReceipt(receipt, reason, options) {
|
|
75
81
|
const createdAt = Date.now();
|
|
76
|
-
const archivedTargetPath = backupArchivePath(receipt.kind, receipt.entry.id, createdAt,
|
|
82
|
+
const archivedTargetPath = backupArchivePath(receipt.kind, receipt.entry.id, createdAt, options, receipt.scope);
|
|
77
83
|
mkdirSync(dirname(archivedTargetPath), { recursive: true });
|
|
78
84
|
rmSync(archivedTargetPath, { recursive: true, force: true });
|
|
79
85
|
if (existsSync(receipt.targetPath)) {
|
|
@@ -93,7 +99,7 @@ function createBackupFromReceipt(receipt, reason, cwd, homeDir) {
|
|
|
93
99
|
receipt,
|
|
94
100
|
reason,
|
|
95
101
|
};
|
|
96
|
-
const metaPath = backupMetaPath(receipt.kind, receipt.entry.id, createdAt,
|
|
102
|
+
const metaPath = backupMetaPath(receipt.kind, receipt.entry.id, createdAt, options, receipt.scope);
|
|
97
103
|
writeFileSync(metaPath, `${JSON.stringify(backup, null, 2)}\n`, 'utf-8');
|
|
98
104
|
return backup;
|
|
99
105
|
}
|
|
@@ -168,10 +174,9 @@ function readCatalogDocument(path) {
|
|
|
168
174
|
}
|
|
169
175
|
}
|
|
170
176
|
export function loadEcosystemCatalog(kind, options) {
|
|
171
|
-
const { cwd, homeDir } = options;
|
|
172
177
|
const seen = new Set();
|
|
173
178
|
const entries = [];
|
|
174
|
-
for (const path of catalogPaths(kind,
|
|
179
|
+
for (const path of catalogPaths(kind, options)) {
|
|
175
180
|
for (const entry of readCatalogFile(path)) {
|
|
176
181
|
if (entry.kind !== kind)
|
|
177
182
|
continue;
|
|
@@ -239,24 +244,23 @@ export function reviewEcosystemCatalogEntry(entry, options) {
|
|
|
239
244
|
};
|
|
240
245
|
}
|
|
241
246
|
export function installEcosystemCatalogEntry(kind, entryId, options) {
|
|
242
|
-
const { cwd, homeDir } = options;
|
|
243
247
|
const scope = options.scope ?? 'project';
|
|
244
|
-
const entry = loadEcosystemCatalog(kind,
|
|
248
|
+
const entry = loadEcosystemCatalog(kind, options).find((candidate) => candidate.id === entryId);
|
|
245
249
|
if (!entry)
|
|
246
250
|
return { ok: false, error: `Unknown curated ${kind} entry: ${entryId}` };
|
|
247
|
-
const review = reviewEcosystemCatalogEntry(entry,
|
|
251
|
+
const review = reviewEcosystemCatalogEntry(entry, options);
|
|
248
252
|
if (review.sourceKind !== 'local-path') {
|
|
249
253
|
return { ok: false, error: `Curated ${kind} entry ${entryId} is not a local path source and cannot be installed directly.` };
|
|
250
254
|
}
|
|
251
255
|
if (!review.sourceExists) {
|
|
252
256
|
return { ok: false, error: `Curated ${kind} source path does not exist: ${review.sourcePath}` };
|
|
253
257
|
}
|
|
254
|
-
const targetPath = join(installedRoot(kind,
|
|
255
|
-
const previousReceipt = loadReceipt(receiptPath(kind, entry.id,
|
|
258
|
+
const targetPath = join(installedRoot(kind, options, scope), entry.id);
|
|
259
|
+
const previousReceipt = loadReceipt(receiptPath(kind, entry.id, options, scope));
|
|
256
260
|
if (previousReceipt && !options.skipBackup) {
|
|
257
|
-
createBackupFromReceipt(previousReceipt, 'replace',
|
|
261
|
+
createBackupFromReceipt(previousReceipt, 'replace', options);
|
|
258
262
|
}
|
|
259
|
-
mkdirSync(installedRoot(kind,
|
|
263
|
+
mkdirSync(installedRoot(kind, options, scope), { recursive: true });
|
|
260
264
|
rmSync(targetPath, { recursive: true, force: true });
|
|
261
265
|
cpSync(review.sourcePath, targetPath, { recursive: true });
|
|
262
266
|
const receipt = {
|
|
@@ -276,48 +280,44 @@ export function installEcosystemCatalogEntry(kind, entryId, options) {
|
|
|
276
280
|
reasons: review.compatibility.reasons,
|
|
277
281
|
},
|
|
278
282
|
};
|
|
279
|
-
const path = receiptPath(kind, entry.id,
|
|
283
|
+
const path = receiptPath(kind, entry.id, options, scope);
|
|
280
284
|
mkdirSync(dirname(path), { recursive: true });
|
|
281
285
|
writeFileSync(path, `${JSON.stringify(receipt, null, 2)}\n`, 'utf-8');
|
|
282
286
|
return { ok: true, receipt };
|
|
283
287
|
}
|
|
284
288
|
export function inspectInstalledEcosystemEntry(kind, entryId, options) {
|
|
285
|
-
const { cwd, homeDir } = options;
|
|
286
289
|
const scope = options.scope ?? 'project';
|
|
287
|
-
const receipt = loadReceipt(receiptPath(kind, entryId,
|
|
290
|
+
const receipt = loadReceipt(receiptPath(kind, entryId, options, scope));
|
|
288
291
|
if (!receipt) {
|
|
289
292
|
return { ok: false, error: `No installed ${kind} receipt found for ${entryId} in ${scope} scope.` };
|
|
290
293
|
}
|
|
291
294
|
return { ok: true, receipt };
|
|
292
295
|
}
|
|
293
296
|
export function uninstallEcosystemCatalogEntry(kind, entryId, options) {
|
|
294
|
-
const { cwd, homeDir } = options;
|
|
295
297
|
const scope = options.scope ?? 'project';
|
|
296
|
-
const receipt = loadReceipt(receiptPath(kind, entryId,
|
|
298
|
+
const receipt = loadReceipt(receiptPath(kind, entryId, options, scope));
|
|
297
299
|
if (!receipt)
|
|
298
300
|
return { ok: false, error: `No installed ${kind} receipt found for ${entryId} in ${scope} scope.` };
|
|
299
|
-
createBackupFromReceipt(receipt, 'uninstall',
|
|
301
|
+
createBackupFromReceipt(receipt, 'uninstall', options);
|
|
300
302
|
rmSync(receipt.targetPath, { recursive: true, force: true });
|
|
301
|
-
rmSync(receiptPath(kind, entryId,
|
|
303
|
+
rmSync(receiptPath(kind, entryId, options, scope), { force: true });
|
|
302
304
|
return { ok: true, removedPath: receipt.targetPath };
|
|
303
305
|
}
|
|
304
306
|
export function updateInstalledEcosystemEntry(kind, entryId, options) {
|
|
305
|
-
const { cwd, homeDir } = options;
|
|
306
307
|
const scope = options.scope ?? 'project';
|
|
307
|
-
const previousReceipt = loadReceipt(receiptPath(kind, entryId,
|
|
308
|
+
const previousReceipt = loadReceipt(receiptPath(kind, entryId, options, scope));
|
|
308
309
|
if (!previousReceipt) {
|
|
309
310
|
return { ok: false, error: `No installed ${kind} receipt found for ${entryId} in ${scope} scope.` };
|
|
310
311
|
}
|
|
311
|
-
createBackupFromReceipt(previousReceipt, 'update',
|
|
312
|
-
const installed = installEcosystemCatalogEntry(kind, entryId, {
|
|
312
|
+
createBackupFromReceipt(previousReceipt, 'update', options);
|
|
313
|
+
const installed = installEcosystemCatalogEntry(kind, entryId, { ...options, scope, skipBackup: true });
|
|
313
314
|
if (!installed.ok)
|
|
314
315
|
return installed;
|
|
315
316
|
return { ok: true, receipt: installed.receipt, previousReceipt };
|
|
316
317
|
}
|
|
317
318
|
export function listEcosystemInstallBackups(kind, entryId, options) {
|
|
318
|
-
const { cwd, homeDir } = options;
|
|
319
319
|
const scope = options.scope ?? 'project';
|
|
320
|
-
const dir = backupRoot(
|
|
320
|
+
const dir = backupRoot(options, scope);
|
|
321
321
|
if (!existsSync(dir))
|
|
322
322
|
return [];
|
|
323
323
|
const prefix = `${backupPrefix(kind, entryId)}-`;
|
|
@@ -328,9 +328,8 @@ export function listEcosystemInstallBackups(kind, entryId, options) {
|
|
|
328
328
|
.sort((a, b) => b.createdAt - a.createdAt);
|
|
329
329
|
}
|
|
330
330
|
export function rollbackInstalledEcosystemEntry(kind, entryId, options) {
|
|
331
|
-
const { cwd, homeDir } = options;
|
|
332
331
|
const scope = options.scope ?? 'project';
|
|
333
|
-
const backups = listEcosystemInstallBackups(kind, entryId, {
|
|
332
|
+
const backups = listEcosystemInstallBackups(kind, entryId, { ...options, scope });
|
|
334
333
|
const backup = options.backupId
|
|
335
334
|
? backups.find((candidate) => candidate.id === options.backupId)
|
|
336
335
|
: backups[0];
|
|
@@ -340,14 +339,13 @@ export function rollbackInstalledEcosystemEntry(kind, entryId, options) {
|
|
|
340
339
|
mkdirSync(dirname(backup.targetPath), { recursive: true });
|
|
341
340
|
rmSync(backup.targetPath, { recursive: true, force: true });
|
|
342
341
|
cpSync(backup.archivedTargetPath, backup.targetPath, { recursive: true });
|
|
343
|
-
writeFileSync(receiptPath(kind, entryId,
|
|
342
|
+
writeFileSync(receiptPath(kind, entryId, options, scope), `${JSON.stringify(backup.receipt, null, 2)}\n`, 'utf-8');
|
|
344
343
|
return { ok: true, receipt: backup.receipt, restoredFrom: backup };
|
|
345
344
|
}
|
|
346
345
|
export function listInstalledEcosystemEntries(kind, options) {
|
|
347
|
-
const { cwd, homeDir } = options;
|
|
348
346
|
const receipts = [
|
|
349
|
-
installedReceiptsRoot(
|
|
350
|
-
installedReceiptsRoot(
|
|
347
|
+
installedReceiptsRoot(options, 'project'),
|
|
348
|
+
installedReceiptsRoot(options, 'user'),
|
|
351
349
|
];
|
|
352
350
|
const found = [];
|
|
353
351
|
for (const dir of receipts) {
|
|
@@ -364,12 +362,11 @@ export function listInstalledEcosystemEntries(kind, options) {
|
|
|
364
362
|
return found.sort((a, b) => b.installedAt - a.installedAt);
|
|
365
363
|
}
|
|
366
364
|
export function exportEcosystemCatalogBundle(scope, options) {
|
|
367
|
-
const { cwd, homeDir } = options;
|
|
368
365
|
const paths = {
|
|
369
|
-
plugin: catalogPath('plugin',
|
|
370
|
-
skill: catalogPath('skill',
|
|
371
|
-
'hook-pack': catalogPath('hook-pack',
|
|
372
|
-
'policy-pack': catalogPath('policy-pack',
|
|
366
|
+
plugin: catalogPath('plugin', options, scope),
|
|
367
|
+
skill: catalogPath('skill', options, scope),
|
|
368
|
+
'hook-pack': catalogPath('hook-pack', options, scope),
|
|
369
|
+
'policy-pack': catalogPath('policy-pack', options, scope),
|
|
373
370
|
};
|
|
374
371
|
return {
|
|
375
372
|
version: 1,
|
|
@@ -410,7 +407,7 @@ export function importEcosystemCatalogBundle(bundle, options) {
|
|
|
410
407
|
for (const kind of ['plugin', 'skill', 'hook-pack', 'policy-pack']) {
|
|
411
408
|
if (byKind[kind].length === 0)
|
|
412
409
|
continue;
|
|
413
|
-
const path = catalogPath(kind, options
|
|
410
|
+
const path = catalogPath(kind, options, scope);
|
|
414
411
|
mkdirSync(dirname(path), { recursive: true });
|
|
415
412
|
writeFileSync(path, `${JSON.stringify({ version: 1, entries: byKind[kind].sort((a, b) => a.name.localeCompare(b.name)) }, null, 2)}\n`, 'utf-8');
|
|
416
413
|
pathByKind[kind] = path;
|
|
@@ -419,9 +416,8 @@ export function importEcosystemCatalogBundle(bundle, options) {
|
|
|
419
416
|
return { imported, pathByKind };
|
|
420
417
|
}
|
|
421
418
|
export function upsertEcosystemCatalogEntry(entry, options) {
|
|
422
|
-
const { cwd, homeDir } = options;
|
|
423
419
|
const scope = options.scope ?? 'project';
|
|
424
|
-
const path = catalogPath(entry.kind,
|
|
420
|
+
const path = catalogPath(entry.kind, options, scope);
|
|
425
421
|
const document = readCatalogDocument(path);
|
|
426
422
|
const nextEntries = document.entries.filter((candidate) => candidate.id !== entry.id || candidate.kind !== entry.kind);
|
|
427
423
|
nextEntries.push(entry);
|
|
@@ -431,9 +427,8 @@ export function upsertEcosystemCatalogEntry(entry, options) {
|
|
|
431
427
|
return { ok: true, path, entry };
|
|
432
428
|
}
|
|
433
429
|
export function removeEcosystemCatalogEntry(kind, entryId, options) {
|
|
434
|
-
const { cwd, homeDir } = options;
|
|
435
430
|
const scope = options.scope ?? 'project';
|
|
436
|
-
const path = catalogPath(kind,
|
|
431
|
+
const path = catalogPath(kind, options, scope);
|
|
437
432
|
const document = readCatalogDocument(path);
|
|
438
433
|
const nextEntries = document.entries.filter((candidate) => candidate.id !== entryId || candidate.kind !== kind);
|
|
439
434
|
if (nextEntries.length === document.entries.length) {
|
|
@@ -362,7 +362,7 @@ async function executeTextEdits(input, env) {
|
|
|
362
362
|
}
|
|
363
363
|
let editResult;
|
|
364
364
|
if (matchMode === 'ast_pattern') {
|
|
365
|
-
editResult = computeAstPatternEdit(currentContent, item, resolvedPath);
|
|
365
|
+
editResult = await computeAstPatternEdit(currentContent, item, resolvedPath);
|
|
366
366
|
}
|
|
367
367
|
else if (matchMode === 'ast') {
|
|
368
368
|
editResult = await computeAstEdit(currentContent, item, resolvedPath);
|
|
@@ -50,12 +50,12 @@ export declare function computeAstEdit(fileContent: string, item: EditItem, file
|
|
|
50
50
|
} | {
|
|
51
51
|
error: string;
|
|
52
52
|
}>;
|
|
53
|
-
export declare function computeAstPatternEdit(fileContent: string, item: EditItem, filePath: string): {
|
|
53
|
+
export declare function computeAstPatternEdit(fileContent: string, item: EditItem, filePath: string): Promise<{
|
|
54
54
|
newContent: string;
|
|
55
55
|
occurrencesReplaced: number;
|
|
56
56
|
} | {
|
|
57
57
|
error: string;
|
|
58
|
-
}
|
|
58
|
+
}>;
|
|
59
59
|
export declare function classifyEditFailure(message: string): EditResultStatus;
|
|
60
60
|
export declare function buildFailedEditResult(item: EditItem, error: string, status: EditResultStatus): EditResult;
|
|
61
61
|
export declare function computeSingleEdit(fileContent: string, item: EditItem, mode: 'exact' | 'fuzzy' | 'regex', caseSensitive: boolean, whitespaceSensitive?: boolean, multiline?: boolean): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/edit/match.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/edit/match.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { extname } from 'node:path';
|
|
2
|
-
import * as astGrep from '@ast-grep/napi';
|
|
3
2
|
import { logger } from '../../utils/logger.js';
|
|
4
3
|
import { CodeIntelligence } from '../../intelligence/index.js';
|
|
5
4
|
import { summarizeError } from '../../utils/error-display.js';
|
|
@@ -248,7 +247,12 @@ export function applyReplacements(content, selections, find, replace, mode, case
|
|
|
248
247
|
}
|
|
249
248
|
return result;
|
|
250
249
|
}
|
|
251
|
-
|
|
250
|
+
let astGrepModulePromise = null;
|
|
251
|
+
async function loadAstGrep() {
|
|
252
|
+
astGrepModulePromise ??= import('@ast-grep/napi');
|
|
253
|
+
return astGrepModulePromise;
|
|
254
|
+
}
|
|
255
|
+
function getAstGrepLang(astGrep, filePath) {
|
|
252
256
|
const lang = extname(filePath).slice(1).toLowerCase();
|
|
253
257
|
switch (lang) {
|
|
254
258
|
case 'ts': return astGrep.ts;
|
|
@@ -318,10 +322,17 @@ export function computeAstEdit(fileContent, item, filePath) {
|
|
|
318
322
|
return { newContent, occurrencesReplaced: selResult.selected.length };
|
|
319
323
|
}).catch(() => computeExactEdit(fileContent, item));
|
|
320
324
|
}
|
|
321
|
-
export function computeAstPatternEdit(fileContent, item, filePath) {
|
|
325
|
+
export async function computeAstPatternEdit(fileContent, item, filePath) {
|
|
322
326
|
const findStr = item.find_base64 ? decodeBase64(item.find_base64) : item.find;
|
|
323
327
|
const replaceStr = item.replace_base64 ? decodeBase64(item.replace_base64) : item.replace;
|
|
324
|
-
|
|
328
|
+
let astGrep;
|
|
329
|
+
try {
|
|
330
|
+
astGrep = await loadAstGrep();
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
return computeExactEdit(fileContent, item);
|
|
334
|
+
}
|
|
335
|
+
const parser = getAstGrepLang(astGrep, filePath);
|
|
325
336
|
if (!parser) {
|
|
326
337
|
return computeExactEdit(fileContent, item);
|
|
327
338
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/find/structural.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/tools/find/structural.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA+BlE,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA0ElC"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { extname } from 'node:path';
|
|
2
|
-
import * as astGrep from '@ast-grep/napi';
|
|
3
2
|
import { collectFilesForSearch, makeCountResult, makeFilesResult, makeLocationsResult, readTextFile, validateSearchPath } from './shared.js';
|
|
4
|
-
|
|
3
|
+
let astGrepModulePromise = null;
|
|
4
|
+
async function loadAstGrep() {
|
|
5
|
+
astGrepModulePromise ??= import('@ast-grep/napi');
|
|
6
|
+
return astGrepModulePromise;
|
|
7
|
+
}
|
|
8
|
+
function getAstGrepLang(astGrep, filePath, override) {
|
|
5
9
|
const lang = override ?? extname(filePath).slice(1).toLowerCase();
|
|
6
10
|
switch (lang) {
|
|
7
11
|
case 'ts': return astGrep.ts;
|
|
@@ -23,6 +27,14 @@ export async function executeStructuralQuery(query, output, projectRoot) {
|
|
|
23
27
|
if (!query.pattern) {
|
|
24
28
|
return { error: 'structural mode requires pattern' };
|
|
25
29
|
}
|
|
30
|
+
let astGrep;
|
|
31
|
+
try {
|
|
32
|
+
astGrep = await loadAstGrep();
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
36
|
+
return { error: `structural mode requires @ast-grep/napi at runtime: ${message}` };
|
|
37
|
+
}
|
|
26
38
|
const format = output.format ?? 'matches';
|
|
27
39
|
const maxPerFile = output.max_per_item ?? 10;
|
|
28
40
|
const maxTotal = output.max_total_matches ?? output.max_results ?? 100;
|
|
@@ -33,7 +45,7 @@ export async function executeStructuralQuery(query, output, projectRoot) {
|
|
|
33
45
|
outer: for (const file of files) {
|
|
34
46
|
if (totalMatches >= maxTotal)
|
|
35
47
|
break;
|
|
36
|
-
const parser = getAstGrepLang(file, query.lang);
|
|
48
|
+
const parser = getAstGrepLang(astGrep, file, query.lang);
|
|
37
49
|
if (!parser)
|
|
38
50
|
continue;
|
|
39
51
|
const content = await readTextFile(file);
|
package/package.json
CHANGED