@jarkkojs/readseek-api 0.9.9 → 0.9.10

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.
@@ -0,0 +1,358 @@
1
+ import type { DigestFacet, VisionAnalysisMode, VisionLevel, VisionMode } from "./contract.ts";
2
+ export interface ReadSeekHashline {
3
+ line: number;
4
+ hash: string;
5
+ text: string;
6
+ }
7
+ export interface ReadSeekReadOutput {
8
+ file: string;
9
+ language: string;
10
+ line_count: number;
11
+ file_hash: string;
12
+ start_line: number;
13
+ end_line: number;
14
+ hashlines: ReadSeekHashline[];
15
+ }
16
+ export interface ReadSeekSymbol {
17
+ kind: string;
18
+ name: string;
19
+ qualified_name: string;
20
+ start_line: number;
21
+ end_line: number;
22
+ start_hash: string;
23
+ end_hash: string;
24
+ }
25
+ export interface ReadSeekMapOutput {
26
+ file: string;
27
+ language: string;
28
+ line_count: number;
29
+ file_hash: string;
30
+ symbols: ReadSeekSymbol[];
31
+ }
32
+ export interface ReadSeekSearchCapture {
33
+ name: string;
34
+ start_line: number;
35
+ end_line: number;
36
+ start_hash: string;
37
+ end_hash: string;
38
+ hashlines: ReadSeekHashline[];
39
+ }
40
+ export interface ReadSeekSearchMatch {
41
+ pattern_index: number;
42
+ start_line: number;
43
+ end_line: number;
44
+ start_hash: string;
45
+ end_hash: string;
46
+ hashlines: ReadSeekHashline[];
47
+ captures: ReadSeekSearchCapture[];
48
+ }
49
+ export interface ReadSeekSearchFileOutput {
50
+ file: string;
51
+ language: string;
52
+ file_hash: string;
53
+ matches: ReadSeekSearchMatch[];
54
+ }
55
+ export interface ReadSeekReference {
56
+ file: string;
57
+ line: number;
58
+ column: number;
59
+ line_hash: string;
60
+ text: string;
61
+ enclosingSymbol?: string;
62
+ }
63
+ export interface ReadSeekDiagnostic {
64
+ kind: "error" | "missing";
65
+ start_line: number;
66
+ end_line: number;
67
+ }
68
+ export interface ReadSeekCheckOutput {
69
+ errorCount: number;
70
+ missingCount: number;
71
+ diagnostics: ReadSeekDiagnostic[];
72
+ }
73
+ export type ReadSeekOcrText = string;
74
+ export interface ReadSeekDetectedObject {
75
+ label: string;
76
+ bbox: [number, number, number, number];
77
+ }
78
+ export type ReadSeekImageMode = VisionAnalysisMode;
79
+ export interface ReadSeekPreparedImage {
80
+ mime: string;
81
+ encoding: "base64";
82
+ data: string;
83
+ }
84
+ export interface ReadSeekDocumentCache {
85
+ content_hash: string;
86
+ state: "built" | "reused";
87
+ }
88
+ export type ReadSeekDetection = {
89
+ kind: "source";
90
+ type: string;
91
+ file: string;
92
+ language: string;
93
+ engine?: string;
94
+ supported: boolean;
95
+ mime?: string;
96
+ syntax?: string;
97
+ } | {
98
+ kind: "image";
99
+ type: string;
100
+ file: string;
101
+ mime?: string;
102
+ format: string;
103
+ width: number;
104
+ height: number;
105
+ animated: boolean;
106
+ encoding?: "base64";
107
+ data?: string;
108
+ ocr?: ReadSeekOcrText;
109
+ caption?: string;
110
+ objects?: ReadSeekDetectedObject[];
111
+ } | {
112
+ kind: "text";
113
+ type: string;
114
+ file: string;
115
+ mime?: string;
116
+ } | {
117
+ kind: "pdf";
118
+ type: "application/pdf";
119
+ file: string;
120
+ mime?: string;
121
+ format: "pdf";
122
+ pages: number;
123
+ };
124
+ export type ReadSeekImageDetection = Extract<ReadSeekDetection, {
125
+ kind: "image";
126
+ }>;
127
+ export interface IdentifierOutput {
128
+ text: string;
129
+ start_column: number;
130
+ end_column: number;
131
+ start_byte: number;
132
+ end_byte: number;
133
+ }
134
+ export interface IdentifyOutput {
135
+ file: string;
136
+ language: string;
137
+ engine?: string;
138
+ line_count: number;
139
+ file_hash: string;
140
+ line: number;
141
+ column: number;
142
+ line_hash: string;
143
+ identifier?: IdentifierOutput;
144
+ symbol?: {
145
+ name: string;
146
+ kind: string;
147
+ qualified_name: string;
148
+ start_line: number;
149
+ end_line: number;
150
+ };
151
+ }
152
+ export interface EditOutput {
153
+ file: string;
154
+ before_hash: string;
155
+ file_hash: string;
156
+ plan_hash: string;
157
+ applied: boolean;
158
+ changed: boolean;
159
+ edit_count: number;
160
+ before_content?: string;
161
+ content?: string;
162
+ }
163
+ export interface RenameConflict {
164
+ line: number;
165
+ column: number;
166
+ reason: string;
167
+ }
168
+ export interface RenameEdit {
169
+ line: number;
170
+ start_column: number;
171
+ end_column: number;
172
+ start_byte: number;
173
+ end_byte: number;
174
+ occurrence: string;
175
+ line_hash: string;
176
+ text: string;
177
+ }
178
+ export interface RenameFileOutput {
179
+ file: string;
180
+ language: string;
181
+ engine?: string;
182
+ file_hash: string;
183
+ conflicts: RenameConflict[];
184
+ edits: RenameEdit[];
185
+ }
186
+ export interface RenameOutput {
187
+ file: string;
188
+ language: string;
189
+ engine?: string;
190
+ file_hash: string;
191
+ old_name: string;
192
+ new_name: string;
193
+ applied: boolean;
194
+ conflicts: RenameConflict[];
195
+ edits: RenameEdit[];
196
+ others: RenameFileOutput[];
197
+ }
198
+ export interface DefLocation {
199
+ file: string;
200
+ line: number;
201
+ column: number;
202
+ line_hash: string;
203
+ text: string;
204
+ kind?: string;
205
+ name?: string;
206
+ qualified_name?: string;
207
+ }
208
+ export interface ReadSeekDigestOptions {
209
+ select?: DigestFacet | DigestFacet[];
210
+ at?: string;
211
+ end?: number;
212
+ limit?: number;
213
+ language?: string;
214
+ visionMode?: VisionMode;
215
+ visionLevel?: VisionLevel;
216
+ stdin?: string;
217
+ stdinName?: string;
218
+ signal?: AbortSignal;
219
+ timeoutMs?: number;
220
+ /** Route through the runner's vision path (serialized, long timeout). */
221
+ vision?: boolean;
222
+ }
223
+ export interface ReadSeekDigestOutput {
224
+ metadata: ReadSeekDetection;
225
+ cache?: ReadSeekDocumentCache;
226
+ content?: unknown;
227
+ map?: ReadSeekMapOutput;
228
+ diagnostics?: ReadSeekCheckOutput;
229
+ identity?: IdentifyOutput;
230
+ }
231
+ export interface ReadSeekFailure {
232
+ code: "readseek-not-installed" | "readseek-execution-error";
233
+ message: string;
234
+ hint?: string;
235
+ }
236
+ /**
237
+ * Classify an error thrown while invoking readseek into the shared failure
238
+ * taxonomy: a missing binary or package (`readseek-not-installed`, with an
239
+ * install hint) versus any other execution error.
240
+ */
241
+ export declare function classifyReadSeekFailure(err: unknown): ReadSeekFailure;
242
+ export interface ReadSeekRunOptions {
243
+ signal?: AbortSignal;
244
+ stdin?: string;
245
+ timeoutMs?: number;
246
+ cancelable?: boolean;
247
+ /** Set by callers that read a vision payload; the runner may serialize and lengthen timeouts. */
248
+ vision?: boolean;
249
+ }
250
+ /**
251
+ * Host-supplied spawn seam: resolve the binary and run it, returning stdout as
252
+ * text or parsed JSON. The plugin owns binary resolution, cache-dir decoration,
253
+ * cwd, timeout settings, and any vision serialization queue; the client owns
254
+ * argv construction and output parsing.
255
+ */
256
+ export interface ReadSeekRunner {
257
+ text(args: readonly string[], options?: ReadSeekRunOptions): Promise<string>;
258
+ json(args: readonly string[], options?: ReadSeekRunOptions): Promise<unknown>;
259
+ }
260
+ interface ReadSeekSearchOptions {
261
+ language?: string;
262
+ cached?: boolean;
263
+ others?: boolean;
264
+ ignored?: boolean;
265
+ signal?: AbortSignal;
266
+ }
267
+ interface ReadSeekRefsOptions {
268
+ name?: string;
269
+ scope?: boolean;
270
+ line?: number;
271
+ column?: number;
272
+ language?: string;
273
+ cached?: boolean;
274
+ others?: boolean;
275
+ ignored?: boolean;
276
+ signal?: AbortSignal;
277
+ }
278
+ interface DefOptions {
279
+ name: string;
280
+ language?: string;
281
+ cached?: boolean;
282
+ others?: boolean;
283
+ ignored?: boolean;
284
+ signal?: AbortSignal;
285
+ }
286
+ interface EditOptions {
287
+ apply?: boolean;
288
+ planHash?: string;
289
+ language?: string;
290
+ signal?: AbortSignal;
291
+ timeoutMs?: number;
292
+ cancelable?: boolean;
293
+ }
294
+ interface RenameOptions {
295
+ to: string;
296
+ line: number;
297
+ column?: number;
298
+ workspace?: string;
299
+ apply?: boolean;
300
+ language?: string;
301
+ cached?: boolean;
302
+ others?: boolean;
303
+ ignored?: boolean;
304
+ signal?: AbortSignal;
305
+ }
306
+ interface IdentifyOptions {
307
+ line?: number;
308
+ column?: number;
309
+ language?: string;
310
+ signal?: AbortSignal;
311
+ }
312
+ export interface ReadSeekViewOptions {
313
+ node?: string;
314
+ page?: number;
315
+ kind?: string;
316
+ depth?: number;
317
+ outline?: boolean;
318
+ visionMode?: ReadSeekImageMode;
319
+ visionLevel?: VisionLevel;
320
+ signal?: AbortSignal;
321
+ }
322
+ export interface ReadSeekClient {
323
+ view(filePath: string, options?: ReadSeekViewOptions): Promise<string>;
324
+ digestRaw(target: string, options?: ReadSeekDigestOptions): Promise<unknown>;
325
+ digest(target: string, options?: ReadSeekDigestOptions): Promise<ReadSeekDigestOutput>;
326
+ digestContent(filePath: string, options?: {
327
+ startLine?: number;
328
+ endLine?: number;
329
+ visionMode?: "none" | ReadSeekImageMode;
330
+ signal?: AbortSignal;
331
+ vision?: boolean;
332
+ }): Promise<{
333
+ metadata: ReadSeekDetection;
334
+ cache?: ReadSeekDocumentCache;
335
+ text?: ReadSeekReadOutput;
336
+ image?: ReadSeekImageDetection;
337
+ }>;
338
+ image(filePath: string, modes: ReadSeekImageMode[], options?: {
339
+ signal?: AbortSignal;
340
+ }): Promise<ReadSeekDetection>;
341
+ preparedImage(filePath: string, options?: {
342
+ signal?: AbortSignal;
343
+ }): Promise<ReadSeekPreparedImage>;
344
+ search(target: string, pattern: string, options?: ReadSeekSearchOptions): Promise<ReadSeekSearchFileOutput[]>;
345
+ refs(target: string, options?: ReadSeekRefsOptions): Promise<ReadSeekReference[]>;
346
+ def(target: string, options: DefOptions): Promise<DefLocation[]>;
347
+ check(filePath: string, content: string, options?: {
348
+ signal?: AbortSignal;
349
+ }): Promise<ReadSeekCheckOutput>;
350
+ identify(filePath: string, content: string, options?: IdentifyOptions): Promise<IdentifyOutput>;
351
+ detect(filePath: string, options?: {
352
+ signal?: AbortSignal;
353
+ }): Promise<ReadSeekDetection>;
354
+ edit(filePath: string, edits: unknown[], options?: EditOptions): Promise<EditOutput>;
355
+ rename(filePath: string, options: RenameOptions): Promise<RenameOutput>;
356
+ }
357
+ export declare function createReadSeekClient(runner: ReadSeekRunner): ReadSeekClient;
358
+ export {};
package/dist/index.d.ts CHANGED
@@ -2,8 +2,9 @@ export { DIGEST_FACETS, DOCUMENT_NODE_KINDS, EDIT_VARIANTS, GIT_SELECTION_FLAGS,
2
2
  export { BUILTIN_FALLBACKS, REPLACEABLE_TOOLS, TOOL_COMPACT_GUIDELINES, fallbackToolDescriptionMap, preferredToolDescriptionMap, renderCompactGuidelines, renderFallbackToolDescription, renderPreferredToolDescription, renderToolRoutingPolicy, resolveToolName, rewriteBacktickedToolNames, type ReplaceableTool, type ToolAliasMap, type ToolRoutingPolicyOptions, } from "./policy.ts";
3
3
  export { validateExactlyOneEditVariant, validateGitSelection, validateRefsNameVsScope, validateVisionLevelVsMode, type EditObject, type GitSelectionInput, type RefsScopeInput, type ValidationResult, type VisionInput, } from "./validation.ts";
4
4
  export { appendApplyAndPlanHash, appendGitSelectionArgs, buildDefArgs, buildDigestArgs, buildEditArgs, buildLineLocation, buildRefsArgs, buildRenameArgs, buildSearchArgs, buildViewArgs, type ApplyPlanHashInput, type ApplyPlanHashOrder, type DefArgsInput, type DigestArgsInput, type EditArgsInput, type RefsArgsInput, type RenameArgsInput, type SearchArgsInput, type ViewArgsInput, } from "./argv.ts";
5
- export { READSEEK_PLATFORM_PACKAGES, readSeekBinaryName, readSeekPlatformKey, resolveReadSeekBinaryFromPackages, type ModuleResolver, } from "./platform.ts";
5
+ export { READSEEK_PLATFORM_PACKAGES, readSeekBinaryName, readSeekPlatformKey, resolveReadSeekBinaryFromPackages, resolveReadSeekBinaryFromPath, type ModuleResolver, } from "./platform.ts";
6
6
  export { cleanReadSeekErrorText, parseReadSeekJson, } from "./json.ts";
7
7
  export { DEFAULT_MAX_OUTPUT_BYTES, DEFAULT_READSEEK_TIMEOUT_MS, ensureSuccessfulStdout, failureFromProcessResult, parseSuccessfulJson, resolveProcessLimits, type ProcessRunOptions, type ProcessRunResult, } from "./process.ts";
8
8
  export { runReadSeekNode, runReadSeekNodeJson, runReadSeekNodeText, } from "./process-node.ts";
9
9
  export { runReadSeekBun, runReadSeekBunJson, runReadSeekBunText, } from "./process-bun.ts";
10
+ export { classifyReadSeekFailure, createReadSeekClient, type DefLocation, type EditOutput, type IdentifierOutput, type IdentifyOutput, type ReadSeekCheckOutput, type ReadSeekClient, type ReadSeekDetection, type ReadSeekDetectedObject, type ReadSeekDiagnostic, type ReadSeekDigestOptions, type ReadSeekDigestOutput, type ReadSeekDocumentCache, type ReadSeekFailure, type ReadSeekHashline, type ReadSeekImageDetection, type ReadSeekImageMode, type ReadSeekMapOutput, type ReadSeekOcrText, type ReadSeekPreparedImage, type ReadSeekReadOutput, type ReadSeekReference, type ReadSeekRunOptions, type ReadSeekRunner, type RenameConflict, type RenameEdit, type RenameFileOutput, type RenameOutput, type ReadSeekSearchCapture, type ReadSeekSearchFileOutput, type ReadSeekSearchMatch, type ReadSeekSymbol, type ReadSeekViewOptions, } from "./client.ts";
package/dist/index.js CHANGED
@@ -410,11 +410,6 @@ function getToolContract(name) {
410
410
  }
411
411
  // src/policy.ts
412
412
  var REPLACEABLE_TOOLS = [
413
- {
414
- tool: "digest",
415
- builtIn: "read",
416
- benefit: "it returns LINE:HASH anchors for safe edits."
417
- },
418
413
  {
419
414
  tool: "edit",
420
415
  builtIn: "edit",
@@ -452,7 +447,6 @@ var TOOL_COMPACT_GUIDELINES = {
452
447
  ]
453
448
  };
454
449
  var BUILTIN_FALLBACKS = {
455
- read: "digest",
456
450
  edit: "edit",
457
451
  write: "write",
458
452
  grep: "grep",
@@ -470,11 +464,10 @@ var PREFERENCE_LEADS = {
470
464
  view: "Preferred for digesting document structure or selected content."
471
465
  };
472
466
  var FALLBACK_TEMPLATES = {
473
- read: "Fallback only. Prefer `digest` with fresh LINE:HASH anchors.",
474
- edit: "Fallback only. Prefer `edit` with fresh LINE:HASH anchors.",
475
- write: "Fallback only. Prefer `write` so the result returns LINE:HASH anchors.",
476
- grep: "Fallback only. Prefer `grep` for text/regex search with edit-ready anchors.",
477
- apply_patch: "Fallback only. Prefer `edit` for existing text files."
467
+ edit: "Prefer `edit` with fresh LINE:HASH anchors.",
468
+ write: "Prefer `write` so the result returns LINE:HASH anchors.",
469
+ grep: "Prefer `grep` for text/regex search with edit-ready anchors.",
470
+ apply_patch: "Prefer `edit` for existing text files."
478
471
  };
479
472
  function resolveToolName(name, aliases = {}) {
480
473
  return aliases[name] ?? name;
@@ -732,6 +725,7 @@ function buildRenameArgs(input) {
732
725
  return appendGitSelectionArgs(args, input);
733
726
  }
734
727
  // src/platform.ts
728
+ import { accessSync, constants as fsConstants } from "node:fs";
735
729
  import { createRequire } from "node:module";
736
730
  import path from "node:path";
737
731
  var READSEEK_PLATFORM_PACKAGES = {
@@ -765,6 +759,19 @@ function resolveReadSeekBinaryFromPackages(resolver = resolveFromPackage, option
765
759
  });
766
760
  return path.join(path.dirname(packageJsonPath), "bin", readSeekBinaryName(platform));
767
761
  }
762
+ function resolveReadSeekBinaryFromPath(pathEnv = process.env.PATH) {
763
+ const name = readSeekBinaryName();
764
+ for (const dir of (pathEnv ?? "").split(path.delimiter)) {
765
+ if (!dir)
766
+ continue;
767
+ const candidate = path.join(dir, name);
768
+ try {
769
+ accessSync(candidate, fsConstants.X_OK);
770
+ return candidate;
771
+ } catch {}
772
+ }
773
+ return null;
774
+ }
768
775
  // src/json.ts
769
776
  var READSEEK_USAGE_HINT = /\n\s*Run readseek(?: [\w-]+)* --help for more information\.?\s*$/;
770
777
  function cleanReadSeekErrorText(stderr) {
@@ -1015,6 +1022,672 @@ async function runReadSeekBunText(binaryPath, args, options = {}) {
1015
1022
  async function runReadSeekBunJson(binaryPath, args, options = {}) {
1016
1023
  return parseSuccessfulJson(await runReadSeekBun(binaryPath, args, options));
1017
1024
  }
1025
+ // src/client.ts
1026
+ function classifyReadSeekFailure(err) {
1027
+ const failure = err;
1028
+ const message = String(failure?.message ?? err);
1029
+ const missing = failure?.code === "ENOENT" || /Cannot find package|Cannot find module|no such file/i.test(message);
1030
+ if (missing) {
1031
+ return { code: "readseek-not-installed", message, hint: "Run npm install to install @jarkkojs/readseek." };
1032
+ }
1033
+ return { code: "readseek-execution-error", message };
1034
+ }
1035
+ function requireNumber(value, field) {
1036
+ if (typeof value !== "number" || !Number.isSafeInteger(value))
1037
+ throw new Error(`invalid readseek ${field}: expected safe integer`);
1038
+ return value;
1039
+ }
1040
+ function requireString(value, field) {
1041
+ if (typeof value !== "string")
1042
+ throw new Error(`invalid readseek ${field}`);
1043
+ return value;
1044
+ }
1045
+ function requireBoolean(value, field) {
1046
+ if (typeof value !== "boolean")
1047
+ throw new Error(`invalid readseek ${field}: expected boolean`);
1048
+ return value;
1049
+ }
1050
+ function optionalString(value, field) {
1051
+ if (value === undefined || value === null)
1052
+ return;
1053
+ return requireString(value, field);
1054
+ }
1055
+ function parseHashline(value, field) {
1056
+ if (!value || typeof value !== "object")
1057
+ throw new Error(`invalid readseek ${field}`);
1058
+ const item = value;
1059
+ return {
1060
+ line: requireNumber(item.line, `${field}.line`),
1061
+ hash: requireString(item.hash, `${field}.hash`),
1062
+ text: requireString(item.text, `${field}.text`)
1063
+ };
1064
+ }
1065
+ function parseSearchHashlines(value, field) {
1066
+ if (!Array.isArray(value))
1067
+ throw new Error(`invalid readseek ${field}`);
1068
+ return value.map((line) => parseHashline(line, field));
1069
+ }
1070
+ function parseReadOutput(value) {
1071
+ if (!value || typeof value !== "object")
1072
+ throw new Error("invalid readseek read output");
1073
+ const output = value;
1074
+ const hashlines = output.hashlines;
1075
+ if (!Array.isArray(hashlines))
1076
+ throw new Error("invalid readseek hashlines");
1077
+ return {
1078
+ file: requireString(output.file, "file"),
1079
+ language: requireString(output.language, "language"),
1080
+ line_count: requireNumber(output.line_count, "line_count"),
1081
+ file_hash: requireString(output.file_hash, "file_hash"),
1082
+ start_line: requireNumber(output.start_line, "start_line"),
1083
+ end_line: requireNumber(output.end_line, "end_line"),
1084
+ hashlines: hashlines.map((line) => parseHashline(line, "hashline"))
1085
+ };
1086
+ }
1087
+ function parseMapOutput(value) {
1088
+ if (!value || typeof value !== "object")
1089
+ throw new Error("invalid readseek map output");
1090
+ const output = value;
1091
+ const symbols = output.symbols;
1092
+ if (!Array.isArray(symbols))
1093
+ throw new Error("invalid readseek symbols");
1094
+ return {
1095
+ file: requireString(output.file, "file"),
1096
+ language: requireString(output.language, "language"),
1097
+ line_count: requireNumber(output.line_count, "line_count"),
1098
+ file_hash: requireString(output.file_hash, "file_hash"),
1099
+ symbols: symbols.map((symbol) => {
1100
+ if (!symbol || typeof symbol !== "object")
1101
+ throw new Error("invalid readseek symbol");
1102
+ const item = symbol;
1103
+ return {
1104
+ kind: requireString(item.kind, "symbol.kind"),
1105
+ name: requireString(item.name, "symbol.name"),
1106
+ qualified_name: requireString(item.qualified_name, "symbol.qualified_name"),
1107
+ start_line: requireNumber(item.start_line, "symbol.start_line"),
1108
+ end_line: requireNumber(item.end_line, "symbol.end_line"),
1109
+ start_hash: requireString(item.start_hash, "symbol.start_hash"),
1110
+ end_hash: requireString(item.end_hash, "symbol.end_hash")
1111
+ };
1112
+ })
1113
+ };
1114
+ }
1115
+ function parseSearchOutput(value) {
1116
+ if (!value || typeof value !== "object")
1117
+ throw new Error("invalid readseek search output");
1118
+ const output = value;
1119
+ if (!Array.isArray(output.results))
1120
+ throw new Error("invalid readseek search results");
1121
+ return output.results.map((result) => {
1122
+ if (!result || typeof result !== "object")
1123
+ throw new Error("invalid readseek search result");
1124
+ const file = result;
1125
+ if (!Array.isArray(file.matches))
1126
+ throw new Error("invalid readseek search matches");
1127
+ return {
1128
+ file: requireString(file.file, "search.file"),
1129
+ language: requireString(file.language, "search.language"),
1130
+ file_hash: requireString(file.file_hash, "search.file_hash"),
1131
+ matches: file.matches.map((match) => {
1132
+ if (!match || typeof match !== "object")
1133
+ throw new Error("invalid readseek search match");
1134
+ const item = match;
1135
+ if (!Array.isArray(item.captures))
1136
+ throw new Error("invalid readseek search captures");
1137
+ return {
1138
+ pattern_index: item.pattern_index === undefined ? 0 : requireNumber(item.pattern_index, "search.match.pattern_index"),
1139
+ start_line: requireNumber(item.start_line, "search.match.start_line"),
1140
+ end_line: requireNumber(item.end_line, "search.match.end_line"),
1141
+ start_hash: requireString(item.start_hash, "search.match.start_hash"),
1142
+ end_hash: requireString(item.end_hash, "search.match.end_hash"),
1143
+ hashlines: parseSearchHashlines(item.hashlines, "search.match.hashlines"),
1144
+ captures: item.captures.map((capture) => {
1145
+ if (!capture || typeof capture !== "object")
1146
+ throw new Error("invalid readseek search capture");
1147
+ const captureItem = capture;
1148
+ return {
1149
+ name: requireString(captureItem.name, "search.capture.name"),
1150
+ start_line: requireNumber(captureItem.start_line, "search.capture.start_line"),
1151
+ end_line: requireNumber(captureItem.end_line, "search.capture.end_line"),
1152
+ start_hash: requireString(captureItem.start_hash, "search.capture.start_hash"),
1153
+ end_hash: requireString(captureItem.end_hash, "search.capture.end_hash"),
1154
+ hashlines: parseSearchHashlines(captureItem.hashlines, "search.capture.hashlines")
1155
+ };
1156
+ })
1157
+ };
1158
+ })
1159
+ };
1160
+ });
1161
+ }
1162
+ function parseRefsOutput(value) {
1163
+ if (!value || typeof value !== "object")
1164
+ throw new Error("invalid readseek refs output");
1165
+ const output = value;
1166
+ if (!Array.isArray(output.references))
1167
+ throw new Error("invalid readseek references");
1168
+ return output.references.map((reference) => {
1169
+ if (!reference || typeof reference !== "object")
1170
+ throw new Error("invalid readseek reference");
1171
+ const item = reference;
1172
+ const symbol = item.symbol;
1173
+ const enclosing = symbol && typeof symbol === "object" ? optionalString(symbol.qualified_name, "reference.symbol.qualified_name") : undefined;
1174
+ return {
1175
+ file: requireString(item.file, "reference.file"),
1176
+ line: requireNumber(item.line, "reference.line"),
1177
+ column: requireNumber(item.column, "reference.column"),
1178
+ line_hash: requireString(item.line_hash, "reference.line_hash"),
1179
+ text: requireString(item.text, "reference.text"),
1180
+ enclosingSymbol: enclosing
1181
+ };
1182
+ });
1183
+ }
1184
+ function parseDiagnosticKind(value) {
1185
+ if (value === "error" || value === "missing")
1186
+ return value;
1187
+ throw new Error("invalid readseek diagnostic.kind");
1188
+ }
1189
+ function parseCheckOutput(value) {
1190
+ if (!value || typeof value !== "object")
1191
+ throw new Error("invalid readseek check output");
1192
+ const output = value;
1193
+ if (!Array.isArray(output.diagnostics))
1194
+ throw new Error("invalid readseek diagnostics");
1195
+ return {
1196
+ errorCount: requireNumber(output.error_count, "error_count"),
1197
+ missingCount: requireNumber(output.missing_count, "missing_count"),
1198
+ diagnostics: output.diagnostics.map((diagnostic) => {
1199
+ if (!diagnostic || typeof diagnostic !== "object")
1200
+ throw new Error("invalid readseek diagnostic");
1201
+ const item = diagnostic;
1202
+ return {
1203
+ kind: parseDiagnosticKind(item.kind),
1204
+ start_line: requireNumber(item.start_line, "diagnostic.start_line"),
1205
+ end_line: requireNumber(item.end_line, "diagnostic.end_line")
1206
+ };
1207
+ })
1208
+ };
1209
+ }
1210
+ function parseDetectedObjects(value) {
1211
+ if (value === undefined || value === null)
1212
+ return;
1213
+ if (!Array.isArray(value))
1214
+ throw new Error("invalid readseek detect objects");
1215
+ return value.map((object) => {
1216
+ if (!object || typeof object !== "object")
1217
+ throw new Error("invalid readseek detect object");
1218
+ const item = object;
1219
+ const bbox = item.bbox;
1220
+ if (!Array.isArray(bbox) || bbox.length !== 4)
1221
+ throw new Error("invalid readseek detect object.bbox");
1222
+ return {
1223
+ label: requireString(item.label, "object.label"),
1224
+ bbox: bbox.map((n, i) => requireNumber(n, `object.bbox[${i}]`))
1225
+ };
1226
+ });
1227
+ }
1228
+ function parseImageEncoding(value) {
1229
+ if (value === "base64")
1230
+ return value;
1231
+ throw new Error("invalid image encoding");
1232
+ }
1233
+ function parseDetectOutput(value) {
1234
+ if (!value || typeof value !== "object")
1235
+ throw new Error("invalid readseek detect output");
1236
+ const output = value;
1237
+ const type = requireString(output.type, "type");
1238
+ const file = requireString(output.file, "file");
1239
+ const mime = optionalString(output.mime, "mime");
1240
+ if (type === "application/pdf") {
1241
+ if (output.format !== "pdf")
1242
+ throw new Error("invalid readseek PDF format");
1243
+ return {
1244
+ kind: "pdf",
1245
+ type,
1246
+ file,
1247
+ mime,
1248
+ format: output.format,
1249
+ pages: requireNumber(output.pages, "pages")
1250
+ };
1251
+ }
1252
+ if (output.width !== undefined || output.height !== undefined) {
1253
+ return {
1254
+ kind: "image",
1255
+ type,
1256
+ file,
1257
+ mime,
1258
+ format: requireString(output.format, "format"),
1259
+ width: requireNumber(output.width, "width"),
1260
+ height: requireNumber(output.height, "height"),
1261
+ animated: requireBoolean(output.animated, "animated"),
1262
+ encoding: output.encoding === undefined ? undefined : parseImageEncoding(output.encoding),
1263
+ data: output.data === undefined ? undefined : requireString(output.data, "data"),
1264
+ ocr: optionalString(output.ocr, "ocr"),
1265
+ caption: optionalString(output.caption, "caption"),
1266
+ objects: parseDetectedObjects(output.objects)
1267
+ };
1268
+ }
1269
+ if (output.language !== undefined) {
1270
+ return {
1271
+ kind: "source",
1272
+ type,
1273
+ file,
1274
+ language: requireString(output.language, "language"),
1275
+ engine: optionalString(output.engine, "engine"),
1276
+ supported: requireBoolean(output.supported, "supported"),
1277
+ mime,
1278
+ syntax: optionalString(output.syntax, "syntax")
1279
+ };
1280
+ }
1281
+ return { kind: "text", type, file, mime };
1282
+ }
1283
+ function parseDocumentCache(value) {
1284
+ if (!value || typeof value !== "object")
1285
+ throw new Error("invalid readseek document cache");
1286
+ const cache = value;
1287
+ const state = requireString(cache.state, "cache.state");
1288
+ if (state !== "built" && state !== "reused")
1289
+ throw new Error("invalid readseek cache.state");
1290
+ return {
1291
+ content_hash: requireString(cache.content_hash, "cache.content_hash"),
1292
+ state
1293
+ };
1294
+ }
1295
+ function parseIdentifyOutput(value) {
1296
+ if (!value || typeof value !== "object")
1297
+ throw new Error("invalid readseek identify output");
1298
+ const output = value;
1299
+ const identifier = output.identifier;
1300
+ const symbol = output.symbol;
1301
+ return {
1302
+ file: requireString(output.file, "file"),
1303
+ language: requireString(output.language, "language"),
1304
+ engine: optionalString(output.engine, "engine"),
1305
+ line_count: requireNumber(output.line_count, "line_count"),
1306
+ file_hash: requireString(output.file_hash, "file_hash"),
1307
+ line: requireNumber(output.line, "line"),
1308
+ column: requireNumber(output.column, "column"),
1309
+ line_hash: requireString(output.line_hash, "line_hash"),
1310
+ identifier: identifier && typeof identifier === "object" ? {
1311
+ text: requireString(identifier.text, "identifier.text"),
1312
+ start_column: requireNumber(identifier.start_column, "identifier.start_column"),
1313
+ end_column: requireNumber(identifier.end_column, "identifier.end_column"),
1314
+ start_byte: requireNumber(identifier.start_byte, "identifier.start_byte"),
1315
+ end_byte: requireNumber(identifier.end_byte, "identifier.end_byte")
1316
+ } : undefined,
1317
+ symbol: symbol && typeof symbol === "object" ? {
1318
+ name: requireString(symbol.name, "symbol.name"),
1319
+ kind: requireString(symbol.kind, "symbol.kind"),
1320
+ qualified_name: requireString(symbol.qualified_name, "symbol.qualified_name"),
1321
+ start_line: requireNumber(symbol.start_line, "symbol.start_line"),
1322
+ end_line: requireNumber(symbol.end_line, "symbol.end_line")
1323
+ } : undefined
1324
+ };
1325
+ }
1326
+ function parseImageContent(value) {
1327
+ const detection = parseDetectOutput(value);
1328
+ if (detection.kind !== "image")
1329
+ throw new Error("invalid readseek image content");
1330
+ return detection;
1331
+ }
1332
+ function parseTextContent(value) {
1333
+ if (!value || typeof value !== "object")
1334
+ throw new Error("invalid readseek content");
1335
+ const output = value;
1336
+ if (output.hashlines !== undefined && output.start_line === undefined) {
1337
+ const hashlines = parseSearchHashlines(output.hashlines, "content.hashlines");
1338
+ const first = hashlines[0];
1339
+ const last = hashlines[hashlines.length - 1];
1340
+ return {
1341
+ file: requireString(output.file, "file"),
1342
+ language: requireString(output.language, "language"),
1343
+ line_count: requireNumber(output.line_count, "line_count"),
1344
+ file_hash: requireString(output.file_hash, "file_hash"),
1345
+ start_line: first?.line ?? 1,
1346
+ end_line: last?.line ?? 0,
1347
+ hashlines
1348
+ };
1349
+ }
1350
+ return parseReadOutput(value);
1351
+ }
1352
+ function parseDigestEnvelope(value) {
1353
+ if (!value || typeof value !== "object")
1354
+ throw new Error("invalid readseek digest output");
1355
+ const output = value;
1356
+ if (output.metadata === undefined)
1357
+ throw new Error("invalid readseek digest metadata");
1358
+ const result = {
1359
+ metadata: parseDetectOutput(output.metadata)
1360
+ };
1361
+ if (output.cache !== undefined)
1362
+ result.cache = parseDocumentCache(output.cache);
1363
+ if (output.content !== undefined)
1364
+ result.content = output.content;
1365
+ if (output.map !== undefined)
1366
+ result.map = parseMapOutput(output.map);
1367
+ if (output.diagnostics !== undefined)
1368
+ result.diagnostics = parseCheckOutput(output.diagnostics);
1369
+ if (output.identity !== undefined)
1370
+ result.identity = parseIdentifyOutput(output.identity);
1371
+ return result;
1372
+ }
1373
+ function parseEditOutput(value) {
1374
+ if (!value || typeof value !== "object")
1375
+ throw new Error("invalid readseek edit output");
1376
+ const output = value;
1377
+ return {
1378
+ file: requireString(output.file, "file"),
1379
+ before_hash: requireString(output.before_hash, "before_hash"),
1380
+ file_hash: requireString(output.file_hash, "file_hash"),
1381
+ plan_hash: requireString(output.plan_hash, "plan_hash"),
1382
+ applied: requireBoolean(output.applied, "applied"),
1383
+ changed: requireBoolean(output.changed, "changed"),
1384
+ edit_count: requireNumber(output.edit_count, "edit_count"),
1385
+ before_content: optionalString(output.before_content, "before_content"),
1386
+ content: optionalString(output.content, "content")
1387
+ };
1388
+ }
1389
+ function parseRenameConflicts(value, field) {
1390
+ if (value === undefined)
1391
+ return [];
1392
+ if (!Array.isArray(value))
1393
+ throw new Error(`invalid readseek ${field}`);
1394
+ return value.map((item) => {
1395
+ if (!item || typeof item !== "object")
1396
+ throw new Error(`invalid readseek ${field} entry`);
1397
+ const c = item;
1398
+ return {
1399
+ line: requireNumber(c.line, `${field}.line`),
1400
+ column: requireNumber(c.column, `${field}.column`),
1401
+ reason: requireString(c.reason, `${field}.reason`)
1402
+ };
1403
+ });
1404
+ }
1405
+ function parseRenameEdits(value, field) {
1406
+ if (value === undefined)
1407
+ return [];
1408
+ if (!Array.isArray(value))
1409
+ throw new Error(`invalid readseek ${field} entry`);
1410
+ return value.map((item) => {
1411
+ if (!item || typeof item !== "object")
1412
+ throw new Error(`invalid readseek ${field} entry`);
1413
+ const e = item;
1414
+ return {
1415
+ line: requireNumber(e.line, `${field}.line`),
1416
+ start_column: requireNumber(e.start_column, `${field}.start_column`),
1417
+ end_column: requireNumber(e.end_column, `${field}.end_column`),
1418
+ start_byte: requireNumber(e.start_byte, `${field}.start_byte`),
1419
+ end_byte: requireNumber(e.end_byte, `${field}.end_byte`),
1420
+ occurrence: requireString(e.occurrence, `${field}.occurrence`),
1421
+ line_hash: requireString(e.line_hash, `${field}.line_hash`),
1422
+ text: requireString(e.text, `${field}.text`)
1423
+ };
1424
+ });
1425
+ }
1426
+ function parseRenameOutput(value) {
1427
+ if (!value || typeof value !== "object")
1428
+ throw new Error("invalid readseek rename output");
1429
+ const output = value;
1430
+ const others = output.others;
1431
+ if (others !== undefined && !Array.isArray(others))
1432
+ throw new Error("invalid readseek others");
1433
+ return {
1434
+ file: requireString(output.file, "file"),
1435
+ language: requireString(output.language, "language"),
1436
+ engine: optionalString(output.engine, "engine"),
1437
+ file_hash: requireString(output.file_hash, "file_hash"),
1438
+ old_name: requireString(output.old_name, "old_name"),
1439
+ new_name: requireString(output.new_name, "new_name"),
1440
+ applied: requireBoolean(output.applied, "applied"),
1441
+ conflicts: parseRenameConflicts(output.conflicts, "conflicts"),
1442
+ edits: parseRenameEdits(output.edits, "edits"),
1443
+ others: others?.map((entry) => {
1444
+ if (!entry || typeof entry !== "object")
1445
+ throw new Error("invalid readseek other");
1446
+ const o = entry;
1447
+ return {
1448
+ file: requireString(o.file, "other.file"),
1449
+ language: requireString(o.language, "other.language"),
1450
+ engine: optionalString(o.engine, "other.engine"),
1451
+ file_hash: requireString(o.file_hash, "other.file_hash"),
1452
+ conflicts: parseRenameConflicts(o.conflicts, "other.conflicts"),
1453
+ edits: parseRenameEdits(o.edits, "other.edits")
1454
+ };
1455
+ }) ?? []
1456
+ };
1457
+ }
1458
+ function parseDefCompact(value) {
1459
+ if (!value || typeof value !== "object")
1460
+ throw new Error("invalid readseek def output");
1461
+ const output = value;
1462
+ const locations = output.locations;
1463
+ if (!Array.isArray(locations))
1464
+ throw new Error("invalid readseek def locations");
1465
+ return locations.map((loc) => {
1466
+ if (!loc || typeof loc !== "object")
1467
+ throw new Error("invalid readseek def location");
1468
+ const item = loc;
1469
+ return {
1470
+ file: requireString(item.file, "location.file"),
1471
+ line: requireNumber(item.line, "location.line"),
1472
+ column: requireNumber(item.column, "location.column"),
1473
+ line_hash: requireString(item.line_hash, "location.line_hash"),
1474
+ text: requireString(item.text, "location.text"),
1475
+ kind: optionalString(item.kind, "location.kind"),
1476
+ name: optionalString(item.name, "location.name"),
1477
+ qualified_name: optionalString(item.qualified_name, "location.qualified_name")
1478
+ };
1479
+ });
1480
+ }
1481
+ function createReadSeekClient(runner) {
1482
+ function digestArgs(target, options) {
1483
+ return buildDigestArgs({
1484
+ path: target,
1485
+ select: options.select ?? "content",
1486
+ at: options.at,
1487
+ end: options.end,
1488
+ limit: options.limit,
1489
+ language: options.language,
1490
+ visionMode: options.visionMode,
1491
+ visionLevel: options.visionLevel,
1492
+ stdinName: options.stdin !== undefined && target === "-" ? options.stdinName ?? target : undefined
1493
+ });
1494
+ }
1495
+ async function runDigestRaw(target, options = {}) {
1496
+ const args = digestArgs(target, options);
1497
+ const runOptions = {
1498
+ signal: options.signal,
1499
+ stdin: options.stdin,
1500
+ timeoutMs: options.timeoutMs,
1501
+ vision: options.vision
1502
+ };
1503
+ return runner.json(args, runOptions);
1504
+ }
1505
+ async function digest(target, options = {}) {
1506
+ return parseDigestEnvelope(await runDigestRaw(target, options));
1507
+ }
1508
+ function requireDigestContent(envelope, field) {
1509
+ if (envelope.content === undefined)
1510
+ throw new Error(`invalid readseek ${field}: missing content`);
1511
+ return envelope.content;
1512
+ }
1513
+ async function digestContent(filePath, options = {}) {
1514
+ const envelope = await digest(filePath, {
1515
+ select: "content",
1516
+ at: options.startLine !== undefined ? buildLineLocation(options.startLine) : undefined,
1517
+ end: options.endLine,
1518
+ visionMode: options.visionMode,
1519
+ signal: options.signal,
1520
+ vision: options.vision
1521
+ });
1522
+ if (envelope.metadata.kind === "pdf") {
1523
+ return { metadata: envelope.metadata, cache: envelope.cache };
1524
+ }
1525
+ const content = requireDigestContent(envelope, "content");
1526
+ if (envelope.metadata.kind === "image") {
1527
+ return { metadata: envelope.metadata, image: parseImageContent(content) };
1528
+ }
1529
+ return { metadata: envelope.metadata, text: parseTextContent(content) };
1530
+ }
1531
+ return {
1532
+ async view(filePath, options = {}) {
1533
+ const args = buildViewArgs({
1534
+ path: filePath,
1535
+ node: options.node,
1536
+ page: options.page,
1537
+ kind: options.kind,
1538
+ depth: options.depth,
1539
+ outline: options.outline,
1540
+ visionMode: options.visionMode,
1541
+ visionLevel: options.visionLevel
1542
+ });
1543
+ return runner.text(args, {
1544
+ signal: options.signal,
1545
+ vision: options.visionMode !== undefined
1546
+ });
1547
+ },
1548
+ digestRaw(target, options = {}) {
1549
+ return runDigestRaw(target, options);
1550
+ },
1551
+ digest,
1552
+ digestContent,
1553
+ async image(filePath, modes, options = {}) {
1554
+ const requestedModes = modes.length > 1 ? ["all"] : modes;
1555
+ const results = await Promise.allSettled(requestedModes.map(async (mode) => {
1556
+ const digested = await digestContent(filePath, {
1557
+ visionMode: mode,
1558
+ signal: options.signal,
1559
+ vision: true
1560
+ });
1561
+ if (!digested.image)
1562
+ throw new Error(`readseek returned no image analysis for ${filePath}`);
1563
+ return digested.image;
1564
+ }));
1565
+ let merged;
1566
+ for (const result of results) {
1567
+ if (result.status !== "fulfilled")
1568
+ continue;
1569
+ const detection = result.value;
1570
+ merged = merged === undefined ? detection : {
1571
+ ...merged,
1572
+ ocr: detection.ocr ?? merged.ocr,
1573
+ caption: detection.caption ?? merged.caption,
1574
+ objects: detection.objects ?? merged.objects
1575
+ };
1576
+ }
1577
+ if (merged !== undefined)
1578
+ return merged;
1579
+ const failure = results.find((result) => result.status === "rejected");
1580
+ if (failure?.status === "rejected")
1581
+ throw failure.reason;
1582
+ throw new Error(`readseek returned no image analysis for ${filePath}`);
1583
+ },
1584
+ async preparedImage(filePath, options = {}) {
1585
+ const digested = await digestContent(filePath, {
1586
+ visionMode: "none",
1587
+ signal: options.signal
1588
+ });
1589
+ const output = digested.image;
1590
+ if (!output || output.encoding !== "base64" || output.data === undefined || output.mime === undefined) {
1591
+ throw new Error(`readseek returned no prepared image for ${filePath}`);
1592
+ }
1593
+ return { mime: output.mime, encoding: output.encoding, data: output.data };
1594
+ },
1595
+ async search(target, pattern, options = {}) {
1596
+ const args = buildSearchArgs({
1597
+ path: target,
1598
+ pattern,
1599
+ language: options.language,
1600
+ cached: options.cached,
1601
+ others: options.others,
1602
+ ignored: options.ignored
1603
+ });
1604
+ return parseSearchOutput(await runner.json(args, { signal: options.signal }));
1605
+ },
1606
+ async refs(target, options = {}) {
1607
+ const args = buildRefsArgs({
1608
+ path: target,
1609
+ name: options.name,
1610
+ scope: options.scope,
1611
+ line: options.line,
1612
+ column: options.column,
1613
+ language: options.language,
1614
+ cached: options.cached,
1615
+ others: options.others,
1616
+ ignored: options.ignored
1617
+ });
1618
+ return parseRefsOutput(await runner.json(args, { signal: options.signal }));
1619
+ },
1620
+ async def(target, options) {
1621
+ const args = buildDefArgs({
1622
+ path: target,
1623
+ name: options.name,
1624
+ format: "plain",
1625
+ language: options.language,
1626
+ cached: options.cached,
1627
+ others: options.others,
1628
+ ignored: options.ignored
1629
+ });
1630
+ return parseDefCompact(await runner.json(args, { signal: options.signal }));
1631
+ },
1632
+ async check(filePath, content, options = {}) {
1633
+ const envelope = await digest("-", {
1634
+ select: "diagnostics",
1635
+ stdin: content,
1636
+ stdinName: filePath,
1637
+ signal: options.signal
1638
+ });
1639
+ if (!envelope.diagnostics)
1640
+ throw new Error("invalid readseek diagnostics: missing diagnostics facet");
1641
+ return envelope.diagnostics;
1642
+ },
1643
+ async identify(filePath, content, options = {}) {
1644
+ const envelope = await digest("-", {
1645
+ select: "identity",
1646
+ stdin: content,
1647
+ stdinName: filePath,
1648
+ at: options.line !== undefined ? buildLineLocation(options.line, options.column) : undefined,
1649
+ language: options.language,
1650
+ signal: options.signal
1651
+ });
1652
+ if (!envelope.identity)
1653
+ throw new Error("invalid readseek identity: missing identity facet");
1654
+ return envelope.identity;
1655
+ },
1656
+ async detect(filePath, options = {}) {
1657
+ const envelope = await digest(filePath, { select: "metadata", signal: options.signal });
1658
+ return envelope.metadata;
1659
+ },
1660
+ async edit(filePath, edits, options = {}) {
1661
+ const args = buildEditArgs({
1662
+ path: filePath,
1663
+ apply: options.apply,
1664
+ planHash: options.planHash,
1665
+ language: options.language
1666
+ });
1667
+ return parseEditOutput(await runner.json(args, {
1668
+ signal: options.signal,
1669
+ stdin: JSON.stringify({ edits }),
1670
+ timeoutMs: options.timeoutMs,
1671
+ cancelable: options.cancelable
1672
+ }));
1673
+ },
1674
+ async rename(filePath, options) {
1675
+ const args = buildRenameArgs({
1676
+ path: filePath,
1677
+ to: options.to,
1678
+ line: options.line,
1679
+ column: options.column,
1680
+ workspace: options.workspace,
1681
+ apply: options.apply,
1682
+ language: options.language,
1683
+ cached: options.cached,
1684
+ others: options.others,
1685
+ ignored: options.ignored
1686
+ });
1687
+ return parseRenameOutput(await runner.json(args, { signal: options.signal }));
1688
+ }
1689
+ };
1690
+ }
1018
1691
  export {
1019
1692
  validateVisionLevelVsMode,
1020
1693
  validateRefsNameVsScope,
@@ -1028,6 +1701,7 @@ export {
1028
1701
  runReadSeekBun,
1029
1702
  rewriteBacktickedToolNames,
1030
1703
  resolveToolName,
1704
+ resolveReadSeekBinaryFromPath,
1031
1705
  resolveReadSeekBinaryFromPackages,
1032
1706
  resolveProcessLimits,
1033
1707
  renderToolRoutingPolicy,
@@ -1044,7 +1718,9 @@ export {
1044
1718
  fallbackToolDescriptionMap,
1045
1719
  failureFromProcessResult,
1046
1720
  ensureSuccessfulStdout,
1721
+ createReadSeekClient,
1047
1722
  cleanReadSeekErrorText,
1723
+ classifyReadSeekFailure,
1048
1724
  buildViewArgs,
1049
1725
  buildSearchArgs,
1050
1726
  buildRenameArgs,
@@ -11,3 +11,9 @@ export declare function resolveReadSeekBinaryFromPackages(resolver?: ModuleResol
11
11
  arch?: string;
12
12
  metaPackage?: string;
13
13
  }): string;
14
+ /**
15
+ * Find an executable readseek on PATH, or null. PATH is the way a user-managed
16
+ * install (package manager, `npm i -g`, cargo) makes itself known; plugins must
17
+ * not grow their own binary-path settings on top of it.
18
+ */
19
+ export declare function resolveReadSeekBinaryFromPath(pathEnv?: string | undefined): string | null;
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@jarkkojs/readseek-api",
3
- "version": "0.9.9",
3
+ "version": "0.9.10",
4
4
  "description": "Shared ReadSeek CLI contract, validation, argv builders, and bounded process runners",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
- "homepage": "https://github.com/jarkkojs/readseek/tree/main/packages/readseek-api#readme",
7
+ "homepage": "https://gitlab.com/jarkkojs/readseek/-/tree/main/packages/readseek-api#readme",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/jarkkojs/readseek.git",
10
+ "url": "git+https://gitlab.com/jarkkojs/readseek.git",
11
11
  "directory": "packages/readseek-api"
12
12
  },
13
13
  "bugs": {
14
- "url": "https://github.com/jarkkojs/readseek/issues"
14
+ "url": "https://gitlab.com/jarkkojs/readseek/-/issues"
15
15
  },
16
16
  "exports": {
17
17
  ".": {
@@ -45,7 +45,7 @@
45
45
  "hashline"
46
46
  ],
47
47
  "dependencies": {
48
- "@jarkkojs/readseek": "^0.9.9"
48
+ "@jarkkojs/readseek": "^0.9.10"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^22.0.0",