mustflow 2.75.0 → 2.75.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/dist/cli/lib/script-pack-registry.js +3 -3
- package/dist/core/code-outline.js +237 -4
- package/package.json +1 -1
- package/schemas/README.md +3 -2
- package/schemas/code-outline-report.schema.json +61 -0
- package/schemas/code-symbol-read-report.schema.json +15 -0
- package/templates/default/manifest.toml +1 -1
|
@@ -14,15 +14,15 @@ export const SCRIPT_PACKS = [
|
|
|
14
14
|
summaryKey: 'scriptPack.script.codeOutline.summary',
|
|
15
15
|
actions: ['scan'],
|
|
16
16
|
useWhen: [
|
|
17
|
-
'Scan TypeScript or JavaScript files for symbol headers before reading large source files chunk by chunk.',
|
|
18
|
-
'Build a bounded source outline with file paths, line ranges, signatures, export flags, and content hashes for codebase orientation.',
|
|
17
|
+
'Scan TypeScript or JavaScript files for symbol headers and source anchors before reading large source files chunk by chunk.',
|
|
18
|
+
'Build a bounded source outline with file paths, line ranges, signatures, export flags, source-anchor metadata, and content hashes for codebase orientation.',
|
|
19
19
|
],
|
|
20
20
|
phases: ['before_change', 'during_change', 'review'],
|
|
21
21
|
readOnly: true,
|
|
22
22
|
mutates: false,
|
|
23
23
|
network: false,
|
|
24
24
|
inputs: ['path', 'max_files', 'max_file_bytes'],
|
|
25
|
-
outputs: ['human_summary', 'json_report', 'symbol_outline'],
|
|
25
|
+
outputs: ['human_summary', 'json_report', 'symbol_outline', 'source_anchors'],
|
|
26
26
|
relatedSkills: [
|
|
27
27
|
'codebase-orientation',
|
|
28
28
|
'javascript-code-change',
|
|
@@ -2,6 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { existsSync, lstatSync, readdirSync } from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { ensureInside, ensureInsideWithoutSymlinks, readFileInsideWithoutSymlinks } from './safe-filesystem.js';
|
|
5
|
+
import { parseSourceAnchorsInContent, sourceAnchorTextContainsSecretLike, splitSourceAnchorList, } from './source-anchors.js';
|
|
5
6
|
export const CODE_PACK_ID = 'code';
|
|
6
7
|
export const CODE_OUTLINE_SCRIPT_ID = 'outline';
|
|
7
8
|
export const CODE_OUTLINE_SCRIPT_REF = `${CODE_PACK_ID}/${CODE_OUTLINE_SCRIPT_ID}`;
|
|
@@ -11,6 +12,7 @@ const DEFAULT_MAX_FILE_BYTES = 1024 * 1024;
|
|
|
11
12
|
const DEFAULT_MAX_FILES = 200;
|
|
12
13
|
const DEFAULT_CONTEXT_LINES = 0;
|
|
13
14
|
const DEFAULT_MAX_SNIPPET_LINES = 250;
|
|
15
|
+
const RETURN_PREVIEW_MAX_CHARS = 120;
|
|
14
16
|
const CODE_FILE_EXTENSIONS = ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs'];
|
|
15
17
|
const IGNORED_DIRECTORIES = [
|
|
16
18
|
'.git',
|
|
@@ -261,6 +263,169 @@ function buildSignature(lines, startLine, endLine) {
|
|
|
261
263
|
const signature = parts.join(' ').replace(/\s+/gu, ' ');
|
|
262
264
|
return signature.length > 240 ? `${signature.slice(0, 237)}...` : signature;
|
|
263
265
|
}
|
|
266
|
+
function normalizeReturnType(value) {
|
|
267
|
+
return value.replace(/\s+/gu, ' ').replace(/[;{]\s*$/u, '').trim();
|
|
268
|
+
}
|
|
269
|
+
function extractExplicitReturnType(signature, match) {
|
|
270
|
+
if (match.kind !== 'function') {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
const functionReturnMatch = /\bfunction(?:\s+[$A-Z_a-z][$\w]*)?\s*\([^)]*\)\s*:\s*(?<returnType>[^={;]+?)(?=\s*(?:\{|$))/u.exec(signature);
|
|
274
|
+
if (functionReturnMatch?.groups?.returnType) {
|
|
275
|
+
return normalizeReturnType(functionReturnMatch.groups.returnType);
|
|
276
|
+
}
|
|
277
|
+
const arrowReturnMatch = /\)\s*:\s*(?<returnType>[^=]+?)\s*=>/u.exec(signature);
|
|
278
|
+
if (arrowReturnMatch?.groups?.returnType) {
|
|
279
|
+
return normalizeReturnType(arrowReturnMatch.groups.returnType);
|
|
280
|
+
}
|
|
281
|
+
const arrowTypeAnnotationMatch = /:\s*(?:async\s*)?\([^)]*\)\s*=>\s*(?<returnType>[^=;]+?)\s*=/u.exec(signature);
|
|
282
|
+
if (arrowTypeAnnotationMatch?.groups?.returnType) {
|
|
283
|
+
return normalizeReturnType(arrowTypeAnnotationMatch.groups.returnType);
|
|
284
|
+
}
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
function truncateReturnPreview(value) {
|
|
288
|
+
const preview = value.replace(/\s+/gu, ' ').trim();
|
|
289
|
+
return preview.length > RETURN_PREVIEW_MAX_CHARS
|
|
290
|
+
? `${preview.slice(0, RETURN_PREVIEW_MAX_CHARS - 3)}...`
|
|
291
|
+
: preview;
|
|
292
|
+
}
|
|
293
|
+
function extractArrowExpressionReturnPreview(signature) {
|
|
294
|
+
const arrowIndex = signature.lastIndexOf('=>');
|
|
295
|
+
if (arrowIndex < 0) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
const expression = signature.slice(arrowIndex + 2).trim().replace(/;\s*$/u, '');
|
|
299
|
+
if (expression.length === 0 || expression.startsWith('{')) {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
return truncateReturnPreview(expression);
|
|
303
|
+
}
|
|
304
|
+
function isIdentifierCharacter(value) {
|
|
305
|
+
return typeof value === 'string' && /[$\w]/u.test(value);
|
|
306
|
+
}
|
|
307
|
+
function findReturnKeywordIndex(line) {
|
|
308
|
+
let quote = null;
|
|
309
|
+
let escaped = false;
|
|
310
|
+
for (let index = 0; index < line.length; index += 1) {
|
|
311
|
+
const character = line[index];
|
|
312
|
+
const nextCharacter = line[index + 1];
|
|
313
|
+
if (quote !== null) {
|
|
314
|
+
if (escaped) {
|
|
315
|
+
escaped = false;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
if (character === '\\') {
|
|
319
|
+
escaped = true;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (character === quote) {
|
|
323
|
+
quote = null;
|
|
324
|
+
}
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (character === '/' && nextCharacter === '/') {
|
|
328
|
+
return -1;
|
|
329
|
+
}
|
|
330
|
+
if (character === '"' || character === "'" || character === '`') {
|
|
331
|
+
quote = character;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (line.startsWith('return', index) &&
|
|
335
|
+
!isIdentifierCharacter(line[index - 1]) &&
|
|
336
|
+
!isIdentifierCharacter(line[index + 'return'.length])) {
|
|
337
|
+
return index;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return -1;
|
|
341
|
+
}
|
|
342
|
+
function extractReturnExpressionPreview(line) {
|
|
343
|
+
const returnIndex = findReturnKeywordIndex(line);
|
|
344
|
+
if (returnIndex < 0) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
const expression = line
|
|
348
|
+
.slice(returnIndex + 'return'.length)
|
|
349
|
+
.replace(/\/\/.*$/u, '')
|
|
350
|
+
.trim()
|
|
351
|
+
.replace(/;\s*$/u, '')
|
|
352
|
+
.trim();
|
|
353
|
+
return expression.length === 0 ? null : truncateReturnPreview(expression);
|
|
354
|
+
}
|
|
355
|
+
function hasReturnStatement(line) {
|
|
356
|
+
return findReturnKeywordIndex(line) >= 0;
|
|
357
|
+
}
|
|
358
|
+
function simpleBodyThrowsOnly(lines, startLine, endLine, returnType) {
|
|
359
|
+
let sawThrow = false;
|
|
360
|
+
let sawOtherExecutableLine = false;
|
|
361
|
+
for (let index = startLine; index < endLine - 1; index += 1) {
|
|
362
|
+
const bodyLine = stripLineForBraceScan(lines[index] ?? '')
|
|
363
|
+
.replace(/[{};]/gu, '')
|
|
364
|
+
.trim();
|
|
365
|
+
if (bodyLine.length === 0) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (/^throw\b/u.test(bodyLine)) {
|
|
369
|
+
sawThrow = true;
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
sawOtherExecutableLine = true;
|
|
373
|
+
}
|
|
374
|
+
return sawThrow && (!sawOtherExecutableLine || returnType === 'never');
|
|
375
|
+
}
|
|
376
|
+
function extractReturnMetadata(lines, startLine, endLine, signature, match) {
|
|
377
|
+
const returnType = extractExplicitReturnType(signature, match);
|
|
378
|
+
if (match.kind !== 'function') {
|
|
379
|
+
return {
|
|
380
|
+
return_type: null,
|
|
381
|
+
return_behavior: 'unknown',
|
|
382
|
+
return_count: 0,
|
|
383
|
+
return_lines: [],
|
|
384
|
+
return_preview: null,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
const returnLines = [];
|
|
388
|
+
const valueReturnPreviews = [];
|
|
389
|
+
let voidReturnCount = 0;
|
|
390
|
+
for (let index = startLine - 1; index < endLine; index += 1) {
|
|
391
|
+
const line = lines[index] ?? '';
|
|
392
|
+
if (!hasReturnStatement(line)) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
returnLines.push(index + 1);
|
|
396
|
+
const preview = extractReturnExpressionPreview(line);
|
|
397
|
+
if (preview === null) {
|
|
398
|
+
voidReturnCount += 1;
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
valueReturnPreviews.push(preview);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
const arrowExpressionPreview = returnLines.length === 0 ? extractArrowExpressionReturnPreview(signature) : null;
|
|
405
|
+
let returnBehavior;
|
|
406
|
+
if (valueReturnPreviews.length > 0 && voidReturnCount > 0) {
|
|
407
|
+
returnBehavior = 'mixed';
|
|
408
|
+
}
|
|
409
|
+
else if (valueReturnPreviews.length > 0 || arrowExpressionPreview !== null) {
|
|
410
|
+
returnBehavior = 'value';
|
|
411
|
+
}
|
|
412
|
+
else if (voidReturnCount > 0) {
|
|
413
|
+
returnBehavior = 'void';
|
|
414
|
+
}
|
|
415
|
+
else if (simpleBodyThrowsOnly(lines, startLine, endLine, returnType)) {
|
|
416
|
+
returnBehavior = 'throws_only';
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
returnBehavior = 'implicit_undefined';
|
|
420
|
+
}
|
|
421
|
+
return {
|
|
422
|
+
return_type: returnType,
|
|
423
|
+
return_behavior: returnBehavior,
|
|
424
|
+
return_count: returnLines.length,
|
|
425
|
+
return_lines: returnLines,
|
|
426
|
+
return_preview: valueReturnPreviews[0] ?? arrowExpressionPreview,
|
|
427
|
+
};
|
|
428
|
+
}
|
|
264
429
|
function extractSymbols(relativePath, language, contentSha256, text) {
|
|
265
430
|
const lines = text.split(/\r\n|\r|\n/u);
|
|
266
431
|
const symbols = [];
|
|
@@ -271,6 +436,8 @@ function extractSymbols(relativePath, language, contentSha256, text) {
|
|
|
271
436
|
}
|
|
272
437
|
const startLine = index + 1;
|
|
273
438
|
const endLine = findDeclarationEndLine(lines, index);
|
|
439
|
+
const signature = buildSignature(lines, startLine, endLine);
|
|
440
|
+
const returnMetadata = extractReturnMetadata(lines, startLine, endLine, signature, match);
|
|
274
441
|
symbols.push({
|
|
275
442
|
id: `${relativePath}:${startLine}:${match.kind}:${match.name}`,
|
|
276
443
|
path: relativePath,
|
|
@@ -279,16 +446,70 @@ function extractSymbols(relativePath, language, contentSha256, text) {
|
|
|
279
446
|
name: match.name,
|
|
280
447
|
start_line: startLine,
|
|
281
448
|
end_line: endLine,
|
|
282
|
-
signature
|
|
449
|
+
signature,
|
|
283
450
|
exported: match.exported,
|
|
284
451
|
async: match.async,
|
|
452
|
+
...returnMetadata,
|
|
285
453
|
parent: null,
|
|
286
454
|
content_sha256: contentSha256,
|
|
287
455
|
});
|
|
288
456
|
}
|
|
289
457
|
return symbols;
|
|
290
458
|
}
|
|
291
|
-
function
|
|
459
|
+
function sourceAnchorEndLine(lineStart, rawText) {
|
|
460
|
+
return lineStart + rawText.split(/\r\n|\r|\n/u).length - 1;
|
|
461
|
+
}
|
|
462
|
+
function canBridgeAnchorToSymbol(lines, anchorEndLine, symbolStartLine) {
|
|
463
|
+
if (symbolStartLine <= anchorEndLine) {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
for (let lineNumber = anchorEndLine + 1; lineNumber < symbolStartLine; lineNumber += 1) {
|
|
467
|
+
const trimmed = (lines[lineNumber - 1] ?? '').trim();
|
|
468
|
+
if (trimmed.length === 0 || trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('@')) {
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
function findAnchorTargetSymbol(relativePath, lines, anchorEndLine, symbols) {
|
|
476
|
+
const followingSymbols = symbols
|
|
477
|
+
.filter((symbol) => symbol.path === relativePath && symbol.start_line > anchorEndLine)
|
|
478
|
+
.sort((left, right) => left.start_line - right.start_line);
|
|
479
|
+
const target = followingSymbols[0] ?? null;
|
|
480
|
+
if (!target || !canBridgeAnchorToSymbol(lines, anchorEndLine, target.start_line)) {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
return target;
|
|
484
|
+
}
|
|
485
|
+
function extractAnchors(relativePath, lines, text, symbols) {
|
|
486
|
+
const anchors = [];
|
|
487
|
+
for (const anchor of parseSourceAnchorsInContent(relativePath, text)) {
|
|
488
|
+
if (!anchor.idValid || sourceAnchorTextContainsSecretLike(anchor.rawText)) {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
const lineEnd = sourceAnchorEndLine(anchor.lineStart, anchor.rawText);
|
|
492
|
+
const target = findAnchorTargetSymbol(relativePath, lines, lineEnd, symbols);
|
|
493
|
+
anchors.push({
|
|
494
|
+
id: anchor.rawId,
|
|
495
|
+
path: relativePath,
|
|
496
|
+
line_start: anchor.lineStart,
|
|
497
|
+
line_end: lineEnd,
|
|
498
|
+
purpose: anchor.fields.get('purpose') ?? null,
|
|
499
|
+
search: splitSourceAnchorList(anchor.fields.get('search')),
|
|
500
|
+
invariant: anchor.fields.get('invariant') ?? null,
|
|
501
|
+
risk: splitSourceAnchorList(anchor.fields.get('risk')),
|
|
502
|
+
navigation_only: true,
|
|
503
|
+
can_instruct_agent: false,
|
|
504
|
+
target_symbol_id: target?.id ?? null,
|
|
505
|
+
target_kind: target?.kind ?? null,
|
|
506
|
+
target_name: target?.name ?? null,
|
|
507
|
+
target_start_line: target?.start_line ?? null,
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
return anchors;
|
|
511
|
+
}
|
|
512
|
+
function createOutlineInputHash(policy, files, anchors, findings) {
|
|
292
513
|
const inputState = {
|
|
293
514
|
policy,
|
|
294
515
|
files: files.map((file) => ({
|
|
@@ -297,6 +518,13 @@ function createOutlineInputHash(policy, files, findings) {
|
|
|
297
518
|
size_bytes: file.size_bytes,
|
|
298
519
|
symbol_count: file.symbol_count,
|
|
299
520
|
})),
|
|
521
|
+
anchors: anchors.map((anchor) => ({
|
|
522
|
+
id: anchor.id,
|
|
523
|
+
path: anchor.path,
|
|
524
|
+
line_start: anchor.line_start,
|
|
525
|
+
line_end: anchor.line_end,
|
|
526
|
+
target_symbol_id: anchor.target_symbol_id,
|
|
527
|
+
})),
|
|
300
528
|
input_errors: findings
|
|
301
529
|
.filter((finding) => ERROR_OUTLINE_CODES.has(finding.code))
|
|
302
530
|
.map((finding) => ({ code: finding.code, path: finding.path })),
|
|
@@ -319,6 +547,7 @@ export function inspectCodeOutline(projectRoot, options) {
|
|
|
319
547
|
ignored_directories: [...IGNORED_DIRECTORIES],
|
|
320
548
|
};
|
|
321
549
|
const files = [];
|
|
550
|
+
const anchors = [];
|
|
322
551
|
const symbols = [];
|
|
323
552
|
const findings = [];
|
|
324
553
|
const issues = [];
|
|
@@ -339,15 +568,18 @@ export function inspectCodeOutline(projectRoot, options) {
|
|
|
339
568
|
}
|
|
340
569
|
const contentSha256 = sha256Tagged(buffer);
|
|
341
570
|
const text = buffer.toString('utf8');
|
|
571
|
+
const lines = text.split(/\r\n|\r|\n/u);
|
|
342
572
|
const fileSymbols = extractSymbols(candidate.relativePath, candidate.language, contentSha256, text);
|
|
573
|
+
const fileAnchors = extractAnchors(candidate.relativePath, lines, text, fileSymbols);
|
|
343
574
|
symbols.push(...fileSymbols);
|
|
575
|
+
anchors.push(...fileAnchors);
|
|
344
576
|
files.push({
|
|
345
577
|
kind: 'source_file',
|
|
346
578
|
path: candidate.relativePath,
|
|
347
579
|
language: candidate.language,
|
|
348
580
|
sha256: contentSha256,
|
|
349
581
|
size_bytes: buffer.byteLength,
|
|
350
|
-
line_count:
|
|
582
|
+
line_count: lines.length,
|
|
351
583
|
symbol_count: fileSymbols.length,
|
|
352
584
|
});
|
|
353
585
|
}
|
|
@@ -363,8 +595,9 @@ export function inspectCodeOutline(projectRoot, options) {
|
|
|
363
595
|
ok: status === 'passed',
|
|
364
596
|
mustflow_root: root,
|
|
365
597
|
policy,
|
|
366
|
-
input_hash: createOutlineInputHash(policy, files, findings),
|
|
598
|
+
input_hash: createOutlineInputHash(policy, files, anchors, findings),
|
|
367
599
|
files,
|
|
600
|
+
anchors: anchors.sort((left, right) => left.path.localeCompare(right.path) || left.line_start - right.line_start),
|
|
368
601
|
symbols: symbols.sort((left, right) => left.path.localeCompare(right.path) || left.start_line - right.start_line),
|
|
369
602
|
findings,
|
|
370
603
|
issues,
|
package/package.json
CHANGED
package/schemas/README.md
CHANGED
|
@@ -67,11 +67,12 @@ Current schemas:
|
|
|
67
67
|
- `code-outline-report.schema.json`: output of
|
|
68
68
|
`mf script-pack run code/outline scan <path...> --json`, containing a bounded TypeScript and
|
|
69
69
|
JavaScript source outline with file hashes, symbol names, declaration kinds, line ranges,
|
|
70
|
-
signatures, export flags,
|
|
70
|
+
signatures, export flags, source-anchor navigation metadata, static return metadata, and stable
|
|
71
|
+
input-limit finding codes
|
|
71
72
|
- `code-symbol-read-report.schema.json`: output of
|
|
72
73
|
`mf script-pack run code/symbol-read read <path> --start-line <line> --json`, containing a
|
|
73
74
|
focused source snippet selected by outline symbol line or explicit line range with file hash,
|
|
74
|
-
resolved line metadata, optional symbol metadata, and stable range/read finding codes
|
|
75
|
+
resolved line metadata, optional symbol and static return metadata, and stable range/read finding codes
|
|
75
76
|
- `text-budget-report.schema.json`: output of
|
|
76
77
|
`mf script-pack run core/text-budget check <path...> --json`, containing
|
|
77
78
|
exact text-budget metrics, input content hashes, policy metadata, findings, and JSON Pointer field
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"policy",
|
|
18
18
|
"input_hash",
|
|
19
19
|
"files",
|
|
20
|
+
"anchors",
|
|
20
21
|
"symbols",
|
|
21
22
|
"findings",
|
|
22
23
|
"issues"
|
|
@@ -37,6 +38,10 @@
|
|
|
37
38
|
"type": "array",
|
|
38
39
|
"items": { "$ref": "#/$defs/file" }
|
|
39
40
|
},
|
|
41
|
+
"anchors": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": { "$ref": "#/$defs/anchor" }
|
|
44
|
+
},
|
|
40
45
|
"symbols": {
|
|
41
46
|
"type": "array",
|
|
42
47
|
"items": { "$ref": "#/$defs/symbol" }
|
|
@@ -90,6 +95,47 @@
|
|
|
90
95
|
"symbol_count": { "type": "integer", "minimum": 0 }
|
|
91
96
|
}
|
|
92
97
|
},
|
|
98
|
+
"anchor": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"additionalProperties": false,
|
|
101
|
+
"required": [
|
|
102
|
+
"id",
|
|
103
|
+
"path",
|
|
104
|
+
"line_start",
|
|
105
|
+
"line_end",
|
|
106
|
+
"purpose",
|
|
107
|
+
"search",
|
|
108
|
+
"invariant",
|
|
109
|
+
"risk",
|
|
110
|
+
"navigation_only",
|
|
111
|
+
"can_instruct_agent",
|
|
112
|
+
"target_symbol_id",
|
|
113
|
+
"target_kind",
|
|
114
|
+
"target_name",
|
|
115
|
+
"target_start_line"
|
|
116
|
+
],
|
|
117
|
+
"properties": {
|
|
118
|
+
"id": { "type": "string" },
|
|
119
|
+
"path": { "type": "string" },
|
|
120
|
+
"line_start": { "type": "integer", "minimum": 1 },
|
|
121
|
+
"line_end": { "type": "integer", "minimum": 1 },
|
|
122
|
+
"purpose": { "type": ["string", "null"] },
|
|
123
|
+
"search": { "$ref": "#/$defs/stringArray" },
|
|
124
|
+
"invariant": { "type": ["string", "null"] },
|
|
125
|
+
"risk": { "$ref": "#/$defs/stringArray" },
|
|
126
|
+
"navigation_only": { "const": true },
|
|
127
|
+
"can_instruct_agent": { "const": false },
|
|
128
|
+
"target_symbol_id": { "type": ["string", "null"] },
|
|
129
|
+
"target_kind": {
|
|
130
|
+
"anyOf": [
|
|
131
|
+
{ "$ref": "#/$defs/symbolKind" },
|
|
132
|
+
{ "type": "null" }
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"target_name": { "type": ["string", "null"] },
|
|
136
|
+
"target_start_line": { "type": ["integer", "null"], "minimum": 1 }
|
|
137
|
+
}
|
|
138
|
+
},
|
|
93
139
|
"symbol": {
|
|
94
140
|
"type": "object",
|
|
95
141
|
"additionalProperties": false,
|
|
@@ -104,6 +150,11 @@
|
|
|
104
150
|
"signature",
|
|
105
151
|
"exported",
|
|
106
152
|
"async",
|
|
153
|
+
"return_type",
|
|
154
|
+
"return_behavior",
|
|
155
|
+
"return_count",
|
|
156
|
+
"return_lines",
|
|
157
|
+
"return_preview",
|
|
107
158
|
"parent",
|
|
108
159
|
"content_sha256"
|
|
109
160
|
],
|
|
@@ -118,6 +169,16 @@
|
|
|
118
169
|
"signature": { "type": "string" },
|
|
119
170
|
"exported": { "type": "boolean" },
|
|
120
171
|
"async": { "type": "boolean" },
|
|
172
|
+
"return_type": { "type": ["string", "null"] },
|
|
173
|
+
"return_behavior": {
|
|
174
|
+
"enum": ["value", "void", "implicit_undefined", "mixed", "throws_only", "unknown"]
|
|
175
|
+
},
|
|
176
|
+
"return_count": { "type": "integer", "minimum": 0 },
|
|
177
|
+
"return_lines": {
|
|
178
|
+
"type": "array",
|
|
179
|
+
"items": { "type": "integer", "minimum": 1 }
|
|
180
|
+
},
|
|
181
|
+
"return_preview": { "type": ["string", "null"] },
|
|
121
182
|
"parent": { "type": ["string", "null"] },
|
|
122
183
|
"content_sha256": { "$ref": "#/$defs/sha256" }
|
|
123
184
|
}
|
|
@@ -91,6 +91,11 @@
|
|
|
91
91
|
"signature",
|
|
92
92
|
"exported",
|
|
93
93
|
"async",
|
|
94
|
+
"return_type",
|
|
95
|
+
"return_behavior",
|
|
96
|
+
"return_count",
|
|
97
|
+
"return_lines",
|
|
98
|
+
"return_preview",
|
|
94
99
|
"parent",
|
|
95
100
|
"content_sha256"
|
|
96
101
|
],
|
|
@@ -105,6 +110,16 @@
|
|
|
105
110
|
"signature": { "type": "string" },
|
|
106
111
|
"exported": { "type": "boolean" },
|
|
107
112
|
"async": { "type": "boolean" },
|
|
113
|
+
"return_type": { "type": ["string", "null"] },
|
|
114
|
+
"return_behavior": {
|
|
115
|
+
"enum": ["value", "void", "implicit_undefined", "mixed", "throws_only", "unknown"]
|
|
116
|
+
},
|
|
117
|
+
"return_count": { "type": "integer", "minimum": 0 },
|
|
118
|
+
"return_lines": {
|
|
119
|
+
"type": "array",
|
|
120
|
+
"items": { "type": "integer", "minimum": 1 }
|
|
121
|
+
},
|
|
122
|
+
"return_preview": { "type": ["string", "null"] },
|
|
108
123
|
"parent": { "type": ["string", "null"] },
|
|
109
124
|
"content_sha256": { "$ref": "#/$defs/sha256" }
|
|
110
125
|
}
|