@shanepadgett/tau-agent 0.2.1 → 0.4.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.
|
@@ -3,6 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import { createGitRunner, type GitRunner, loadRepoStatus } from "../../shared/git.ts";
|
|
5
5
|
import { errorText } from "../../shared/text.ts";
|
|
6
|
+
import { PublishActivityPanel, type PublishProgress } from "./publish-ui.ts";
|
|
6
7
|
|
|
7
8
|
const PACKAGE_PATHS = ["packages/tui/package.json", "packages/agent/package.json"] as const;
|
|
8
9
|
const LOCKFILE_PATH = "package-lock.json";
|
|
@@ -38,14 +39,10 @@ export default function publishExtension(pi: ExtensionAPI): void {
|
|
|
38
39
|
ctx.ui.notify("Publishing requires interactive confirmation.", "error");
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
|
-
ctx.ui.setStatus("publish", "preparing release");
|
|
42
42
|
try {
|
|
43
43
|
await publish(pi, ctx);
|
|
44
44
|
} catch (error) {
|
|
45
45
|
ctx.ui.notify(`Publish failed: ${errorText(error)}`, "error");
|
|
46
|
-
} finally {
|
|
47
|
-
ctx.ui.setStatus("publish", undefined);
|
|
48
|
-
ctx.ui.setWidget("publish", undefined);
|
|
49
46
|
}
|
|
50
47
|
},
|
|
51
48
|
});
|
|
@@ -86,19 +83,54 @@ async function publish(pi: ExtensionAPI, ctx: ExtensionCommandContext): Promise<
|
|
|
86
83
|
);
|
|
87
84
|
if (!confirmed) return;
|
|
88
85
|
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
if (ctx.mode !== "tui") {
|
|
87
|
+
await completePublish(pi, ctx, git, repo.root, manifests, tag, finalVersion, releaseTag);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const failure = await ctx.ui.custom<Error | undefined>((tui, theme, _keybindings, done) => {
|
|
91
|
+
const progress = new PublishActivityPanel(tui, theme, releaseTag);
|
|
92
|
+
void completePublish(pi, ctx, git, repo.root, manifests, tag, finalVersion, releaseTag, progress)
|
|
93
|
+
.then(() => done(undefined))
|
|
94
|
+
.catch((error) => done(error instanceof Error ? error : new Error(errorText(error))));
|
|
95
|
+
return progress;
|
|
96
|
+
});
|
|
97
|
+
if (failure) throw failure;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function completePublish(
|
|
101
|
+
pi: ExtensionAPI,
|
|
102
|
+
ctx: ExtensionCommandContext,
|
|
103
|
+
git: GitRunner,
|
|
104
|
+
root: string,
|
|
105
|
+
manifests: readonly PackageManifest[],
|
|
106
|
+
tag: string | undefined,
|
|
107
|
+
version: string,
|
|
108
|
+
releaseTag: string,
|
|
109
|
+
progress: PublishProgress | undefined = undefined,
|
|
110
|
+
): Promise<void> {
|
|
111
|
+
if (tag) {
|
|
112
|
+
progress?.update("write package versions");
|
|
113
|
+
await writeReleaseVersion(root, manifests, version);
|
|
114
|
+
}
|
|
115
|
+
progress?.update("npm pack --dry-run @shanepadgett/tau-tui");
|
|
116
|
+
await run(pi, ctx, "npm", ["pack", "--dry-run", "--workspace", "@shanepadgett/tau-tui"], root);
|
|
117
|
+
progress?.update("npm pack --dry-run @shanepadgett/tau-agent");
|
|
118
|
+
await run(pi, ctx, "npm", ["pack", "--dry-run", "--workspace", "@shanepadgett/tau-agent"], root);
|
|
93
119
|
|
|
94
120
|
if (tag) {
|
|
95
|
-
|
|
96
|
-
await git.run(["
|
|
121
|
+
progress?.update("git add release files");
|
|
122
|
+
await git.run(["add", ...PACKAGE_PATHS, LOCKFILE_PATH], { cwd: root });
|
|
123
|
+
progress?.update(`git commit chore(release): ${releaseTag}`);
|
|
124
|
+
await git.run(["commit", "-m", `chore(release): ${releaseTag}`], { cwd: root });
|
|
97
125
|
}
|
|
98
|
-
|
|
99
|
-
await git.run(["
|
|
100
|
-
|
|
101
|
-
await
|
|
126
|
+
progress?.update(`git tag ${releaseTag}`);
|
|
127
|
+
await git.run(["tag", releaseTag], { cwd: root });
|
|
128
|
+
progress?.update("git push origin HEAD");
|
|
129
|
+
await git.run(["push", "origin", "HEAD"], { cwd: root, timeout: 120_000 });
|
|
130
|
+
progress?.update(`git push origin ${releaseTag}`);
|
|
131
|
+
await git.run(["push", "origin", releaseTag], { cwd: root, timeout: 120_000 });
|
|
132
|
+
progress?.update("Waiting for GitHub Actions");
|
|
133
|
+
await monitorWorkflow(pi, ctx, root, await git.run(["rev-parse", "HEAD"], { cwd: root }), releaseTag, progress);
|
|
102
134
|
}
|
|
103
135
|
|
|
104
136
|
async function loadManifests(root: string): Promise<PackageManifest[]> {
|
|
@@ -188,6 +220,7 @@ async function monitorWorkflow(
|
|
|
188
220
|
root: string,
|
|
189
221
|
sha: string,
|
|
190
222
|
tag: string,
|
|
223
|
+
progress: PublishProgress | undefined = undefined,
|
|
191
224
|
): Promise<void> {
|
|
192
225
|
const deadline = Date.now() + WORKFLOW_WAIT_MS;
|
|
193
226
|
while (Date.now() < deadline) {
|
|
@@ -211,10 +244,19 @@ async function monitorWorkflow(
|
|
|
211
244
|
);
|
|
212
245
|
const workflowRun = (JSON.parse(output) as WorkflowRun[])[0];
|
|
213
246
|
if (workflowRun) {
|
|
214
|
-
|
|
247
|
+
progress?.update(`GitHub Actions: ${workflowRun.status}`, workflowRun.url);
|
|
215
248
|
if (workflowRun.status === "completed") {
|
|
216
249
|
if (workflowRun.conclusion === "success") {
|
|
217
|
-
|
|
250
|
+
const version = tag.slice(1);
|
|
251
|
+
ctx.ui.notify(
|
|
252
|
+
[
|
|
253
|
+
`Published ${tag}`,
|
|
254
|
+
`GitHub Actions: ${workflowRun.url}`,
|
|
255
|
+
`npm TUI: https://www.npmjs.com/package/@shanepadgett/tau-tui/v/${version}`,
|
|
256
|
+
`npm Agent: https://www.npmjs.com/package/@shanepadgett/tau-agent/v/${version}`,
|
|
257
|
+
].join("\n"),
|
|
258
|
+
"info",
|
|
259
|
+
);
|
|
218
260
|
return;
|
|
219
261
|
}
|
|
220
262
|
throw new Error(`GitHub Actions ${workflowRun.conclusion ?? "failed"}: ${workflowRun.url}`);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type Component, Text, type TUI } from "@earendil-works/pi-tui";
|
|
3
|
+
import { ToolPanel } from "@shanepadgett/tau-tui";
|
|
4
|
+
|
|
5
|
+
const RELEASE_STEPS = [
|
|
6
|
+
"write package versions",
|
|
7
|
+
"npm pack --dry-run @shanepadgett/tau-tui",
|
|
8
|
+
"npm pack --dry-run @shanepadgett/tau-agent",
|
|
9
|
+
"git add release files",
|
|
10
|
+
"git commit",
|
|
11
|
+
"git tag",
|
|
12
|
+
"git push origin HEAD",
|
|
13
|
+
"git push origin v",
|
|
14
|
+
"Waiting for GitHub Actions",
|
|
15
|
+
"GitHub Actions: publishing",
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
export interface PublishProgress {
|
|
19
|
+
update(status: string, detail?: string): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class PublishActivityPanel implements Component, PublishProgress {
|
|
23
|
+
private readonly tui: TUI;
|
|
24
|
+
private readonly theme: Theme;
|
|
25
|
+
private readonly body = new Text("", 0, 0);
|
|
26
|
+
private readonly panel: ToolPanel;
|
|
27
|
+
private status = "Preparing release";
|
|
28
|
+
private detail: string | undefined;
|
|
29
|
+
private readonly completed: string[] = ["Release confirmed"];
|
|
30
|
+
|
|
31
|
+
constructor(tui: TUI, theme: Theme, tag: string) {
|
|
32
|
+
this.tui = tui;
|
|
33
|
+
this.theme = theme;
|
|
34
|
+
this.panel = new ToolPanel(theme, {
|
|
35
|
+
title: `Publishing ${tag}`,
|
|
36
|
+
secondary: "Editor is unavailable until this release finishes.",
|
|
37
|
+
header: [theme.fg("muted", "GitHub Actions publishes through npm trusted publishing.")],
|
|
38
|
+
body: this.body,
|
|
39
|
+
footer: { kind: "hints", hints: [] },
|
|
40
|
+
});
|
|
41
|
+
this.renderBody();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
update(status: string, detail: string | undefined = undefined): void {
|
|
45
|
+
if (this.status !== "Preparing release" && this.status !== status) this.completed.push(this.status);
|
|
46
|
+
this.status = status;
|
|
47
|
+
this.detail = detail;
|
|
48
|
+
this.renderBody();
|
|
49
|
+
this.tui.requestRender();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
render(width: number): string[] {
|
|
53
|
+
return this.panel.render(width);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
invalidate(): void {
|
|
57
|
+
this.panel.invalidate();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private renderBody(): void {
|
|
61
|
+
const upcoming = RELEASE_STEPS.filter(
|
|
62
|
+
(step) => !this.completed.some((completed) => completed.startsWith(step)) && step !== this.status,
|
|
63
|
+
);
|
|
64
|
+
this.body.setText(
|
|
65
|
+
[
|
|
66
|
+
...this.completed.map((step) => this.theme.fg("success", `✓ ${step}`)),
|
|
67
|
+
this.theme.fg("accent", `… ${this.status}`),
|
|
68
|
+
...(this.detail ? [this.theme.fg("muted", this.detail)] : []),
|
|
69
|
+
...upcoming.map((step) => this.theme.fg("muted", `· ${step}`)),
|
|
70
|
+
].join("\n"),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shanepadgett/tau-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Tau is a custom agentic harness built with pi extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"README.md"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@shanepadgett/tau-tui": "0.
|
|
31
|
+
"@shanepadgett/tau-tui": "0.4.0",
|
|
32
32
|
"@toon-format/toon": "2.3.0"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|