pi-readseek 0.4.30 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -44
- package/index.ts +45 -7
- package/package.json +2 -2
- package/prompts/def.md +2 -9
- package/prompts/edit.md +13 -13
- package/prompts/grep.md +3 -3
- package/prompts/hover.md +2 -6
- package/prompts/read.md +3 -3
- package/prompts/refs.md +1 -1
- package/prompts/rename.md +3 -7
- package/prompts/sg.md +1 -1
- package/prompts/write.md +5 -5
- package/src/def.ts +12 -19
- package/src/edit-output.ts +3 -3
- package/src/edit-syntax-validate.ts +3 -3
- package/src/edit.ts +18 -25
- package/src/file-map.ts +2 -2
- package/src/grep-budget.ts +7 -51
- package/src/grep-output.ts +4 -4
- package/src/grep.ts +19 -26
- package/src/hover.ts +4 -8
- package/src/read-output.ts +4 -4
- package/src/read.ts +30 -43
- package/src/readseek-client.ts +111 -79
- package/src/readseek-params.ts +1 -1
- package/src/readseek-settings.ts +144 -61
- package/src/readseek-value.ts +4 -4
- package/src/refs-output.ts +3 -3
- package/src/refs.ts +6 -10
- package/src/register-tool.ts +4 -42
- package/src/rename.ts +6 -10
- package/src/replace-symbol.ts +2 -2
- package/src/sg-output.ts +3 -3
- package/src/sg.ts +21 -25
- package/src/syntax-validate-mode.ts +3 -13
- package/src/tool-prompt-metadata.ts +13 -13
- package/src/tui-render-utils.ts +2 -2
- package/src/write.ts +22 -26
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
`pi-readseek` is a pi extension for readseek-backed file reading, hash-anchored
|
|
4
4
|
editing, anchored grep, structural maps, symbol lookup, and structural search.
|
|
5
|
-
It
|
|
6
|
-
|
|
5
|
+
It exposes readseek tools under the `readSeek_` prefix. Built-in pi tools stay
|
|
6
|
+
active unless excluded in settings.
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
|
|
@@ -23,61 +23,56 @@ npm install --save-dev @jarkkojs/readseek
|
|
|
23
23
|
|
|
24
24
|
## Tools
|
|
25
25
|
|
|
26
|
-
- **
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- **
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- **
|
|
35
|
-
|
|
36
|
-
- **search** — searches code by structural pattern (AST) and returns anchored
|
|
37
|
-
matches. Use when syntax matters more than raw text.
|
|
38
|
-
- **refs** — finds binding-accurate references to an identifier and returns
|
|
39
|
-
anchored usages with their enclosing symbols. Use before renaming or deleting
|
|
40
|
-
a symbol.
|
|
41
|
-
- **write** — creates or overwrites whole files and returns anchors for
|
|
42
|
-
immediate follow-up edits.
|
|
26
|
+
- **readSeek_read:** reads text files with `LINE:HASH` anchors; images can
|
|
27
|
+
include local OCR, captions, and object text.
|
|
28
|
+
- **readSeek_edit:** edits existing text files using fresh `LINE:HASH` anchors.
|
|
29
|
+
- **readSeek_grep:** searches text and returns edit-ready anchors.
|
|
30
|
+
- **readSeek_search:** searches code by structural AST pattern.
|
|
31
|
+
- **readSeek_refs:** finds identifier references with enclosing symbols.
|
|
32
|
+
- **readSeek_rename:** plans or applies binding-aware renames.
|
|
33
|
+
- **readSeek_hover:** identifies the cursor token and enclosing symbol.
|
|
34
|
+
- **readSeek_def:** finds structural symbol definitions.
|
|
35
|
+
- **readSeek_write:** creates or overwrites whole files and returns anchors.
|
|
43
36
|
|
|
44
37
|
## Settings
|
|
45
38
|
|
|
46
39
|
`pi-readseek` reads optional JSON settings from:
|
|
47
40
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
| `~/.pi/agent/readseek/settings.json` | Global |
|
|
51
|
-
| `.pi/readseek/settings.json` | Project |
|
|
41
|
+
- `~/.pi/agent/settings.json` — Global
|
|
42
|
+
- `.pi/settings.json` — Project
|
|
52
43
|
|
|
53
|
-
Project settings override global settings.
|
|
54
|
-
`
|
|
44
|
+
Project settings override global settings. The `readseek` section lives inside pi's
|
|
45
|
+
shared `settings.json`, alongside other extensions' sections. All settings are
|
|
46
|
+
optional (defaults shown):
|
|
55
47
|
|
|
56
48
|
```json
|
|
57
49
|
{
|
|
58
|
-
"
|
|
59
|
-
"
|
|
50
|
+
"readseek": {
|
|
51
|
+
"excludeTools": [],
|
|
52
|
+
"imageMode": "force",
|
|
53
|
+
"syntaxValidation": "warn",
|
|
54
|
+
"timeoutMs": 120000,
|
|
55
|
+
"grep": {
|
|
56
|
+
"maxLines": 2000,
|
|
57
|
+
"maxBytes": 51200
|
|
58
|
+
}
|
|
60
59
|
}
|
|
61
60
|
}
|
|
62
61
|
```
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- [readseek.vim](https://github.com/jarkkojs/readseek.vim) — Vim 9 plugin
|
|
79
|
-
frontend for the readseek CLI. Provides go-to-definition, references,
|
|
80
|
-
rename, hover, and structural search from within Vim.
|
|
63
|
+
- **excludeTools:** active tool names to hide after activating `readSeek_*`
|
|
64
|
+
tools. For a readseek-only file surface, use `["read", "edit", "write",
|
|
65
|
+
"grep"]`.
|
|
66
|
+
- **imageMode:** image OCR/caption/object analysis in `readSeek_read`: `"force"`
|
|
67
|
+
(or its alias `"on"`) always runs it, `"off"` returns only the image
|
|
68
|
+
attachment, and `"auto"` runs it only when the active model does not support
|
|
69
|
+
native image input.
|
|
70
|
+
- **syntaxValidation:** pre-write syntax-regression check in `readSeek_edit`:
|
|
71
|
+
`"warn"` writes with a warning, `"block"` aborts without writing, `"off"`
|
|
72
|
+
skips the check.
|
|
73
|
+
- **timeoutMs:** readseek invocation timeout in milliseconds.
|
|
74
|
+
- **grep.maxLines** / **grep.maxBytes:** visible `readSeek_grep` output
|
|
75
|
+
budget; values above the defaults are clamped.
|
|
81
76
|
|
|
82
77
|
## Licensing
|
|
83
78
|
|
package/index.ts
CHANGED
|
@@ -9,7 +9,24 @@ import { registerHoverTool } from "./src/hover.js";
|
|
|
9
9
|
import { registerWriteTool } from "./src/write.js";
|
|
10
10
|
import { registerDefTool } from "./src/def.js";
|
|
11
11
|
import { SessionAnchors } from "./src/session-anchors.js";
|
|
12
|
-
import {
|
|
12
|
+
import { readSeekBinaryAvailability } from "./src/readseek-client.js";
|
|
13
|
+
import { resolveReadSeekJsonSettings, type ReadSeekSettingsWarning } from "./src/readseek-settings.js";
|
|
14
|
+
|
|
15
|
+
const READSEEK_TOOL_NAMES = [
|
|
16
|
+
"readSeek_read",
|
|
17
|
+
"readSeek_edit",
|
|
18
|
+
"readSeek_grep",
|
|
19
|
+
"readSeek_search",
|
|
20
|
+
"readSeek_refs",
|
|
21
|
+
"readSeek_rename",
|
|
22
|
+
"readSeek_hover",
|
|
23
|
+
"readSeek_write",
|
|
24
|
+
"readSeek_def",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
function formatSettingsWarning(warning: ReadSeekSettingsWarning): string {
|
|
28
|
+
return `${warning.message} (${warning.source})`;
|
|
29
|
+
}
|
|
13
30
|
|
|
14
31
|
export default function piReadSeekExtension(pi: ExtensionAPI): void {
|
|
15
32
|
const sessionAnchors = new SessionAnchors();
|
|
@@ -18,16 +35,37 @@ export default function piReadSeekExtension(pi: ExtensionAPI): void {
|
|
|
18
35
|
|
|
19
36
|
registerReadTool(pi, { onSuccessfulRead: markAnchored });
|
|
20
37
|
registerEditTool(pi, { wasReadInSession: hasFreshAnchors });
|
|
21
|
-
|
|
22
|
-
const searchGuideline = searchAvailable
|
|
23
|
-
? "Use grep summary for counts; use search for structural code patterns."
|
|
24
|
-
: "Use grep summary for counts; search is unavailable (readseek native backend not loaded).";
|
|
25
|
-
|
|
26
|
-
registerGrepTool(pi, { searchGuideline, onFileAnchored: markAnchored });
|
|
38
|
+
registerGrepTool(pi, { onFileAnchored: markAnchored });
|
|
27
39
|
registerSgTool(pi, { onFileAnchored: markAnchored });
|
|
28
40
|
registerRefsTool(pi, { onFileAnchored: markAnchored });
|
|
29
41
|
registerRenameTool(pi);
|
|
30
42
|
registerHoverTool(pi);
|
|
31
43
|
registerDefTool(pi, { onFileAnchored: markAnchored });
|
|
32
44
|
registerWriteTool(pi, { onFileAnchored: markAnchored });
|
|
45
|
+
|
|
46
|
+
pi.on("session_start", (_event, ctx) => {
|
|
47
|
+
const { settings, warnings } = resolveReadSeekJsonSettings();
|
|
48
|
+
const excludeTools = new Set(settings.excludeTools ?? []);
|
|
49
|
+
const knownTools = new Set([...pi.getAllTools().map((tool) => tool.name), ...READSEEK_TOOL_NAMES]);
|
|
50
|
+
const problems = warnings.map(formatSettingsWarning);
|
|
51
|
+
for (const name of excludeTools) {
|
|
52
|
+
if (!knownTools.has(name)) problems.push(`Unknown tool "${name}" in readseek.excludeTools`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const availability = readSeekBinaryAvailability();
|
|
56
|
+
if (!availability.available) {
|
|
57
|
+
problems.push(`readseek tools are inactive: ${availability.reason}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const problem of problems) {
|
|
61
|
+
if (ctx.hasUI) ctx.ui.notify(problem, "warning");
|
|
62
|
+
else console.warn(problem);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!availability.available) return;
|
|
66
|
+
|
|
67
|
+
const activeTools = [...pi.getActiveTools(), ...READSEEK_TOOL_NAMES]
|
|
68
|
+
.filter((name) => !excludeTools.has(name));
|
|
69
|
+
pi.setActiveTools([...new Set(activeTools)]);
|
|
70
|
+
});
|
|
33
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-readseek",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Pi extension for readseek-backed hash-anchored read/edit/grep, structural code maps, structural search, and file exploration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"node": ">=20.0.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@jarkkojs/readseek": "^0.
|
|
42
|
+
"@jarkkojs/readseek": "^0.5.0",
|
|
43
43
|
"diff": "^8.0.3",
|
|
44
44
|
"xxhash-wasm": "^1.1.0"
|
|
45
45
|
},
|
package/prompts/def.md
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
---
|
|
2
|
-
tools: def
|
|
3
|
-
---
|
|
4
|
-
|
|
5
1
|
Find structural symbol definitions. Calls `readseek def` which searches
|
|
6
2
|
for the definition of a named symbol across a file or directory.
|
|
7
3
|
|
|
8
4
|
## Parameters
|
|
9
5
|
|
|
10
6
|
- `path` (optional): File or directory to search (default: ".").
|
|
11
|
-
- `name
|
|
12
|
-
`fromIdentify` is true.
|
|
7
|
+
- `name`: Qualified or unqualified symbol name.
|
|
13
8
|
- `lang` (optional): Language override.
|
|
14
|
-
- `fromIdentify` (optional): When true, reads identify output from a
|
|
15
|
-
previous identify call to extract the symbol name automatically.
|
|
16
9
|
- `cached` (optional): Search tracked/indexed files in a Git repository.
|
|
17
10
|
- `others` (optional): Search untracked files.
|
|
18
11
|
- `ignored` (optional): Include ignored untracked files.
|
|
19
12
|
|
|
20
13
|
## When to use
|
|
21
14
|
|
|
22
|
-
- After a
|
|
15
|
+
- After a `readSeek_hover` call, use the qualified symbol name to jump to its definition.
|
|
23
16
|
- When the user asks "where is X defined?".
|
|
24
17
|
- To find a function/class/type definition by its qualified name.
|
package/prompts/edit.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Surgically edit existing text files. Prefer hash-verified anchors from fresh `
|
|
1
|
+
Surgically edit existing text files. Prefer hash-verified anchors from fresh `readSeek_read`, `readSeek_grep`, `readSeek_search`, or `readSeek_write` output; copy `LINE:HASH` anchors exactly.
|
|
2
2
|
|
|
3
|
-
`
|
|
3
|
+
`readSeek_edit` requires the target file to have been anchored earlier in the current session. If you get `file-not-read`, run `readSeek_read`, `readSeek_grep`, `readSeek_search`, or `readSeek_write` first.
|
|
4
4
|
|
|
5
5
|
## Variants
|
|
6
6
|
|
|
@@ -43,28 +43,28 @@ Wrap string replacements as `{ "replace": { "old_text": "...", "new_text": "..."
|
|
|
43
43
|
|
|
44
44
|
## `replace_symbol`
|
|
45
45
|
|
|
46
|
-
Use `replace_symbol` when you want to replace one whole mapped symbol without line anchors. Query symbols like `
|
|
46
|
+
Use `replace_symbol` when you want to replace one whole mapped symbol without line anchors. Query symbols like `readSeek_read({ symbol })`: `Name`, `Class.method`, or `Name@<line>`.
|
|
47
47
|
|
|
48
48
|
Rules:
|
|
49
49
|
|
|
50
|
-
- Use an exact name, dotted path, or `@<line>`. If `
|
|
50
|
+
- Use an exact name, dotted path, or `@<line>`. If `readSeek_read({ symbol })` returned a fuzzy match, confirm the exact symbol first.
|
|
51
51
|
- Supported for TypeScript, JavaScript, Rust, and Java. For other languages, use anchored edits.
|
|
52
52
|
- `new_body` must not be empty or whitespace-only.
|
|
53
|
-
- Write `new_body` without extra leading indentation; `
|
|
53
|
+
- Write `new_body` without extra leading indentation; `readSeek_edit` re-indents it to match the original symbol.
|
|
54
54
|
- If `new_body` appears to declare a different symbol name, the edit still applies but returns a `name-mismatch` warning.
|
|
55
55
|
- Do not combine `replace_symbol` with anchored edits that touch the same lines. Duplicate or overlapping `replace_symbol` ranges are rejected.
|
|
56
56
|
|
|
57
57
|
## Stale anchors
|
|
58
58
|
|
|
59
|
-
If anchors no longer match, `
|
|
59
|
+
If anchors no longer match, `readSeek_edit` fails with `hash-mismatch` and shows nearby current lines. Lines marked `>>>` include updated anchors:
|
|
60
60
|
|
|
61
61
|
```text
|
|
62
62
|
>>> 41:b34| const renamed = 3;
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
Copy the updated `LINE:HASH` and retry. If the target moved farther away, re-run `
|
|
65
|
+
Copy the updated `LINE:HASH` and retry. If the target moved farther away, re-run `readSeek_read`, `readSeek_grep`, `readSeek_search`, or `readSeek_write` for fresh anchors.
|
|
66
66
|
|
|
67
|
-
If `
|
|
67
|
+
If `readSeek_edit` auto-relocates an anchor, read the warning and verify that the edit landed in the intended place.
|
|
68
68
|
|
|
69
69
|
## Validation and warnings
|
|
70
70
|
|
|
@@ -80,21 +80,21 @@ Syntax validation runs before writing when supported:
|
|
|
80
80
|
- Default `warn`: write succeeds, but warnings include `syntax-regression: lines X-Y`.
|
|
81
81
|
- `block`: aborts without writing.
|
|
82
82
|
- `off`: skips validation.
|
|
83
|
-
- `
|
|
83
|
+
- The `readseek.syntaxValidation` setting can change the default mode.
|
|
84
84
|
|
|
85
85
|
Existing syntax errors are tolerated; warnings are for newly introduced parser errors.
|
|
86
86
|
|
|
87
87
|
## Optional post-edit verification
|
|
88
88
|
|
|
89
|
-
`postEditVerify: true` opts into read-back verification for this call. It is off by default. When enabled, `
|
|
89
|
+
`postEditVerify: true` opts into read-back verification for this call. It is off by default. When enabled, `readSeek_edit` writes normally, then reads the file back and compares persisted content to the intended content, including BOM and original line endings. This is not syntax validation.
|
|
90
90
|
|
|
91
91
|
## Diff data contract
|
|
92
92
|
|
|
93
|
-
Successful `
|
|
93
|
+
Successful `readSeek_edit` results include:
|
|
94
94
|
|
|
95
|
-
- `details.diff` and `details.
|
|
95
|
+
- `details.diff` and `details.readSeekValue.diff`: compact human-readable hashline diff strings.
|
|
96
96
|
- `details.patch`: standard unified diff with file and hunk headers.
|
|
97
|
-
- `details.diffData` and `details.
|
|
97
|
+
- `details.diffData` and `details.readSeekValue.diffData`: stable structured diff data.
|
|
98
98
|
|
|
99
99
|
`diffData` shape:
|
|
100
100
|
|
package/prompts/grep.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Search file contents. Non-summary results include edit-ready `LINE:HASH` anchors, so you usually do not need a follow-up `
|
|
1
|
+
Search file contents. Non-summary results include edit-ready `LINE:HASH` anchors, so you usually do not need a follow-up `readSeek_read` before `readSeek_edit`.
|
|
2
2
|
|
|
3
3
|
## Modes
|
|
4
4
|
|
|
@@ -21,8 +21,8 @@ Search file contents. Non-summary results include edit-ready `LINE:HASH` anchors
|
|
|
21
21
|
|
|
22
22
|
## Use well
|
|
23
23
|
|
|
24
|
-
Use `
|
|
24
|
+
Use `readSeek_grep` for text: identifiers, strings, config keys, error messages, comments, or docs. Use `literal: true` unless you want regex behavior.
|
|
25
25
|
|
|
26
|
-
For code shape — calls, imports, declarations, JSX, object literals, control flow — prefer `
|
|
26
|
+
For code shape — calls, imports, declarations, JSX, object literals, control flow — prefer `readSeek_search`, which parses AST patterns.
|
|
27
27
|
|
|
28
28
|
If output says results were truncated at `limit` or by display budget, narrow before editing. Good narrowing order: `summary` → `path`/`glob` → stricter pattern → `scope: "symbol"` or `context`.
|
package/prompts/hover.md
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
tools: hover
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Use hover to identify the identifier and enclosing symbol at a cursor
|
|
1
|
+
Use `readSeek_hover` to identify the identifier and enclosing symbol at a cursor
|
|
6
2
|
position. Calls `readseek identify` with the file content sent via stdin
|
|
7
3
|
so unsaved editor content is included.
|
|
8
4
|
|
|
@@ -14,6 +10,6 @@ so unsaved editor content is included.
|
|
|
14
10
|
|
|
15
11
|
## When to use
|
|
16
12
|
|
|
17
|
-
- Before a
|
|
13
|
+
- Before a `readSeek_rename`, to confirm the identifier under the cursor.
|
|
18
14
|
- Before a go-to-definition, to get the qualified symbol name.
|
|
19
15
|
- To inspect what symbol a specific line belongs to.
|
package/prompts/read.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Read files through readseek. Text output uses `LINE:HASH|content` anchors that can be copied directly into `
|
|
1
|
+
Read files through readseek. Text output uses `LINE:HASH|content` anchors that can be copied directly into `readSeek_edit`; supported images return attachments and may append OCR/caption/object text depending on `readseek.imageMode`. Default cap: {{DEFAULT_MAX_LINES}} lines or {{DEFAULT_MAX_BYTES}}.
|
|
2
2
|
|
|
3
3
|
## Choose the right read
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ Read files through readseek. Text output uses `LINE:HASH|content` anchors that c
|
|
|
15
15
|
- `symbol` — symbol query; supports `Class.method`, package-relative Java names, and `Name@<line>` disambiguation; cannot combine with `offset` / `limit`.
|
|
16
16
|
- `bundle` — only `"local"`; requires `symbol` and cannot combine with `map`.
|
|
17
17
|
|
|
18
|
-
When a full-file read is truncated, readseek appends a structural map automatically when available. Use map line ranges for follow-up `
|
|
18
|
+
When a full-file read is truncated, readseek appends a structural map automatically when available. Use map line ranges for follow-up `readSeek_read({ offset, limit })` calls.
|
|
19
19
|
|
|
20
20
|
## Symbol examples
|
|
21
21
|
|
|
@@ -38,4 +38,4 @@ Result behavior:
|
|
|
38
38
|
- **Fuzzy**: returns the best camelCase/substring match with a warning; verify before editing from those anchors.
|
|
39
39
|
- **Not found** or **unmappable**: falls back to normal read with a warning and, when available, symbol suggestions.
|
|
40
40
|
|
|
41
|
-
Hash anchors from normal, symbol, and bundled reads are valid for `
|
|
41
|
+
Hash anchors from normal, symbol, and bundled reads are valid for `readSeek_edit` until the file changes.
|
package/prompts/refs.md
CHANGED
|
@@ -20,4 +20,4 @@ Without `scope`, references match by identifier name across the target. With `sc
|
|
|
20
20
|
|
|
21
21
|
When searching a directory inside a Git repository, readseek defaults to tracked/indexed files plus untracked non-ignored files. Use `cached`, `others`, and `ignored` to narrow or expand that selection. `ignored` requires `others`.
|
|
22
22
|
|
|
23
|
-
Use `
|
|
23
|
+
Use `readSeek_grep` for plain text, `readSeek_search` for code shape, and `readSeek_refs` for identifier usage.
|
package/prompts/rename.md
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
tools: rename
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Use rename to rename an identifier (variable, function, type, etc.) with
|
|
1
|
+
Use `readSeek_rename` to rename an identifier (variable, function, type, etc.) with
|
|
6
2
|
binding accuracy. The tool calls `readseek rename` which resolves the
|
|
7
3
|
lexical binding under the cursor and renames every occurrence that binds
|
|
8
4
|
to the same declaration.
|
|
@@ -27,5 +23,5 @@ to the same declaration.
|
|
|
27
23
|
|
|
28
24
|
## When not to use
|
|
29
25
|
|
|
30
|
-
- For search-and-replace across files, use
|
|
31
|
-
- For refactoring that requires adding/removing parameters, use
|
|
26
|
+
- For search-and-replace across files, use `readSeek_grep` or `readSeek_search`.
|
|
27
|
+
- For refactoring that requires adding/removing parameters, use `readSeek_edit`.
|
package/prompts/sg.md
CHANGED
|
@@ -37,4 +37,4 @@ Useful `lang` values include `assembly`, `bash`, `c`, `cpp`, `csharp`, `css`, `d
|
|
|
37
37
|
|
|
38
38
|
When searching a directory inside a Git repository, readseek defaults to tracked/indexed files plus untracked non-ignored files. Use `cached`, `others`, and `ignored` to narrow or expand that selection. `ignored` requires `others`.
|
|
39
39
|
|
|
40
|
-
Use `
|
|
40
|
+
Use `readSeek_grep` for plain text and `readSeek_search` for structure.
|
package/prompts/write.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Create or overwrite a whole file and return `LINE:HASH` anchors for immediate follow-up `
|
|
1
|
+
Create or overwrite a whole file and return `LINE:HASH` anchors for immediate follow-up `readSeek_edit` calls.
|
|
2
2
|
|
|
3
3
|
## Use / avoid
|
|
4
4
|
|
|
5
|
-
Use `
|
|
5
|
+
Use `readSeek_write` for new files, generated files, or intentional full-file replacement. For small changes or appends to an existing file, run `readSeek_read` or `readSeek_search` first and use `readSeek_edit` (`insert_after` for appends).
|
|
6
6
|
|
|
7
|
-
Existing files are overwritten without confirmation. Binary-looking content can be written, but hashlines are not generated, so there are no anchors for `
|
|
7
|
+
Existing files are overwritten without confirmation. Binary-looking content can be written, but hashlines are not generated, so there are no anchors for `readSeek_edit`.
|
|
8
8
|
|
|
9
9
|
## Parameters
|
|
10
10
|
|
|
@@ -14,11 +14,11 @@ Existing files are overwritten without confirmation. Binary-looking content can
|
|
|
14
14
|
|
|
15
15
|
## Output
|
|
16
16
|
|
|
17
|
-
Successful text writes return `LINE:HASH|content`. Display hashlines escape control characters for safe rendering. Visible output is capped at 2000 lines or 50 KB, but full anchors remain available in `
|
|
17
|
+
Successful text writes return `LINE:HASH|content`. Display hashlines escape control characters for safe rendering. Visible output is capped at 2000 lines or 50 KB, but full anchors remain available in `readSeekValue`.
|
|
18
18
|
|
|
19
19
|
## Diff data contract
|
|
20
20
|
|
|
21
|
-
Successful text `
|
|
21
|
+
Successful text `readSeek_write` results include additive final `details.diff`, `details.readSeekValue.diff`, `details.diffData`, and `details.readSeekValue.diffData` fields. String diff fields remain the backward-compatible human-readable fallback.
|
|
22
22
|
|
|
23
23
|
`diffData` is a stable versioned contract:
|
|
24
24
|
|
package/src/def.ts
CHANGED
|
@@ -6,8 +6,8 @@ import { defineToolPromptMetadata } from "./tool-prompt-metadata.js";
|
|
|
6
6
|
import { buildReadSeekLineWithHash, buildToolErrorResult } from "./readseek-value.js";
|
|
7
7
|
import { resolveToCwd } from "./path-utils.js";
|
|
8
8
|
import { statSearchPathOrError } from "./stat-search-path.js";
|
|
9
|
-
import { classifyReadSeekFailure,
|
|
10
|
-
import { searchPathParam, langParam,
|
|
9
|
+
import { classifyReadSeekFailure, readSeekDef } from "./readseek-client.js";
|
|
10
|
+
import { searchPathParam, langParam, readSeekGitSearchParams } from "./readseek-params.js";
|
|
11
11
|
import { registerReadSeekTool } from "./register-tool.js";
|
|
12
12
|
|
|
13
13
|
import { renderAnchoredFilesResult, renderReadSeekSearchCall } from "./tui-render-utils.js";
|
|
@@ -22,7 +22,6 @@ type DefParams = {
|
|
|
22
22
|
name?: string;
|
|
23
23
|
path?: string;
|
|
24
24
|
lang?: string;
|
|
25
|
-
fromIdentify?: boolean;
|
|
26
25
|
cached?: boolean;
|
|
27
26
|
others?: boolean;
|
|
28
27
|
ignored?: boolean;
|
|
@@ -43,8 +42,8 @@ export async function executeDef(opts: ExecuteDefOptions): Promise<any> {
|
|
|
43
42
|
const { params, signal, cwd, onFileAnchored } = opts;
|
|
44
43
|
const p = params as DefParams;
|
|
45
44
|
|
|
46
|
-
if (!p.
|
|
47
|
-
return buildToolErrorResult("def", "invalid-parameter", "
|
|
45
|
+
if (!p.name || !p.name.trim()) {
|
|
46
|
+
return buildToolErrorResult("def", "invalid-parameter", "readSeek_def requires 'name'");
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
const searchPath = resolveToCwd(p.path ?? ".", cwd);
|
|
@@ -53,9 +52,8 @@ export async function executeDef(opts: ExecuteDefOptions): Promise<any> {
|
|
|
53
52
|
if (!statResult.ok) return statResult.error;
|
|
54
53
|
|
|
55
54
|
try {
|
|
56
|
-
const definitions = await
|
|
55
|
+
const definitions = await readSeekDef(searchPath, {
|
|
57
56
|
name: p.name,
|
|
58
|
-
fromIdentify: p.fromIdentify,
|
|
59
57
|
language: p.lang,
|
|
60
58
|
cached: p.cached,
|
|
61
59
|
others: p.others,
|
|
@@ -67,7 +65,7 @@ export async function executeDef(opts: ExecuteDefOptions): Promise<any> {
|
|
|
67
65
|
return {
|
|
68
66
|
content: [{ type: "text", text: "no definitions found" }],
|
|
69
67
|
details: {
|
|
70
|
-
|
|
68
|
+
readSeekValue: { tool: "def", ok: true, path: searchPath, definitions: [] },
|
|
71
69
|
},
|
|
72
70
|
};
|
|
73
71
|
}
|
|
@@ -92,14 +90,14 @@ export async function executeDef(opts: ExecuteDefOptions): Promise<any> {
|
|
|
92
90
|
for (const file of fileList) {
|
|
93
91
|
textParts.push(file.displayPath);
|
|
94
92
|
for (const line of file.lines) {
|
|
95
|
-
|
|
93
|
+
textParts.push(` ${line.line}:${line.hash} ${line.display}`);
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
96
|
|
|
99
97
|
return {
|
|
100
98
|
content: [{ type: "text", text: textParts.join("\n") }],
|
|
101
99
|
details: {
|
|
102
|
-
|
|
100
|
+
readSeekValue: { tool: "def", ok: true, path: searchPath, definitions },
|
|
103
101
|
},
|
|
104
102
|
};
|
|
105
103
|
} catch (err: any) {
|
|
@@ -110,21 +108,16 @@ export async function executeDef(opts: ExecuteDefOptions): Promise<any> {
|
|
|
110
108
|
|
|
111
109
|
export function registerDefTool(pi: ExtensionAPI, options: DefToolOptions = {}) {
|
|
112
110
|
registerReadSeekTool(pi, {
|
|
113
|
-
|
|
114
|
-
pythonName: "def",
|
|
115
|
-
defaultExposure: "opt-in",
|
|
116
|
-
}, {
|
|
117
|
-
name: "def",
|
|
111
|
+
name: "readSeek_def",
|
|
118
112
|
label: "Definition",
|
|
119
113
|
description: DEF_PROMPT_METADATA.description,
|
|
120
114
|
promptSnippet: DEF_PROMPT_METADATA.promptSnippet,
|
|
121
115
|
promptGuidelines: DEF_PROMPT_METADATA.promptGuidelines,
|
|
122
116
|
parameters: Type.Object({
|
|
123
|
-
name: Type.
|
|
117
|
+
name: Type.String({ description: "Qualified or unqualified symbol name" }),
|
|
124
118
|
path: searchPathParam(),
|
|
125
119
|
lang: langParam(),
|
|
126
|
-
|
|
127
|
-
...readseekGitSearchParams(),
|
|
120
|
+
...readSeekGitSearchParams(),
|
|
128
121
|
}),
|
|
129
122
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
130
123
|
return executeDef({ params, signal, cwd: ctx.cwd, onFileAnchored: options.onFileAnchored });
|
|
@@ -133,7 +126,7 @@ export function registerDefTool(pi: ExtensionAPI, options: DefToolOptions = {})
|
|
|
133
126
|
return renderReadSeekSearchCall(args, theme, rest, {
|
|
134
127
|
label: "def",
|
|
135
128
|
accent: args.name,
|
|
136
|
-
flags: [args.
|
|
129
|
+
flags: [args.cached && "cached", args.others && "others", args.ignored && "ignored"],
|
|
137
130
|
});
|
|
138
131
|
},
|
|
139
132
|
renderResult(result: any, options: ToolRenderResultOptions, theme: any, ...rest: any[]) {
|
package/src/edit-output.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface BuildEditOutputInput {
|
|
|
17
17
|
export interface EditOutputResult {
|
|
18
18
|
text: string;
|
|
19
19
|
patch: string;
|
|
20
|
-
|
|
20
|
+
readSeekValue: ReturnType<typeof buildReadSeekEditResult>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const EDIT_OPERATION_NAMES = ["set_line", "replace_lines", "insert_after", "replace"] as const;
|
|
@@ -84,7 +84,7 @@ function formatReplaceHint(edits: unknown[] | undefined, noopEdits: unknown[]):
|
|
|
84
84
|
const counts = countEditTypes(edits);
|
|
85
85
|
if (counts.replace === 0) return undefined;
|
|
86
86
|
if (counts.replace !== counts.total) return undefined;
|
|
87
|
-
return "[info: this edit used replace (unverified). For safer future edits, prefer set_line/replace_lines with an anchor from
|
|
87
|
+
return "[info: this edit used replace (unverified). For safer future edits, prefer set_line/replace_lines with an anchor from readSeek_read/readSeek_grep/readSeek_search.]";
|
|
88
88
|
}
|
|
89
89
|
export function buildEditOutput(input: BuildEditOutputInput): EditOutputResult {
|
|
90
90
|
const summary = `Updated ${input.displayPath}`;
|
|
@@ -99,7 +99,7 @@ export function buildEditOutput(input: BuildEditOutputInput): EditOutputResult {
|
|
|
99
99
|
return {
|
|
100
100
|
text,
|
|
101
101
|
patch: input.patch ?? "",
|
|
102
|
-
|
|
102
|
+
readSeekValue: buildReadSeekEditResult({
|
|
103
103
|
path: input.path,
|
|
104
104
|
summary,
|
|
105
105
|
diff: input.diff,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readSeekCheck, type ReadSeekCheckOutput, type ReadSeekDiagnostic } from "./readseek-client.js";
|
|
2
2
|
|
|
3
3
|
export interface ValidateInput {
|
|
4
4
|
filePath: string;
|
|
@@ -46,8 +46,8 @@ export async function validateSyntaxRegression(
|
|
|
46
46
|
let before: ReadSeekCheckOutput;
|
|
47
47
|
let after: ReadSeekCheckOutput;
|
|
48
48
|
try {
|
|
49
|
-
before = input.before === undefined ? EMPTY : await
|
|
50
|
-
after = await
|
|
49
|
+
before = input.before === undefined ? EMPTY : await readSeekCheck(input.filePath, input.before, { signal: options.signal });
|
|
50
|
+
after = await readSeekCheck(input.filePath, input.after, { signal: options.signal });
|
|
51
51
|
} catch {
|
|
52
52
|
return null;
|
|
53
53
|
}
|