@lchase/kiln 0.10.0 → 0.12.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 +27 -0
- package/assets/serve.css +210 -480
- package/assets/serve.js +125 -3
- package/dist/board-view.js +688 -0
- package/dist/board.js +0 -97
- package/dist/cli.js +7 -1
- package/dist/config.js +5 -0
- package/dist/driver.js +48 -13
- package/dist/events.js +59 -2
- package/dist/host.js +53 -0
- package/dist/intake/jira.js +87 -0
- package/dist/jobs.js +4 -3
- package/dist/reconcile.js +7 -3
- package/dist/schemas.js +51 -3
- package/dist/serve-page.js +415 -324
- package/dist/serve.js +196 -15
- package/dist/settings.js +40 -1
- package/dist/triggers.js +787 -0
- package/dist/workflow.js +18 -15
- package/package.json +3 -2
- package/prompts/kiln/review.md +13 -0
- package/workflows/review.yaml +64 -0
package/assets/serve.js
CHANGED
|
@@ -911,6 +911,54 @@
|
|
|
911
911
|
.catch(function () { showSettingsError("Could not load settings."); });
|
|
912
912
|
}
|
|
913
913
|
|
|
914
|
+
function toggleTrigger(button) {
|
|
915
|
+
var id = button.getAttribute("data-trigger-toggle");
|
|
916
|
+
var enabled = button.getAttribute("data-enabled") !== "true";
|
|
917
|
+
var error = document.getElementById("trigger-error");
|
|
918
|
+
if (error) error.hidden = true;
|
|
919
|
+
button.disabled = true;
|
|
920
|
+
fetch("/api/settings", { cache: "no-store", headers: { Accept: "application/json" } })
|
|
921
|
+
.then(function (response) { return response.json().then(function (data) { return { ok: response.ok, data: data }; }); })
|
|
922
|
+
.then(function (result) {
|
|
923
|
+
if (!result.ok) throw new Error((result.data && result.data.error) || "Could not load settings.");
|
|
924
|
+
var data = result.data;
|
|
925
|
+
var toggles = [];
|
|
926
|
+
var buttons = document.querySelectorAll("[data-trigger-toggle]");
|
|
927
|
+
for (var i = 0; i < buttons.length; i++) {
|
|
928
|
+
var buttonId = buttons[i].getAttribute("data-trigger-toggle");
|
|
929
|
+
var on = buttons[i].getAttribute("data-enabled") === "true";
|
|
930
|
+
if (buttonId === id) on = enabled;
|
|
931
|
+
toggles.push({ id: buttonId, enabled: on });
|
|
932
|
+
}
|
|
933
|
+
var body = { revision: data.revision, repos: data.repos || {}, triggers: toggles };
|
|
934
|
+
["stallTimeoutMs", "maxAttempts", "maxFixRounds", "maxSameFingerprint", "dailyDollarCap"].forEach(function (key) {
|
|
935
|
+
if (data[key] !== undefined && data[key] !== null) body[key] = data[key];
|
|
936
|
+
});
|
|
937
|
+
if (data.sandbox) body.sandbox = data.sandbox;
|
|
938
|
+
return fetch("/api/settings", {
|
|
939
|
+
method: "PUT",
|
|
940
|
+
headers: {
|
|
941
|
+
Accept: "application/json",
|
|
942
|
+
"Content-Type": "application/json",
|
|
943
|
+
"X-Kiln-CSRF": document.body.getAttribute("data-csrf") || "",
|
|
944
|
+
},
|
|
945
|
+
body: JSON.stringify(body),
|
|
946
|
+
});
|
|
947
|
+
})
|
|
948
|
+
.then(function (response) { return response.json().then(function (data) { return { ok: response.ok, data: data }; }); })
|
|
949
|
+
.then(function (result) {
|
|
950
|
+
if (!result.ok) throw new Error((result.data && result.data.error) || "Could not save settings.");
|
|
951
|
+
location.reload();
|
|
952
|
+
})
|
|
953
|
+
.catch(function (err) {
|
|
954
|
+
button.disabled = false;
|
|
955
|
+
if (error) {
|
|
956
|
+
error.hidden = false;
|
|
957
|
+
error.textContent = err && err.message ? err.message : "Could not update the trigger.";
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
|
|
914
962
|
function saveSettings() {
|
|
915
963
|
if (settingsSaving) return;
|
|
916
964
|
if (!flushEditor()) return;
|
|
@@ -1011,8 +1059,14 @@
|
|
|
1011
1059
|
document.addEventListener("click", function (event) {
|
|
1012
1060
|
var target = event.target;
|
|
1013
1061
|
if (!target || !target.closest) return;
|
|
1014
|
-
|
|
1015
|
-
|
|
1062
|
+
var triggerToggle = target.closest("[data-trigger-toggle]");
|
|
1063
|
+
if (triggerToggle) {
|
|
1064
|
+
toggleTrigger(triggerToggle);
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
var settingsControl = target.closest("#open-settings");
|
|
1068
|
+
if (settingsControl) {
|
|
1069
|
+
if (settingsControl.tagName !== "A") openSettings();
|
|
1016
1070
|
return;
|
|
1017
1071
|
}
|
|
1018
1072
|
if (target.closest("#add-job")) {
|
|
@@ -1169,7 +1223,7 @@
|
|
|
1169
1223
|
return;
|
|
1170
1224
|
}
|
|
1171
1225
|
el.className = "status";
|
|
1172
|
-
var jobs = document.querySelectorAll(".
|
|
1226
|
+
var jobs = document.querySelectorAll(".job").length;
|
|
1173
1227
|
el.textContent = jobs + (jobs === 1 ? " job · " : " jobs · ") + new Date().toLocaleTimeString();
|
|
1174
1228
|
localizeTimes(document);
|
|
1175
1229
|
}
|
|
@@ -1194,11 +1248,20 @@
|
|
|
1194
1248
|
toggle.textContent = data.paused ? "Resume" : "Pause";
|
|
1195
1249
|
toggle.setAttribute("aria-pressed", data.paused ? "true" : "false");
|
|
1196
1250
|
form.setAttribute("action", data.paused ? "/api/resume" : "/api/pause");
|
|
1251
|
+
var label = document.getElementById("run-label");
|
|
1252
|
+
var dot = document.getElementById("run-dot");
|
|
1253
|
+
if (label) label.textContent = data.paused ? "Paused" : "Running";
|
|
1254
|
+
if (dot) dot.classList.toggle("paused", data.paused);
|
|
1197
1255
|
}
|
|
1198
1256
|
var spend = document.getElementById("spend");
|
|
1199
1257
|
if (spend && data && data.spend) {
|
|
1200
1258
|
var capText = data.spend.cap == null ? "no cap" : "$" + Number(data.spend.cap).toFixed(2);
|
|
1201
1259
|
spend.textContent = "today " + data.spend.day + " $" + Number(data.spend.usd).toFixed(2) + " / " + capText;
|
|
1260
|
+
var capNote = document.getElementById("cap-note");
|
|
1261
|
+
if (capNote) {
|
|
1262
|
+
var blocked = data.spend.blocked === true || (data.spend.cap != null && Number(data.spend.usd) >= Number(data.spend.cap));
|
|
1263
|
+
capNote.hidden = !blocked;
|
|
1264
|
+
}
|
|
1202
1265
|
}
|
|
1203
1266
|
stamp(true);
|
|
1204
1267
|
})
|
|
@@ -1237,11 +1300,70 @@
|
|
|
1237
1300
|
}
|
|
1238
1301
|
var previewBtn = document.getElementById("preview-job");
|
|
1239
1302
|
if (previewBtn) previewBtn.addEventListener("click", function () { submitIntake(true); });
|
|
1303
|
+
function readSeen() {
|
|
1304
|
+
try {
|
|
1305
|
+
var raw = localStorage.getItem("kiln-seen");
|
|
1306
|
+
var parsed = raw ? JSON.parse(raw) : {};
|
|
1307
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
1308
|
+
} catch (err) {
|
|
1309
|
+
return {};
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
function writeSeen(map) {
|
|
1314
|
+
try { localStorage.setItem("kiln-seen", JSON.stringify(map)); } catch (err) { /* private mode */ }
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
function paintCount(node, count) {
|
|
1318
|
+
if (!node) return;
|
|
1319
|
+
if (!count) {
|
|
1320
|
+
node.hidden = true;
|
|
1321
|
+
node.textContent = "";
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
node.hidden = false;
|
|
1325
|
+
node.textContent = count === 1 ? "1 change since you last looked" : count + " changes since you last looked";
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
function paintUnseen() {
|
|
1329
|
+
var seen = readSeen();
|
|
1330
|
+
var params = [];
|
|
1331
|
+
for (var id in seen) {
|
|
1332
|
+
if (!Object.prototype.hasOwnProperty.call(seen, id)) continue;
|
|
1333
|
+
if (typeof seen[id] !== "string" || !seen[id]) continue;
|
|
1334
|
+
params.push("seen=" + encodeURIComponent(id + "|" + seen[id]));
|
|
1335
|
+
}
|
|
1336
|
+
fetch("/api/unseen" + (params.length ? "?" + params.join("&") : ""), { cache: "no-store", headers: { Accept: "application/json" } })
|
|
1337
|
+
.then(function (response) { return response.ok ? response.json() : null; })
|
|
1338
|
+
.then(function (data) {
|
|
1339
|
+
if (!data) return;
|
|
1340
|
+
var counts = {};
|
|
1341
|
+
var jobs = data.jobs || [];
|
|
1342
|
+
for (var i = 0; i < jobs.length; i++) counts[jobs[i].jobId] = jobs[i].count;
|
|
1343
|
+
var nodes = document.querySelectorAll("[data-unseen-for]");
|
|
1344
|
+
for (var n = 0; n < nodes.length; n++) paintCount(nodes[n], counts[nodes[n].getAttribute("data-unseen-for")] || 0);
|
|
1345
|
+
paintCount(document.getElementById("inbox-unseen"), data.inbox || 0);
|
|
1346
|
+
})
|
|
1347
|
+
.catch(function () { /* the list still works without the badge */ });
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
function markLooking() {
|
|
1351
|
+
var id = body.getAttribute("data-job");
|
|
1352
|
+
var latest = body.getAttribute("data-latest");
|
|
1353
|
+
if (!id || !latest) return;
|
|
1354
|
+
var seen = readSeen();
|
|
1355
|
+
seen[id] = latest;
|
|
1356
|
+
writeSeen(seen);
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1240
1359
|
showFresh();
|
|
1241
1360
|
renderCompact();
|
|
1242
1361
|
notifyLabel();
|
|
1243
1362
|
applyRepo();
|
|
1244
1363
|
stamp(true);
|
|
1364
|
+
paintUnseen();
|
|
1365
|
+
markLooking();
|
|
1366
|
+
if (document.getElementById("settings-form")) loadSettings();
|
|
1245
1367
|
try {
|
|
1246
1368
|
var open = localStorage.getItem("kiln-drawer");
|
|
1247
1369
|
if (open) openJob(open);
|