@joshuafolkken/kit 1.1229.0 → 1.1240.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/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +5 -0
- package/.claude/skills/workflow-commands/kickoff.md +1 -0
- package/.claude/skills/workflow-commands/latest-gate.md +1 -1
- package/.github/workflows/publish.yml +2 -0
- package/README.md +30 -31
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-JUDKDCDP.js → chunk-4TZVB44A.js} +8 -8
- package/dist/hooks/{chunk-RNWHN5BP.js → chunk-F3ELQ2AF.js} +3 -3
- package/dist/hooks/{chunk-VC3PZPZO.js → chunk-GPTFMK5E.js} +1 -1
- package/dist/hooks/{chunk-FIVDHQGT.js → chunk-KHGB5S3Y.js} +1 -1
- package/dist/hooks/{chunk-NV2JRZZO.js → chunk-KHX4U3BG.js} +17 -2
- package/dist/hooks/{chunk-F56MFS4B.js → chunk-KRBERBBI.js} +3 -3
- package/dist/hooks/{chunk-TQNPDZNH.js → chunk-QVSWU24O.js} +4 -4
- package/dist/hooks/{chunk-55HHG5PX.js → chunk-WK2XSHSI.js} +284 -63
- package/dist/hooks/{chunk-5VMKCCC4.js → chunk-XZYKEM6J.js} +2 -2
- package/dist/hooks/{chunk-6HJJXRBX.js → chunk-ZQGD4GBY.js} +1 -1
- package/dist/hooks/codex-hook-adapter.js +10 -10
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +172 -170
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/stop-guard.js +3 -17
- package/dist/josh.js +279 -63
- package/package.json +1 -1
- package/prompts/collaboration-workflow/issue-template.md +1 -0
- package/scripts/gate/core-admission.ts +162 -0
- package/scripts/gate/core-budget.ts +121 -67
- package/scripts/gate/gate-plan.ts +35 -2
- package/scripts/gate/gate-report.ts +28 -9
- package/scripts/gate/machine-capacity.ts +175 -0
- package/scripts/gate/verification-gate.ts +7 -2
- package/scripts/init/init.ts +5 -1
- package/scripts/init/package-manager-pin.ts +35 -0
- package/scripts/issue/issue-auto-ok.ts +31 -6
- package/scripts/issue/issue-file-cli.ts +31 -8
- package/scripts/issue/issue-file.ts +5 -0
- package/scripts/issue/issue-labels.ts +13 -0
- package/scripts/issue/issue-release-cli.ts +155 -0
- package/scripts/issue/issue-release.ts +58 -0
- package/scripts/josh/josh-command-types.ts +3 -0
- package/scripts/josh/josh-commands-development.ts +8 -0
- package/scripts/josh/josh-commands-issue.ts +8 -1
- package/scripts/josh/josh-commands-lane.ts +2 -1
- package/scripts/josh/josh-commands-maintenance.ts +2 -2
- package/scripts/josh/josh-logic.ts +4 -3
- package/scripts/lane/lane-cli.ts +9 -1
- package/scripts/lane/lane-leftover.ts +43 -29
- package/scripts/lane/lane-open.ts +5 -5
- package/scripts/lane/lane-paths.ts +13 -0
- package/scripts/lane/lane-registry.ts +11 -0
- package/scripts/lane/lane-stray.ts +140 -0
- package/scripts/release/github-release-environment.ts +1 -0
- package/scripts/release/github-release-runs.ts +115 -0
- package/scripts/release/github-release.ts +13 -67
- package/scripts/run/cut/run-cut-cli.ts +16 -3
- package/scripts/run/event/run-event-render.ts +1 -0
- package/scripts/run/event/run-event-stream.ts +4 -0
- package/scripts/run/run-step.ts +5 -2
- package/scripts/run/wake/run-wake-cli.ts +2 -3
- package/scripts/run/wake/run-wake-describe.ts +56 -5
- package/scripts/run/wake/run-wake-loop.ts +5 -13
- package/scripts/run/wake/run-wake.ts +15 -64
- package/scripts/version/latest-corepack.ts +109 -78
- package/templates/workflows/github-release.yml +4 -0
|
@@ -309,10 +309,16 @@ var ISSUE_COMMANDS = {
|
|
|
309
309
|
description: "File an Issue with every filing step: lint, Origin, WIP cap, duplicate scout, labels, then epic:bundle",
|
|
310
310
|
category: "AI tools",
|
|
311
311
|
reference: [
|
|
312
|
-
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok]",
|
|
312
|
+
"<title> --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>] [--distinct <N,\u2026>] [--over-cap] [--no-auto-ok] [--release]",
|
|
313
313
|
"automation",
|
|
314
314
|
["network"]
|
|
315
315
|
]
|
|
316
|
+
},
|
|
317
|
+
"issue:release": {
|
|
318
|
+
script: "scripts/issue/issue-release-cli.ts",
|
|
319
|
+
description: "Link an Issue to the repository's open release Issue as its blocker, filing one when none is open",
|
|
320
|
+
category: "AI tools",
|
|
321
|
+
reference: ["<issue>", "automation", ["network"]]
|
|
316
322
|
}
|
|
317
323
|
};
|
|
318
324
|
|
|
@@ -348,7 +354,7 @@ var LANE_COMMANDS = {
|
|
|
348
354
|
},
|
|
349
355
|
"lane:prune": {
|
|
350
356
|
...LANE_ARGUMENTS,
|
|
351
|
-
description: "Close every lane an interruption left without its work tree",
|
|
357
|
+
description: "Close every lane an interruption left without its work tree, then sweep unregistered leftovers under the lanes root",
|
|
352
358
|
category: "AI tools",
|
|
353
359
|
reference: ["", "automation", ["files", "git"]],
|
|
354
360
|
default_script_arguments: ["prune"]
|
|
@@ -741,7 +747,7 @@ var CLONE_COMMANDS = {
|
|
|
741
747
|
// scripts/gate/core-budget.ts
|
|
742
748
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
743
749
|
import { readdirSync as readdirSync2 } from "node:fs";
|
|
744
|
-
import { availableParallelism as
|
|
750
|
+
import { availableParallelism as availableParallelism3 } from "node:os";
|
|
745
751
|
import path3 from "node:path";
|
|
746
752
|
|
|
747
753
|
// scripts/josh/process-identity.ts
|
|
@@ -1016,6 +1022,159 @@ var unit_worker_share = {
|
|
|
1016
1022
|
|
|
1017
1023
|
// scripts/gate/core-budget.ts
|
|
1018
1024
|
import { z as z3 } from "zod";
|
|
1025
|
+
|
|
1026
|
+
// scripts/gate/core-admission.ts
|
|
1027
|
+
var MS_PER_SECOND = 1e3;
|
|
1028
|
+
var RAMP_UP_MS = 3e4;
|
|
1029
|
+
function compare_claim(left, right) {
|
|
1030
|
+
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
1031
|
+
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
1032
|
+
}
|
|
1033
|
+
function add_load(totals, reservation) {
|
|
1034
|
+
totals.cores += reservation.weight;
|
|
1035
|
+
totals.memory_mb += reservation.memory_mb ?? 0;
|
|
1036
|
+
}
|
|
1037
|
+
function exceeds(totals, budget) {
|
|
1038
|
+
return totals.cores > budget.cores || totals.memory_mb > budget.memory_mb;
|
|
1039
|
+
}
|
|
1040
|
+
function admitted_keys(reservations, budget, memory_budget = Infinity) {
|
|
1041
|
+
const limit = { cores: budget, memory_mb: memory_budget };
|
|
1042
|
+
const totals = { cores: 0, memory_mb: 0 };
|
|
1043
|
+
const admitted = /* @__PURE__ */ new Set();
|
|
1044
|
+
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
1045
|
+
add_load(totals, entry.reservation);
|
|
1046
|
+
if (index !== 0 && exceeds(totals, limit)) break;
|
|
1047
|
+
admitted.add(entry.key);
|
|
1048
|
+
}
|
|
1049
|
+
return admitted;
|
|
1050
|
+
}
|
|
1051
|
+
function is_admitted(key, reservations, budget) {
|
|
1052
|
+
return admitted_keys(reservations, budget.cores, budget.memory_mb).has(key);
|
|
1053
|
+
}
|
|
1054
|
+
function sum_load(reservations) {
|
|
1055
|
+
const load = { cores: 0, memory_mb: 0 };
|
|
1056
|
+
for (const entry of reservations) add_load(load, entry.reservation);
|
|
1057
|
+
return load;
|
|
1058
|
+
}
|
|
1059
|
+
function is_ramped(reservation, now) {
|
|
1060
|
+
const { admitted_at } = reservation;
|
|
1061
|
+
return admitted_at !== void 0 && now - admitted_at >= RAMP_UP_MS;
|
|
1062
|
+
}
|
|
1063
|
+
function ledger_load(reservations, now) {
|
|
1064
|
+
const admitted = reservations.filter((entry) => entry.reservation.admitted_at !== void 0);
|
|
1065
|
+
const ramped = admitted.filter((entry) => is_ramped(entry.reservation, now));
|
|
1066
|
+
return { cores: sum_load(admitted).cores, memory_mb: sum_load(ramped).memory_mb };
|
|
1067
|
+
}
|
|
1068
|
+
function total_weight(reservations) {
|
|
1069
|
+
return sum_load(reservations).cores;
|
|
1070
|
+
}
|
|
1071
|
+
function admitted_load(reservations, budget) {
|
|
1072
|
+
const admitted = admitted_keys(reservations, budget);
|
|
1073
|
+
return total_weight(reservations.filter((entry) => admitted.has(entry.key)));
|
|
1074
|
+
}
|
|
1075
|
+
function describe_memory(ledger, budget) {
|
|
1076
|
+
if (!Number.isFinite(budget.memory_mb)) return "";
|
|
1077
|
+
return ` and ${String(Math.round(ledger.memory_mb))} MB of memory against ${String(Math.round(budget.memory_mb))} MB`;
|
|
1078
|
+
}
|
|
1079
|
+
function describe_overflow(admission) {
|
|
1080
|
+
const { overflow } = admission;
|
|
1081
|
+
if (overflow === void 0) return void 0;
|
|
1082
|
+
const { ledger, budget } = overflow;
|
|
1083
|
+
const waited = String(Math.round(overflow.waited_ms / MS_PER_SECOND));
|
|
1084
|
+
const cores = `the ledger held ${String(ledger.cores)} cores against a budget of ${String(budget.cores)}`;
|
|
1085
|
+
return `started past the core budget after ${waited}s \u2014 ${cores}${describe_memory(ledger, budget)}`;
|
|
1086
|
+
}
|
|
1087
|
+
var core_admission = {
|
|
1088
|
+
RAMP_UP_MS,
|
|
1089
|
+
admitted_keys,
|
|
1090
|
+
admitted_load,
|
|
1091
|
+
describe_overflow,
|
|
1092
|
+
is_admitted,
|
|
1093
|
+
ledger_load,
|
|
1094
|
+
sum_load
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
// scripts/gate/machine-capacity.ts
|
|
1098
|
+
import { readFile } from "node:fs/promises";
|
|
1099
|
+
import { availableParallelism as availableParallelism2, cpus, totalmem } from "node:os";
|
|
1100
|
+
import { execa } from "execa";
|
|
1101
|
+
var SAMPLE_WINDOW_MS = 250;
|
|
1102
|
+
var BASELINE_CORES = 2;
|
|
1103
|
+
var BYTES_PER_MB = 1048576;
|
|
1104
|
+
var KB_PER_MB = 1024;
|
|
1105
|
+
var PERCENT = 100;
|
|
1106
|
+
var MEMINFO_PATH = "/proc/meminfo";
|
|
1107
|
+
var LINUX_AVAILABLE = /^MemAvailable:\s+(?<kb>\d+) kB/mu;
|
|
1108
|
+
var PRESSURE_ARGUMENTS = ["-n", "kern.memorystatus_level"];
|
|
1109
|
+
var PRESSURE_LEVEL = /^\s*(?<level>\d+)\s*$/u;
|
|
1110
|
+
function cpu_times() {
|
|
1111
|
+
let busy = 0;
|
|
1112
|
+
let idle = 0;
|
|
1113
|
+
for (const { times } of cpus()) {
|
|
1114
|
+
busy += times.user + times.nice + times.sys + times.irq;
|
|
1115
|
+
idle += times.idle;
|
|
1116
|
+
}
|
|
1117
|
+
return { busy, total: busy + idle };
|
|
1118
|
+
}
|
|
1119
|
+
function busy_cores_between(before, after, cores) {
|
|
1120
|
+
const total = after.total - before.total;
|
|
1121
|
+
if (total <= 0) return void 0;
|
|
1122
|
+
return (after.busy - before.busy) / total * cores;
|
|
1123
|
+
}
|
|
1124
|
+
function parse_darwin_pressure(output, total_bytes) {
|
|
1125
|
+
const level = PRESSURE_LEVEL.exec(output)?.groups?.["level"];
|
|
1126
|
+
if (level === void 0) return void 0;
|
|
1127
|
+
return Number(level) / PERCENT * (total_bytes / BYTES_PER_MB);
|
|
1128
|
+
}
|
|
1129
|
+
function parse_linux_available(meminfo) {
|
|
1130
|
+
const kb = LINUX_AVAILABLE.exec(meminfo)?.groups?.["kb"];
|
|
1131
|
+
return kb === void 0 ? void 0 : Number(kb) / KB_PER_MB;
|
|
1132
|
+
}
|
|
1133
|
+
async function read_available_mb(platform = process.platform) {
|
|
1134
|
+
try {
|
|
1135
|
+
if (platform === "darwin") {
|
|
1136
|
+
const { stdout } = await execa("sysctl", PRESSURE_ARGUMENTS);
|
|
1137
|
+
return parse_darwin_pressure(stdout, totalmem());
|
|
1138
|
+
}
|
|
1139
|
+
return platform === "linux" ? parse_linux_available(await readFile(MEMINFO_PATH, "utf8")) : void 0;
|
|
1140
|
+
} catch {
|
|
1141
|
+
return void 0;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
function is_unquoted() {
|
|
1145
|
+
return cpus().length > 0 && cpus().length === availableParallelism2();
|
|
1146
|
+
}
|
|
1147
|
+
async function default_sleep(ms) {
|
|
1148
|
+
await new Promise((resolve) => {
|
|
1149
|
+
setTimeout(resolve, ms);
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
async function read_machine(sleep = default_sleep) {
|
|
1153
|
+
const before = cpu_times();
|
|
1154
|
+
const [available_mb] = await Promise.all([read_available_mb(), sleep(SAMPLE_WINDOW_MS)]);
|
|
1155
|
+
const busy_cores = is_unquoted() ? busy_cores_between(before, cpu_times(), cpus().length) : void 0;
|
|
1156
|
+
return { busy_cores, available_mb };
|
|
1157
|
+
}
|
|
1158
|
+
function external_cores(busy_cores, ledger_cores) {
|
|
1159
|
+
if (busy_cores === void 0) return 0;
|
|
1160
|
+
return Math.floor(Math.max(0, busy_cores - ledger_cores - BASELINE_CORES));
|
|
1161
|
+
}
|
|
1162
|
+
function machine_budget(cores, reading, ledger) {
|
|
1163
|
+
return {
|
|
1164
|
+
cores: cores - external_cores(reading.busy_cores, ledger.cores),
|
|
1165
|
+
memory_mb: reading.available_mb === void 0 ? Infinity : reading.available_mb + ledger.memory_mb
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
var machine_capacity = {
|
|
1169
|
+
BASELINE_CORES,
|
|
1170
|
+
busy_cores_between,
|
|
1171
|
+
machine_budget,
|
|
1172
|
+
parse_darwin_pressure,
|
|
1173
|
+
parse_linux_available,
|
|
1174
|
+
read_machine
|
|
1175
|
+
};
|
|
1176
|
+
|
|
1177
|
+
// scripts/gate/core-budget.ts
|
|
1019
1178
|
var RESERVED_PREFIX = "josh-core-reserved-";
|
|
1020
1179
|
var RESERVED_SUFFIX = ".json";
|
|
1021
1180
|
var POLL_INTERVAL_MS = 50;
|
|
@@ -1027,11 +1186,20 @@ var CORE_WEIGHTS = {
|
|
|
1027
1186
|
spell_check: 1,
|
|
1028
1187
|
eslint_scan: 1
|
|
1029
1188
|
};
|
|
1189
|
+
var MEMORY_MB = {
|
|
1190
|
+
lint: 2400,
|
|
1191
|
+
type_check: 1300,
|
|
1192
|
+
spell_check: 350,
|
|
1193
|
+
eslint_scan: 2400,
|
|
1194
|
+
unit_worker: 350
|
|
1195
|
+
};
|
|
1030
1196
|
var HELD_KEY = "JOSH_CORE_RESERVED";
|
|
1031
1197
|
var HELD_VALUE = "1";
|
|
1032
1198
|
var reservation_schema = process_owner_schema.extend({
|
|
1033
1199
|
weight: z3.number(),
|
|
1034
|
-
claimed_at: z3.number()
|
|
1200
|
+
claimed_at: z3.number(),
|
|
1201
|
+
memory_mb: z3.number().optional(),
|
|
1202
|
+
admitted_at: z3.number().optional()
|
|
1035
1203
|
});
|
|
1036
1204
|
function marker_name(key) {
|
|
1037
1205
|
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
|
|
@@ -1064,7 +1232,9 @@ function live_reservation(source) {
|
|
|
1064
1232
|
}
|
|
1065
1233
|
function marker_files2(directory) {
|
|
1066
1234
|
try {
|
|
1067
|
-
return readdirSync2(directory).filter(
|
|
1235
|
+
return readdirSync2(directory).filter(
|
|
1236
|
+
(name) => name.startsWith(RESERVED_PREFIX) && name.endsWith(RESERVED_SUFFIX)
|
|
1237
|
+
);
|
|
1068
1238
|
} catch {
|
|
1069
1239
|
return [];
|
|
1070
1240
|
}
|
|
@@ -1075,67 +1245,79 @@ function live_reservations(directory = PLATFORM_TEMP_ROOT) {
|
|
|
1075
1245
|
return reservation === void 0 ? [] : { key: name, reservation };
|
|
1076
1246
|
});
|
|
1077
1247
|
}
|
|
1078
|
-
function compare_claim(left, right) {
|
|
1079
|
-
const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
|
|
1080
|
-
return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
|
|
1081
|
-
}
|
|
1082
|
-
function admitted_keys(reservations, budget) {
|
|
1083
|
-
const admitted = /* @__PURE__ */ new Set();
|
|
1084
|
-
let cumulative = 0;
|
|
1085
|
-
for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
|
|
1086
|
-
cumulative += entry.reservation.weight;
|
|
1087
|
-
if (index !== 0 && cumulative > budget) break;
|
|
1088
|
-
admitted.add(entry.key);
|
|
1089
|
-
}
|
|
1090
|
-
return admitted;
|
|
1091
|
-
}
|
|
1092
|
-
function is_admitted(key, reservations, budget) {
|
|
1093
|
-
return admitted_keys(reservations, budget).has(key);
|
|
1094
|
-
}
|
|
1095
|
-
function admitted_load(reservations, budget) {
|
|
1096
|
-
const admitted = admitted_keys(reservations, budget);
|
|
1097
|
-
return reservations.filter((entry) => admitted.has(entry.key)).reduce((total, entry) => total + entry.reservation.weight, 0);
|
|
1098
|
-
}
|
|
1099
1248
|
function normalize_budget(budget) {
|
|
1100
1249
|
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
|
|
1101
1250
|
}
|
|
1102
|
-
async function
|
|
1251
|
+
async function default_sleep2(ms) {
|
|
1103
1252
|
await new Promise((resolve) => {
|
|
1104
1253
|
setTimeout(resolve, ms);
|
|
1105
1254
|
});
|
|
1106
1255
|
}
|
|
1107
|
-
function write_reservation(target,
|
|
1108
|
-
stamp_file.
|
|
1256
|
+
function write_reservation(target, fields) {
|
|
1257
|
+
stamp_file.replace_stamp(target, { ...process_identity.own_fields(), ...fields });
|
|
1109
1258
|
}
|
|
1110
1259
|
function resolve_timing(options) {
|
|
1111
1260
|
return {
|
|
1112
1261
|
now: options.now ?? Date.now,
|
|
1113
|
-
sleep: options.sleep ??
|
|
1114
|
-
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS
|
|
1262
|
+
sleep: options.sleep ?? default_sleep2,
|
|
1263
|
+
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
|
|
1264
|
+
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS
|
|
1115
1265
|
};
|
|
1116
1266
|
}
|
|
1267
|
+
async function current_budget(context, reservations) {
|
|
1268
|
+
if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity };
|
|
1269
|
+
const reading = await context.read_machine();
|
|
1270
|
+
const ledger = core_admission.ledger_load(reservations, context.now());
|
|
1271
|
+
const budget = machine_capacity.machine_budget(context.budget, reading, ledger);
|
|
1272
|
+
return { ...budget, cores: normalize_budget(budget.cores) };
|
|
1273
|
+
}
|
|
1274
|
+
function admit(context, overflow) {
|
|
1275
|
+
write_reservation(context.target, { ...context.fields, admitted_at: context.now() });
|
|
1276
|
+
return { overflow };
|
|
1277
|
+
}
|
|
1278
|
+
function overflow_of(context, reservations, budget) {
|
|
1279
|
+
return {
|
|
1280
|
+
waited_ms: context.now() - context.fields.claimed_at,
|
|
1281
|
+
ledger: core_admission.sum_load(reservations),
|
|
1282
|
+
budget
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
async function poll_admission(context) {
|
|
1286
|
+
const reservations = live_reservations(context.directory);
|
|
1287
|
+
const budget = await current_budget(context, reservations);
|
|
1288
|
+
if (core_admission.is_admitted(context.key, reservations, budget)) return admit(context);
|
|
1289
|
+
if (context.now() >= context.deadline) {
|
|
1290
|
+
return admit(context, overflow_of(context, reservations, budget));
|
|
1291
|
+
}
|
|
1292
|
+
return void 0;
|
|
1293
|
+
}
|
|
1117
1294
|
async function await_admission(context) {
|
|
1118
|
-
|
|
1119
|
-
|
|
1295
|
+
let admission = await poll_admission(context);
|
|
1296
|
+
while (admission === void 0) {
|
|
1120
1297
|
await context.sleep(context.poll_interval_ms);
|
|
1298
|
+
admission = await poll_admission(context);
|
|
1121
1299
|
}
|
|
1300
|
+
return admission;
|
|
1122
1301
|
}
|
|
1123
1302
|
async function reserve(weight, options = {}) {
|
|
1124
1303
|
const timing = resolve_timing(options);
|
|
1125
1304
|
const directory = options.directory ?? PLATFORM_TEMP_ROOT;
|
|
1126
|
-
const budget = normalize_budget(options.budget ?? availableParallelism2());
|
|
1127
1305
|
const claimed_at = timing.now();
|
|
1128
1306
|
const name = marker_name(randomUUID2());
|
|
1129
1307
|
const target = path3.join(directory, name);
|
|
1130
|
-
|
|
1131
|
-
|
|
1308
|
+
const fields = { weight, claimed_at, memory_mb: options.memory_mb };
|
|
1309
|
+
write_reservation(target, fields);
|
|
1310
|
+
const admission = await await_admission({
|
|
1132
1311
|
...timing,
|
|
1133
1312
|
key: name,
|
|
1313
|
+
target,
|
|
1134
1314
|
directory,
|
|
1135
|
-
budget,
|
|
1136
|
-
deadline: claimed_at +
|
|
1315
|
+
budget: normalize_budget(options.budget ?? availableParallelism3()),
|
|
1316
|
+
deadline: claimed_at + timing.wait_cap_ms,
|
|
1317
|
+
fields,
|
|
1318
|
+
read_machine: options.read_machine ?? machine_capacity.read_machine
|
|
1137
1319
|
});
|
|
1138
|
-
return { target };
|
|
1320
|
+
return { target, admission };
|
|
1139
1321
|
}
|
|
1140
1322
|
function release(handle) {
|
|
1141
1323
|
sweep_marker2(handle.target);
|
|
@@ -1143,7 +1325,7 @@ function release(handle) {
|
|
|
1143
1325
|
async function with_core_reservation(weight, run, options = {}) {
|
|
1144
1326
|
const handle = await reserve(weight, options);
|
|
1145
1327
|
try {
|
|
1146
|
-
return await run();
|
|
1328
|
+
return await run(handle.admission);
|
|
1147
1329
|
} finally {
|
|
1148
1330
|
release(handle);
|
|
1149
1331
|
}
|
|
@@ -1171,9 +1353,11 @@ var core_budget = {
|
|
|
1171
1353
|
CORE_WEIGHTS,
|
|
1172
1354
|
HELD_KEY,
|
|
1173
1355
|
HELD_VALUE,
|
|
1356
|
+
MEMORY_MB,
|
|
1174
1357
|
RESERVED_PREFIX,
|
|
1175
|
-
admitted_keys,
|
|
1176
|
-
admitted_load,
|
|
1358
|
+
admitted_keys: core_admission.admitted_keys,
|
|
1359
|
+
admitted_load: core_admission.admitted_load,
|
|
1360
|
+
describe_overflow: core_admission.describe_overflow,
|
|
1177
1361
|
is_held,
|
|
1178
1362
|
live_reservations,
|
|
1179
1363
|
release,
|
|
@@ -1184,7 +1368,7 @@ var core_budget = {
|
|
|
1184
1368
|
};
|
|
1185
1369
|
|
|
1186
1370
|
// scripts/gate/gate-plan.ts
|
|
1187
|
-
import { availableParallelism as
|
|
1371
|
+
import { availableParallelism as availableParallelism4 } from "node:os";
|
|
1188
1372
|
|
|
1189
1373
|
// scripts/lib/status-icons.ts
|
|
1190
1374
|
var FAIL_ICON = "\u2717";
|
|
@@ -1234,13 +1418,24 @@ var UNIT_LABEL = "test:unit";
|
|
|
1234
1418
|
var BEHAVIOR_LABEL = "behavior";
|
|
1235
1419
|
var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
|
|
1236
1420
|
var STATIC_CHECKS = [
|
|
1237
|
-
{
|
|
1421
|
+
{
|
|
1422
|
+
label: LINT_LABEL,
|
|
1423
|
+
target: "lint",
|
|
1424
|
+
reserved_cores: core_budget.CORE_WEIGHTS.lint,
|
|
1425
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1426
|
+
},
|
|
1238
1427
|
{
|
|
1239
1428
|
label: TYPE_CHECK_LABEL,
|
|
1240
1429
|
target: "check",
|
|
1241
|
-
reserved_cores: core_budget.CORE_WEIGHTS.type_check
|
|
1430
|
+
reserved_cores: core_budget.CORE_WEIGHTS.type_check,
|
|
1431
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
label: "cspell",
|
|
1435
|
+
target: "cspell:dot",
|
|
1436
|
+
reserved_cores: core_budget.CORE_WEIGHTS.spell_check,
|
|
1437
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1242
1438
|
},
|
|
1243
|
-
{ label: "cspell", target: "cspell:dot", reserved_cores: core_budget.CORE_WEIGHTS.spell_check },
|
|
1244
1439
|
{ label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
|
|
1245
1440
|
// **The unused-member check reserves no core** (joshuafolkken/kit#2987): it builds one TypeScript
|
|
1246
1441
|
// program and walks it for about 5s, and it is over well before lint and the type check. A
|
|
@@ -1293,14 +1488,24 @@ function check_weight(check, plan, available_cores) {
|
|
|
1293
1488
|
if (check.label !== UNIT_LABEL) return check.reserved_cores;
|
|
1294
1489
|
return plan.unit_worker_cap ?? solo_unit_weight(available_cores);
|
|
1295
1490
|
}
|
|
1296
|
-
function
|
|
1491
|
+
function unit_memory(workers) {
|
|
1492
|
+
return workers * core_budget.MEMORY_MB.unit_worker;
|
|
1493
|
+
}
|
|
1494
|
+
function check_memory(check, plan, available_cores) {
|
|
1495
|
+
if (check.label !== UNIT_LABEL) return check.memory_mb ?? 0;
|
|
1496
|
+
return unit_memory(check_weight(check, plan, available_cores));
|
|
1497
|
+
}
|
|
1498
|
+
function direct_unit_weight(available_cores = availableParallelism4(), live_runs = unit_worker_share.live_run_count()) {
|
|
1297
1499
|
const weight = unit_worker_share.current_share(available_cores, live_runs) ?? solo_unit_weight(available_cores);
|
|
1298
1500
|
return Math.max(unit_worker_share.MIN_WORKERS, weight);
|
|
1299
1501
|
}
|
|
1502
|
+
function direct_unit_memory() {
|
|
1503
|
+
return unit_memory(direct_unit_weight());
|
|
1504
|
+
}
|
|
1300
1505
|
function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
|
|
1301
1506
|
return { checks, concurrency, unit_worker_cap };
|
|
1302
1507
|
}
|
|
1303
|
-
function resolve_gate_plan(available_cores =
|
|
1508
|
+
function resolve_gate_plan(available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true) {
|
|
1304
1509
|
const checks = select_gate_checks(is_unit_included);
|
|
1305
1510
|
return {
|
|
1306
1511
|
checks,
|
|
@@ -1318,7 +1523,7 @@ function format_unit_cap(plan) {
|
|
|
1318
1523
|
if (plan.unit_worker_cap === void 0) return `${UNIT_LABEL} unrestricted`;
|
|
1319
1524
|
return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`;
|
|
1320
1525
|
}
|
|
1321
|
-
function format_gate_plan(plan, available_cores =
|
|
1526
|
+
function format_gate_plan(plan, available_cores = availableParallelism4(), concurrent_runs = unit_worker_share.SOLO_RUNS) {
|
|
1322
1527
|
const cap = format_unit_cap(plan);
|
|
1323
1528
|
const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`;
|
|
1324
1529
|
const width = `${count}${josh_verdict.GATE_OPENING_MARK}`;
|
|
@@ -1334,7 +1539,9 @@ var gate_plan = {
|
|
|
1334
1539
|
TYPE_CHECK_LABEL,
|
|
1335
1540
|
UNIT_LABEL,
|
|
1336
1541
|
WARNING_CHECKER_LABELS,
|
|
1542
|
+
check_memory,
|
|
1337
1543
|
check_weight,
|
|
1544
|
+
direct_unit_memory,
|
|
1338
1545
|
direct_unit_weight,
|
|
1339
1546
|
format_gate_plan,
|
|
1340
1547
|
format_machine,
|
|
@@ -1370,28 +1577,32 @@ var DEV_COMMANDS = {
|
|
|
1370
1577
|
description: "Check code with prettier and eslint (skips a tool a basic project lacks)",
|
|
1371
1578
|
category: "Development",
|
|
1372
1579
|
reference: ["", "developer", ["processes"]],
|
|
1373
|
-
core_weight: core_budget.CORE_WEIGHTS.lint
|
|
1580
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1581
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1374
1582
|
},
|
|
1375
1583
|
"lint:related": {
|
|
1376
1584
|
script: "scripts/lint/lint-related.ts",
|
|
1377
1585
|
description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
|
|
1378
1586
|
category: "Development",
|
|
1379
1587
|
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1380
|
-
core_weight: core_budget.CORE_WEIGHTS.lint
|
|
1588
|
+
core_weight: core_budget.CORE_WEIGHTS.lint,
|
|
1589
|
+
memory_mb: core_budget.MEMORY_MB.lint
|
|
1381
1590
|
},
|
|
1382
1591
|
lines: {
|
|
1383
1592
|
script: "scripts/lines/lines-command.ts",
|
|
1384
1593
|
description: "Print a file's code lines against the max-lines limit and the headroom left",
|
|
1385
1594
|
category: "Development",
|
|
1386
1595
|
reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]],
|
|
1387
|
-
core_weight: core_budget.CORE_WEIGHTS.eslint_scan
|
|
1596
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1597
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
1388
1598
|
},
|
|
1389
1599
|
"refactor:scan": {
|
|
1390
1600
|
script: "scripts/refactor/refactor-scan-cli.ts",
|
|
1391
1601
|
description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
|
|
1392
1602
|
category: "Development",
|
|
1393
1603
|
reference: ["", "automation", ["processes"]],
|
|
1394
|
-
core_weight: core_budget.CORE_WEIGHTS.eslint_scan
|
|
1604
|
+
core_weight: core_budget.CORE_WEIGHTS.eslint_scan,
|
|
1605
|
+
memory_mb: core_budget.MEMORY_MB.eslint_scan
|
|
1395
1606
|
},
|
|
1396
1607
|
bytes: {
|
|
1397
1608
|
script: "scripts/lines/bytes-command.ts",
|
|
@@ -1471,7 +1682,8 @@ var DEV_COMMANDS = {
|
|
|
1471
1682
|
description: "Run spell check including dotfiles",
|
|
1472
1683
|
category: "Development",
|
|
1473
1684
|
reference: ["", "developer", ["processes"]],
|
|
1474
|
-
core_weight: core_budget.CORE_WEIGHTS.spell_check
|
|
1685
|
+
core_weight: core_budget.CORE_WEIGHTS.spell_check,
|
|
1686
|
+
memory_mb: core_budget.MEMORY_MB.spell_check
|
|
1475
1687
|
},
|
|
1476
1688
|
behavior: {
|
|
1477
1689
|
script: "scripts/behavior/behavior-cli.ts",
|
|
@@ -1490,14 +1702,16 @@ var DEV_COMMANDS = {
|
|
|
1490
1702
|
description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
|
|
1491
1703
|
category: "Development",
|
|
1492
1704
|
reference: [FILTER_ARGUMENTS, "developer", ["processes"]],
|
|
1493
|
-
core_weight: gate_plan.direct_unit_weight
|
|
1705
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
1706
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
1494
1707
|
},
|
|
1495
1708
|
"test:related": {
|
|
1496
1709
|
script: "scripts/test/test-related.ts",
|
|
1497
1710
|
description: "Run only the unit tests related to the changed files (full suite on fallback)",
|
|
1498
1711
|
category: "Development",
|
|
1499
1712
|
reference: [FILE_ARGUMENTS, "developer", ["processes"]],
|
|
1500
|
-
core_weight: gate_plan.direct_unit_weight
|
|
1713
|
+
core_weight: gate_plan.direct_unit_weight,
|
|
1714
|
+
memory_mb: gate_plan.direct_unit_memory
|
|
1501
1715
|
},
|
|
1502
1716
|
"test:declared": {
|
|
1503
1717
|
script: "scripts/test/test-declared.ts",
|
|
@@ -1541,7 +1755,8 @@ var DEV_COMMANDS = {
|
|
|
1541
1755
|
description: "Type-check with tsc (skips a basic project with no TypeScript to check)",
|
|
1542
1756
|
category: "Development",
|
|
1543
1757
|
reference: ["[arguments...]", "developer", ["processes"]],
|
|
1544
|
-
core_weight: core_budget.CORE_WEIGHTS.type_check
|
|
1758
|
+
core_weight: core_budget.CORE_WEIGHTS.type_check,
|
|
1759
|
+
memory_mb: core_budget.MEMORY_MB.type_check
|
|
1545
1760
|
},
|
|
1546
1761
|
port: {
|
|
1547
1762
|
script: "scripts/ports/port-command.ts",
|
|
@@ -1662,9 +1877,9 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1662
1877
|
shell: [
|
|
1663
1878
|
"sh",
|
|
1664
1879
|
"-c",
|
|
1665
|
-
"export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:
|
|
1880
|
+
"export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:update && pnpm josh ranges && pnpm josh audit && pnpm josh latest:corepack && pnpm josh latest:scope --record"
|
|
1666
1881
|
],
|
|
1667
|
-
description: "Update
|
|
1882
|
+
description: "Update dependencies, run security audit, then update pnpm",
|
|
1668
1883
|
category: "Maintenance",
|
|
1669
1884
|
reference: ["", "developer", ["files", "network", "processes"]],
|
|
1670
1885
|
argument_targets: ["latest:corepack", "latest:update", "audit"]
|
|
@@ -2479,7 +2694,7 @@ var PrConflictError = class extends Error {
|
|
|
2479
2694
|
|
|
2480
2695
|
// scripts/time-runtime/time-format.ts
|
|
2481
2696
|
var MS_PER_MINUTE = 6e4;
|
|
2482
|
-
var
|
|
2697
|
+
var MS_PER_SECOND2 = 1e3;
|
|
2483
2698
|
var MINUTE_DECIMALS = 1;
|
|
2484
2699
|
var SECOND_DECIMALS = 1;
|
|
2485
2700
|
var PERCENT_SCALE = 100;
|
|
@@ -2499,7 +2714,7 @@ function format_minutes(duration_ms) {
|
|
|
2499
2714
|
return `${(duration_ms / MS_PER_MINUTE).toFixed(MINUTE_DECIMALS)} min`;
|
|
2500
2715
|
}
|
|
2501
2716
|
function format_seconds(duration_ms) {
|
|
2502
|
-
return `${(duration_ms /
|
|
2717
|
+
return `${(duration_ms / MS_PER_SECOND2).toFixed(SECOND_DECIMALS)} s`;
|
|
2503
2718
|
}
|
|
2504
2719
|
function format_share(part, whole) {
|
|
2505
2720
|
if (whole === 0) return "n/a";
|
|
@@ -2596,7 +2811,7 @@ var git_followup_stages = {
|
|
|
2596
2811
|
var LINE_SEPARATOR = "\n";
|
|
2597
2812
|
var SECONDS_SUFFIX = " s";
|
|
2598
2813
|
var DIGIT_OR_POINT = /[\d.]/u;
|
|
2599
|
-
var
|
|
2814
|
+
var MS_PER_SECOND3 = 1e3;
|
|
2600
2815
|
var NO_STAGES = [];
|
|
2601
2816
|
function stage_body(line) {
|
|
2602
2817
|
const trimmed = line.trimStart();
|
|
@@ -2619,7 +2834,7 @@ function to_stage(body) {
|
|
|
2619
2834
|
const name = head.slice(0, start).trim();
|
|
2620
2835
|
const digits = head.slice(start);
|
|
2621
2836
|
if (name === "" || !is_duration(digits)) return void 0;
|
|
2622
|
-
return { name, duration_ms: Number(digits) *
|
|
2837
|
+
return { name, duration_ms: Number(digits) * MS_PER_SECOND3 };
|
|
2623
2838
|
}
|
|
2624
2839
|
function read_stages(text) {
|
|
2625
2840
|
if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
|
|
@@ -4090,10 +4305,16 @@ function lane_issue_of(directory, environment = process.env) {
|
|
|
4090
4305
|
function lane_branch(issue) {
|
|
4091
4306
|
return `${issue}${LANE_BRANCH_SUFFIX}`;
|
|
4092
4307
|
}
|
|
4308
|
+
var SEAT_LOCK_DIR = ".seat-locks";
|
|
4309
|
+
function is_lane_entry(name) {
|
|
4310
|
+
return LANE_ISSUE_PATTERN.test(name) || DEFAULT_LANE_ROOT_PATTERN.test(name);
|
|
4311
|
+
}
|
|
4093
4312
|
var lane_paths = {
|
|
4094
4313
|
LANE_BRANCH_SUFFIX,
|
|
4095
4314
|
LANE_ROOT_KEY,
|
|
4315
|
+
SEAT_LOCK_DIR,
|
|
4096
4316
|
default_lane_root,
|
|
4317
|
+
is_lane_entry,
|
|
4097
4318
|
lane_branch,
|
|
4098
4319
|
lane_directory,
|
|
4099
4320
|
lane_issue_of,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hook_decision
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZQGD4GBY.js";
|
|
4
4
|
import {
|
|
5
5
|
cost_blocks,
|
|
6
6
|
cost_transcript,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
time_bundle_call,
|
|
9
9
|
time_shell,
|
|
10
10
|
time_spans
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-WK2XSHSI.js";
|
|
12
12
|
|
|
13
13
|
// scripts/delegation/investigation-reads.ts
|
|
14
14
|
import path2 from "node:path";
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
2
|
import {
|
|
3
3
|
pretool_guard
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-4TZVB44A.js";
|
|
5
|
+
import "./chunk-QVSWU24O.js";
|
|
6
6
|
import {
|
|
7
7
|
bounded_pool
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-KHX4U3BG.js";
|
|
9
9
|
import {
|
|
10
10
|
build_envelope,
|
|
11
11
|
compose_context,
|
|
12
12
|
format_edited_payload
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KHGB5S3Y.js";
|
|
14
14
|
import "./chunk-JBBMAPC4.js";
|
|
15
15
|
import "./chunk-CDY4NFQG.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-F3ELQ2AF.js";
|
|
17
|
+
import "./chunk-KRBERBBI.js";
|
|
18
|
+
import "./chunk-XZYKEM6J.js";
|
|
19
|
+
import "./chunk-GPTFMK5E.js";
|
|
20
20
|
import {
|
|
21
21
|
hook_decision
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZQGD4GBY.js";
|
|
23
23
|
import {
|
|
24
24
|
time_density_hook
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-WK2XSHSI.js";
|
|
26
26
|
import "./chunk-WPALEIRX.js";
|
|
27
27
|
import "./chunk-RKUAD3I6.js";
|
|
28
28
|
import "./chunk-ELCN5LCH.js";
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
is_enabled,
|
|
10
10
|
notice_refusal_path,
|
|
11
11
|
refusal_path
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-QVSWU24O.js";
|
|
13
|
+
import "./chunk-XZYKEM6J.js";
|
|
14
|
+
import "./chunk-GPTFMK5E.js";
|
|
15
|
+
import "./chunk-ZQGD4GBY.js";
|
|
16
|
+
import "./chunk-WK2XSHSI.js";
|
|
17
17
|
import "./chunk-WPALEIRX.js";
|
|
18
18
|
import "./chunk-RKUAD3I6.js";
|
|
19
19
|
import "./chunk-ELCN5LCH.js";
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
report_no_payload,
|
|
4
4
|
run_hook
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KHGB5S3Y.js";
|
|
6
6
|
import "./chunk-JBBMAPC4.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-WK2XSHSI.js";
|
|
8
8
|
import "./chunk-RKUAD3I6.js";
|
|
9
9
|
import "./chunk-ELCN5LCH.js";
|
|
10
10
|
|