@shanepadgett/tau-agent 0.26.0 → 0.28.0
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/docs/subagents.md +1 -1
- package/extensions/appshot/README.md +1 -1
- package/extensions/appshot/index.ts +5 -11
- package/extensions/context/sync.ts +1 -9
- package/extensions/context-pruning/README.md +2 -2
- package/extensions/context-pruning/index.ts +58 -57
- package/extensions/context-pruning/prune.ts +2 -2
- package/extensions/context-pruning/render.ts +51 -39
- package/extensions/context-pruning/settings.ts +4 -5
- package/extensions/explore/README.md +13 -14
- package/extensions/explore/ast/adapter.ts +97 -0
- package/extensions/explore/ast/engine.ts +470 -0
- package/extensions/explore/ast/format/ast-search.ts +97 -0
- package/extensions/explore/ast/format/composite.ts +26 -0
- package/extensions/explore/ast/format/context.ts +66 -0
- package/extensions/explore/ast/format/deps.ts +86 -0
- package/extensions/explore/ast/format/discover.ts +85 -0
- package/extensions/explore/ast/format/impact.ts +105 -0
- package/extensions/explore/ast/format/outline.ts +66 -0
- package/extensions/explore/ast/format/relationships.ts +81 -0
- package/extensions/explore/ast/format/show.ts +38 -0
- package/extensions/explore/ast/grammars/kotlin.wasm +0 -0
- package/extensions/explore/ast/grammars/manifest.json +41 -0
- package/extensions/explore/ast/grammars/manifest.ts +99 -0
- package/extensions/explore/ast/grammars/odin.wasm +0 -0
- package/extensions/explore/ast/grammars/swift.wasm +0 -0
- package/extensions/explore/ast/graph/file-graph.ts +360 -0
- package/extensions/explore/ast/graph/relationships.ts +597 -0
- package/extensions/explore/ast/identity.ts +119 -0
- package/extensions/explore/ast/ir.ts +130 -0
- package/extensions/explore/ast/languages/csharp-file-deps.ts +189 -0
- package/extensions/explore/ast/languages/csharp.ts +493 -0
- package/extensions/explore/ast/languages/file-dep-util.ts +120 -0
- package/extensions/explore/ast/languages/fixtures/sample.cs +17 -0
- package/extensions/explore/ast/languages/fixtures/sample.java +21 -0
- package/extensions/explore/ast/languages/fixtures/sample.kt +15 -0
- package/extensions/explore/ast/languages/fixtures/sample.odin +28 -0
- package/extensions/explore/ast/languages/fixtures/sample.rs +31 -0
- package/extensions/explore/ast/languages/fixtures/sample.swift +25 -0
- package/extensions/explore/ast/languages/go-file-deps.ts +139 -0
- package/extensions/explore/ast/languages/go.ts +545 -0
- package/extensions/explore/ast/languages/java.ts +412 -0
- package/extensions/explore/ast/languages/jvm-file-deps.ts +217 -0
- package/extensions/explore/ast/languages/kotlin.ts +611 -0
- package/extensions/explore/ast/languages/odin-file-deps.ts +175 -0
- package/extensions/explore/ast/languages/odin.ts +407 -0
- package/extensions/explore/ast/languages/rust-file-deps.ts +159 -0
- package/extensions/explore/ast/languages/rust.ts +506 -0
- package/extensions/explore/ast/languages/swift-file-deps.ts +59 -0
- package/extensions/explore/ast/languages/swift.ts +466 -0
- package/extensions/explore/ast/languages/tree.ts +220 -0
- package/extensions/explore/ast/languages/typescript-file-deps.ts +259 -0
- package/extensions/explore/ast/languages/typescript-package-surface.ts +440 -0
- package/extensions/explore/ast/languages/typescript.ts +716 -0
- package/extensions/explore/ast/markdown.ts +145 -0
- package/extensions/explore/ast/package-surface.ts +42 -0
- package/extensions/explore/ast/queries/ast-search.ts +306 -0
- package/extensions/explore/ast/queries/composite-target.ts +77 -0
- package/extensions/explore/ast/queries/context.ts +406 -0
- package/extensions/explore/ast/queries/discover.ts +427 -0
- package/extensions/explore/ast/queries/impact.ts +250 -0
- package/extensions/explore/ast/queries/outline.ts +203 -0
- package/extensions/explore/ast/queries/show.ts +262 -0
- package/extensions/explore/ast/query.ts +48 -0
- package/extensions/explore/ast/read/hook.ts +125 -0
- package/extensions/explore/ast/read/policy.ts +55 -0
- package/extensions/explore/ast/registry.ts +120 -0
- package/extensions/explore/ast/scan.ts +76 -0
- package/extensions/explore/ast/slice.ts +31 -0
- package/extensions/explore/ast/tools/ast-search.ts +138 -0
- package/extensions/explore/ast/tools/context.ts +126 -0
- package/extensions/explore/ast/tools/deps.ts +72 -0
- package/extensions/explore/ast/tools/discover.ts +208 -0
- package/extensions/explore/ast/tools/impact.ts +135 -0
- package/extensions/explore/ast/tools/outline.ts +200 -0
- package/extensions/explore/ast/tools/relationships.ts +160 -0
- package/extensions/explore/ast/tools/render.ts +121 -0
- package/extensions/explore/ast/tools/reverse-deps.ts +72 -0
- package/extensions/explore/ast/tools/show.ts +116 -0
- package/extensions/explore/guidance.ts +52 -0
- package/extensions/explore/index.ts +91 -45
- package/extensions/explore/read/autoread.ts +118 -0
- package/extensions/explore/settings.ts +64 -0
- package/extensions/explore/traverse.ts +260 -86
- package/extensions/handoff/index.ts +1 -1
- package/extensions/patch/executor.ts +95 -1
- package/extensions/patch/index.ts +1 -0
- package/extensions/publish/index.ts +18 -85
- package/extensions/publish/publish-ui.ts +0 -4
- package/extensions/soul/README.md +7 -4
- package/extensions/soul/index.ts +11 -5
- package/extensions/soul/prompt.ts +30 -14
- package/extensions/soul/settings.ts +7 -2
- package/extensions/subagent/agents/context-sync.md +6 -10
- package/extensions/subagent/agents/review.md +44 -24
- package/extensions/subagent/agents/scout.md +53 -34
- package/extensions/subagent/run.ts +1 -1
- package/extensions/tau-help/help.md +2 -2
- package/package.json +6 -5
- package/schemas/tau.schema.json +51 -6
- package/{extensions/explore → shared}/autoread.ts +21 -7
- package/shared/bounded-text-result.ts +304 -0
- package/shared/events.ts +1 -0
- package/shared/full-file-knowledge.ts +49 -0
- package/shared/temporary-output-store.ts +275 -0
- package/extensions/explore/ast-tools.ts +0 -828
- package/extensions/explore/ast-worker.ts +0 -356
- package/extensions/explore/find.ts +0 -147
- package/extensions/explore/full-file-knowledge.ts +0 -234
- package/extensions/explore/grep.ts +0 -749
- package/extensions/explore/limits.ts +0 -22
- package/extensions/explore/ls.ts +0 -113
- package/extensions/explore/path-display.ts +0 -41
- package/extensions/explore/path-tree.ts +0 -150
- package/extensions/explore/read-cache.ts +0 -273
- package/extensions/explore/read-snapshots.ts +0 -57
- package/extensions/explore/read-stats-panel.ts +0 -154
- package/extensions/explore/read-stats.ts +0 -120
- package/extensions/explore/read.ts +0 -335
- package/extensions/explore/result.ts +0 -29
- package/native-bin/darwin-arm64/tau-ast +0 -0
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { generateUnifiedPatch, truncateHead } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import type { ReadCacheMetaV1, ReadCacheMode, ReadCachePresentation } from "./read-cache.ts";
|
|
4
|
-
|
|
5
|
-
export const COMPLETE_FILE_SCOPE = "full";
|
|
6
|
-
export const MAX_COMPLETE_FILE_SNAPSHOT_BYTES = 1024 * 1024;
|
|
7
|
-
|
|
8
|
-
export interface CompleteFileSelection {
|
|
9
|
-
text: string;
|
|
10
|
-
mode: ReadCacheMode;
|
|
11
|
-
summary: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function createCompleteFileMeta(options: {
|
|
15
|
-
pathKey: string;
|
|
16
|
-
presentation: ReadCachePresentation;
|
|
17
|
-
servedHash: string;
|
|
18
|
-
mode: ReadCacheMode;
|
|
19
|
-
sourceText: string;
|
|
20
|
-
returnedText: string;
|
|
21
|
-
totalLines: number;
|
|
22
|
-
summary: string;
|
|
23
|
-
baseHash?: string;
|
|
24
|
-
}): ReadCacheMetaV1 {
|
|
25
|
-
return {
|
|
26
|
-
v: 1,
|
|
27
|
-
pathKey: options.pathKey,
|
|
28
|
-
scopeKey: COMPLETE_FILE_SCOPE,
|
|
29
|
-
presentation: options.presentation,
|
|
30
|
-
servedHash: options.servedHash,
|
|
31
|
-
baseHash: options.baseHash,
|
|
32
|
-
mode: options.mode,
|
|
33
|
-
baselineTokens: estimateTokens(options.sourceText),
|
|
34
|
-
returnedTokens: estimateTokens(options.returnedText),
|
|
35
|
-
totalLines: options.totalLines,
|
|
36
|
-
summary: options.summary,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function readScopeKey(
|
|
41
|
-
completeFile: boolean,
|
|
42
|
-
startLine: number,
|
|
43
|
-
endLine: number,
|
|
44
|
-
presentation: ReadCachePresentation,
|
|
45
|
-
): string {
|
|
46
|
-
return completeFile ? COMPLETE_FILE_SCOPE : `r:${startLine}:${endLine}:n${presentation === "line-numbered" ? 1 : 0}`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function decodeCompleteFileSource(options: {
|
|
50
|
-
content: unknown;
|
|
51
|
-
autoread: boolean;
|
|
52
|
-
pathHeader?: string;
|
|
53
|
-
presentation: ReadCachePresentation;
|
|
54
|
-
servedHash: string;
|
|
55
|
-
}): { valid: boolean; text?: string } {
|
|
56
|
-
const payload = textContent(options.content);
|
|
57
|
-
if (payload === undefined) return { valid: false };
|
|
58
|
-
const separator = payload.indexOf("\n");
|
|
59
|
-
if (
|
|
60
|
-
options.autoread &&
|
|
61
|
-
(separator < 0 || options.pathHeader === undefined || payload.slice(0, separator) !== options.pathHeader)
|
|
62
|
-
)
|
|
63
|
-
return { valid: false };
|
|
64
|
-
const body = options.autoread ? payload.slice(separator + 1) : payload;
|
|
65
|
-
const text = options.presentation === "plain" ? body : decodeLineNumbers(body);
|
|
66
|
-
if (text === undefined) return { valid: false };
|
|
67
|
-
const bytes = Buffer.byteLength(text, "utf8");
|
|
68
|
-
if (createHash("sha256").update(text, "utf8").digest("hex") !== options.servedHash) return { valid: false };
|
|
69
|
-
return bytes <= MAX_COMPLETE_FILE_SNAPSHOT_BYTES ? { valid: true, text } : { valid: true };
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function applyCompleteFileDiff(options: {
|
|
73
|
-
content: unknown;
|
|
74
|
-
baseText: string;
|
|
75
|
-
baseHash: string;
|
|
76
|
-
servedHash: string;
|
|
77
|
-
}): { valid: boolean; text?: string } {
|
|
78
|
-
if (hashText(options.baseText) !== options.baseHash) return { valid: false };
|
|
79
|
-
const payload = textContent(options.content);
|
|
80
|
-
if (payload === undefined) return { valid: false };
|
|
81
|
-
const separator = payload.indexOf("\n");
|
|
82
|
-
if (separator < 0 || !/^\[read: \d+ lines added, \d+ removed of \d+\]$/.test(payload.slice(0, separator))) {
|
|
83
|
-
return { valid: false };
|
|
84
|
-
}
|
|
85
|
-
const text = applyUnifiedDiff(options.baseText, payload.slice(separator + 1));
|
|
86
|
-
if (text === undefined || hashText(text) !== options.servedHash) return { valid: false };
|
|
87
|
-
return Buffer.byteLength(text, "utf8") <= MAX_COMPLETE_FILE_SNAPSHOT_BYTES ? { valid: true, text } : { valid: true };
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function selectCompleteFileResponse(options: {
|
|
91
|
-
displayPath: string;
|
|
92
|
-
currentText: string;
|
|
93
|
-
currentHash: string;
|
|
94
|
-
fullText: string;
|
|
95
|
-
totalLines: number;
|
|
96
|
-
recovery: boolean;
|
|
97
|
-
baseHash?: string;
|
|
98
|
-
baselineText?: string;
|
|
99
|
-
}): CompleteFileSelection {
|
|
100
|
-
if (options.recovery) return { text: options.fullText, mode: "recovery", summary: `${options.totalLines} lines` };
|
|
101
|
-
if (!options.baseHash) return { text: options.fullText, mode: "baseline", summary: `${options.totalLines} lines` };
|
|
102
|
-
if (options.baseHash === options.currentHash) {
|
|
103
|
-
const text = `unchanged, ${options.totalLines} lines`;
|
|
104
|
-
return { text, mode: "unchanged", summary: text };
|
|
105
|
-
}
|
|
106
|
-
if (options.baselineText !== undefined) {
|
|
107
|
-
const patch = generateUnifiedPatch(options.displayPath, options.baselineText, options.currentText, 3);
|
|
108
|
-
const counts = countDiffLines(patch);
|
|
109
|
-
const candidate = `[read: ${counts.added} lines added, ${counts.removed} removed of ${options.totalLines}]\n${patch}`;
|
|
110
|
-
if (!truncateHead(candidate).truncated && estimateTokens(candidate) < estimateTokens(options.fullText)) {
|
|
111
|
-
return { text: candidate, mode: "diff", summary: `+${counts.added} -${counts.removed}` };
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return { text: options.fullText, mode: "baseline", summary: `${options.totalLines} lines` };
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function estimateTokens(text: string): number {
|
|
118
|
-
return Math.ceil(text.length / 4);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function textContent(content: unknown): string | undefined {
|
|
122
|
-
if (typeof content === "string") return content;
|
|
123
|
-
if (!Array.isArray(content) || content.length !== 1) return undefined;
|
|
124
|
-
const part = content[0];
|
|
125
|
-
if (!part || typeof part !== "object") return undefined;
|
|
126
|
-
const record = part as Record<string, unknown>;
|
|
127
|
-
return record.type === "text" && typeof record.text === "string" ? record.text : undefined;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function applyUnifiedDiff(source: string, patch: string): string | undefined {
|
|
131
|
-
const patchLines = patch.split("\n");
|
|
132
|
-
const oldHeaderIndex = patchLines.findIndex(
|
|
133
|
-
(line, index) => line.startsWith("--- ") && patchLines[index + 1]?.startsWith("+++ "),
|
|
134
|
-
);
|
|
135
|
-
if (oldHeaderIndex < 0) return undefined;
|
|
136
|
-
const sourceEndsWithNewline = source.endsWith("\n");
|
|
137
|
-
const sourceLines = source === "" ? [] : source.split("\n");
|
|
138
|
-
if (sourceEndsWithNewline) sourceLines.pop();
|
|
139
|
-
const output: string[] = [];
|
|
140
|
-
let sourceIndex = 0;
|
|
141
|
-
let patchIndex = oldHeaderIndex + 2;
|
|
142
|
-
let hunkCount = 0;
|
|
143
|
-
let outputEndsWithNewline = sourceEndsWithNewline;
|
|
144
|
-
|
|
145
|
-
while (patchIndex < patchLines.length) {
|
|
146
|
-
const header = patchLines[patchIndex];
|
|
147
|
-
if (header === "" && patchIndex === patchLines.length - 1) break;
|
|
148
|
-
if (header === undefined) return undefined;
|
|
149
|
-
const match = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(?: .*)?$/.exec(header);
|
|
150
|
-
if (!match) return undefined;
|
|
151
|
-
const oldStartValue = Number(match[1]);
|
|
152
|
-
const oldCount = match[2] === undefined ? 1 : Number(match[2]);
|
|
153
|
-
const newCount = match[4] === undefined ? 1 : Number(match[4]);
|
|
154
|
-
if (!Number.isSafeInteger(oldStartValue) || !Number.isSafeInteger(oldCount) || !Number.isSafeInteger(newCount)) {
|
|
155
|
-
return undefined;
|
|
156
|
-
}
|
|
157
|
-
const oldStart = oldCount === 0 ? oldStartValue : oldStartValue - 1;
|
|
158
|
-
if (oldStart < sourceIndex || oldStart > sourceLines.length) return undefined;
|
|
159
|
-
output.push(...sourceLines.slice(sourceIndex, oldStart));
|
|
160
|
-
sourceIndex = oldStart;
|
|
161
|
-
patchIndex += 1;
|
|
162
|
-
let consumedOld = 0;
|
|
163
|
-
let producedNew = 0;
|
|
164
|
-
let previousMarker: string | undefined;
|
|
165
|
-
let newSideHasNoFinalNewline = false;
|
|
166
|
-
|
|
167
|
-
while (patchIndex < patchLines.length && !patchLines[patchIndex]?.startsWith("@@ ")) {
|
|
168
|
-
const line = patchLines[patchIndex];
|
|
169
|
-
if (line === "" && patchIndex === patchLines.length - 1) break;
|
|
170
|
-
if (line === undefined) return undefined;
|
|
171
|
-
if (line === "\") {
|
|
172
|
-
if (previousMarker !== "+" && previousMarker !== "-" && previousMarker !== " ") return undefined;
|
|
173
|
-
if (previousMarker === "+" || previousMarker === " ") newSideHasNoFinalNewline = true;
|
|
174
|
-
patchIndex += 1;
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
const marker = line[0];
|
|
178
|
-
const value = line.slice(1);
|
|
179
|
-
if (marker === " ") {
|
|
180
|
-
if (sourceLines[sourceIndex] !== value) return undefined;
|
|
181
|
-
output.push(value);
|
|
182
|
-
sourceIndex += 1;
|
|
183
|
-
consumedOld += 1;
|
|
184
|
-
producedNew += 1;
|
|
185
|
-
} else if (marker === "-") {
|
|
186
|
-
if (sourceLines[sourceIndex] !== value) return undefined;
|
|
187
|
-
sourceIndex += 1;
|
|
188
|
-
consumedOld += 1;
|
|
189
|
-
} else if (marker === "+") {
|
|
190
|
-
output.push(value);
|
|
191
|
-
producedNew += 1;
|
|
192
|
-
} else {
|
|
193
|
-
return undefined;
|
|
194
|
-
}
|
|
195
|
-
previousMarker = marker;
|
|
196
|
-
patchIndex += 1;
|
|
197
|
-
}
|
|
198
|
-
if (consumedOld !== oldCount || producedNew !== newCount) return undefined;
|
|
199
|
-
if (sourceIndex === sourceLines.length) {
|
|
200
|
-
outputEndsWithNewline = newCount > 0 && !newSideHasNoFinalNewline;
|
|
201
|
-
}
|
|
202
|
-
hunkCount += 1;
|
|
203
|
-
}
|
|
204
|
-
if (hunkCount === 0) return undefined;
|
|
205
|
-
output.push(...sourceLines.slice(sourceIndex));
|
|
206
|
-
const text = output.join("\n");
|
|
207
|
-
return outputEndsWithNewline && output.length > 0 ? `${text}\n` : text;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function hashText(text: string): string {
|
|
211
|
-
return createHash("sha256").update(text, "utf8").digest("hex");
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function decodeLineNumbers(content: string): string | undefined {
|
|
215
|
-
const lines = content.split("\n");
|
|
216
|
-
const decoded: string[] = [];
|
|
217
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
218
|
-
const prefix = `${index + 1}: `;
|
|
219
|
-
const line = lines[index];
|
|
220
|
-
if (line === undefined || !line.startsWith(prefix)) return undefined;
|
|
221
|
-
decoded.push(line.slice(prefix.length));
|
|
222
|
-
}
|
|
223
|
-
return decoded.join("\n");
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function countDiffLines(patch: string): { added: number; removed: number } {
|
|
227
|
-
let added = 0;
|
|
228
|
-
let removed = 0;
|
|
229
|
-
for (const line of patch.split("\n")) {
|
|
230
|
-
if (line.startsWith("+") && !line.startsWith("+++")) added += 1;
|
|
231
|
-
else if (line.startsWith("-") && !line.startsWith("---")) removed += 1;
|
|
232
|
-
}
|
|
233
|
-
return { added, removed };
|
|
234
|
-
}
|