@unrdf/kgc-runtime 26.4.2
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/IMPLEMENTATION_SUMMARY.json +150 -0
- package/PLUGIN_SYSTEM_SUMMARY.json +149 -0
- package/README.md +98 -0
- package/TRANSACTION_IMPLEMENTATION.json +119 -0
- package/capability-map.md +93 -0
- package/docs/api-stability.md +269 -0
- package/docs/extensions/plugin-development.md +382 -0
- package/package.json +40 -0
- package/plugins/registry.json +35 -0
- package/src/admission-gate.mjs +414 -0
- package/src/api-version.mjs +373 -0
- package/src/atomic-admission.mjs +310 -0
- package/src/bounds.mjs +289 -0
- package/src/bulkhead-manager.mjs +280 -0
- package/src/capsule.mjs +524 -0
- package/src/crdt.mjs +361 -0
- package/src/enhanced-bounds.mjs +614 -0
- package/src/executor.mjs +73 -0
- package/src/freeze-restore.mjs +521 -0
- package/src/index.mjs +62 -0
- package/src/materialized-views.mjs +371 -0
- package/src/merge.mjs +472 -0
- package/src/plugin-isolation.mjs +392 -0
- package/src/plugin-manager.mjs +441 -0
- package/src/projections-api.mjs +336 -0
- package/src/projections-cli.mjs +238 -0
- package/src/projections-docs.mjs +300 -0
- package/src/projections-ide.mjs +278 -0
- package/src/receipt.mjs +340 -0
- package/src/rollback.mjs +258 -0
- package/src/saga-orchestrator.mjs +355 -0
- package/src/schemas.mjs +1330 -0
- package/src/storage-optimization.mjs +359 -0
- package/src/tool-registry.mjs +272 -0
- package/src/transaction.mjs +466 -0
- package/src/validators.mjs +485 -0
- package/src/work-item.mjs +449 -0
- package/templates/plugin-template/README.md +58 -0
- package/templates/plugin-template/index.mjs +162 -0
- package/templates/plugin-template/plugin.json +19 -0
- package/test/admission-gate.test.mjs +583 -0
- package/test/api-version.test.mjs +74 -0
- package/test/atomic-admission.test.mjs +155 -0
- package/test/bounds.test.mjs +341 -0
- package/test/bulkhead-manager.test.mjs +236 -0
- package/test/capsule.test.mjs +625 -0
- package/test/crdt.test.mjs +215 -0
- package/test/enhanced-bounds.test.mjs +487 -0
- package/test/freeze-restore.test.mjs +472 -0
- package/test/materialized-views.test.mjs +243 -0
- package/test/merge.test.mjs +665 -0
- package/test/plugin-isolation.test.mjs +109 -0
- package/test/plugin-manager.test.mjs +208 -0
- package/test/projections-api.test.mjs +293 -0
- package/test/projections-cli.test.mjs +204 -0
- package/test/projections-docs.test.mjs +173 -0
- package/test/projections-ide.test.mjs +230 -0
- package/test/receipt.test.mjs +295 -0
- package/test/rollback.test.mjs +132 -0
- package/test/saga-orchestrator.test.mjs +279 -0
- package/test/schemas.test.mjs +716 -0
- package/test/storage-optimization.test.mjs +503 -0
- package/test/tool-registry.test.mjs +341 -0
- package/test/transaction.test.mjs +189 -0
- package/test/validators.test.mjs +463 -0
- package/test/work-item.test.mjs +548 -0
- package/test/work-item.test.mjs.bak +548 -0
- package/var/kgc/test-atomic-log.json +519 -0
- package/var/kgc/test-cascading-log.json +145 -0
- package/vitest.config.mjs +18 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Π_docs - Documentation Generation Projections
|
|
3
|
+
* Transforms KGC structures into Markdown documentation with code examples
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Documentation projection schema
|
|
10
|
+
*/
|
|
11
|
+
export const DocsProjectionSchema = z.object({
|
|
12
|
+
type: z.literal('docs'),
|
|
13
|
+
format: z.enum(['markdown', 'html', 'json']),
|
|
14
|
+
content: z.string(),
|
|
15
|
+
frontMatter: z.record(z.any()).optional(),
|
|
16
|
+
sections: z.array(z.object({
|
|
17
|
+
title: z.string(),
|
|
18
|
+
level: z.number(),
|
|
19
|
+
content: z.string(),
|
|
20
|
+
})).optional(),
|
|
21
|
+
crossRefs: z.array(z.object({
|
|
22
|
+
source: z.string(),
|
|
23
|
+
target: z.string(),
|
|
24
|
+
type: z.string(),
|
|
25
|
+
})).optional(),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {z.infer<typeof DocsProjectionSchema>} DocsProjection
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Escape markdown special characters
|
|
34
|
+
* @param {string} text - Text to escape
|
|
35
|
+
* @returns {string} Escaped text
|
|
36
|
+
*/
|
|
37
|
+
function escapeMarkdown(text) {
|
|
38
|
+
return text.replace(/([*_`#\[\]()>])/g, '\\$1');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate markdown heading
|
|
43
|
+
* @param {string} text - Heading text
|
|
44
|
+
* @param {number} level - Heading level (1-6)
|
|
45
|
+
* @returns {string} Markdown heading
|
|
46
|
+
*/
|
|
47
|
+
function heading(text, level = 1) {
|
|
48
|
+
return `${'#'.repeat(Math.min(level, 6))} ${text}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Generate markdown code block
|
|
53
|
+
* @param {string} code - Code content
|
|
54
|
+
* @param {string} [language='javascript'] - Language for syntax highlighting
|
|
55
|
+
* @returns {string} Markdown code block
|
|
56
|
+
*/
|
|
57
|
+
function codeBlock(code, language = 'javascript') {
|
|
58
|
+
return `\`\`\`${language}\n${code}\n\`\`\``;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Project receipt to documentation
|
|
63
|
+
* @param {import('./receipt.mjs').Receipt} receipt - Receipt to document
|
|
64
|
+
* @returns {DocsProjection} Documentation projection
|
|
65
|
+
*/
|
|
66
|
+
export function projectReceiptToDocs(receipt) {
|
|
67
|
+
const sections = [
|
|
68
|
+
{
|
|
69
|
+
title: 'Overview',
|
|
70
|
+
level: 2,
|
|
71
|
+
content: `Receipt ID: \`${receipt.id}\`\n\nOperation: **${receipt.operation}**\n\nTimestamp: ${receipt.timestamp}`,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
title: 'Inputs',
|
|
75
|
+
level: 2,
|
|
76
|
+
content: codeBlock(JSON.stringify(receipt.inputs, null, 2), 'json'),
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
title: 'Outputs',
|
|
80
|
+
level: 2,
|
|
81
|
+
content: codeBlock(JSON.stringify(receipt.outputs, null, 2), 'json'),
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: 'Verification',
|
|
85
|
+
level: 2,
|
|
86
|
+
content: `Content Hash: \`${receipt.hash}\`` +
|
|
87
|
+
(receipt.parentHash ? `\n\nParent Hash: \`${receipt.parentHash}\`` : ''),
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
const content = [
|
|
92
|
+
heading('Receipt Documentation', 1),
|
|
93
|
+
'',
|
|
94
|
+
...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
|
|
95
|
+
].join('\n');
|
|
96
|
+
|
|
97
|
+
return DocsProjectionSchema.parse({
|
|
98
|
+
type: 'docs',
|
|
99
|
+
format: 'markdown',
|
|
100
|
+
content,
|
|
101
|
+
frontMatter: {
|
|
102
|
+
id: receipt.id,
|
|
103
|
+
operation: receipt.operation,
|
|
104
|
+
timestamp: receipt.timestamp,
|
|
105
|
+
},
|
|
106
|
+
sections,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Project schema to documentation with examples
|
|
112
|
+
* @param {string} schemaName - Schema name
|
|
113
|
+
* @param {import('zod').ZodType} schema - Zod schema
|
|
114
|
+
* @param {Record<string, any>} [example] - Example object
|
|
115
|
+
* @returns {DocsProjection} Documentation projection
|
|
116
|
+
*/
|
|
117
|
+
export function projectSchemaToDocs(schemaName, schema, example) {
|
|
118
|
+
const sections = [
|
|
119
|
+
{
|
|
120
|
+
title: 'Schema Definition',
|
|
121
|
+
level: 2,
|
|
122
|
+
content: `\`${schemaName}\` - Type-safe schema for validation and type inference.`,
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
if (example) {
|
|
127
|
+
sections.push({
|
|
128
|
+
title: 'Example',
|
|
129
|
+
level: 2,
|
|
130
|
+
content: codeBlock(JSON.stringify(example, null, 2), 'json'),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
sections.push({
|
|
134
|
+
title: 'Usage',
|
|
135
|
+
level: 2,
|
|
136
|
+
content: codeBlock(
|
|
137
|
+
`import { ${schemaName} } from '@unrdf/kgc-runtime/schemas';\n\n` +
|
|
138
|
+
`const validated = ${schemaName}.parse(data);`,
|
|
139
|
+
'javascript'
|
|
140
|
+
),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const content = [
|
|
145
|
+
heading(`${schemaName} Documentation`, 1),
|
|
146
|
+
'',
|
|
147
|
+
...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
|
|
148
|
+
].join('\n');
|
|
149
|
+
|
|
150
|
+
return DocsProjectionSchema.parse({
|
|
151
|
+
type: 'docs',
|
|
152
|
+
format: 'markdown',
|
|
153
|
+
content,
|
|
154
|
+
frontMatter: {
|
|
155
|
+
schema: schemaName,
|
|
156
|
+
type: 'schema-documentation',
|
|
157
|
+
},
|
|
158
|
+
sections,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Generate API documentation from function
|
|
164
|
+
* @param {Function} fn - Function to document
|
|
165
|
+
* @param {object} metadata - Function metadata
|
|
166
|
+
* @param {string} metadata.name - Function name
|
|
167
|
+
* @param {string} metadata.description - Function description
|
|
168
|
+
* @param {Array<{name: string, type: string, description: string}>} metadata.params - Parameters
|
|
169
|
+
* @param {object} metadata.returns - Return value info
|
|
170
|
+
* @param {string} [metadata.example] - Usage example
|
|
171
|
+
* @returns {DocsProjection} Documentation projection
|
|
172
|
+
*/
|
|
173
|
+
export function projectFunctionToDocs(fn, metadata) {
|
|
174
|
+
const sections = [
|
|
175
|
+
{
|
|
176
|
+
title: 'Description',
|
|
177
|
+
level: 2,
|
|
178
|
+
content: metadata.description,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
title: 'Parameters',
|
|
182
|
+
level: 2,
|
|
183
|
+
content: metadata.params.map(p =>
|
|
184
|
+
`- **${p.name}** (\`${p.type}\`): ${p.description}`
|
|
185
|
+
).join('\n'),
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
title: 'Returns',
|
|
189
|
+
level: 2,
|
|
190
|
+
content: `\`${metadata.returns.type}\` - ${metadata.returns.description}`,
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
if (metadata.example) {
|
|
195
|
+
sections.push({
|
|
196
|
+
title: 'Example',
|
|
197
|
+
level: 2,
|
|
198
|
+
content: codeBlock(metadata.example, 'javascript'),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const content = [
|
|
203
|
+
heading(`${metadata.name}()`, 1),
|
|
204
|
+
'',
|
|
205
|
+
...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
|
|
206
|
+
].join('\n');
|
|
207
|
+
|
|
208
|
+
return DocsProjectionSchema.parse({
|
|
209
|
+
type: 'docs',
|
|
210
|
+
format: 'markdown',
|
|
211
|
+
content,
|
|
212
|
+
frontMatter: {
|
|
213
|
+
function: metadata.name,
|
|
214
|
+
type: 'api-documentation',
|
|
215
|
+
},
|
|
216
|
+
sections,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Generate cross-reference links in markdown
|
|
222
|
+
* @param {string} text - Text with potential references
|
|
223
|
+
* @param {Map<string, string>} refMap - Map of reference IDs to URLs
|
|
224
|
+
* @returns {string} Text with markdown links
|
|
225
|
+
*/
|
|
226
|
+
export function generateCrossRefs(text, refMap) {
|
|
227
|
+
let result = text;
|
|
228
|
+
|
|
229
|
+
for (const [ref, url] of refMap.entries()) {
|
|
230
|
+
const pattern = new RegExp(`\\b${ref}\\b`, 'g');
|
|
231
|
+
result = result.replace(pattern, `[${ref}](${url})`);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Generate table of contents from sections
|
|
239
|
+
* @param {Array<{title: string, level: number}>} sections - Document sections
|
|
240
|
+
* @returns {string} Markdown table of contents
|
|
241
|
+
*/
|
|
242
|
+
export function generateTableOfContents(sections) {
|
|
243
|
+
const toc = sections.map(section => {
|
|
244
|
+
const indent = ' '.repeat(section.level - 1);
|
|
245
|
+
const anchor = section.title.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '');
|
|
246
|
+
return `${indent}- [${section.title}](#${anchor})`;
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
return '## Table of Contents\n\n' + toc.join('\n');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Project workflow to documentation
|
|
254
|
+
* @param {object} workflow - Workflow definition
|
|
255
|
+
* @param {string} workflow.id - Workflow ID
|
|
256
|
+
* @param {string} workflow.name - Workflow name
|
|
257
|
+
* @param {string} workflow.description - Workflow description
|
|
258
|
+
* @param {Array<{id: string, type: string, description: string}>} workflow.steps - Workflow steps
|
|
259
|
+
* @returns {DocsProjection} Documentation projection
|
|
260
|
+
*/
|
|
261
|
+
export function projectWorkflowToDocs(workflow) {
|
|
262
|
+
const sections = [
|
|
263
|
+
{
|
|
264
|
+
title: 'Overview',
|
|
265
|
+
level: 2,
|
|
266
|
+
content: workflow.description,
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
title: 'Workflow Steps',
|
|
270
|
+
level: 2,
|
|
271
|
+
content: workflow.steps.map((step, i) =>
|
|
272
|
+
`${i + 1}. **${step.type}** (\`${step.id}\`)\n ${step.description}`
|
|
273
|
+
).join('\n\n'),
|
|
274
|
+
},
|
|
275
|
+
];
|
|
276
|
+
|
|
277
|
+
const content = [
|
|
278
|
+
heading(workflow.name, 1),
|
|
279
|
+
'',
|
|
280
|
+
...sections.map(s => [heading(s.title, s.level), '', s.content, ''].join('\n')),
|
|
281
|
+
].join('\n');
|
|
282
|
+
|
|
283
|
+
const crossRefs = workflow.steps.map((step, i) => ({
|
|
284
|
+
source: workflow.id,
|
|
285
|
+
target: step.id,
|
|
286
|
+
type: 'step',
|
|
287
|
+
}));
|
|
288
|
+
|
|
289
|
+
return DocsProjectionSchema.parse({
|
|
290
|
+
type: 'docs',
|
|
291
|
+
format: 'markdown',
|
|
292
|
+
content,
|
|
293
|
+
frontMatter: {
|
|
294
|
+
workflowId: workflow.id,
|
|
295
|
+
name: workflow.name,
|
|
296
|
+
},
|
|
297
|
+
sections,
|
|
298
|
+
crossRefs,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Π_ide - IDE Metadata Projections
|
|
3
|
+
* Transforms KGC structures into LSP-compatible metadata for IDE integration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* IDE projection schema (LSP-compatible)
|
|
10
|
+
*/
|
|
11
|
+
export const IDEProjectionSchema = z.object({
|
|
12
|
+
type: z.literal('ide'),
|
|
13
|
+
format: z.enum(['lsp', 'hover', 'completion', 'definition']),
|
|
14
|
+
content: z.record(z.any()),
|
|
15
|
+
uri: z.string().optional(),
|
|
16
|
+
range: z.object({
|
|
17
|
+
start: z.object({ line: z.number(), character: z.number() }),
|
|
18
|
+
end: z.object({ line: z.number(), character: z.number() }),
|
|
19
|
+
}).optional(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {z.infer<typeof IDEProjectionSchema>} IDEProjection
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* LSP Position
|
|
28
|
+
* @typedef {{line: number, character: number}} Position
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* LSP Range
|
|
33
|
+
* @typedef {{start: Position, end: Position}} Range
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Project function to LSP hover information
|
|
38
|
+
* @param {object} fnInfo - Function information
|
|
39
|
+
* @param {string} fnInfo.name - Function name
|
|
40
|
+
* @param {string} fnInfo.signature - Function signature
|
|
41
|
+
* @param {string} fnInfo.documentation - Documentation text
|
|
42
|
+
* @param {Array<{name: string, type: string, description: string}>} fnInfo.parameters - Parameters
|
|
43
|
+
* @param {object} fnInfo.returns - Return type info
|
|
44
|
+
* @returns {IDEProjection} IDE projection
|
|
45
|
+
*/
|
|
46
|
+
export function projectFunctionToHover(fnInfo) {
|
|
47
|
+
const paramDocs = fnInfo.parameters.map(p =>
|
|
48
|
+
`@param {${p.type}} ${p.name} - ${p.description}`
|
|
49
|
+
).join('\n');
|
|
50
|
+
|
|
51
|
+
const returnDoc = `@returns {${fnInfo.returns.type}} ${fnInfo.returns.description}`;
|
|
52
|
+
|
|
53
|
+
const markdown = [
|
|
54
|
+
`\`\`\`javascript`,
|
|
55
|
+
fnInfo.signature,
|
|
56
|
+
`\`\`\``,
|
|
57
|
+
'',
|
|
58
|
+
fnInfo.documentation,
|
|
59
|
+
'',
|
|
60
|
+
paramDocs,
|
|
61
|
+
returnDoc,
|
|
62
|
+
].join('\n');
|
|
63
|
+
|
|
64
|
+
return IDEProjectionSchema.parse({
|
|
65
|
+
type: 'ide',
|
|
66
|
+
format: 'hover',
|
|
67
|
+
content: {
|
|
68
|
+
kind: 'markdown',
|
|
69
|
+
value: markdown,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Project schema to LSP completion items
|
|
76
|
+
* @param {string} schemaName - Schema name
|
|
77
|
+
* @param {object} fields - Schema fields
|
|
78
|
+
* @returns {IDEProjection} IDE projection with completions
|
|
79
|
+
*/
|
|
80
|
+
export function projectSchemaToCompletions(schemaName, fields) {
|
|
81
|
+
const completionItems = Object.entries(fields).map(([key, info]) => ({
|
|
82
|
+
label: key,
|
|
83
|
+
kind: 10, // LSP CompletionItemKind.Property
|
|
84
|
+
detail: info.type,
|
|
85
|
+
documentation: {
|
|
86
|
+
kind: 'markdown',
|
|
87
|
+
value: info.description || `${key} field of ${schemaName}`,
|
|
88
|
+
},
|
|
89
|
+
insertText: key,
|
|
90
|
+
insertTextFormat: 1, // PlainText
|
|
91
|
+
}));
|
|
92
|
+
|
|
93
|
+
return IDEProjectionSchema.parse({
|
|
94
|
+
type: 'ide',
|
|
95
|
+
format: 'completion',
|
|
96
|
+
content: {
|
|
97
|
+
isIncomplete: false,
|
|
98
|
+
items: completionItems,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Project function to LSP definition location
|
|
105
|
+
* @param {object} location - Source location
|
|
106
|
+
* @param {string} location.uri - File URI
|
|
107
|
+
* @param {Range} location.range - Location range
|
|
108
|
+
* @returns {IDEProjection} IDE projection
|
|
109
|
+
*/
|
|
110
|
+
export function projectToDefinition(location) {
|
|
111
|
+
return IDEProjectionSchema.parse({
|
|
112
|
+
type: 'ide',
|
|
113
|
+
format: 'definition',
|
|
114
|
+
content: {
|
|
115
|
+
uri: location.uri,
|
|
116
|
+
range: location.range,
|
|
117
|
+
},
|
|
118
|
+
uri: location.uri,
|
|
119
|
+
range: location.range,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Project receipt to LSP diagnostic
|
|
125
|
+
* @param {object} issue - Issue information
|
|
126
|
+
* @param {string} issue.message - Error message
|
|
127
|
+
* @param {string} issue.severity - Severity level (error, warning, info)
|
|
128
|
+
* @param {Range} issue.range - Error range
|
|
129
|
+
* @param {string} [issue.code] - Error code
|
|
130
|
+
* @returns {object} LSP Diagnostic
|
|
131
|
+
*/
|
|
132
|
+
export function projectToDiagnostic(issue) {
|
|
133
|
+
const severityMap = {
|
|
134
|
+
error: 1,
|
|
135
|
+
warning: 2,
|
|
136
|
+
info: 3,
|
|
137
|
+
hint: 4,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
range: issue.range,
|
|
142
|
+
severity: severityMap[issue.severity] || 1,
|
|
143
|
+
code: issue.code,
|
|
144
|
+
message: issue.message,
|
|
145
|
+
source: 'kgc-runtime',
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Generate LSP symbol information for workspace indexing
|
|
151
|
+
* @param {object} symbolInfo - Symbol information
|
|
152
|
+
* @param {string} symbolInfo.name - Symbol name
|
|
153
|
+
* @param {string} symbolInfo.kind - Symbol kind (function, class, variable, etc.)
|
|
154
|
+
* @param {string} symbolInfo.containerName - Container name
|
|
155
|
+
* @param {object} symbolInfo.location - Symbol location
|
|
156
|
+
* @returns {object} LSP DocumentSymbol
|
|
157
|
+
*/
|
|
158
|
+
export function projectToSymbol(symbolInfo) {
|
|
159
|
+
const kindMap = {
|
|
160
|
+
function: 12,
|
|
161
|
+
class: 5,
|
|
162
|
+
interface: 11,
|
|
163
|
+
variable: 13,
|
|
164
|
+
constant: 14,
|
|
165
|
+
property: 7,
|
|
166
|
+
method: 6,
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
name: symbolInfo.name,
|
|
171
|
+
kind: kindMap[symbolInfo.kind] || 13,
|
|
172
|
+
location: symbolInfo.location,
|
|
173
|
+
containerName: symbolInfo.containerName,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Generate code action (quick fix) for common issues
|
|
179
|
+
* @param {object} actionInfo - Action information
|
|
180
|
+
* @param {string} actionInfo.title - Action title
|
|
181
|
+
* @param {string} actionInfo.kind - Action kind (quickfix, refactor, etc.)
|
|
182
|
+
* @param {object} actionInfo.edit - Workspace edit
|
|
183
|
+
* @returns {object} LSP CodeAction
|
|
184
|
+
*/
|
|
185
|
+
export function projectToCodeAction(actionInfo) {
|
|
186
|
+
return {
|
|
187
|
+
title: actionInfo.title,
|
|
188
|
+
kind: actionInfo.kind || 'quickfix',
|
|
189
|
+
edit: actionInfo.edit,
|
|
190
|
+
isPreferred: actionInfo.isPreferred || false,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Project work item to LSP code lens
|
|
196
|
+
* @param {object} workItem - Work item
|
|
197
|
+
* @param {Range} range - Code range
|
|
198
|
+
* @returns {object} LSP CodeLens
|
|
199
|
+
*/
|
|
200
|
+
export function projectToCodeLens(workItem, range) {
|
|
201
|
+
return {
|
|
202
|
+
range,
|
|
203
|
+
command: {
|
|
204
|
+
title: `▶ ${workItem.goal}`,
|
|
205
|
+
command: 'kgc.executeWorkItem',
|
|
206
|
+
arguments: [workItem.id],
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Generate signature help for function calls
|
|
213
|
+
* @param {object} fnInfo - Function information
|
|
214
|
+
* @param {number} activeParameter - Active parameter index
|
|
215
|
+
* @returns {IDEProjection} IDE projection with signature help
|
|
216
|
+
*/
|
|
217
|
+
export function projectToSignatureHelp(fnInfo, activeParameter = 0) {
|
|
218
|
+
const parameters = fnInfo.parameters.map(p => ({
|
|
219
|
+
label: `${p.name}: ${p.type}`,
|
|
220
|
+
documentation: {
|
|
221
|
+
kind: 'markdown',
|
|
222
|
+
value: p.description,
|
|
223
|
+
},
|
|
224
|
+
}));
|
|
225
|
+
|
|
226
|
+
const signature = {
|
|
227
|
+
label: `${fnInfo.name}(${fnInfo.parameters.map(p => `${p.name}: ${p.type}`).join(', ')}) => ${fnInfo.returns.type}`,
|
|
228
|
+
documentation: {
|
|
229
|
+
kind: 'markdown',
|
|
230
|
+
value: fnInfo.documentation,
|
|
231
|
+
},
|
|
232
|
+
parameters,
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
return IDEProjectionSchema.parse({
|
|
236
|
+
type: 'ide',
|
|
237
|
+
format: 'lsp',
|
|
238
|
+
content: {
|
|
239
|
+
signatures: [signature],
|
|
240
|
+
activeSignature: 0,
|
|
241
|
+
activeParameter,
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Generate semantic tokens for syntax highlighting
|
|
248
|
+
* @param {Array<{line: number, char: number, length: number, tokenType: string, modifiers?: string[]}>} tokens - Token information
|
|
249
|
+
* @returns {object} LSP SemanticTokens
|
|
250
|
+
*/
|
|
251
|
+
export function projectToSemanticTokens(tokens) {
|
|
252
|
+
const tokenTypes = ['namespace', 'class', 'function', 'variable', 'property', 'parameter'];
|
|
253
|
+
const tokenModifiers = ['declaration', 'readonly', 'static', 'async'];
|
|
254
|
+
|
|
255
|
+
// Encode tokens as per LSP specification (delta encoding)
|
|
256
|
+
const data = [];
|
|
257
|
+
let prevLine = 0;
|
|
258
|
+
let prevChar = 0;
|
|
259
|
+
|
|
260
|
+
for (const token of tokens) {
|
|
261
|
+
const deltaLine = token.line - prevLine;
|
|
262
|
+
const deltaChar = deltaLine === 0 ? token.char - prevChar : token.char;
|
|
263
|
+
const typeIndex = tokenTypes.indexOf(token.tokenType);
|
|
264
|
+
const modifierBits = (token.modifiers || []).reduce(
|
|
265
|
+
(acc, mod) => acc | (1 << tokenModifiers.indexOf(mod)),
|
|
266
|
+
0
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
data.push(deltaLine, deltaChar, token.length, typeIndex, modifierBits);
|
|
270
|
+
|
|
271
|
+
prevLine = token.line;
|
|
272
|
+
prevChar = token.char;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
data,
|
|
277
|
+
};
|
|
278
|
+
}
|