@edgehero/pi-dispatch-admin 4.3.1 → 5.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 +187 -68
- package/dist/console.mjs +79839 -0
- package/dist/index.mjs +160343 -115745
- package/dist/sandbox-session-monitor.mjs +107167 -0
- package/package.json +8 -4
- package/skills/operate-pi-dispatch/SKILL.md +147 -393
package/README.md
CHANGED
|
@@ -1,34 +1,55 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-reduced-motion: reduce) and (prefers-color-scheme:light)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/banner-light-still.png?v=2026-11-05">
|
|
4
|
+
<source media="(prefers-reduced-motion: reduce)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/banner-still.png?v=2026-11-04b">
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/banner-light.png?v=2026-11-05">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/banner.png?v=2026-11-04b" alt="An animation of the pi-dispatch banner: go from sitting next to one AI coding agent to running many in the background. In the loop, near the loop, out of the loop, dark engineering. On a lit floor you stand beside one agent. As the lights go off, more agents start, and you walk away to the one page that stays lit, whose counts follow the floor. Spending limits that hold, a sealed box for every job, and you decide what ships." width="880">
|
|
7
|
+
</picture>
|
|
3
8
|
</p>
|
|
4
9
|
|
|
5
|
-
# pi-dispatch:
|
|
10
|
+
# pi-dispatch: go from sitting next to one AI coding agent to running many in the background
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
[pi](https://github.com/earendil-works/pi) is an open source coding agent that you normally run in a terminal. pi-dispatch runs it for you
|
|
13
|
+
in the background: on a schedule, on your repo's issues and pull requests, or from the command line. Each job happens in a sealed box that is
|
|
14
|
+
thrown away afterwards, stops at the spending limit you set, and shows up live on one web page. You start in the loop, watching it work. You
|
|
15
|
+
move to near the loop, where it asks when it needs you, and to out of the loop, where a second agent reviews the work and then you decide, until you are looking after a swarm of
|
|
16
|
+
agents rather than one: dark engineering. pi-dispatch never merges anything, so what ships stays a person's decision. It runs on a provider key or a subscription you already have, falls back to other models you
|
|
17
|
+
list, and brings your own pi setup and extensions along with `pi-dispatch import-pi`. The [main README](https://github.com/edgehero/pi-dispatch#readme)
|
|
18
|
+
explains all of it.
|
|
9
19
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
<p align="center">
|
|
21
|
+
<picture>
|
|
22
|
+
<source media="(prefers-reduced-motion: reduce) and (prefers-color-scheme:dark)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/how-close-you-stay-dark-still.png?v=2026-11-04">
|
|
23
|
+
<source media="(prefers-reduced-motion: reduce)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/how-close-you-stay-still.png?v=2026-11-04">
|
|
24
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/how-close-you-stay-dark.png?v=2026-11-04">
|
|
25
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/how-close-you-stay.png?v=2026-11-04" alt="An animation of one loop of work drawn three times, one above the other, under the headline: decide how closely you watch. In the loop, you are on the track: you watch it work and step in, and a message from you crosses to the agent. Near the loop, you stand just beside it: it works alone and stops to ask when it needs you, and it waits until you answer. Out of the loop, you are far away: it starts without you, a second agent reviews it, and only the change, reviewed by AI, travels to you, and then you decide. At every stage: a spending limit, a sealed box, and the final say stays yours." width="820">
|
|
26
|
+
</picture>
|
|
27
|
+
</p>
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
<p align="center">
|
|
30
|
+
<picture>
|
|
31
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/console/console-overview-dark.png?v=2026-11-03">
|
|
32
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/console/console-overview.png?v=2026-11-03" alt="The web console's overview page: what needs you, what is waiting and why, what is running, what today has cost, and a timeline of every project's runs" width="820">
|
|
33
|
+
</picture>
|
|
34
|
+
</p>
|
|
23
35
|
|
|
24
|
-
> This npm package, **`@edgehero/pi-dispatch-admin`**,
|
|
25
|
-
>
|
|
26
|
-
>
|
|
27
|
-
>
|
|
28
|
-
> docs (Docker, Podman, egress, every forge) and SECURITY.md.
|
|
36
|
+
> This npm package, **`@edgehero/pi-dispatch-admin`**, holds the two ways to work with a deployment: the **web console**
|
|
37
|
+
> (`pi-dispatch-console`, above) and the **`/dispatch` panel**, a pi extension. The service itself is
|
|
38
|
+
> [`@edgehero/pi-dispatch`](https://www.npmjs.com/package/@edgehero/pi-dispatch) (worker and CLI) and
|
|
39
|
+
> [`@edgehero/pi-dispatch-receiver`](https://www.npmjs.com/package/@edgehero/pi-dispatch-receiver) (the webhook edge). The
|
|
40
|
+
> [main repo](https://github.com/edgehero/pi-dispatch) has the job image, the docs (Docker, Podman, egress, every forge) and SECURITY.md.
|
|
29
41
|
|
|
30
42
|
## How it works
|
|
31
43
|
|
|
44
|
+
<p align="center">
|
|
45
|
+
<picture>
|
|
46
|
+
<source media="(prefers-reduced-motion: reduce) and (prefers-color-scheme:dark)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/one-job-dark-still.png?v=2026-11-04">
|
|
47
|
+
<source media="(prefers-reduced-motion: reduce)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/one-job-still.png?v=2026-11-04">
|
|
48
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/one-job-dark.png?v=2026-11-04">
|
|
49
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/explain/one-job.png?v=2026-11-05" alt="An animation of one job in five steps, under the headline: you pay for AI only while the agent works. Something starts it: a schedule, an issue, or you. It waits in line, and nothing runs yet. It is checked: over a limit, it is refused. The agent works in a sealed box, and if it needs you it stops to ask. You decide on a proposed change: you accept it, not pi-dispatch. A strip under the steps shows no AI cost in the first three and the last, and AI cost only where the agent works. A job crosses the strip and it fills only there. A second job is refused at the check." width="820">
|
|
50
|
+
</picture>
|
|
51
|
+
</p>
|
|
52
|
+
|
|
32
53
|
Every trigger produces the same job, through the same path: one queue, one container, one budget.
|
|
33
54
|
|
|
34
55
|
```
|
|
@@ -82,7 +103,7 @@ default and goes through an allowlist proxy, and the allowed hosts are yours to
|
|
|
82
103
|
## Triggers: what starts a job
|
|
83
104
|
|
|
84
105
|
Every trigger is one `{ on, run }` entry in a single `triggers.json`. The worker reads it live for cron,
|
|
85
|
-
the receiver reads it live for forge webhooks, and the console can edit it. **`on` is what fires it;
|
|
106
|
+
the receiver reads it live for forge webhooks, and the panel and the web console can edit it. **`on` is what fires it;
|
|
86
107
|
`run` is the skill it runs.**
|
|
87
108
|
|
|
88
109
|
| `on.type` | Fires on | What the agent gets as its task |
|
|
@@ -124,37 +145,56 @@ Four things to know before you build on it:
|
|
|
124
145
|
persists. A forge job gets a fresh clone that is thrown away with the container
|
|
125
146
|
([`docs/workflows.md`](https://github.com/edgehero/pi-dispatch/blob/main/docs/workflows.md)).
|
|
126
147
|
|
|
127
|
-
## The
|
|
148
|
+
## The panel: `/dispatch`
|
|
128
149
|
|
|
129
150
|
One command puts a live terminal view over the whole deployment:
|
|
130
151
|
|
|
131
152
|
<p align="center">
|
|
132
|
-
<
|
|
153
|
+
<picture>
|
|
154
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/dispatch-dashboard-light.png?v=2026-11-05">
|
|
155
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/dispatch-dashboard.png?v=2026-10-22-710" alt="The /dispatch panel: status, spend meters, dollar windows, triggers with a portfolio trigger, pause windows, scoped limits with their dollar caps, held and failed jobs, runs with their projects and the u hosts key, and settings" width="820">
|
|
156
|
+
</picture>
|
|
133
157
|
</p>
|
|
134
158
|
|
|
135
159
|
- **MCP servers, read-only.** A trigger that names MCP servers says so on its row (`[mcp ...]`), and its
|
|
136
160
|
drill-in shows each one as the overlay offers it now: where it runs, how its tools are reached, and the
|
|
137
|
-
variable names it is handed, or why every job of it would be refused. No tool and no key changes them
|
|
161
|
+
variable names it is handed, or why every job of it would be refused. No `dispatch_*` tool and no panel key changes them: a person
|
|
162
|
+
switches a trigger's servers on its page in the web console, or in the file.
|
|
138
163
|
- **Status and spend.** Queue and worker state, day, week and month spend meters, a daily token counter,
|
|
139
|
-
and the run history with tokens and cost per job.
|
|
140
|
-
running
|
|
141
|
-
|
|
142
|
-
|
|
164
|
+
and the run history with tokens and cost per job. Each running job shows where it is: its turn, steps done and
|
|
165
|
+
failed, the tool running and for how long, and the phase it reported (or, when its worker has written nothing for
|
|
166
|
+
3 minutes, that the worker may be gone). `Enter` on a run opens its full record, `x`
|
|
167
|
+
on a running job cancels it after asking, and `b` on an opened run reopens its workspace.
|
|
168
|
+
- **A run's chat.** `/dispatch chat <run-id | issue-or-PR-url | session-key>` opens the run the way it can be talked
|
|
169
|
+
to now: a running job opens on its live transcript, and `Esc` lands on its row, where `t` and `T` steer it; a
|
|
170
|
+
parked run shows its question and asks for your answer, then queues it after a confirm; a finished run opens in
|
|
171
|
+
your own pi as a fork, on this host, with its tools off. It is a command you type, never a model callable tool
|
|
172
|
+
([`docs/chat.md`](https://github.com/edgehero/pi-dispatch/blob/main/docs/chat.md#in-pi-dispatch-chat)).
|
|
173
|
+
- **Insights, the one analytics page.** It is `/insights` in the web console (below); press `i` (or type
|
|
174
|
+
`/dispatch insights`) and the panel shows its address. It shows the budget dials, plan verdicts against API rates, daily,
|
|
143
175
|
cumulative and per flow spend charts, five breakdowns (by flow, trigger, model, repo and project), the
|
|
144
176
|
budget split with each project's share, spend and floor and the split's history, how busy each host was
|
|
145
|
-
(jobs only), and the trigger and flow topology with spend on each trigger
|
|
177
|
+
(jobs only), and the trigger and flow topology with spend on each trigger, plus a what if form that re-prices a
|
|
178
|
+
flow on another model. A plan covered run never shows as $0.00, and an estimate is
|
|
146
179
|
always marked as one ([`docs/insights.md`](https://github.com/edgehero/pi-dispatch/blob/main/docs/insights.md)).
|
|
147
180
|
|
|
148
181
|
<p align="center">
|
|
149
|
-
<
|
|
182
|
+
<picture>
|
|
183
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/console/console-spend-dark.png?v=2026-11-05">
|
|
184
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/console/console-spend.png?v=2026-11-03" alt="The Spend page: KPI tiles, budget dials, the budget split, a plan verdict, spend charts, the five breakdowns, how busy each host was, and the topology with spend badges" width="820">
|
|
185
|
+
</picture>
|
|
150
186
|
</p>
|
|
151
187
|
|
|
152
188
|
- **Triggers, editable live.** Add, edit and delete triggers without a restart. Drill-ins show what
|
|
153
189
|
fires each one, what it runs and who may fire it. A one-shot shows armed or spent. A spent entry
|
|
154
190
|
stays in the list, matches nothing, and is re-armed when you delete its `on.disarmed` mark from the file.
|
|
155
|
-
Triggers that run third party code or a custom image carry a badge.
|
|
156
|
-
|
|
157
|
-
|
|
191
|
+
Triggers that run third party code or a custom image carry a badge. No panel key and no model callable tool turns
|
|
192
|
+
either on or off. The staged packages are a person's switch on the trigger's page in the web console, or an edit to
|
|
193
|
+
the reviewed `triggers.json`, and a custom image stays an edit to that file.
|
|
194
|
+
A portfolio manager's cron trigger carries `[portfolio]`: its jobs write the budget split. The trigger tools can
|
|
195
|
+
turn on `progress` (the job gets a `report_progress` tool to name its phases) and `statusComment` (one forge comment
|
|
196
|
+
the worker edits as the run goes, numbers only), and `recover` (a run the worker loses continues from its last
|
|
197
|
+
checkpoint), behind your confirm.
|
|
158
198
|
- **Quiet hours.** Pause windows per folder or repo, timezone aware. A paused job waits, never drops, and
|
|
159
199
|
costs nothing.
|
|
160
200
|
- **Scoped limits.** Job caps per repo, folder or project (day, week, month), refused before any spend, plus a
|
|
@@ -184,13 +224,16 @@ One command puts a live terminal view over the whole deployment:
|
|
|
184
224
|
It counts jobs only: a machine busy with other work reads as idle.
|
|
185
225
|
|
|
186
226
|
<p align="center">
|
|
187
|
-
<
|
|
227
|
+
<picture>
|
|
228
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/dispatch-hosts-light.png?v=2026-11-05">
|
|
229
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/dispatch-hosts.png?v=2026-10-26" alt="The panel's hosts view: three machines, each with its slots in use, the memory and CPU its budget has promised, its running jobs with project, size and age, a host with an orphaned container, and the last 7 days as busy share, jobs at once, time full, the wait and the top projects, then each host's last doctor run with its failing and warning checks" width="820">
|
|
230
|
+
</picture>
|
|
188
231
|
</p>
|
|
189
232
|
|
|
190
233
|
- **The budget split.** With an allocation envelope (a dollar total per window and a floor per project), `b`
|
|
191
234
|
in the list shows each project's share and spend, the applied plan with the reasons it gave, and the history.
|
|
192
|
-
`r` on a history row reverts to it after a yes or no. `dispatch_priorities_set` sets a plan of weights
|
|
193
|
-
|
|
235
|
+
`r` on a history row reverts to it after a yes or no. `dispatch_priorities_set` sets a plan of weights inside the envelope,
|
|
236
|
+
confirmed in an interactive session or delegated headless with the explicit process grant; `dispatch_envelope_set` changes the envelope
|
|
194
237
|
behind your confirm; `dispatch_allocations` reads the split. pi's own `write` and `edit` tools are blocked on
|
|
195
238
|
the envelope, `projects.json`, `scoped-limits.json`, `triggers.json` and the settings file
|
|
196
239
|
([`docs/allocation.md`](https://github.com/edgehero/pi-dispatch/blob/main/docs/allocation.md)).
|
|
@@ -198,7 +241,10 @@ One command puts a live terminal view over the whole deployment:
|
|
|
198
241
|
plan. A run's detail names the plan a portfolio run wrote and the dollars it settled.
|
|
199
242
|
|
|
200
243
|
<p align="center">
|
|
201
|
-
<
|
|
244
|
+
<picture>
|
|
245
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/dispatch-allocation-light.png?v=2026-11-05">
|
|
246
|
+
<img src="https://raw.githubusercontent.com/edgehero/pi-dispatch/main/docs/images/dispatch-allocation.png?v=2026-10-14" alt="The panel's budget split view: the weekly envelope, each project's floor, weight, share and spend, the headroom, the applied plan with its reasons, and the history across two hosts with a revert and a refused plan" width="820">
|
|
247
|
+
</picture>
|
|
202
248
|
</p>
|
|
203
249
|
|
|
204
250
|
- **The portfolio manager.** A weekly flow you own reads the budget and writes a plan of weights. The
|
|
@@ -209,22 +255,61 @@ One command puts a live terminal view over the whole deployment:
|
|
|
209
255
|
anything waits (the target, the condition and how long), and a **failed** section for jobs the queue
|
|
210
256
|
marked failed after their last attempt. `dispatch_waits` lists held jobs and `dispatch_wait_cancel` stops one behind your confirm
|
|
211
257
|
([`docs/wait-for.md`](https://github.com/edgehero/pi-dispatch/blob/main/docs/wait-for.md)).
|
|
212
|
-
- **AI operable, with
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
258
|
+
- **AI operable, with explicit authority.** Every model write uses the same action policy as the browser.
|
|
259
|
+
Interactive sessions confirm every change, including pause, priorities and paid starts. Headless sessions
|
|
260
|
+
need `PI_DISPATCH_AGENT_WRITES=1` in the actual pi process before it starts, and can use only unattended
|
|
261
|
+
actions. That includes explicit cap decreases, adding ordinary restrictive limit rows and pauses,
|
|
262
|
+
turning existing run flags off, cancellation, failed-job removal and bounded priorities. Scope, size,
|
|
263
|
+
minimums, inherited limits and mixed widening requests stay confirmed. The deployment file and pointer
|
|
264
|
+
cannot grant this authority. Answers, draft decisions, standing-answer adoption and forge reruns remain person actions, and no
|
|
265
|
+
`dispatch_*` tool can set a trigger's job cap, allowed models, fallbacks, MCP servers, tool exclusions, staged packages, extension exclusions or extension tool exclusions, while `dispatch_trigger_edit` can still move its flow, provider and model behind a confirm. A pi process's own `bash`, `write` and
|
|
266
|
+
`edit` tools are outside this policy, so an unattended one must run with them disabled
|
|
267
|
+
([`SECURITY.md`](https://github.com/edgehero/pi-dispatch/blob/main/SECURITY.md)). Tool writes are audited as agents; human-confirmed intervention is tracked separately.
|
|
268
|
+
- **Paid starts stay bounded.** `dispatch_run`, Fire now and local or cron reruns need explicit valid
|
|
269
|
+
`PI_DISPATCH_RUN_ROOTS` in the pi process environment. Fire now and reruns also require an explicit valid
|
|
270
|
+
`PI_DISPATCH_RUN_PER_HOUR`. `dispatch_run` keeps its default of three starts per hour when that value is
|
|
271
|
+
absent or invalid; a valid zero disables it. They check the
|
|
272
|
+
current committed flow's `ai-trigger: allow`, a clean tree and the shared hourly allowance again before
|
|
273
|
+
enqueue. They accept no spend settings, cannot run commands or portfolio flows, and still pass the
|
|
274
|
+
worker's budget gates. A paid run edits its folder in place. Read
|
|
275
|
+
[`SECURITY.md`](https://github.com/edgehero/pi-dispatch/blob/main/SECURITY.md) before enabling it.
|
|
276
|
+
The bundled `operate-pi-dispatch` skill explains each action mark and refusal.
|
|
277
|
+
- **Agent reads expose operational facts.** Failed jobs, all waiting jobs, hosts and setup have dedicated
|
|
278
|
+
read tools. Runs report local retention when known; hosts report budgets, holds, CPU reserve, orphans,
|
|
279
|
+
kept sandboxes, doctor counts and qualified venue declarations. Costs include running holds and bounded
|
|
280
|
+
what-if estimates. Model results omit private job/operator text, question and draft content, variable
|
|
281
|
+
names, host paths and what a run loaded. Setup suggestions come from the trusted command catalogue.
|
|
223
282
|
- **Logs stay put.** Raw container output shows only in the panel's viewer, never in model context.
|
|
224
283
|
|
|
284
|
+
**A web console as well.** The same package installs `pi-dispatch-console`, a separate process that serves a live web
|
|
285
|
+
console for the deployment on loopback or on a private unix socket, behind a named token per person. It shows the
|
|
286
|
+
whole fleet as it changes: an overview of what needs you, what waits and why, and the last hours as a timeline (on a
|
|
287
|
+
deployment that has not run yet, what stands before its first job), every run with filters and what it loaded (a run that
|
|
288
|
+
finished without its flow or with a failed extension says so), one search by
|
|
289
|
+
repository, target or job id, the last 24 hours counted by outcome and paging, a card for each run waiting for an
|
|
290
|
+
answer, spend and insights by range, queues, hosts and schedules, the configuration, what a trigger's jobs get and what a project's runs load on each host, and its own audit
|
|
291
|
+
log, plus `/api/state` as JSON for scripts. It also has Models (roles, fallbacks and canary comparisons), Updates (what jobs run and what is
|
|
292
|
+
newer), Watch (findings from your alerts), Sandboxes (kept workspaces and shells, and what pi can load in one), Zero touch (how often runs needed a person) and
|
|
293
|
+
Setup (a live checklist for a new deployment). It reads through the same code as the panel, so the two never disagree;
|
|
294
|
+
the panel shows the waiting runs too.
|
|
295
|
+
It can act as well as show: cancel, retry, remove and re-run jobs, answer a parked run, pause the fleet or one queue,
|
|
296
|
+
change what a trigger's jobs get and edit the configuration, each previewed (with how to undo it), confirmed and recorded in one audit log that holds
|
|
297
|
+
the panel's own writes too, and after each change the page names it, who made it and its audit row, with an Undo
|
|
298
|
+
where there is a way back. When `serve` starts it prints how to sign in (the commands that make a token or a one time
|
|
299
|
+
link, never a token), and `pi-dispatch-console link --name <you> --port <n>` prints the link for an SSH tunnel's local
|
|
300
|
+
port. The sign-in page says why a session ended. Every running job's progress shows in its row on the fleet page
|
|
301
|
+
and on its run page, and its transcript, redacted, streams live
|
|
302
|
+
on its run page for operators, and the panel's live tail
|
|
303
|
+
(`l`) reads the same transcript for a run on any host. Nothing listens unless you start it. In pi,
|
|
304
|
+
`/dispatch console [page] [--link]` prints a page's address, says whether the console is running, makes a one time
|
|
305
|
+
sign-in link for an operator token (shown only to you, and recorded in the audit log first; with one operator token
|
|
306
|
+
and the console running it does this by itself when a browser on this machine will open it, and `--no-link` turns it off), and opens your browser when the
|
|
307
|
+
session is local (not over SSH; `--no-open` keeps it closed). See
|
|
308
|
+
[`docs/console.md`](https://github.com/edgehero/pi-dispatch/blob/main/docs/console.md).
|
|
309
|
+
|
|
225
310
|
## More than one machine
|
|
226
311
|
|
|
227
|
-
The
|
|
312
|
+
The panel reads the whole deployment, not one host. The status line names the workers once they have
|
|
228
313
|
names. The run detail names the machine that ran a job. The pause switch stops every queue, and the
|
|
229
314
|
scheduler view spans hosts. On a single host none of that shows, because there is nothing to tell apart.
|
|
230
315
|
The HOSTS view (`u`) shows each machine's slots, budget and running jobs now and how busy it was over the last 7
|
|
@@ -238,20 +323,18 @@ See [`docs/multi-host.md`](https://github.com/edgehero/pi-dispatch/blob/main/doc
|
|
|
238
323
|
pi install npm:@edgehero/pi-dispatch-admin # then, in pi: /dispatch
|
|
239
324
|
```
|
|
240
325
|
|
|
241
|
-
**This is the default way to set up pi-dispatch.** With nothing configured, `/dispatch`
|
|
242
|
-
setup
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
private key), a trigger edge (receiver service, docker compose profile or the polling command), and a
|
|
254
|
-
first **cron** trigger for the repo you are in.
|
|
326
|
+
**This is the default way to set up pi-dispatch.** With nothing configured, `/dispatch` offers
|
|
327
|
+
**Finish setup in browser**, checks Docker or rootless Podman (and OpenShell when configured), installs
|
|
328
|
+
exact worker, admin and pi packages in a durable deployment folder, then runs the consented
|
|
329
|
+
`up --console` pass. It offers a deployment pointer and opens `/setup` with a private one-use link.
|
|
330
|
+
The checklist uses actual heartbeat and doctor evidence, keeps Starting distinct from Ready, and offers
|
|
331
|
+
individually previewed and confirmed service actions, a create-only provider key field and editable
|
|
332
|
+
first-trigger recipes. [First run](../docs/console.md#first-run) explains the explicit local host grant,
|
|
333
|
+
read-only/viewer/agent views, key and invitation privacy, and terminal recovery.
|
|
334
|
+
|
|
335
|
+
**Guided setup** retains the terminal workflow: runtime check and pinned install, `up`, deployment pointer,
|
|
336
|
+
provider-key guidance, optional worker service, GitHub credentials, receiver or polling, and a first local
|
|
337
|
+
cron trigger. GitHub setup asks for a webhook URL or `--no-webhook`; browser App creation remains open.
|
|
255
338
|
|
|
256
339
|
Every step says what it will do, asks first and can be declined. Nothing is written into your repo, and no
|
|
257
340
|
credential passes through a dialog. A deployment whose queue is only down keeps the unreachable banner:
|
|
@@ -267,10 +350,13 @@ when that file is yours and nobody else can write it. A key your env sets differ
|
|
|
267
350
|
warning, never with its value. The switches that grant a capability (`PI_BACKENDS`, `PI_EGRESS`,
|
|
268
351
|
`DOCKER_HOST`, `PI_DISPATCH_RUN_ROOTS`) are never read from a file.
|
|
269
352
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
353
|
+
Paid model starts need explicit valid `PI_DISPATCH_RUN_ROOTS` in the actual pi process environment.
|
|
354
|
+
Fire now and local or cron reruns also require explicit valid `PI_DISPATCH_RUN_PER_HOUR`; `dispatch_run`
|
|
355
|
+
defaults to three starts per hour when that value is absent or invalid, and zero disables it.
|
|
356
|
+
Headless mutation additionally requires
|
|
357
|
+
`PI_DISPATCH_AGENT_WRITES=1`. None is loaded from the deployment pointer or its `.env`. A reviewed external
|
|
358
|
+
skill may use private owner context to propose a permitted operation, but it cannot grant authority or
|
|
359
|
+
send an answer. Upgrade the host runtime and console together before using an agent token.
|
|
274
360
|
|
|
275
361
|
## Get the whole thing
|
|
276
362
|
|
|
@@ -279,3 +365,36 @@ reaches commands either: a `run.command` fires from the reviewed triggers file o
|
|
|
279
365
|
MIT, self hosted. Read [`SECURITY.md`](https://github.com/edgehero/pi-dispatch/blob/main/SECURITY.md)
|
|
280
366
|
before you rely on it: it states plainly what is and is not defended. Short version: the trust model is a
|
|
281
367
|
GitHub Action's. Whoever can merge to your default branch can instruct the agent.
|
|
368
|
+
|
|
369
|
+
## Configuration in the browser
|
|
370
|
+
|
|
371
|
+
The [operator console](../docs/console.md#configuration-and-trigger-pages) includes a Pulse Configuration
|
|
372
|
+
page, a page per trigger and a structured editor for five trigger kinds. Edit and Delete work from each
|
|
373
|
+
row, with a diff, confirmation and Undo. Human row numbers count from 1; tool indexes remain zero-based.
|
|
374
|
+
The editor and its JSON fallback preserve the add tool's secret-bundle opt-out.
|
|
375
|
+
|
|
376
|
+
**What its jobs get**, on a trigger's page, says what a job of it would start with on each host, with a label for each host, and under each row what
|
|
377
|
+
a recent run really had.
|
|
378
|
+
|
|
379
|
+
There a person changes the flow, the provider and model, the job cap, the allowed models and fallbacks, the MCP
|
|
380
|
+
servers, the tools, the all-or-nothing switch for staged packages, each extension the trigger leaves out and each extension's tool it removes, with one preview that
|
|
381
|
+
says each change in words, one Confirm, and Undo.
|
|
382
|
+
|
|
383
|
+
An extension left out does not load, and a tool removed leaves the rest of its extension running. Neither stops what an agent that can run commands, write files or edit files can reach
|
|
384
|
+
([what exclusion does not stop](../docs/exclude-tools.md#what-exclusion-does-not-stop)). Every running machine must run a release that can read these two settings: the
|
|
385
|
+
[upgrade notes](../docs/upgrading.md#what-a-fleet-needs-before-a-trigger-leaves-something-out) say which release, and what to do until then. While a running worker cannot read them, the page refuses the change and names it.
|
|
386
|
+
|
|
387
|
+
A viewer reads the same rows with no controls, an agent's page draws no card, and no tool reaches the action. The file works as it
|
|
388
|
+
always has ([`docs/console.md`](../docs/console.md#what-a-triggers-jobs-get)).
|
|
389
|
+
|
|
390
|
+
`dispatch_trigger_edit` also takes `maxTurns` and the four run-option flags. `dispatch_trigger_fire(index)`
|
|
391
|
+
shares the console's Fire now planner, reserve and refusals. It fires a served cron trigger after the same fresh folder, committed flow, clean tree and hourly checks
|
|
392
|
+
as `dispatch_run`. Interactive callers confirm; headless callers need the process write grant and both
|
|
393
|
+
paid-start grant values in the pi or console process environment.
|
|
394
|
+
Viewers see trigger facts and runs without private prompt text or write controls.
|
|
395
|
+
|
|
396
|
+
The Triggers page groups rules by schedule and forge, with retained history, spend and a timezone-aware
|
|
397
|
+
schedule view. Its phone and viewer layouts keep the same facts readable. **Check an event** uses the
|
|
398
|
+
receiver filters to explain a hypothetical match without a forge call, queue write or spend. It is a
|
|
399
|
+
viewer read, available even on a read-only console; entered permissions remain assumptions and comment
|
|
400
|
+
text is neither saved nor logged. Rules and filters still work without JavaScript.
|