@jarkkojs/readseek-api 0.9.16 → 0.10.1
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 +14 -4
- package/bin/readseek.cjs +8 -2
- package/dist/argv.d.ts +30 -24
- package/dist/client-output.d.ts +425 -0
- package/dist/client.d.ts +30 -256
- package/dist/contract.d.ts +15 -21
- package/dist/edit-plan.d.ts +1 -0
- package/dist/{json.d.ts → error.d.ts} +0 -1
- package/dist/index.d.ts +10 -8
- package/dist/index.js +1059 -766
- package/dist/kdl.d.ts +7 -0
- package/dist/output-kdl.d.ts +1 -0
- package/dist/process-bun.d.ts +1 -1
- package/dist/process-node.d.ts +1 -1
- package/dist/process.d.ts +3 -1
- package/dist/validation.d.ts +0 -7
- package/package.json +10 -5
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/contract.ts
|
|
2
|
-
var
|
|
2
|
+
var INSPECT_FACETS = [
|
|
3
3
|
"metadata",
|
|
4
4
|
"content",
|
|
5
5
|
"map",
|
|
@@ -9,18 +9,6 @@ var DIGEST_FACETS = [
|
|
|
9
9
|
var VISION_MODES = ["none", "all", "ocr", "caption", "objects"];
|
|
10
10
|
var VISION_ANALYSIS_MODES = ["all", "ocr", "caption", "objects"];
|
|
11
11
|
var VISION_LEVELS = ["low", "medium", "high"];
|
|
12
|
-
var DOCUMENT_NODE_KINDS = [
|
|
13
|
-
"artifact",
|
|
14
|
-
"footer",
|
|
15
|
-
"header",
|
|
16
|
-
"heading",
|
|
17
|
-
"marginal_label",
|
|
18
|
-
"page",
|
|
19
|
-
"page_number",
|
|
20
|
-
"paragraph",
|
|
21
|
-
"section",
|
|
22
|
-
"structural_section"
|
|
23
|
-
];
|
|
24
12
|
var EDIT_VARIANTS = [
|
|
25
13
|
"set_line",
|
|
26
14
|
"replace_lines",
|
|
@@ -28,13 +16,13 @@ var EDIT_VARIANTS = [
|
|
|
28
16
|
"replace",
|
|
29
17
|
"replace_symbol"
|
|
30
18
|
];
|
|
31
|
-
var
|
|
19
|
+
var GIT_SCOPES = ["tracked", "untracked", "ignored", "all"];
|
|
32
20
|
var TOOL_NAMES = [
|
|
33
|
-
"
|
|
21
|
+
"inspect",
|
|
34
22
|
"edit",
|
|
35
23
|
"write",
|
|
36
24
|
"grep",
|
|
37
|
-
"
|
|
25
|
+
"extract",
|
|
38
26
|
"search",
|
|
39
27
|
"def",
|
|
40
28
|
"refs",
|
|
@@ -56,28 +44,24 @@ var PARAM_DESCRIPTIONS = {
|
|
|
56
44
|
line: "One-based cursor line; required with scope",
|
|
57
45
|
renameLine: "One-based cursor line of the symbol to rename",
|
|
58
46
|
column: "One-based cursor byte column for disambiguation",
|
|
59
|
-
|
|
60
|
-
others: "In a Git repository, search untracked files",
|
|
61
|
-
ignored: "With others=true, include ignored untracked files",
|
|
47
|
+
gitScope: "In a Git repository, which files to search: tracked, untracked, ignored (untracked plus ignored), or all. Defaults to tracked plus untracked.",
|
|
62
48
|
select: "Facets: metadata, content, map, diagnostics, identity (default content)",
|
|
63
49
|
selectComma: "Comma-separated facets: metadata, content, map, diagnostics, identity",
|
|
64
|
-
|
|
50
|
+
selector: "Positional selector: line:N[:COLUMN], hash:H[:COLUMN], symbol:NAME, page:N, node:ID, or asset:ID. Columns require the identity facet, which in turn rejects symbol selectors",
|
|
51
|
+
assetSelector: "Document asset selector in the form asset:ID",
|
|
52
|
+
query: "KDL selection query, @path, or '-' for standard input",
|
|
53
|
+
stdinName: "File name hint when the target is '-'",
|
|
65
54
|
end: "Last line to include",
|
|
66
55
|
limit: "Maximum number of lines to include",
|
|
67
|
-
|
|
56
|
+
inspectDepth: "Maximum structural depth for map output; defaults to 1 in agent tools",
|
|
68
57
|
offset: "One-based starting line",
|
|
69
58
|
readLimit: "Maximum lines to return",
|
|
70
59
|
symbolRead: "Symbol name to read",
|
|
71
60
|
bundle: "Include related symbols from the same file; requires symbol",
|
|
72
61
|
image: "Standalone image mode: none, all, ocr, caption, objects. Required for standalone images.",
|
|
73
|
-
|
|
74
|
-
visionModeView: "Analyze selected assets: all, ocr, caption, or objects",
|
|
62
|
+
visionModeInspect: "Standalone image mode: none, all, caption, objects, or ocr",
|
|
75
63
|
visionLevel: "Vision inference level: low (default), medium, or high",
|
|
76
|
-
|
|
77
|
-
page: "One-based source page",
|
|
78
|
-
kind: "Node kind filter",
|
|
79
|
-
depth: "Maximum depth below selected roots",
|
|
80
|
-
outline: "Return outline nodes only",
|
|
64
|
+
output: "Destination file for extracted binary data; stdout is not supported",
|
|
81
65
|
edits: "Use set_line, replace_lines, insert_after, replace_symbol, or replace",
|
|
82
66
|
editVariant: "Exactly one nested edit variant",
|
|
83
67
|
setLine: 'Replace one line: {"set_line":{"anchor":"LINE:HASH","new_text":"..."}}',
|
|
@@ -114,11 +98,11 @@ var PARAM_DESCRIPTIONS = {
|
|
|
114
98
|
scopeContext: "Context lines within each symbol"
|
|
115
99
|
};
|
|
116
100
|
var TOOL_DESCRIPTIONS = {
|
|
117
|
-
|
|
101
|
+
inspect: "Inspect source content, images, and documents through the native CLI envelope. Use it before edits to obtain fresh `LINE:HASH` anchors; use shallow maps for structural overviews, diagnostics for syntax checks, and identity for cursor context.",
|
|
118
102
|
edit: 'Edit existing text files with fresh `LINE:HASH` anchors. Read or search first when no fresh anchors are available. Each `edits[]` item must use exactly one nested object: `{"set_line":{"anchor":"LINE:HASH","new_text":"..."}}`, `{"replace_lines":{"start_anchor":"LINE:HASH","end_anchor":"LINE:HASH","new_text":"..."}}`, `{"insert_after":{"anchor":"LINE:HASH","new_text":"..."}}`, `{"replace_symbol":{"symbol":"name","new_body":"..."}}`, or `{"replace":{"old_text":"...","new_text":"..."}}`.',
|
|
119
103
|
write: "Create or replace a complete text file and return `LINE:HASH` anchors. Use `edit` for small changes to an existing file.",
|
|
120
104
|
grep: "Search text or regex in files and return edit-ready `LINE:HASH` anchors. Use for identifiers, strings, configuration, errors, comments, and documentation.",
|
|
121
|
-
|
|
105
|
+
extract: "Extract a selected document asset into a destination file. Use an `asset:ID` selector discovered through `inspect`; extracted binary data is never returned on stdout.",
|
|
122
106
|
search: "Search code by AST structure using ast-grep-style patterns. Results include line hashes usable as `LINE:HASH` anchors. Use `grep` for identifiers, strings, comments, configuration, documentation, or other plain text and regex.",
|
|
123
107
|
def: "Go to a symbol definition or declaration by name. Accepts qualified or unqualified names; use this instead of text search for functions, methods, classes, types, and other declarations.",
|
|
124
108
|
refs: "Find references or usages of an identifier by name or cursor binding. Results include enclosing symbols and line hashes usable as `LINE:HASH` anchors. Without cursor scope, results are identifier-name matches; with scope, they follow one binding and exclude shadows. Use text search for literals, and use this before renaming or deleting a symbol.",
|
|
@@ -130,18 +114,11 @@ function renderToolDescription(name, aliases = {}) {
|
|
|
130
114
|
throw new Error(`Missing TOOL_DESCRIPTIONS for ${name}`);
|
|
131
115
|
return TOOL_NAMES.reduce((description, toolName) => description.replaceAll(`\`${toolName}\``, `\`${aliases[toolName] ?? toolName}\``), desc);
|
|
132
116
|
}
|
|
133
|
-
var
|
|
134
|
-
|
|
135
|
-
type: "
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
others: {
|
|
139
|
-
type: "boolean",
|
|
140
|
-
description: PARAM_DESCRIPTIONS.others
|
|
141
|
-
},
|
|
142
|
-
ignored: {
|
|
143
|
-
type: "boolean",
|
|
144
|
-
description: PARAM_DESCRIPTIONS.ignored
|
|
117
|
+
var gitScopeSchema = {
|
|
118
|
+
gitScope: {
|
|
119
|
+
type: "string",
|
|
120
|
+
enum: GIT_SCOPES,
|
|
121
|
+
description: PARAM_DESCRIPTIONS.gitScope
|
|
145
122
|
}
|
|
146
123
|
};
|
|
147
124
|
var editItemSchema = {
|
|
@@ -207,29 +184,31 @@ var editItemSchema = {
|
|
|
207
184
|
};
|
|
208
185
|
var TOOL_CONTRACTS = [
|
|
209
186
|
{
|
|
210
|
-
name: "
|
|
211
|
-
title: "
|
|
212
|
-
description: TOOL_DESCRIPTIONS.
|
|
187
|
+
name: "inspect",
|
|
188
|
+
title: "Inspect input",
|
|
189
|
+
description: TOOL_DESCRIPTIONS.inspect,
|
|
213
190
|
inputSchema: {
|
|
214
191
|
type: "object",
|
|
215
192
|
properties: {
|
|
216
193
|
path: { type: "string", description: PARAM_DESCRIPTIONS.path },
|
|
194
|
+
selector: { type: "string", description: PARAM_DESCRIPTIONS.selector },
|
|
217
195
|
select: { type: "string", description: PARAM_DESCRIPTIONS.select },
|
|
218
|
-
|
|
196
|
+
query: { type: "string", description: PARAM_DESCRIPTIONS.query },
|
|
219
197
|
end: { type: "integer", minimum: 1, description: PARAM_DESCRIPTIONS.end },
|
|
220
198
|
limit: { type: "integer", minimum: 1, description: PARAM_DESCRIPTIONS.limit },
|
|
221
|
-
depth: { type: "integer", minimum: 0, description: PARAM_DESCRIPTIONS.
|
|
199
|
+
depth: { type: "integer", minimum: 0, description: PARAM_DESCRIPTIONS.inspectDepth },
|
|
222
200
|
language: { type: "string", description: PARAM_DESCRIPTIONS.languageOverride },
|
|
223
201
|
visionMode: {
|
|
224
202
|
type: "string",
|
|
225
203
|
enum: [...VISION_MODES],
|
|
226
|
-
description: PARAM_DESCRIPTIONS.
|
|
204
|
+
description: PARAM_DESCRIPTIONS.visionModeInspect
|
|
227
205
|
},
|
|
228
206
|
visionLevel: {
|
|
229
207
|
type: "string",
|
|
230
208
|
enum: [...VISION_LEVELS],
|
|
231
209
|
description: PARAM_DESCRIPTIONS.visionLevel
|
|
232
|
-
}
|
|
210
|
+
},
|
|
211
|
+
stdinName: { type: "string", description: PARAM_DESCRIPTIONS.stdinName }
|
|
233
212
|
},
|
|
234
213
|
required: ["path"],
|
|
235
214
|
additionalProperties: false
|
|
@@ -303,34 +282,27 @@ var TOOL_CONTRACTS = [
|
|
|
303
282
|
}
|
|
304
283
|
},
|
|
305
284
|
{
|
|
306
|
-
name: "
|
|
307
|
-
title: "
|
|
308
|
-
description: TOOL_DESCRIPTIONS.
|
|
285
|
+
name: "extract",
|
|
286
|
+
title: "Extract asset",
|
|
287
|
+
description: TOOL_DESCRIPTIONS.extract,
|
|
309
288
|
inputSchema: {
|
|
310
289
|
type: "object",
|
|
311
290
|
properties: {
|
|
312
291
|
path: { type: "string", description: PARAM_DESCRIPTIONS.path },
|
|
313
|
-
|
|
314
|
-
page: { type: "integer", minimum: 1, description: PARAM_DESCRIPTIONS.page },
|
|
315
|
-
kind: {
|
|
292
|
+
selector: {
|
|
316
293
|
type: "string",
|
|
317
|
-
|
|
318
|
-
description: PARAM_DESCRIPTIONS.
|
|
294
|
+
pattern: "^asset:.+",
|
|
295
|
+
description: PARAM_DESCRIPTIONS.assetSelector
|
|
319
296
|
},
|
|
320
|
-
|
|
321
|
-
outline: { type: "boolean", description: PARAM_DESCRIPTIONS.outline },
|
|
322
|
-
visionMode: {
|
|
297
|
+
output: {
|
|
323
298
|
type: "string",
|
|
324
|
-
|
|
325
|
-
|
|
299
|
+
minLength: 1,
|
|
300
|
+
pattern: "^(?!-$).+",
|
|
301
|
+
description: PARAM_DESCRIPTIONS.output
|
|
326
302
|
},
|
|
327
|
-
|
|
328
|
-
type: "string",
|
|
329
|
-
enum: [...VISION_LEVELS],
|
|
330
|
-
description: PARAM_DESCRIPTIONS.visionLevel
|
|
331
|
-
}
|
|
303
|
+
stdinName: { type: "string", description: PARAM_DESCRIPTIONS.stdinName }
|
|
332
304
|
},
|
|
333
|
-
required: ["path"],
|
|
305
|
+
required: ["path", "selector", "output"],
|
|
334
306
|
additionalProperties: false
|
|
335
307
|
}
|
|
336
308
|
},
|
|
@@ -344,7 +316,8 @@ var TOOL_CONTRACTS = [
|
|
|
344
316
|
pattern: { type: "string", description: PARAM_DESCRIPTIONS.pattern },
|
|
345
317
|
path: { type: "string", description: PARAM_DESCRIPTIONS.searchPath },
|
|
346
318
|
language: { type: "string", description: PARAM_DESCRIPTIONS.language },
|
|
347
|
-
|
|
319
|
+
limit: { type: "integer", minimum: 1, description: PARAM_DESCRIPTIONS.matchLimit },
|
|
320
|
+
...gitScopeSchema
|
|
348
321
|
},
|
|
349
322
|
required: ["pattern"],
|
|
350
323
|
additionalProperties: false
|
|
@@ -360,7 +333,7 @@ var TOOL_CONTRACTS = [
|
|
|
360
333
|
name: { type: "string", description: PARAM_DESCRIPTIONS.name },
|
|
361
334
|
path: { type: "string", description: PARAM_DESCRIPTIONS.searchPath },
|
|
362
335
|
language: { type: "string", description: PARAM_DESCRIPTIONS.language },
|
|
363
|
-
...
|
|
336
|
+
...gitScopeSchema
|
|
364
337
|
},
|
|
365
338
|
required: ["name"],
|
|
366
339
|
additionalProperties: false
|
|
@@ -379,7 +352,7 @@ var TOOL_CONTRACTS = [
|
|
|
379
352
|
scope: { type: "boolean", description: PARAM_DESCRIPTIONS.scope },
|
|
380
353
|
line: { type: "integer", minimum: 1, description: PARAM_DESCRIPTIONS.line },
|
|
381
354
|
column: { type: "integer", minimum: 1, description: PARAM_DESCRIPTIONS.column },
|
|
382
|
-
...
|
|
355
|
+
...gitScopeSchema
|
|
383
356
|
},
|
|
384
357
|
additionalProperties: false
|
|
385
358
|
}
|
|
@@ -397,7 +370,9 @@ var TOOL_CONTRACTS = [
|
|
|
397
370
|
to: { type: "string", description: PARAM_DESCRIPTIONS.to },
|
|
398
371
|
workspace: { type: "boolean", description: PARAM_DESCRIPTIONS.workspace },
|
|
399
372
|
apply: { type: "boolean", description: PARAM_DESCRIPTIONS.apply },
|
|
400
|
-
planHash: { type: "string", description: PARAM_DESCRIPTIONS.planHash }
|
|
373
|
+
planHash: { type: "string", description: PARAM_DESCRIPTIONS.planHash },
|
|
374
|
+
language: { type: "string", description: PARAM_DESCRIPTIONS.language },
|
|
375
|
+
...gitScopeSchema
|
|
401
376
|
},
|
|
402
377
|
required: ["path", "line", "to"],
|
|
403
378
|
additionalProperties: false
|
|
@@ -413,7 +388,7 @@ function getToolContract(name) {
|
|
|
413
388
|
// src/policy.ts
|
|
414
389
|
var REPLACEABLE_TOOLS = [
|
|
415
390
|
{
|
|
416
|
-
tool: "
|
|
391
|
+
tool: "inspect",
|
|
417
392
|
builtIn: "read",
|
|
418
393
|
benefit: "it returns LINE:HASH anchors for safe edits."
|
|
419
394
|
},
|
|
@@ -434,8 +409,8 @@ var REPLACEABLE_TOOLS = [
|
|
|
434
409
|
}
|
|
435
410
|
];
|
|
436
411
|
var TOOL_COMPACT_GUIDELINES = {
|
|
437
|
-
|
|
438
|
-
"Use `
|
|
412
|
+
inspect: [
|
|
413
|
+
"Use `inspect` for shallow maps, diagnostics, and identity; use `def`, `refs`, or `search` for targeted symbol questions."
|
|
439
414
|
],
|
|
440
415
|
edit: [
|
|
441
416
|
"Prefer set_line, replace_lines, and insert_after; use replace only when anchors are impractical."
|
|
@@ -454,14 +429,14 @@ var TOOL_COMPACT_GUIDELINES = {
|
|
|
454
429
|
]
|
|
455
430
|
};
|
|
456
431
|
var BUILTIN_FALLBACKS = {
|
|
457
|
-
read: "
|
|
432
|
+
read: "inspect",
|
|
458
433
|
edit: "edit",
|
|
459
434
|
write: "write",
|
|
460
435
|
grep: "grep",
|
|
461
436
|
apply_patch: "edit"
|
|
462
437
|
};
|
|
463
438
|
var PREFERENCE_LEADS = {
|
|
464
|
-
|
|
439
|
+
inspect: "Preferred for reading source with anchors and facets.",
|
|
465
440
|
edit: "Preferred for editing existing text files with fresh LINE:HASH anchors.",
|
|
466
441
|
write: "Preferred for creating or replacing a complete text file; returns LINE:HASH anchors.",
|
|
467
442
|
grep: "Preferred text/regex search; returns edit-ready LINE:HASH anchors.",
|
|
@@ -469,10 +444,10 @@ var PREFERENCE_LEADS = {
|
|
|
469
444
|
def: "Preferred for go-to-definition or declaration lookup by name.",
|
|
470
445
|
refs: "Preferred for finding identifier-name matches or binding-specific references before rename or delete.",
|
|
471
446
|
rename: "Preferred for renaming a symbol with binding-aware, verified edits.",
|
|
472
|
-
|
|
447
|
+
extract: "Preferred for saving a selected document asset to a file."
|
|
473
448
|
};
|
|
474
449
|
var FALLBACK_TEMPLATES = {
|
|
475
|
-
read: "Prefer `
|
|
450
|
+
read: "Prefer `inspect` with fresh LINE:HASH anchors.",
|
|
476
451
|
edit: "Prefer `edit` with fresh LINE:HASH anchors.",
|
|
477
452
|
write: "Prefer `write` so the result returns LINE:HASH anchors.",
|
|
478
453
|
grep: "Prefer `grep` for text/regex search with edit-ready anchors.",
|
|
@@ -498,7 +473,7 @@ function renderFallbackToolDescription(builtIn, aliases = {}) {
|
|
|
498
473
|
}
|
|
499
474
|
function renderToolRoutingPolicy(options = {}) {
|
|
500
475
|
const aliases = options.aliases ?? {};
|
|
501
|
-
const
|
|
476
|
+
const inspect = resolveToolName("inspect", aliases);
|
|
502
477
|
const edit = resolveToolName("edit", aliases);
|
|
503
478
|
const write = resolveToolName("write", aliases);
|
|
504
479
|
const grep = resolveToolName("grep", aliases);
|
|
@@ -506,11 +481,11 @@ function renderToolRoutingPolicy(options = {}) {
|
|
|
506
481
|
const def = resolveToolName("def", aliases);
|
|
507
482
|
const refs = resolveToolName("refs", aliases);
|
|
508
483
|
const rename = resolveToolName("rename", aliases);
|
|
509
|
-
const
|
|
484
|
+
const extract = resolveToolName("extract", aliases);
|
|
510
485
|
if (options.style === "server") {
|
|
511
486
|
return [
|
|
512
|
-
"Structural code navigation, document
|
|
513
|
-
"For structural questions, prefer these tools to text Grep/Bash: targeted definitions, references, and AST search; shallow
|
|
487
|
+
"Structural code navigation, document inspection, and hash-verified edits with readseek.",
|
|
488
|
+
"For structural questions, prefer these tools to text Grep/Bash: targeted definitions, references, and AST search; shallow inspect maps; diagnostics and identity; and document inspection.",
|
|
514
489
|
`Use ${edit} for LINE:HASH-anchored mutations (preview with apply=false; apply defaults to true and re-checks plan_hash).`,
|
|
515
490
|
"Paths resolve against CLAUDE_PROJECT_DIR. Native Read/Grep/Edit hooks provide passive context;",
|
|
516
491
|
"call MCP tools for active navigation, document questions, or anchored edits."
|
|
@@ -521,7 +496,7 @@ function renderToolRoutingPolicy(options = {}) {
|
|
|
521
496
|
if (options.preferOverBuiltIns) {
|
|
522
497
|
bullets.push("- Prefer ReadSeek tools over built-ins when they can do the job.");
|
|
523
498
|
}
|
|
524
|
-
bullets.push(`- Read with ${
|
|
499
|
+
bullets.push(`- Read with ${inspect} first; ${edit} needs fresh LINE:HASH anchors.`, `- Use ${grep} for text/regex, ${search} for AST patterns, ${def}/${refs} for targeted symbols, and shallow ${inspect} maps only for file overviews.`, `- Use ${edit} for existing files, ${write} for whole-file creation or replacement, and ${rename} for symbol renames.`, `- Use ${inspect} for document structure; run ${inspect} with select diagnostics after source edits for a quick syntax check.`, `- Use ${extract} to save a selected document asset.`);
|
|
525
500
|
if (options.demoteBuiltIns && options.demoteBuiltIns.length > 0) {
|
|
526
501
|
bullets.push(`- Do not use built-in ${options.demoteBuiltIns.join(", ")} when a ReadSeek tool can do the job.`);
|
|
527
502
|
}
|
|
@@ -563,12 +538,6 @@ function parseLineAnchor(anchor) {
|
|
|
563
538
|
}
|
|
564
539
|
|
|
565
540
|
// src/validation.ts
|
|
566
|
-
function validateGitSelection(input) {
|
|
567
|
-
if (input.ignored && !input.others) {
|
|
568
|
-
return { ok: false, error: "ignored requires others=true" };
|
|
569
|
-
}
|
|
570
|
-
return { ok: true };
|
|
571
|
-
}
|
|
572
541
|
function validateRefsNameVsScope(input) {
|
|
573
542
|
if (input.scope) {
|
|
574
543
|
if (input.line === undefined) {
|
|
@@ -585,11 +554,8 @@ function validateRefsNameVsScope(input) {
|
|
|
585
554
|
return { ok: true };
|
|
586
555
|
}
|
|
587
556
|
function validateVisionLevelVsMode(input) {
|
|
588
|
-
if (input.
|
|
589
|
-
return { ok: false, error: "
|
|
590
|
-
}
|
|
591
|
-
if (input.visionLevel !== undefined && input.visionMode === undefined) {
|
|
592
|
-
return { ok: false, error: "visionLevel requires visionMode" };
|
|
557
|
+
if (input.visionLevel !== undefined && !["all", "ocr", "caption", "objects"].includes(input.visionMode ?? "")) {
|
|
558
|
+
return { ok: false, error: "visionLevel requires an analysis visionMode" };
|
|
593
559
|
}
|
|
594
560
|
return { ok: true };
|
|
595
561
|
}
|
|
@@ -716,22 +682,54 @@ function coerceNonNegativeInt(value) {
|
|
|
716
682
|
}
|
|
717
683
|
return;
|
|
718
684
|
}
|
|
685
|
+
// src/edit-plan.ts
|
|
686
|
+
import { Document, Node, format } from "@bgotink/kdl";
|
|
687
|
+
function node(name, properties, children = []) {
|
|
688
|
+
const result = Node.create(name);
|
|
689
|
+
for (const [key, value] of Object.entries(properties))
|
|
690
|
+
result.setProperty(key, value);
|
|
691
|
+
if (children.length > 0)
|
|
692
|
+
result.children = new Document(children);
|
|
693
|
+
return result;
|
|
694
|
+
}
|
|
695
|
+
function editNode(edit) {
|
|
696
|
+
if ("set_line" in edit) {
|
|
697
|
+
const value = edit.set_line;
|
|
698
|
+
return node("set-line", { anchor: value.anchor, text: value.new_text });
|
|
699
|
+
}
|
|
700
|
+
if ("replace_lines" in edit) {
|
|
701
|
+
const value = edit.replace_lines;
|
|
702
|
+
return node("replace-lines", { start: value.start_anchor, end: value.end_anchor, text: value.new_text });
|
|
703
|
+
}
|
|
704
|
+
if ("insert_after" in edit) {
|
|
705
|
+
const value = edit.insert_after;
|
|
706
|
+
return node("insert-after", { anchor: value.anchor, text: value.new_text });
|
|
707
|
+
}
|
|
708
|
+
if ("replace_symbol" in edit) {
|
|
709
|
+
const value = edit.replace_symbol;
|
|
710
|
+
return node("replace-symbol", { symbol: value.symbol, body: value.new_body });
|
|
711
|
+
}
|
|
712
|
+
const value = edit.replace;
|
|
713
|
+
return node("replace", {
|
|
714
|
+
old: value.old_text,
|
|
715
|
+
new: value.new_text,
|
|
716
|
+
...value.all === undefined ? {} : { all: value.all }
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
function serializeEditPlan(edits) {
|
|
720
|
+
const validation = validateExactlyOneEditVariant(edits);
|
|
721
|
+
if (!validation.ok)
|
|
722
|
+
throw new Error(validation.error);
|
|
723
|
+
return format(new Document([node("plan", {}, validation.edits.map(editNode))]));
|
|
724
|
+
}
|
|
719
725
|
// src/argv.ts
|
|
720
|
-
var
|
|
726
|
+
var DEFAULT_INSPECT_MAP_DEPTH = 1;
|
|
721
727
|
function buildLineLocation(line, column) {
|
|
722
728
|
return column === undefined ? `line:${line}` : `line:${line}:${column}`;
|
|
723
729
|
}
|
|
724
|
-
function
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
throw new Error(validated.error);
|
|
728
|
-
}
|
|
729
|
-
if (input.cached)
|
|
730
|
-
args.push("--cached");
|
|
731
|
-
if (input.others)
|
|
732
|
-
args.push("--others");
|
|
733
|
-
if (input.ignored)
|
|
734
|
-
args.push("--ignored");
|
|
730
|
+
function appendGitScopeArgs(args, input) {
|
|
731
|
+
if (input.gitScope !== undefined)
|
|
732
|
+
args.push("--git-scope", input.gitScope);
|
|
735
733
|
return args;
|
|
736
734
|
}
|
|
737
735
|
function pushOptionalString(args, flag, value) {
|
|
@@ -760,33 +758,138 @@ function selectArg(select) {
|
|
|
760
758
|
return;
|
|
761
759
|
return Array.isArray(select) ? select.join(",") : select;
|
|
762
760
|
}
|
|
763
|
-
function
|
|
764
|
-
const
|
|
765
|
-
|
|
761
|
+
function selectedInspectFacets(select) {
|
|
762
|
+
const facets = (selectArg(select) ?? "content").split(",").map((facet) => facet.trim());
|
|
763
|
+
for (const facet of facets) {
|
|
764
|
+
if (!INSPECT_FACETS.includes(facet)) {
|
|
765
|
+
throw new Error(`unknown inspect facet: ${facet}`);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return facets;
|
|
769
|
+
}
|
|
770
|
+
function hasInspectFacet(facets, facet) {
|
|
771
|
+
return facets.includes(facet);
|
|
772
|
+
}
|
|
773
|
+
function validateTarget(command, target, stdinName) {
|
|
774
|
+
if (target.length === 0)
|
|
775
|
+
throw new Error(`${command} requires a target file path or '-'`);
|
|
776
|
+
if (stdinName !== undefined && stdinName.length > 0 && target !== "-") {
|
|
777
|
+
throw new Error("stdinName requires '-' as the target");
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function validatePositiveInteger(value, name) {
|
|
781
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
782
|
+
throw new Error(`${name} must be a positive integer`);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
var SELECTOR_KINDS = ["line", "hash", "symbol", "page", "node", "asset"];
|
|
786
|
+
function isSelectorKind(value) {
|
|
787
|
+
return SELECTOR_KINDS.includes(value);
|
|
766
788
|
}
|
|
767
|
-
function
|
|
789
|
+
function parseSelector(text) {
|
|
790
|
+
const separator = text.indexOf(":");
|
|
791
|
+
if (separator < 0) {
|
|
792
|
+
throw new Error("selector must start with line:, hash:, symbol:, page:, node:, or asset:");
|
|
793
|
+
}
|
|
794
|
+
const kind = text.slice(0, separator);
|
|
795
|
+
const value = text.slice(separator + 1);
|
|
796
|
+
if (value.length === 0)
|
|
797
|
+
throw new Error(`${kind} selector must not be empty`);
|
|
798
|
+
if (!isSelectorKind(kind)) {
|
|
799
|
+
throw new Error(`unknown selector kind \`${kind}\`; expected line, hash, symbol, page, node, or asset`);
|
|
800
|
+
}
|
|
801
|
+
if (kind === "line" || kind === "hash") {
|
|
802
|
+
const parts = value.split(":");
|
|
803
|
+
if (parts.length > 2)
|
|
804
|
+
throw new Error("selector has too many components");
|
|
805
|
+
if (parts.length === 2) {
|
|
806
|
+
const column = Number(parts[1]);
|
|
807
|
+
if (!Number.isSafeInteger(column))
|
|
808
|
+
throw new Error(`invalid column \`${parts[1]}\``);
|
|
809
|
+
if (column < 1)
|
|
810
|
+
throw new Error("column must be greater than zero");
|
|
811
|
+
return { kind, value: parts[0], column };
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (kind === "page") {
|
|
815
|
+
if (value.includes(":"))
|
|
816
|
+
throw new Error("page selector has too many components");
|
|
817
|
+
const page = Number(value);
|
|
818
|
+
if (!Number.isSafeInteger(page))
|
|
819
|
+
throw new Error(`invalid page \`${value}\``);
|
|
820
|
+
if (page < 1)
|
|
821
|
+
throw new Error("page must be greater than zero");
|
|
822
|
+
}
|
|
823
|
+
return { kind, value };
|
|
824
|
+
}
|
|
825
|
+
function buildInspectArgs(input) {
|
|
826
|
+
validateTarget("inspect", input.path, input.stdinName);
|
|
827
|
+
if (input.selector !== undefined && input.selector.length === 0) {
|
|
828
|
+
throw new Error("selector must not be empty");
|
|
829
|
+
}
|
|
768
830
|
const vision = validateVisionLevelVsMode({
|
|
769
831
|
visionMode: input.visionMode,
|
|
770
832
|
visionLevel: input.visionLevel
|
|
771
833
|
});
|
|
772
834
|
if (!vision.ok)
|
|
773
835
|
throw new Error(vision.error);
|
|
774
|
-
const
|
|
836
|
+
const facets = selectedInspectFacets(input.select);
|
|
837
|
+
const hasContent = hasInspectFacet(facets, "content");
|
|
838
|
+
const hasIdentity = hasInspectFacet(facets, "identity");
|
|
839
|
+
const hasMap = hasInspectFacet(facets, "map");
|
|
840
|
+
const hasSourceFacet = hasMap || hasInspectFacet(facets, "diagnostics") || hasIdentity;
|
|
841
|
+
if (input.end !== undefined)
|
|
842
|
+
validatePositiveInteger(input.end, "end");
|
|
843
|
+
if (input.limit !== undefined)
|
|
844
|
+
validatePositiveInteger(input.limit, "limit");
|
|
845
|
+
if (input.end !== undefined && input.limit !== undefined) {
|
|
846
|
+
throw new Error("cannot combine end with limit");
|
|
847
|
+
}
|
|
775
848
|
if (input.depth !== undefined) {
|
|
776
|
-
if (!Number.
|
|
849
|
+
if (!Number.isSafeInteger(input.depth) || input.depth < 0) {
|
|
777
850
|
throw new Error("depth must be a non-negative integer");
|
|
778
851
|
}
|
|
779
|
-
if (!
|
|
852
|
+
if (!hasMap)
|
|
780
853
|
throw new Error("depth requires the map facet");
|
|
781
854
|
}
|
|
855
|
+
if (input.selector !== undefined && input.query !== undefined) {
|
|
856
|
+
throw new Error("cannot combine selector with query");
|
|
857
|
+
}
|
|
858
|
+
if (!hasContent && (input.end !== undefined || input.limit !== undefined || input.query !== undefined)) {
|
|
859
|
+
throw new Error("ranges and queries require the content facet");
|
|
860
|
+
}
|
|
861
|
+
if (hasIdentity && input.selector === undefined) {
|
|
862
|
+
throw new Error("the identity facet requires a selector");
|
|
863
|
+
}
|
|
864
|
+
if (input.selector !== undefined && !hasContent && !hasIdentity) {
|
|
865
|
+
throw new Error("selectors require the content or identity facet");
|
|
866
|
+
}
|
|
867
|
+
if (input.selector !== undefined) {
|
|
868
|
+
const selector = parseSelector(input.selector);
|
|
869
|
+
if (selector.kind === "symbol" && hasIdentity) {
|
|
870
|
+
throw new Error("the identity facet does not accept symbol selectors");
|
|
871
|
+
}
|
|
872
|
+
if (selector.column !== undefined && !hasIdentity) {
|
|
873
|
+
throw new Error("selector columns require the identity facet");
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
const hasVision = input.visionMode !== undefined || input.visionLevel !== undefined;
|
|
877
|
+
if (hasVision && !hasContent) {
|
|
878
|
+
throw new Error("vision options require the content facet");
|
|
879
|
+
}
|
|
880
|
+
if (hasVision && hasSourceFacet) {
|
|
881
|
+
throw new Error("vision options cannot be combined with source facets");
|
|
882
|
+
}
|
|
782
883
|
const args = [];
|
|
783
884
|
if (input.readseekDir !== undefined)
|
|
784
885
|
args.push("--readseek-dir", input.readseekDir);
|
|
785
|
-
args.push("
|
|
886
|
+
args.push("inspect", input.path);
|
|
887
|
+
if (input.selector !== undefined)
|
|
888
|
+
args.push(input.selector);
|
|
786
889
|
const select = selectArg(input.select);
|
|
787
890
|
if (select !== undefined)
|
|
788
891
|
args.push("--select", select);
|
|
789
|
-
pushOptionalString(args, "--
|
|
892
|
+
pushOptionalString(args, "--query", input.query);
|
|
790
893
|
pushOptionalNumber(args, "--end", input.end);
|
|
791
894
|
pushOptionalNumber(args, "--limit", input.limit);
|
|
792
895
|
pushOptionalNumber(args, "--depth", input.depth);
|
|
@@ -794,30 +897,24 @@ function buildDigestArgs(input) {
|
|
|
794
897
|
pushOptionalString(args, "--vision-mode", input.visionMode);
|
|
795
898
|
pushOptionalString(args, "--vision-level", input.visionLevel);
|
|
796
899
|
pushOptionalString(args, "--stdin-name", input.stdinName);
|
|
900
|
+
args.push("--kdl");
|
|
797
901
|
return args;
|
|
798
902
|
}
|
|
799
|
-
function
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
903
|
+
function buildExtractArgs(input) {
|
|
904
|
+
validateTarget("extract", input.path, input.stdinName);
|
|
905
|
+
if (input.selector.length === 0)
|
|
906
|
+
throw new Error("extract requires an asset selector");
|
|
907
|
+
if (!input.selector.startsWith("asset:") || input.selector === "asset:") {
|
|
908
|
+
throw new Error("extract requires an asset: selector");
|
|
909
|
+
}
|
|
910
|
+
if (input.output.length === 0 || input.output === "-") {
|
|
911
|
+
throw new Error("extract output must be a file path");
|
|
912
|
+
}
|
|
807
913
|
const args = [];
|
|
808
914
|
if (input.readseekDir !== undefined)
|
|
809
915
|
args.push("--readseek-dir", input.readseekDir);
|
|
810
|
-
args.push("
|
|
811
|
-
|
|
812
|
-
args.push("--format", input.format);
|
|
813
|
-
pushOptionalString(args, "--node", input.node);
|
|
814
|
-
pushOptionalNumber(args, "--page", input.page);
|
|
815
|
-
pushOptionalString(args, "--kind", input.kind);
|
|
816
|
-
pushOptionalNumber(args, "--depth", input.depth);
|
|
817
|
-
if (input.outline)
|
|
818
|
-
args.push("--outline");
|
|
819
|
-
pushOptionalString(args, "--vision-mode", input.visionMode);
|
|
820
|
-
pushOptionalString(args, "--vision-level", input.visionLevel);
|
|
916
|
+
args.push("--output", input.output, "extract", input.path, input.selector);
|
|
917
|
+
pushOptionalString(args, "--stdin-name", input.stdinName);
|
|
821
918
|
return args;
|
|
822
919
|
}
|
|
823
920
|
function buildSearchArgs(input) {
|
|
@@ -825,15 +922,17 @@ function buildSearchArgs(input) {
|
|
|
825
922
|
pushOptionalString(args, "--path", input.path);
|
|
826
923
|
pushOptionalString(args, "--language", input.language);
|
|
827
924
|
pushOptionalNumber(args, "--limit", input.limit);
|
|
828
|
-
|
|
925
|
+
appendGitScopeArgs(args, input);
|
|
926
|
+
args.push("--kdl");
|
|
927
|
+
return args;
|
|
829
928
|
}
|
|
830
929
|
function buildDefArgs(input) {
|
|
831
930
|
const args = ["def", input.name];
|
|
832
931
|
pushOptionalString(args, "--path", input.path);
|
|
833
|
-
if (input.format !== undefined)
|
|
834
|
-
args.push("--format", input.format);
|
|
835
932
|
pushOptionalString(args, "--language", input.language);
|
|
836
|
-
|
|
933
|
+
appendGitScopeArgs(args, input);
|
|
934
|
+
args.push("--kdl");
|
|
935
|
+
return args;
|
|
837
936
|
}
|
|
838
937
|
function buildRefsArgs(input) {
|
|
839
938
|
const validated = validateRefsNameVsScope(input);
|
|
@@ -848,10 +947,10 @@ function buildRefsArgs(input) {
|
|
|
848
947
|
pushOptionalNumber(args, "--line", input.line);
|
|
849
948
|
pushOptionalNumber(args, "--column", input.column);
|
|
850
949
|
}
|
|
851
|
-
if (input.format !== undefined)
|
|
852
|
-
args.push("--format", input.format);
|
|
853
950
|
pushOptionalString(args, "--language", input.language);
|
|
854
|
-
|
|
951
|
+
appendGitScopeArgs(args, input);
|
|
952
|
+
args.push("--kdl");
|
|
953
|
+
return args;
|
|
855
954
|
}
|
|
856
955
|
function buildEditArgs(input) {
|
|
857
956
|
const args = ["edit", input.path];
|
|
@@ -863,6 +962,7 @@ function buildEditArgs(input) {
|
|
|
863
962
|
pushOptionalString(args, "--language", input.language);
|
|
864
963
|
if (input.requestFromStdin)
|
|
865
964
|
args.push("--edits", "-");
|
|
965
|
+
args.push("--kdl");
|
|
866
966
|
return args;
|
|
867
967
|
}
|
|
868
968
|
function buildRenameArgs(input) {
|
|
@@ -875,7 +975,9 @@ function buildRenameArgs(input) {
|
|
|
875
975
|
flagOrder: input.flagOrder ?? "plan-hash-first"
|
|
876
976
|
});
|
|
877
977
|
pushOptionalString(args, "--language", input.language);
|
|
878
|
-
|
|
978
|
+
appendGitScopeArgs(args, input);
|
|
979
|
+
args.push("--kdl");
|
|
980
|
+
return args;
|
|
879
981
|
}
|
|
880
982
|
// src/platform.ts
|
|
881
983
|
import { accessSync, constants as fsConstants, existsSync, statSync } from "node:fs";
|
|
@@ -891,6 +993,8 @@ var READSEEK_PLATFORM_PACKAGES = {
|
|
|
891
993
|
};
|
|
892
994
|
var resolveFromPackage = createRequire(import.meta.url).resolve;
|
|
893
995
|
function readSeekBinaryName(platform = process.platform) {
|
|
996
|
+
if (platform === "linux")
|
|
997
|
+
return "readseek.AppImage";
|
|
894
998
|
return platform === "win32" ? "readseek.exe" : "readseek";
|
|
895
999
|
}
|
|
896
1000
|
function readSeekPlatformKey(platform = process.platform, arch = process.arch) {
|
|
@@ -965,7 +1069,7 @@ function resolveReadSeekCacheDir(subPath, options = {}) {
|
|
|
965
1069
|
return pathModule.join(base, ...parts);
|
|
966
1070
|
}
|
|
967
1071
|
// src/path.ts
|
|
968
|
-
import { realpathSync } from "node:fs";
|
|
1072
|
+
import { lstatSync, realpathSync } from "node:fs";
|
|
969
1073
|
import { homedir as homedir2 } from "node:os";
|
|
970
1074
|
import path2 from "node:path";
|
|
971
1075
|
var UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
@@ -994,30 +1098,338 @@ function isSubPath(parent, candidate) {
|
|
|
994
1098
|
const relative = path2.relative(parent, candidate);
|
|
995
1099
|
return relative === "" || !relative.startsWith(`..${path2.sep}`) && relative !== ".." && !path2.isAbsolute(relative);
|
|
996
1100
|
}
|
|
1101
|
+
function resolvePathWithMissingTail(filePath) {
|
|
1102
|
+
let ancestor = filePath;
|
|
1103
|
+
const missing = [];
|
|
1104
|
+
while (true) {
|
|
1105
|
+
try {
|
|
1106
|
+
lstatSync(ancestor);
|
|
1107
|
+
} catch (error) {
|
|
1108
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT")
|
|
1109
|
+
throw error;
|
|
1110
|
+
const parent = path2.dirname(ancestor);
|
|
1111
|
+
if (parent === ancestor)
|
|
1112
|
+
throw error;
|
|
1113
|
+
missing.push(path2.basename(ancestor));
|
|
1114
|
+
ancestor = parent;
|
|
1115
|
+
continue;
|
|
1116
|
+
}
|
|
1117
|
+
return path2.join(realpathSync.native(ancestor), ...missing.reverse());
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
997
1120
|
function resolveScopedPath(root, rawPath, fallback = ".") {
|
|
998
|
-
|
|
999
|
-
|
|
1121
|
+
let canonicalRoot;
|
|
1122
|
+
let candidate;
|
|
1123
|
+
try {
|
|
1124
|
+
canonicalRoot = realpathSync.native(path2.resolve(root));
|
|
1125
|
+
candidate = resolvePathWithMissingTail(path2.resolve(canonicalRoot, rawPath ?? fallback));
|
|
1126
|
+
} catch (error) {
|
|
1127
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1128
|
+
return { ok: false, error: `cannot resolve project path (${root}): ${rawPath ?? fallback}: ${message}` };
|
|
1129
|
+
}
|
|
1000
1130
|
if (!isSubPath(canonicalRoot, candidate)) {
|
|
1001
1131
|
return { ok: false, error: `path escapes project root (${canonicalRoot}): ${rawPath ?? fallback}` };
|
|
1002
1132
|
}
|
|
1003
1133
|
return { ok: true, path: candidate };
|
|
1004
1134
|
}
|
|
1005
|
-
// src/
|
|
1006
|
-
var READSEEK_USAGE_HINT =
|
|
1135
|
+
// src/error.ts
|
|
1136
|
+
var READSEEK_USAGE_HINT = /(?:^|\n)\s*Run readseek(?: [\w-]+)* --help for more information\.?\s*$/;
|
|
1007
1137
|
function cleanReadSeekErrorText(stderr) {
|
|
1008
1138
|
return stderr.replace(READSEEK_USAGE_HINT, "").replace(/^error:\s*/i, "").replace(/\s*\n\s*/g, " ").trim();
|
|
1009
1139
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1140
|
+
// src/kdl.ts
|
|
1141
|
+
import { parse } from "@bgotink/kdl";
|
|
1142
|
+
function convertNode(node) {
|
|
1143
|
+
if (node.getTag() !== null)
|
|
1144
|
+
throw new Error("KDL node annotations are not supported");
|
|
1145
|
+
const properties = new Map;
|
|
1146
|
+
for (const entry of node.entries) {
|
|
1147
|
+
const name = entry.getName();
|
|
1148
|
+
if (name === null)
|
|
1149
|
+
throw new Error("KDL positional arguments are not supported");
|
|
1150
|
+
if (properties.has(name))
|
|
1151
|
+
throw new Error(`KDL duplicate property '${name}'`);
|
|
1152
|
+
if (entry.getTag() !== null)
|
|
1153
|
+
throw new Error("KDL value annotations are not supported");
|
|
1154
|
+
const value = entry.getValue();
|
|
1155
|
+
if (value === null)
|
|
1156
|
+
throw new Error("KDL null values are not supported");
|
|
1157
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
1158
|
+
throw new Error("KDL number out of range");
|
|
1159
|
+
}
|
|
1160
|
+
properties.set(name, value);
|
|
1161
|
+
}
|
|
1162
|
+
return {
|
|
1163
|
+
name: node.getName(),
|
|
1164
|
+
properties,
|
|
1165
|
+
children: node.children?.nodes.map(convertNode) ?? []
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
function parseKdlDocument(text) {
|
|
1169
|
+
const document = parse(text);
|
|
1170
|
+
if (document.nodes.length !== 1)
|
|
1171
|
+
throw new Error("KDL document must contain exactly one root node");
|
|
1172
|
+
return convertNode(document.nodes[0]);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
// src/output-kdl.ts
|
|
1176
|
+
function properties(node) {
|
|
1177
|
+
return Object.fromEntries(node.properties);
|
|
1178
|
+
}
|
|
1179
|
+
function children(node, name) {
|
|
1180
|
+
return node.children.filter((child) => child.name === name);
|
|
1181
|
+
}
|
|
1182
|
+
function child(node, name) {
|
|
1183
|
+
return node.children.find((candidate) => candidate.name === name);
|
|
1184
|
+
}
|
|
1185
|
+
function requireProperty(node, name) {
|
|
1186
|
+
const value = node.properties.get(name);
|
|
1187
|
+
if (value === undefined)
|
|
1188
|
+
throw new Error(`invalid readseek KDL: ${node.name} is missing '${name}'`);
|
|
1189
|
+
return value;
|
|
1190
|
+
}
|
|
1191
|
+
function line(node) {
|
|
1192
|
+
const anchor = requireProperty(node, "anchor");
|
|
1193
|
+
const content = requireProperty(node, "content");
|
|
1194
|
+
if (typeof anchor !== "string" || typeof content !== "string") {
|
|
1195
|
+
throw new Error("invalid readseek KDL line");
|
|
1196
|
+
}
|
|
1197
|
+
const match = /^(\d+):([0-9a-f]+)$/.exec(anchor);
|
|
1198
|
+
if (!match)
|
|
1199
|
+
throw new Error(`invalid readseek KDL line anchor: ${anchor}`);
|
|
1200
|
+
return {
|
|
1201
|
+
line: Number(match[1]),
|
|
1202
|
+
hash: match[2],
|
|
1203
|
+
text: content
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
function mapNode(node) {
|
|
1207
|
+
return {
|
|
1208
|
+
...properties(node),
|
|
1209
|
+
children: children(node, "node").map(mapNode)
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
function sourceContent(node) {
|
|
1213
|
+
const result = properties(node);
|
|
1214
|
+
result.hashlines = children(node, "line").map(line);
|
|
1215
|
+
const objects = children(node, "object");
|
|
1216
|
+
if (objects.length > 0) {
|
|
1217
|
+
result.objects = objects.map((object) => ({
|
|
1218
|
+
label: requireProperty(object, "label"),
|
|
1219
|
+
bbox: [
|
|
1220
|
+
requireProperty(object, "xmin"),
|
|
1221
|
+
requireProperty(object, "ymin"),
|
|
1222
|
+
requireProperty(object, "xmax"),
|
|
1223
|
+
requireProperty(object, "ymax")
|
|
1224
|
+
]
|
|
1225
|
+
}));
|
|
1226
|
+
}
|
|
1227
|
+
return result;
|
|
1228
|
+
}
|
|
1229
|
+
function sourceMap(node) {
|
|
1230
|
+
const root = child(node, "node");
|
|
1231
|
+
return {
|
|
1232
|
+
...properties(node),
|
|
1233
|
+
...root ? { root: mapNode(root) } : {},
|
|
1234
|
+
symbols: children(node, "symbol").map(properties)
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
function diagnostics(node) {
|
|
1238
|
+
return {
|
|
1239
|
+
...properties(node),
|
|
1240
|
+
diagnostics: children(node, "diagnostic").map(properties)
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
function identity(node) {
|
|
1244
|
+
const result = properties(node);
|
|
1245
|
+
const identifier = child(node, "identifier");
|
|
1246
|
+
const symbol = child(node, "symbol");
|
|
1247
|
+
if (identifier)
|
|
1248
|
+
result.identifier = properties(identifier);
|
|
1249
|
+
if (symbol)
|
|
1250
|
+
result.symbol = properties(symbol);
|
|
1251
|
+
return result;
|
|
1252
|
+
}
|
|
1253
|
+
function sourceDocument(root) {
|
|
1254
|
+
const result = {};
|
|
1255
|
+
const metadata = child(root, "metadata");
|
|
1256
|
+
const cache = child(root, "cache");
|
|
1257
|
+
const content = child(root, "content");
|
|
1258
|
+
const map = child(root, "map");
|
|
1259
|
+
const diagnosticOutput = child(root, "diagnostics");
|
|
1260
|
+
const identityOutput = child(root, "identity");
|
|
1261
|
+
if (metadata)
|
|
1262
|
+
result.metadata = properties(metadata);
|
|
1263
|
+
if (cache)
|
|
1264
|
+
result.cache = properties(cache);
|
|
1265
|
+
if (content)
|
|
1266
|
+
result.content = sourceContent(content);
|
|
1267
|
+
if (map)
|
|
1268
|
+
result.map = sourceMap(map);
|
|
1269
|
+
if (diagnosticOutput)
|
|
1270
|
+
result.diagnostics = diagnostics(diagnosticOutput);
|
|
1271
|
+
if (identityOutput)
|
|
1272
|
+
result.identity = identity(identityOutput);
|
|
1273
|
+
return result;
|
|
1274
|
+
}
|
|
1275
|
+
function hit(node) {
|
|
1276
|
+
return {
|
|
1277
|
+
...properties(node),
|
|
1278
|
+
hashlines: children(node, "line").map(line),
|
|
1279
|
+
captures: children(node, "capture").map((capture) => ({
|
|
1280
|
+
...properties(capture),
|
|
1281
|
+
hashlines: children(capture, "line").map(line)
|
|
1282
|
+
}))
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
function search(root) {
|
|
1286
|
+
return {
|
|
1287
|
+
...properties(root),
|
|
1288
|
+
results: children(root, "match").map((match) => ({
|
|
1289
|
+
...properties(match),
|
|
1290
|
+
matches: children(match, "hit").map(hit)
|
|
1291
|
+
})),
|
|
1292
|
+
documents: children(root, "document").map((documentNode) => ({
|
|
1293
|
+
...properties(documentNode),
|
|
1294
|
+
hits: children(documentNode, "hit").map(properties)
|
|
1295
|
+
}))
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function references(root) {
|
|
1299
|
+
const parsed = children(root, "reference").map((reference) => {
|
|
1300
|
+
const sourceLine = child(reference, "line");
|
|
1301
|
+
if (!sourceLine)
|
|
1302
|
+
throw new Error("invalid readseek KDL reference: missing line");
|
|
1303
|
+
const parsedLine = line(sourceLine);
|
|
1304
|
+
const symbol = child(reference, "symbol");
|
|
1305
|
+
return {
|
|
1306
|
+
...properties(reference),
|
|
1307
|
+
line_hash: parsedLine.hash,
|
|
1308
|
+
text: parsedLine.text,
|
|
1309
|
+
...symbol ? { symbol: properties(symbol) } : {}
|
|
1310
|
+
};
|
|
1311
|
+
});
|
|
1312
|
+
return {
|
|
1313
|
+
references: parsed,
|
|
1314
|
+
locations: parsed.map((reference) => {
|
|
1315
|
+
const { symbol, ...location } = reference;
|
|
1316
|
+
return symbol && typeof symbol === "object" ? { ...location, ...symbol } : location;
|
|
1317
|
+
})
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
function definitions(root) {
|
|
1321
|
+
return {
|
|
1322
|
+
locations: children(root, "definition").map((definition) => {
|
|
1323
|
+
const symbol = child(definition, "symbol");
|
|
1324
|
+
const sourceLine = child(definition, "line");
|
|
1325
|
+
if (!symbol || !sourceLine) {
|
|
1326
|
+
throw new Error("invalid readseek KDL definition: missing symbol or line");
|
|
1327
|
+
}
|
|
1328
|
+
const symbolProperties = properties(symbol);
|
|
1329
|
+
const parsedLine = line(sourceLine);
|
|
1330
|
+
const definitionColumn = definition.properties.get("column");
|
|
1331
|
+
const nameByte = symbol.properties.get("name_byte");
|
|
1332
|
+
const startByte = symbol.properties.get("start_byte");
|
|
1333
|
+
let column = 1;
|
|
1334
|
+
if (typeof definitionColumn === "number") {
|
|
1335
|
+
column = definitionColumn;
|
|
1336
|
+
} else if (typeof nameByte === "number" && typeof startByte === "number") {
|
|
1337
|
+
column = nameByte - startByte + 1;
|
|
1338
|
+
}
|
|
1339
|
+
return {
|
|
1340
|
+
file: requireProperty(definition, "file"),
|
|
1341
|
+
line: parsedLine.line,
|
|
1342
|
+
column,
|
|
1343
|
+
line_hash: parsedLine.hash,
|
|
1344
|
+
text: parsedLine.text,
|
|
1345
|
+
kind: symbolProperties.kind,
|
|
1346
|
+
name: symbolProperties.name,
|
|
1347
|
+
qualified_name: symbolProperties.qualified_name
|
|
1348
|
+
};
|
|
1349
|
+
})
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
function edit(root) {
|
|
1353
|
+
const result = properties(root);
|
|
1354
|
+
for (const name of ["before_content", "content"]) {
|
|
1355
|
+
const contentNode = child(root, name);
|
|
1356
|
+
if (contentNode)
|
|
1357
|
+
result[name] = requireProperty(contentNode, "content");
|
|
1358
|
+
}
|
|
1359
|
+
return result;
|
|
1360
|
+
}
|
|
1361
|
+
function renameEdit(node) {
|
|
1362
|
+
const sourceLine = child(node, "line");
|
|
1363
|
+
if (!sourceLine)
|
|
1364
|
+
throw new Error("invalid readseek KDL rename edit: missing line");
|
|
1365
|
+
return {
|
|
1366
|
+
...properties(node),
|
|
1367
|
+
text: requireProperty(sourceLine, "content")
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
function renameFile(node) {
|
|
1371
|
+
return {
|
|
1372
|
+
...properties(node),
|
|
1373
|
+
edits: children(node, "edit").map(renameEdit),
|
|
1374
|
+
conflicts: children(node, "conflict").map(properties)
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
function rename(root) {
|
|
1378
|
+
return {
|
|
1379
|
+
...renameFile(root),
|
|
1380
|
+
others: children(root, "other").map(renameFile)
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
function genericNode(node) {
|
|
1384
|
+
const result = properties(node);
|
|
1385
|
+
const textNode = child(node, "text");
|
|
1386
|
+
const bbox = child(node, "bbox");
|
|
1387
|
+
if (textNode)
|
|
1388
|
+
result.text = requireProperty(textNode, "content");
|
|
1389
|
+
if (bbox)
|
|
1390
|
+
result.bbox = properties(bbox);
|
|
1391
|
+
const objects = children(node, "object");
|
|
1392
|
+
if (objects.length > 0)
|
|
1393
|
+
result.objects = objects.map(genericNode);
|
|
1394
|
+
return result;
|
|
1395
|
+
}
|
|
1396
|
+
function pdfDocument(root) {
|
|
1397
|
+
return {
|
|
1398
|
+
...properties(root),
|
|
1399
|
+
nodes: children(root, "node").map(genericNode),
|
|
1400
|
+
assets: children(root, "asset").map(genericNode),
|
|
1401
|
+
vision: children(root, "vision").map(genericNode)
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
function parseReadSeekKdl(text) {
|
|
1405
|
+
const root = parseKdlDocument(text);
|
|
1406
|
+
switch (root.name) {
|
|
1407
|
+
case "document":
|
|
1408
|
+
return root.properties.has("format") ? pdfDocument(root) : sourceDocument(root);
|
|
1409
|
+
case "search":
|
|
1410
|
+
return search(root);
|
|
1411
|
+
case "check":
|
|
1412
|
+
return diagnostics(root);
|
|
1413
|
+
case "refs":
|
|
1414
|
+
return references(root);
|
|
1415
|
+
case "def":
|
|
1416
|
+
return definitions(root);
|
|
1417
|
+
case "edit":
|
|
1418
|
+
return edit(root);
|
|
1419
|
+
case "edit-batch":
|
|
1420
|
+
return { ...properties(root), files: children(root, "file").map(edit) };
|
|
1421
|
+
case "rename":
|
|
1422
|
+
return rename(root);
|
|
1423
|
+
default:
|
|
1424
|
+
throw new Error(`unsupported readseek KDL root: ${root.name}`);
|
|
1016
1425
|
}
|
|
1017
1426
|
}
|
|
1018
1427
|
// src/process.ts
|
|
1019
1428
|
var DEFAULT_READSEEK_TIMEOUT_MS = 120000;
|
|
1020
1429
|
var DEFAULT_MAX_OUTPUT_BYTES = 32 * 1024 * 1024;
|
|
1430
|
+
function readSeekProcessEnvironment() {
|
|
1431
|
+
return process.platform === "linux" ? { ...process.env, APPIMAGE_EXTRACT_AND_RUN: "1" } : process.env;
|
|
1432
|
+
}
|
|
1021
1433
|
function resolveProcessLimits(options = {}) {
|
|
1022
1434
|
return {
|
|
1023
1435
|
timeoutMs: options.timeoutMs ?? DEFAULT_READSEEK_TIMEOUT_MS,
|
|
@@ -1048,8 +1460,8 @@ function ensureSuccessfulStdout(result) {
|
|
|
1048
1460
|
return result.stdout;
|
|
1049
1461
|
throw failureFromProcessResult(result);
|
|
1050
1462
|
}
|
|
1051
|
-
function
|
|
1052
|
-
return
|
|
1463
|
+
function parseSuccessfulKdl(result) {
|
|
1464
|
+
return parseReadSeekKdl(ensureSuccessfulStdout(result));
|
|
1053
1465
|
}
|
|
1054
1466
|
// src/process-node.ts
|
|
1055
1467
|
import { spawn } from "node:child_process";
|
|
@@ -1116,7 +1528,7 @@ async function runReadSeekNode(binaryPath, args, options = {}) {
|
|
|
1116
1528
|
try {
|
|
1117
1529
|
child = spawn(binaryPath, [...args], {
|
|
1118
1530
|
cwd: options.cwd,
|
|
1119
|
-
env:
|
|
1531
|
+
env: readSeekProcessEnvironment(),
|
|
1120
1532
|
shell: false,
|
|
1121
1533
|
stdio: [options.stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
|
|
1122
1534
|
windowsHide: true
|
|
@@ -1159,17 +1571,17 @@ async function runReadSeekNode(binaryPath, args, options = {}) {
|
|
|
1159
1571
|
async function runReadSeekNodeText(binaryPath, args, options = {}) {
|
|
1160
1572
|
return ensureSuccessfulStdout(await runReadSeekNode(binaryPath, args, options));
|
|
1161
1573
|
}
|
|
1162
|
-
async function
|
|
1163
|
-
return
|
|
1574
|
+
async function runReadSeekNodeKdl(binaryPath, args, options = {}) {
|
|
1575
|
+
return parseSuccessfulKdl(await runReadSeekNode(binaryPath, args, options));
|
|
1164
1576
|
}
|
|
1165
1577
|
// src/process-bun.ts
|
|
1166
1578
|
function getBunSpawn() {
|
|
1167
1579
|
const bunGlobal = globalThis;
|
|
1168
|
-
const
|
|
1169
|
-
if (typeof
|
|
1580
|
+
const spawn = bunGlobal.Bun?.spawn;
|
|
1581
|
+
if (typeof spawn !== "function") {
|
|
1170
1582
|
throw new Error("Bun.spawn is unavailable in this runtime");
|
|
1171
1583
|
}
|
|
1172
|
-
return
|
|
1584
|
+
return spawn;
|
|
1173
1585
|
}
|
|
1174
1586
|
async function readBoundedText(stream, streamName, maxOutputBytes, onOverflow) {
|
|
1175
1587
|
const reader = stream.getReader();
|
|
@@ -1206,16 +1618,16 @@ async function runReadSeekBun(binaryPath, args, options = {}) {
|
|
|
1206
1618
|
if (limits.cancelable && options.signal?.aborted) {
|
|
1207
1619
|
throw readSeekCancellationError(options.signal);
|
|
1208
1620
|
}
|
|
1209
|
-
const
|
|
1621
|
+
const spawn = getBunSpawn();
|
|
1210
1622
|
const stdin = options.stdin === undefined ? undefined : new TextEncoder().encode(options.stdin);
|
|
1211
1623
|
const spawnOptions = {
|
|
1212
1624
|
cwd: options.cwd,
|
|
1213
|
-
env:
|
|
1625
|
+
env: readSeekProcessEnvironment(),
|
|
1214
1626
|
stderr: "pipe",
|
|
1215
1627
|
stdin,
|
|
1216
1628
|
stdout: "pipe"
|
|
1217
1629
|
};
|
|
1218
|
-
const child =
|
|
1630
|
+
const child = spawn([binaryPath, ...args], limits.cancelable && options.signal ? { ...spawnOptions, killSignal: "SIGKILL", signal: options.signal } : spawnOptions);
|
|
1219
1631
|
const killForOverflow = () => {
|
|
1220
1632
|
try {
|
|
1221
1633
|
child.kill("SIGKILL");
|
|
@@ -1244,368 +1656,374 @@ async function runReadSeekBun(binaryPath, args, options = {}) {
|
|
|
1244
1656
|
} finally {
|
|
1245
1657
|
if (timeout !== undefined)
|
|
1246
1658
|
clearTimeout(timeout);
|
|
1659
|
+
pending.catch(() => {
|
|
1660
|
+
return;
|
|
1661
|
+
});
|
|
1247
1662
|
}
|
|
1248
1663
|
}
|
|
1249
1664
|
async function runReadSeekBunText(binaryPath, args, options = {}) {
|
|
1250
1665
|
return ensureSuccessfulStdout(await runReadSeekBun(binaryPath, args, options));
|
|
1251
1666
|
}
|
|
1252
|
-
async function
|
|
1253
|
-
return
|
|
1667
|
+
async function runReadSeekBunKdl(binaryPath, args, options = {}) {
|
|
1668
|
+
return parseSuccessfulKdl(await runReadSeekBun(binaryPath, args, options));
|
|
1254
1669
|
}
|
|
1255
|
-
// src/client.ts
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
return
|
|
1670
|
+
// src/client-output.ts
|
|
1671
|
+
import { Type } from "@sinclair/typebox";
|
|
1672
|
+
import { AssertError, Value } from "@sinclair/typebox/value";
|
|
1673
|
+
var OPERATIONS = ["Clone", "Clean", "Default", "Assert"];
|
|
1674
|
+
function parse2(schema, value, what) {
|
|
1675
|
+
try {
|
|
1676
|
+
return Value.Parse(OPERATIONS, schema, value);
|
|
1677
|
+
} catch (error) {
|
|
1678
|
+
if (!(error instanceof AssertError))
|
|
1679
|
+
throw error;
|
|
1680
|
+
const detail = error.error;
|
|
1681
|
+
throw new Error(`invalid readseek ${what}${detail?.path ?? ""}: ${detail?.message ?? "invalid value"}`);
|
|
1262
1682
|
}
|
|
1263
|
-
return { code: "readseek-execution-error", message };
|
|
1264
|
-
}
|
|
1265
|
-
function requireNumber(value, field) {
|
|
1266
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value))
|
|
1267
|
-
throw new Error(`invalid readseek ${field}: expected safe integer`);
|
|
1268
|
-
return value;
|
|
1269
|
-
}
|
|
1270
|
-
function requireString(value, field) {
|
|
1271
|
-
if (typeof value !== "string")
|
|
1272
|
-
throw new Error(`invalid readseek ${field}`);
|
|
1273
|
-
return value;
|
|
1274
|
-
}
|
|
1275
|
-
function requireBoolean(value, field) {
|
|
1276
|
-
if (typeof value !== "boolean")
|
|
1277
|
-
throw new Error(`invalid readseek ${field}: expected boolean`);
|
|
1278
|
-
return value;
|
|
1279
|
-
}
|
|
1280
|
-
function optionalString(value, field) {
|
|
1281
|
-
if (value === undefined || value === null)
|
|
1282
|
-
return;
|
|
1283
|
-
return requireString(value, field);
|
|
1284
|
-
}
|
|
1285
|
-
function parseHashline(value, field) {
|
|
1286
|
-
if (!value || typeof value !== "object")
|
|
1287
|
-
throw new Error(`invalid readseek ${field}`);
|
|
1288
|
-
const item = value;
|
|
1289
|
-
return {
|
|
1290
|
-
line: requireNumber(item.line, `${field}.line`),
|
|
1291
|
-
hash: requireString(item.hash, `${field}.hash`),
|
|
1292
|
-
text: requireString(item.text, `${field}.text`)
|
|
1293
|
-
};
|
|
1294
1683
|
}
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1684
|
+
var Int = Type.Integer({ minimum: Number.MIN_SAFE_INTEGER, maximum: Number.MAX_SAFE_INTEGER });
|
|
1685
|
+
var Str = Type.String();
|
|
1686
|
+
var Bool = Type.Boolean();
|
|
1687
|
+
var OptStr = Type.Optional(Str);
|
|
1688
|
+
var OptInt = Type.Optional(Int);
|
|
1689
|
+
var Hashline = Type.Object({ line: Int, hash: Str, text: Str });
|
|
1690
|
+
var Hashlines = Type.Array(Hashline);
|
|
1691
|
+
var ReadOutput = Type.Object({
|
|
1692
|
+
file: Str,
|
|
1693
|
+
language: Str,
|
|
1694
|
+
line_count: Int,
|
|
1695
|
+
file_hash: Str,
|
|
1696
|
+
start_line: Int,
|
|
1697
|
+
end_line: Int,
|
|
1698
|
+
hashlines: Hashlines
|
|
1699
|
+
});
|
|
1700
|
+
var SymbolOutput = Type.Object({
|
|
1701
|
+
kind: Str,
|
|
1702
|
+
name: Str,
|
|
1703
|
+
qualified_name: OptStr,
|
|
1704
|
+
start_line: Int,
|
|
1705
|
+
end_line: Int,
|
|
1706
|
+
start_hash: OptStr,
|
|
1707
|
+
end_hash: OptStr,
|
|
1708
|
+
start_anchor: OptStr,
|
|
1709
|
+
end_anchor: OptStr
|
|
1710
|
+
});
|
|
1711
|
+
function mapNodeShape(child) {
|
|
1712
|
+
return Type.Object({
|
|
1713
|
+
kind: Str,
|
|
1714
|
+
name: Str,
|
|
1715
|
+
start_line: Int,
|
|
1716
|
+
end_line: Int,
|
|
1717
|
+
start_anchor: Str,
|
|
1718
|
+
end_anchor: Str,
|
|
1719
|
+
children: Type.Array(child)
|
|
1720
|
+
});
|
|
1299
1721
|
}
|
|
1722
|
+
function recursiveMapNode() {
|
|
1723
|
+
return Type.Recursive((self) => mapNodeShape(self));
|
|
1724
|
+
}
|
|
1725
|
+
var MapNode = typeof Type.Recursive === "function" ? recursiveMapNode() : Type.Cyclic({ MapNode: mapNodeShape(Type.Ref("MapNode")) }, "MapNode");
|
|
1726
|
+
var MapOutput = Type.Object({
|
|
1727
|
+
file: Str,
|
|
1728
|
+
language: Str,
|
|
1729
|
+
line_count: Int,
|
|
1730
|
+
file_hash: Str,
|
|
1731
|
+
root: Type.Optional(MapNode),
|
|
1732
|
+
symbols: Type.Array(SymbolOutput)
|
|
1733
|
+
});
|
|
1734
|
+
var SearchSpan = {
|
|
1735
|
+
start_byte: OptInt,
|
|
1736
|
+
end_byte: OptInt,
|
|
1737
|
+
text: OptStr,
|
|
1738
|
+
start_line: Int,
|
|
1739
|
+
end_line: Int,
|
|
1740
|
+
start_hash: Str,
|
|
1741
|
+
end_hash: Str,
|
|
1742
|
+
hashlines: Hashlines
|
|
1743
|
+
};
|
|
1744
|
+
var SearchCapture = Type.Object({ name: Str, ...SearchSpan });
|
|
1745
|
+
var SearchMatch = Type.Object({
|
|
1746
|
+
pattern_index: Type.Integer({ default: 0 }),
|
|
1747
|
+
...SearchSpan,
|
|
1748
|
+
captures: Type.Array(SearchCapture)
|
|
1749
|
+
});
|
|
1750
|
+
var SearchFileOutput = Type.Object({
|
|
1751
|
+
file: Str,
|
|
1752
|
+
language: Str,
|
|
1753
|
+
file_hash: Str,
|
|
1754
|
+
matches: Type.Array(SearchMatch)
|
|
1755
|
+
});
|
|
1756
|
+
var SearchEnvelope = Type.Object({
|
|
1757
|
+
results: Type.Array(SearchFileOutput),
|
|
1758
|
+
returned_matches: OptInt,
|
|
1759
|
+
truncated: Type.Optional(Bool),
|
|
1760
|
+
byte_basis: OptStr
|
|
1761
|
+
});
|
|
1762
|
+
var RefsEnvelope = Type.Object({
|
|
1763
|
+
references: Type.Array(Type.Object({
|
|
1764
|
+
file: Str,
|
|
1765
|
+
line: Int,
|
|
1766
|
+
column: Int,
|
|
1767
|
+
line_hash: Str,
|
|
1768
|
+
text: Str,
|
|
1769
|
+
symbol: Type.Optional(Type.Object({ qualified_name: OptStr }))
|
|
1770
|
+
}))
|
|
1771
|
+
});
|
|
1772
|
+
var Diagnostic = Type.Object({
|
|
1773
|
+
kind: Type.Union([Type.Literal("error"), Type.Literal("missing")]),
|
|
1774
|
+
start_line: Int,
|
|
1775
|
+
end_line: Int
|
|
1776
|
+
});
|
|
1777
|
+
var CheckEnvelope = Type.Object({
|
|
1778
|
+
file_hash: OptStr,
|
|
1779
|
+
error_count: Int,
|
|
1780
|
+
missing_count: Int,
|
|
1781
|
+
diagnostics: Type.Array(Diagnostic)
|
|
1782
|
+
});
|
|
1783
|
+
var DetectedObject = Type.Object({
|
|
1784
|
+
label: Str,
|
|
1785
|
+
bbox: Type.Tuple([Int, Int, Int, Int])
|
|
1786
|
+
});
|
|
1787
|
+
var PreparedImage = Type.Object({
|
|
1788
|
+
mime: Str,
|
|
1789
|
+
encoding: Type.Literal("base64"),
|
|
1790
|
+
data: Str
|
|
1791
|
+
});
|
|
1792
|
+
var SourceDetection = Type.Object({
|
|
1793
|
+
kind: Type.Literal("source"),
|
|
1794
|
+
type: Str,
|
|
1795
|
+
file: Str,
|
|
1796
|
+
language: Str,
|
|
1797
|
+
engine: OptStr,
|
|
1798
|
+
supported: Bool,
|
|
1799
|
+
mime: OptStr,
|
|
1800
|
+
syntax: OptStr
|
|
1801
|
+
});
|
|
1802
|
+
var ImageDetection = Type.Object({
|
|
1803
|
+
kind: Type.Literal("image"),
|
|
1804
|
+
type: Str,
|
|
1805
|
+
file: Str,
|
|
1806
|
+
mime: OptStr,
|
|
1807
|
+
format: Str,
|
|
1808
|
+
width: Int,
|
|
1809
|
+
height: Int,
|
|
1810
|
+
animated: Bool,
|
|
1811
|
+
encoding: Type.Optional(Type.Literal("base64")),
|
|
1812
|
+
data: OptStr,
|
|
1813
|
+
ocr: OptStr,
|
|
1814
|
+
caption: OptStr,
|
|
1815
|
+
objects: Type.Optional(Type.Array(DetectedObject))
|
|
1816
|
+
});
|
|
1817
|
+
var TextDetection = Type.Object({
|
|
1818
|
+
kind: Type.Literal("text"),
|
|
1819
|
+
type: Str,
|
|
1820
|
+
file: Str,
|
|
1821
|
+
mime: OptStr
|
|
1822
|
+
});
|
|
1823
|
+
var PdfDetection = Type.Object({
|
|
1824
|
+
kind: Type.Literal("pdf"),
|
|
1825
|
+
type: Type.Literal("application/pdf"),
|
|
1826
|
+
file: Str,
|
|
1827
|
+
mime: OptStr,
|
|
1828
|
+
format: Type.Literal("pdf"),
|
|
1829
|
+
pages: Int
|
|
1830
|
+
});
|
|
1831
|
+
var Detection = Type.Union([SourceDetection, ImageDetection, TextDetection, PdfDetection]);
|
|
1832
|
+
var SourceDetectionInput = Type.Omit(SourceDetection, ["kind"]);
|
|
1833
|
+
var ImageDetectionInput = Type.Omit(ImageDetection, ["kind"]);
|
|
1834
|
+
var TextDetectionInput = Type.Omit(TextDetection, ["kind"]);
|
|
1835
|
+
var PdfDetectionInput = Type.Omit(PdfDetection, ["kind"]);
|
|
1836
|
+
var UnspannedContent = Type.Omit(ReadOutput, ["start_line", "end_line"]);
|
|
1837
|
+
var PdfInspectMetadata = Type.Object({ source: Str, format: Type.Literal("pdf"), pages: Int });
|
|
1838
|
+
var DocumentCache = Type.Object({
|
|
1839
|
+
content_hash: Str,
|
|
1840
|
+
state: Type.Union([Type.Literal("built"), Type.Literal("reused")])
|
|
1841
|
+
});
|
|
1842
|
+
var Identifier = Type.Object({
|
|
1843
|
+
text: Str,
|
|
1844
|
+
start_column: Int,
|
|
1845
|
+
end_column: Int,
|
|
1846
|
+
start_byte: Int,
|
|
1847
|
+
end_byte: Int
|
|
1848
|
+
});
|
|
1849
|
+
var IdentifyEnvelope = Type.Object({
|
|
1850
|
+
file: Str,
|
|
1851
|
+
language: Str,
|
|
1852
|
+
engine: OptStr,
|
|
1853
|
+
line_count: Int,
|
|
1854
|
+
file_hash: Str,
|
|
1855
|
+
line: Int,
|
|
1856
|
+
column: Int,
|
|
1857
|
+
line_hash: Str,
|
|
1858
|
+
identifier: Type.Optional(Identifier),
|
|
1859
|
+
symbol: Type.Optional(Type.Object({
|
|
1860
|
+
name: Str,
|
|
1861
|
+
kind: Str,
|
|
1862
|
+
qualified_name: Str,
|
|
1863
|
+
start_line: Int,
|
|
1864
|
+
end_line: Int
|
|
1865
|
+
}))
|
|
1866
|
+
});
|
|
1867
|
+
var EditOutputSchema = Type.Object({
|
|
1868
|
+
file: Str,
|
|
1869
|
+
before_hash: Str,
|
|
1870
|
+
file_hash: Str,
|
|
1871
|
+
plan_hash: Str,
|
|
1872
|
+
applied: Bool,
|
|
1873
|
+
changed: Bool,
|
|
1874
|
+
edit_count: Int,
|
|
1875
|
+
before_content: OptStr,
|
|
1876
|
+
content: OptStr
|
|
1877
|
+
});
|
|
1878
|
+
var RenameConflictSchema = Type.Object({ line: Int, column: Int, reason: Str });
|
|
1879
|
+
var RenameEditSchema = Type.Object({
|
|
1880
|
+
line: Int,
|
|
1881
|
+
start_column: Int,
|
|
1882
|
+
end_column: Int,
|
|
1883
|
+
start_byte: Int,
|
|
1884
|
+
end_byte: Int,
|
|
1885
|
+
occurrence: Str,
|
|
1886
|
+
line_hash: Str,
|
|
1887
|
+
text: Str
|
|
1888
|
+
});
|
|
1889
|
+
var Conflicts = Type.Array(RenameConflictSchema, { default: [] });
|
|
1890
|
+
var Edits = Type.Array(RenameEditSchema, { default: [] });
|
|
1891
|
+
var RenameFileOutputSchema = Type.Object({
|
|
1892
|
+
file: Str,
|
|
1893
|
+
language: Str,
|
|
1894
|
+
engine: OptStr,
|
|
1895
|
+
file_hash: Str,
|
|
1896
|
+
conflicts: Conflicts,
|
|
1897
|
+
edits: Edits
|
|
1898
|
+
});
|
|
1899
|
+
var RenameOutputSchema = Type.Object({
|
|
1900
|
+
file: Str,
|
|
1901
|
+
language: Str,
|
|
1902
|
+
engine: OptStr,
|
|
1903
|
+
file_hash: Str,
|
|
1904
|
+
old_name: Str,
|
|
1905
|
+
new_name: Str,
|
|
1906
|
+
plan_hash: Str,
|
|
1907
|
+
applied: Bool,
|
|
1908
|
+
conflicts: Conflicts,
|
|
1909
|
+
edits: Edits,
|
|
1910
|
+
others: Type.Array(RenameFileOutputSchema, { default: [] })
|
|
1911
|
+
});
|
|
1912
|
+
var DefEnvelope = Type.Object({
|
|
1913
|
+
locations: Type.Array(Type.Object({
|
|
1914
|
+
file: Str,
|
|
1915
|
+
line: Int,
|
|
1916
|
+
column: Int,
|
|
1917
|
+
line_hash: Str,
|
|
1918
|
+
text: Str,
|
|
1919
|
+
kind: OptStr,
|
|
1920
|
+
name: OptStr,
|
|
1921
|
+
qualified_name: OptStr
|
|
1922
|
+
}))
|
|
1923
|
+
});
|
|
1300
1924
|
function parseReadOutput(value) {
|
|
1301
|
-
|
|
1302
|
-
throw new Error("invalid readseek read output");
|
|
1303
|
-
const output = value;
|
|
1304
|
-
const hashlines = output.hashlines;
|
|
1305
|
-
if (!Array.isArray(hashlines))
|
|
1306
|
-
throw new Error("invalid readseek hashlines");
|
|
1307
|
-
return {
|
|
1308
|
-
file: requireString(output.file, "file"),
|
|
1309
|
-
language: requireString(output.language, "language"),
|
|
1310
|
-
line_count: requireNumber(output.line_count, "line_count"),
|
|
1311
|
-
file_hash: requireString(output.file_hash, "file_hash"),
|
|
1312
|
-
start_line: requireNumber(output.start_line, "start_line"),
|
|
1313
|
-
end_line: requireNumber(output.end_line, "end_line"),
|
|
1314
|
-
hashlines: hashlines.map((line) => parseHashline(line, "hashline"))
|
|
1315
|
-
};
|
|
1316
|
-
}
|
|
1317
|
-
function parseMapNode(value) {
|
|
1318
|
-
if (!value || typeof value !== "object")
|
|
1319
|
-
throw new Error("invalid readseek map node");
|
|
1320
|
-
const node = value;
|
|
1321
|
-
if (!Array.isArray(node.children))
|
|
1322
|
-
throw new Error("invalid readseek map node children");
|
|
1323
|
-
return {
|
|
1324
|
-
kind: requireString(node.kind, "map node.kind"),
|
|
1325
|
-
name: requireString(node.name, "map node.name"),
|
|
1326
|
-
start_line: requireNumber(node.start_line, "map node.start_line"),
|
|
1327
|
-
end_line: requireNumber(node.end_line, "map node.end_line"),
|
|
1328
|
-
start_anchor: requireString(node.start_anchor, "map node.start_anchor"),
|
|
1329
|
-
end_anchor: requireString(node.end_anchor, "map node.end_anchor"),
|
|
1330
|
-
children: node.children.map(parseMapNode)
|
|
1331
|
-
};
|
|
1925
|
+
return parse2(ReadOutput, value, "read output");
|
|
1332
1926
|
}
|
|
1333
1927
|
function parseMapOutput(value) {
|
|
1334
|
-
|
|
1335
|
-
throw new Error("invalid readseek map output");
|
|
1336
|
-
const output = value;
|
|
1337
|
-
const symbols = output.symbols;
|
|
1338
|
-
if (!Array.isArray(symbols))
|
|
1339
|
-
throw new Error("invalid readseek symbols");
|
|
1340
|
-
return {
|
|
1341
|
-
file: requireString(output.file, "file"),
|
|
1342
|
-
language: requireString(output.language, "language"),
|
|
1343
|
-
line_count: requireNumber(output.line_count, "line_count"),
|
|
1344
|
-
file_hash: requireString(output.file_hash, "file_hash"),
|
|
1345
|
-
root: parseMapNode(output.root),
|
|
1346
|
-
symbols: symbols.map((symbol) => {
|
|
1347
|
-
if (!symbol || typeof symbol !== "object")
|
|
1348
|
-
throw new Error("invalid readseek symbol");
|
|
1349
|
-
const item = symbol;
|
|
1350
|
-
return {
|
|
1351
|
-
kind: requireString(item.kind, "symbol.kind"),
|
|
1352
|
-
name: requireString(item.name, "symbol.name"),
|
|
1353
|
-
qualified_name: requireString(item.qualified_name, "symbol.qualified_name"),
|
|
1354
|
-
start_line: requireNumber(item.start_line, "symbol.start_line"),
|
|
1355
|
-
end_line: requireNumber(item.end_line, "symbol.end_line"),
|
|
1356
|
-
start_hash: requireString(item.start_hash, "symbol.start_hash"),
|
|
1357
|
-
end_hash: requireString(item.end_hash, "symbol.end_hash")
|
|
1358
|
-
};
|
|
1359
|
-
})
|
|
1360
|
-
};
|
|
1928
|
+
return parse2(MapOutput, value, "map output");
|
|
1361
1929
|
}
|
|
1362
1930
|
function parseSearchOutput(value) {
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
if (!Array.isArray(file.matches))
|
|
1373
|
-
throw new Error("invalid readseek search matches");
|
|
1374
|
-
return {
|
|
1375
|
-
file: requireString(file.file, "search.file"),
|
|
1376
|
-
language: requireString(file.language, "search.language"),
|
|
1377
|
-
file_hash: requireString(file.file_hash, "search.file_hash"),
|
|
1378
|
-
matches: file.matches.map((match) => {
|
|
1379
|
-
if (!match || typeof match !== "object")
|
|
1380
|
-
throw new Error("invalid readseek search match");
|
|
1381
|
-
const item = match;
|
|
1382
|
-
if (!Array.isArray(item.captures))
|
|
1383
|
-
throw new Error("invalid readseek search captures");
|
|
1384
|
-
return {
|
|
1385
|
-
pattern_index: item.pattern_index === undefined ? 0 : requireNumber(item.pattern_index, "search.match.pattern_index"),
|
|
1386
|
-
start_line: requireNumber(item.start_line, "search.match.start_line"),
|
|
1387
|
-
end_line: requireNumber(item.end_line, "search.match.end_line"),
|
|
1388
|
-
start_hash: requireString(item.start_hash, "search.match.start_hash"),
|
|
1389
|
-
end_hash: requireString(item.end_hash, "search.match.end_hash"),
|
|
1390
|
-
hashlines: parseSearchHashlines(item.hashlines, "search.match.hashlines"),
|
|
1391
|
-
captures: item.captures.map((capture) => {
|
|
1392
|
-
if (!capture || typeof capture !== "object")
|
|
1393
|
-
throw new Error("invalid readseek search capture");
|
|
1394
|
-
const captureItem = capture;
|
|
1395
|
-
return {
|
|
1396
|
-
name: requireString(captureItem.name, "search.capture.name"),
|
|
1397
|
-
start_line: requireNumber(captureItem.start_line, "search.capture.start_line"),
|
|
1398
|
-
end_line: requireNumber(captureItem.end_line, "search.capture.end_line"),
|
|
1399
|
-
start_hash: requireString(captureItem.start_hash, "search.capture.start_hash"),
|
|
1400
|
-
end_hash: requireString(captureItem.end_hash, "search.capture.end_hash"),
|
|
1401
|
-
hashlines: parseSearchHashlines(captureItem.hashlines, "search.capture.hashlines")
|
|
1402
|
-
};
|
|
1403
|
-
})
|
|
1404
|
-
};
|
|
1405
|
-
})
|
|
1406
|
-
};
|
|
1407
|
-
});
|
|
1931
|
+
const envelope = parse2(SearchEnvelope, value, "search output");
|
|
1932
|
+
const results = envelope.results;
|
|
1933
|
+
if (envelope.returned_matches !== undefined)
|
|
1934
|
+
results.returned_matches = envelope.returned_matches;
|
|
1935
|
+
if (envelope.truncated !== undefined)
|
|
1936
|
+
results.truncated = envelope.truncated;
|
|
1937
|
+
if (envelope.byte_basis !== undefined)
|
|
1938
|
+
results.byte_basis = envelope.byte_basis;
|
|
1939
|
+
return results;
|
|
1408
1940
|
}
|
|
1409
1941
|
function parseRefsOutput(value) {
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
throw new Error("invalid readseek references");
|
|
1415
|
-
return output.references.map((reference) => {
|
|
1416
|
-
if (!reference || typeof reference !== "object")
|
|
1417
|
-
throw new Error("invalid readseek reference");
|
|
1418
|
-
const item = reference;
|
|
1419
|
-
const symbol = item.symbol;
|
|
1420
|
-
const enclosing = symbol && typeof symbol === "object" ? optionalString(symbol.qualified_name, "reference.symbol.qualified_name") : undefined;
|
|
1421
|
-
return {
|
|
1422
|
-
file: requireString(item.file, "reference.file"),
|
|
1423
|
-
line: requireNumber(item.line, "reference.line"),
|
|
1424
|
-
column: requireNumber(item.column, "reference.column"),
|
|
1425
|
-
line_hash: requireString(item.line_hash, "reference.line_hash"),
|
|
1426
|
-
text: requireString(item.text, "reference.text"),
|
|
1427
|
-
enclosingSymbol: enclosing
|
|
1428
|
-
};
|
|
1429
|
-
});
|
|
1430
|
-
}
|
|
1431
|
-
function parseDiagnosticKind(value) {
|
|
1432
|
-
if (value === "error" || value === "missing")
|
|
1433
|
-
return value;
|
|
1434
|
-
throw new Error("invalid readseek diagnostic.kind");
|
|
1942
|
+
return parse2(RefsEnvelope, value, "refs output").references.map(({ symbol, ...reference }) => ({
|
|
1943
|
+
...reference,
|
|
1944
|
+
enclosingSymbol: symbol?.qualified_name
|
|
1945
|
+
}));
|
|
1435
1946
|
}
|
|
1436
1947
|
function parseCheckOutput(value) {
|
|
1437
|
-
|
|
1438
|
-
throw new Error("invalid readseek check output");
|
|
1439
|
-
const output = value;
|
|
1440
|
-
if (!Array.isArray(output.diagnostics))
|
|
1441
|
-
throw new Error("invalid readseek diagnostics");
|
|
1948
|
+
const output = parse2(CheckEnvelope, value, "check output");
|
|
1442
1949
|
return {
|
|
1443
|
-
file_hash:
|
|
1444
|
-
errorCount:
|
|
1445
|
-
missingCount:
|
|
1446
|
-
diagnostics: output.diagnostics
|
|
1447
|
-
if (!diagnostic || typeof diagnostic !== "object")
|
|
1448
|
-
throw new Error("invalid readseek diagnostic");
|
|
1449
|
-
const item = diagnostic;
|
|
1450
|
-
return {
|
|
1451
|
-
kind: parseDiagnosticKind(item.kind),
|
|
1452
|
-
start_line: requireNumber(item.start_line, "diagnostic.start_line"),
|
|
1453
|
-
end_line: requireNumber(item.end_line, "diagnostic.end_line")
|
|
1454
|
-
};
|
|
1455
|
-
})
|
|
1950
|
+
file_hash: output.file_hash,
|
|
1951
|
+
errorCount: output.error_count,
|
|
1952
|
+
missingCount: output.missing_count,
|
|
1953
|
+
diagnostics: output.diagnostics
|
|
1456
1954
|
};
|
|
1457
1955
|
}
|
|
1458
|
-
function parseDetectedObjects(value) {
|
|
1459
|
-
if (value === undefined || value === null)
|
|
1460
|
-
return;
|
|
1461
|
-
if (!Array.isArray(value))
|
|
1462
|
-
throw new Error("invalid readseek detect objects");
|
|
1463
|
-
return value.map((object) => {
|
|
1464
|
-
if (!object || typeof object !== "object")
|
|
1465
|
-
throw new Error("invalid readseek detect object");
|
|
1466
|
-
const item = object;
|
|
1467
|
-
const bbox = item.bbox;
|
|
1468
|
-
if (!Array.isArray(bbox) || bbox.length !== 4)
|
|
1469
|
-
throw new Error("invalid readseek detect object.bbox");
|
|
1470
|
-
return {
|
|
1471
|
-
label: requireString(item.label, "object.label"),
|
|
1472
|
-
bbox: bbox.map((n, i) => requireNumber(n, `object.bbox[${i}]`))
|
|
1473
|
-
};
|
|
1474
|
-
});
|
|
1475
|
-
}
|
|
1476
|
-
function parseImageEncoding(value) {
|
|
1477
|
-
if (value === "base64")
|
|
1478
|
-
return value;
|
|
1479
|
-
throw new Error("invalid image encoding");
|
|
1480
|
-
}
|
|
1481
1956
|
function parseDetectOutput(value) {
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
const type = requireString(output.type, "type");
|
|
1486
|
-
const file = requireString(output.file, "file");
|
|
1487
|
-
const mime = optionalString(output.mime, "mime");
|
|
1488
|
-
if (type === "application/pdf") {
|
|
1489
|
-
if (output.format !== "pdf")
|
|
1490
|
-
throw new Error("invalid readseek PDF format");
|
|
1491
|
-
return {
|
|
1492
|
-
kind: "pdf",
|
|
1493
|
-
type,
|
|
1494
|
-
file,
|
|
1495
|
-
mime,
|
|
1496
|
-
format: output.format,
|
|
1497
|
-
pages: requireNumber(output.pages, "pages")
|
|
1498
|
-
};
|
|
1957
|
+
const output = value ?? {};
|
|
1958
|
+
if (output.type === "application/pdf") {
|
|
1959
|
+
return { kind: "pdf", ...parse2(PdfDetectionInput, value, "detect output") };
|
|
1499
1960
|
}
|
|
1500
1961
|
if (output.width !== undefined || output.height !== undefined) {
|
|
1501
|
-
return {
|
|
1502
|
-
kind: "image",
|
|
1503
|
-
type,
|
|
1504
|
-
file,
|
|
1505
|
-
mime,
|
|
1506
|
-
format: requireString(output.format, "format"),
|
|
1507
|
-
width: requireNumber(output.width, "width"),
|
|
1508
|
-
height: requireNumber(output.height, "height"),
|
|
1509
|
-
animated: requireBoolean(output.animated, "animated"),
|
|
1510
|
-
encoding: output.encoding === undefined ? undefined : parseImageEncoding(output.encoding),
|
|
1511
|
-
data: output.data === undefined ? undefined : requireString(output.data, "data"),
|
|
1512
|
-
ocr: optionalString(output.ocr, "ocr"),
|
|
1513
|
-
caption: optionalString(output.caption, "caption"),
|
|
1514
|
-
objects: parseDetectedObjects(output.objects)
|
|
1515
|
-
};
|
|
1962
|
+
return { kind: "image", ...parse2(ImageDetectionInput, value, "detect output") };
|
|
1516
1963
|
}
|
|
1517
1964
|
if (output.language !== undefined) {
|
|
1518
|
-
return {
|
|
1519
|
-
kind: "source",
|
|
1520
|
-
type,
|
|
1521
|
-
file,
|
|
1522
|
-
language: requireString(output.language, "language"),
|
|
1523
|
-
engine: optionalString(output.engine, "engine"),
|
|
1524
|
-
supported: requireBoolean(output.supported, "supported"),
|
|
1525
|
-
mime,
|
|
1526
|
-
syntax: optionalString(output.syntax, "syntax")
|
|
1527
|
-
};
|
|
1965
|
+
return { kind: "source", ...parse2(SourceDetectionInput, value, "detect output") };
|
|
1528
1966
|
}
|
|
1529
|
-
return { kind: "text",
|
|
1530
|
-
}
|
|
1531
|
-
function parseDocumentCache(value) {
|
|
1532
|
-
if (!value || typeof value !== "object")
|
|
1533
|
-
throw new Error("invalid readseek document cache");
|
|
1534
|
-
const cache = value;
|
|
1535
|
-
const state = requireString(cache.state, "cache.state");
|
|
1536
|
-
if (state !== "built" && state !== "reused")
|
|
1537
|
-
throw new Error("invalid readseek cache.state");
|
|
1538
|
-
return {
|
|
1539
|
-
content_hash: requireString(cache.content_hash, "cache.content_hash"),
|
|
1540
|
-
state
|
|
1541
|
-
};
|
|
1542
|
-
}
|
|
1543
|
-
function parseIdentifyOutput(value) {
|
|
1544
|
-
if (!value || typeof value !== "object")
|
|
1545
|
-
throw new Error("invalid readseek identify output");
|
|
1546
|
-
const output = value;
|
|
1547
|
-
const identifier = output.identifier;
|
|
1548
|
-
const symbol = output.symbol;
|
|
1549
|
-
return {
|
|
1550
|
-
file: requireString(output.file, "file"),
|
|
1551
|
-
language: requireString(output.language, "language"),
|
|
1552
|
-
engine: optionalString(output.engine, "engine"),
|
|
1553
|
-
line_count: requireNumber(output.line_count, "line_count"),
|
|
1554
|
-
file_hash: requireString(output.file_hash, "file_hash"),
|
|
1555
|
-
line: requireNumber(output.line, "line"),
|
|
1556
|
-
column: requireNumber(output.column, "column"),
|
|
1557
|
-
line_hash: requireString(output.line_hash, "line_hash"),
|
|
1558
|
-
identifier: identifier && typeof identifier === "object" ? {
|
|
1559
|
-
text: requireString(identifier.text, "identifier.text"),
|
|
1560
|
-
start_column: requireNumber(identifier.start_column, "identifier.start_column"),
|
|
1561
|
-
end_column: requireNumber(identifier.end_column, "identifier.end_column"),
|
|
1562
|
-
start_byte: requireNumber(identifier.start_byte, "identifier.start_byte"),
|
|
1563
|
-
end_byte: requireNumber(identifier.end_byte, "identifier.end_byte")
|
|
1564
|
-
} : undefined,
|
|
1565
|
-
symbol: symbol && typeof symbol === "object" ? {
|
|
1566
|
-
name: requireString(symbol.name, "symbol.name"),
|
|
1567
|
-
kind: requireString(symbol.kind, "symbol.kind"),
|
|
1568
|
-
qualified_name: requireString(symbol.qualified_name, "symbol.qualified_name"),
|
|
1569
|
-
start_line: requireNumber(symbol.start_line, "symbol.start_line"),
|
|
1570
|
-
end_line: requireNumber(symbol.end_line, "symbol.end_line")
|
|
1571
|
-
} : undefined
|
|
1572
|
-
};
|
|
1967
|
+
return { kind: "text", ...parse2(TextDetectionInput, value, "detect output") };
|
|
1573
1968
|
}
|
|
1574
1969
|
function parseImageContent(value) {
|
|
1575
1970
|
const detection = parseDetectOutput(value);
|
|
1576
1971
|
if (detection.kind !== "image")
|
|
1577
|
-
throw new Error("invalid readseek image content");
|
|
1972
|
+
throw new Error("invalid readseek image content: expected an image");
|
|
1578
1973
|
return detection;
|
|
1579
1974
|
}
|
|
1580
1975
|
function parseTextContent(value) {
|
|
1976
|
+
const output = value ?? {};
|
|
1977
|
+
if (output.hashlines === undefined || output.start_line !== undefined)
|
|
1978
|
+
return parseReadOutput(value);
|
|
1979
|
+
const spanned = parse2(UnspannedContent, value, "content");
|
|
1980
|
+
return {
|
|
1981
|
+
...spanned,
|
|
1982
|
+
start_line: spanned.hashlines[0]?.line ?? 1,
|
|
1983
|
+
end_line: spanned.hashlines[spanned.hashlines.length - 1]?.line ?? 0
|
|
1984
|
+
};
|
|
1985
|
+
}
|
|
1986
|
+
function parseDocumentCache(value) {
|
|
1987
|
+
return parse2(DocumentCache, value, "document cache");
|
|
1988
|
+
}
|
|
1989
|
+
function parseIdentifyOutput(value) {
|
|
1990
|
+
return parse2(IdentifyEnvelope, value, "identify output");
|
|
1991
|
+
}
|
|
1992
|
+
function parsePdfInspectMetadata(value) {
|
|
1581
1993
|
if (!value || typeof value !== "object")
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1994
|
+
return;
|
|
1995
|
+
if (value.format !== "pdf")
|
|
1996
|
+
return;
|
|
1997
|
+
const document = parse2(PdfInspectMetadata, value, "inspect metadata");
|
|
1998
|
+
return { kind: "pdf", type: "application/pdf", file: document.source, format: "pdf", pages: document.pages };
|
|
1999
|
+
}
|
|
2000
|
+
function parseEditOutput(value) {
|
|
2001
|
+
return parse2(EditOutputSchema, value, "edit output");
|
|
2002
|
+
}
|
|
2003
|
+
function parseRenameOutput(value) {
|
|
2004
|
+
return parse2(RenameOutputSchema, value, "rename output");
|
|
2005
|
+
}
|
|
2006
|
+
function parseDefOutput(value) {
|
|
2007
|
+
return parse2(DefEnvelope, value, "def output").locations;
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
// src/client.ts
|
|
2011
|
+
function classifyReadSeekFailure(err) {
|
|
2012
|
+
const failure = err;
|
|
2013
|
+
const message = String(failure?.message ?? err);
|
|
2014
|
+
const missing = failure?.code === "ENOENT" || /Cannot find package|Cannot find module|no such file/i.test(message);
|
|
2015
|
+
if (missing) {
|
|
2016
|
+
return { code: "readseek-not-installed", message, hint: "Run npm install to install @jarkkojs/readseek." };
|
|
1597
2017
|
}
|
|
1598
|
-
return
|
|
2018
|
+
return { code: "readseek-execution-error", message };
|
|
1599
2019
|
}
|
|
1600
|
-
function
|
|
2020
|
+
function parseSourceInspectEnvelope(value) {
|
|
1601
2021
|
if (!value || typeof value !== "object")
|
|
1602
|
-
throw new Error("invalid readseek
|
|
2022
|
+
throw new Error("invalid readseek inspect output");
|
|
1603
2023
|
const output = value;
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
metadata: parseDetectOutput(output.metadata)
|
|
1608
|
-
};
|
|
2024
|
+
const result = {};
|
|
2025
|
+
if (output.metadata !== undefined)
|
|
2026
|
+
result.metadata = parseDetectOutput(output.metadata);
|
|
1609
2027
|
if (output.cache !== undefined)
|
|
1610
2028
|
result.cache = parseDocumentCache(output.cache);
|
|
1611
2029
|
if (output.content !== undefined)
|
|
@@ -1618,224 +2036,104 @@ function parseDigestEnvelope(value) {
|
|
|
1618
2036
|
result.identity = parseIdentifyOutput(output.identity);
|
|
1619
2037
|
return result;
|
|
1620
2038
|
}
|
|
1621
|
-
function parseEditOutput(value) {
|
|
1622
|
-
if (!value || typeof value !== "object")
|
|
1623
|
-
throw new Error("invalid readseek edit output");
|
|
1624
|
-
const output = value;
|
|
1625
|
-
return {
|
|
1626
|
-
file: requireString(output.file, "file"),
|
|
1627
|
-
before_hash: requireString(output.before_hash, "before_hash"),
|
|
1628
|
-
file_hash: requireString(output.file_hash, "file_hash"),
|
|
1629
|
-
plan_hash: requireString(output.plan_hash, "plan_hash"),
|
|
1630
|
-
applied: requireBoolean(output.applied, "applied"),
|
|
1631
|
-
changed: requireBoolean(output.changed, "changed"),
|
|
1632
|
-
edit_count: requireNumber(output.edit_count, "edit_count"),
|
|
1633
|
-
before_content: optionalString(output.before_content, "before_content"),
|
|
1634
|
-
content: optionalString(output.content, "content")
|
|
1635
|
-
};
|
|
1636
|
-
}
|
|
1637
|
-
function parseRenameConflicts(value, field) {
|
|
1638
|
-
if (value === undefined)
|
|
1639
|
-
return [];
|
|
1640
|
-
if (!Array.isArray(value))
|
|
1641
|
-
throw new Error(`invalid readseek ${field}`);
|
|
1642
|
-
return value.map((item) => {
|
|
1643
|
-
if (!item || typeof item !== "object")
|
|
1644
|
-
throw new Error(`invalid readseek ${field} entry`);
|
|
1645
|
-
const c = item;
|
|
1646
|
-
return {
|
|
1647
|
-
line: requireNumber(c.line, `${field}.line`),
|
|
1648
|
-
column: requireNumber(c.column, `${field}.column`),
|
|
1649
|
-
reason: requireString(c.reason, `${field}.reason`)
|
|
1650
|
-
};
|
|
1651
|
-
});
|
|
1652
|
-
}
|
|
1653
|
-
function parseRenameEdits(value, field) {
|
|
1654
|
-
if (value === undefined)
|
|
1655
|
-
return [];
|
|
1656
|
-
if (!Array.isArray(value))
|
|
1657
|
-
throw new Error(`invalid readseek ${field} entry`);
|
|
1658
|
-
return value.map((item) => {
|
|
1659
|
-
if (!item || typeof item !== "object")
|
|
1660
|
-
throw new Error(`invalid readseek ${field} entry`);
|
|
1661
|
-
const e = item;
|
|
1662
|
-
return {
|
|
1663
|
-
line: requireNumber(e.line, `${field}.line`),
|
|
1664
|
-
start_column: requireNumber(e.start_column, `${field}.start_column`),
|
|
1665
|
-
end_column: requireNumber(e.end_column, `${field}.end_column`),
|
|
1666
|
-
start_byte: requireNumber(e.start_byte, `${field}.start_byte`),
|
|
1667
|
-
end_byte: requireNumber(e.end_byte, `${field}.end_byte`),
|
|
1668
|
-
occurrence: requireString(e.occurrence, `${field}.occurrence`),
|
|
1669
|
-
line_hash: requireString(e.line_hash, `${field}.line_hash`),
|
|
1670
|
-
text: requireString(e.text, `${field}.text`)
|
|
1671
|
-
};
|
|
1672
|
-
});
|
|
1673
|
-
}
|
|
1674
|
-
function parseRenameOutput(value) {
|
|
1675
|
-
if (!value || typeof value !== "object")
|
|
1676
|
-
throw new Error("invalid readseek rename output");
|
|
1677
|
-
const output = value;
|
|
1678
|
-
const others = output.others;
|
|
1679
|
-
if (others !== undefined && !Array.isArray(others))
|
|
1680
|
-
throw new Error("invalid readseek others");
|
|
1681
|
-
return {
|
|
1682
|
-
file: requireString(output.file, "file"),
|
|
1683
|
-
language: requireString(output.language, "language"),
|
|
1684
|
-
engine: optionalString(output.engine, "engine"),
|
|
1685
|
-
file_hash: requireString(output.file_hash, "file_hash"),
|
|
1686
|
-
old_name: requireString(output.old_name, "old_name"),
|
|
1687
|
-
new_name: requireString(output.new_name, "new_name"),
|
|
1688
|
-
applied: requireBoolean(output.applied, "applied"),
|
|
1689
|
-
conflicts: parseRenameConflicts(output.conflicts, "conflicts"),
|
|
1690
|
-
edits: parseRenameEdits(output.edits, "edits"),
|
|
1691
|
-
others: others?.map((entry) => {
|
|
1692
|
-
if (!entry || typeof entry !== "object")
|
|
1693
|
-
throw new Error("invalid readseek other");
|
|
1694
|
-
const o = entry;
|
|
1695
|
-
return {
|
|
1696
|
-
file: requireString(o.file, "other.file"),
|
|
1697
|
-
language: requireString(o.language, "other.language"),
|
|
1698
|
-
engine: optionalString(o.engine, "other.engine"),
|
|
1699
|
-
file_hash: requireString(o.file_hash, "other.file_hash"),
|
|
1700
|
-
conflicts: parseRenameConflicts(o.conflicts, "other.conflicts"),
|
|
1701
|
-
edits: parseRenameEdits(o.edits, "other.edits")
|
|
1702
|
-
};
|
|
1703
|
-
}) ?? []
|
|
1704
|
-
};
|
|
1705
|
-
}
|
|
1706
|
-
function parseDefCompact(value) {
|
|
1707
|
-
if (!value || typeof value !== "object")
|
|
1708
|
-
throw new Error("invalid readseek def output");
|
|
1709
|
-
const output = value;
|
|
1710
|
-
const locations = output.locations;
|
|
1711
|
-
if (!Array.isArray(locations))
|
|
1712
|
-
throw new Error("invalid readseek def locations");
|
|
1713
|
-
return locations.map((loc) => {
|
|
1714
|
-
if (!loc || typeof loc !== "object")
|
|
1715
|
-
throw new Error("invalid readseek def location");
|
|
1716
|
-
const item = loc;
|
|
1717
|
-
return {
|
|
1718
|
-
file: requireString(item.file, "location.file"),
|
|
1719
|
-
line: requireNumber(item.line, "location.line"),
|
|
1720
|
-
column: requireNumber(item.column, "location.column"),
|
|
1721
|
-
line_hash: requireString(item.line_hash, "location.line_hash"),
|
|
1722
|
-
text: requireString(item.text, "location.text"),
|
|
1723
|
-
kind: optionalString(item.kind, "location.kind"),
|
|
1724
|
-
name: optionalString(item.name, "location.name"),
|
|
1725
|
-
qualified_name: optionalString(item.qualified_name, "location.qualified_name")
|
|
1726
|
-
};
|
|
1727
|
-
});
|
|
1728
|
-
}
|
|
1729
2039
|
function createReadSeekClient(runner) {
|
|
1730
|
-
function
|
|
1731
|
-
return
|
|
2040
|
+
function inspectArgs(target, options) {
|
|
2041
|
+
return buildInspectArgs({
|
|
1732
2042
|
path: target,
|
|
2043
|
+
selector: options.selector,
|
|
1733
2044
|
select: options.select ?? "content",
|
|
1734
|
-
|
|
2045
|
+
query: options.query,
|
|
1735
2046
|
end: options.end,
|
|
1736
2047
|
limit: options.limit,
|
|
1737
2048
|
depth: options.depth,
|
|
1738
2049
|
language: options.language,
|
|
1739
2050
|
visionMode: options.visionMode,
|
|
1740
2051
|
visionLevel: options.visionLevel,
|
|
1741
|
-
stdinName: options.
|
|
2052
|
+
stdinName: options.stdinName
|
|
1742
2053
|
});
|
|
1743
2054
|
}
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
const runOptions = {
|
|
2055
|
+
function inspectRunOptions(options) {
|
|
2056
|
+
return {
|
|
1747
2057
|
signal: options.signal,
|
|
1748
2058
|
stdin: options.stdin,
|
|
1749
2059
|
timeoutMs: options.timeoutMs,
|
|
1750
2060
|
vision: options.vision
|
|
1751
2061
|
};
|
|
1752
|
-
return runner.json(args, runOptions);
|
|
1753
2062
|
}
|
|
1754
|
-
async function
|
|
1755
|
-
return
|
|
2063
|
+
async function inspect(target, options = {}) {
|
|
2064
|
+
return runner.kdl(inspectArgs(target, options), inspectRunOptions(options));
|
|
2065
|
+
}
|
|
2066
|
+
async function inspectText(target, options = {}) {
|
|
2067
|
+
return runner.text(inspectArgs(target, options), inspectRunOptions(options));
|
|
1756
2068
|
}
|
|
1757
|
-
function
|
|
2069
|
+
async function inspectSource(target, options = {}) {
|
|
2070
|
+
return parseSourceInspectEnvelope(await inspect(target, options));
|
|
2071
|
+
}
|
|
2072
|
+
function requireInspectMetadata(envelope, field) {
|
|
2073
|
+
if (envelope.metadata === undefined)
|
|
2074
|
+
throw new Error(`invalid readseek ${field}: missing metadata`);
|
|
2075
|
+
return envelope.metadata;
|
|
2076
|
+
}
|
|
2077
|
+
function requireInspectContent(envelope, field) {
|
|
1758
2078
|
if (envelope.content === undefined)
|
|
1759
2079
|
throw new Error(`invalid readseek ${field}: missing content`);
|
|
1760
2080
|
return envelope.content;
|
|
1761
2081
|
}
|
|
1762
|
-
async function
|
|
1763
|
-
const
|
|
1764
|
-
select: "content",
|
|
1765
|
-
|
|
2082
|
+
async function inspectContent(filePath, options = {}) {
|
|
2083
|
+
const inspected = await inspect(filePath, {
|
|
2084
|
+
select: ["metadata", "content"],
|
|
2085
|
+
selector: options.startLine !== undefined ? buildLineLocation(options.startLine) : undefined,
|
|
1766
2086
|
end: options.endLine,
|
|
1767
2087
|
visionMode: options.visionMode,
|
|
1768
2088
|
signal: options.signal,
|
|
1769
2089
|
vision: options.vision
|
|
1770
2090
|
});
|
|
1771
|
-
|
|
1772
|
-
|
|
2091
|
+
const pdf = parsePdfInspectMetadata(inspected);
|
|
2092
|
+
if (pdf)
|
|
2093
|
+
return { metadata: pdf };
|
|
2094
|
+
const envelope = parseSourceInspectEnvelope(inspected);
|
|
2095
|
+
const metadata = requireInspectMetadata(envelope, "content");
|
|
2096
|
+
const content = requireInspectContent(envelope, "content");
|
|
2097
|
+
if (metadata.kind === "image") {
|
|
2098
|
+
return { metadata, image: parseImageContent(content) };
|
|
1773
2099
|
}
|
|
1774
|
-
|
|
1775
|
-
if (envelope.metadata.kind === "image") {
|
|
1776
|
-
return { metadata: envelope.metadata, image: parseImageContent(content) };
|
|
1777
|
-
}
|
|
1778
|
-
return { metadata: envelope.metadata, text: parseTextContent(content) };
|
|
2100
|
+
return { metadata, text: parseTextContent(content) };
|
|
1779
2101
|
}
|
|
1780
2102
|
return {
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
});
|
|
1792
|
-
return runner.text(args, {
|
|
2103
|
+
inspect,
|
|
2104
|
+
inspectText,
|
|
2105
|
+
inspectContent,
|
|
2106
|
+
async extract(target, selector, output, options = {}) {
|
|
2107
|
+
await runner.text(buildExtractArgs({
|
|
2108
|
+
path: target,
|
|
2109
|
+
selector,
|
|
2110
|
+
output,
|
|
2111
|
+
stdinName: options.stdinName
|
|
2112
|
+
}), {
|
|
1793
2113
|
signal: options.signal,
|
|
1794
|
-
|
|
2114
|
+
stdin: options.stdin,
|
|
2115
|
+
timeoutMs: options.timeoutMs,
|
|
2116
|
+
cancelable: options.cancelable
|
|
1795
2117
|
});
|
|
1796
2118
|
},
|
|
1797
|
-
digestRaw(target, options = {}) {
|
|
1798
|
-
return runDigestRaw(target, options);
|
|
1799
|
-
},
|
|
1800
|
-
digest,
|
|
1801
|
-
digestContent,
|
|
1802
2119
|
async image(filePath, modes, options = {}) {
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
}));
|
|
1814
|
-
let merged;
|
|
1815
|
-
for (const result of results) {
|
|
1816
|
-
if (result.status !== "fulfilled")
|
|
1817
|
-
continue;
|
|
1818
|
-
const detection = result.value;
|
|
1819
|
-
merged = merged === undefined ? detection : {
|
|
1820
|
-
...merged,
|
|
1821
|
-
ocr: detection.ocr ?? merged.ocr,
|
|
1822
|
-
caption: detection.caption ?? merged.caption,
|
|
1823
|
-
objects: detection.objects ?? merged.objects
|
|
1824
|
-
};
|
|
1825
|
-
}
|
|
1826
|
-
if (merged !== undefined)
|
|
1827
|
-
return merged;
|
|
1828
|
-
const failure = results.find((result) => result.status === "rejected");
|
|
1829
|
-
if (failure?.status === "rejected")
|
|
1830
|
-
throw failure.reason;
|
|
1831
|
-
throw new Error(`readseek returned no image analysis for ${filePath}`);
|
|
2120
|
+
if (modes.length === 0)
|
|
2121
|
+
throw new Error(`readseek returned no image analysis for ${filePath}`);
|
|
2122
|
+
const inspected = await inspectContent(filePath, {
|
|
2123
|
+
visionMode: modes.length > 1 ? "all" : modes[0],
|
|
2124
|
+
signal: options.signal,
|
|
2125
|
+
vision: true
|
|
2126
|
+
});
|
|
2127
|
+
if (!inspected.image)
|
|
2128
|
+
throw new Error(`readseek returned no image analysis for ${filePath}`);
|
|
2129
|
+
return inspected.image;
|
|
1832
2130
|
},
|
|
1833
2131
|
async preparedImage(filePath, options = {}) {
|
|
1834
|
-
const
|
|
2132
|
+
const inspected = await inspectContent(filePath, {
|
|
1835
2133
|
visionMode: "none",
|
|
1836
2134
|
signal: options.signal
|
|
1837
2135
|
});
|
|
1838
|
-
const output =
|
|
2136
|
+
const output = inspected.image;
|
|
1839
2137
|
if (!output || output.encoding !== "base64" || output.data === undefined || output.mime === undefined) {
|
|
1840
2138
|
throw new Error(`readseek returned no prepared image for ${filePath}`);
|
|
1841
2139
|
}
|
|
@@ -1847,11 +2145,9 @@ function createReadSeekClient(runner) {
|
|
|
1847
2145
|
pattern,
|
|
1848
2146
|
language: options.language,
|
|
1849
2147
|
limit: options.limit,
|
|
1850
|
-
|
|
1851
|
-
others: options.others,
|
|
1852
|
-
ignored: options.ignored
|
|
2148
|
+
gitScope: options.gitScope
|
|
1853
2149
|
});
|
|
1854
|
-
return parseSearchOutput(await runner.
|
|
2150
|
+
return parseSearchOutput(await runner.kdl(args, { signal: options.signal }));
|
|
1855
2151
|
},
|
|
1856
2152
|
async refs(target, options = {}) {
|
|
1857
2153
|
const args = buildRefsArgs({
|
|
@@ -1861,26 +2157,21 @@ function createReadSeekClient(runner) {
|
|
|
1861
2157
|
line: options.line,
|
|
1862
2158
|
column: options.column,
|
|
1863
2159
|
language: options.language,
|
|
1864
|
-
|
|
1865
|
-
others: options.others,
|
|
1866
|
-
ignored: options.ignored
|
|
2160
|
+
gitScope: options.gitScope
|
|
1867
2161
|
});
|
|
1868
|
-
return parseRefsOutput(await runner.
|
|
2162
|
+
return parseRefsOutput(await runner.kdl(args, { signal: options.signal }));
|
|
1869
2163
|
},
|
|
1870
2164
|
async def(target, options) {
|
|
1871
2165
|
const args = buildDefArgs({
|
|
1872
2166
|
path: target,
|
|
1873
2167
|
name: options.name,
|
|
1874
|
-
format: "plain",
|
|
1875
2168
|
language: options.language,
|
|
1876
|
-
|
|
1877
|
-
others: options.others,
|
|
1878
|
-
ignored: options.ignored
|
|
2169
|
+
gitScope: options.gitScope
|
|
1879
2170
|
});
|
|
1880
|
-
return
|
|
2171
|
+
return parseDefOutput(await runner.kdl(args, { signal: options.signal }));
|
|
1881
2172
|
},
|
|
1882
2173
|
async check(filePath, content, options = {}) {
|
|
1883
|
-
const envelope = await
|
|
2174
|
+
const envelope = await inspectSource("-", {
|
|
1884
2175
|
select: "diagnostics",
|
|
1885
2176
|
stdin: content,
|
|
1886
2177
|
stdinName: filePath,
|
|
@@ -1890,12 +2181,12 @@ function createReadSeekClient(runner) {
|
|
|
1890
2181
|
throw new Error("invalid readseek diagnostics: missing diagnostics facet");
|
|
1891
2182
|
return envelope.diagnostics;
|
|
1892
2183
|
},
|
|
1893
|
-
async identify(filePath, content, options
|
|
1894
|
-
const envelope = await
|
|
2184
|
+
async identify(filePath, content, options) {
|
|
2185
|
+
const envelope = await inspectSource("-", {
|
|
1895
2186
|
select: "identity",
|
|
1896
2187
|
stdin: content,
|
|
1897
2188
|
stdinName: filePath,
|
|
1898
|
-
|
|
2189
|
+
selector: buildLineLocation(options.line, options.column),
|
|
1899
2190
|
language: options.language,
|
|
1900
2191
|
signal: options.signal
|
|
1901
2192
|
});
|
|
@@ -1904,8 +2195,11 @@ function createReadSeekClient(runner) {
|
|
|
1904
2195
|
return envelope.identity;
|
|
1905
2196
|
},
|
|
1906
2197
|
async detect(filePath, options = {}) {
|
|
1907
|
-
const
|
|
1908
|
-
|
|
2198
|
+
const inspected = await inspect(filePath, { select: "metadata", signal: options.signal });
|
|
2199
|
+
const pdf = parsePdfInspectMetadata(inspected);
|
|
2200
|
+
if (pdf)
|
|
2201
|
+
return pdf;
|
|
2202
|
+
return requireInspectMetadata(parseSourceInspectEnvelope(inspected), "metadata");
|
|
1909
2203
|
},
|
|
1910
2204
|
async edit(filePath, edits, options = {}) {
|
|
1911
2205
|
const args = buildEditArgs({
|
|
@@ -1915,9 +2209,9 @@ function createReadSeekClient(runner) {
|
|
|
1915
2209
|
language: options.language,
|
|
1916
2210
|
requestFromStdin: true
|
|
1917
2211
|
});
|
|
1918
|
-
return parseEditOutput(await runner.
|
|
2212
|
+
return parseEditOutput(await runner.kdl(args, {
|
|
1919
2213
|
signal: options.signal,
|
|
1920
|
-
stdin:
|
|
2214
|
+
stdin: serializeEditPlan(edits),
|
|
1921
2215
|
timeoutMs: options.timeoutMs,
|
|
1922
2216
|
cancelable: options.cancelable
|
|
1923
2217
|
}));
|
|
@@ -1930,89 +2224,88 @@ function createReadSeekClient(runner) {
|
|
|
1930
2224
|
column: options.column,
|
|
1931
2225
|
workspace: options.workspace,
|
|
1932
2226
|
apply: options.apply,
|
|
2227
|
+
planHash: options.planHash,
|
|
1933
2228
|
language: options.language,
|
|
1934
|
-
|
|
1935
|
-
others: options.others,
|
|
1936
|
-
ignored: options.ignored
|
|
2229
|
+
gitScope: options.gitScope
|
|
1937
2230
|
});
|
|
1938
|
-
return parseRenameOutput(await runner.
|
|
2231
|
+
return parseRenameOutput(await runner.kdl(args, { signal: options.signal }));
|
|
1939
2232
|
}
|
|
1940
2233
|
};
|
|
1941
2234
|
}
|
|
1942
2235
|
export {
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
validateGitSelection,
|
|
1946
|
-
validateExactlyOneEditVariant,
|
|
1947
|
-
tryParseLineAnchor,
|
|
1948
|
-
runReadSeekNodeText,
|
|
1949
|
-
runReadSeekNodeJson,
|
|
1950
|
-
runReadSeekNode,
|
|
1951
|
-
runReadSeekBunText,
|
|
1952
|
-
runReadSeekBunJson,
|
|
1953
|
-
runReadSeekBun,
|
|
1954
|
-
rewriteBacktickedToolNames,
|
|
1955
|
-
resolveToolName,
|
|
1956
|
-
resolveToCwd,
|
|
1957
|
-
resolveScopedPath,
|
|
1958
|
-
resolveReadSeekCacheDir,
|
|
1959
|
-
resolveReadSeekBinaryOverride,
|
|
1960
|
-
resolveReadSeekBinaryFromPackages,
|
|
1961
|
-
resolveProcessLimits,
|
|
1962
|
-
renderToolRoutingPolicy,
|
|
1963
|
-
renderToolDescription,
|
|
1964
|
-
renderPreferredToolDescription,
|
|
1965
|
-
renderFallbackToolDescription,
|
|
1966
|
-
renderCompactGuidelines,
|
|
1967
|
-
readSeekPlatformKey,
|
|
1968
|
-
readSeekBinaryName,
|
|
1969
|
-
preferredToolDescriptionMap,
|
|
1970
|
-
parseSuccessfulJson,
|
|
1971
|
-
parseReadSeekJson,
|
|
1972
|
-
parseLineAnchor,
|
|
1973
|
-
isSubPath,
|
|
1974
|
-
getToolContract,
|
|
1975
|
-
fallbackToolDescriptionMap,
|
|
1976
|
-
failureFromProcessResult,
|
|
1977
|
-
expandUserPath,
|
|
1978
|
-
ensureSuccessfulStdout,
|
|
1979
|
-
createReadSeekClient,
|
|
1980
|
-
coercePositiveInt,
|
|
1981
|
-
coerceOptionalString,
|
|
1982
|
-
coerceObviousBase10Int,
|
|
1983
|
-
coerceNonNegativeInt,
|
|
1984
|
-
coerceBoolean,
|
|
1985
|
-
cleanReadSeekErrorText,
|
|
1986
|
-
classifyReadSeekFailure,
|
|
1987
|
-
canonicalPathKey,
|
|
1988
|
-
buildViewArgs,
|
|
1989
|
-
buildSearchArgs,
|
|
1990
|
-
buildRenameArgs,
|
|
1991
|
-
buildRefsArgs,
|
|
1992
|
-
buildLineLocation,
|
|
1993
|
-
buildEditArgs,
|
|
1994
|
-
buildDigestArgs,
|
|
1995
|
-
buildDefArgs,
|
|
1996
|
-
appendGitSelectionArgs,
|
|
1997
|
-
appendApplyAndPlanHash,
|
|
1998
|
-
VISION_MODES,
|
|
1999
|
-
VISION_LEVELS,
|
|
2000
|
-
VISION_ANALYSIS_MODES,
|
|
2001
|
-
TOOL_NAMES,
|
|
2002
|
-
TOOL_DESCRIPTIONS,
|
|
2003
|
-
TOOL_CONTRACTS,
|
|
2004
|
-
TOOL_COMPACT_GUIDELINES,
|
|
2005
|
-
REPLACEABLE_TOOLS,
|
|
2006
|
-
READSEEK_PLATFORM_PACKAGES,
|
|
2007
|
-
READSEEK_BINARY_ENV,
|
|
2008
|
-
PARAM_DESCRIPTIONS,
|
|
2009
|
-
HASH_LEN,
|
|
2010
|
-
GIT_SELECTION_FLAGS,
|
|
2011
|
-
EDIT_VARIANTS,
|
|
2012
|
-
DOCUMENT_NODE_KINDS,
|
|
2013
|
-
DIGEST_FACETS,
|
|
2014
|
-
DEFAULT_READSEEK_TIMEOUT_MS,
|
|
2236
|
+
BUILTIN_FALLBACKS,
|
|
2237
|
+
DEFAULT_INSPECT_MAP_DEPTH,
|
|
2015
2238
|
DEFAULT_MAX_OUTPUT_BYTES,
|
|
2016
|
-
|
|
2017
|
-
|
|
2239
|
+
DEFAULT_READSEEK_TIMEOUT_MS,
|
|
2240
|
+
EDIT_VARIANTS,
|
|
2241
|
+
GIT_SCOPES,
|
|
2242
|
+
HASH_LEN,
|
|
2243
|
+
INSPECT_FACETS,
|
|
2244
|
+
PARAM_DESCRIPTIONS,
|
|
2245
|
+
READSEEK_BINARY_ENV,
|
|
2246
|
+
READSEEK_PLATFORM_PACKAGES,
|
|
2247
|
+
REPLACEABLE_TOOLS,
|
|
2248
|
+
TOOL_COMPACT_GUIDELINES,
|
|
2249
|
+
TOOL_CONTRACTS,
|
|
2250
|
+
TOOL_DESCRIPTIONS,
|
|
2251
|
+
TOOL_NAMES,
|
|
2252
|
+
VISION_ANALYSIS_MODES,
|
|
2253
|
+
VISION_LEVELS,
|
|
2254
|
+
VISION_MODES,
|
|
2255
|
+
appendApplyAndPlanHash,
|
|
2256
|
+
appendGitScopeArgs,
|
|
2257
|
+
buildDefArgs,
|
|
2258
|
+
buildEditArgs,
|
|
2259
|
+
buildExtractArgs,
|
|
2260
|
+
buildInspectArgs,
|
|
2261
|
+
buildLineLocation,
|
|
2262
|
+
buildRefsArgs,
|
|
2263
|
+
buildRenameArgs,
|
|
2264
|
+
buildSearchArgs,
|
|
2265
|
+
canonicalPathKey,
|
|
2266
|
+
classifyReadSeekFailure,
|
|
2267
|
+
cleanReadSeekErrorText,
|
|
2268
|
+
coerceBoolean,
|
|
2269
|
+
coerceNonNegativeInt,
|
|
2270
|
+
coerceObviousBase10Int,
|
|
2271
|
+
coerceOptionalString,
|
|
2272
|
+
coercePositiveInt,
|
|
2273
|
+
createReadSeekClient,
|
|
2274
|
+
ensureSuccessfulStdout,
|
|
2275
|
+
expandUserPath,
|
|
2276
|
+
failureFromProcessResult,
|
|
2277
|
+
fallbackToolDescriptionMap,
|
|
2278
|
+
getToolContract,
|
|
2279
|
+
isSubPath,
|
|
2280
|
+
parseLineAnchor,
|
|
2281
|
+
parseReadSeekKdl,
|
|
2282
|
+
parseSuccessfulKdl,
|
|
2283
|
+
preferredToolDescriptionMap,
|
|
2284
|
+
readSeekBinaryName,
|
|
2285
|
+
readSeekPlatformKey,
|
|
2286
|
+
readSeekProcessEnvironment,
|
|
2287
|
+
renderCompactGuidelines,
|
|
2288
|
+
renderFallbackToolDescription,
|
|
2289
|
+
renderPreferredToolDescription,
|
|
2290
|
+
renderToolDescription,
|
|
2291
|
+
renderToolRoutingPolicy,
|
|
2292
|
+
resolveProcessLimits,
|
|
2293
|
+
resolveReadSeekBinaryFromPackages,
|
|
2294
|
+
resolveReadSeekBinaryOverride,
|
|
2295
|
+
resolveReadSeekCacheDir,
|
|
2296
|
+
resolveScopedPath,
|
|
2297
|
+
resolveToCwd,
|
|
2298
|
+
resolveToolName,
|
|
2299
|
+
rewriteBacktickedToolNames,
|
|
2300
|
+
runReadSeekBun,
|
|
2301
|
+
runReadSeekBunKdl,
|
|
2302
|
+
runReadSeekBunText,
|
|
2303
|
+
runReadSeekNode,
|
|
2304
|
+
runReadSeekNodeKdl,
|
|
2305
|
+
runReadSeekNodeText,
|
|
2306
|
+
serializeEditPlan,
|
|
2307
|
+
tryParseLineAnchor,
|
|
2308
|
+
validateExactlyOneEditVariant,
|
|
2309
|
+
validateRefsNameVsScope,
|
|
2310
|
+
validateVisionLevelVsMode
|
|
2018
2311
|
};
|