@myagentroam/node 0.9.98 → 0.9.100
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/service/code-navigation/ecmascript-path-specifier-resolver.js +17 -2
- package/dist/service/code-navigation/path-specifier-resolver.js +20 -0
- package/dist/service/code-navigation/stylesheet-path-specifier-resolver.js +8 -2
- package/dist/service/workspace-code-navigation-service.js +7 -5
- package/package.json +4 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { posix } from 'node:path';
|
|
2
|
+
import { trailingPathCandidateScore } from './path-specifier-resolver.js';
|
|
2
3
|
const importExtensionMappings = [
|
|
3
4
|
{ importExtension: '.js', sourceExtensions: ['.ts', '.tsx'] },
|
|
4
5
|
{ importExtension: '.jsx', sourceExtensions: ['.tsx'] },
|
|
@@ -8,11 +9,12 @@ const importExtensionMappings = [
|
|
|
8
9
|
const extensionlessSourceExtensions = ['.ts', '.tsx', '.js', '.jsx'];
|
|
9
10
|
function accepts(value) {
|
|
10
11
|
return (/^(?:\.\.?\/)[A-Za-z0-9_./$-]+$/u.test(value) ||
|
|
12
|
+
/^@\/[A-Za-z0-9_./$-]+$/u.test(value) ||
|
|
11
13
|
/^(?:@?[A-Za-z0-9_$-]+)(?:\/[A-Za-z0-9_.$-]+)+$/u.test(value));
|
|
12
14
|
}
|
|
13
15
|
function matches(path, currentPath, specifier) {
|
|
14
16
|
if (!specifier.startsWith('.'))
|
|
15
|
-
return
|
|
17
|
+
return unresolvedSpecifierScore(path, specifier) !== undefined;
|
|
16
18
|
const resolved = resolveRelative(currentPath, specifier);
|
|
17
19
|
return (resolved !== undefined &&
|
|
18
20
|
candidates(resolved).some((candidate) => path === candidate ||
|
|
@@ -23,7 +25,7 @@ function matches(path, currentPath, specifier) {
|
|
|
23
25
|
}
|
|
24
26
|
function score(path, currentPath, specifier) {
|
|
25
27
|
if (!specifier.startsWith('.'))
|
|
26
|
-
return path.
|
|
28
|
+
return unresolvedSpecifierScore(path, specifier) ?? Number.MAX_SAFE_INTEGER;
|
|
27
29
|
const resolved = resolveRelative(currentPath, specifier);
|
|
28
30
|
if (resolved === undefined)
|
|
29
31
|
return Number.MAX_SAFE_INTEGER;
|
|
@@ -72,6 +74,19 @@ function sourceFileStem(path) {
|
|
|
72
74
|
const name = path.slice(path.lastIndexOf('/') + 1);
|
|
73
75
|
return name.replace(/(?:\.d)?\.[^.]+$/u, '');
|
|
74
76
|
}
|
|
77
|
+
function unresolvedSpecifierScore(path, specifier) {
|
|
78
|
+
const normalizedSpecifier = specifier.startsWith('@/') ? specifier.slice(2) : specifier;
|
|
79
|
+
return trailingPathCandidateScore(path, unresolvedCandidates(normalizedSpecifier));
|
|
80
|
+
}
|
|
81
|
+
function unresolvedCandidates(specifier) {
|
|
82
|
+
return candidates(specifier).flatMap((candidate) => [
|
|
83
|
+
candidate,
|
|
84
|
+
`${candidate}/index.ts`,
|
|
85
|
+
`${candidate}/index.tsx`,
|
|
86
|
+
`${candidate}/index.js`,
|
|
87
|
+
`${candidate}/index.jsx`
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
75
90
|
export const ecmascriptPathSpecifierResolver = {
|
|
76
91
|
id: 'ecmascript.path-specifier',
|
|
77
92
|
accepts,
|
|
@@ -4,3 +4,23 @@ export function matchesPathSuffix(path, suffix) {
|
|
|
4
4
|
export function shortestPathScore(path) {
|
|
5
5
|
return path.length;
|
|
6
6
|
}
|
|
7
|
+
export function trailingPathCandidateScore(path, candidates) {
|
|
8
|
+
let best;
|
|
9
|
+
for (const [candidateIndex, candidate] of candidates.entries()) {
|
|
10
|
+
const pathSegments = path.split('/');
|
|
11
|
+
const candidateSegments = candidate.split('/');
|
|
12
|
+
let matchedSegments = 0;
|
|
13
|
+
while (matchedSegments < pathSegments.length &&
|
|
14
|
+
matchedSegments < candidateSegments.length &&
|
|
15
|
+
pathSegments[pathSegments.length - matchedSegments - 1] ===
|
|
16
|
+
candidateSegments[candidateSegments.length - matchedSegments - 1])
|
|
17
|
+
matchedSegments += 1;
|
|
18
|
+
if (matchedSegments === 0)
|
|
19
|
+
continue;
|
|
20
|
+
const unmatchedSegments = candidateSegments.length - matchedSegments;
|
|
21
|
+
const leadingPathSegments = pathSegments.length - matchedSegments;
|
|
22
|
+
const candidateScore = unmatchedSegments * 10_000 + candidateIndex * 100 + leadingPathSegments;
|
|
23
|
+
best = best === undefined ? candidateScore : Math.min(best, candidateScore);
|
|
24
|
+
}
|
|
25
|
+
return best;
|
|
26
|
+
}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { posix } from 'node:path';
|
|
2
|
+
import { trailingPathCandidateScore } from './path-specifier-resolver.js';
|
|
2
3
|
function accepts(value) {
|
|
3
4
|
return /^(?:\.\.?\/)?[A-Za-z0-9_./$+@ -]+$/u.test(value);
|
|
4
5
|
}
|
|
5
6
|
function createResolver(languageId, extensions, partials = false) {
|
|
6
7
|
const candidates = (currentPath, specifier) => pathCandidates(currentPath, specifier, extensions, partials);
|
|
8
|
+
const aliasCandidates = (specifier) => pathCandidates('', specifier.slice(2), extensions, partials);
|
|
7
9
|
return {
|
|
8
10
|
id: `${languageId}.path-specifier`,
|
|
9
11
|
accepts,
|
|
10
|
-
directCandidates: candidates,
|
|
11
|
-
matches: (path, currentPath, specifier) =>
|
|
12
|
+
directCandidates: (currentPath, specifier) => specifier.startsWith('@/') ? [] : candidates(currentPath, specifier),
|
|
13
|
+
matches: (path, currentPath, specifier) => specifier.startsWith('@/')
|
|
14
|
+
? trailingPathCandidateScore(path, aliasCandidates(specifier)) !== undefined
|
|
15
|
+
: candidates(currentPath, specifier).includes(path),
|
|
12
16
|
score: (path, currentPath, specifier) => {
|
|
17
|
+
if (specifier.startsWith('@/'))
|
|
18
|
+
return (trailingPathCandidateScore(path, aliasCandidates(specifier)) ?? Number.MAX_SAFE_INTEGER);
|
|
13
19
|
const index = candidates(currentPath, specifier).indexOf(path);
|
|
14
20
|
return index >= 0 ? index : Number.MAX_SAFE_INTEGER;
|
|
15
21
|
}
|
|
@@ -3,6 +3,7 @@ import { constants } from 'node:fs';
|
|
|
3
3
|
import { access, open, realpath, rename, rm, stat, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { relative, resolve, sep } from 'node:path';
|
|
6
|
+
import { isNavigationSymbol } from '@myagentroam/code-navigation';
|
|
6
7
|
import { supportsSymbolNavigationPath } from '@myagentroam/code-navigation/symbol-navigation';
|
|
7
8
|
import { workspaceFileReferenceSchema } from '@myagentroam/protocol';
|
|
8
9
|
import { bundledCtagsPath, BUNDLED_CTAGS_VERSION, repairBundledCtagsExecutable } from '../ctags-binary.js';
|
|
@@ -87,6 +88,7 @@ export class WorkspaceCodeNavigationService {
|
|
|
87
88
|
async definition(workspace, input) {
|
|
88
89
|
const path = input.path;
|
|
89
90
|
const symbol = input.symbol;
|
|
91
|
+
const includeReferences = input.includeReferences;
|
|
90
92
|
const reference = input.reference === undefined
|
|
91
93
|
? undefined
|
|
92
94
|
: workspaceFileReferenceSchema.safeParse(input.reference);
|
|
@@ -95,7 +97,8 @@ export class WorkspaceCodeNavigationService {
|
|
|
95
97
|
path.length > 4096 ||
|
|
96
98
|
(typeof symbol === 'string' && reference !== undefined) ||
|
|
97
99
|
(typeof symbol !== 'string' && reference === undefined) ||
|
|
98
|
-
(typeof symbol === 'string' && !
|
|
100
|
+
(typeof symbol === 'string' && !isNavigationSymbol(path, symbol)) ||
|
|
101
|
+
(includeReferences !== undefined && typeof includeReferences !== 'boolean') ||
|
|
99
102
|
(reference !== undefined && !reference.success))
|
|
100
103
|
throw new Error('SYMBOL_DEFINITION_INVALID');
|
|
101
104
|
if (reference !== undefined) {
|
|
@@ -171,7 +174,9 @@ export class WorkspaceCodeNavigationService {
|
|
|
171
174
|
});
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
|
-
const references =
|
|
177
|
+
const references = includeReferences === false
|
|
178
|
+
? { matches: [], truncated: false }
|
|
179
|
+
: await this.findReferences(workspace, requestedSymbol, targets);
|
|
175
180
|
return {
|
|
176
181
|
state: fresh ? 'READY' : 'STALE',
|
|
177
182
|
targets: targets.slice(0, MAX_RESULTS),
|
|
@@ -595,9 +600,6 @@ function emptyDefinitionResult(input) {
|
|
|
595
600
|
function isCtagsSourcePath(path) {
|
|
596
601
|
return supportsSymbolNavigationPath(path);
|
|
597
602
|
}
|
|
598
|
-
function isSymbol(value) {
|
|
599
|
-
return value.length > 0 && value.length <= 512 && /^[\p{L}_$][\p{L}\p{N}_$]*$/u.test(value);
|
|
600
|
-
}
|
|
601
603
|
function buildFailure(error) {
|
|
602
604
|
return error instanceof Error && error.message === 'SYMBOL_INDEX_LIMIT_EXCEEDED'
|
|
603
605
|
? 'SYMBOL_INDEX_LIMIT_EXCEEDED'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.100",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"npm": "11.12.1",
|
|
31
31
|
"ws": "^8.21.3",
|
|
32
32
|
"zod": "4.4.3",
|
|
33
|
-
"@myagentroam/agent": "0.9.
|
|
34
|
-
"@myagentroam/
|
|
35
|
-
"@myagentroam/
|
|
33
|
+
"@myagentroam/agent": "0.9.100",
|
|
34
|
+
"@myagentroam/code-navigation": "0.9.100",
|
|
35
|
+
"@myagentroam/protocol": "0.9.100"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/ws": "^8.18.1"
|