@shanepadgett/tau-agent 0.1.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/README.md +30 -0
- package/docs/extending-tau-agent.md +119 -0
- package/docs/subagents.md +57 -0
- package/docs/tui.md +107 -0
- package/extensions/appshot/README.md +11 -0
- package/extensions/appshot/capture.swift +191 -0
- package/extensions/appshot/index.ts +245 -0
- package/extensions/appshot/native-helper.ts +102 -0
- package/extensions/attention/README.md +23 -0
- package/extensions/attention/index.ts +71 -0
- package/extensions/auto-name/README.md +26 -0
- package/extensions/auto-name/index.ts +163 -0
- package/extensions/branch/README.md +22 -0
- package/extensions/branch/index.ts +145 -0
- package/extensions/branch/panel.ts +148 -0
- package/extensions/clear-screen/README.md +29 -0
- package/extensions/clear-screen/index.ts +75 -0
- package/extensions/commit/README.md +15 -0
- package/extensions/commit/commit-plan.ts +328 -0
- package/extensions/commit/git-change-set.ts +268 -0
- package/extensions/commit/index.ts +138 -0
- package/extensions/commit/review-ui.ts +745 -0
- package/extensions/explore/README.md +7 -0
- package/extensions/explore/autoread.ts +140 -0
- package/extensions/explore/find.ts +147 -0
- package/extensions/explore/grep.ts +749 -0
- package/extensions/explore/index.ts +17 -0
- package/extensions/explore/limits.ts +22 -0
- package/extensions/explore/ls.ts +113 -0
- package/extensions/explore/path-display.ts +41 -0
- package/extensions/explore/path-tree.ts +150 -0
- package/extensions/explore/read.ts +160 -0
- package/extensions/explore/result.ts +29 -0
- package/extensions/explore/traverse.ts +226 -0
- package/extensions/footer/README.md +23 -0
- package/extensions/footer/index.ts +534 -0
- package/extensions/footer/settings.ts +13 -0
- package/extensions/ideas/README.md +10 -0
- package/extensions/ideas/browser.ts +66 -0
- package/extensions/ideas/index.ts +31 -0
- package/extensions/ideas/store.ts +32 -0
- package/extensions/image-gen/README.md +11 -0
- package/extensions/image-gen/client.ts +186 -0
- package/extensions/image-gen/index.ts +152 -0
- package/extensions/manage-sessions/README.md +12 -0
- package/extensions/manage-sessions/index.ts +58 -0
- package/extensions/manage-sessions/manager-ui.ts +323 -0
- package/extensions/manage-sessions/sessions.ts +126 -0
- package/extensions/patch/README.md +48 -0
- package/extensions/patch/executor.ts +355 -0
- package/extensions/patch/index.ts +170 -0
- package/extensions/patch/matcher.ts +236 -0
- package/extensions/patch/parser.ts +347 -0
- package/extensions/patch/render.ts +247 -0
- package/extensions/patch/summary.ts +35 -0
- package/extensions/publish/README.md +11 -0
- package/extensions/publish/index.ts +225 -0
- package/extensions/qna/README.md +45 -0
- package/extensions/qna/additional-context-body.ts +51 -0
- package/extensions/qna/body-render.ts +6 -0
- package/extensions/qna/choice-question-body.ts +322 -0
- package/extensions/qna/index.ts +245 -0
- package/extensions/qna/inline-editor-row.ts +56 -0
- package/extensions/qna/input-question-body.ts +89 -0
- package/extensions/qna/model.ts +317 -0
- package/extensions/qna/panel.ts +240 -0
- package/extensions/qna/ui.ts +16 -0
- package/extensions/reference/README.md +47 -0
- package/extensions/reference/index.ts +76 -0
- package/extensions/reference/panel.ts +874 -0
- package/extensions/reference/settings.ts +29 -0
- package/extensions/run-summary/README.md +5 -0
- package/extensions/run-summary/index.ts +98 -0
- package/extensions/silent-command-runner/README.md +25 -0
- package/extensions/silent-command-runner/index.ts +468 -0
- package/extensions/silent-command-runner/settings.ts +65 -0
- package/extensions/soul/README.md +19 -0
- package/extensions/soul/index.ts +20 -0
- package/extensions/soul/prompt.ts +254 -0
- package/extensions/soul/settings.ts +13 -0
- package/extensions/stash/README.md +48 -0
- package/extensions/stash/browser.ts +51 -0
- package/extensions/stash/index.ts +55 -0
- package/extensions/stash/store.ts +36 -0
- package/extensions/subagent/README.md +34 -0
- package/extensions/subagent/agents/scout.md +85 -0
- package/extensions/subagent/agents/web-research.md +95 -0
- package/extensions/subagent/agents.ts +196 -0
- package/extensions/subagent/index.ts +214 -0
- package/extensions/subagent/render.ts +89 -0
- package/extensions/subagent/run.ts +325 -0
- package/extensions/tau/README.md +17 -0
- package/extensions/tau/index.ts +122 -0
- package/extensions/tau-help/README.md +3 -0
- package/extensions/tau-help/help.md +125 -0
- package/extensions/tau-help/index.ts +68 -0
- package/extensions/turn-budget/README.md +14 -0
- package/extensions/turn-budget/index.ts +150 -0
- package/extensions/turn-budget/settings.ts +35 -0
- package/extensions/web/README.md +13 -0
- package/extensions/web/codesearch.ts +79 -0
- package/extensions/web/exa.ts +101 -0
- package/extensions/web/html.ts +67 -0
- package/extensions/web/index.ts +13 -0
- package/extensions/web/limits.ts +11 -0
- package/extensions/web/tool-output.ts +54 -0
- package/extensions/web/webfetch.ts +177 -0
- package/extensions/web/websearch.ts +100 -0
- package/package.json +57 -0
- package/prompts/.gitkeep +1 -0
- package/prompts/cavemanify.md +25 -0
- package/prompts/implement.md +25 -0
- package/prompts/interview.md +48 -0
- package/prompts/plan-feature.md +30 -0
- package/prompts/plan-implementation.md +50 -0
- package/schemas/tau.schema.json +205 -0
- package/shared/agent-blocked.ts +12 -0
- package/shared/description.ts +28 -0
- package/shared/events.ts +135 -0
- package/shared/git.ts +41 -0
- package/shared/injected-context.ts +69 -0
- package/shared/jsonl-store.ts +108 -0
- package/shared/model-fallback/index.ts +278 -0
- package/shared/model-fallback/settings.ts +18 -0
- package/shared/model-fallback/types.ts +8 -0
- package/shared/ranges.ts +21 -0
- package/shared/settings/define.ts +15 -0
- package/shared/settings/files.ts +20 -0
- package/shared/settings/json.ts +41 -0
- package/shared/settings/load.ts +59 -0
- package/shared/settings/merge.ts +21 -0
- package/shared/settings/paths.ts +41 -0
- package/shared/settings/schema.ts +25 -0
- package/shared/settings/specs.ts +23 -0
- package/shared/text.ts +11 -0
- package/shared/tool-row-state.ts +43 -0
- package/skills/writing-preferences/SKILL.md +136 -0
- package/themes/.gitkeep +1 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { emitAgentBlocked } from "../../shared/agent-blocked.ts";
|
|
3
|
+
import { createGitRunner, type GitRunner, loadRepoStatus } from "../../shared/git.ts";
|
|
4
|
+
import { errorText } from "../../shared/text.ts";
|
|
5
|
+
import { type CommitPlanState, generatePlan } from "./commit-plan.ts";
|
|
6
|
+
import {
|
|
7
|
+
assertCommittableState,
|
|
8
|
+
commitStaged,
|
|
9
|
+
computeWorktreeSignature,
|
|
10
|
+
type DirtyFile,
|
|
11
|
+
loadChangeSet,
|
|
12
|
+
stageFilesOnly,
|
|
13
|
+
} from "./git-change-set.ts";
|
|
14
|
+
import { reviewPlan } from "./review-ui.ts";
|
|
15
|
+
|
|
16
|
+
const COMMIT_MARKER_TYPE = "tau.commit";
|
|
17
|
+
const PUSH_TIMEOUT_MS = 120_000;
|
|
18
|
+
|
|
19
|
+
interface CommitMarker {
|
|
20
|
+
hash: string;
|
|
21
|
+
subject: string;
|
|
22
|
+
timestamp: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default function commitExtension(pi: ExtensionAPI): void {
|
|
26
|
+
pi.registerCommand("commit", {
|
|
27
|
+
description: "Generate semantic commit groups and commit selected repository changes",
|
|
28
|
+
handler: async (_args, ctx) => {
|
|
29
|
+
await ctx.waitForIdle();
|
|
30
|
+
ctx.ui.setStatus("commit", "preparing commit plan");
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
await runCommit(pi, ctx);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
ctx.ui.notify(`Commit failed: ${errorText(error)}`, "error");
|
|
36
|
+
} finally {
|
|
37
|
+
ctx.ui.setStatus("commit", undefined);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function runCommit(pi: ExtensionAPI, ctx: ExtensionCommandContext): Promise<void> {
|
|
44
|
+
const git = createGitRunner(pi, ctx);
|
|
45
|
+
const repo = await loadRepoStatus(git);
|
|
46
|
+
if (!repo) {
|
|
47
|
+
ctx.ui.notify("No git repository found.", "info");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (repo.fileCount === 0) {
|
|
51
|
+
ctx.ui.notify("No uncommitted changes detected.", "info");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (ctx.hasUI && ctx.mode !== "tui") {
|
|
55
|
+
ctx.ui.notify("Commit review UI requires TUI mode.", "error");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const evidence = await loadChangeSet(git, repo.root, ctx.sessionManager.getBranch(), COMMIT_MARKER_TYPE);
|
|
60
|
+
assertCommittableState(evidence.files);
|
|
61
|
+
let state: CommitPlanState = {
|
|
62
|
+
files: evidence.files,
|
|
63
|
+
worktreeSignature: await computeWorktreeSignature(git, repo.root, evidence.files),
|
|
64
|
+
groups: await generatePlan(ctx, evidence),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
if (ctx.hasUI) {
|
|
68
|
+
emitAgentBlocked(pi, { body: "Waiting for commit plan review", source: "commit.review" });
|
|
69
|
+
const reviewed = await reviewPlan(ctx, git, repo.root, evidence, state, state.groups[0]?.id, COMMIT_MARKER_TYPE);
|
|
70
|
+
if (!reviewed) return;
|
|
71
|
+
state = reviewed;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const completed = await executePlan(pi, ctx, git, repo.root, state);
|
|
75
|
+
if (completed.length === 0) return;
|
|
76
|
+
|
|
77
|
+
if (ctx.hasUI && (await ctx.ui.confirm("Push after commits?", "Run `git push` after all commits succeeded?"))) {
|
|
78
|
+
ctx.ui.setStatus("commit", "pushing");
|
|
79
|
+
await git.run(["push"], { cwd: repo.root, timeout: PUSH_TIMEOUT_MS });
|
|
80
|
+
ctx.ui.notify(
|
|
81
|
+
`Committed and pushed ${completed.length} commit(s): ${completed.map((item) => item.hash).join(", ")}`,
|
|
82
|
+
"info",
|
|
83
|
+
);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ctx.ui.notify(`Committed ${completed.length} commit(s): ${completed.map((item) => item.hash).join(", ")}`, "info");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function executePlan(
|
|
91
|
+
pi: ExtensionAPI,
|
|
92
|
+
ctx: ExtensionCommandContext,
|
|
93
|
+
git: GitRunner,
|
|
94
|
+
root: string,
|
|
95
|
+
state: CommitPlanState,
|
|
96
|
+
): Promise<CommitMarker[]> {
|
|
97
|
+
const groups = state.groups.filter((group) => group.files.length > 0);
|
|
98
|
+
if (groups.length === 0) {
|
|
99
|
+
ctx.ui.notify("No commit groups to execute.", "info");
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if ((await computeWorktreeSignature(git, root, state.files)) !== state.worktreeSignature) {
|
|
104
|
+
throw new Error("Working tree changed during commit review. Regenerate the commit plan and try again.");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const filesByPath = new Map(state.files.map((file) => [file.path, file]));
|
|
108
|
+
const completed: CommitMarker[] = [];
|
|
109
|
+
try {
|
|
110
|
+
for (const group of groups) {
|
|
111
|
+
const subject = group.message.split("\n")[0] ?? group.message;
|
|
112
|
+
ctx.ui.setStatus("commit", `committing ${subject}`);
|
|
113
|
+
await stageFilesOnly(
|
|
114
|
+
git,
|
|
115
|
+
root,
|
|
116
|
+
group.files.flatMap((path) => knownFile(filesByPath, path)),
|
|
117
|
+
);
|
|
118
|
+
const hash = await commitStaged(git, root, group.message);
|
|
119
|
+
const marker = { hash, subject, timestamp: Date.now() };
|
|
120
|
+
completed.push(marker);
|
|
121
|
+
pi.appendEntry<CommitMarker>(COMMIT_MARKER_TYPE, marker);
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (completed.length > 0) {
|
|
125
|
+
ctx.ui.notify(
|
|
126
|
+
`Partially committed ${completed.length}: ${completed.map((item) => item.hash).join(", ")}; then failed: ${errorText(error)}`,
|
|
127
|
+
"warning",
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
return completed;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function knownFile(filesByPath: ReadonlyMap<string, DirtyFile>, path: string): DirtyFile[] {
|
|
136
|
+
const file = filesByPath.get(path);
|
|
137
|
+
return file ? [file] : [];
|
|
138
|
+
}
|