@joshuafolkken/kit 1.947.0 → 1.957.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.
Files changed (41) hide show
  1. package/README.md +4 -5
  2. package/dist/hooks/batch-guard.js +4 -4
  3. package/dist/hooks/{chunk-V7RH56HU.js → chunk-244WYOEO.js} +2 -2
  4. package/dist/hooks/{chunk-IA7WC4NS.js → chunk-3ON7HOYB.js} +1 -1
  5. package/dist/hooks/{chunk-EYFJ74MJ.js → chunk-BELI5XSS.js} +6 -2
  6. package/dist/hooks/{chunk-IBFC25IX.js → chunk-GNOITLRR.js} +4 -4
  7. package/dist/hooks/{chunk-M4U4YNRE.js → chunk-HJXQZ7V4.js} +3 -3
  8. package/dist/hooks/{chunk-3FWV6CFC.js → chunk-IJPBTDTB.js} +371 -178
  9. package/dist/hooks/{chunk-NKVLBB65.js → chunk-KOCK5FXQ.js} +3 -3
  10. package/dist/hooks/{chunk-O3PEDF3M.js → chunk-LDQDZYHX.js} +1 -1
  11. package/dist/hooks/{chunk-GIX5SAAB.js → chunk-M6K7EQDO.js} +8 -8
  12. package/dist/hooks/{chunk-OM5VDM6F.js → chunk-XSL4SRMA.js} +2 -2
  13. package/dist/hooks/codex-hook-adapter.js +10 -10
  14. package/dist/hooks/duplicate-read-guard.js +5 -5
  15. package/dist/hooks/format-edited.js +2 -2
  16. package/dist/hooks/investigation-guard.js +5 -5
  17. package/dist/hooks/pretool-guard.js +9 -9
  18. package/dist/hooks/stop-guard.js +3 -3
  19. package/dist/josh.js +6 -2
  20. package/dist/version/index.js +7 -4
  21. package/package.json +1 -1
  22. package/scripts/backlog/backlog-drive-cli.ts +5 -1
  23. package/scripts/backlog/backlog-drive-retrospective.ts +20 -0
  24. package/scripts/backlog/backlog-drive.ts +7 -3
  25. package/scripts/git/git-worktree.ts +35 -4
  26. package/scripts/git/issue-labels.ts +19 -0
  27. package/scripts/git/repository-lock.ts +138 -0
  28. package/scripts/git/stash-sweep-lock.ts +6 -117
  29. package/scripts/init/project-profile.ts +9 -5
  30. package/scripts/init/start-plan.ts +145 -0
  31. package/scripts/init/start-prompt.ts +55 -0
  32. package/scripts/init/start-steps.ts +167 -0
  33. package/scripts/init/start.ts +92 -16
  34. package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +2 -1
  35. package/scripts/josh/josh-commands-project.ts +6 -2
  36. package/scripts/run/run-retrospective.ts +34 -0
  37. package/scripts/run/run-step-cli.ts +3 -5
  38. package/scripts/run/run-step.ts +3 -15
  39. package/scripts/safe-chain/project-config.ts +55 -10
  40. package/scripts/sync/sync.ts +3 -1
  41. package/scripts/version/release-age.ts +11 -6
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  lane_child_marker,
3
3
  run_issue_number
4
- } from "./chunk-O3PEDF3M.js";
4
+ } from "./chunk-LDQDZYHX.js";
5
5
  import {
6
6
  PLATFORM_TEMP_ROOT,
7
7
  cost_blocks,
@@ -12,7 +12,7 @@ import {
12
12
  time_density_hook,
13
13
  time_shell,
14
14
  time_transcript_line
15
- } from "./chunk-EYFJ74MJ.js";
15
+ } from "./chunk-BELI5XSS.js";
16
16
  import {
17
17
  ENV_FILE_NAME,
18
18
  LANE_SEAT_KEY,
@@ -1625,6 +1625,7 @@ var lane_background = {
1625
1625
  };
1626
1626
 
1627
1627
  // scripts/git/issue-labels.ts
1628
+ var EPIC_LABEL = "epic";
1628
1629
  var BUG_LABEL = "bug";
1629
1630
  var ENHANCEMENT_LABEL = "enhancement";
1630
1631
  var BREAKING_CHANGE_LABEL = "breaking-change";
@@ -1632,6 +1633,66 @@ var IN_PROGRESS_LABEL = "in-progress";
1632
1633
  var NEEDS_DECISION_LABEL = "needs-decision";
1633
1634
  var NEEDS_HUMAN_REVIEW_LABEL = "needs-human-review";
1634
1635
  var ALREADY_DONE_LABEL = "already-done";
1636
+ var INTERRUPT_ROUTE_LABEL = "route:interrupt";
1637
+ var REVIEW_CAP_ROUTE_LABEL = "route:review-cap";
1638
+ var SPLIT_ROUTE_LABEL = "route:split";
1639
+ var TIER_A_ROUTE_LABEL = "route:tier-a";
1640
+ var FILING_ROUTE_LABELS = [
1641
+ {
1642
+ name: INTERRUPT_ROUTE_LABEL,
1643
+ // Not `5319e7`, which is the `epic` label's purple: in a listing an interrupt would render as
1644
+ // an epic, and the two are read at a glance rather than by name.
1645
+ color: "1d76db",
1646
+ // Keyed to the tests rather than to severity. "A serious defect" is the self-assessment
1647
+ // `wip-cap.md` bans as a criterion, and this string is what a person reads in `gh label list`.
1648
+ description: "Filed past the WIP cap \u2014 meets one of the three interrupt tests (wip-cap.md)"
1649
+ },
1650
+ {
1651
+ name: REVIEW_CAP_ROUTE_LABEL,
1652
+ color: "eab308",
1653
+ description: "Filed by the review round cap's carry-forward (prompts/review.md \u2192 Review round cap)"
1654
+ },
1655
+ {
1656
+ name: SPLIT_ROUTE_LABEL,
1657
+ color: "0e8a16",
1658
+ description: "A child issue created by a split (split-assessment.md)"
1659
+ },
1660
+ {
1661
+ name: TIER_A_ROUTE_LABEL,
1662
+ color: "d93f0b",
1663
+ description: "Filed Tier A during implementation \u2014 an upstream defect or a prerequisite"
1664
+ }
1665
+ ];
1666
+ var DEPTH_0_LABEL = "depth:0";
1667
+ var DEPTH_1_LABEL = "depth:1";
1668
+ var DEPTH_2_LABEL = "depth:2";
1669
+ var DEPTH_LABELS = [
1670
+ {
1671
+ name: DEPTH_0_LABEL,
1672
+ color: "0e8a16",
1673
+ description: "Depth 0 \u2014 what a consumer of this package touches (SKILL.md \xA72i)"
1674
+ },
1675
+ {
1676
+ name: DEPTH_1_LABEL,
1677
+ color: "fbc02d",
1678
+ description: "Depth 1 \u2014 the run orchestration that executes an Issue (SKILL.md \xA72i)"
1679
+ },
1680
+ {
1681
+ name: DEPTH_2_LABEL,
1682
+ color: "c5def5",
1683
+ description: "Depth 2 \u2014 what measures a run (SKILL.md \xA72i)"
1684
+ }
1685
+ ];
1686
+ var WORKFLOW_LABELS = [
1687
+ {
1688
+ name: EPIC_LABEL,
1689
+ color: "5319e7",
1690
+ description: "Tracks a batch of child issues from one split"
1691
+ },
1692
+ { name: IN_PROGRESS_LABEL, color: "0075ca", description: "Work is actively in progress" },
1693
+ ...FILING_ROUTE_LABELS,
1694
+ ...DEPTH_LABELS
1695
+ ];
1635
1696
  function has_any_label(labels, wanted) {
1636
1697
  return (labels ?? []).some((label) => wanted.has(label.name.toLowerCase()));
1637
1698
  }
@@ -1906,8 +1967,8 @@ function current_owner(repository_path = process.cwd()) {
1906
1967
  var repo_party = { FIRST_PARTY, THIRD_PARTY, UNKNOWN, classify: classify3, current_owner, target_owner };
1907
1968
 
1908
1969
  // scripts/lane/lane-registry.ts
1909
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
1910
- import path2 from "node:path";
1970
+ import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
1971
+ import path3 from "node:path";
1911
1972
 
1912
1973
  // scripts/git/git-ls-remote.ts
1913
1974
  var LS_REMOTE_COMMAND = "ls-remote";
@@ -1918,23 +1979,323 @@ function ls_remote_branch_arguments(branch_name) {
1918
1979
  return [LS_REMOTE_COMMAND, HEADS_FLAG, ORIGIN_REMOTE, `${HEADS_REF_PREFIX}${branch_name}`];
1919
1980
  }
1920
1981
 
1982
+ // scripts/git/repository-lock.ts
1983
+ import { randomUUID as randomUUID2 } from "node:crypto";
1984
+ import { linkSync, renameSync, rmSync as rmSync2 } from "node:fs";
1985
+ import { setTimeout as sleep } from "node:timers/promises";
1986
+
1987
+ // scripts/josh/process-identity.ts
1988
+ import { execFileSync as execFileSync2, spawnSync } from "node:child_process";
1989
+ import { randomUUID } from "node:crypto";
1990
+ import { readFileSync as readFileSync3, rmSync } from "node:fs";
1991
+ import { createServer } from "node:net";
1992
+ import path2 from "node:path";
1993
+ var PS_COMMAND = "/bin/ps";
1994
+ var FORMAT_FLAG = "-o";
1995
+ var START_TIME_FORMAT = "lstart=";
1996
+ var PID_FLAG = "-p";
1997
+ var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
1998
+ var PROBE_TIMEOUT_MS = 2e3;
1999
+ var LIVENESS_SIGNAL = 0;
2000
+ var LOWEST_REAL_PID = 1;
2001
+ var PROC_START_FIELD_INDEX = 19;
2002
+ var BEACON_SCHEME = "socket:";
2003
+ var BEACON_SUFFIX = ".sock";
2004
+ var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
2005
+ var BEACON_ID_LENGTH = 36;
2006
+ var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
2007
+ var WINDOWS_PLATFORM = "win32";
2008
+ var SOCKET_PROBE_SOURCE = "const net=require('node:net');const socket=net.createConnection(process.argv[1]);socket.once('connect',()=>process.exit(0));socket.once('error',()=>process.exit(1));socket.setTimeout(1000,()=>process.exit(1));";
2009
+ var beacons = /* @__PURE__ */ new Map();
2010
+ var exit_cleanup = { is_registered: false };
2011
+ function is_live_pid(pid) {
2012
+ if (pid < LOWEST_REAL_PID) return false;
2013
+ try {
2014
+ process.kill(pid, LIVENESS_SIGNAL);
2015
+ return true;
2016
+ } catch {
2017
+ return false;
2018
+ }
2019
+ }
2020
+ function read_proc_start(pid) {
2021
+ try {
2022
+ const stat = readFileSync3(`/proc/${String(pid)}/stat`, "utf8");
2023
+ const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
2024
+ const start = fields[PROC_START_FIELD_INDEX];
2025
+ return start === void 0 ? void 0 : `proc:${start}`;
2026
+ } catch {
2027
+ return void 0;
2028
+ }
2029
+ }
2030
+ function read_ps_start(pid) {
2031
+ try {
2032
+ const printed = execFileSync2(
2033
+ PS_COMMAND,
2034
+ [FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
2035
+ {
2036
+ encoding: "utf8",
2037
+ timeout: PROBE_TIMEOUT_MS,
2038
+ stdio: ["ignore", "pipe", "ignore"],
2039
+ env: PROBE_ENVIRONMENT
2040
+ }
2041
+ ).trim();
2042
+ return printed.length > 0 ? printed : void 0;
2043
+ } catch {
2044
+ return void 0;
2045
+ }
2046
+ }
2047
+ var START_PROBES = { read_proc_start, read_ps_start };
2048
+ function safe_probe(probe, pid) {
2049
+ try {
2050
+ return probe(pid);
2051
+ } catch {
2052
+ return void 0;
2053
+ }
2054
+ }
2055
+ function read_start(pid, probes = START_PROBES) {
2056
+ return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
2057
+ }
2058
+ function close_beacon(token) {
2059
+ const server = beacons.get(token);
2060
+ if (server === void 0) return;
2061
+ beacons.delete(token);
2062
+ server.close();
2063
+ rmSync(token.slice(BEACON_SCHEME.length), { force: true });
2064
+ }
2065
+ function close_beacons() {
2066
+ for (const token of beacons.keys()) close_beacon(token);
2067
+ }
2068
+ function ensure_exit_cleanup() {
2069
+ if (exit_cleanup.is_registered) return;
2070
+ exit_cleanup.is_registered = true;
2071
+ process.once("exit", close_beacons);
2072
+ }
2073
+ function ignore_beacon_error() {
2074
+ }
2075
+ function bind_beacon(target) {
2076
+ return createServer().on("error", ignore_beacon_error).listen(target);
2077
+ }
2078
+ function try_bind_beacon(bind, target) {
2079
+ try {
2080
+ const server = bind(target);
2081
+ return server.listening ? server : void 0;
2082
+ } catch {
2083
+ return void 0;
2084
+ }
2085
+ }
2086
+ function open_beacon(bind = bind_beacon) {
2087
+ const target = path2.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
2088
+ const token = `${BEACON_SCHEME}${target}`;
2089
+ const server = try_bind_beacon(bind, target);
2090
+ if (server === void 0) return void 0;
2091
+ server.unref();
2092
+ beacons.set(token, server);
2093
+ ensure_exit_cleanup();
2094
+ return token;
2095
+ }
2096
+ function resolve_own_start(probes = START_PROBES, platform2 = process.platform) {
2097
+ const start = read_start(process.pid, probes);
2098
+ if (start !== void 0 || platform2 === WINDOWS_PLATFORM) return start;
2099
+ return open_beacon();
2100
+ }
2101
+ function is_valid_beacon_name(name) {
2102
+ if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
2103
+ const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
2104
+ return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
2105
+ }
2106
+ function beacon_target(token) {
2107
+ if (!token.startsWith(BEACON_SCHEME)) return void 0;
2108
+ const target = token.slice(BEACON_SCHEME.length);
2109
+ if (path2.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
2110
+ return is_valid_beacon_name(path2.basename(target)) ? target : void 0;
2111
+ }
2112
+ function is_live_beacon(target) {
2113
+ return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
2114
+ stdio: "ignore",
2115
+ timeout: PROBE_TIMEOUT_MS
2116
+ }).status === 0;
2117
+ }
2118
+ function has_matching_start(pid, recorded_start, read2) {
2119
+ const observed = read2(pid);
2120
+ return observed === void 0 ? void 0 : observed === recorded_start;
2121
+ }
2122
+ function matches_recorded_start(pid, recorded_start, read2) {
2123
+ const target = beacon_target(recorded_start);
2124
+ return target === void 0 ? has_matching_start(pid, recorded_start, read2) : is_live_beacon(target);
2125
+ }
2126
+ var own_probe = /* @__PURE__ */ new Map();
2127
+ function own_start() {
2128
+ if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
2129
+ return own_probe.get(process.pid);
2130
+ }
2131
+ function own_fields() {
2132
+ const start = own_start();
2133
+ return { pid: process.pid, ...start !== void 0 && { process_start: start } };
2134
+ }
2135
+ function is_same_process(pid, recorded_start, read2 = read_start) {
2136
+ if (pid === void 0 || !is_live_pid(pid)) return false;
2137
+ if (recorded_start === void 0) return void 0;
2138
+ return matches_recorded_start(pid, recorded_start, read2);
2139
+ }
2140
+ function is_own_process(pid, recorded_start) {
2141
+ return pid === process.pid && recorded_start === own_start();
2142
+ }
2143
+ var process_identity = {
2144
+ close_beacon,
2145
+ is_live_pid,
2146
+ is_own_process,
2147
+ is_same_process,
2148
+ open_beacon,
2149
+ own_fields,
2150
+ own_start,
2151
+ read_start,
2152
+ resolve_own_start
2153
+ };
2154
+
2155
+ // scripts/git/git-common-directory.ts
2156
+ import { execFileSync as execFileSync3 } from "node:child_process";
2157
+ var OWN_GIT_DIRECTORY = 0;
2158
+ var COMMON_GIT_DIRECTORY = 1;
2159
+ var PROBE_TIMEOUT_MS2 = 2e3;
2160
+ function read_directories(cwd) {
2161
+ const git = git_utilities.get_git_command_for_spawn();
2162
+ const output = execFileSync3(git, [...git_command.GIT_DIRECTORY_ARGUMENTS], {
2163
+ cwd,
2164
+ encoding: "utf8",
2165
+ stdio: ["ignore", "pipe", "ignore"],
2166
+ timeout: PROBE_TIMEOUT_MS2
2167
+ });
2168
+ return output.trim().split("\n");
2169
+ }
2170
+ function select_linked(directories) {
2171
+ const own = directories[OWN_GIT_DIRECTORY];
2172
+ const common = directories[COMMON_GIT_DIRECTORY];
2173
+ return own !== void 0 && common !== void 0 && own !== common ? common : void 0;
2174
+ }
2175
+ function resolve2(cwd) {
2176
+ try {
2177
+ return select_linked(read_directories(cwd));
2178
+ } catch {
2179
+ return void 0;
2180
+ }
2181
+ }
2182
+ function repository(cwd) {
2183
+ try {
2184
+ return read_directories(cwd)[COMMON_GIT_DIRECTORY];
2185
+ } catch {
2186
+ return void 0;
2187
+ }
2188
+ }
2189
+ var git_common_directory = { repository, resolve: resolve2, select_linked };
2190
+
2191
+ // scripts/git/repository-lock.ts
2192
+ var POLL_INTERVAL_MS = 200;
2193
+ function lock_path(prefix, cwd = process.cwd()) {
2194
+ return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd);
2195
+ }
2196
+ function parse_owner(raw) {
2197
+ if (raw === void 0) return void 0;
2198
+ try {
2199
+ return JSON.parse(raw);
2200
+ } catch {
2201
+ return void 0;
2202
+ }
2203
+ }
2204
+ function read_owner(target) {
2205
+ return parse_owner(stamp_file.read_stamp_text(target));
2206
+ }
2207
+ function is_owner_gone(owner) {
2208
+ return process_identity.is_same_process(owner.pid, owner.process_start) === false;
2209
+ }
2210
+ function restore(aside, target) {
2211
+ try {
2212
+ linkSync(aside, target);
2213
+ } catch {
2214
+ }
2215
+ }
2216
+ function stale_record(target, is_gone2) {
2217
+ const raw = stamp_file.read_stamp_text(target);
2218
+ const owner = parse_owner(raw);
2219
+ return owner !== void 0 && is_gone2(owner) ? raw : void 0;
2220
+ }
2221
+ function move_aside(target) {
2222
+ const aside = `${target}.${String(process.pid)}.${randomUUID2()}`;
2223
+ try {
2224
+ renameSync(target, aside);
2225
+ return aside;
2226
+ } catch {
2227
+ return void 0;
2228
+ }
2229
+ }
2230
+ function clear_stale(target, is_gone2 = is_owner_gone) {
2231
+ const raw = stale_record(target, is_gone2);
2232
+ if (raw === void 0) return;
2233
+ const aside = move_aside(target);
2234
+ if (aside === void 0) return;
2235
+ if (stamp_file.read_stamp_text(aside) !== raw) restore(aside, target);
2236
+ rmSync2(aside, { force: true });
2237
+ }
2238
+ function claim(target) {
2239
+ clear_stale(target);
2240
+ return stamp_file.create_stamp(target, process_identity.own_fields());
2241
+ }
2242
+ function release(target) {
2243
+ const owner = read_owner(target);
2244
+ if (owner !== void 0 && process_identity.is_own_process(owner.pid, owner.process_start)) {
2245
+ stamp_file.remove_stamp(target);
2246
+ }
2247
+ }
2248
+ async function acquire(target, max_wait_ms) {
2249
+ const deadline = Date.now() + max_wait_ms;
2250
+ while (!claim(target)) {
2251
+ if (Date.now() >= deadline) return false;
2252
+ await sleep(POLL_INTERVAL_MS);
2253
+ }
2254
+ return true;
2255
+ }
2256
+ async function with_lock(work, target, max_wait_ms) {
2257
+ if (!await acquire(target, max_wait_ms)) return void 0;
2258
+ try {
2259
+ return await work();
2260
+ } finally {
2261
+ release(target);
2262
+ }
2263
+ }
2264
+ var repository_lock = { clear_stale, lock_path, with_lock };
2265
+
1921
2266
  // scripts/git/git-worktree.ts
1922
2267
  var WORKTREE = "worktree";
2268
+ var WORKTREE_LOCK_PREFIX = "josh-worktree-lock-";
2269
+ var WORKTREE_LOCK_MAX_WAIT_MS = 12e4;
2270
+ async function locked(arguments_) {
2271
+ const target = repository_lock.lock_path(WORKTREE_LOCK_PREFIX);
2272
+ const output = await repository_lock.with_lock(
2273
+ async () => await git_spawn.read(arguments_),
2274
+ target,
2275
+ WORKTREE_LOCK_MAX_WAIT_MS
2276
+ );
2277
+ if (output === void 0) {
2278
+ throw new Error(
2279
+ `git ${arguments_.join(" ")}: timed out waiting for the work-tree lock ${target}`
2280
+ );
2281
+ }
2282
+ return output;
2283
+ }
1923
2284
  async function worktree_list() {
1924
2285
  return await git_spawn.read([WORKTREE, "list", PORCELAIN_FLAG]);
1925
2286
  }
1926
2287
  async function worktree_add(directory, branch_name, start_point) {
1927
2288
  const flags = start_point === void 0 ? ["add"] : ["add", "--no-track", "-b", branch_name];
1928
- return await git_spawn.read([WORKTREE, ...flags, directory, start_point ?? branch_name]);
2289
+ return await locked([WORKTREE, ...flags, directory, start_point ?? branch_name]);
1929
2290
  }
1930
2291
  async function worktree_add_detached(directory, commit2) {
1931
- return await git_spawn.read([WORKTREE, "add", "--detach", directory, commit2]);
2292
+ return await locked([WORKTREE, "add", "--detach", directory, commit2]);
1932
2293
  }
1933
2294
  async function worktree_remove(directory) {
1934
- return await git_spawn.read([WORKTREE, "remove", "--force", directory]);
2295
+ return await locked([WORKTREE, "remove", "--force", directory]);
1935
2296
  }
1936
2297
  async function worktree_prune() {
1937
- return await git_spawn.read([WORKTREE, "prune"]);
2298
+ return await locked([WORKTREE, "prune"]);
1938
2299
  }
1939
2300
  async function ls_remote_branch(branch_name) {
1940
2301
  return await git_spawn.read(ls_remote_branch_arguments(branch_name));
@@ -2097,7 +2458,7 @@ function held_seat(content) {
2097
2458
  }
2098
2459
  function read_environment(directory) {
2099
2460
  try {
2100
- return readFileSync3(path2.join(directory, ENV_FILE_NAME), "utf8");
2461
+ return readFileSync4(path3.join(directory, ENV_FILE_NAME), "utf8");
2101
2462
  } catch {
2102
2463
  return void 0;
2103
2464
  }
@@ -2463,174 +2824,6 @@ var run_invocation = {
2463
2824
  rebuild
2464
2825
  };
2465
2826
 
2466
- // scripts/josh/process-identity.ts
2467
- import { execFileSync as execFileSync2, spawnSync } from "node:child_process";
2468
- import { randomUUID } from "node:crypto";
2469
- import { readFileSync as readFileSync4, rmSync } from "node:fs";
2470
- import { createServer } from "node:net";
2471
- import path3 from "node:path";
2472
- var PS_COMMAND = "/bin/ps";
2473
- var FORMAT_FLAG = "-o";
2474
- var START_TIME_FORMAT = "lstart=";
2475
- var PID_FLAG = "-p";
2476
- var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
2477
- var PROBE_TIMEOUT_MS = 2e3;
2478
- var LIVENESS_SIGNAL = 0;
2479
- var LOWEST_REAL_PID = 1;
2480
- var PROC_START_FIELD_INDEX = 19;
2481
- var BEACON_SCHEME = "socket:";
2482
- var BEACON_SUFFIX = ".sock";
2483
- var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
2484
- var BEACON_ID_LENGTH = 36;
2485
- var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
2486
- var WINDOWS_PLATFORM = "win32";
2487
- var SOCKET_PROBE_SOURCE = "const net=require('node:net');const socket=net.createConnection(process.argv[1]);socket.once('connect',()=>process.exit(0));socket.once('error',()=>process.exit(1));socket.setTimeout(1000,()=>process.exit(1));";
2488
- var beacons = /* @__PURE__ */ new Map();
2489
- var exit_cleanup = { is_registered: false };
2490
- function is_live_pid(pid) {
2491
- if (pid < LOWEST_REAL_PID) return false;
2492
- try {
2493
- process.kill(pid, LIVENESS_SIGNAL);
2494
- return true;
2495
- } catch {
2496
- return false;
2497
- }
2498
- }
2499
- function read_proc_start(pid) {
2500
- try {
2501
- const stat = readFileSync4(`/proc/${String(pid)}/stat`, "utf8");
2502
- const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
2503
- const start = fields[PROC_START_FIELD_INDEX];
2504
- return start === void 0 ? void 0 : `proc:${start}`;
2505
- } catch {
2506
- return void 0;
2507
- }
2508
- }
2509
- function read_ps_start(pid) {
2510
- try {
2511
- const printed = execFileSync2(
2512
- PS_COMMAND,
2513
- [FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
2514
- {
2515
- encoding: "utf8",
2516
- timeout: PROBE_TIMEOUT_MS,
2517
- stdio: ["ignore", "pipe", "ignore"],
2518
- env: PROBE_ENVIRONMENT
2519
- }
2520
- ).trim();
2521
- return printed.length > 0 ? printed : void 0;
2522
- } catch {
2523
- return void 0;
2524
- }
2525
- }
2526
- var START_PROBES = { read_proc_start, read_ps_start };
2527
- function safe_probe(probe, pid) {
2528
- try {
2529
- return probe(pid);
2530
- } catch {
2531
- return void 0;
2532
- }
2533
- }
2534
- function read_start(pid, probes = START_PROBES) {
2535
- return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
2536
- }
2537
- function close_beacon(token) {
2538
- const server = beacons.get(token);
2539
- if (server === void 0) return;
2540
- beacons.delete(token);
2541
- server.close();
2542
- rmSync(token.slice(BEACON_SCHEME.length), { force: true });
2543
- }
2544
- function close_beacons() {
2545
- for (const token of beacons.keys()) close_beacon(token);
2546
- }
2547
- function ensure_exit_cleanup() {
2548
- if (exit_cleanup.is_registered) return;
2549
- exit_cleanup.is_registered = true;
2550
- process.once("exit", close_beacons);
2551
- }
2552
- function ignore_beacon_error() {
2553
- }
2554
- function bind_beacon(target) {
2555
- return createServer().on("error", ignore_beacon_error).listen(target);
2556
- }
2557
- function try_bind_beacon(bind, target) {
2558
- try {
2559
- const server = bind(target);
2560
- return server.listening ? server : void 0;
2561
- } catch {
2562
- return void 0;
2563
- }
2564
- }
2565
- function open_beacon(bind = bind_beacon) {
2566
- const target = path3.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
2567
- const token = `${BEACON_SCHEME}${target}`;
2568
- const server = try_bind_beacon(bind, target);
2569
- if (server === void 0) return void 0;
2570
- server.unref();
2571
- beacons.set(token, server);
2572
- ensure_exit_cleanup();
2573
- return token;
2574
- }
2575
- function resolve_own_start(probes = START_PROBES, platform2 = process.platform) {
2576
- const start = read_start(process.pid, probes);
2577
- if (start !== void 0 || platform2 === WINDOWS_PLATFORM) return start;
2578
- return open_beacon();
2579
- }
2580
- function is_valid_beacon_name(name) {
2581
- if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
2582
- const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
2583
- return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
2584
- }
2585
- function beacon_target(token) {
2586
- if (!token.startsWith(BEACON_SCHEME)) return void 0;
2587
- const target = token.slice(BEACON_SCHEME.length);
2588
- if (path3.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
2589
- return is_valid_beacon_name(path3.basename(target)) ? target : void 0;
2590
- }
2591
- function is_live_beacon(target) {
2592
- return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
2593
- stdio: "ignore",
2594
- timeout: PROBE_TIMEOUT_MS
2595
- }).status === 0;
2596
- }
2597
- function has_matching_start(pid, recorded_start, read2) {
2598
- const observed = read2(pid);
2599
- return observed === void 0 ? void 0 : observed === recorded_start;
2600
- }
2601
- function matches_recorded_start(pid, recorded_start, read2) {
2602
- const target = beacon_target(recorded_start);
2603
- return target === void 0 ? has_matching_start(pid, recorded_start, read2) : is_live_beacon(target);
2604
- }
2605
- var own_probe = /* @__PURE__ */ new Map();
2606
- function own_start() {
2607
- if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
2608
- return own_probe.get(process.pid);
2609
- }
2610
- function own_fields() {
2611
- const start = own_start();
2612
- return { pid: process.pid, ...start !== void 0 && { process_start: start } };
2613
- }
2614
- function is_same_process(pid, recorded_start, read2 = read_start) {
2615
- if (pid === void 0 || !is_live_pid(pid)) return false;
2616
- if (recorded_start === void 0) return void 0;
2617
- return matches_recorded_start(pid, recorded_start, read2);
2618
- }
2619
- function is_own_process(pid, recorded_start) {
2620
- return pid === process.pid && recorded_start === own_start();
2621
- }
2622
- var process_identity = {
2623
- close_beacon,
2624
- is_live_pid,
2625
- is_own_process,
2626
- is_same_process,
2627
- open_beacon,
2628
- own_fields,
2629
- own_start,
2630
- read_start,
2631
- resolve_own_start
2632
- };
2633
-
2634
2827
  // scripts/run/run-carry.ts
2635
2828
  import { z as z5 } from "zod";
2636
2829
 
@@ -3404,8 +3597,8 @@ export {
3404
3597
  gh_failure,
3405
3598
  has_stderr_field,
3406
3599
  git_gh_exec,
3407
- lane_registry,
3408
3600
  process_identity,
3601
+ lane_registry,
3409
3602
  run_invocation,
3410
3603
  run_carry,
3411
3604
  run_watcher_guard
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  investigation_reads
3
- } from "./chunk-M4U4YNRE.js";
3
+ } from "./chunk-HJXQZ7V4.js";
4
4
  import {
5
5
  lane_guard_policy
6
- } from "./chunk-OM5VDM6F.js";
6
+ } from "./chunk-XSL4SRMA.js";
7
7
  import {
8
8
  hook_decision
9
- } from "./chunk-O3PEDF3M.js";
9
+ } from "./chunk-LDQDZYHX.js";
10
10
 
11
11
  // scripts/delegation/investigation-guard.ts
12
12
  import { text } from "node:stream/consumers";
@@ -3,7 +3,7 @@ import {
3
3
  stamp_file,
4
4
  time_density_hook,
5
5
  time_hook_transcript
6
- } from "./chunk-EYFJ74MJ.js";
6
+ } from "./chunk-BELI5XSS.js";
7
7
  import {
8
8
  josh_environment_file
9
9
  } from "./chunk-WPALEIRX.js";
@@ -35,31 +35,31 @@ import {
35
35
  run_watcher_guard,
36
36
  shell_segments,
37
37
  tail_commands
38
- } from "./chunk-3FWV6CFC.js";
38
+ } from "./chunk-IJPBTDTB.js";
39
39
  import {
40
40
  find_local_bin_upwards
41
41
  } from "./chunk-3V37IID6.js";
42
42
  import {
43
43
  batch_outcome
44
- } from "./chunk-V7RH56HU.js";
44
+ } from "./chunk-244WYOEO.js";
45
45
  import {
46
46
  investigation_refusal
47
- } from "./chunk-NKVLBB65.js";
47
+ } from "./chunk-KOCK5FXQ.js";
48
48
  import {
49
49
  duplicate_read_outcome
50
- } from "./chunk-IBFC25IX.js";
50
+ } from "./chunk-GNOITLRR.js";
51
51
  import {
52
52
  investigation_reads
53
- } from "./chunk-M4U4YNRE.js";
53
+ } from "./chunk-HJXQZ7V4.js";
54
54
  import {
55
55
  lane_guard_policy,
56
56
  time_batch_guard
57
- } from "./chunk-OM5VDM6F.js";
57
+ } from "./chunk-XSL4SRMA.js";
58
58
  import {
59
59
  hook_decision,
60
60
  lane_child_marker,
61
61
  run_issue_number
62
- } from "./chunk-O3PEDF3M.js";
62
+ } from "./chunk-LDQDZYHX.js";
63
63
  import {
64
64
  PLATFORM_TEMP_ROOT,
65
65
  cost_attribute,
@@ -71,7 +71,7 @@ import {
71
71
  stamp_file,
72
72
  time_density_hook,
73
73
  time_shell
74
- } from "./chunk-EYFJ74MJ.js";
74
+ } from "./chunk-BELI5XSS.js";
75
75
 
76
76
  // scripts/hooks/pretool-guard.ts
77
77
  import { text } from "node:stream/consumers";