pi-baton 0.7.2 → 0.7.3
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/CHANGELOG.md +12 -2
- package/README.md +1 -1
- package/docs/incidents/2026-07-04-publish-duplicate-version.md +249 -0
- package/extensions/index.ts +7 -2
- package/lib/run-store.ts +21 -2
- package/lib/status.ts +14 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,14 +6,24 @@ This project follows semantic versioning.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Bump package version to `0.7.3` for the next patch release.
|
|
12
|
+
|
|
13
|
+
## [0.7.2] - 2026-07-04
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- `/baton:status` now shows the most recent finished run summary (state, last step, iteration, run directory) after a run reaches `completed` or `failed`, with clear finished-run framing instead of the no-active-run message.
|
|
18
|
+
|
|
19
|
+
- Buy Me a Coffee sponsor button in README and native GitHub funding link via `.github/FUNDING.yml`.
|
|
10
20
|
|
|
11
21
|
### Changed
|
|
12
22
|
|
|
13
23
|
- Merged Dependabot PR #14: bump `@earendil-works/pi-ai` devDependency from 0.78.1 to 0.80.2 (type-check clean, 57/57 tests passing).
|
|
14
24
|
- Removed leftover template scaffolding (`prompts/`, `themes/`, `skills/`).
|
|
15
25
|
- Deleted stale template bootstrap docs (`docs/examples.md`, `docs/github-template.md`, `docs/repository-settings.md`, `docs/typescript.md`, `docs/template-checklist.md`) that shipped to npm consumers describing non-existent commands.
|
|
16
|
-
- Updated ROADMAP.md to reflect current version (0.7.
|
|
26
|
+
- Updated ROADMAP.md to reflect current version (0.7.2), test count (57), and seed completion status for S-101, S-102, S-103, S-105.
|
|
17
27
|
|
|
18
28
|
## [0.7.1] - 2026-06-27
|
|
19
29
|
|
package/README.md
CHANGED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Incident — 2026-07-04 `Publish to npm` failed with duplicate-version E403
|
|
2
|
+
|
|
3
|
+
> Status: **investigation report only.** No release workflow, package version,
|
|
4
|
+
> CHANGELOG, npm registry state, or release was changed to produce this document.
|
|
5
|
+
> Correction options below are proposals for a separate follow-up issue.
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
The `Publish to npm` run
|
|
10
|
+
[28704529442](https://github.com/eiei114/pi-baton/actions/runs/28704529442)
|
|
11
|
+
(`v0.7.2`, dispatched 2026-07-04) failed at the final `npm publish` step with:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
npm error code E403
|
|
15
|
+
npm error 403 403 Forbidden - PUT https://registry.npmjs.org/pi-baton
|
|
16
|
+
npm error 403 You cannot publish over the previously published versions: 0.7.2.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Root cause (classification: trigger/configuration):** a version-bump push to
|
|
20
|
+
`main` fans out into **two concurrent `publish.yml` runs** for the same version,
|
|
21
|
+
keyed by **different concurrency groups** so they are not serialized. The
|
|
22
|
+
"Skip already published version" guard is a non-atomic check-then-publish
|
|
23
|
+
(TOCTOU) and was defeated by ~11s of npm registry propagation latency, so the
|
|
24
|
+
losing run reached `npm publish` after the winning run had already published
|
|
25
|
+
`0.7.2`.
|
|
26
|
+
|
|
27
|
+
This is **not** an authentication / Trusted Publishing failure (OIDC provenance
|
|
28
|
+
was signed successfully) and **not** a duplicate-version-at-dispatch (the version
|
|
29
|
+
was unpublished when the run started).
|
|
30
|
+
|
|
31
|
+
**Impact:** none on the registry. `pi-baton@0.7.2` is correctly published and is
|
|
32
|
+
`dist-tags.latest`. The failed run is a harmless duplicate that lost the race.
|
|
33
|
+
|
|
34
|
+
## Evidence
|
|
35
|
+
|
|
36
|
+
### Failed run
|
|
37
|
+
|
|
38
|
+
| Field | Value |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| Run | [`Publish to npm` · 28704529442](https://github.com/eiei114/pi-baton/actions/runs/28704529442) |
|
|
41
|
+
| Workflow | `.github/workflows/publish.yml` |
|
|
42
|
+
| Event / trigger | `workflow_dispatch` |
|
|
43
|
+
| Ref checked out | `v0.7.2` (tag), via `actions/checkout@v7` (`ref: v0.7.2`) |
|
|
44
|
+
| Package | `pi-baton@0.7.2` |
|
|
45
|
+
| Started / failed | 2026-07-04T11:18:38Z / 2026-07-04T11:19:11Z |
|
|
46
|
+
| Failed step | `Publish to npm` (`npm publish --access public`) |
|
|
47
|
+
| Conclusion | failure, exit code 1 |
|
|
48
|
+
|
|
49
|
+
Step-by-step status (from the run): `Set up job`, `Checkout`, `Setup Node.js`,
|
|
50
|
+
`Ensure npm supports trusted publishing`, `Install dependencies`, `Validate
|
|
51
|
+
package`, `Skip already published version` all **passed**; `Publish to npm`
|
|
52
|
+
**failed**.
|
|
53
|
+
|
|
54
|
+
Failure output excerpt (from the failed step log):
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
npm notice 📦 pi-baton@0.7.2
|
|
58
|
+
...
|
|
59
|
+
npm notice Publishing to https://registry.npmjs.org/ with tag latest and public access
|
|
60
|
+
npm notice publish Signed provenance statement with source and build information from GitHub Actions
|
|
61
|
+
npm notice publish Provenance statement published to transparency log: https://search.sigstore.dev/?logIndex=2069634820
|
|
62
|
+
npm error code E403
|
|
63
|
+
npm error 403 403 Forbidden - PUT https://registry.npmjs.org/pi-baton - You cannot publish over the previously published versions: 0.7.2.
|
|
64
|
+
npm error A complete log of this run can be found in: /home/runner/.npm/_logs/2026-07-04T11_19_08_227Z-debug-0.log
|
|
65
|
+
##[error]Process completed with exit code 1.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Note: provenance **was** signed (Trusted Publishing / OIDC worked); the failure is
|
|
69
|
+
the publish PUT, not authentication.
|
|
70
|
+
|
|
71
|
+
### Who dispatched it (trigger chain)
|
|
72
|
+
|
|
73
|
+
The `workflow_dispatch` run was dispatched by the `Auto Release` workflow, not by
|
|
74
|
+
a human clicking "Run workflow" in the UI:
|
|
75
|
+
|
|
76
|
+
- PR #25 (`chore/sponsor-funding-patch-20260704`) merged to `main` at
|
|
77
|
+
**11:18:31Z**, bumping `package.json` to `0.7.2`.
|
|
78
|
+
- The merge push fired two workflows on `main`:
|
|
79
|
+
- [`Publish to npm` · 28704526901](https://github.com/eiei114/pi-baton/actions/runs/28704526901)
|
|
80
|
+
(event `push`, ref `refs/heads/main`) — **success**.
|
|
81
|
+
- [`Auto Release` · 28704526903](https://github.com/eiei114/pi-baton/actions/runs/28704526903)
|
|
82
|
+
(event `push`, ref `refs/heads/main`) — **success**.
|
|
83
|
+
- `Auto Release` detected the version bump, created tag `v0.7.2` and the GitHub
|
|
84
|
+
Release (11:18:35–37Z), then ran its final step:
|
|
85
|
+
`gh workflow run publish.yml --ref v0.7.2 -f ref=v0.7.2`
|
|
86
|
+
(log: `Run TAG="v0.7.2"` → `gh workflow run publish.yml --ref "$TAG" -f ref="$TAG"`).
|
|
87
|
+
- That dispatch produced the failed run **28704529442** at **11:18:38Z**.
|
|
88
|
+
|
|
89
|
+
So a single version-bump merge produced **two** `publish.yml` runs for `0.7.2`:
|
|
90
|
+
one from the `push` trigger (main) and one from `Auto Release`'s explicit
|
|
91
|
+
`workflow_dispatch` (v0.7.2). This double-trigger is consistent with the design
|
|
92
|
+
documented in [`docs/release.md`](../release.md) (the push trigger and the
|
|
93
|
+
auto-release handoff both fire; the tag/`release.published` triggers are
|
|
94
|
+
unreliable for `GITHUB_TOKEN`-created tags, which is why auto-release dispatches
|
|
95
|
+
explicitly).
|
|
96
|
+
|
|
97
|
+
### Race timeline (all times UTC)
|
|
98
|
+
|
|
99
|
+
| Time | Run | Event |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| 11:18:31 | 28704526901 / 28704526903 | merge push to `main` fires `publish.yml` (push) + `auto-release.yml` |
|
|
102
|
+
| 11:18:35–37 | 28704526903 | `Auto Release` creates tag `v0.7.2`, release, dispatches `publish.yml` |
|
|
103
|
+
| 11:18:38 | 28704529442 | dispatched `publish.yml` (v0.7.2) starts — the failed run |
|
|
104
|
+
| 11:18:52 | 28704526901 | skip guard says `Publishing pi-baton@0.7.2.` (0.7.2 not yet on npm) |
|
|
105
|
+
| **11:18:56** | **28704526901** | **`+ pi-baton@0.7.2` — push run publishes 0.7.2** |
|
|
106
|
+
| 11:19:07 | 28704529442 | skip guard runs `npm view pi-baton@0.7.2 version` → **404** (skip=false) |
|
|
107
|
+
| 11:19:08 | 28704529442 | prints `Publishing pi-baton@0.7.2.`, starts `npm publish` |
|
|
108
|
+
| 11:19:11 | 28704529442 | `E403` — cannot publish over `0.7.2` (already published 11s earlier) |
|
|
109
|
+
|
|
110
|
+
The decisive detail: the failed run's `npm view pi-baton@0.7.2 version` returned
|
|
111
|
+
**404 at 11:19:07**, ~11 seconds **after** the push run actually published
|
|
112
|
+
`0.7.2` at 11:18:56. The skip guard therefore proceeded, and `npm publish` hit
|
|
113
|
+
the real-time conflict.
|
|
114
|
+
|
|
115
|
+
### npm public state (read-only)
|
|
116
|
+
|
|
117
|
+
```console
|
|
118
|
+
$ npm view pi-baton version dist-tags.latest
|
|
119
|
+
0.7.2
|
|
120
|
+
{ latest: '0.7.2' }
|
|
121
|
+
|
|
122
|
+
$ npm view pi-baton time --json
|
|
123
|
+
{
|
|
124
|
+
"0.7.2": "2026-07-04T11:18:56.171Z",
|
|
125
|
+
...
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The `0.7.2` timestamp was published by the winning push run (28704526901).
|
|
130
|
+
|
|
131
|
+
`pi-baton@0.7.2` is present, is `dist-tags.latest`, and was published at
|
|
132
|
+
11:18:56Z — i.e. by the parallel push run (28704526901), not by the failed run.
|
|
133
|
+
Published versions: `0.2.2, 0.2.3, 0.3.0, 0.4.0, 0.5.0, 0.6.0, 0.7.0, 0.7.1,
|
|
134
|
+
0.7.2`. No registry correction is needed.
|
|
135
|
+
|
|
136
|
+
## Cause classification
|
|
137
|
+
|
|
138
|
+
**Trigger / configuration** — specifically a concurrent-duplicate-publish race:
|
|
139
|
+
|
|
140
|
+
1. **Double trigger for one version bump.** A `package.json` version bump on
|
|
141
|
+
`main` fires `publish.yml` twice: once via the `push` (branches: `main`,
|
|
142
|
+
paths: `package.json`) trigger, and once via `auto-release.yml`'s explicit
|
|
143
|
+
`gh workflow run publish.yml --ref "$TAG" -f ref="$TAG"`.
|
|
144
|
+
2. **Concurrency groups do not collide.** `publish.yml` uses
|
|
145
|
+
`group: npm-publish-${{ github.event.inputs.ref || github.ref }}`:
|
|
146
|
+
- push run → `npm-publish-refs/heads/main`
|
|
147
|
+
- dispatch run → `npm-publish-v0.7.2`
|
|
148
|
+
|
|
149
|
+
Different keys ⇒ `concurrency` does not serialize the two runs; they execute
|
|
150
|
+
in parallel for the same version.
|
|
151
|
+
3. **Non-atomic idempotency guard (TOCTOU).** "Skip already published version"
|
|
152
|
+
runs `npm view <name>@<version>` and, on 404, proceeds to `npm publish` in a
|
|
153
|
+
later step. There is no lock between check and publish, and `npm view` reads
|
|
154
|
+
registry metadata that lags the actual publish (here by ~11s). The losing run
|
|
155
|
+
therefore sees "not published", then loses the race to `npm publish`.
|
|
156
|
+
|
|
157
|
+
Explicitly **not** the cause:
|
|
158
|
+
|
|
159
|
+
- **Duplicate-version at dispatch.** No — `0.7.2` was not on npm when the run was
|
|
160
|
+
dispatched (11:18:38) or when its skip guard ran (the guard returned 404).
|
|
161
|
+
- **Trusted Publishing / authentication.** No — provenance was signed
|
|
162
|
+
successfully, `permissions.id-token: write` is set, `registry-url` is correct,
|
|
163
|
+
and no `NPM_TOKEN` is used (Trusted Publishing). Auth was healthy.
|
|
164
|
+
|
|
165
|
+
## Reproducible non-publish check
|
|
166
|
+
|
|
167
|
+
These commands are **read-only** — they do not publish, rerun the workflow, or
|
|
168
|
+
touch the registry/versions. They reproduce the diagnosis from a clean checkout.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# 1) Confirm 0.7.2 is published and is latest (read-only registry query).
|
|
172
|
+
npm view pi-baton version # -> 0.7.2
|
|
173
|
+
npm view pi-baton dist-tags.latest # -> 0.7.2
|
|
174
|
+
npm view pi-baton@0.7.2 time --json # -> "0.7.2": "2026-07-04T11:18:56.171Z"
|
|
175
|
+
|
|
176
|
+
# 2) Show the two concurrent publish runs produced by one version-bump merge.
|
|
177
|
+
# (--created takes a date, not a full timestamp.)
|
|
178
|
+
gh run list --repo eiei114/pi-baton --workflow "Publish to npm" \
|
|
179
|
+
--created 2026-07-04 --limit 10 \
|
|
180
|
+
--json databaseId,event,headBranch,conclusion,createdAt
|
|
181
|
+
# Expect both:
|
|
182
|
+
# 28704526901 push main success (published 0.7.2)
|
|
183
|
+
# 28704529442 workflow_dispatch v0.7.2 failure (E403 duplicate)
|
|
184
|
+
|
|
185
|
+
# 3) Show the dispatch origin (Auto Release triggered the failed run).
|
|
186
|
+
gh run view 28704526903 --repo eiei114/pi-baton --log \
|
|
187
|
+
| grep -E 'gh workflow run publish.yml|released=true|TAG="v0.7.2"'
|
|
188
|
+
|
|
189
|
+
# 4) Prove the two runs had DIFFERENT concurrency groups (so they raced).
|
|
190
|
+
# publish.yml: group: npm-publish-${{ github.event.inputs.ref || github.ref }}
|
|
191
|
+
# push run -> github.event.inputs.ref is unset, github.ref = refs/heads/main
|
|
192
|
+
# => "npm-publish-refs/heads/main"
|
|
193
|
+
# dispatch run -> github.event.inputs.ref = "v0.7.2" (-f ref=v0.7.2)
|
|
194
|
+
# => "npm-publish-v0.7.2"
|
|
195
|
+
node -e '
|
|
196
|
+
const g = (ref, inputRef) => `npm-publish-${inputRef || ref}`;
|
|
197
|
+
console.log("push :", g("refs/heads/main", undefined));
|
|
198
|
+
console.log("dispatch:", g("refs/tags/v0.7.2", "v0.7.2"));
|
|
199
|
+
console.log("collide :", g("refs/heads/main", undefined) === g("refs/tags/v0.7.2", "v0.7.2"));
|
|
200
|
+
'
|
|
201
|
+
# => push : npm-publish-refs/heads/main
|
|
202
|
+
# => dispatch: npm-publish-v0.7.2
|
|
203
|
+
# => collide : false
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Minimal safe correction options
|
|
207
|
+
|
|
208
|
+
None of these are applied here — they are candidates for a **separate
|
|
209
|
+
correction issue** (release/publish workflows remain human-owned). Listed from
|
|
210
|
+
smallest/safest to largest behavior change.
|
|
211
|
+
|
|
212
|
+
- **Option A — make `npm publish` idempotent (recommended, smallest).** In the
|
|
213
|
+
`Publish to npm` step, treat the specific "cannot publish over the previously
|
|
214
|
+
published versions" `E403` as success instead of failure. This makes the
|
|
215
|
+
workflow resilient to the double-trigger race regardless of concurrency or
|
|
216
|
+
propagation lag. Scope the match to that exact message so genuine permission
|
|
217
|
+
errors still fail. Sketch (not applied):
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
set +e
|
|
221
|
+
npm publish --access public 2>&1 | tee /tmp/publish.log
|
|
222
|
+
status=${PIPESTATUS[0]}
|
|
223
|
+
set -e
|
|
224
|
+
if [ "$status" -ne 0 ] && grep -Eq 'cannot publish over the previously published versions' /tmp/publish.log; then
|
|
225
|
+
echo "Version already published; treating publish as success."
|
|
226
|
+
exit 0
|
|
227
|
+
fi
|
|
228
|
+
exit "$status"
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
- **Option B — serialize the two runs via one concurrency group.** Replace the
|
|
232
|
+
ref-keyed group with a single constant group (e.g. `group: npm-publish`) and
|
|
233
|
+
keep `cancel-in-progress: false`, so the push run and the auto-release dispatch
|
|
234
|
+
queue instead of racing. Best combined with Option A, since the skip guard is
|
|
235
|
+
still non-atomic. Avoid `cancel-in-progress: true` here — cancelling mid-publish
|
|
236
|
+
risks a partial publish.
|
|
237
|
+
|
|
238
|
+
- **Option C — collapse to a single handoff path.** Remove the `push`
|
|
239
|
+
(`branches: [main]`, `paths: [package.json]`) trigger from `publish.yml` so a
|
|
240
|
+
version bump publishes only via `auto-release.yml`'s explicit dispatch (the path
|
|
241
|
+
`docs/release.md` already describes as the reliable one). Largest behavior
|
|
242
|
+
change; needs validation that the manual tag / `release.published` /
|
|
243
|
+
`workflow_dispatch` entry points still cover intended cases.
|
|
244
|
+
|
|
245
|
+
## Out of scope for this issue (enforced)
|
|
246
|
+
|
|
247
|
+
Per the issue brief, this slice intentionally does **not**: edit release/publish
|
|
248
|
+
workflows, publish a package, rerun the workflow, change the package version, or
|
|
249
|
+
update the CHANGELOG. A safe correction should be tracked in a follow-up issue.
|
package/extensions/index.ts
CHANGED
|
@@ -5,7 +5,12 @@ import { MissingAgentsError, validateWorkflowAgents } from "../lib/agents.ts";
|
|
|
5
5
|
import { ensureBatonScaffolding } from "../lib/paths.ts";
|
|
6
6
|
import { formatRunResultSummary, runContinuous } from "../lib/run-engine.ts";
|
|
7
7
|
import { createRunUiController } from "../lib/run-ui.ts";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ActiveRunGuardError,
|
|
10
|
+
createIdleRun,
|
|
11
|
+
loadActiveRun,
|
|
12
|
+
loadMostRecentTerminalRun,
|
|
13
|
+
} from "../lib/run-store.ts";
|
|
9
14
|
import { NO_ACTIVE_RUN_MESSAGE, formatStatusSummary } from "../lib/status.ts";
|
|
10
15
|
import { createSubagentRunner } from "../lib/subagent-runner.ts";
|
|
11
16
|
import { WorkflowNameCollisionError, createWorkflowScaffold } from "../lib/workflow-scaffold.ts";
|
|
@@ -185,7 +190,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
185
190
|
pi.registerCommand("baton:status", {
|
|
186
191
|
description: "Show the active Baton run summary",
|
|
187
192
|
handler: async (_args, ctx) => {
|
|
188
|
-
const manifest = await loadActiveRun(ctx.cwd);
|
|
193
|
+
const manifest = (await loadActiveRun(ctx.cwd)) ?? (await loadMostRecentTerminalRun(ctx.cwd));
|
|
189
194
|
if (!manifest) {
|
|
190
195
|
ctx.ui.notify(NO_ACTIVE_RUN_MESSAGE, "info");
|
|
191
196
|
return;
|
package/lib/run-store.ts
CHANGED
|
@@ -41,13 +41,32 @@ export async function readRunManifest(cwd: string, runId: string): Promise<RunMa
|
|
|
41
41
|
return readJson<RunManifest>(getRunManifestPath(cwd, runId));
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
function isTerminalRunState(state: RunState): boolean {
|
|
45
|
+
return state === "completed" || state === "failed";
|
|
46
|
+
}
|
|
47
|
+
|
|
44
48
|
export async function loadActiveRun(cwd: string): Promise<RunManifest | null> {
|
|
45
49
|
const pointer = await readActiveRunPointer(cwd);
|
|
46
|
-
if (!pointer) return null;
|
|
50
|
+
if (!pointer?.runId) return null;
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const manifest = await readRunManifest(cwd, pointer.runId);
|
|
54
|
+
if (isTerminalRunState(manifest.state)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return manifest;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function loadMostRecentTerminalRun(cwd: string): Promise<RunManifest | null> {
|
|
64
|
+
const pointer = await readActiveRunPointer(cwd);
|
|
65
|
+
if (!pointer?.runId) return null;
|
|
47
66
|
|
|
48
67
|
try {
|
|
49
68
|
const manifest = await readRunManifest(cwd, pointer.runId);
|
|
50
|
-
if (manifest.state
|
|
69
|
+
if (!isTerminalRunState(manifest.state)) {
|
|
51
70
|
return null;
|
|
52
71
|
}
|
|
53
72
|
return manifest;
|
package/lib/status.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import type { RunManifest } from "./types.ts";
|
|
2
2
|
|
|
3
|
+
function isTerminalRunState(state: RunManifest["state"]): boolean {
|
|
4
|
+
return state === "completed" || state === "failed";
|
|
5
|
+
}
|
|
6
|
+
|
|
3
7
|
export function formatStatusSummary(manifest: RunManifest): string {
|
|
4
|
-
|
|
8
|
+
const lines: string[] = [];
|
|
9
|
+
|
|
10
|
+
if (isTerminalRunState(manifest.state)) {
|
|
11
|
+
lines.push(`This Baton run has finished (${manifest.state}).`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
lines.push(
|
|
5
15
|
`workflow: ${manifest.workflowName}`,
|
|
6
16
|
`task brief: ${manifest.taskBrief}`,
|
|
7
17
|
`last step: ${manifest.lastStep ?? "(none)"}`,
|
|
@@ -9,7 +19,9 @@ export function formatStatusSummary(manifest: RunManifest): string {
|
|
|
9
19
|
`run state: ${manifest.state}`,
|
|
10
20
|
`iteration count: ${manifest.iteration}`,
|
|
11
21
|
`run directory: .pi/baton/runs/${manifest.id}`,
|
|
12
|
-
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return lines.join("\n");
|
|
13
25
|
}
|
|
14
26
|
|
|
15
27
|
export const NO_ACTIVE_RUN_MESSAGE =
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-baton",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Pi-native workflow baton runner with per-step model switching and isolated step context.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"typebox": "*"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@earendil-works/pi-ai": "
|
|
62
|
-
"@earendil-works/pi-coding-agent": "
|
|
61
|
+
"@earendil-works/pi-ai": "^0.80.6",
|
|
62
|
+
"@earendil-works/pi-coding-agent": "^0.80.6",
|
|
63
63
|
"typebox": "latest",
|
|
64
64
|
"@types/node": "^26.0.1",
|
|
65
65
|
"typescript": "^6.0.3"
|