@shanepadgett/tau-agent 0.27.0 → 0.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/extensions/context/sync.ts +1 -9
  2. package/extensions/context-pruning/prune.ts +2 -2
  3. package/extensions/explore/README.md +13 -21
  4. package/extensions/explore/ast/adapter.ts +97 -0
  5. package/extensions/explore/ast/engine.ts +470 -0
  6. package/extensions/explore/ast/format/ast-search.ts +97 -0
  7. package/extensions/explore/ast/format/composite.ts +26 -0
  8. package/extensions/explore/ast/format/context.ts +66 -0
  9. package/extensions/explore/ast/format/deps.ts +86 -0
  10. package/extensions/explore/ast/format/discover.ts +85 -0
  11. package/extensions/explore/ast/format/impact.ts +105 -0
  12. package/extensions/explore/ast/format/outline.ts +66 -0
  13. package/extensions/explore/ast/format/relationships.ts +81 -0
  14. package/extensions/explore/ast/format/show.ts +38 -0
  15. package/extensions/explore/ast/grammars/kotlin.wasm +0 -0
  16. package/extensions/explore/ast/grammars/manifest.json +41 -0
  17. package/extensions/explore/ast/grammars/manifest.ts +99 -0
  18. package/extensions/explore/ast/grammars/odin.wasm +0 -0
  19. package/extensions/explore/ast/grammars/swift.wasm +0 -0
  20. package/extensions/explore/ast/graph/file-graph.ts +360 -0
  21. package/extensions/explore/ast/graph/relationships.ts +597 -0
  22. package/extensions/explore/ast/identity.ts +119 -0
  23. package/extensions/explore/ast/ir.ts +136 -0
  24. package/extensions/explore/ast/languages/csharp-file-deps.ts +189 -0
  25. package/extensions/explore/ast/languages/csharp.ts +493 -0
  26. package/extensions/explore/ast/languages/file-dep-util.ts +120 -0
  27. package/extensions/explore/ast/languages/fixtures/sample.cs +17 -0
  28. package/extensions/explore/ast/languages/fixtures/sample.java +21 -0
  29. package/extensions/explore/ast/languages/fixtures/sample.kt +15 -0
  30. package/extensions/explore/ast/languages/fixtures/sample.odin +28 -0
  31. package/extensions/explore/ast/languages/fixtures/sample.rs +31 -0
  32. package/extensions/explore/ast/languages/fixtures/sample.swift +25 -0
  33. package/extensions/explore/ast/languages/go-file-deps.ts +139 -0
  34. package/extensions/explore/ast/languages/go.ts +545 -0
  35. package/extensions/explore/ast/languages/java.ts +412 -0
  36. package/extensions/explore/ast/languages/jvm-file-deps.ts +217 -0
  37. package/extensions/explore/ast/languages/kotlin.ts +611 -0
  38. package/extensions/explore/ast/languages/odin-file-deps.ts +175 -0
  39. package/extensions/explore/ast/languages/odin.ts +407 -0
  40. package/extensions/explore/ast/languages/rust-file-deps.ts +159 -0
  41. package/extensions/explore/ast/languages/rust.ts +506 -0
  42. package/extensions/explore/ast/languages/swift-file-deps.ts +59 -0
  43. package/extensions/explore/ast/languages/swift.ts +466 -0
  44. package/extensions/explore/ast/languages/tree.ts +220 -0
  45. package/extensions/explore/ast/languages/typescript-file-deps.ts +259 -0
  46. package/extensions/explore/ast/languages/typescript-package-surface.ts +440 -0
  47. package/extensions/explore/ast/languages/typescript.ts +751 -0
  48. package/extensions/explore/ast/markdown.ts +145 -0
  49. package/extensions/explore/ast/package-surface.ts +42 -0
  50. package/extensions/explore/ast/queries/ast-search.ts +306 -0
  51. package/extensions/explore/ast/queries/composite-target.ts +77 -0
  52. package/extensions/explore/ast/queries/context.ts +406 -0
  53. package/extensions/explore/ast/queries/discover.ts +427 -0
  54. package/extensions/explore/ast/queries/impact.ts +250 -0
  55. package/extensions/explore/ast/queries/outline.ts +203 -0
  56. package/extensions/explore/ast/queries/show.ts +262 -0
  57. package/extensions/explore/ast/query.ts +48 -0
  58. package/extensions/explore/ast/read/hook.ts +125 -0
  59. package/extensions/explore/ast/read/policy.ts +55 -0
  60. package/extensions/explore/ast/registry.ts +120 -0
  61. package/extensions/explore/ast/scan.ts +76 -0
  62. package/extensions/explore/ast/slice.ts +44 -0
  63. package/extensions/explore/ast/tools/ast-search.ts +138 -0
  64. package/extensions/explore/ast/tools/context.ts +126 -0
  65. package/extensions/explore/ast/tools/deps.ts +72 -0
  66. package/extensions/explore/ast/tools/discover.ts +208 -0
  67. package/extensions/explore/ast/tools/impact.ts +135 -0
  68. package/extensions/explore/ast/tools/outline.ts +200 -0
  69. package/extensions/explore/ast/tools/relationships.ts +160 -0
  70. package/extensions/explore/ast/tools/render.ts +121 -0
  71. package/extensions/explore/ast/tools/reverse-deps.ts +72 -0
  72. package/extensions/explore/ast/tools/show.ts +116 -0
  73. package/extensions/explore/guidance.ts +52 -0
  74. package/extensions/explore/index.ts +82 -92
  75. package/extensions/explore/read/autoread.ts +118 -0
  76. package/extensions/explore/settings.ts +49 -31
  77. package/extensions/explore/traverse.ts +254 -91
  78. package/extensions/handoff/index.ts +1 -1
  79. package/extensions/publish/index.ts +18 -85
  80. package/extensions/publish/publish-ui.ts +0 -4
  81. package/extensions/soul/README.md +7 -4
  82. package/extensions/soul/index.ts +11 -5
  83. package/extensions/soul/prompt.ts +31 -13
  84. package/extensions/soul/settings.ts +7 -2
  85. package/extensions/subagent/agents/context-sync.md +6 -10
  86. package/extensions/subagent/agents/review.md +24 -55
  87. package/extensions/subagent/agents/scout.md +38 -115
  88. package/extensions/subagent/run.ts +1 -1
  89. package/extensions/tau-help/help.md +2 -4
  90. package/package.json +6 -4
  91. package/schemas/tau.schema.json +35 -30
  92. package/{extensions/explore → shared}/autoread.ts +21 -7
  93. package/shared/events.ts +1 -1
  94. package/shared/full-file-knowledge.ts +49 -0
  95. package/extensions/explore/ast-guidance.ts +0 -67
  96. package/extensions/explore/ast-languages.ts +0 -61
  97. package/extensions/explore/ast-tools.ts +0 -1994
  98. package/extensions/explore/ast-worker.ts +0 -1025
  99. package/extensions/explore/find.ts +0 -147
  100. package/extensions/explore/full-file-knowledge.ts +0 -234
  101. package/extensions/explore/grep.ts +0 -749
  102. package/extensions/explore/limits.ts +0 -22
  103. package/extensions/explore/ls.ts +0 -113
  104. package/extensions/explore/orientation-state.ts +0 -280
  105. package/extensions/explore/path-display.ts +0 -41
  106. package/extensions/explore/path-tree.ts +0 -150
  107. package/extensions/explore/read-cache.ts +0 -273
  108. package/extensions/explore/read-snapshots.ts +0 -57
  109. package/extensions/explore/read-stats-panel.ts +0 -176
  110. package/extensions/explore/read-stats.ts +0 -138
  111. package/extensions/explore/read.ts +0 -372
  112. package/extensions/explore/result.ts +0 -29
  113. package/native-bin/darwin-arm64/tau-ast +0 -0
@@ -2,11 +2,10 @@ import { createHash } from "node:crypto";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { resolve } from "node:path";
4
4
  import type { ExtensionAPI, Theme } from "@earendil-works/pi-coding-agent";
5
- import { onTauEvent, type TauAgentEvents } from "../../shared/events.js";
6
- import type { ToolRowStateStore } from "../../shared/tool-row-state.js";
7
5
  import { Marker, type MarkerState } from "@shanepadgett/tau-tui";
8
- import { createCompleteFileMeta } from "./full-file-knowledge.ts";
9
- import type { ReadCacheMetaV1 } from "./read-cache.ts";
6
+ import { onTauEvent, type TauAgentEvents } from "./events.js";
7
+ import { createCompleteFileMeta, type ReadCacheMetaV1 } from "./full-file-knowledge.ts";
8
+ import type { ToolRowStateStore } from "./tool-row-state.js";
10
9
 
11
10
  const AUTOREAD_MESSAGE_TYPE = "tau.autoread";
12
11
 
@@ -30,6 +29,17 @@ export interface PreparedAutoreadMessage {
30
29
  details: AutoreadDetails & { status: "read"; readCache: ReadCacheMetaV1 };
31
30
  }
32
31
 
32
+ export type PrepareAutoreadMessage = (options: {
33
+ rowId: string;
34
+ path: string;
35
+ cwd: string;
36
+ source: string;
37
+ batchId: string;
38
+ signal: AbortSignal | undefined;
39
+ isLifecycleCurrent: () => boolean;
40
+ maximumBytes?: number;
41
+ }) => Promise<PreparedAutoreadMessage>;
42
+
33
43
  export async function prepareAutoreadMessage(options: {
34
44
  rowId: string;
35
45
  path: string;
@@ -76,7 +86,11 @@ export async function prepareAutoreadMessage(options: {
76
86
  };
77
87
  }
78
88
 
79
- export function registerAutoread(pi: ExtensionAPI, rowState: ToolRowStateStore): void {
89
+ export function registerAutoread(
90
+ pi: ExtensionAPI,
91
+ rowState: ToolRowStateStore,
92
+ prepare: PrepareAutoreadMessage = prepareAutoreadMessage,
93
+ ): void {
80
94
  let lifecycleGeneration = 0;
81
95
  pi.on("session_start", () => {
82
96
  lifecycleGeneration += 1;
@@ -90,7 +104,7 @@ export function registerAutoread(pi: ExtensionAPI, rowState: ToolRowStateStore):
90
104
  pi.on("session_shutdown", () => {
91
105
  lifecycleGeneration += 1;
92
106
  });
93
- onTauEvent(pi, "explore.autoread", "tau:autoread.requested", async (data) => {
107
+ onTauEvent(pi, "shared.autoread", "tau:autoread.requested", async (data) => {
94
108
  const event = readAutoreadRequestedEvent(data);
95
109
  if (!event) return;
96
110
  const generation = lifecycleGeneration;
@@ -105,7 +119,7 @@ export function registerAutoread(pi: ExtensionAPI, rowState: ToolRowStateStore):
105
119
  batchId: event.batchId,
106
120
  } satisfies Omit<AutoreadDetails, "status" | "error">;
107
121
  try {
108
- const message = await prepareAutoreadMessage({
122
+ const message = await prepare({
109
123
  ...details,
110
124
  signal: undefined,
111
125
  isLifecycleCurrent: () => generation === lifecycleGeneration,
package/shared/events.ts CHANGED
@@ -15,7 +15,7 @@ export type TauAgentEvents = {
15
15
  disposition: "notify" | "discard";
16
16
  };
17
17
  "tau:file-mutation.applied": {
18
- source: "patch" | "locatorEdit";
18
+ source: "patch";
19
19
  toolCallId: string;
20
20
  cwd: string;
21
21
  status: "completed" | "partial" | "failed";
@@ -0,0 +1,49 @@
1
+ type ReadCacheMode = "baseline" | "recovery" | "unchanged" | "diff";
2
+ type ReadCachePresentation = "plain" | "line-numbered";
3
+
4
+ export interface ReadCacheMetaV1 {
5
+ v: 1;
6
+ pathKey: string;
7
+ scopeKey: string;
8
+ presentation: ReadCachePresentation;
9
+ servedHash: string;
10
+ baseHash?: string;
11
+ mode: ReadCacheMode;
12
+ baselineTokens: number;
13
+ returnedTokens: number;
14
+ totalLines: number;
15
+ summary: string;
16
+ }
17
+
18
+ const COMPLETE_FILE_SCOPE = "full";
19
+ export const MAX_COMPLETE_FILE_SNAPSHOT_BYTES = 1024 * 1024;
20
+
21
+ export function createCompleteFileMeta(options: {
22
+ pathKey: string;
23
+ presentation: ReadCachePresentation;
24
+ servedHash: string;
25
+ mode: ReadCacheMode;
26
+ sourceText: string;
27
+ returnedText: string;
28
+ totalLines: number;
29
+ summary: string;
30
+ baseHash?: string;
31
+ }): ReadCacheMetaV1 {
32
+ return {
33
+ v: 1,
34
+ pathKey: options.pathKey,
35
+ scopeKey: COMPLETE_FILE_SCOPE,
36
+ presentation: options.presentation,
37
+ servedHash: options.servedHash,
38
+ baseHash: options.baseHash,
39
+ mode: options.mode,
40
+ baselineTokens: estimateTokens(options.sourceText),
41
+ returnedTokens: estimateTokens(options.returnedText),
42
+ totalLines: options.totalLines,
43
+ summary: options.summary,
44
+ };
45
+ }
46
+
47
+ function estimateTokens(text: string): number {
48
+ return Math.ceil(text.length / 4);
49
+ }
@@ -1,67 +0,0 @@
1
- import {
2
- AST_LANGUAGE_REGISTRY,
3
- astLanguageForPath,
4
- formatAstLanguageLabels,
5
- type AstLanguage,
6
- } from "./ast-languages.ts";
7
- import { collectPaths } from "./traverse.ts";
8
-
9
- export const AST_DISCOVERY_BUDGET = 4096;
10
-
11
- export interface AstGuidanceRequest {
12
- cwd: string;
13
- workerLanguages(): Promise<readonly AstLanguage[]>;
14
- discoveryBudget: number;
15
- }
16
-
17
- export async function effectiveAstGuidance(request: AstGuidanceRequest): Promise<string | undefined> {
18
- let detected: Set<AstLanguage>;
19
- try {
20
- const entries = await collectPaths({
21
- cwd: request.cwd,
22
- root: request.cwd,
23
- maxEntries: request.discoveryBudget,
24
- includeRoot: false,
25
- includeHidden: true,
26
- includeIgnored: false,
27
- includeNoise: false,
28
- });
29
- detected = new Set(
30
- entries.flatMap((entry) => {
31
- if (entry.type !== "file") return [];
32
- const language = astLanguageForPath(entry.absolutePath);
33
- return language ? [language] : [];
34
- }),
35
- );
36
- } catch {
37
- return undefined;
38
- }
39
-
40
- if (detected.size === 0) return undefined;
41
- let workerLanguages: readonly AstLanguage[];
42
- try {
43
- workerLanguages = await request.workerLanguages();
44
- } catch {
45
- return undefined;
46
- }
47
- const available = new Set(workerLanguages);
48
- const languages = AST_LANGUAGE_REGISTRY.filter(
49
- (language) => detected.has(language.workerLanguage) && available.has(language.workerLanguage),
50
- );
51
- if (languages.length === 0) return undefined;
52
- const labels = formatAstLanguageLabels(languages, "and");
53
- return `## Explore source policy
54
-
55
- AST-backed exploration is available here for ${labels}.
56
-
57
- - Use the smallest structural query that can answer the current question. Stop when the result is sufficient; expand only for a specific unresolved question.
58
- - Identify the current job before exploring: locate, reuse, edit, explain, or debug. Do not preload implementation, callers, tests, or documentation needed only by a later stage.
59
- - For an unfamiliar repository or subtree, use recursive \`outline\` when available. Otherwise find a likely package, then outline that directory. For a known package or file, outline it directly.
60
- - Outline large Markdown files first, then retrieve only the relevant heading section with \`symbol\`.
61
- - For reuse work with an unknown location, use \`api_discover\` and prefer \`packageSurface\`, \`sourceExport\`, or \`public\` results. Inspect private declarations only when targeted implementation work requires them.
62
- - Narrow paths, exact \`names\`, query work, and result limits as soon as the likely target is known.
63
- - Treat a clear outline or API candidate signature as enough. Use \`symbol(signature)\` only when that selected contract needs closer inspection, \`signatureWithDocs\` only when attached documentation matters, and declaration views only for exact implementation source.
64
- - Discover references, callers, implementations, and affected tests after selecting a change target and when that impact information can change the plan. Do not inspect tests up front unless the task starts from test behavior or a failure.
65
- - Use \`ast_search\` for code shapes and \`grep\` for literal text. Use targeted \`read\` for exact formatting, comments, unsupported files, or source outside declaration boundaries.
66
- - Prefer locator edits for a known declaration or body when they express the complete change cleanly. Use textual patching when the change crosses structural boundaries or depends on exact surrounding text.`;
67
- }
@@ -1,61 +0,0 @@
1
- import { basename, extname } from "node:path";
2
-
3
- export const AST_LANGUAGE_REGISTRY = [
4
- {
5
- id: "typescript",
6
- label: "TypeScript",
7
- extensions: [".ts"],
8
- workerLanguage: "typeScript",
9
- },
10
- { id: "tsx", label: "TSX", extensions: [".tsx"], workerLanguage: "tsx" },
11
- { id: "odin", label: "Odin", extensions: [".odin"], workerLanguage: "odin" },
12
- { id: "go", label: "Go", extensions: [".go"], workerLanguage: "go" },
13
- { id: "rust", label: "Rust", extensions: [".rs"], workerLanguage: "rust" },
14
- { id: "csharp", label: "C#", extensions: [".cs"], workerLanguage: "cSharp" },
15
- { id: "java", label: "Java", extensions: [".java"], workerLanguage: "java" },
16
- {
17
- id: "kotlin",
18
- label: "Kotlin",
19
- extensions: [".kt", ".ktm", ".kts"],
20
- workerLanguage: "kotlin",
21
- },
22
- { id: "swift", label: "Swift", extensions: [".swift"], workerLanguage: "swift" },
23
- {
24
- id: "markdown",
25
- label: "Markdown",
26
- extensions: [".md", ".markdown", ".mdown"],
27
- workerLanguage: "markdown",
28
- },
29
- ] as const;
30
-
31
- export type AstLanguageDefinition = (typeof AST_LANGUAGE_REGISTRY)[number];
32
- export type AstLanguage = AstLanguageDefinition["workerLanguage"];
33
-
34
- export function isAstLanguage(value: unknown): value is AstLanguage {
35
- return AST_LANGUAGE_REGISTRY.some((language) => language.workerLanguage === value);
36
- }
37
-
38
- export function astLanguageForPath(path: string): AstLanguage | undefined {
39
- const extension = extname(basename(path)).toLowerCase();
40
- for (const language of AST_LANGUAGE_REGISTRY) {
41
- const extensions: readonly string[] = language.extensions;
42
- if (extensions.includes(extension)) return language.workerLanguage;
43
- }
44
- return undefined;
45
- }
46
-
47
- export function requireAstLanguageForPath(path: string): AstLanguage {
48
- const language = astLanguageForPath(path);
49
- if (language) return language;
50
- throw new Error(`Unsupported outline file type: ${extname(path) || "no extension"}`);
51
- }
52
-
53
- export function formatAstLanguageLabels(
54
- languages: readonly Pick<AstLanguageDefinition, "label">[],
55
- conjunction: "and" | "or",
56
- ): string {
57
- const labels = languages.map((language) => language.label);
58
- if (labels.length < 2) return labels[0] ?? "";
59
- if (labels.length === 2) return `${labels[0]} ${conjunction} ${labels[1]}`;
60
- return `${labels.slice(0, -1).join(", ")}, ${conjunction} ${labels.at(-1)}`;
61
- }