opencode-readseek 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +17 -3
  2. package/index.ts +29 -2
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -9,7 +9,7 @@ Add the plugin to `opencode.json`:
9
9
 
10
10
  ```json
11
11
  {
12
- "plugin": [["opencode-readseek", { "imageMode": "auto" }]]
12
+ "plugin": ["opencode-readseek"]
13
13
  }
14
14
  ```
15
15
 
@@ -18,7 +18,8 @@ binary dependency with Bun at startup.
18
18
 
19
19
  ## Tools
20
20
 
21
- - `readseek_read`: read text with `LINE:HASH` anchors; image/PDF handling is explicit and PDFs default to one page.
21
+ - `readseek_read`: read text with `LINE:HASH` anchors; PDFs select one page by
22
+ default and accept an explicit page.
22
23
  - `readseek_edit`: apply line, range, and insertion edits with fresh `LINE:HASH` anchors.
23
24
  - `readseek_write`: create or replace a complete text file.
24
25
  - `readseek_grep`: plain-text or regular-expression search with anchored results.
@@ -27,15 +28,28 @@ binary dependency with Bun at startup.
27
28
  - `readseek_def`, `readseek_refs`, `readseek_hover`: symbol navigation.
28
29
  - `readseek_rename`: apply a verified rename by default; `apply: false` returns a dry-run plan.
29
30
  - `readseek_check`: parse diagnostics.
30
- - `readseek_view`: view an indexed PDF overview or narrow it by page, node, kind, or depth.
31
+ - `readseek_view`: create or reuse a PDF index, return its overview, or narrow
32
+ it by page, node, kind, or depth.
31
33
 
32
34
  The plugin requests OpenCode read, grep, external-directory, and edit permissions
33
35
  as needed. File changes invalidate remembered anchors. Compaction context records
34
36
  paths with fresh anchors and summaries of pending dry-run rename plans. Text reads
35
37
  return at most 2,000 lines by default.
36
38
 
39
+ The plugin also instructs OpenCode to prefer ReadSeek's anchored read, edit,
40
+ write, and rename tools over built-in file mutation tools while leaving the
41
+ built-ins available as fallbacks.
42
+
37
43
  ## Configuration
38
44
 
45
+ Pass options with OpenCode's plugin tuple form:
46
+
47
+ ```json
48
+ {
49
+ "plugin": [["opencode-readseek", { "imageMode": "auto" }]]
50
+ }
51
+ ```
52
+
39
53
  `imageMode` defaults to `"auto"`: it exposes `none`, `all`, `ocr`, `caption`, and
40
54
  `objects`. `"on"` omits `none`; `"off"` skips image/PDF files. Omitting
41
55
  `image` also skips visual files.
package/index.ts CHANGED
@@ -11,8 +11,22 @@ import { tool, type Plugin, type PluginOptions, type ToolAttachment, type ToolCo
11
11
  const require = createRequire(import.meta.url);
12
12
  const MAX_OUTPUT_BYTES = 32 * 1024 * 1024;
13
13
  const DEFAULT_READ_LIMIT = 2000;
14
+ const EDIT_RESULT_READ_LIMIT = 40;
14
15
  const MAX_DOCUMENT_OUTPUT_BYTES = 256 * 1024;
15
16
  const MAX_DOCUMENT_OUTPUT_LINES = 2000;
17
+ const EDITING_POLICY = [
18
+ "ReadSeek editing policy:",
19
+ "- Prefer readseek_read over built-in file reads when preparing to edit existing text; its LINE:HASH anchors are required by readseek_edit.",
20
+ "- Prefer readseek_edit for existing text files, readseek_write for whole-file creation or replacement, and readseek_rename for symbol renames.",
21
+ "- Do not use built-in edit, write, or apply_patch when the corresponding ReadSeek tool can perform the change.",
22
+ "- Use readseek_check after source edits for a quick syntax check.",
23
+ ].join("\n");
24
+ const PREFERRED_TOOL_DESCRIPTIONS: Record<string, string> = {
25
+ readseek_edit: "Preferred tool for editing existing text files with verified LINE:HASH anchors.",
26
+ readseek_read: "Preferred file reader when an existing text file may be edited; returns the anchors required by readseek_edit.",
27
+ readseek_rename: "Preferred tool for renaming code symbols safely across their resolved bindings.",
28
+ readseek_write: "Preferred tool for creating or replacing a complete text file.",
29
+ };
16
30
  const READSEEK_PLATFORM_PACKAGES: Record<string, string> = {
17
31
  "darwin-arm64": "@jarkkojs/readseek-darwin-arm64",
18
32
  "linux-arm64": "@jarkkojs/readseek-linux-arm64",
@@ -1283,14 +1297,20 @@ export const ReadSeekPlugin: Plugin = async (_input, options) => {
1283
1297
  context.abort.throwIfAborted();
1284
1298
  await authorizeRead(context, filePath);
1285
1299
  await rejectSymlinkMutation(filePath);
1286
- const edits = input.edits;
1300
+ const edits = input.edits as AnchorEdit[];
1287
1301
  const before = await readFile(filePath, "utf8");
1288
1302
  await verifyAnchors(context, filePath, edits);
1289
1303
  const after = applyAnchorEdits(before, edits);
1290
1304
  await authorizeEdit(context, [filePath], simpleDiff(filePath, before, after), false);
1291
1305
  context.abort.throwIfAborted();
1292
1306
  if (before !== after) await writeText(filePath, { exists: true, content: before }, after);
1293
- return runReadSeek(context, ["read", filePath, "--end", String(DEFAULT_READ_LIMIT)], { cancelable: false });
1307
+ const firstEditedLine = Math.min(...edits.flatMap((edit) => anchorRefs(edit).map((ref) => ref.line)));
1308
+ const previewStart = Math.max(1, firstEditedLine - 3);
1309
+ return runReadSeek(
1310
+ context,
1311
+ ["read", `${filePath}:${previewStart}`, "--end", String(previewStart + EDIT_RESULT_READ_LIMIT - 1)],
1312
+ { cancelable: false },
1313
+ );
1294
1314
  });
1295
1315
  },
1296
1316
  ),
@@ -1333,6 +1353,13 @@ export const ReadSeekPlugin: Plugin = async (_input, options) => {
1333
1353
  },
1334
1354
  ),
1335
1355
  },
1356
+ "experimental.chat.system.transform": async (_input, output) => {
1357
+ output.system.push(EDITING_POLICY);
1358
+ },
1359
+ "tool.definition": async (input, output) => {
1360
+ const preference = PREFERRED_TOOL_DESCRIPTIONS[input.toolID];
1361
+ if (preference) output.description = `${preference} ${output.description}`;
1362
+ },
1336
1363
  event: async ({ event }) => {
1337
1364
  if (event.type === "file.edited" || event.type === "file.watcher.updated") {
1338
1365
  anchors.forget(event.properties.file);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-readseek",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "OpenCode plugin for readseek-backed structural code navigation",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -30,7 +30,7 @@
30
30
  "node": ">=20.0.0"
31
31
  },
32
32
  "dependencies": {
33
- "@jarkkojs/readseek": "^0.7.0",
33
+ "@jarkkojs/readseek": "^0.7.2",
34
34
  "@opencode-ai/plugin": "^1.17.20"
35
35
  },
36
36
  "devDependencies": {