opencode-readseek 0.11.0 → 0.11.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.
- package/README.md +5 -0
- package/dist/index.js +241 -50
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -58,6 +58,11 @@ Use `at` selectors (`line:N[:COLUMN]`, `hash:H[:COLUMN]`, `symbol:NAME`,
|
|
|
58
58
|
`depth: 1`. Use separate structure, metadata, and syntax tools rather than
|
|
59
59
|
combining facets in a content request.
|
|
60
60
|
|
|
61
|
+
The four `show` tools return readable summaries and grouped text: anchored source
|
|
62
|
+
lines, document sections, structure trees, metadata fields, and asset paths.
|
|
63
|
+
Notices identify omitted ranges and how to continue. The unchanged native result
|
|
64
|
+
is retained separately in `metadata.readseek`; image attachments are unchanged.
|
|
65
|
+
|
|
61
66
|
`readseek_find_nodes` accepts `pattern`, `context` with `selector`, or `rule`.
|
|
62
67
|
`readseek_find_references` requires exactly one of `name` or `at`; binding
|
|
63
68
|
references and renames use line or hash cursors. KDL selection/check rules
|
package/dist/index.js
CHANGED
|
@@ -1028,6 +1028,221 @@ function serializeEditPlan(edits) {
|
|
|
1028
1028
|
throw new Error(validation.error);
|
|
1029
1029
|
return format(new Document([node("plan", {}, validation.edits.map(editNode))]));
|
|
1030
1030
|
}
|
|
1031
|
+
// ../readseek-api/src/show-presentation.ts
|
|
1032
|
+
function isShowTool(name) {
|
|
1033
|
+
return name === "show_content" || name === "show_structure" || name === "show_metadata" || name === "show_assets";
|
|
1034
|
+
}
|
|
1035
|
+
function record(value) {
|
|
1036
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1037
|
+
}
|
|
1038
|
+
function records(value) {
|
|
1039
|
+
return Array.isArray(value) ? value.map(record) : [];
|
|
1040
|
+
}
|
|
1041
|
+
function text(value) {
|
|
1042
|
+
return typeof value === "string" ? value : "";
|
|
1043
|
+
}
|
|
1044
|
+
function count(value) {
|
|
1045
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : undefined;
|
|
1046
|
+
}
|
|
1047
|
+
function safe(value) {
|
|
1048
|
+
return value.replace(/[\x00-\x09\x0b-\x1f\x7f-\x9f]/g, (char) => {
|
|
1049
|
+
if (char === "\t")
|
|
1050
|
+
return "\\t";
|
|
1051
|
+
if (char === "\r")
|
|
1052
|
+
return "\\r";
|
|
1053
|
+
return `\\x${char.charCodeAt(0).toString(16).padStart(2, "0")}`;
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
function inline(value) {
|
|
1057
|
+
return safe(text(value)).replaceAll(`
|
|
1058
|
+
`, "\\n");
|
|
1059
|
+
}
|
|
1060
|
+
function plural(n, unit) {
|
|
1061
|
+
return `${n} ${unit}${n === 1 ? "" : "s"}`;
|
|
1062
|
+
}
|
|
1063
|
+
function fields(value, omit = []) {
|
|
1064
|
+
return Object.entries(value).flatMap(([key, item]) => {
|
|
1065
|
+
if (omit.includes(key) || item === undefined || item === null || typeof item === "object")
|
|
1066
|
+
return [];
|
|
1067
|
+
const label = key.replaceAll("_", " ");
|
|
1068
|
+
return [`${label[0]?.toUpperCase() ?? ""}${label.slice(1)}: ${safe(String(item))}`];
|
|
1069
|
+
}).join(`
|
|
1070
|
+
`);
|
|
1071
|
+
}
|
|
1072
|
+
function location(value) {
|
|
1073
|
+
const start = text(value.start_anchor) || (count(value.start_line) !== undefined ? `${value.start_line}${text(value.start_hash) ? `:${value.start_hash}` : ""}` : "");
|
|
1074
|
+
const end = text(value.end_anchor) || (count(value.end_line) !== undefined ? `${value.end_line}${text(value.end_hash) ? `:${value.end_hash}` : ""}` : "");
|
|
1075
|
+
return start ? ` ${inline(start)}${end && end !== start ? ` - ${inline(end)}` : ""}` : "";
|
|
1076
|
+
}
|
|
1077
|
+
function sourceStructure(structure) {
|
|
1078
|
+
const sections = [];
|
|
1079
|
+
if (structure.root) {
|
|
1080
|
+
const lines = [];
|
|
1081
|
+
const stack = [{ node: record(structure.root), depth: 0 }];
|
|
1082
|
+
while (stack.length > 0) {
|
|
1083
|
+
const { node, depth } = stack.pop();
|
|
1084
|
+
lines.push(`${" ".repeat(Math.min(depth, 12))}${inline(node.kind) || "node"}${text(node.name) ? ` ${inline(node.name)}` : ""}${location(node)}`);
|
|
1085
|
+
const children = records(node.children);
|
|
1086
|
+
for (let i = children.length - 1;i >= 0; i--)
|
|
1087
|
+
stack.push({ node: children[i], depth: depth + 1 });
|
|
1088
|
+
}
|
|
1089
|
+
sections.push(`Tree
|
|
1090
|
+
${lines.join(`
|
|
1091
|
+
`)}`);
|
|
1092
|
+
}
|
|
1093
|
+
const symbols = records(structure.symbols);
|
|
1094
|
+
if (symbols.length > 0) {
|
|
1095
|
+
sections.push(`Symbols
|
|
1096
|
+
${symbols.map((symbol) => `${inline(symbol.kind) || "symbol"} ${inline(symbol.qualified_name || symbol.name)}${location(symbol)}`).join(`
|
|
1097
|
+
`)}`);
|
|
1098
|
+
}
|
|
1099
|
+
return sections.join(`
|
|
1100
|
+
|
|
1101
|
+
`) || "No structure found in this selection.";
|
|
1102
|
+
}
|
|
1103
|
+
function documentNodes(nodes, content) {
|
|
1104
|
+
const depths = new Map;
|
|
1105
|
+
return nodes.map((node) => {
|
|
1106
|
+
const depth = Math.min((depths.get(text(node.parent_id)) ?? -1) + 1, 12);
|
|
1107
|
+
depths.set(text(node.id), depth);
|
|
1108
|
+
const indent = " ".repeat(depth);
|
|
1109
|
+
const label = inline(node.title) || inline(node.kind) || "node";
|
|
1110
|
+
const page = count(node.page);
|
|
1111
|
+
const selector = text(node.id) ? `node:${inline(node.id)}` : "";
|
|
1112
|
+
const position = [selector, page !== undefined ? `page:${page}` : ""].filter(Boolean).join(" · ");
|
|
1113
|
+
const heading = `${indent}${label}${position ? ` [${position}]` : ""}`;
|
|
1114
|
+
const body = text(node.text);
|
|
1115
|
+
return content && body ? `${heading}
|
|
1116
|
+
${safe(body).split(`
|
|
1117
|
+
`).map((line) => indent + line).join(`
|
|
1118
|
+
`)}` : heading;
|
|
1119
|
+
}).join(content ? `
|
|
1120
|
+
|
|
1121
|
+
` : `
|
|
1122
|
+
`);
|
|
1123
|
+
}
|
|
1124
|
+
function assetList(assets) {
|
|
1125
|
+
return assets.map((asset) => {
|
|
1126
|
+
const id = text(asset.id);
|
|
1127
|
+
const page = count(asset.page);
|
|
1128
|
+
const heading = [id ? `asset:${inline(id)}` : inline(asset.kind) || "image", inline(asset.mime), page !== undefined ? `page:${page}` : ""].filter(Boolean).join(" · ");
|
|
1129
|
+
const details = fields(asset, ["id", "kind", "mime", "page", "bbox", "content_identity"]);
|
|
1130
|
+
return `${heading}${details ? `
|
|
1131
|
+
${details.split(`
|
|
1132
|
+
`).map((line) => ` ${line}`).join(`
|
|
1133
|
+
`)}` : ""}`;
|
|
1134
|
+
}).join(`
|
|
1135
|
+
|
|
1136
|
+
`);
|
|
1137
|
+
}
|
|
1138
|
+
function presentShowResult(tool, value, options = {}) {
|
|
1139
|
+
const output = record(value);
|
|
1140
|
+
const metadata = record(output.metadata);
|
|
1141
|
+
const content = record(output.content);
|
|
1142
|
+
const cursor = record(output.cursor);
|
|
1143
|
+
const structure = record(output.structure);
|
|
1144
|
+
const document = typeof output.format === "string" && (Array.isArray(output.nodes) || typeof output.source === "string");
|
|
1145
|
+
const path = inline(options.path || output.source || output.file || content.file || structure.file || metadata.file || cursor.file) || "(unknown path)";
|
|
1146
|
+
const summary = [];
|
|
1147
|
+
const result = { summary: "", body: "", notices: [], metadata: {} };
|
|
1148
|
+
if (tool === "show_metadata") {
|
|
1149
|
+
const data = Object.keys(metadata).length > 0 ? metadata : output;
|
|
1150
|
+
if (text(data.format || data.language || data.type))
|
|
1151
|
+
summary.push(inline(data.format || data.language || data.type));
|
|
1152
|
+
if (count(data.pages) !== undefined) {
|
|
1153
|
+
result.metadata.pages = data.pages;
|
|
1154
|
+
summary.push(plural(result.metadata.pages, "page"));
|
|
1155
|
+
}
|
|
1156
|
+
result.body = fields(data) || "No metadata available.";
|
|
1157
|
+
} else if (tool === "show_assets") {
|
|
1158
|
+
const assets = records(output.assets);
|
|
1159
|
+
result.metadata.assets = assets.length;
|
|
1160
|
+
summary.push(plural(assets.length, "asset"));
|
|
1161
|
+
result.body = assetList(assets) || "No assets in this selection.";
|
|
1162
|
+
} else if (document) {
|
|
1163
|
+
const nodes = records(output.nodes);
|
|
1164
|
+
const assets = records(output.assets);
|
|
1165
|
+
result.metadata.nodes = nodes.length;
|
|
1166
|
+
if (count(output.pages) !== undefined)
|
|
1167
|
+
result.metadata.pages = output.pages;
|
|
1168
|
+
summary.push(plural(nodes.length, "node"));
|
|
1169
|
+
if (result.metadata.pages !== undefined)
|
|
1170
|
+
summary.push(plural(result.metadata.pages, "page"));
|
|
1171
|
+
const sections = [text(output.title) ? safe(text(output.title)) : "", documentNodes(nodes, tool === "show_content")];
|
|
1172
|
+
if (assets.length > 0) {
|
|
1173
|
+
result.metadata.assets = assets.length;
|
|
1174
|
+
sections.push(`Assets
|
|
1175
|
+
${assetList(assets)}`);
|
|
1176
|
+
}
|
|
1177
|
+
result.body = sections.filter(Boolean).join(`
|
|
1178
|
+
|
|
1179
|
+
`) || "No content in this selection.";
|
|
1180
|
+
} else if (tool === "show_structure") {
|
|
1181
|
+
const symbols = records(structure.symbols);
|
|
1182
|
+
result.metadata.symbols = symbols.length;
|
|
1183
|
+
summary.push(plural(symbols.length, "symbol"));
|
|
1184
|
+
result.body = sourceStructure(structure);
|
|
1185
|
+
} else if (content.kind === "image" || count(content.width) !== undefined && count(content.height) !== undefined || count(metadata.width) !== undefined && count(metadata.height) !== undefined || text(content.mime).startsWith("image/") || text(metadata.mime).startsWith("image/") || text(metadata.type).startsWith("image/")) {
|
|
1186
|
+
const description = Object.keys(content).length > 0 ? content : Object.keys(metadata).length > 0 ? metadata : output;
|
|
1187
|
+
if (count(description.width) !== undefined && count(description.height) !== undefined) {
|
|
1188
|
+
summary.push(`${description.width} × ${description.height}`);
|
|
1189
|
+
} else if (count(metadata.width) !== undefined && count(metadata.height) !== undefined) {
|
|
1190
|
+
summary.push(`${metadata.width} × ${metadata.height}`);
|
|
1191
|
+
}
|
|
1192
|
+
const mime = text(description.mime || metadata.mime || metadata.type);
|
|
1193
|
+
if (mime)
|
|
1194
|
+
summary.push(inline(mime));
|
|
1195
|
+
result.body = fields(description, ["hashlines"]) || fields(metadata) || "No content in this selection.";
|
|
1196
|
+
} else if (Array.isArray(content.hashlines) || Array.isArray(cursor.hashlines)) {
|
|
1197
|
+
const lines = records(content.hashlines ?? cursor.hashlines);
|
|
1198
|
+
const start = count(content.start_line) ?? count(lines[0]?.line);
|
|
1199
|
+
const end = count(content.end_line) ?? count(lines.at(-1)?.line);
|
|
1200
|
+
const total = count(content.line_count) ?? count(cursor.line_count);
|
|
1201
|
+
if (start !== undefined && end !== undefined && start <= end) {
|
|
1202
|
+
result.metadata.start_line = start;
|
|
1203
|
+
result.metadata.end_line = end;
|
|
1204
|
+
summary.push(`lines ${start}-${end}${total !== undefined ? ` of ${total}` : ""}`);
|
|
1205
|
+
} else
|
|
1206
|
+
summary.push(plural(lines.length, "line"));
|
|
1207
|
+
const lang = text(metadata.language || content.language);
|
|
1208
|
+
if (lang)
|
|
1209
|
+
summary.push(inline(lang));
|
|
1210
|
+
const rows = lines.map((line) => `${line.line}${options.noAnchors ? "" : `:${text(line.hash)}`} | ${safe(text(line.text)).replaceAll("\\n", "\\\\n")}`);
|
|
1211
|
+
const identifier = record(cursor.identifier);
|
|
1212
|
+
if (count(cursor.line) !== undefined)
|
|
1213
|
+
result.metadata.line = cursor.line;
|
|
1214
|
+
if (count(cursor.column) !== undefined)
|
|
1215
|
+
result.metadata.column = cursor.column;
|
|
1216
|
+
if (Object.keys(cursor).length > 0) {
|
|
1217
|
+
const symbol = record(cursor.symbol);
|
|
1218
|
+
const description = [text(identifier.text), text(symbol.qualified_name || symbol.name), text(symbol.kind)].filter(Boolean);
|
|
1219
|
+
rows.unshift(`Cursor: ${cursor.line ?? "?"}:${cursor.column ?? "?"}${description.length > 0 ? ` · ${[...new Set(description)].map(inline).join(" · ")}` : ""}`, "");
|
|
1220
|
+
}
|
|
1221
|
+
result.body = rows.join(`
|
|
1222
|
+
`) || "Empty source selection.";
|
|
1223
|
+
if (start !== undefined && start > 1)
|
|
1224
|
+
result.notices.push(`Earlier lines omitted. Read preceding content with at: line:1 and limit: ${start - 1}.`);
|
|
1225
|
+
if (end !== undefined && total !== undefined && end < total) {
|
|
1226
|
+
result.notices.push(`More lines available. Continue with at: line:${end + 1}.`);
|
|
1227
|
+
} else if (content.truncated === true && (end === undefined || total === undefined)) {
|
|
1228
|
+
result.notices.push(`Content is truncated.${end !== undefined ? ` Continue with at: line:${end + 1}.` : " Select a smaller range with at and limit."}`);
|
|
1229
|
+
}
|
|
1230
|
+
} else {
|
|
1231
|
+
const description = Object.keys(content).length > 0 ? content : output;
|
|
1232
|
+
result.body = fields(description) || "No content in this selection.";
|
|
1233
|
+
}
|
|
1234
|
+
if (tool === "show_structure")
|
|
1235
|
+
result.notices.push("Structure is limited to the requested depth, kind, and outline. Use a deeper depth or focus with at to inspect further.");
|
|
1236
|
+
if (text(output.warning))
|
|
1237
|
+
result.notices.push(safe(text(output.warning)));
|
|
1238
|
+
result.summary = summary.join(" · ") || "complete";
|
|
1239
|
+
return result;
|
|
1240
|
+
}
|
|
1241
|
+
function formatShowResult(presentation) {
|
|
1242
|
+
return [presentation.summary, presentation.body, ...presentation.notices.map((notice) => `Note: ${notice}`)].filter(Boolean).join(`
|
|
1243
|
+
|
|
1244
|
+
`);
|
|
1245
|
+
}
|
|
1031
1246
|
// ../readseek-api/src/platform.ts
|
|
1032
1247
|
import { accessSync, constants as fsConstants, existsSync, statSync } from "node:fs";
|
|
1033
1248
|
import { createRequire } from "node:module";
|
|
@@ -1581,7 +1796,7 @@ import path4 from "node:path";
|
|
|
1581
1796
|
function render(value) {
|
|
1582
1797
|
return JSON.stringify(value, null, 2);
|
|
1583
1798
|
}
|
|
1584
|
-
function
|
|
1799
|
+
function record2(value) {
|
|
1585
1800
|
return value && typeof value === "object" ? value : {};
|
|
1586
1801
|
}
|
|
1587
1802
|
function items(value) {
|
|
@@ -1606,19 +1821,19 @@ function collectAnchoredFiles(value, files) {
|
|
|
1606
1821
|
return;
|
|
1607
1822
|
const output = value;
|
|
1608
1823
|
const hashlines = output.hashlines;
|
|
1609
|
-
if (typeof output.file === "string" && Array.isArray(hashlines) && hashlines.some((line) => typeof
|
|
1824
|
+
if (typeof output.file === "string" && Array.isArray(hashlines) && hashlines.some((line) => typeof record2(line).line === "number" && typeof record2(line).hash === "string"))
|
|
1610
1825
|
files.add(output.file);
|
|
1611
1826
|
for (const item of Object.values(output))
|
|
1612
1827
|
collectAnchoredFiles(item, files);
|
|
1613
1828
|
}
|
|
1614
1829
|
function renameFiles(value, directory = process.cwd()) {
|
|
1615
|
-
const output =
|
|
1830
|
+
const output = record2(value);
|
|
1616
1831
|
const files = [];
|
|
1617
1832
|
if (typeof output.file === "string" && items(output.edits).length > 0) {
|
|
1618
1833
|
files.push(path4.resolve(directory, output.file));
|
|
1619
1834
|
}
|
|
1620
1835
|
for (const other of items(output.others)) {
|
|
1621
|
-
const item =
|
|
1836
|
+
const item = record2(other);
|
|
1622
1837
|
if (typeof item.file === "string" && items(item.edits).length > 0) {
|
|
1623
1838
|
files.push(path4.resolve(directory, item.file));
|
|
1624
1839
|
}
|
|
@@ -1675,7 +1890,7 @@ function contentArgs(filePath, options = {}) {
|
|
|
1675
1890
|
return buildShowContentArgs({ path: filePath, ...options, at: options.at ?? (options.end === undefined ? undefined : "line:1") });
|
|
1676
1891
|
}
|
|
1677
1892
|
function requireContent(envelope) {
|
|
1678
|
-
const value =
|
|
1893
|
+
const value = record2(envelope).content;
|
|
1679
1894
|
if (value === undefined || value === null || typeof value !== "object") {
|
|
1680
1895
|
throw new Error("show content returned no source content");
|
|
1681
1896
|
}
|
|
@@ -2200,52 +2415,27 @@ function initialTitle(kind, args) {
|
|
|
2200
2415
|
}
|
|
2201
2416
|
}
|
|
2202
2417
|
function resultPresentation(kind, args, value) {
|
|
2203
|
-
const output =
|
|
2418
|
+
const output = record2(value);
|
|
2419
|
+
if (isShowTool(kind)) {
|
|
2420
|
+
const presentation = presentShowResult(kind, value, args);
|
|
2421
|
+
return { title: presentation.summary, metadata: presentation.metadata };
|
|
2422
|
+
}
|
|
2204
2423
|
switch (kind) {
|
|
2205
|
-
case "show_assets":
|
|
2206
|
-
return { title: `Assets ${args.path}`, metadata: {} };
|
|
2207
|
-
case "show_structure": {
|
|
2208
|
-
const symbols = items(record(output.structure).symbols).length;
|
|
2209
|
-
return { title: `Structure ${args.path} (${symbols} symbols)`, metadata: { symbols } };
|
|
2210
|
-
}
|
|
2211
2424
|
case "check_syntax": {
|
|
2212
|
-
const diagnostics =
|
|
2425
|
+
const diagnostics = record2(output.diagnostics ?? output);
|
|
2213
2426
|
const errors = typeof diagnostics.error_count === "number" ? diagnostics.error_count : 0;
|
|
2214
2427
|
const missing = typeof diagnostics.missing_count === "number" ? diagnostics.missing_count : 0;
|
|
2215
2428
|
return { title: `Syntax ${args.path} (${errors} errors, ${missing} missing)`, metadata: { error_count: errors, missing_count: missing } };
|
|
2216
2429
|
}
|
|
2217
|
-
case "show_content": {
|
|
2218
|
-
const identity = record(output.cursor);
|
|
2219
|
-
const content = record(output.content);
|
|
2220
|
-
const metadata = {};
|
|
2221
|
-
const summary = [];
|
|
2222
|
-
if (output.cursor !== undefined) {
|
|
2223
|
-
if (typeof identity.line === "number")
|
|
2224
|
-
metadata.line = identity.line;
|
|
2225
|
-
if (typeof identity.column === "number")
|
|
2226
|
-
metadata.column = identity.column;
|
|
2227
|
-
const identifier = record(identity.identifier).text;
|
|
2228
|
-
if (typeof identifier === "string")
|
|
2229
|
-
summary.push(identifier);
|
|
2230
|
-
}
|
|
2231
|
-
if (typeof content.start_line === "number")
|
|
2232
|
-
metadata.start_line = content.start_line;
|
|
2233
|
-
if (typeof content.end_line === "number")
|
|
2234
|
-
metadata.end_line = content.end_line;
|
|
2235
|
-
return {
|
|
2236
|
-
title: summary.length > 0 ? `Read ${args.path} (${summary.join(", ")})` : `Read ${args.path}`,
|
|
2237
|
-
metadata
|
|
2238
|
-
};
|
|
2239
|
-
}
|
|
2240
2430
|
case "find_nodes": {
|
|
2241
2431
|
const results = items(output.results);
|
|
2242
|
-
const matches = results.reduce((total, result) => total + items(
|
|
2432
|
+
const matches = results.reduce((total, result) => total + items(record2(result).matches).length, 0);
|
|
2243
2433
|
return { title: `Found ${matches} matches`, metadata: { results: results.length, matches } };
|
|
2244
2434
|
}
|
|
2245
2435
|
case "find_text": {
|
|
2246
2436
|
const results = items(output.results);
|
|
2247
2437
|
const matches = results.reduce((total, result) => {
|
|
2248
|
-
const entry =
|
|
2438
|
+
const entry = record2(result);
|
|
2249
2439
|
return total + (typeof entry.count === "number" ? entry.count : items(entry.matches).length);
|
|
2250
2440
|
}, 0);
|
|
2251
2441
|
return { title: `Found ${matches} matches`, metadata: { results: results.length, matches } };
|
|
@@ -2261,7 +2451,7 @@ function resultPresentation(kind, args, value) {
|
|
|
2261
2451
|
case "rename_symbol": {
|
|
2262
2452
|
const oldName = output.old_name;
|
|
2263
2453
|
const newName = output.new_name;
|
|
2264
|
-
const otherOutputs = items(output.others).map(
|
|
2454
|
+
const otherOutputs = items(output.others).map(record2);
|
|
2265
2455
|
const edits = otherOutputs.reduce((total, item) => total + items(item.edits).length, items(output.edits).length);
|
|
2266
2456
|
const conflicts = otherOutputs.reduce((total, item) => total + items(item.conflicts).length, items(output.conflicts).length);
|
|
2267
2457
|
const others = otherOutputs.length;
|
|
@@ -2302,11 +2492,12 @@ function readseekTool(description, args, kind, execute, imagePolicy) {
|
|
|
2302
2492
|
if (imagePolicy !== "off")
|
|
2303
2493
|
attachments.push({ type: "file", mime, url: pathToFileURL(path).href });
|
|
2304
2494
|
}
|
|
2495
|
+
const displayResult = imagePolicy === "off" && imagePaths.size > 0 ? { ...record2(result), warning: "Image attachments are disabled; use the returned paths to view the images." } : result;
|
|
2305
2496
|
return {
|
|
2306
2497
|
...attachments.length > 0 ? { attachments } : {},
|
|
2307
2498
|
title: presentation.title,
|
|
2308
|
-
output:
|
|
2309
|
-
metadata: presentation.metadata
|
|
2499
|
+
output: isShowTool(kind) ? formatShowResult(presentShowResult(kind, displayResult, args)) : render(displayResult),
|
|
2500
|
+
metadata: { ...presentation.metadata, ...isShowTool(kind) ? { readseek: result } : {} }
|
|
2310
2501
|
};
|
|
2311
2502
|
}
|
|
2312
2503
|
});
|
|
@@ -2400,16 +2591,16 @@ function createReadSeekTools(imagePolicy) {
|
|
|
2400
2591
|
}
|
|
2401
2592
|
const linesByNumber = new Map;
|
|
2402
2593
|
for (const [start, end] of mergedRanges) {
|
|
2403
|
-
const output =
|
|
2594
|
+
const output = record2(await runContent(context, readRangeArgs(filePath, start, end)));
|
|
2404
2595
|
for (const hashline of items(output.hashlines)) {
|
|
2405
|
-
const line =
|
|
2596
|
+
const line = record2(hashline).line;
|
|
2406
2597
|
if (typeof line === "number" && !linesByNumber.has(line))
|
|
2407
2598
|
linesByNumber.set(line, hashline);
|
|
2408
2599
|
}
|
|
2409
2600
|
}
|
|
2410
2601
|
const hashlines = [...linesByNumber.values()];
|
|
2411
2602
|
const matches = hashlines.filter((hashline) => {
|
|
2412
|
-
const line =
|
|
2603
|
+
const line = record2(hashline).line;
|
|
2413
2604
|
return typeof line === "number" && matchLines.has(line);
|
|
2414
2605
|
});
|
|
2415
2606
|
results.push({ file: filePath, matches, hashlines });
|
|
@@ -2494,7 +2685,7 @@ function createReadSeekTools(imagePolicy) {
|
|
|
2494
2685
|
await authorizeRead(context, filePath);
|
|
2495
2686
|
if (input.workspace) {
|
|
2496
2687
|
const envelope = await runReadSeek(context, contentArgs(filePath, { at: input.at }));
|
|
2497
|
-
const name = identifiedName(
|
|
2688
|
+
const name = identifiedName(record2(envelope).cursor);
|
|
2498
2689
|
if (!name)
|
|
2499
2690
|
throw new Error("readseek could not identify a binding at the rename cursor");
|
|
2500
2691
|
await authorizeSearch(context, context.directory, name);
|
|
@@ -2508,13 +2699,13 @@ function createReadSeekTools(imagePolicy) {
|
|
|
2508
2699
|
gitScope: input.gitScope
|
|
2509
2700
|
});
|
|
2510
2701
|
const plan = await runReadSeek(context, args);
|
|
2511
|
-
if (input.planHash !== undefined &&
|
|
2702
|
+
if (input.planHash !== undefined && record2(plan).plan_hash !== input.planHash) {
|
|
2512
2703
|
throw new Error("readseek rename plan does not match planHash");
|
|
2513
2704
|
}
|
|
2514
2705
|
if (input.apply === false)
|
|
2515
2706
|
return plan;
|
|
2516
2707
|
const files = renameFiles(plan, context.directory);
|
|
2517
|
-
const planHash =
|
|
2708
|
+
const planHash = record2(plan).plan_hash;
|
|
2518
2709
|
if (typeof planHash !== "string" || planHash.length === 0) {
|
|
2519
2710
|
throw new Error("readseek rename plan did not include a plan hash");
|
|
2520
2711
|
}
|
|
@@ -2588,7 +2779,7 @@ function createReadSeekTools(imagePolicy) {
|
|
|
2588
2779
|
gitScope: input.gitScope,
|
|
2589
2780
|
requestFromStdin: true
|
|
2590
2781
|
});
|
|
2591
|
-
const plan =
|
|
2782
|
+
const plan = record2(await runReadSeek(context, baseArgs, { stdin: request }));
|
|
2592
2783
|
if (typeof plan.before_content !== "string" || typeof plan.content !== "string" || typeof plan.plan_hash !== "string") {
|
|
2593
2784
|
throw new Error("readseek edit plan is missing before_content, content, or plan_hash");
|
|
2594
2785
|
}
|
|
@@ -2606,7 +2797,7 @@ function createReadSeekTools(imagePolicy) {
|
|
|
2606
2797
|
}
|
|
2607
2798
|
await authorizeEdit(context, [filePath], simpleDiff(filePath, before, after), false);
|
|
2608
2799
|
context.abort.throwIfAborted();
|
|
2609
|
-
const applied =
|
|
2800
|
+
const applied = record2(await runReadSeek(context, buildEditTextArgs({
|
|
2610
2801
|
path: filePath,
|
|
2611
2802
|
language: input.language,
|
|
2612
2803
|
gitScope: input.gitScope,
|
|
@@ -2776,7 +2967,7 @@ var ReadSeekPlugin = async (_input, options) => {
|
|
|
2776
2967
|
const result = JSON.parse(output.output);
|
|
2777
2968
|
if (input.tool === "readseek_rename_symbol") {
|
|
2778
2969
|
anchors.planRename(input.sessionID, result);
|
|
2779
|
-
if (
|
|
2970
|
+
if (record2(result).applied === true) {
|
|
2780
2971
|
for (const filePath of renameFiles(result))
|
|
2781
2972
|
anchors.forget(filePath);
|
|
2782
2973
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-readseek",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "OpenCode plugin for anchored file operations and structural code navigation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"node": ">=20.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@jarkkojs/readseek": "^0.11.
|
|
37
|
-
"@jarkkojs/readseek-api": "^0.11.
|
|
36
|
+
"@jarkkojs/readseek": "^0.11.2",
|
|
37
|
+
"@jarkkojs/readseek-api": "^0.11.2",
|
|
38
38
|
"@opencode-ai/plugin": "^1.18.18"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|