@shanepadgett/tau-agent 0.26.0 → 0.27.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-pruning/README.md +2 -2
- package/extensions/context-pruning/index.ts +58 -57
- package/extensions/context-pruning/render.ts +51 -39
- package/extensions/context-pruning/settings.ts +4 -5
- package/extensions/explore/README.md +18 -11
- package/extensions/explore/ast-guidance.ts +67 -0
- package/extensions/explore/ast-languages.ts +61 -0
- package/extensions/explore/ast-tools.ts +1257 -91
- package/extensions/explore/ast-worker.ts +735 -66
- package/extensions/explore/index.ts +62 -6
- package/extensions/explore/orientation-state.ts +280 -0
- package/extensions/explore/read-stats-panel.ts +23 -1
- package/extensions/explore/read-stats.ts +21 -3
- package/extensions/explore/read.ts +58 -21
- package/extensions/explore/settings.ts +46 -0
- package/extensions/explore/traverse.ts +15 -4
- package/extensions/patch/executor.ts +95 -1
- package/extensions/patch/index.ts +1 -0
- package/extensions/soul/prompt.ts +1 -3
- package/extensions/subagent/agents/review.md +76 -25
- package/extensions/subagent/agents/scout.md +118 -22
- package/extensions/tau-help/help.md +3 -1
- package/native-bin/darwin-arm64/tau-ast +0 -0
- package/package.json +2 -3
- package/schemas/tau.schema.json +44 -4
- package/shared/bounded-text-result.ts +304 -0
- package/shared/events.ts +2 -1
- package/shared/temporary-output-store.ts +275 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { relative, resolve } from "node:path";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import { matchGlob, posixPath } from "../../shared/glob.ts";
|
|
4
|
+
import { defineTauExtensionSettings } from "../../shared/settings/define.ts";
|
|
5
|
+
|
|
6
|
+
export interface ExploreReadGateSettings {
|
|
7
|
+
includeGlobs: string[];
|
|
8
|
+
excludeGlobs: string[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default defineTauExtensionSettings({
|
|
12
|
+
key: "explore",
|
|
13
|
+
defaults: {
|
|
14
|
+
readGate: {
|
|
15
|
+
includeGlobs: ["**/*"] as string[],
|
|
16
|
+
excludeGlobs: ["**/*.md", "**/*.markdown", "**/*.mdown"] as string[],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
schema: Type.Object(
|
|
20
|
+
{
|
|
21
|
+
readGate: Type.Object(
|
|
22
|
+
{
|
|
23
|
+
includeGlobs: Type.Array(Type.String(), {
|
|
24
|
+
default: ["**/*"],
|
|
25
|
+
description:
|
|
26
|
+
"Working-directory-relative supported source paths that require a structural attempt before read.",
|
|
27
|
+
}),
|
|
28
|
+
excludeGlobs: Type.Array(Type.String(), {
|
|
29
|
+
default: ["**/*.md", "**/*.markdown", "**/*.mdown"],
|
|
30
|
+
description: "Working-directory-relative paths excluded from the Explore read gate. Exclusions win.",
|
|
31
|
+
}),
|
|
32
|
+
},
|
|
33
|
+
{ additionalProperties: false },
|
|
34
|
+
),
|
|
35
|
+
},
|
|
36
|
+
{ additionalProperties: false },
|
|
37
|
+
),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export function matchesExploreReadGate(path: string, cwd: string, settings: ExploreReadGateSettings): boolean {
|
|
41
|
+
const projectPath = posixPath(relative(resolve(cwd), resolve(path)));
|
|
42
|
+
return (
|
|
43
|
+
settings.includeGlobs.some((pattern) => matchGlob(pattern, projectPath)) &&
|
|
44
|
+
!settings.excludeGlobs.some((pattern) => matchGlob(pattern, projectPath))
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Stats } from "node:fs";
|
|
2
|
-
import { lstat,
|
|
2
|
+
import { lstat, opendir, readFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, join, matchesGlob, resolve, sep } from "node:path";
|
|
4
4
|
import { formatPathForDisplay, isWithinPath, relativeSlash, toSlashPath } from "./path-display.ts";
|
|
5
5
|
|
|
@@ -18,6 +18,7 @@ export interface CollectPathOptions {
|
|
|
18
18
|
cwd: string;
|
|
19
19
|
root: string;
|
|
20
20
|
maxDepth?: number;
|
|
21
|
+
maxEntries?: number;
|
|
21
22
|
includeRoot: boolean;
|
|
22
23
|
includeHidden: boolean;
|
|
23
24
|
includeIgnored: boolean;
|
|
@@ -149,9 +150,14 @@ function sortEntries(entries: TraversalEntry[]): TraversalEntry[] {
|
|
|
149
150
|
});
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
async function readDirectoryNames(directory: string, cwd: string): Promise<string[]> {
|
|
153
|
+
async function readDirectoryNames(directory: string, cwd: string, limit: number | undefined): Promise<string[]> {
|
|
153
154
|
try {
|
|
154
|
-
|
|
155
|
+
const names: string[] = [];
|
|
156
|
+
for await (const entry of await opendir(directory)) {
|
|
157
|
+
names.push(entry.name);
|
|
158
|
+
if (limit !== undefined && names.length >= limit) break;
|
|
159
|
+
}
|
|
160
|
+
return names;
|
|
155
161
|
} catch {
|
|
156
162
|
throw new Error(`Cannot read directory: ${formatPathForDisplay(directory, cwd)}`);
|
|
157
163
|
}
|
|
@@ -160,6 +166,7 @@ async function readDirectoryNames(directory: string, cwd: string): Promise<strin
|
|
|
160
166
|
export async function collectPaths(options: CollectPathOptions): Promise<TraversalEntry[]> {
|
|
161
167
|
const entries: TraversalEntry[] = [];
|
|
162
168
|
const entryByPath = new Map<string, TraversalEntry>();
|
|
169
|
+
let inspectedEntries = 0;
|
|
163
170
|
const rootStats = await lstat(options.root);
|
|
164
171
|
const rootKind = entryKind(rootStats);
|
|
165
172
|
const rootDirectory = rootKind === "dir" ? options.root : dirname(options.root);
|
|
@@ -183,13 +190,17 @@ export async function collectPaths(options: CollectPathOptions): Promise<Travers
|
|
|
183
190
|
|
|
184
191
|
async function walkDirectory(directory: string, depth: number, rules: readonly IgnoreRule[]): Promise<number> {
|
|
185
192
|
if (options.maxDepth !== undefined && depth >= options.maxDepth) return 0;
|
|
193
|
+
if (options.maxEntries !== undefined && inspectedEntries >= options.maxEntries) return 0;
|
|
186
194
|
|
|
187
|
-
const
|
|
195
|
+
const remaining = options.maxEntries === undefined ? undefined : options.maxEntries - inspectedEntries;
|
|
196
|
+
const names = await readDirectoryNames(directory, options.cwd, remaining);
|
|
188
197
|
|
|
189
198
|
const children: TraversalEntry[] = [];
|
|
190
199
|
for (const name of names) {
|
|
200
|
+
if (options.maxEntries !== undefined && inspectedEntries >= options.maxEntries) break;
|
|
191
201
|
const childPath = `${directory}/${name}`;
|
|
192
202
|
const stats = await lstat(childPath);
|
|
203
|
+
inspectedEntries += 1;
|
|
193
204
|
const kind = entryKind(stats);
|
|
194
205
|
if (shouldSkipPath(childPath, kind, rules, options)) continue;
|
|
195
206
|
children.push({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { access, mkdir, readFile, realpath, rmdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
2
3
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
3
4
|
import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
|
|
4
5
|
import { applyChunksWithRanges, countLogicalLines, UpdateChunkApplyError } from "./matcher.ts";
|
|
@@ -11,6 +12,7 @@ export interface ApplyPatchChange {
|
|
|
11
12
|
move?: { from: string; to: string };
|
|
12
13
|
linesAdded: number;
|
|
13
14
|
linesRemoved: number;
|
|
15
|
+
resultingFingerprint: string | null;
|
|
14
16
|
snapshotRanges?: Array<{ startLine: number; endLine: number }>;
|
|
15
17
|
}
|
|
16
18
|
|
|
@@ -32,6 +34,12 @@ export interface ApplyPatchStats {
|
|
|
32
34
|
completedOperations: number;
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
export interface ExactSourceMutation {
|
|
38
|
+
path: string;
|
|
39
|
+
expectedFingerprint: string;
|
|
40
|
+
source: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
export function deriveStats(summary: ApplyPatchSummary): ApplyPatchStats {
|
|
36
44
|
const added: string[] = [];
|
|
37
45
|
const replaced: string[] = [];
|
|
@@ -80,6 +88,10 @@ function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
|
80
88
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
81
89
|
}
|
|
82
90
|
|
|
91
|
+
function fingerprint(source: string): string {
|
|
92
|
+
return `sha256:${createHash("sha256").update(source, "utf8").digest("hex")}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
83
95
|
async function pathExists(path: string): Promise<boolean> {
|
|
84
96
|
try {
|
|
85
97
|
await access(path);
|
|
@@ -136,6 +148,7 @@ async function stageWholeFile(
|
|
|
136
148
|
path: op.path,
|
|
137
149
|
linesAdded: op.linesAdded,
|
|
138
150
|
linesRemoved,
|
|
151
|
+
resultingFingerprint: fingerprint(op.content),
|
|
139
152
|
snapshotRanges: lineCount > 0 ? [{ startLine: 1, endLine: Math.min(lineCount, 120) }] : undefined,
|
|
140
153
|
},
|
|
141
154
|
async commit() {
|
|
@@ -156,6 +169,7 @@ async function stageDelete(cwd: string, op: Extract<PatchOperation, { type: "del
|
|
|
156
169
|
path: op.path,
|
|
157
170
|
linesAdded: 0,
|
|
158
171
|
linesRemoved: countLogicalLines(current),
|
|
172
|
+
resultingFingerprint: null,
|
|
159
173
|
},
|
|
160
174
|
async commit() {
|
|
161
175
|
await unlink(target);
|
|
@@ -180,6 +194,7 @@ async function stageUpdate(cwd: string, op: Extract<PatchOperation, { type: "upd
|
|
|
180
194
|
path: op.path,
|
|
181
195
|
linesAdded: op.linesAdded,
|
|
182
196
|
linesRemoved: op.linesRemoved,
|
|
197
|
+
resultingFingerprint: fingerprint(next),
|
|
183
198
|
snapshotRanges: result?.snapshotRanges,
|
|
184
199
|
},
|
|
185
200
|
async commit() {
|
|
@@ -203,6 +218,7 @@ async function stageUpdate(cwd: string, op: Extract<PatchOperation, { type: "upd
|
|
|
203
218
|
move: { from: op.path, to: movePath },
|
|
204
219
|
linesAdded: op.linesAdded,
|
|
205
220
|
linesRemoved: op.linesRemoved,
|
|
221
|
+
resultingFingerprint: fingerprint(next),
|
|
206
222
|
snapshotRanges: result?.snapshotRanges,
|
|
207
223
|
},
|
|
208
224
|
async commit() {
|
|
@@ -256,6 +272,84 @@ function withMutationQueuePaths<T>(paths: string[], fn: () => Promise<T>): Promi
|
|
|
256
272
|
return current();
|
|
257
273
|
}
|
|
258
274
|
|
|
275
|
+
export async function applyExactSourceMutations(
|
|
276
|
+
cwd: string,
|
|
277
|
+
mutations: readonly ExactSourceMutation[],
|
|
278
|
+
signal?: AbortSignal,
|
|
279
|
+
): Promise<ApplyPatchSummary> {
|
|
280
|
+
throwIfAborted(signal);
|
|
281
|
+
if (mutations.length === 0) throw new Error("Exact-source mutation requires at least one file.");
|
|
282
|
+
const byPath = new Map<string, ExactSourceMutation>();
|
|
283
|
+
for (const mutation of mutations) {
|
|
284
|
+
const path = resolvePath(cwd, mutation.path);
|
|
285
|
+
if (byPath.has(path)) throw new Error(`Conflicting exact-source mutations for path: ${mutation.path}`);
|
|
286
|
+
byPath.set(path, { ...mutation, path });
|
|
287
|
+
}
|
|
288
|
+
const ordered = [...byPath.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
289
|
+
|
|
290
|
+
return withMutationQueuePaths(
|
|
291
|
+
ordered.map((mutation) => mutation.path),
|
|
292
|
+
async () => {
|
|
293
|
+
const staged: Array<{ mutation: ExactSourceMutation; change: ApplyPatchChange }> = [];
|
|
294
|
+
for (const [sectionIndex, mutation] of ordered.entries()) {
|
|
295
|
+
throwIfAborted(signal);
|
|
296
|
+
await assertExistingFile(mutation.path, mutation.path);
|
|
297
|
+
const canonical = await realpath(mutation.path);
|
|
298
|
+
if (canonical !== mutation.path) {
|
|
299
|
+
throw new Error(`Exact-source mutation path is not canonical: ${mutation.path}`);
|
|
300
|
+
}
|
|
301
|
+
const current = await readUtf8(mutation.path, mutation.path);
|
|
302
|
+
const currentFingerprint = fingerprint(current);
|
|
303
|
+
if (currentFingerprint !== mutation.expectedFingerprint) {
|
|
304
|
+
throw new Error(
|
|
305
|
+
`Source changed before exact-source mutation for ${mutation.path}; expected ${mutation.expectedFingerprint}, found ${currentFingerprint}.`,
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
const displayPath = relative(resolve(cwd), mutation.path);
|
|
309
|
+
const lineCount = countLogicalLines(mutation.source);
|
|
310
|
+
staged.push({
|
|
311
|
+
mutation,
|
|
312
|
+
change: {
|
|
313
|
+
sectionIndex,
|
|
314
|
+
kind: "update",
|
|
315
|
+
path: displayPath.startsWith("..") || isAbsolute(displayPath) ? mutation.path : displayPath,
|
|
316
|
+
linesAdded: lineCount,
|
|
317
|
+
linesRemoved: countLogicalLines(current),
|
|
318
|
+
resultingFingerprint: fingerprint(mutation.source),
|
|
319
|
+
snapshotRanges: lineCount > 0 ? [{ startLine: 1, endLine: Math.min(lineCount, 120) }] : undefined,
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
throwIfAborted(signal);
|
|
325
|
+
const changes: ApplyPatchChange[] = [];
|
|
326
|
+
for (const { mutation, change } of staged) {
|
|
327
|
+
try {
|
|
328
|
+
throwIfAborted(signal);
|
|
329
|
+
await writeFile(mutation.path, mutation.source, "utf8");
|
|
330
|
+
changes.push(change);
|
|
331
|
+
} catch (error) {
|
|
332
|
+
return {
|
|
333
|
+
status: changes.length === 0 ? "failed" : "partial",
|
|
334
|
+
changes,
|
|
335
|
+
failures: [
|
|
336
|
+
{
|
|
337
|
+
phase: "apply",
|
|
338
|
+
sectionIndex: change.sectionIndex,
|
|
339
|
+
path: change.path,
|
|
340
|
+
kind: "update",
|
|
341
|
+
message: error instanceof Error ? error.message : String(error),
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
totalSections: staged.length,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return { status: "completed", changes, failures: [], totalSections: staged.length };
|
|
349
|
+
},
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
259
353
|
export async function applyPatch(
|
|
260
354
|
cwd: string,
|
|
261
355
|
input: string,
|
|
@@ -165,6 +165,7 @@ export default function patchExtension(pi: ExtensionAPI): void {
|
|
|
165
165
|
move: change.move,
|
|
166
166
|
linesAdded: change.linesAdded,
|
|
167
167
|
linesRemoved: change.linesRemoved,
|
|
168
|
+
resultingFingerprint: change.resultingFingerprint,
|
|
168
169
|
snapshotRanges: change.snapshotRanges,
|
|
169
170
|
})),
|
|
170
171
|
});
|
|
@@ -12,9 +12,7 @@ Human interrupts. Human sometimes idiot. Human sometimes has good idea. Rok thin
|
|
|
12
12
|
|
|
13
13
|
Build only what human specifically asked for. User ask approves that scope only. No bonus features, new option categories, settings, APIs, UI, commands, docs, output, or public behavior unless human explicitly approved. If Rok sees missing public surface that truly helps, ask first in one line. Do not sneak it into diff.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Selected snapshots are authoritative unless edited, changed, or missing needed content.
|
|
15
|
+
Gather only the evidence needed for the current decision. Expand scope only when a specific uncertainty requires it. Do not chase related code, documentation, or tests merely because they exist. If an investigation wanders, discard stale evidence before continuing.
|
|
18
16
|
|
|
19
17
|
Never cut validation, data safety, security, accessibility, explicit user ask, hardware calibration.
|
|
20
18
|
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
name: review
|
|
3
3
|
description: Perform an adversarial, read-only review for correctness, runtime risks, duplication, and over- or under-engineering
|
|
4
4
|
tools:
|
|
5
|
-
- read
|
|
6
|
-
- grep
|
|
7
|
-
- find
|
|
8
5
|
- ls
|
|
9
|
-
-
|
|
10
|
-
-
|
|
6
|
+
- find
|
|
7
|
+
- grep
|
|
8
|
+
- api_discover
|
|
9
|
+
- ast_search
|
|
10
|
+
- outline
|
|
11
|
+
- symbol
|
|
12
|
+
- references
|
|
13
|
+
- callers
|
|
14
|
+
- callees
|
|
15
|
+
- implementations
|
|
16
|
+
- tests
|
|
11
17
|
names:
|
|
12
18
|
- Auditor
|
|
13
19
|
- Inspector
|
|
@@ -15,34 +21,79 @@ names:
|
|
|
15
21
|
- Examiner
|
|
16
22
|
- Sentinel
|
|
17
23
|
model: openai-codex/gpt-5.6-sol
|
|
18
|
-
thinking:
|
|
24
|
+
thinking: high
|
|
19
25
|
---
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
Stay inside delegated change. Answer two questions:
|
|
28
|
+
|
|
29
|
+
1. Is runtime behavior correct?
|
|
30
|
+
2. Is this the simplest implementation of requested behavior?
|
|
31
|
+
|
|
32
|
+
Find concrete failures or needless complexity. Report. Stop. No unrelated review or concern inventory.
|
|
33
|
+
|
|
34
|
+
## Evidence ladder
|
|
35
|
+
|
|
36
|
+
Use cheapest tool that settles question. Escalate only when answer could change verdict.
|
|
37
|
+
|
|
38
|
+
### Supplied context
|
|
39
|
+
|
|
40
|
+
Task files are current, line-numbered snapshots. Treat as authoritative this turn. Start there. Do not search for facts already supplied.
|
|
41
|
+
|
|
42
|
+
### Paths and text
|
|
43
|
+
|
|
44
|
+
- `ls` or `find`: relevant path unknown.
|
|
45
|
+
- `grep`: exact names, imports, registrations, configuration keys, and unsupported source formats.
|
|
46
|
+
- Keep roots and result limits narrow. Text occurrence does not prove runtime behavior.
|
|
47
|
+
|
|
48
|
+
### Structure and reuse
|
|
49
|
+
|
|
50
|
+
- Default to `outline`. Inspect known file or package. Pass likely names. Include private declarations only when verdict needs them.
|
|
51
|
+
- Use `api_discover` when code may duplicate an existing repository API but name or path is unknown.
|
|
52
|
+
- Use `ast_search` for code shapes: repeated wrappers, duplicated branches, risky call patterns. Keep pattern and scope focused.
|
|
53
|
+
|
|
54
|
+
No repository sweeps for hypothetical reuse. Search only when changed code gives concrete reason.
|
|
55
|
+
|
|
56
|
+
### Runtime relationships
|
|
57
|
+
|
|
58
|
+
Select declaration locator. Use one focused relationship tool when needed:
|
|
59
|
+
|
|
60
|
+
- `callers`: direct call sites.
|
|
61
|
+
- `callees`: dependencies inside executable scope.
|
|
62
|
+
- `references`: direct uses and re-exports.
|
|
63
|
+
- `implementations`: inheritance or override behavior.
|
|
64
|
+
- `tests`: directly affected coverage.
|
|
65
|
+
|
|
66
|
+
Use narrowest useful root and small result limit. Preserve exact, inferred, and ambiguous labels. Results prove bounded syntactic relationships. They do not prove dynamic dispatch or complete runtime reachability.
|
|
67
|
+
|
|
68
|
+
### Exact declarations
|
|
69
|
+
|
|
70
|
+
Use `symbol` only with locators returned in this child session:
|
|
71
|
+
|
|
72
|
+
- `signature`: shape.
|
|
73
|
+
- `signatureWithDocs`: contract.
|
|
74
|
+
- `declaration`: implementation needed to judge behavior.
|
|
75
|
+
- `declarationWithImports`: dependency choice matters.
|
|
76
|
+
|
|
77
|
+
Retrieve only declarations that prove or dismiss a finding. No `read` or `bash`. No whole-file reconstruction through huge grep contexts or exhaustive symbol retrieval.
|
|
22
78
|
|
|
23
79
|
## Review procedure
|
|
24
80
|
|
|
25
|
-
1.
|
|
26
|
-
2.
|
|
27
|
-
3.
|
|
28
|
-
4.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- under-engineering, missing validation, incomplete wiring, weak tests, and assumptions that should be enforced;
|
|
32
|
-
- tests that only mirror the implementation, miss realistic sequences, or fail to protect the requested behavior;
|
|
33
|
-
- dead code, stale documentation, and obsolete resources left behind by the change.
|
|
34
|
-
5. Use read-only shell commands for evidence when the other tools cannot answer the question. Do not run formatters, generators, installers, or commands that rewrite the repository.
|
|
35
|
-
6. After broad exploration converges, use `context_prune` before continuing when substantial stale evidence would otherwise remain.
|
|
81
|
+
1. Extract requested behavior, changed scope, and relevant repository constraints from task and supplied files.
|
|
82
|
+
2. Inspect changed declarations. Form only actionable runtime and simplicity questions.
|
|
83
|
+
3. Runtime: follow shortest relevant path through callers, state transitions, boundaries, error handling, and tests. Check realistic sequences. Skip theoretical branch inventory.
|
|
84
|
+
4. Simplicity: can wrappers, helpers, option bags, duplicated logic, or staged abstractions go away without changing requested behavior? Report only material reductions in concepts, branches, or ownership.
|
|
85
|
+
5. Inspect surrounding code only to confirm suspected failure, contract mismatch, missed caller, or existing simpler API.
|
|
86
|
+
6. Stop when both questions have evidence-backed answers.
|
|
36
87
|
|
|
37
|
-
|
|
88
|
+
Treat implementation as untrusted. Reject speculation, personal style preferences, and complexity complaints without concrete maintenance or reasoning cost. Review volume earns nothing. Do not modify files.
|
|
38
89
|
|
|
39
90
|
## Output
|
|
40
91
|
|
|
41
|
-
List findings first, ordered by severity.
|
|
92
|
+
List findings first, ordered by severity. Each finding needs:
|
|
42
93
|
|
|
43
|
-
- severity and
|
|
44
|
-
- exact file and
|
|
45
|
-
-
|
|
46
|
-
-
|
|
94
|
+
- severity and direct title;
|
|
95
|
+
- exact file, line range, and symbol when one exists;
|
|
96
|
+
- runtime failure mechanism or concrete complexity cost;
|
|
97
|
+
- smallest credible fix direction.
|
|
47
98
|
|
|
48
|
-
Then list unresolved questions that materially affect correctness.
|
|
99
|
+
Then list only unresolved questions that materially affect runtime correctness. No findings: say so. State that runtime appears correct and implementation is already simplest credible version. Briefly name inspected scope. No preamble, search log, broad summary, or repeated evidence.
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scout
|
|
3
|
-
description:
|
|
3
|
+
description: Tiered, AST-first local discovery of files, symbols, data flow, constraints, and unknowns without changes
|
|
4
4
|
tools:
|
|
5
|
-
- read
|
|
6
|
-
- grep
|
|
7
|
-
- find
|
|
8
5
|
- ls
|
|
6
|
+
- find
|
|
7
|
+
- grep
|
|
8
|
+
- api_discover
|
|
9
|
+
- ast_search
|
|
10
|
+
- outline
|
|
11
|
+
- symbol
|
|
12
|
+
- references
|
|
13
|
+
- callers
|
|
14
|
+
- callees
|
|
15
|
+
- implementations
|
|
16
|
+
- tests
|
|
9
17
|
names:
|
|
10
18
|
- Pathfinder
|
|
11
19
|
- Trailblazer
|
|
@@ -16,23 +24,109 @@ model: openai-codex/gpt-5.6-luna
|
|
|
16
24
|
thinking: high
|
|
17
25
|
---
|
|
18
26
|
|
|
19
|
-
Stay inside
|
|
27
|
+
Stay inside task. Answer only what was asked. No side quests, background sweeps, unasked advice, or mutations.
|
|
28
|
+
|
|
29
|
+
Delegating prompt controls output. Otherwise use smallest matching shape below.
|
|
30
|
+
|
|
31
|
+
## Evidence ladder
|
|
32
|
+
|
|
33
|
+
Use cheapest tier that proves claim. Skip tiers when task gives exact path or symbol. Escalate only when current tier fails.
|
|
34
|
+
|
|
35
|
+
### Tier 0: Supplied context
|
|
36
|
+
|
|
37
|
+
Task files are current, line-numbered snapshots. Treat as authoritative this turn. Do not search for facts already present.
|
|
38
|
+
|
|
39
|
+
### Tier 1: Paths
|
|
40
|
+
|
|
41
|
+
- `ls`: compact view of known directory.
|
|
42
|
+
- `find`: structured file or directory discovery.
|
|
43
|
+
- Keep roots narrow. Search one package or subtree when enough.
|
|
44
|
+
|
|
45
|
+
Path match finds candidate. It does not prove behavior.
|
|
46
|
+
|
|
47
|
+
### Tier 2: Text occurrences
|
|
48
|
+
|
|
49
|
+
Use `grep` for exact names, imports, registrations, config keys, call sites, and unsupported formats. Batch focused patterns. Request only context needed to identify symbol or relationship.
|
|
50
|
+
|
|
51
|
+
Text match proves occurrence. It does not prove complete declaration inventory or runtime flow.
|
|
52
|
+
|
|
53
|
+
### Tier 3: Repository API discovery
|
|
54
|
+
|
|
55
|
+
Use `api_discover` when reuse intent is known but the declaration path or exact name is not. Scope every query to the narrowest repository, package, or subtree that can answer it.
|
|
56
|
+
|
|
57
|
+
- Prefer exact, prefix, substring, or declaration-kind queries when possible.
|
|
58
|
+
- Use bounded fuzzy-name or documentation terms only for uncertain names or concepts.
|
|
59
|
+
- Use `packageSurface` when the caller needs a supported public import path.
|
|
60
|
+
- Treat provenance or uncertainty as part of the result. Do not present inferred resolution as exact.
|
|
61
|
+
|
|
62
|
+
Discovery proves declaration candidates and supported import paths. It does not prove implementation behavior.
|
|
63
|
+
|
|
64
|
+
### Tier 4: Structural search
|
|
65
|
+
|
|
66
|
+
Use `ast_search` when the question is about source shape rather than declaration identity or literal text.
|
|
67
|
+
|
|
68
|
+
- Scope the search to one repository, package, subtree, or file.
|
|
69
|
+
- Pass `language` for directory targets. A supported file can infer it.
|
|
70
|
+
- Use `$NAME` for one node and `$$$NAME` for multiple nodes.
|
|
71
|
+
- Keep `resultLimit` narrow. Retrieve only selected match or enclosing-scope locators.
|
|
72
|
+
- Treat parser certainty and metavariable bindings as evidence. A syntactic match does not prove runtime behavior.
|
|
73
|
+
|
|
74
|
+
### Tier 5: Structure and orientation
|
|
75
|
+
|
|
76
|
+
Default to `outline` for code orientation:
|
|
77
|
+
|
|
78
|
+
- Known file: inspect declarations without bodies.
|
|
79
|
+
- Known package directory: inspect supported source files.
|
|
80
|
+
- Unfamiliar repository or subtree: set `recursive=true` before file-by-file work.
|
|
81
|
+
- Likely names: pass exact `names` to reduce native work and output.
|
|
82
|
+
- Internal behavior: set `includePrivate=true` only when private declarations matter.
|
|
83
|
+
- Documented API discovery: set `includeDocs=true` only when outline needs docs.
|
|
84
|
+
|
|
85
|
+
Outline ranges and locators answer most location, inventory, ownership, visibility, and declaration-shape questions. Do not retrieve bodies only to prove symbol exists.
|
|
86
|
+
|
|
87
|
+
### Tier 6: Relationships
|
|
88
|
+
|
|
89
|
+
Use a focused relationship tool after selecting a declaration or executable-scope locator:
|
|
90
|
+
|
|
91
|
+
- `references`: direct references and type usages.
|
|
92
|
+
- `callers`: direct call sites; preserve inferred-dispatch labels.
|
|
93
|
+
- `callees`: direct dependencies inside one executable scope.
|
|
94
|
+
- `implementations`: syntactic inheritance and conservative same-name overrides.
|
|
95
|
+
- `tests`: direct references in standard test files and containers.
|
|
96
|
+
|
|
97
|
+
Scope every request to the narrowest repository, package, or subtree that can answer it. Keep `resultLimit` narrow. Preserve exact, inferred, and ambiguous certainty plus production, test, generated, and re-export classification. Ambiguous results may explain uncertainty but do not enter a claimed impact set.
|
|
98
|
+
|
|
99
|
+
Relationship results prove the reported bounded syntactic relationship. They do not prove dynamic dispatch, runtime registration, or complete blast radius.
|
|
100
|
+
|
|
101
|
+
### Tier 7: Exact declarations
|
|
102
|
+
|
|
103
|
+
Use `symbol` only with locators returned by AST tools in this child session:
|
|
104
|
+
|
|
105
|
+
- `signature`: exact shape without docs or body.
|
|
106
|
+
- `signatureWithDocs`: documented contract.
|
|
107
|
+
- `declaration`: implementation needed for behavior or data flow.
|
|
108
|
+
- `declarationWithImports`: required imports matter.
|
|
109
|
+
|
|
110
|
+
For structural matches and relationships, choose the exact-match, target-declaration, or editable enclosing-scope locator that answers the question. Batch related locators. Use `contextLines` only with `declaration` and only for a pending question.
|
|
20
111
|
|
|
21
|
-
|
|
112
|
+
No `read` or `bash`. Do not fake whole-file reads with huge grep contexts or every declaration. Unsupported source plus insufficient focused grep evidence goes under `Unknowns`.
|
|
22
113
|
|
|
23
|
-
##
|
|
114
|
+
## Search procedure
|
|
24
115
|
|
|
25
|
-
1. Extract
|
|
26
|
-
2.
|
|
27
|
-
3.
|
|
28
|
-
4.
|
|
29
|
-
5.
|
|
116
|
+
1. Extract target, question, scope, and output shape.
|
|
117
|
+
2. List required claims. Pick lowest evidence tier for each.
|
|
118
|
+
3. Start from supplied paths and symbols. Search outward only for required relationships.
|
|
119
|
+
4. Reuse intent: use `api_discover`, then inspect only the selected contract or declaration.
|
|
120
|
+
5. Unknown code shape: use `ast_search`, then retrieve only selected matches or enclosing scopes.
|
|
121
|
+
6. Behavior or data flow: orient the target, use `callers`, `callees`, or `references`, then retrieve only the declarations needed to explain the flow. Use `grep` for literal registrations or unresolved textual consumers.
|
|
122
|
+
7. Impact: use `references`, `implementations`, and `tests` as applicable. State searched roots, limits, certainty, and classifications. Do not turn ambiguous results into affected code.
|
|
123
|
+
8. Stop when all requested fields have evidence. Put gaps under `Unknowns`.
|
|
30
124
|
|
|
31
|
-
Absolute paths may
|
|
125
|
+
Absolute paths may point to reference repositories outside cwd.
|
|
32
126
|
|
|
33
127
|
## Result shapes
|
|
34
128
|
|
|
35
|
-
Use
|
|
129
|
+
Use relevant sections only. Omit empty sections.
|
|
36
130
|
|
|
37
131
|
### Locate
|
|
38
132
|
|
|
@@ -41,10 +135,10 @@ Use only relevant sections. Omit empty sections.
|
|
|
41
135
|
### Explain behavior
|
|
42
136
|
|
|
43
137
|
- `Entry:` `path:start-end` — symbol
|
|
44
|
-
- `Flow:` ordered steps; one cited fact
|
|
138
|
+
- `Flow:` ordered steps; one cited fact each
|
|
45
139
|
- `Result:` observed outcome
|
|
46
140
|
|
|
47
|
-
|
|
141
|
+
Include only relevant branches.
|
|
48
142
|
|
|
49
143
|
### Trace data
|
|
50
144
|
|
|
@@ -54,7 +148,8 @@ Only branches relevant to requested behavior.
|
|
|
54
148
|
|
|
55
149
|
### Find references or impact
|
|
56
150
|
|
|
57
|
-
- `Direct references:` cited relationships
|
|
151
|
+
- `Direct references:` cited relationships with certainty and classification
|
|
152
|
+
- `Editable scopes:` selected enclosing declarations when inspection or change would be required
|
|
58
153
|
- `Behavior affected:` evidence-backed consequences
|
|
59
154
|
- `Unknowns:` remaining uncertainty
|
|
60
155
|
|
|
@@ -69,14 +164,14 @@ No speculative blast radius.
|
|
|
69
164
|
### Compare
|
|
70
165
|
|
|
71
166
|
- `Shared:` cited similarities
|
|
72
|
-
- `Differences:` cited
|
|
167
|
+
- `Differences:` cited by aspect
|
|
73
168
|
- `Relevant consequence:` requested consequences only
|
|
74
169
|
|
|
75
170
|
### Inventory
|
|
76
171
|
|
|
77
172
|
`path:start-end` — symbol — role
|
|
78
173
|
|
|
79
|
-
When completeness matters, state searched scope. If
|
|
174
|
+
When completeness matters, state searched scope and tiers. If uncertain, say why.
|
|
80
175
|
|
|
81
176
|
### Constraints and unknowns
|
|
82
177
|
|
|
@@ -86,6 +181,7 @@ When completeness matters, state searched scope. If completeness cannot be guara
|
|
|
86
181
|
## Reporting rules
|
|
87
182
|
|
|
88
183
|
- Every material code claim needs exact path, line range, and symbol when one exists.
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
184
|
+
- Cite ranges from `grep`, `outline`, or `symbol`. Never estimate line numbers.
|
|
185
|
+
- Separate fact from inference. Label inference.
|
|
186
|
+
- Quote smallest useful fragment. Prefer citation plus concise description over whole declaration.
|
|
187
|
+
- No preamble, search log, generic repository summary, repeated evidence, or unasked next steps.
|
|
@@ -40,7 +40,9 @@ Gives the agent `context_prune` for creating a hard context checkpoint after bro
|
|
|
40
40
|
|
|
41
41
|
## explore
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
`replace_declaration`, `replace_body`, `insert_declaration`, and `rename_declaration` apply stale-safe edits through numeric declaration locators. They validate syntax before writing, invalidate old locators, and return fresh locators after a clean reparse. For Markdown headings, declaration replacement rewrites the complete section while body replacement preserves the heading. Nested headings must remain deeper than the selected heading. Markdown insertion and rename remain unavailable. Code rename requires an explicit scope; inferred references require approval and ambiguous references remain unchanged.
|
|
44
|
+
|
|
45
|
+
Replaces Pi’s filesystem inspection tools with compact Tau versions: `ls`, `find`, `grep`, and `read`. It adds `api_discover` for repository-wide declaration and caller import-path discovery, `ast_search` for bounded ast-grep code-pattern search with metavariable bindings and retrievable match or enclosing-scope locators, plus `outline` for public declarations in TypeScript, TSX, Odin, Go, Rust, C#, Java, Kotlin, Swift, and Markdown files or package directories. `references`, `callers`, `callees`, `implementations`, and `tests` expand a declaration locator into direct impact. Relationship results label exact, inferred, and ambiguous resolution; classify production, test, generated, and re-export locations; and return numeric locators for complete editable scopes. Ambiguous results stay non-actionable. `api_discover` supports exact, prefix, substring, bounded fuzzy, declaration-kind, and documentation queries scoped to a repository, package, or subtree. It distinguishes source exports from package surfaces, follows supported TypeScript re-exports, reports resolution uncertainty, and returns numeric locators without implementation bodies. Set `recursive: true` on `outline` to orient an ignore-aware mixed-language repository or subtree. Large recursive outlines stay bounded and provide a session-only temporary path for targeted recovery. Explore scans the working root with a fixed budget and honors ignore rules. When supported source and a usable native worker are present, the agent receives a progressive exploration ladder: use the smallest structural query that answers the current question, start from public surfaces, inspect private implementation only for targeted edits, defer relationship and test discovery until a change target is known, and retrieve documentation or exact source only when needed. Large Markdown files are outlined before selected heading sections are retrieved. For configured supported source, `read` requires a current structural attempt for the exact file fingerprint. Direct file outlines and searches qualify, along with files returned by `symbol`, `api_discover`, structural search, and relationship tools. Markdown is excluded from the gate by default, and `extensions.explore.readGate` can narrow the gated paths. Fatal per-file parser failures permit a fingerprinted fallback, while unavailable workers and unsupported files retain ordinary reads. Markdown headings locate their complete sections. Exact-name filters and `includePrivate` narrow or expand that surface. Attached documentation comments are omitted by default; `includeDocs` adds them without hiding annotations or attributes. Parenthesized numbers identify declarations for `symbol`. Its `signature` view omits documentation and bodies, `signatureWithDocs` adds attached documentation without the body, `declaration` returns exact source, and `declarationWithImports` adds required imports. Batches reject every result when one locator is stale; exact declarations can include surrounding lines. Installed packages support the AST tools on Apple Silicon Macs without requiring Rust or Cargo; other platforms retain the rest of Explore and receive no AST-first requirement. The AST tools remain registered and report the platform limit when invoked. These tools produce smaller model payloads and readable tool rows. Repeated `read` calls return unchanged markers or useful diffs when branch history proves the agent already saw the base content. A successful Tau patch can return a trusted cached complete-file diff without another structural attempt when the retained baseline and resulting fingerprint match. `/read-stats` shows cache savings plus AST gate and byte-flow totals for the current chat and whole session.
|
|
44
46
|
|
|
45
47
|
## footer
|
|
46
48
|
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shanepadgett/tau-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Tau is a custom agentic harness built with pi extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
"README.md"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@shanepadgett/tau-tui": "0.
|
|
39
|
-
"@toon-format/toon": "2.3.0",
|
|
38
|
+
"@shanepadgett/tau-tui": "0.27.0",
|
|
40
39
|
"image-size": "2.0.2",
|
|
41
40
|
"smol-toml": "1.7.0"
|
|
42
41
|
},
|