@vibe-agent-toolkit/resource-compiler 0.1.11
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/README.md +449 -0
- package/bin/vat-compile-resources +8 -0
- package/dist/cli/compile-command.d.ts +11 -0
- package/dist/cli/compile-command.d.ts.map +1 -0
- package/dist/cli/compile-command.js +34 -0
- package/dist/cli/compile-command.js.map +1 -0
- package/dist/cli/compile-utils.d.ts +41 -0
- package/dist/cli/compile-utils.d.ts.map +1 -0
- package/dist/cli/compile-utils.js +51 -0
- package/dist/cli/compile-utils.js.map +1 -0
- package/dist/cli/generate-types-command.d.ts +11 -0
- package/dist/cli/generate-types-command.d.ts.map +1 -0
- package/dist/cli/generate-types-command.js +107 -0
- package/dist/cli/generate-types-command.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +34 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/watch-command.d.ts +11 -0
- package/dist/cli/watch-command.d.ts.map +1 -0
- package/dist/cli/watch-command.js +88 -0
- package/dist/cli/watch-command.js.map +1 -0
- package/dist/compiler/dts-generator.d.ts +29 -0
- package/dist/compiler/dts-generator.d.ts.map +1 -0
- package/dist/compiler/dts-generator.js +133 -0
- package/dist/compiler/dts-generator.js.map +1 -0
- package/dist/compiler/index.d.ts +9 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +9 -0
- package/dist/compiler/index.js.map +1 -0
- package/dist/compiler/javascript-generator.d.ts +22 -0
- package/dist/compiler/javascript-generator.d.ts.map +1 -0
- package/dist/compiler/javascript-generator.js +106 -0
- package/dist/compiler/javascript-generator.js.map +1 -0
- package/dist/compiler/markdown-compiler.d.ts +30 -0
- package/dist/compiler/markdown-compiler.d.ts.map +1 -0
- package/dist/compiler/markdown-compiler.js +125 -0
- package/dist/compiler/markdown-compiler.js.map +1 -0
- package/dist/compiler/markdown-parser.d.ts +32 -0
- package/dist/compiler/markdown-parser.d.ts.map +1 -0
- package/dist/compiler/markdown-parser.js +126 -0
- package/dist/compiler/markdown-parser.js.map +1 -0
- package/dist/compiler/types.d.ts +71 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/compiler/types.js +5 -0
- package/dist/compiler/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/language-service/completions.d.ts +27 -0
- package/dist/language-service/completions.d.ts.map +1 -0
- package/dist/language-service/completions.js +147 -0
- package/dist/language-service/completions.js.map +1 -0
- package/dist/language-service/definitions.d.ts +14 -0
- package/dist/language-service/definitions.d.ts.map +1 -0
- package/dist/language-service/definitions.js +140 -0
- package/dist/language-service/definitions.js.map +1 -0
- package/dist/language-service/diagnostics.d.ts +13 -0
- package/dist/language-service/diagnostics.d.ts.map +1 -0
- package/dist/language-service/diagnostics.js +169 -0
- package/dist/language-service/diagnostics.js.map +1 -0
- package/dist/language-service/hover.d.ts +15 -0
- package/dist/language-service/hover.d.ts.map +1 -0
- package/dist/language-service/hover.js +125 -0
- package/dist/language-service/hover.js.map +1 -0
- package/dist/language-service/index.d.ts +26 -0
- package/dist/language-service/index.d.ts.map +1 -0
- package/dist/language-service/index.js +30 -0
- package/dist/language-service/index.js.map +1 -0
- package/dist/language-service/markdown-cache.d.ts +44 -0
- package/dist/language-service/markdown-cache.d.ts.map +1 -0
- package/dist/language-service/markdown-cache.js +77 -0
- package/dist/language-service/markdown-cache.js.map +1 -0
- package/dist/language-service/plugin.d.ts +15 -0
- package/dist/language-service/plugin.d.ts.map +1 -0
- package/dist/language-service/plugin.js +51 -0
- package/dist/language-service/plugin.js.map +1 -0
- package/dist/language-service/utils.d.ts +173 -0
- package/dist/language-service/utils.d.ts.map +1 -0
- package/dist/language-service/utils.js +341 -0
- package/dist/language-service/utils.js.map +1 -0
- package/dist/transformer/ast-helpers.d.ts +35 -0
- package/dist/transformer/ast-helpers.d.ts.map +1 -0
- package/dist/transformer/ast-helpers.js +153 -0
- package/dist/transformer/ast-helpers.js.map +1 -0
- package/dist/transformer/declaration-generator.d.ts +47 -0
- package/dist/transformer/declaration-generator.d.ts.map +1 -0
- package/dist/transformer/declaration-generator.js +53 -0
- package/dist/transformer/declaration-generator.js.map +1 -0
- package/dist/transformer/import-detector.d.ts +62 -0
- package/dist/transformer/import-detector.d.ts.map +1 -0
- package/dist/transformer/import-detector.js +115 -0
- package/dist/transformer/import-detector.js.map +1 -0
- package/dist/transformer/index.d.ts +11 -0
- package/dist/transformer/index.d.ts.map +1 -0
- package/dist/transformer/index.js +11 -0
- package/dist/transformer/index.js.map +1 -0
- package/dist/transformer/module-generator.d.ts +29 -0
- package/dist/transformer/module-generator.d.ts.map +1 -0
- package/dist/transformer/module-generator.js +48 -0
- package/dist/transformer/module-generator.js.map +1 -0
- package/dist/transformer/path-resolver.d.ts +32 -0
- package/dist/transformer/path-resolver.d.ts.map +1 -0
- package/dist/transformer/path-resolver.js +112 -0
- package/dist/transformer/path-resolver.js.map +1 -0
- package/dist/transformer/transformer.d.ts +46 -0
- package/dist/transformer/transformer.d.ts.map +1 -0
- package/dist/transformer/transformer.js +89 -0
- package/dist/transformer/transformer.js.map +1 -0
- package/dist/utils/copy-resources.d.ts +54 -0
- package/dist/utils/copy-resources.d.ts.map +1 -0
- package/dist/utils/copy-resources.js +77 -0
- package/dist/utils/copy-resources.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhance go-to-definition for markdown imports and fragments
|
|
3
|
+
*/
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types -- TypeScript Language Service plugin API requires any */
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { findNodeAtPosition, getMarkdownPathFromImport, getMarkdownPathFromExpression, resolveMarkdownPath, resolveAndLoadMarkdown, findHeadingPosition, } from './utils.js';
|
|
7
|
+
/**
|
|
8
|
+
* Enhance definition results with markdown file and fragment locations
|
|
9
|
+
*
|
|
10
|
+
* @param ts - TypeScript module
|
|
11
|
+
* @param info - Plugin create info
|
|
12
|
+
* @param fileName - File being edited
|
|
13
|
+
* @param position - Cursor position
|
|
14
|
+
* @returns Enhanced definition info, or original if no enhancements needed
|
|
15
|
+
*/
|
|
16
|
+
export function enhanceDefinitions(ts, info, fileName, position) {
|
|
17
|
+
try {
|
|
18
|
+
// Get the source file and program
|
|
19
|
+
const program = info.languageService.getProgram();
|
|
20
|
+
if (!program) {
|
|
21
|
+
return info.languageService.getDefinitionAtPosition(fileName, position);
|
|
22
|
+
}
|
|
23
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
24
|
+
if (!sourceFile) {
|
|
25
|
+
return info.languageService.getDefinitionAtPosition(fileName, position);
|
|
26
|
+
}
|
|
27
|
+
// Find the node at cursor position
|
|
28
|
+
const node = findNodeAtPosition(ts, sourceFile, position);
|
|
29
|
+
if (!node) {
|
|
30
|
+
return info.languageService.getDefinitionAtPosition(fileName, position);
|
|
31
|
+
}
|
|
32
|
+
// Check if clicking on a markdown import
|
|
33
|
+
const importPath = getMarkdownPathFromImport(ts, node);
|
|
34
|
+
if (importPath) {
|
|
35
|
+
return createMarkdownFileDefinition(info, importPath, fileName);
|
|
36
|
+
}
|
|
37
|
+
// Check if clicking on a fragment property
|
|
38
|
+
const expressionInfo = getMarkdownPathFromExpression(ts, node, sourceFile);
|
|
39
|
+
if (expressionInfo) {
|
|
40
|
+
return createMarkdownFragmentDefinition(info, expressionInfo.markdownPath, expressionInfo.fragmentName, fileName);
|
|
41
|
+
}
|
|
42
|
+
// Not a markdown context - return original definitions
|
|
43
|
+
return info.languageService.getDefinitionAtPosition(fileName, position);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
info.project.projectService.logger.info(`markdown-import-plugin: Error enhancing definitions: ${String(error)}`);
|
|
47
|
+
return info.languageService.getDefinitionAtPosition(fileName, position);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create definition info for a markdown file
|
|
52
|
+
*
|
|
53
|
+
* @param info - Plugin create info
|
|
54
|
+
* @param markdownPath - Import path to markdown file
|
|
55
|
+
* @param containingFile - File containing the import
|
|
56
|
+
* @returns Definition info array, or undefined if not found
|
|
57
|
+
*/
|
|
58
|
+
function createMarkdownFileDefinition(info, markdownPath, containingFile) {
|
|
59
|
+
const compilerOptions = info.project.getCompilerOptions();
|
|
60
|
+
const absolutePath = resolveMarkdownPath(markdownPath, containingFile, compilerOptions);
|
|
61
|
+
if (!absolutePath) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
fileName: absolutePath,
|
|
67
|
+
textSpan: { start: 0, length: 0 },
|
|
68
|
+
kind: 1, // ts.ScriptElementKind.moduleElement
|
|
69
|
+
name: 'Markdown Resource',
|
|
70
|
+
containerKind: 0, // ts.ScriptElementKind.unknown
|
|
71
|
+
containerName: '',
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create definition info for a markdown fragment
|
|
77
|
+
*
|
|
78
|
+
* @param info - Plugin create info
|
|
79
|
+
* @param markdownPath - Import path to markdown file
|
|
80
|
+
* @param fragmentName - camelCase fragment property name
|
|
81
|
+
* @param containingFile - File containing the fragment access
|
|
82
|
+
* @returns Definition info array, or undefined if not found
|
|
83
|
+
*/
|
|
84
|
+
function createMarkdownFragmentDefinition(info, markdownPath, fragmentName, containingFile) {
|
|
85
|
+
try {
|
|
86
|
+
// Resolve markdown path and load resource
|
|
87
|
+
const result = resolveAndLoadMarkdown(info, markdownPath, containingFile);
|
|
88
|
+
if (!result) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
const { absolutePath, resource } = result;
|
|
92
|
+
// Find the fragment matching this property name
|
|
93
|
+
const fragment = resource.fragments.find((f) => f.camelCase === fragmentName);
|
|
94
|
+
if (!fragment) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
// Read markdown file content to find heading position
|
|
98
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Using validated path from TypeScript Language Service
|
|
99
|
+
const content = readFileSync(absolutePath, 'utf-8');
|
|
100
|
+
const position = findHeadingPosition(content, fragment.heading);
|
|
101
|
+
if (!position) {
|
|
102
|
+
// If we can't find the heading, just jump to start of file
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
fileName: absolutePath,
|
|
106
|
+
textSpan: { start: 0, length: 0 },
|
|
107
|
+
kind: 7, // ts.ScriptElementKind.constElement
|
|
108
|
+
name: fragment.heading,
|
|
109
|
+
containerKind: 0,
|
|
110
|
+
containerName: '',
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
}
|
|
114
|
+
// Calculate character offset from line/character position
|
|
115
|
+
const lines = content.split('\n');
|
|
116
|
+
let offset = 0;
|
|
117
|
+
for (let i = 0; i < position.line; i++) {
|
|
118
|
+
const line = lines[i];
|
|
119
|
+
if (line !== undefined) {
|
|
120
|
+
offset += line.length + 1; // +1 for newline
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
offset += position.character;
|
|
124
|
+
return [
|
|
125
|
+
{
|
|
126
|
+
fileName: absolutePath,
|
|
127
|
+
textSpan: { start: offset, length: fragment.heading.length + 3 }, // +3 for "## "
|
|
128
|
+
kind: 7, // ts.ScriptElementKind.constElement
|
|
129
|
+
name: fragment.heading,
|
|
130
|
+
containerKind: 0,
|
|
131
|
+
containerName: '',
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
info.project.projectService.logger.info(`markdown-import-plugin: Error creating fragment definition: ${String(error)}`);
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/language-service/definitions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhance diagnostics to check markdown file and fragment existence
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Enhance semantic diagnostics with markdown-specific error checking
|
|
6
|
+
*
|
|
7
|
+
* @param ts - TypeScript module
|
|
8
|
+
* @param info - Plugin create info
|
|
9
|
+
* @param fileName - File being checked
|
|
10
|
+
* @returns Enhanced diagnostics array
|
|
11
|
+
*/
|
|
12
|
+
export declare function enhanceDiagnostics(ts: any, info: any, fileName: string): readonly any[];
|
|
13
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/language-service/diagnostics.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,MAAM,GACf,SAAS,GAAG,EAAE,CA2DhB"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhance diagnostics to check markdown file and fragment existence
|
|
3
|
+
*/
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types -- TypeScript Language Service plugin API requires any */
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
6
|
+
import { getMarkdownPathFromImport, getMarkdownPathFromExpression, resolveMarkdownPath, resolveAndLoadMarkdown, } from './utils.js';
|
|
7
|
+
/**
|
|
8
|
+
* Enhance semantic diagnostics with markdown-specific error checking
|
|
9
|
+
*
|
|
10
|
+
* @param ts - TypeScript module
|
|
11
|
+
* @param info - Plugin create info
|
|
12
|
+
* @param fileName - File being checked
|
|
13
|
+
* @returns Enhanced diagnostics array
|
|
14
|
+
*/
|
|
15
|
+
export function enhanceDiagnostics(ts, info, fileName) {
|
|
16
|
+
try {
|
|
17
|
+
const baseDiagnostics = info.languageService.getSemanticDiagnostics(fileName);
|
|
18
|
+
const program = info.languageService.getProgram();
|
|
19
|
+
if (!program) {
|
|
20
|
+
return baseDiagnostics;
|
|
21
|
+
}
|
|
22
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
23
|
+
if (!sourceFile) {
|
|
24
|
+
return baseDiagnostics;
|
|
25
|
+
}
|
|
26
|
+
const additionalDiagnostics = [];
|
|
27
|
+
// Traverse AST to find markdown-related nodes
|
|
28
|
+
const visit = (node) => {
|
|
29
|
+
// Check markdown imports
|
|
30
|
+
const importPath = getMarkdownPathFromImport(ts, node);
|
|
31
|
+
if (importPath) {
|
|
32
|
+
const diagnostic = checkMarkdownFileExists(info, importPath, fileName, node);
|
|
33
|
+
if (diagnostic) {
|
|
34
|
+
additionalDiagnostics.push(diagnostic);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Check fragment accesses
|
|
38
|
+
const expressionInfo = getMarkdownPathFromExpression(ts, node, sourceFile);
|
|
39
|
+
if (expressionInfo) {
|
|
40
|
+
const diagnostic = checkFragmentExists(info, expressionInfo.markdownPath, expressionInfo.fragmentName, fileName, node);
|
|
41
|
+
if (diagnostic) {
|
|
42
|
+
additionalDiagnostics.push(diagnostic);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
ts.forEachChild(node, visit);
|
|
46
|
+
};
|
|
47
|
+
visit(sourceFile);
|
|
48
|
+
return [...baseDiagnostics, ...additionalDiagnostics];
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
info.project.projectService.logger.info(`markdown-import-plugin: Error enhancing diagnostics: ${String(error)}`);
|
|
52
|
+
return info.languageService.getSemanticDiagnostics(fileName);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if a markdown file exists
|
|
57
|
+
*
|
|
58
|
+
* @param info - Plugin create info
|
|
59
|
+
* @param markdownPath - Import path to markdown file
|
|
60
|
+
* @param containingFile - File containing the import
|
|
61
|
+
* @param node - AST node of the import
|
|
62
|
+
* @returns Diagnostic if file doesn't exist, undefined otherwise
|
|
63
|
+
*/
|
|
64
|
+
function checkMarkdownFileExists(info, markdownPath, containingFile, node) {
|
|
65
|
+
const compilerOptions = info.project.getCompilerOptions();
|
|
66
|
+
const absolutePath = resolveMarkdownPath(markdownPath, containingFile, compilerOptions);
|
|
67
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Using validated path from TypeScript Language Service
|
|
68
|
+
if (!absolutePath || !existsSync(absolutePath)) {
|
|
69
|
+
return {
|
|
70
|
+
file: node.getSourceFile(),
|
|
71
|
+
start: node.moduleSpecifier ? node.moduleSpecifier.getStart() : node.getStart(),
|
|
72
|
+
length: node.moduleSpecifier ? node.moduleSpecifier.getWidth() : node.getWidth(),
|
|
73
|
+
messageText: `Cannot find markdown file: ${markdownPath}`,
|
|
74
|
+
category: 1, // ts.DiagnosticCategory.Error
|
|
75
|
+
code: 9999,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check if a fragment exists in a markdown file
|
|
82
|
+
*
|
|
83
|
+
* @param info - Plugin create info
|
|
84
|
+
* @param markdownPath - Import path to markdown file
|
|
85
|
+
* @param fragmentName - camelCase fragment property name
|
|
86
|
+
* @param containingFile - File containing the fragment access
|
|
87
|
+
* @param node - AST node of the fragment access
|
|
88
|
+
* @returns Diagnostic if fragment doesn't exist, undefined otherwise
|
|
89
|
+
*/
|
|
90
|
+
function checkFragmentExists(info, markdownPath, fragmentName, containingFile, node) {
|
|
91
|
+
try {
|
|
92
|
+
// Resolve markdown path and load resource
|
|
93
|
+
const result = resolveAndLoadMarkdown(info, markdownPath, containingFile);
|
|
94
|
+
if (!result) {
|
|
95
|
+
// File doesn't exist - this will be caught by checkMarkdownFileExists
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
const { resource } = result;
|
|
99
|
+
// Check if this is accessing a known property (meta, text, fragments)
|
|
100
|
+
if (fragmentName === 'meta' || fragmentName === 'text' || fragmentName === 'fragments') {
|
|
101
|
+
return undefined; // These are always valid
|
|
102
|
+
}
|
|
103
|
+
// Check if fragment exists
|
|
104
|
+
const fragmentExists = resource.fragments.some((f) => f.camelCase === fragmentName);
|
|
105
|
+
if (!fragmentExists) {
|
|
106
|
+
// Get property name node for error span
|
|
107
|
+
let propertyNode = node;
|
|
108
|
+
if (node.name) {
|
|
109
|
+
propertyNode = node.name;
|
|
110
|
+
}
|
|
111
|
+
// Suggest similar fragment names
|
|
112
|
+
const suggestions = resource.fragments
|
|
113
|
+
.map((f) => f.camelCase)
|
|
114
|
+
.filter((name) => levenshteinDistance(name, fragmentName) <= 3)
|
|
115
|
+
.slice(0, 3);
|
|
116
|
+
let message = `Fragment '${fragmentName}' does not exist in ${markdownPath}`;
|
|
117
|
+
if (suggestions.length > 0) {
|
|
118
|
+
message += `. Did you mean: ${suggestions.join(', ')}?`;
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
file: propertyNode.getSourceFile(),
|
|
122
|
+
start: propertyNode.getStart(),
|
|
123
|
+
length: propertyNode.getWidth(),
|
|
124
|
+
messageText: message,
|
|
125
|
+
category: 1, // ts.DiagnosticCategory.Error
|
|
126
|
+
code: 9998,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
info.project.projectService.logger.info(`markdown-import-plugin: Error checking fragment: ${String(error)}`);
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Calculate Levenshtein distance between two strings (for suggestions)
|
|
138
|
+
*
|
|
139
|
+
* @param a - First string
|
|
140
|
+
* @param b - Second string
|
|
141
|
+
* @returns Edit distance
|
|
142
|
+
*/
|
|
143
|
+
function levenshteinDistance(a, b) {
|
|
144
|
+
const matrix = [];
|
|
145
|
+
for (let i = 0; i <= b.length; i++) {
|
|
146
|
+
matrix[i] = [i];
|
|
147
|
+
}
|
|
148
|
+
for (let j = 0; j <= a.length; j++) {
|
|
149
|
+
if (matrix[0]) {
|
|
150
|
+
matrix[0][j] = j;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
for (let i = 1; i <= b.length; i++) {
|
|
154
|
+
for (let j = 1; j <= a.length; j++) {
|
|
155
|
+
const cost = b.charAt(i - 1) === a.charAt(j - 1) ? 0 : 1;
|
|
156
|
+
const row = matrix[i];
|
|
157
|
+
const prevRow = matrix[i - 1];
|
|
158
|
+
if (row && prevRow) {
|
|
159
|
+
const deletion = (prevRow[j] ?? 0) + 1;
|
|
160
|
+
const insertion = (row[j - 1] ?? 0) + 1;
|
|
161
|
+
const substitution = (prevRow[j - 1] ?? 0) + cost;
|
|
162
|
+
row[j] = Math.min(deletion, insertion, substitution);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const lastRow = matrix[b.length];
|
|
167
|
+
return lastRow ? lastRow[a.length] ?? 0 : 0;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/language-service/diagnostics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhance hover tooltips with markdown content
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Enhance hover tooltips with markdown fragment information
|
|
6
|
+
*
|
|
7
|
+
* @param ts - TypeScript module
|
|
8
|
+
* @param info - Plugin create info
|
|
9
|
+
* @param prior - Original quick info from TypeScript
|
|
10
|
+
* @param fileName - File being edited
|
|
11
|
+
* @param position - Cursor position
|
|
12
|
+
* @returns Enhanced quick info, or original if no enhancements needed
|
|
13
|
+
*/
|
|
14
|
+
export declare function enhanceHover(ts: any, info: any, prior: any, fileName: string, position: number): any;
|
|
15
|
+
//# sourceMappingURL=hover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover.d.ts","sourceRoot":"","sources":["../../src/language-service/hover.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,GAAG,EACT,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,GAAG,CAyCL"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhance hover tooltips with markdown content
|
|
3
|
+
*/
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types -- TypeScript Language Service plugin API requires any */
|
|
5
|
+
import { findNodeAtPosition, getMarkdownPathFromExpression, resolveAndLoadMarkdown, } from './utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Enhance hover tooltips with markdown fragment information
|
|
8
|
+
*
|
|
9
|
+
* @param ts - TypeScript module
|
|
10
|
+
* @param info - Plugin create info
|
|
11
|
+
* @param prior - Original quick info from TypeScript
|
|
12
|
+
* @param fileName - File being edited
|
|
13
|
+
* @param position - Cursor position
|
|
14
|
+
* @returns Enhanced quick info, or original if no enhancements needed
|
|
15
|
+
*/
|
|
16
|
+
export function enhanceHover(ts, info, prior, fileName, position) {
|
|
17
|
+
try {
|
|
18
|
+
// Get the source file and program
|
|
19
|
+
const program = info.languageService.getProgram();
|
|
20
|
+
if (!program) {
|
|
21
|
+
return prior;
|
|
22
|
+
}
|
|
23
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
24
|
+
if (!sourceFile) {
|
|
25
|
+
return prior;
|
|
26
|
+
}
|
|
27
|
+
// Find the node at cursor position
|
|
28
|
+
const node = findNodeAtPosition(ts, sourceFile, position);
|
|
29
|
+
if (!node) {
|
|
30
|
+
return prior;
|
|
31
|
+
}
|
|
32
|
+
// Check if hovering over a fragment property
|
|
33
|
+
const expressionInfo = getMarkdownPathFromExpression(ts, node, sourceFile);
|
|
34
|
+
if (expressionInfo) {
|
|
35
|
+
return createMarkdownFragmentHover(ts, info, expressionInfo.markdownPath, expressionInfo.fragmentName, fileName, node);
|
|
36
|
+
}
|
|
37
|
+
// Not a markdown context - return original hover info
|
|
38
|
+
return prior;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
// Log error and return original hover info
|
|
42
|
+
info.project.projectService.logger.info(`markdown-import-plugin: Error enhancing hover: ${String(error)}`);
|
|
43
|
+
return prior;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Create hover information for a markdown fragment
|
|
48
|
+
*
|
|
49
|
+
* @param ts - TypeScript module
|
|
50
|
+
* @param info - Plugin create info
|
|
51
|
+
* @param markdownPath - Import path to markdown file
|
|
52
|
+
* @param fragmentName - camelCase fragment property name
|
|
53
|
+
* @param containingFile - File containing the fragment access
|
|
54
|
+
* @param node - AST node being hovered
|
|
55
|
+
* @returns Quick info with fragment details, or undefined if not found
|
|
56
|
+
*/
|
|
57
|
+
function createMarkdownFragmentHover(ts, info, markdownPath, fragmentName, containingFile, node) {
|
|
58
|
+
try {
|
|
59
|
+
// Resolve markdown path and load resource
|
|
60
|
+
const result = resolveAndLoadMarkdown(info, markdownPath, containingFile);
|
|
61
|
+
if (!result) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
const { resource } = result;
|
|
65
|
+
// Find the fragment matching this property name
|
|
66
|
+
const fragment = resource.fragments.find((f) => f.camelCase === fragmentName);
|
|
67
|
+
if (!fragment) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
// Get the property name node for text span
|
|
71
|
+
let propertyNode = node;
|
|
72
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
73
|
+
propertyNode = node.name;
|
|
74
|
+
}
|
|
75
|
+
// Create quick info with fragment heading and content
|
|
76
|
+
const quickInfo = {
|
|
77
|
+
kind: ts.ScriptElementKind.memberVariableElement,
|
|
78
|
+
kindModifiers: 'declare',
|
|
79
|
+
textSpan: {
|
|
80
|
+
start: propertyNode.getStart(),
|
|
81
|
+
length: propertyNode.getWidth(),
|
|
82
|
+
},
|
|
83
|
+
displayParts: [
|
|
84
|
+
{ text: 'fragment', kind: 'keyword' },
|
|
85
|
+
{ text: ' ', kind: 'space' },
|
|
86
|
+
{ text: fragmentName, kind: 'propertyName' },
|
|
87
|
+
{ text: ':', kind: 'punctuation' },
|
|
88
|
+
{ text: ' ', kind: 'space' },
|
|
89
|
+
{ text: 'MarkdownFragment', kind: 'interfaceName' },
|
|
90
|
+
],
|
|
91
|
+
documentation: createFragmentDocumentation(fragment.heading, fragment.body),
|
|
92
|
+
};
|
|
93
|
+
return quickInfo;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
info.project.projectService.logger.info(`markdown-import-plugin: Error creating fragment hover: ${String(error)}`);
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create documentation display parts for a fragment
|
|
102
|
+
*
|
|
103
|
+
* @param heading - Fragment heading text
|
|
104
|
+
* @param body - Fragment body content
|
|
105
|
+
* @returns Array of display parts for documentation
|
|
106
|
+
*/
|
|
107
|
+
function createFragmentDocumentation(heading, body) {
|
|
108
|
+
const parts = [];
|
|
109
|
+
// Add heading
|
|
110
|
+
parts.push({ text: '## ', kind: 'text' }, { text: heading, kind: 'text' }, { text: '\n\n', kind: 'lineBreak' });
|
|
111
|
+
// Add body content (truncate if too long)
|
|
112
|
+
const maxBodyLength = 500;
|
|
113
|
+
let bodyText = body.trim();
|
|
114
|
+
if (bodyText.length > maxBodyLength) {
|
|
115
|
+
bodyText = bodyText.slice(0, maxBodyLength) + '...';
|
|
116
|
+
}
|
|
117
|
+
if (bodyText.length > 0) {
|
|
118
|
+
parts.push({ text: bodyText, kind: 'text' });
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
parts.push({ text: '(empty fragment)', kind: 'text' });
|
|
122
|
+
}
|
|
123
|
+
return parts;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=hover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hover.js","sourceRoot":"","sources":["../../src/language-service/hover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript Language Service Plugin for markdown imports
|
|
3
|
+
* Provides IDE support for markdown resources compiled by vat-compile-resources
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* Add to tsconfig.json:
|
|
7
|
+
* ```json
|
|
8
|
+
* {
|
|
9
|
+
* "compilerOptions": {
|
|
10
|
+
* "plugins": [
|
|
11
|
+
* {
|
|
12
|
+
* "name": "@vibe-agent-toolkit/resource-compiler/language-service"
|
|
13
|
+
* }
|
|
14
|
+
* ]
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export { default } from './plugin.js';
|
|
20
|
+
export { findNodeAtPosition, getMarkdownPathFromImport, getMarkdownPathFromExpression, resolveMarkdownPath, loadMarkdownResource, findHeadingPosition, } from './utils.js';
|
|
21
|
+
export { getMarkdownResource, clearCache, invalidateFile, getCacheStats } from './markdown-cache.js';
|
|
22
|
+
export { enhanceCompletions, getCompletionEntryDetails } from './completions.js';
|
|
23
|
+
export { enhanceDefinitions } from './definitions.js';
|
|
24
|
+
export { enhanceDiagnostics } from './diagnostics.js';
|
|
25
|
+
export { enhanceHover } from './hover.js';
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/language-service/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGrG,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript Language Service Plugin for markdown imports
|
|
3
|
+
* Provides IDE support for markdown resources compiled by vat-compile-resources
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* Add to tsconfig.json:
|
|
7
|
+
* ```json
|
|
8
|
+
* {
|
|
9
|
+
* "compilerOptions": {
|
|
10
|
+
* "plugins": [
|
|
11
|
+
* {
|
|
12
|
+
* "name": "@vibe-agent-toolkit/resource-compiler/language-service"
|
|
13
|
+
* }
|
|
14
|
+
* ]
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
// Export the plugin initialization function
|
|
20
|
+
export { default } from './plugin.js';
|
|
21
|
+
// Export utility functions for testing
|
|
22
|
+
export { findNodeAtPosition, getMarkdownPathFromImport, getMarkdownPathFromExpression, resolveMarkdownPath, loadMarkdownResource, findHeadingPosition, } from './utils.js';
|
|
23
|
+
// Export cache functions for testing
|
|
24
|
+
export { getMarkdownResource, clearCache, invalidateFile, getCacheStats } from './markdown-cache.js';
|
|
25
|
+
// Export enhancement functions for testing
|
|
26
|
+
export { enhanceCompletions, getCompletionEntryDetails } from './completions.js';
|
|
27
|
+
export { enhanceDefinitions } from './definitions.js';
|
|
28
|
+
export { enhanceDiagnostics } from './diagnostics.js';
|
|
29
|
+
export { enhanceHover } from './hover.js';
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/language-service/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,4CAA4C;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,uCAAuC;AACvC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAEpB,qCAAqC;AACrC,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAErG,2CAA2C;AAC3C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache for parsed markdown resources with mtime-based invalidation
|
|
3
|
+
* Prevents re-parsing markdown files on every IDE operation
|
|
4
|
+
*/
|
|
5
|
+
import type { MarkdownResource } from '../compiler/types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Get a cached markdown resource or load it using the provided loader
|
|
8
|
+
* Invalidates cache if file has been modified since last load
|
|
9
|
+
*
|
|
10
|
+
* @param filePath - Absolute path to markdown file
|
|
11
|
+
* @param loader - Function to load and parse the markdown file
|
|
12
|
+
* @returns Parsed markdown resource
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const resource = getMarkdownResource('/path/to/file.md', () => {
|
|
17
|
+
* const content = readFileSync('/path/to/file.md', 'utf-8');
|
|
18
|
+
* return parseMarkdown(content);
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function getMarkdownResource(filePath: string, loader: () => MarkdownResource): MarkdownResource;
|
|
23
|
+
/**
|
|
24
|
+
* Clear the entire cache
|
|
25
|
+
* Useful for testing or manual cache invalidation
|
|
26
|
+
*/
|
|
27
|
+
export declare function clearCache(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Remove a specific file from the cache
|
|
30
|
+
* Useful when a file is deleted or moved
|
|
31
|
+
*
|
|
32
|
+
* @param filePath - Absolute path to markdown file
|
|
33
|
+
*/
|
|
34
|
+
export declare function invalidateFile(filePath: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get cache statistics for debugging
|
|
37
|
+
*
|
|
38
|
+
* @returns Object with cache size and list of cached files
|
|
39
|
+
*/
|
|
40
|
+
export declare function getCacheStats(): {
|
|
41
|
+
size: number;
|
|
42
|
+
files: string[];
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=markdown-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-cache.d.ts","sourceRoot":"","sources":["../../src/language-service/markdown-cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAgB7D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,gBAAgB,GAC7B,gBAAgB,CAuBlB;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAErD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAKjE"}
|