@edgehero/pi-dispatch-admin 0.1.2 → 0.1.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/dist/index.mjs
CHANGED
|
@@ -6591,6 +6591,51 @@ ${JSON.stringify(w)}` },
|
|
|
6591
6591
|
return toolText(JSON.stringify(result));
|
|
6592
6592
|
}
|
|
6593
6593
|
});
|
|
6594
|
+
pi.registerTool({
|
|
6595
|
+
name: "dispatch_pause_edit",
|
|
6596
|
+
label: "pi-dispatch edit pause window",
|
|
6597
|
+
description: "Changes fields of an existing pause window (by array index from dispatch_pauses) and applies it live. Provide only the fields to change (scope/from/to/tz/days/dateFrom/dateTo); the rest keep their current value. The operator MUST approve a confirm dialog showing the before->after; refused with no interactive operator.",
|
|
6598
|
+
executionMode: "sequential",
|
|
6599
|
+
parameters: typebox_exports.Object({
|
|
6600
|
+
index: typebox_exports.Integer({ minimum: 0 }),
|
|
6601
|
+
scope: typebox_exports.Optional(typebox_exports.String()),
|
|
6602
|
+
from: typebox_exports.Optional(typebox_exports.String()),
|
|
6603
|
+
to: typebox_exports.Optional(typebox_exports.String()),
|
|
6604
|
+
tz: typebox_exports.Optional(typebox_exports.String()),
|
|
6605
|
+
days: typebox_exports.Optional(typebox_exports.Array(typebox_exports.String())),
|
|
6606
|
+
dateFrom: typebox_exports.Optional(typebox_exports.String()),
|
|
6607
|
+
dateTo: typebox_exports.Optional(typebox_exports.String())
|
|
6608
|
+
}),
|
|
6609
|
+
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
6610
|
+
const paths = resolvePaths(process.env);
|
|
6611
|
+
const p = readPauseWindows({ pauseWindowsPath: paths.pauseWindowsPath });
|
|
6612
|
+
const list = Array.isArray(p?.windows) ? p.windows : [];
|
|
6613
|
+
const cur = list[params.index];
|
|
6614
|
+
if (!cur) throw new Error(`no pause window at index ${params.index} (have ${list.length})`);
|
|
6615
|
+
const before = buildPauseWindow(cur);
|
|
6616
|
+
const merged = buildPauseWindow({
|
|
6617
|
+
scope: params.scope ?? cur.scope,
|
|
6618
|
+
from: params.from ?? cur.from,
|
|
6619
|
+
to: params.to ?? cur.to,
|
|
6620
|
+
tz: params.tz ?? cur.tz,
|
|
6621
|
+
days: params.days ?? cur.days,
|
|
6622
|
+
dateFrom: params.dateFrom ?? cur.dateFrom,
|
|
6623
|
+
dateTo: params.dateTo ?? cur.dateTo
|
|
6624
|
+
});
|
|
6625
|
+
const result = await confirmedWrite(
|
|
6626
|
+
ctx,
|
|
6627
|
+
{ title: `Edit pause window #${params.index + 1}`, message: `pause window #${params.index + 1}:
|
|
6628
|
+
${JSON.stringify(before)}
|
|
6629
|
+
\u2192 ${JSON.stringify(merged)}` },
|
|
6630
|
+
() => {
|
|
6631
|
+
const res = writePauseWindows({ pauseWindowsPath: paths.pauseWindowsPath, mutate: (l) => l.map((w, i) => i === params.index ? merged : w) });
|
|
6632
|
+
if (res.invalid) throw new Error(`rejected: ${res.invalid}`);
|
|
6633
|
+
return { applied: true, index: params.index, window: merged };
|
|
6634
|
+
}
|
|
6635
|
+
);
|
|
6636
|
+
return toolText(JSON.stringify(result));
|
|
6637
|
+
}
|
|
6638
|
+
});
|
|
6594
6639
|
pi.registerTool({
|
|
6595
6640
|
name: "dispatch_trigger_delete",
|
|
6596
6641
|
label: "pi-dispatch delete trigger",
|
|
@@ -6814,9 +6859,10 @@ async function handleDashboardAction(result, paths, ctx) {
|
|
|
6814
6859
|
}
|
|
6815
6860
|
}
|
|
6816
6861
|
async function managePausesViaDialogs(paths, ui, notify) {
|
|
6817
|
-
const action = await ui.select("Pause windows", ["Add a pause window", "Delete a pause window"]);
|
|
6862
|
+
const action = await ui.select("Pause windows", ["Add a pause window", "Edit a pause window", "Delete a pause window"]);
|
|
6818
6863
|
if (!action) return;
|
|
6819
6864
|
if (action.startsWith("Add")) return addPauseWindowViaDialogs(paths, ui, notify);
|
|
6865
|
+
if (action.startsWith("Edit")) return editPauseWindowViaDialogs(paths, ui, notify);
|
|
6820
6866
|
return deletePauseWindowViaDialogs(paths, ui, notify);
|
|
6821
6867
|
}
|
|
6822
6868
|
async function addPauseWindowViaDialogs(paths, ui, notify) {
|
|
@@ -6838,6 +6884,47 @@ async function addPauseWindowViaDialogs(paths, ui, notify) {
|
|
|
6838
6884
|
const res = writePauseWindows({ pauseWindowsPath: paths.pauseWindowsPath, mutate: (list) => [...list, w] });
|
|
6839
6885
|
notify?.(res.ok ? `pause window added (live) \u2014 ${w.scope} ${w.from}-${w.to}` : `add rejected: ${res.invalid}`, res.ok ? "info" : "error");
|
|
6840
6886
|
}
|
|
6887
|
+
async function editPauseWindowViaDialogs(paths, ui, notify) {
|
|
6888
|
+
const p = readPauseWindows({ pauseWindowsPath: paths.pauseWindowsPath });
|
|
6889
|
+
const list = Array.isArray(p?.windows) ? p.windows : [];
|
|
6890
|
+
if (list.length === 0) {
|
|
6891
|
+
notify?.("no pause windows to edit", "info");
|
|
6892
|
+
return;
|
|
6893
|
+
}
|
|
6894
|
+
const labels = list.map((w, i) => `#${i + 1} ${w.scope} ${w.from}-${w.to} ${w.tz}${w.days ? ` [${w.days.join(",")}]` : ""}`);
|
|
6895
|
+
const picked = await ui.select("Edit which pause window", labels);
|
|
6896
|
+
if (!picked) return;
|
|
6897
|
+
const index = labels.indexOf(picked);
|
|
6898
|
+
if (index < 0) return;
|
|
6899
|
+
const cur = list[index];
|
|
6900
|
+
const ask = async (label, current) => ui.input(`${label} \u2014 blank keeps "${current}"`, current);
|
|
6901
|
+
const keep = (v, current) => v === void 0 || v.trim() === "" ? current : v;
|
|
6902
|
+
const scope = await ask("scope", cur.scope ?? "");
|
|
6903
|
+
if (scope === void 0) return;
|
|
6904
|
+
const from = await ask("from (HH:MM)", cur.from ?? "");
|
|
6905
|
+
if (from === void 0) return;
|
|
6906
|
+
const to = await ask("to (HH:MM)", cur.to ?? "");
|
|
6907
|
+
if (to === void 0) return;
|
|
6908
|
+
const tz = await ask("tz (IANA / UTC)", cur.tz ?? "UTC");
|
|
6909
|
+
if (tz === void 0) return;
|
|
6910
|
+
const days = await ask("days (space-separated)", (cur.days ?? []).join(" "));
|
|
6911
|
+
if (days === void 0) return;
|
|
6912
|
+
const dateFrom = await ask("dateFrom (YYYY-MM-DD)", cur.dateFrom ?? "");
|
|
6913
|
+
if (dateFrom === void 0) return;
|
|
6914
|
+
const dateTo = await ask("dateTo (YYYY-MM-DD)", cur.dateTo ?? "");
|
|
6915
|
+
if (dateTo === void 0) return;
|
|
6916
|
+
const merged = buildPauseWindow({
|
|
6917
|
+
scope: keep(scope, cur.scope),
|
|
6918
|
+
from: keep(from, cur.from),
|
|
6919
|
+
to: keep(to, cur.to),
|
|
6920
|
+
tz: keep(tz, cur.tz),
|
|
6921
|
+
days: keep(days, cur.days),
|
|
6922
|
+
dateFrom: keep(dateFrom, cur.dateFrom),
|
|
6923
|
+
dateTo: keep(dateTo, cur.dateTo)
|
|
6924
|
+
});
|
|
6925
|
+
const res = writePauseWindows({ pauseWindowsPath: paths.pauseWindowsPath, mutate: (l) => l.map((w, i) => i === index ? merged : w) });
|
|
6926
|
+
notify?.(res.ok ? `pause window #${index + 1} updated (live) \u2014 ${merged.scope} ${merged.from}-${merged.to}` : `edit rejected: ${res.invalid}`, res.ok ? "info" : "error");
|
|
6927
|
+
}
|
|
6841
6928
|
async function deletePauseWindowViaDialogs(paths, ui, notify) {
|
|
6842
6929
|
const p = readPauseWindows({ pauseWindowsPath: paths.pauseWindowsPath });
|
|
6843
6930
|
const list = Array.isArray(p?.windows) ? p.windows : [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgehero/pi-dispatch-admin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
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 triggers (cron/label/comment/PR), and scheduled pause windows — plus AI-operable, human-confirmed controls. Runs against a live pi-dispatch deployment.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -30,9 +30,10 @@ dialog before it takes effect**:
|
|
|
30
30
|
- `dispatch_set` — change a limit/setting (e.g. `dailyCap`, `weeklyCap`, `maxTurns`, `model`). Omit `value`
|
|
31
31
|
to unset.
|
|
32
32
|
- `dispatch_trigger_add` / `dispatch_trigger_edit` / `dispatch_trigger_delete` — manage triggers.
|
|
33
|
-
- `dispatch_pause_add` / `dispatch_pause_delete` — manage scheduled pause windows
|
|
34
|
-
hours": runs for a scope are deferred between certain times and auto-resume after;
|
|
35
|
-
them).
|
|
33
|
+
- `dispatch_pause_add` / `dispatch_pause_edit` / `dispatch_pause_delete` — manage scheduled pause windows
|
|
34
|
+
(per folder/repo "quiet hours": runs for a scope are deferred between certain times and auto-resume after;
|
|
35
|
+
`dispatch_pauses` lists them with their index). `dispatch_pause_edit` is a partial change — pass the index
|
|
36
|
+
plus only the fields to alter. Deferring never drops a job and costs no budget.
|
|
36
37
|
|
|
37
38
|
Use them like this:
|
|
38
39
|
|