pi-readseek 0.8.18 → 0.8.20
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 +51 -37
- package/dist/index.ts +74 -48
- package/package.json +3 -3
- package/prompts/check.md +2 -2
- package/prompts/def.md +6 -5
- package/prompts/edit.md +41 -44
- package/prompts/grep.md +17 -14
- package/prompts/hover.md +3 -2
- package/prompts/read.md +42 -37
- package/prompts/refs.md +16 -20
- package/prompts/rename.md +7 -5
- package/prompts/search.md +28 -28
- package/prompts/view.md +9 -9
- package/prompts/write.md +7 -10
package/README.md
CHANGED
|
@@ -1,37 +1,43 @@
|
|
|
1
1
|
# pi-readseek
|
|
2
2
|
|
|
3
|
-
`pi-readseek` adds ReadSeek's anchored file
|
|
4
|
-
navigation to Pi. Built-
|
|
5
|
-
`read`, `edit`, `write`, or `grep` to
|
|
3
|
+
`pi-readseek` adds ReadSeek's anchored file operations, structural search,
|
|
4
|
+
symbol navigation, and PDF tools to Pi. Built-ins remain available unless
|
|
5
|
+
`replacedTools` maps `read`, `edit`, `write`, or `grep` to a ReadSeek-backed
|
|
6
|
+
implementation.
|
|
6
7
|
|
|
7
|
-
##
|
|
8
|
+
## Install
|
|
8
9
|
|
|
9
10
|
```sh
|
|
10
11
|
pi install npm:pi-readseek
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
The
|
|
14
|
+
The package depends on `@jarkkojs/readseek`, which supplies the native binary on
|
|
14
15
|
supported platforms.
|
|
15
16
|
|
|
16
17
|
## Tools
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
| Tool | Purpose |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `readSeek_read` | Read anchored text by range, symbol, or map; read images and PDFs |
|
|
22
|
+
| `readSeek_edit` | Apply hash-verified edits to an existing text file |
|
|
23
|
+
| `readSeek_write` | Create or replace a complete text file and return anchors |
|
|
24
|
+
| `readSeek_grep` | Search text or regex and return edit-ready anchors |
|
|
25
|
+
| `readSeek_search` | Search AST patterns |
|
|
26
|
+
| `readSeek_def` | Find symbol definitions |
|
|
27
|
+
| `readSeek_refs` | Find identifier usages, optionally scoped to a cursor binding |
|
|
28
|
+
| `readSeek_hover` | Identify the token and enclosing symbol at a cursor |
|
|
29
|
+
| `readSeek_rename` | Rename a cursor symbol; set `apply: false` to preview the plan |
|
|
30
|
+
| `readSeek_check` | Report parser errors and missing syntax |
|
|
31
|
+
| `readSeek_view` | View or narrow a structural PDF index |
|
|
32
|
+
|
|
33
|
+
The extension also tells Pi to get fresh anchors before editing and to run a
|
|
34
|
+
syntax check after source edits.
|
|
30
35
|
|
|
31
36
|
## Settings
|
|
32
37
|
|
|
33
|
-
Add
|
|
34
|
-
`.pi/settings.json` (project). Project settings
|
|
38
|
+
Add a `readseek` object to `~/.pi/agent/settings.json` (global) or
|
|
39
|
+
`.pi/settings.json` (project). Project settings override matching global values.
|
|
40
|
+
Defaults:
|
|
35
41
|
|
|
36
42
|
```json
|
|
37
43
|
{
|
|
@@ -54,24 +60,32 @@ Add an optional `readseek` section to `~/.pi/agent/settings.json` (global) or
|
|
|
54
60
|
}
|
|
55
61
|
```
|
|
56
62
|
|
|
57
|
-
- `replacedTools`:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
- `
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
- `replacedTools`: any of `"read"`, `"edit"`, `"write"`, and `"grep"`.
|
|
64
|
+
- `imageMode`: `"auto"` uses Pi's native image input when available, `"on"`
|
|
65
|
+
always runs local analysis, and `"off"` skips images while still reading PDF
|
|
66
|
+
text. Standalone images require `image`; values are `all`, `ocr`, `caption`, and
|
|
67
|
+
`objects`. In `"auto"`, `none` returns a prepared standalone image without local
|
|
68
|
+
analysis. Local analysis uses
|
|
69
|
+
[Qwen3-VL-2B-Instruct](../../docs/models/qwen3-vl-2b-instruct.md).
|
|
70
|
+
- `syntaxValidation`: `"warn"` (write and warn), `"block"` (abort), or `"off"`.
|
|
71
|
+
Validation triggers only when an edit increases parser error or missing-node
|
|
72
|
+
counts.
|
|
73
|
+
- `timeoutMs`: native command timeout in milliseconds.
|
|
74
|
+
- `grep.maxLines` and `grep.maxBytes`: output limits; larger values are clamped
|
|
75
|
+
to the defaults.
|
|
76
|
+
- `display`: initial `"compact"` or `"expanded"` state for `read`, `grep`,
|
|
77
|
+
`edit`, and `write` results.
|
|
78
|
+
|
|
79
|
+
## Development
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
npm install
|
|
83
|
+
npm test
|
|
84
|
+
npm run typecheck
|
|
85
|
+
```
|
|
72
86
|
|
|
73
|
-
##
|
|
87
|
+
## License
|
|
74
88
|
|
|
75
|
-
`pi-readseek` is
|
|
89
|
+
`pi-readseek` is Apache-2.0; see [LICENSE](LICENSE).
|
|
76
90
|
`@jarkkojs/readseek` is licensed separately under
|
|
77
|
-
|
|
91
|
+
Apache-2.0 AND LGPL-2.1-or-later.
|
package/dist/index.ts
CHANGED
|
@@ -15,7 +15,7 @@ var REPLACEABLE_TOOL_GUIDELINES = {
|
|
|
15
15
|
"read.md": {
|
|
16
16
|
readSeekName: "readSeek_read",
|
|
17
17
|
builtInName: "read",
|
|
18
|
-
benefit: "it
|
|
18
|
+
benefit: "it returns LINE:HASH anchors for safe edits."
|
|
19
19
|
},
|
|
20
20
|
"edit.md": {
|
|
21
21
|
readSeekName: "readSeek_edit",
|
|
@@ -25,7 +25,7 @@ var REPLACEABLE_TOOL_GUIDELINES = {
|
|
|
25
25
|
"grep.md": {
|
|
26
26
|
readSeekName: "readSeek_grep",
|
|
27
27
|
builtInName: "grep",
|
|
28
|
-
benefit: "it returns
|
|
28
|
+
benefit: "it returns LINE:HASH anchors."
|
|
29
29
|
},
|
|
30
30
|
"write.md": {
|
|
31
31
|
readSeekName: "readSeek_write",
|
|
@@ -35,23 +35,22 @@ var REPLACEABLE_TOOL_GUIDELINES = {
|
|
|
35
35
|
};
|
|
36
36
|
var COMPACT_GUIDELINES = {
|
|
37
37
|
"read.md": [
|
|
38
|
-
"Use readSeek_read map or symbol
|
|
38
|
+
"Use readSeek_read with map or symbol to inspect large files without reading them in full."
|
|
39
39
|
],
|
|
40
40
|
"edit.md": [
|
|
41
|
-
"
|
|
41
|
+
"Prefer set_line, replace_lines, and insert_after; use replace only when anchors are impractical."
|
|
42
42
|
],
|
|
43
43
|
"grep.md": [
|
|
44
|
-
"Use readSeek_grep summary
|
|
44
|
+
"Use readSeek_grep with summary first for broad searches, then narrow by path, glob, or pattern."
|
|
45
45
|
],
|
|
46
46
|
"write.md": [
|
|
47
|
-
"Use anchored edits rather than readSeek_write for small changes or appends
|
|
47
|
+
"Use anchored edits rather than readSeek_write for small changes or appends."
|
|
48
48
|
],
|
|
49
49
|
"search.md": [
|
|
50
|
-
"Use readSeek_search for
|
|
50
|
+
"Use readSeek_search for AST patterns; use readSeek_grep for plain text."
|
|
51
51
|
],
|
|
52
52
|
"refs.md": [
|
|
53
|
-
"Use readSeek_refs
|
|
54
|
-
"Use readSeek_refs with scope plus line/column to follow a specific binding instead of every same-named identifier."
|
|
53
|
+
"Use readSeek_refs before changing a symbol; add scope plus line/column to follow one binding."
|
|
55
54
|
]
|
|
56
55
|
};
|
|
57
56
|
function loadPrompt(promptUrl) {
|
|
@@ -3661,21 +3660,21 @@ function registerReadTool(pi, options = {}) {
|
|
|
3661
3660
|
const imageModes = imageMode === "auto" ? ["none", "all", "ocr", "caption", "objects"] : ["all", "ocr", "caption", "objects"];
|
|
3662
3661
|
const promptMetadata = defineToolPromptMetadata({
|
|
3663
3662
|
promptUrl: new URL("../prompts/read.md", import.meta.url),
|
|
3664
|
-
promptSnippet: "Read anchored text, symbols, maps, images, or PDFs",
|
|
3663
|
+
promptSnippet: imageMode === "off" ? "Read anchored text, symbols, maps, or PDF text" : "Read anchored text, symbols, maps, images, or PDFs",
|
|
3665
3664
|
registeredName: name
|
|
3666
3665
|
});
|
|
3667
3666
|
const tool = registerReadSeekTool(pi, {
|
|
3668
3667
|
name,
|
|
3669
3668
|
label: "Read",
|
|
3670
|
-
description: imageMode === "off" ?
|
|
3669
|
+
description: imageMode === "off" ? "Read anchored text by range, symbol, or map. Images are disabled; PDFs still return text." : promptMetadata.description,
|
|
3671
3670
|
promptSnippet: promptMetadata.promptSnippet,
|
|
3672
3671
|
promptGuidelines: [
|
|
3673
3672
|
...promptMetadata.promptGuidelines,
|
|
3674
|
-
imageMode === "
|
|
3673
|
+
...imageMode === "auto" ? ["Image-capable Pi models receive prepared images directly. For standalone images, image=none skips local analysis; other modes use ReadSeek when native vision is unavailable."] : []
|
|
3675
3674
|
],
|
|
3676
3675
|
parameters: Type2.Object({
|
|
3677
3676
|
path: filePathParam(),
|
|
3678
|
-
offset: optionalIntOrString("
|
|
3677
|
+
offset: optionalIntOrString("One-based starting line"),
|
|
3679
3678
|
limit: optionalIntOrString("Maximum lines to return"),
|
|
3680
3679
|
page: optionalIntOrString("One-based PDF page; defaults to 1"),
|
|
3681
3680
|
symbol: Type2.Optional(Type2.String({ description: "Symbol name to read" })),
|
|
@@ -3685,7 +3684,7 @@ function registerReadTool(pi, options = {}) {
|
|
|
3685
3684
|
})),
|
|
3686
3685
|
...imageMode === "off" ? {} : {
|
|
3687
3686
|
image: Type2.Optional(Type2.Union(imageModes.map((mode) => Type2.Literal(mode)), {
|
|
3688
|
-
description: `Standalone
|
|
3687
|
+
description: `Standalone/PDF-embedded image mode: ${imageModes.join(", ")}. Required for standalone images.${imageMode === "auto" ? " For standalone images, none skips local analysis." : ""}`
|
|
3689
3688
|
}))
|
|
3690
3689
|
}
|
|
3691
3690
|
}),
|
|
@@ -4793,20 +4792,43 @@ function pendingPreviewLines(summary, preview, expanded) {
|
|
|
4793
4792
|
const headerLine = summaryLine(preview.data.headerLabel, { hidden: !expanded });
|
|
4794
4793
|
return { lines: [summary, headerLine], diffData: expanded ? diffData : undefined, headerLabel: preview.data.headerLabel };
|
|
4795
4794
|
}
|
|
4796
|
-
var hashlineEditItemSchema = Type3.
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4795
|
+
var hashlineEditItemSchema = Type3.Object({
|
|
4796
|
+
set_line: Type3.Optional(Type3.Object({
|
|
4797
|
+
anchor: Type3.String({ description: "Fresh LINE:HASH anchor for the line to replace" }),
|
|
4798
|
+
new_text: Type3.String({ description: "Replacement text; use an empty string to delete the line" })
|
|
4799
|
+
}, { description: 'Replace one line: {"set_line":{"anchor":"LINE:HASH","new_text":"..."}}' })),
|
|
4800
|
+
replace_lines: Type3.Optional(Type3.Object({
|
|
4801
|
+
start_anchor: Type3.String({ description: "Fresh LINE:HASH anchor for the first line in the range" }),
|
|
4802
|
+
end_anchor: Type3.String({ description: "Fresh LINE:HASH anchor for the last line in the range" }),
|
|
4803
|
+
new_text: Type3.String({ description: "Replacement text; use an empty string to delete the range" })
|
|
4804
|
+
}, { description: 'Replace a range: {"replace_lines":{"start_anchor":"LINE:HASH","end_anchor":"LINE:HASH","new_text":"..."}}' })),
|
|
4805
|
+
insert_after: Type3.Optional(Type3.Object({
|
|
4806
|
+
anchor: Type3.String({ description: "Fresh LINE:HASH anchor for the line after which to insert" }),
|
|
4807
|
+
new_text: Type3.String({ description: "Text to insert after the anchored line" })
|
|
4808
|
+
}, { description: 'Insert text: {"insert_after":{"anchor":"LINE:HASH","new_text":"..."}}' })),
|
|
4809
|
+
replace: Type3.Optional(Type3.Object({
|
|
4810
|
+
old_text: Type3.String({ description: "Exact text to find" }),
|
|
4811
|
+
new_text: Type3.String({ description: "Replacement text" }),
|
|
4812
|
+
all: Type3.Optional(Type3.Boolean({ description: "Replace every exact match" })),
|
|
4813
|
+
fuzzy: Type3.Optional(Type3.Boolean({ description: "Allow unverified fuzzy matching when exact text is absent" }))
|
|
4814
|
+
}, { description: 'Replace text: {"replace":{"old_text":"...","new_text":"..."}}' })),
|
|
4815
|
+
replace_symbol: Type3.Optional(Type3.Object({
|
|
4816
|
+
symbol: Type3.String({ description: "Mapped symbol name" }),
|
|
4817
|
+
new_body: Type3.String({ description: "Complete replacement body for the symbol" })
|
|
4818
|
+
}, { description: 'Replace a symbol: {"replace_symbol":{"symbol":"name","new_body":"..."}}' }))
|
|
4819
|
+
}, {
|
|
4820
|
+
additionalProperties: false,
|
|
4821
|
+
minProperties: 1,
|
|
4822
|
+
maxProperties: 1,
|
|
4823
|
+
description: "Exactly one nested edit variant"
|
|
4824
|
+
});
|
|
4803
4825
|
var hashlineEditSchema = Type3.Object({
|
|
4804
4826
|
path: filePathParam(),
|
|
4805
4827
|
edits: Type3.Optional(Type3.Array(hashlineEditItemSchema, {
|
|
4806
|
-
description: "
|
|
4828
|
+
description: "Use set_line, replace_lines, insert_after, replace_symbol, or replace"
|
|
4807
4829
|
})),
|
|
4808
4830
|
postEditVerify: Type3.Optional(Type3.Boolean({
|
|
4809
|
-
description: "
|
|
4831
|
+
description: "Read back and verify persisted content"
|
|
4810
4832
|
}))
|
|
4811
4833
|
}, { additionalProperties: true });
|
|
4812
4834
|
function buildEditError(path2, code, message, hint, errorDetails) {
|
|
@@ -4860,7 +4882,12 @@ async function executeEdit(opts) {
|
|
|
4860
4882
|
}
|
|
4861
4883
|
for (let i = 0;i < edits.length; i++) {
|
|
4862
4884
|
throwIfAborted(signal);
|
|
4863
|
-
const
|
|
4885
|
+
const edit = edits[i];
|
|
4886
|
+
if (!edit || typeof edit !== "object" || Array.isArray(edit)) {
|
|
4887
|
+
const message = `edits[${i}] must be an object containing exactly one edit variant.`;
|
|
4888
|
+
return buildEditError(absolutePath, "invalid-edit-variant", message);
|
|
4889
|
+
}
|
|
4890
|
+
const e = edit;
|
|
4864
4891
|
if ((("old_text" in e) || ("new_text" in e)) && !("replace" in e)) {
|
|
4865
4892
|
const message = `edits[${i}] has top-level 'old_text'/'new_text'. Use {replace: {old_text, new_text}} or {set_line}, {replace_lines}, {insert_after}.`;
|
|
4866
4893
|
return buildEditError(absolutePath, "invalid-edit-variant", message);
|
|
@@ -4870,7 +4897,7 @@ async function executeEdit(opts) {
|
|
|
4870
4897
|
return buildEditError(absolutePath, "invalid-edit-variant", message);
|
|
4871
4898
|
}
|
|
4872
4899
|
const variantCount = Number("set_line" in e) + Number("replace_lines" in e) + Number("insert_after" in e) + Number("replace" in e) + Number("replace_symbol" in e);
|
|
4873
|
-
if (variantCount !== 1) {
|
|
4900
|
+
if (variantCount !== 1 || Object.keys(e).length !== 1) {
|
|
4874
4901
|
const message = `edits[${i}] must contain exactly one of: 'set_line', 'replace_lines', 'insert_after', 'replace', 'replace_symbol'. Got: [${Object.keys(e).join(", ")}].`;
|
|
4875
4902
|
return buildEditError(absolutePath, "invalid-edit-variant", message);
|
|
4876
4903
|
}
|
|
@@ -5202,7 +5229,7 @@ function registerEditTool(pi, options = {}) {
|
|
|
5202
5229
|
const name = options.name ?? "readSeek_edit";
|
|
5203
5230
|
const promptMetadata = defineToolPromptMetadata({
|
|
5204
5231
|
promptUrl: new URL("../prompts/edit.md", import.meta.url),
|
|
5205
|
-
promptSnippet: "
|
|
5232
|
+
promptSnippet: "Edit existing files with fresh LINE:HASH anchors",
|
|
5206
5233
|
registeredName: name,
|
|
5207
5234
|
toolAliases: options.toolAliases
|
|
5208
5235
|
});
|
|
@@ -5669,7 +5696,7 @@ function validateIgnoredRequiresOthers(tool, params) {
|
|
|
5669
5696
|
|
|
5670
5697
|
// src/grep.ts
|
|
5671
5698
|
var grepSchema = Type5.Object({
|
|
5672
|
-
pattern: Type5.String({ description: "Regex pattern;
|
|
5699
|
+
pattern: Type5.String({ description: "Regex pattern; set literal for exact text" }),
|
|
5673
5700
|
path: searchPathParam(),
|
|
5674
5701
|
glob: Type5.Optional(Type5.String({ description: "File-name glob, such as *.ts" })),
|
|
5675
5702
|
ignoreCase: Type5.Optional(Type5.Boolean({ description: "Ignore case" })),
|
|
@@ -6040,7 +6067,7 @@ function registerGrepTool(pi, options = {}) {
|
|
|
6040
6067
|
const name = options.name ?? "readSeek_grep";
|
|
6041
6068
|
const promptMetadata = defineToolPromptMetadata({
|
|
6042
6069
|
promptUrl: new URL("../prompts/grep.md", import.meta.url),
|
|
6043
|
-
promptSnippet: "Search
|
|
6070
|
+
promptSnippet: "Search text or regex with edit-ready LINE:HASH anchors",
|
|
6044
6071
|
registeredName: name
|
|
6045
6072
|
});
|
|
6046
6073
|
const tool = registerReadSeekTool(pi, {
|
|
@@ -6186,7 +6213,7 @@ function mergeRanges(ranges) {
|
|
|
6186
6213
|
}
|
|
6187
6214
|
var SEARCH_PROMPT_METADATA = defineToolPromptMetadata({
|
|
6188
6215
|
promptUrl: new URL("../prompts/search.md", import.meta.url),
|
|
6189
|
-
promptSnippet: "Search
|
|
6216
|
+
promptSnippet: "Search source code with AST patterns"
|
|
6190
6217
|
});
|
|
6191
6218
|
function linesFromSearchResult(result, ranges) {
|
|
6192
6219
|
const lineMap = new Map;
|
|
@@ -6295,7 +6322,7 @@ function registerSearchTool(pi, options = {}) {
|
|
|
6295
6322
|
promptSnippet: SEARCH_PROMPT_METADATA.promptSnippet,
|
|
6296
6323
|
promptGuidelines: SEARCH_PROMPT_METADATA.promptGuidelines,
|
|
6297
6324
|
parameters: Type6.Object({
|
|
6298
|
-
pattern: Type6.String({ description: "ast-grep
|
|
6325
|
+
pattern: Type6.String({ description: "AST pattern (ast-grep style), such as console.log($$$ARGS)" }),
|
|
6299
6326
|
lang: langParam(),
|
|
6300
6327
|
path: searchPathParam(),
|
|
6301
6328
|
...readSeekGitSearchParams()
|
|
@@ -6349,7 +6376,7 @@ function buildRefsOutput(input) {
|
|
|
6349
6376
|
// src/refs.ts
|
|
6350
6377
|
var REFS_PROMPT_METADATA = defineToolPromptMetadata({
|
|
6351
6378
|
promptUrl: new URL("../prompts/refs.md", import.meta.url),
|
|
6352
|
-
promptSnippet: "Find usages
|
|
6379
|
+
promptSnippet: "Find identifier usages or a cursor binding"
|
|
6353
6380
|
});
|
|
6354
6381
|
function refsLine(reference) {
|
|
6355
6382
|
return {
|
|
@@ -6431,8 +6458,8 @@ function registerRefsTool(pi, options = {}) {
|
|
|
6431
6458
|
path: searchPathParam(),
|
|
6432
6459
|
lang: langParam(),
|
|
6433
6460
|
scope: Type7.Optional(Type7.Boolean({ description: "Restrict results to the binding at the cursor" })),
|
|
6434
|
-
line: Type7.Optional(Type7.Number({ description: "
|
|
6435
|
-
column: Type7.Optional(Type7.Number({ description: "
|
|
6461
|
+
line: Type7.Optional(Type7.Number({ description: "One-based cursor line; required with scope" })),
|
|
6462
|
+
column: Type7.Optional(Type7.Number({ description: "One-based cursor byte column for disambiguation" })),
|
|
6436
6463
|
...readSeekGitSearchParams()
|
|
6437
6464
|
}),
|
|
6438
6465
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
@@ -6463,15 +6490,15 @@ import path5 from "node:path";
|
|
|
6463
6490
|
import { Text as Text6 } from "@earendil-works/pi-tui";
|
|
6464
6491
|
var RENAME_PROMPT_METADATA = defineToolPromptMetadata({
|
|
6465
6492
|
promptUrl: new URL("../prompts/rename.md", import.meta.url),
|
|
6466
|
-
promptSnippet: "Rename
|
|
6493
|
+
promptSnippet: "Rename a cursor symbol with verified edits"
|
|
6467
6494
|
});
|
|
6468
6495
|
var renameSchema = Type8.Object({
|
|
6469
6496
|
path: filePathParam(),
|
|
6470
|
-
line: Type8.Integer({ minimum: 1, description: "One-based line of the symbol to rename" }),
|
|
6471
|
-
column: Type8.Optional(Type8.Integer({ minimum: 1, description: "One-based byte column for disambiguation" })),
|
|
6497
|
+
line: Type8.Integer({ minimum: 1, description: "One-based cursor line of the symbol to rename" }),
|
|
6498
|
+
column: Type8.Optional(Type8.Integer({ minimum: 1, description: "One-based cursor byte column for disambiguation" })),
|
|
6472
6499
|
to: Type8.String({ description: "New symbol name" }),
|
|
6473
6500
|
workspace: Type8.Optional(Type8.Boolean({ description: "Rename across the project" })),
|
|
6474
|
-
apply: Type8.Optional(Type8.Boolean({ description: "Apply the verified edits;
|
|
6501
|
+
apply: Type8.Optional(Type8.Boolean({ description: "Apply the verified edits; defaults to true" }))
|
|
6475
6502
|
});
|
|
6476
6503
|
async function executeRename(opts) {
|
|
6477
6504
|
const { params, signal, cwd, onFileMutated } = opts;
|
|
@@ -6886,7 +6913,7 @@ function registerWriteTool(pi, options = {}) {
|
|
|
6886
6913
|
const name = options.name ?? "readSeek_write";
|
|
6887
6914
|
const promptMetadata = defineToolPromptMetadata({
|
|
6888
6915
|
promptUrl: new URL("../prompts/write.md", import.meta.url),
|
|
6889
|
-
promptSnippet: "Create or replace a complete file with
|
|
6916
|
+
promptSnippet: "Create or replace a complete file with LINE:HASH anchors",
|
|
6890
6917
|
registeredName: name
|
|
6891
6918
|
});
|
|
6892
6919
|
const tool = registerReadSeekTool(pi, {
|
|
@@ -6897,7 +6924,7 @@ function registerWriteTool(pi, options = {}) {
|
|
|
6897
6924
|
promptGuidelines: promptMetadata.promptGuidelines,
|
|
6898
6925
|
parameters: Type10.Object({
|
|
6899
6926
|
path: filePathParam(),
|
|
6900
|
-
content: Type10.String({ description: "Complete file content" }),
|
|
6927
|
+
content: Type10.String({ description: "Complete text file content" }),
|
|
6901
6928
|
map: mapParam()
|
|
6902
6929
|
}),
|
|
6903
6930
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
@@ -7002,7 +7029,7 @@ import { Type as Type11 } from "@sinclair/typebox";
|
|
|
7002
7029
|
import path6 from "node:path";
|
|
7003
7030
|
var DEF_PROMPT_METADATA = defineToolPromptMetadata({
|
|
7004
7031
|
promptUrl: new URL("../prompts/def.md", import.meta.url),
|
|
7005
|
-
promptSnippet: "Find
|
|
7032
|
+
promptSnippet: "Find symbol declarations by name"
|
|
7006
7033
|
});
|
|
7007
7034
|
async function executeDef(opts) {
|
|
7008
7035
|
const { params, signal, cwd, onFileAnchored } = opts;
|
|
@@ -7107,7 +7134,7 @@ import { Text as Text9 } from "@earendil-works/pi-tui";
|
|
|
7107
7134
|
import { Type as Type12 } from "@sinclair/typebox";
|
|
7108
7135
|
var CHECK_PROMPT_METADATA = defineToolPromptMetadata({
|
|
7109
7136
|
promptUrl: new URL("../prompts/check.md", import.meta.url),
|
|
7110
|
-
promptSnippet: "
|
|
7137
|
+
promptSnippet: "Run a quick syntax check on a source file"
|
|
7111
7138
|
});
|
|
7112
7139
|
async function executeCheck(opts) {
|
|
7113
7140
|
const { params, signal, cwd } = opts;
|
|
@@ -7200,7 +7227,7 @@ var NODE_KINDS = [
|
|
|
7200
7227
|
];
|
|
7201
7228
|
var VIEW_PROMPT_METADATA = defineToolPromptMetadata({
|
|
7202
7229
|
promptUrl: new URL("../prompts/view.md", import.meta.url),
|
|
7203
|
-
promptSnippet: "View
|
|
7230
|
+
promptSnippet: "View PDF structure or selected content"
|
|
7204
7231
|
});
|
|
7205
7232
|
async function executeView(opts) {
|
|
7206
7233
|
const { params, signal, cwd } = opts;
|
|
@@ -7262,11 +7289,11 @@ function registerViewTool(pi) {
|
|
|
7262
7289
|
parameters: Type13.Object({
|
|
7263
7290
|
path: filePathParam(),
|
|
7264
7291
|
node: Type13.Optional(Type13.String({ description: "Node ID to use as the view root" })),
|
|
7265
|
-
page: optionalIntOrString("One-based
|
|
7292
|
+
page: optionalIntOrString("One-based PDF page"),
|
|
7266
7293
|
kind: Type13.Optional(Type13.Union(NODE_KINDS.map((kind) => Type13.Literal(kind)), {
|
|
7267
7294
|
description: "Node kind filter"
|
|
7268
7295
|
})),
|
|
7269
|
-
depth: optionalIntOrString("Maximum depth below
|
|
7296
|
+
depth: optionalIntOrString("Maximum depth below selected roots"),
|
|
7270
7297
|
outline: Type13.Optional(Type13.Boolean({ description: "Return outline nodes only" }))
|
|
7271
7298
|
}),
|
|
7272
7299
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
@@ -7341,10 +7368,9 @@ function formatSettingsWarning(warning) {
|
|
|
7341
7368
|
function editingPolicy(readName, editName, writeName) {
|
|
7342
7369
|
return [
|
|
7343
7370
|
"ReadSeek editing policy:",
|
|
7344
|
-
`-
|
|
7345
|
-
`-
|
|
7346
|
-
"-
|
|
7347
|
-
"- Use readSeek_check after source edits for a quick syntax check."
|
|
7371
|
+
`- Read first with ${readName} when preparing to edit; ${editName} needs fresh LINE:HASH anchors.`,
|
|
7372
|
+
`- Use ${editName} for existing files, ${writeName} for whole-file creation or replacement, and readSeek_rename for symbol renames.`,
|
|
7373
|
+
"- Run readSeek_check after source edits for a quick syntax check."
|
|
7348
7374
|
].join(`
|
|
7349
7375
|
`);
|
|
7350
7376
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-readseek",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "Pi extension for
|
|
3
|
+
"version": "0.8.20",
|
|
4
|
+
"description": "Pi extension for LINE:HASH-anchored file operations and structural code navigation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./dist/index.ts"
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"node": ">=20.0.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@jarkkojs/readseek": "^0.8.
|
|
43
|
+
"@jarkkojs/readseek": "^0.8.20",
|
|
44
44
|
"diff": "^9.0.0",
|
|
45
45
|
"xxhash-wasm": "^1.1.0"
|
|
46
46
|
},
|
package/prompts/check.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
Run a quick syntax check on a source file. Use after edits to find parser errors and missing syntax; this is not a compiler or linter.
|
|
2
2
|
|
|
3
3
|
## Parameters
|
|
4
4
|
|
|
5
|
-
- `path` — source file
|
|
5
|
+
- `path` — source file.
|
|
6
6
|
|
|
7
7
|
## Output
|
|
8
8
|
|
package/prompts/def.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
Find symbol declarations by qualified or unqualified name. Use instead of text search when locating
|
|
1
|
+
Find symbol declarations by qualified or unqualified name. Use this instead of text search when locating a function, class, type, or other definition.
|
|
2
2
|
|
|
3
3
|
## Parameters
|
|
4
4
|
|
|
5
|
-
- `path` — file or directory, default `.`.
|
|
6
5
|
- `name` — qualified or unqualified symbol name.
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
6
|
+
- `path` — file or directory; defaults to the current directory.
|
|
7
|
+
- `lang` — language override when detection is ambiguous.
|
|
8
|
+
- `cached`, `others`, `ignored` — Git file selection; `ignored` requires
|
|
9
|
+
`others`.
|
|
9
10
|
|
|
10
|
-
After `readSeek_hover`,
|
|
11
|
+
After `readSeek_hover`, prefer its qualified symbol name.
|
package/prompts/edit.md
CHANGED
|
@@ -1,71 +1,68 @@
|
|
|
1
|
-
Edit existing text files
|
|
1
|
+
Edit existing text files with fresh `LINE:HASH` anchors. Read or search the file 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":"..."}}`.
|
|
2
2
|
|
|
3
|
-
Anchors come from `readSeek_read`, `readSeek_grep`, `readSeek_search`, or
|
|
3
|
+
Anchors come from `readSeek_read`, `readSeek_grep`, `readSeek_search`, or
|
|
4
|
+
`readSeek_write`.
|
|
4
5
|
|
|
5
6
|
## Variants
|
|
6
7
|
|
|
7
|
-
| Variant | Use |
|
|
8
|
-
|
|
9
|
-
| `set_line` | Replace or delete one line |
|
|
10
|
-
| `replace_lines` | Replace or delete one contiguous range |
|
|
11
|
-
| `insert_after` | Insert after
|
|
12
|
-
| `replace_symbol` | Replace one mapped symbol |
|
|
13
|
-
| `replace` |
|
|
8
|
+
| Variant | Use | Required anchor |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| `set_line` | Replace or delete one line | `anchor` |
|
|
11
|
+
| `replace_lines` | Replace or delete one contiguous range | `start_anchor`, `end_anchor` |
|
|
12
|
+
| `insert_after` | Insert after one line | `anchor` |
|
|
13
|
+
| `replace_symbol` | Replace one mapped symbol | `symbol` instead of an anchor |
|
|
14
|
+
| `replace` | Replace exact text; one match unless `all: true` | None |
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
anchored variants. Use `
|
|
16
|
+
Use `new_text: ""` to delete lines and `new_text: "\n"` for a blank line.
|
|
17
|
+
Prefer anchored variants. Use `replace_symbol` for a whole symbol and `replace`
|
|
18
|
+
only when anchors are impractical.
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
Each `edits[]` item contains exactly one variant. `new_text` and `new_body` are
|
|
21
|
+
plain file content, not a diff or hashline output.
|
|
19
22
|
|
|
20
23
|
```json
|
|
21
24
|
{
|
|
22
25
|
"path": "src/foo.ts",
|
|
23
26
|
"edits": [
|
|
24
27
|
{ "set_line": { "anchor": "42:ab1", "new_text": "const x = 2;" } },
|
|
25
|
-
{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
{
|
|
29
|
+
"replace_lines": {
|
|
30
|
+
"start_anchor": "50:c3d",
|
|
31
|
+
"end_anchor": "55:e4f",
|
|
32
|
+
"new_text": "const y = 3;\nreturn y;"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{ "insert_after": { "anchor": "60:f5a", "new_text": "// TODO\n" } }
|
|
29
36
|
]
|
|
30
37
|
}
|
|
31
38
|
```
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
and `new_body` are plain file content, not diffs or hashlines.
|
|
40
|
+
## Exact, fuzzy, and symbol replacement
|
|
35
41
|
|
|
36
|
-
|
|
42
|
+
`replace` is exact by default and fails when its text is absent. `fuzzy: true`
|
|
43
|
+
retries only after exact matching fails and normalizes whitespace plus
|
|
44
|
+
confusable Unicode. Verify any warned fuzzy match.
|
|
37
45
|
|
|
38
|
-
`
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
`replace_symbol` accepts `Name`, `Class.method`, or `Name@<line>` in a mappable
|
|
47
|
+
source file. `new_body` must be non-empty and unindented. Do not overlap a
|
|
48
|
+
symbol replacement with anchored edits.
|
|
41
49
|
|
|
42
|
-
##
|
|
50
|
+
## Stale anchors and validation
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
`Name@<line>` in any mappable source file. `new_body` must be non-empty and
|
|
46
|
-
unindented. Confirm fuzzy symbol matches first; do not overlap them with anchored
|
|
47
|
-
edits.
|
|
48
|
-
|
|
49
|
-
## Stale anchors
|
|
50
|
-
|
|
51
|
-
On `hash-mismatch`, nearby lines marked `>>>` include fresh anchors:
|
|
52
|
+
A `hash-mismatch` response marks nearby current lines with `>>>`, for example:
|
|
52
53
|
|
|
53
54
|
```text
|
|
54
55
|
>>> 41:b34| const renamed = 3;
|
|
55
56
|
```
|
|
56
57
|
|
|
57
|
-
Retry with those anchors
|
|
58
|
-
|
|
59
|
-
## Validation and warnings
|
|
60
|
-
|
|
61
|
-
All edits validate before writing; hard failures write nothing. Anchored edits run
|
|
62
|
-
bottom-up. `no-op` means no change. Syntax validation for every language with a
|
|
63
|
-
tree-sitter parser follows `readseek.syntaxValidation`: `warn` (default), `block`,
|
|
64
|
-
or `off`. It triggers when error or missing-node counts increase and reports the
|
|
65
|
-
post-edit diagnostic ranges.
|
|
58
|
+
Retry with those anchors or read/search again. Verify any automatic relocation
|
|
59
|
+
warning.
|
|
66
60
|
|
|
67
|
-
|
|
61
|
+
All edits validate before writing; a hard failure writes nothing. Anchored edits
|
|
62
|
+
run bottom-up. `no-op` means no content changed. For languages with a tree-sitter
|
|
63
|
+
parser, `readseek.syntaxValidation` controls newly introduced parse errors:
|
|
64
|
+
`warn` (default), `block`, or `off`.
|
|
68
65
|
|
|
69
|
-
`postEditVerify: true`
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
Set `postEditVerify: true` to read back the file and compare persisted content,
|
|
67
|
+
including its BOM and line endings. Verification returns a compact anchored
|
|
68
|
+
diff, unified patch, and structured `details.diffData`.
|
package/prompts/grep.md
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
Search
|
|
1
|
+
Search text or regex in files and return edit-ready `LINE:HASH` anchors. Use for identifiers, strings, configuration, errors, comments, and documentation.
|
|
2
2
|
|
|
3
3
|
## Modes
|
|
4
4
|
|
|
5
|
-
- Default: matching lines
|
|
6
|
-
- `context: N`: include N lines
|
|
7
|
-
|
|
8
|
-
- `
|
|
5
|
+
- Default: return matching lines as `path:>>LINE:HASH|content`.
|
|
6
|
+
- `context: N`: include N surrounding lines. Context rows use
|
|
7
|
+
`path: LINE:HASH|content`; overlapping ranges are merged.
|
|
8
|
+
- `summary: true`: return per-file counts only. Use this first for a broad
|
|
9
|
+
search, then narrow by `path`, `glob`, or pattern.
|
|
10
|
+
- `scope: "symbol"`: group matches by their enclosing symbol. By default the
|
|
11
|
+
full symbol is returned; `scopeContext: N` clips each match to ±N lines inside
|
|
12
|
+
it, and `0` returns only matching lines. `summary` ignores symbol scope.
|
|
9
13
|
|
|
10
14
|
## Parameters
|
|
11
15
|
|
|
12
|
-
- `pattern` — regular expression by default; set `literal: true` for exact text
|
|
13
|
-
- `path` — file or directory
|
|
16
|
+
- `pattern` — regular expression by default; set `literal: true` for exact text.
|
|
17
|
+
- `path` — file or directory; defaults to the current directory.
|
|
14
18
|
- `glob` — file-name filter such as `*.ts` or `**/*.test.ts`.
|
|
15
19
|
- `ignoreCase` — case-insensitive search.
|
|
16
|
-
- `context` — surrounding lines
|
|
17
|
-
- `limit` — maximum matches
|
|
18
|
-
- `summary` — counts
|
|
20
|
+
- `context` — surrounding lines in normal mode.
|
|
21
|
+
- `limit` — maximum matches; defaults to 100.
|
|
22
|
+
- `summary` — return counts without anchors.
|
|
19
23
|
- `scope` — only `"symbol"` is supported.
|
|
20
|
-
- `scopeContext` — non-negative context
|
|
24
|
+
- `scopeContext` — non-negative context inside symbol scope.
|
|
21
25
|
|
|
22
|
-
If
|
|
23
|
-
|
|
24
|
-
after narrowing.
|
|
26
|
+
If `limit` or the display budget truncates output, start with `summary`, narrow
|
|
27
|
+
the file set and pattern, then request context or symbol blocks.
|
package/prompts/hover.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
Identify the token and enclosing symbol at a cursor. Use before
|
|
1
|
+
Identify the token and enclosing symbol at a cursor. Use before definition lookup or rename, or to identify a line's enclosing symbol.
|
|
2
2
|
|
|
3
3
|
## Parameters
|
|
4
4
|
|
|
5
|
-
- `path
|
|
5
|
+
- `path` — source file.
|
|
6
|
+
- `line` — one-based cursor line.
|
|
6
7
|
- `column` — optional one-based cursor byte column.
|
package/prompts/read.md
CHANGED
|
@@ -1,45 +1,50 @@
|
|
|
1
|
-
Read anchored text by range,
|
|
1
|
+
Read anchored text by range, symbol, or map. Standalone images require an explicit mode; PDF text is always returned.
|
|
2
2
|
|
|
3
|
-
## Choose
|
|
3
|
+
## Choose a read
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
- `map: true`: append
|
|
5
|
+
- Default: read a small file or an `offset` / `limit` range.
|
|
6
|
+
- `map: true`: append the file's structural map.
|
|
7
7
|
- `symbol: "Name"`: read one mapped symbol.
|
|
8
|
-
- `bundle: "local"`: include
|
|
8
|
+
- `bundle: "local"`: include directly related symbols from the same file.
|
|
9
9
|
|
|
10
10
|
## Parameters
|
|
11
11
|
|
|
12
12
|
- `path` — file path.
|
|
13
|
-
- `offset` / `limit` — positive
|
|
14
|
-
- `map` — full-file map; incompatible with `symbol`
|
|
15
|
-
- `symbol` — `Name`, `Class.method`, or `Name@<line>`; incompatible with
|
|
13
|
+
- `offset` / `limit` — positive line numbers; `offset` is one-based.
|
|
14
|
+
- `map` — append a full-file map; incompatible with `symbol` and `bundle`.
|
|
15
|
+
- `symbol` — `Name`, `Class.method`, or `Name@<line>`; incompatible with
|
|
16
|
+
`offset` and `limit`.
|
|
16
17
|
- `bundle` — only `"local"`; requires `symbol` and excludes `map`.
|
|
17
|
-
- `image` —
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
18
|
+
- `image` — standalone-image/PDF embedded-image mode; unavailable when
|
|
19
|
+
`imageMode` is `"off"`.
|
|
20
|
+
- `page` — one-based PDF page; defaults to 1 and excludes `offset` / `limit`.
|
|
21
|
+
|
|
22
|
+
Text output is capped at {{DEFAULT_MAX_LINES}} lines or {{DEFAULT_MAX_BYTES}}.
|
|
23
|
+
A truncated full-file read appends a map when available; use its ranges for
|
|
24
|
+
follow-up reads.
|
|
25
|
+
|
|
26
|
+
Standalone images require `image`. In `"auto"`, `image: "none"` returns a
|
|
27
|
+
prepared standalone image without local analysis. PDF text is always read;
|
|
28
|
+
without `image`, embedded images are skipped unless an image-capable Pi model is
|
|
29
|
+
active in `"auto"` mode. That model receives prepared images directly.
|
|
30
|
+
|
|
31
|
+
## Symbol lookup
|
|
32
|
+
|
|
33
|
+
| Query | Result |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| `{"symbol":"processEvent"}` | Function or other unqualified symbol |
|
|
36
|
+
| `{"symbol":"EventEmitter"}` | Class, interface, type, enum, or similar symbol |
|
|
37
|
+
| `{"symbol":"EventEmitter.emit"}` | Qualified child method or member |
|
|
38
|
+
| `{"symbol":"Foo.bar@42"}` | Definition or overload near line 42 |
|
|
39
|
+
| `{"symbol":"handleRequest","bundle":"local"}` | Symbol plus direct same-file support |
|
|
40
|
+
|
|
41
|
+
`@<line>` is a trailing disambiguator; `foo@bar` remains an ordinary name.
|
|
42
|
+
Resolution prefers a containing range, then the nearest symbol at or after the
|
|
43
|
+
line, then one above it.
|
|
44
|
+
|
|
45
|
+
A successful lookup returns the symbol range. Ambiguous results include
|
|
46
|
+
`name@<startLine>` retry hints. Verify fuzzy matches before editing. A missing or
|
|
47
|
+
unmappable symbol falls back to a normal read with a warning.
|
|
48
|
+
|
|
49
|
+
Anchors from text, symbol, and bundled reads remain valid for `readSeek_edit`
|
|
50
|
+
until the file changes.
|
package/prompts/refs.md
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
|
-
Find identifier usages with enclosing symbols and edit-ready anchors.
|
|
1
|
+
Find identifier usages with enclosing symbols and edit-ready `LINE:HASH` anchors. Add cursor scope to follow one binding and exclude shadows.
|
|
2
2
|
|
|
3
3
|
## Parameters
|
|
4
4
|
|
|
5
|
-
- `name` — identifier to find
|
|
6
|
-
- `path` — file or directory
|
|
7
|
-
- `lang` — language
|
|
8
|
-
- `scope` — restrict results to the binding
|
|
9
|
-
|
|
10
|
-
- `
|
|
11
|
-
- `
|
|
12
|
-
- `
|
|
13
|
-
- `
|
|
5
|
+
- `name` — identifier to find.
|
|
6
|
+
- `path` — file or directory; defaults to the current directory.
|
|
7
|
+
- `lang` — language override for ambiguous, extensionless, or generated source.
|
|
8
|
+
- `scope` — restrict results to the binding at `line` / `column` in one file;
|
|
9
|
+
requires `line`.
|
|
10
|
+
- `line` — one-based cursor line used with `scope`.
|
|
11
|
+
- `column` — optional one-based cursor byte column used with `scope`.
|
|
12
|
+
- `cached` — search tracked/indexed files in a Git repository.
|
|
13
|
+
- `others` — search untracked files in a Git repository.
|
|
14
|
+
- `ignored` — include ignored untracked files; requires `others`.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
Without `scope`, results match by name. With `scope`, results follow the cursor
|
|
17
|
+
binding and exclude shadows.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## Git selection
|
|
22
|
-
|
|
23
|
-
In Git repositories, directory search includes tracked/indexed and untracked,
|
|
24
|
-
non-ignored files by default. `cached` or `others` restricts the search to that
|
|
25
|
-
group; `ignored` requires `others`.
|
|
19
|
+
In a Git work tree, directory search includes tracked/indexed and untracked
|
|
20
|
+
non-ignored files by default. Setting `cached` or `others` restricts the set;
|
|
21
|
+
`ignored` requires `others`.
|
package/prompts/rename.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
Rename the symbol at a cursor
|
|
1
|
+
Rename the symbol at a cursor while preserving resolvable same-named bindings. Set `apply: false` to preview the verified plan.
|
|
2
2
|
|
|
3
3
|
## Parameters
|
|
4
4
|
|
|
5
|
-
- `path
|
|
5
|
+
- `path` — source file containing the cursor.
|
|
6
|
+
- `line` — one-based cursor line.
|
|
6
7
|
- `column` — optional one-based cursor byte column.
|
|
7
|
-
- `
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
- `to` — new plain identifier.
|
|
9
|
+
- `workspace` — expand across the project. The cursor file remains binding-aware;
|
|
10
|
+
other files use name matching where binding resolution is unavailable.
|
|
11
|
+
- `apply` — defaults to `true`; set `false` to return only the verified plan.
|
package/prompts/search.md
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
Search
|
|
1
|
+
Search AST patterns (ast-grep style) and return edit-ready `LINE:HASH` anchors. Use `readSeek_grep` for plain text or regex.
|
|
2
2
|
|
|
3
3
|
## Parameters
|
|
4
4
|
|
|
5
|
-
- `pattern` —
|
|
6
|
-
- `
|
|
7
|
-
- `
|
|
8
|
-
-
|
|
9
|
-
- `
|
|
10
|
-
- `
|
|
5
|
+
- `pattern` — AST pattern to match.
|
|
6
|
+
- `path` — file or directory; defaults to the current directory.
|
|
7
|
+
- `lang` — language override for ambiguous, extensionless, generated, or
|
|
8
|
+
JSX-like source.
|
|
9
|
+
- `cached` — search tracked/indexed files in a Git repository.
|
|
10
|
+
- `others` — search untracked files in a Git repository.
|
|
11
|
+
- `ignored` — include ignored untracked files; requires `others`.
|
|
11
12
|
|
|
12
13
|
## Pattern syntax
|
|
13
14
|
|
|
14
15
|
- `$NAME` matches one AST node.
|
|
15
|
-
- `$_` matches
|
|
16
|
-
- `$$$ARGS` matches zero or more sibling nodes
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
group; `ignored` requires `others`.
|
|
16
|
+
- `$_` matches one node without capturing a reusable value.
|
|
17
|
+
- `$$$ARGS` matches zero or more sibling nodes, such as arguments, statements,
|
|
18
|
+
object fields, or JSX children.
|
|
19
|
+
- Reusing a metavariable requires every occurrence to match the same source text.
|
|
20
|
+
|
|
21
|
+
Patterns are code, not text. Formatting is mostly ignored, but syntax and
|
|
22
|
+
required punctuation must be valid for the selected language.
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
console.log($$$ARGS)
|
|
26
|
+
import $NAME from '$SOURCE'
|
|
27
|
+
export function $NAME($$$PARAMS) { $$$BODY }
|
|
28
|
+
$OBJ.$METHOD($$$ARGS)
|
|
29
|
+
<$TAG $$$ATTRS>$$$CHILDREN</$TAG>
|
|
30
|
+
if ($COND) { $$$BODY }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
In a Git work tree, directory search includes tracked/indexed and untracked
|
|
34
|
+
non-ignored files by default. Setting `cached` or `others` restricts the set;
|
|
35
|
+
`ignored` requires `others`.
|
package/prompts/view.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
View the structure or selected content of
|
|
1
|
+
View the structure or selected content of a PDF. Start with the overview, then narrow by page or node instead of reading the whole document.
|
|
2
2
|
|
|
3
3
|
## Parameters
|
|
4
4
|
|
|
5
|
-
- `path` — PDF
|
|
6
|
-
- `node` —
|
|
7
|
-
- `page` —
|
|
8
|
-
- `kind` —
|
|
9
|
-
- `depth` —
|
|
5
|
+
- `path` — PDF file.
|
|
6
|
+
- `node` — node ID to use as the view root.
|
|
7
|
+
- `page` — one-based PDF page.
|
|
8
|
+
- `kind` — node kind filter.
|
|
9
|
+
- `depth` — maximum depth below selected roots.
|
|
10
10
|
- `outline` — return outline nodes only.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
A `.readseek/` directory must already exist; run `readseek init` if needed. The
|
|
13
|
+
first call then creates a reusable structural index. Output is a bounded text
|
|
14
|
+
projection with stable node IDs and source-page references.
|
package/prompts/write.md
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
Create or replace a complete file and return `LINE:HASH` anchors. Use
|
|
1
|
+
Create or replace a complete text file and return `LINE:HASH` anchors. Use anchored edits for small changes to an existing file.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Existing files are overwritten without confirmation. Binary-looking content is
|
|
6
|
-
rejected without writing.
|
|
3
|
+
Existing files are replaced without confirmation. Binary-looking content is
|
|
4
|
+
rejected before writing.
|
|
7
5
|
|
|
8
6
|
## Parameters
|
|
9
7
|
|
|
10
8
|
- `path` — file path.
|
|
11
|
-
- `content` — complete file
|
|
9
|
+
- `content` — complete file content.
|
|
12
10
|
- `map` — append a best-effort structural map.
|
|
13
11
|
|
|
14
12
|
## Output
|
|
15
13
|
|
|
16
|
-
Text
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
diff, unified patch, and structured `details.diffData`.
|
|
14
|
+
Text output uses `LINE:HASH|content` and is capped at {{DEFAULT_MAX_LINES}} lines
|
|
15
|
+
or {{DEFAULT_MAX_BYTES}}. Complete anchors remain in `readSeekValue`. Results
|
|
16
|
+
also include a compact diff and structured `details.diffData`.
|