@edgehero/pi-dispatch-admin 1.4.0 → 1.6.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 +5 -3
- package/dist/index.mjs +903 -60
- package/package.json +1 -1
- package/skills/operate-pi-dispatch/SKILL.md +59 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgehero/pi-dispatch-admin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Operator console (a pi extension) + skill for pi-dispatch: run the pi coding agent as a self-hosted service. A /dispatch TUI for the queue, spend caps, run history, editable GitHub, GitLab, Forgejo and Azure DevOps triggers (cron/label/comment/PR/MR/work item), and scheduled pause windows — plus AI-operable, human-confirmed controls. Runs against a live pi-dispatch deployment.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -41,6 +41,18 @@ dialog before it takes effect**:
|
|
|
41
41
|
(per folder/repo "quiet hours": runs for a scope are deferred between certain times and auto-resume after;
|
|
42
42
|
`dispatch_pauses` lists them with their index). `dispatch_pause_edit` is a partial change — pass the index
|
|
43
43
|
plus only the fields to alter. Deferring never drops a job and costs no budget.
|
|
44
|
+
- `dispatch_waits` — list the jobs the worker is HOLDING on a trigger's `run.waitFor` condition: job id,
|
|
45
|
+
an id-only target, the operator's own words for what it waits on, and how long it has waited. Different
|
|
46
|
+
from the queue's `delayed` count, which also mixes cron next-occurrences, retry backoff and quiet hours.
|
|
47
|
+
- `dispatch_wait_cancel` — remove a held job so it never runs (confirm-gated). It is the only lever that
|
|
48
|
+
reaches one: a held job has spent nothing, so no budget cap will ever refuse it, and deleting the trigger
|
|
49
|
+
does not reach a job already enqueued.
|
|
50
|
+
- `dispatch_limit_add` / `dispatch_limit_edit` / `dispatch_limit_delete` — manage scoped limits (per
|
|
51
|
+
repo/folder budget caps and concurrency: `day`/`week`/`month` job-count caps refuse a job pre-spend with
|
|
52
|
+
reason `scope-cap`, never retried; `concurrent` defers the excess, never drops it; `dispatch_limits`
|
|
53
|
+
lists them with their index and used counts). `dispatch_limit_edit` is a partial change — pass the index
|
|
54
|
+
plus only the fields to alter. Scopes match exactly (a repo `owner/name` or an ABSOLUTE folder path, no
|
|
55
|
+
globs).
|
|
44
56
|
|
|
45
57
|
Use them like this:
|
|
46
58
|
|
|
@@ -235,3 +247,50 @@ If you are asked why a GitLab trigger did not fire, the usual answers in order:
|
|
|
235
247
|
2. **No label was added by that event.** GitLab has no `labeled` action; the trigger fires on the labels
|
|
236
248
|
an event *added*, so editing an already-labelled issue does nothing. This is deliberate.
|
|
237
249
|
3. **The action word belongs to the other forge.** See above.
|
|
250
|
+
|
|
251
|
+
## Held jobs — what `waitFor` looks like from here
|
|
252
|
+
|
|
253
|
+
A trigger may carry `run.waitFor`, and a job whose conditions have not cleared is **held**: deferred, with
|
|
254
|
+
no budget slot reserved, no kill timer armed, no retry attempt consumed, and no run record written. It runs
|
|
255
|
+
exactly once when every condition clears.
|
|
256
|
+
|
|
257
|
+
What that means when you are asked about a job that "has not run":
|
|
258
|
+
|
|
259
|
+
- **Look at `dispatch_waits` before the queue counts.** A held job is not `waiting` and not `active`. It is
|
|
260
|
+
in the delayed set, which also holds every cron trigger's next occurrence, so the panel's `delayed` number
|
|
261
|
+
is not an answer to "what is stuck".
|
|
262
|
+
- **A held job has cost nothing yet.** Do not reason about it against the spend caps: they count container
|
|
263
|
+
starts, and this job has started none. The bounds that apply to it are its own (`PI_WAIT_MAX_MS`,
|
|
264
|
+
`PI_WAIT_MAX_CHECKS`), and when one is reached the job terminates with a run record naming the reason.
|
|
265
|
+
- **The terminal reasons say what to do.** `wait-refused` means the operator's check reported the condition
|
|
266
|
+
will never clear. `wait-unanswerable` means the check could not answer repeatedly, which usually means the
|
|
267
|
+
script is broken rather than the condition slow. `wait-expired` means a bound was reached.
|
|
268
|
+
`wait-skew` / `wait-unreadable` mean two services in the deployment disagree about the field and one needs
|
|
269
|
+
upgrading or restarting.
|
|
270
|
+
- **Cancelling is an operator decision.** `dispatch_wait_cancel` needs a confirm, writes no run record (the
|
|
271
|
+
job never ran), and cannot be undone: the delivery is gone, and a webhook does not resend itself.
|
|
272
|
+
|
|
273
|
+
## Scoped limits — and the folder mutex you cannot turn off
|
|
274
|
+
|
|
275
|
+
`scoped-limits.json` holds per-scope bounds beside the deployment-global ones: `day`/`week`/`month` cap
|
|
276
|
+
how many jobs a repo or folder may run per window (refused pre-spend, reason `scope-cap`, never retried,
|
|
277
|
+
the scope's own counter still counts the refusal), and `concurrent` caps how many run at once (the excess
|
|
278
|
+
is deferred to the delayed set and runs when a slot frees — never dropped, no budget spent while waiting).
|
|
279
|
+
Edits apply live: the worker hot-reloads the file and keeps the last good version on a bad edit.
|
|
280
|
+
|
|
281
|
+
Separate from all of that, **local jobs carry a built-in one-job-per-folder mutex: at most one job per
|
|
282
|
+
folder at a time, always on, with NO configuration, NO tool, and NO panel key.** If an operator asks to
|
|
283
|
+
disable it, say plainly that there is no switch, deliberately: two agents editing one working tree race
|
|
284
|
+
each other with no gate and no undo, and an off switch's only use is re-opening that race. A `concurrent`
|
|
285
|
+
value on a folder scope can never raise the mutex's one-at-a-time (the lower bound always wins).
|
|
286
|
+
|
|
287
|
+
Three more things to say when asked:
|
|
288
|
+
|
|
289
|
+
- **A `scope-cap` refusal is final for that window.** The counter is not resettable from any tool; the
|
|
290
|
+
window rolls over on its own (day/week/month, UTC). Raising the cap via `dispatch_limit_edit` takes
|
|
291
|
+
effect at the next job.
|
|
292
|
+
- **Deferrals are visible only as the queue's delayed count** (the panel's status line shows it when it
|
|
293
|
+
is nonzero). That count also includes cron next-occurrences and retry backoff — a nonzero number is
|
|
294
|
+
normal on any deployment with schedules.
|
|
295
|
+
- **Per-scope in-flight is not displayed anywhere.** The panel and `dispatch_limits` show `concurrent` as
|
|
296
|
+
configuration only; the live count lives inside the worker process and no reader can see it.
|