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