pi-roundtable-coding 0.27.1 → 0.28.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/CHANGELOG.md +12 -0
- package/README.md +38 -10
- package/package.json +3 -3
- package/src/coding-desk.ts +429 -84
- package/src/coding-plugin.ts +105 -28
- package/src/index.ts +14 -2
- package/src/pi-coding-worker.ts +40 -4
- package/src/repo-shelf.ts +212 -1
- package/src/worker-entry.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.28.0] - 2026-10-31
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Workers run in their own git worktrees, so several can work on one repository at once; a finished branch is rebased and fast-forwarded into the clone, and a conflict keeps the branch and worktree and lists its files in the report.
|
|
11
|
+
- With the new `modes` and `autonomy` options, workers follow the yolo and long-running modes of the owner conversation that started them, live, and the report lists what yolo approved.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- A host-wide `maxWorkers` cap (default 4) with a FIFO queue (`maxQueued`, default 16) replaces the per-repository and per-channel limits; `start()` answers `queuePosition` for a queued task, queued tasks are dropped with a notice on stop, and `presentation.taskQueued` words the queued reply. The core peer range moves to `>=0.28.0 <0.29.0`.
|
|
16
|
+
|
|
5
17
|
## [0.27.1] - 2026-10-31
|
|
6
18
|
|
|
7
19
|
- Release in lockstep with pi-roundtable 0.27.1; no package-specific behavior changes. The core peer range stays `>=0.27.0 <0.28.0`.
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ This package is a reference for the plugin guide's [Helpers for a Pi session of
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
9
9
|
- Bun 1.4.4 or newer on a POSIX host (Linux or macOS).
|
|
10
|
-
- pi-roundtable `>=0.
|
|
10
|
+
- pi-roundtable `>=0.28.0 <0.29.0` as a peer dependency; this package uses only its public main, kit and testing entries.
|
|
11
11
|
- Pi `>=1.0.0 <2`, shared with the host's core dependencies.
|
|
12
12
|
A core-only host still pinned to Pi 0.99.x must update its Pi dependencies before adding coding, so cross-package extension and session types resolve to one Pi version.
|
|
13
13
|
- Git, plus GitHub CLI (`gh`) for the default clone implementation.
|
|
@@ -77,7 +77,7 @@ System report turns cannot call `repo_task`; do the work in the turn or hand it
|
|
|
77
77
|
| --- | --- | --- |
|
|
78
78
|
| `repo_add` | `repo` | Clone `owner/repo` into `shelfDir/owner/repo`; refuse invalid names and existing clones. |
|
|
79
79
|
| `repo_list` | `fetch?` | List paths, branches, upstream ahead/behind counts, dirty files, last commits, prose summaries, CI hints and linked skills. |
|
|
80
|
-
| `repo_task` | `repo`, `task`, `skills?` | Start a background worker, returning its job number immediately. The host's own turns, such as a report's, may not. |
|
|
80
|
+
| `repo_task` | `repo`, `task`, `skills?` | Start a background worker in its own worktree, or queue it when every worker slot is taken, returning its job number (and queue position) immediately. The host's own turns, such as a report's, may not. |
|
|
81
81
|
| `repo_change_report` | `repo` | Fetch and post the commits and diffstat ahead of the default branch; return its full SHA. |
|
|
82
82
|
| `repo_push` | `repo`, `sha` | Push the exact reported SHA to the reported default branch, without force, after the hold gate permits it. |
|
|
83
83
|
|
|
@@ -95,10 +95,22 @@ The role is checked when the session is built and again before every extra `skil
|
|
|
95
95
|
A newly granted role makes the extra tool available once the session is rebuilt.
|
|
96
96
|
|
|
97
97
|
A worker reads the repository's instructions, edits and checks the work, and commits using repository conventions.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
The
|
|
101
|
-
|
|
98
|
+
Each worker runs in its own linked worktree on its own branch, `worker/<job>` (with a suffix when a kept branch already has that name), cut from the clone's HEAD when it starts, so several workers can work on one repository at once.
|
|
99
|
+
Worktrees live under `shelfDir/.worktrees/<owner>/<repo>/`; the shelf lists no repository there, and owners starting with a dot are refused as repository names.
|
|
100
|
+
The managed clone stays the place reports and pushes ship from.
|
|
101
|
+
|
|
102
|
+
When a worker finishes, its branch is rebased onto the clone's current HEAD inside its worktree and the clone is fast-forwarded to it; the worktree and branch are then removed, and `repo_change_report` ships the result as before.
|
|
103
|
+
A rebase conflict is aborted in the worktree, so the clone is never left mid-rebase; the branch and worktree are kept and the report names the conflicting files, the branch and the worktree path.
|
|
104
|
+
A clone with uncommitted changes at that moment, or a worktree the worker left uncommitted changes in, is not touched: the report says why and keeps the branch.
|
|
105
|
+
A worker that committed nothing leaves no worktree or branch behind.
|
|
106
|
+
Integrations of one clone run one at a time, and wait for a report or push of it in progress.
|
|
107
|
+
Reports and pushes refuse a repository only while an integration is changing its clone, not while workers run in their worktrees; the desk also refuses a second concurrent report or push of a repository and new coding tasks for it while one runs.
|
|
108
|
+
|
|
109
|
+
At most `maxWorkers` workers (default 4) run at once on the host, across repositories and channels.
|
|
110
|
+
Past that a task waits in a first-in, first-out queue of at most `maxQueued` tasks (default 16), and `repo_task` answers at once with its queue position; one more is refused.
|
|
111
|
+
A queued task starts when a worker slot frees.
|
|
112
|
+
On host stop queued tasks are dropped and each gets a report saying it never ran; the shutdown drain waits only for running workers.
|
|
113
|
+
The worker's report includes its final answer, declined or unanswered actions, calls approved by yolo mode, what became of its branch, branch, HEAD, new commits and uncommitted files.
|
|
102
114
|
Failures and timeouts also report the final Git state when it can be read.
|
|
103
115
|
By default reports are sent to the caller's surface; `onResult(result)` can instead enqueue a background conversation turn through your host integration.
|
|
104
116
|
Dates are formatted using `context.env.timeZone`, not a process-wide zone.
|
|
@@ -132,6 +144,16 @@ While it works, the worker posts its progress into its thread, as the host's own
|
|
|
132
144
|
The thread's cards come after the text written before them, the final report is posted once, and a failed progress post or edit is logged and never fails the job.
|
|
133
145
|
`interimText: "off"` posts only the task, the held-action notices, the cards and the report; a thread whose host cannot edit its posts gets no progress either.
|
|
134
146
|
`promptSlot` tracks these cards and `workTimeout` excludes their waiting time from the worker's budget (one hour by default).
|
|
147
|
+
|
|
148
|
+
### Yolo and long-running modes
|
|
149
|
+
|
|
150
|
+
With `modes` (the host's `MODES` service, `context.services.find(MODES)`) and `autonomy` (the same values as the host's `autonomy` config), a worker follows the yolo and long-running modes of the conversation whose turn started it, read live: switching a mode in that conversation applies to its running workers at once.
|
|
151
|
+
They act only when an owner other than the host's own principal spoke that turn, so a worker gains nothing its starter could not turn on.
|
|
152
|
+
In yolo mode a held call is approved without a card exactly as in the conversation: it needs hold classes, and none of them may be carded by `autonomy.yolo.card`, by `YOLO_CARDED_SHELL_CLASSES` unless `autonomy.yolo.allow` names it, or be an unclassed rule `allow` leaves out; push-class holds that the host cards still stop on a card.
|
|
153
|
+
The worker reports the classes of every check that holds a call: the shell rule's and the host hold check's `classesOf`; a check that holds a call without classes leaves it unclassed, so a card decides.
|
|
154
|
+
Each approval is told to `modes.autoApproved` with the starter's channel and listed under "Approved by yolo mode" in the report.
|
|
155
|
+
In long-running mode a worker that reaches `timeoutMs` goes on, looking again at the mode each minute, up to `autonomy.longRunningMaxMs` of work in all (four hours by default).
|
|
156
|
+
Without `modes` every held call asks a card and the worker stops at `timeoutMs`.
|
|
135
157
|
`timeoutMs` must be positive and finite, and at most 2,147,483,647 ms to fit the host timer.
|
|
136
158
|
A worker's card has no grace period and no deadline: the worker waits for the answer until it is stopped, and the waiting does not count against its time.
|
|
137
159
|
An approved call runs; a declined, missing or failed card blocks it and instructs the worker not to retry or work around the refusal.
|
|
@@ -142,7 +164,8 @@ Card expiration is determined by the host's surface implementation, not this pac
|
|
|
142
164
|
|
|
143
165
|
The worker runs in a fresh Bun child process with an unsaved Pi session and uses the public `runWorkerTask` helper.
|
|
144
166
|
Timeout and shutdown kill its POSIX process group and wait for exit; normal completion also removes shell descendants left in that group.
|
|
145
|
-
The service advertises running jobs through `busy()` so the host can drain them before shutdown.
|
|
167
|
+
The service advertises running jobs through `busy()` so the host can drain them before shutdown; queued tasks are not among them.
|
|
168
|
+
`CodingDesk.busy()` lists running and queued jobs, marking each queued one with its position, and `queuedChannels()` names the channels of queued tasks.
|
|
146
169
|
Jobs are in memory; they do not resume after a crash.
|
|
147
170
|
The injectable `worker` runner must observe aborts and settle its run; this is a trusted test/integration seam.
|
|
148
171
|
|
|
@@ -181,7 +204,7 @@ The `CODING` service exposes `shelf: RepoShelf` and `desk: CodingDesk` for trust
|
|
|
181
204
|
| `adoptClones` | `[]` | Startup `{ from, repo }` moves of standalone clones; existing shelf destinations are never replaced. |
|
|
182
205
|
| `resolveRun` | configured model/thinking, caller channel | Per-caller model, thinking, report channel and optional thread origin. |
|
|
183
206
|
| `postChangeReport` | caller surface reply | Post the record using the calling identity and channel. |
|
|
184
|
-
| `presentation` | English package text | Separate change-report post/result text, task-start/omitted-skill wording, and the `repo_list` result (`list(repos, { shelfDir, fetched })`). |
|
|
207
|
+
| `presentation` | English package text | Separate change-report post/result text, task-start/omitted-skill wording, queued-task wording (`taskQueued(job, position, skipped)`), and the `repo_list` result (`list(repos, { shelfDir, fetched })`). |
|
|
185
208
|
| `toolText` | package wording | Trusted description and argument descriptions for each repository tool, as `{ repo_task: { description, parameters: { task: "…" } } }`; it never changes a tool's arguments or approval rules. |
|
|
186
209
|
| `threads` | none | Public `DispatchThreads`-compatible progress and approval thread port. |
|
|
187
210
|
| `threadText` | English package text | Thread introduction, held-action notice, approval title and final report. |
|
|
@@ -196,12 +219,17 @@ The `CODING` service exposes `shelf: RepoShelf` and `desk: CodingDesk` for trust
|
|
|
196
219
|
| `workerPackages` | `[]` | Absolute installed extension paths. |
|
|
197
220
|
| `agentDir` | Pi host directory | Pi credentials and model configuration. |
|
|
198
221
|
| `timeoutMs` | `3600000` | Work-time limit in ms, excluding owner wait; 0 < value <= 2147483647. |
|
|
222
|
+
| `maxWorkers` | `4` | Workers running at once on the host; a whole number of at least 1. |
|
|
223
|
+
| `maxQueued` | `16` | Tasks waiting for a worker slot; a whole number of at least 0. |
|
|
224
|
+
| `modes` | none | The host's conversation modes (`peek`, optional `autoApproved`), for workers to follow their starter's yolo and long-running modes. |
|
|
225
|
+
| `autonomy` | `{ yolo: { allow: [], card: [] }, longRunningMaxMs: 14400000 }` | The host's resolved autonomy limits those modes follow. |
|
|
199
226
|
| `holds` | none | Additional worker hold check. |
|
|
200
227
|
| `clone` | `ghClone` | Git-host clone implementation. |
|
|
201
228
|
| `worker` | `PiCodingWorker` | Trusted worker runner replacement. |
|
|
202
229
|
| `onResult` | surface reply | Report delivery integration. |
|
|
203
230
|
|
|
204
|
-
`RepoShelf`, `CodingDesk`, `PiCodingWorker`, `CodingWorkerFailure`, `REPO_TOOLS`, `codingReport`, `reportPost` and their option/result types are exported for testing and host integrations.
|
|
231
|
+
`RepoShelf`, `CodingDesk`, `PiCodingWorker`, `CodingWorkerFailure`, `REPO_TOOLS`, `codingReport`, `integrationText`, `reportPost`, `WORKTREES_DIR` and their option/result types are exported for testing and host integrations.
|
|
232
|
+
`CodingResult.integration` tells what became of the worker's branch (`merged`, `nothing`, `conflict` with its files, or `refused` with the reason) and `CodingResult.autoApproved` the calls yolo mode approved; `CodingJob.starter` names the conversation and speaker whose modes the worker follows, and `CodingJob.branch` its branch.
|
|
205
233
|
`resolveRun(turn)` receives the public `ToolTurn`, including the calling agent scope and channel.
|
|
206
234
|
It returns `{ model, thinking, channel, origin? }`; skill selection still follows the caller, not the resolved report destination.
|
|
207
235
|
A `resolveRun` or `postChangeReport` that sends a person's report away from the calling channel sends it to that person's own direct channel, `context.directChannels.reach(turn.speaker.principalId)`, and throws `ToolRefusal` when none reaches them.
|
|
@@ -223,7 +251,7 @@ bun run --cwd packages/coding lint
|
|
|
223
251
|
```
|
|
224
252
|
|
|
225
253
|
Tests use temporary bare Git origins, `testPlugin`, fake workers and a real child Pi session with an offline faux provider.
|
|
226
|
-
They cover cloning/listing, reports, push holds and approved pushes, owner exceptions, work-time exclusion, bad names, closed approval paths
|
|
254
|
+
They cover cloning/listing, reports, push holds and approved pushes, owner exceptions, work-time exclusion, bad names, closed approval paths, child-process exit, parallel workers merging into one clone, kept conflicts, the worker cap and queue, and yolo and long-running modes.
|
|
227
255
|
CI runs those checks.
|
|
228
256
|
The shared `publish.yml` workflow repeats them, checks that every workspace version and core peer range match the single `v*` tag, then uses npm trusted publishing with provenance.
|
|
229
257
|
The owner performs the initial npm publication and configures this package's trust against `publish.yml`; no separate repository or package-specific tag is needed.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-roundtable-coding",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Repository shelves and owner-approved Pi coding workers for pi-roundtable",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"typebox": "1.3.37"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"pi-roundtable": ">=0.
|
|
41
|
+
"pi-roundtable": ">=0.28.0 <0.29.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@earendil-works/pi-ai": ">=1.0.0 <2",
|
|
45
45
|
"@biomejs/biome": "2.5.15",
|
|
46
46
|
"@types/bun": "1.4.3",
|
|
47
|
-
"pi-roundtable": "0.
|
|
47
|
+
"pi-roundtable": "0.28.0",
|
|
48
48
|
"typescript": "7.0.2"
|
|
49
49
|
}
|
|
50
50
|
}
|