@joshuafolkken/kit 1.1035.0 → 1.1050.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/verify-ui/SKILL.md +1 -1
- package/.claude/skills/workflow-commands/SKILL.md +2 -2
- package/.claude/skills/workflow-commands/background-commands.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-child.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
- package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -36
- package/.claude/skills/workflow-commands/backlogrun-steps.md +16 -16
- package/.claude/skills/workflow-commands/chain-rule.md +2 -2
- package/.claude/skills/workflow-commands/followup-reference.md +2 -2
- package/.claude/skills/workflow-commands/issue-comments.md +1 -1
- package/.claude/skills/workflow-commands/observation-filing.md +41 -86
- package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
- package/.claude/skills/workflow-commands/working-tree-hold.md +2 -2
- package/.github/workflows/auto-tag.yml +21 -0
- package/.github/workflows/publish.yml +9 -10
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-HU66PWWL.js → chunk-5BK3K7V4.js} +89 -41
- package/dist/hooks/{chunk-GLBDBJOK.js → chunk-7VPDUBRN.js} +49 -151
- package/dist/hooks/{chunk-GJT4BNVE.js → chunk-DMQN45FN.js} +3 -3
- package/dist/hooks/{chunk-D67KVGGY.js → chunk-EJDX2TOB.js} +13 -3
- package/dist/hooks/{chunk-KG6PZD72.js → chunk-GQ7KP45M.js} +2 -2
- package/dist/hooks/{chunk-Y27M6A7X.js → chunk-HJIISEAC.js} +4 -4
- package/dist/hooks/{chunk-XPLP27WA.js → chunk-NAS4C7GP.js} +4 -26
- package/dist/hooks/{chunk-ZXNE6NY3.js → chunk-NJQOBE6L.js} +2 -2
- package/dist/hooks/{chunk-EIFCAJRB.js → chunk-RLDX5SOC.js} +1184 -946
- package/dist/hooks/{chunk-HOYJU5RM.js → chunk-WQ4OSBSS.js} +10 -3
- package/dist/hooks/codex-hook-adapter.js +10 -10
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +15 -34
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +23 -16
- package/dist/hooks/stop-guard.js +13 -188
- package/dist/josh.js +4 -106
- package/dist/version/index.js +381 -9
- package/package.json +6 -6
- package/prompts/collaboration-workflow/file-edits.md +6 -53
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +4 -35
- package/prompts/collaboration-workflow/shell-body.md +7 -9
- package/prompts/collaboration-workflow/turn-batching.md +21 -37
- package/prompts/collaboration-workflow/wip-cap.md +15 -18
- package/prompts/sonar-hotspot-handling.md +1 -1
- package/scripts/adopt/adopt-toolkits.ts +2 -0
- package/scripts/auto-ok/auto-ok-cli.ts +9 -9
- package/scripts/backlog/backlog-next.ts +24 -8
- package/scripts/backlog/backlog-plan-cli.ts +5 -1
- package/scripts/backlog/backlog-pool.ts +31 -11
- package/scripts/backlog/backlog-rank.ts +106 -0
- package/scripts/backlog/backlog-waves.ts +42 -29
- package/scripts/build/build-hooks.ts +7 -2
- package/scripts/delegation/delegation-policy.ts +11 -0
- package/scripts/document/document-byte-budget.ts +5 -5
- package/scripts/document/entry-read-budget.ts +5 -4
- package/scripts/epic/epic-lane-offer.ts +11 -22
- package/scripts/epic/epic-rank.ts +37 -0
- package/scripts/epic/epic-solo.ts +29 -28
- package/scripts/git/git-command.ts +1 -1
- package/scripts/git/git-execa-error.ts +6 -1
- package/scripts/git/git-next-issues.ts +34 -5
- package/scripts/git/git-preflight.ts +22 -4
- package/scripts/git/git-push-transport.ts +12 -69
- package/scripts/git/git-spawn.ts +79 -3
- package/scripts/git/git-ssh-keepalive.ts +74 -0
- package/scripts/git/gone-branch.ts +3 -2
- package/scripts/git/issue-labels.ts +12 -0
- package/scripts/git/issue-rank.ts +89 -0
- package/scripts/hooks/format-edited-cli.ts +15 -0
- package/scripts/hooks/format-edited-file.ts +2 -9
- package/scripts/hooks/pretool-guard-cli.ts +21 -0
- package/scripts/hooks/pretool-guard.ts +14 -15
- package/scripts/init/start-exec.ts +7 -1
- package/scripts/init/start-plan.ts +18 -5
- package/scripts/init/start-setup-pr.ts +46 -19
- package/scripts/init/start-steps.ts +41 -9
- package/scripts/init/start.ts +40 -10
- package/scripts/issue/issue-cite.ts +19 -1
- package/scripts/josh/josh-command-map.ts +0 -102
- package/scripts/josh/josh-commands-development.ts +2 -2
- package/scripts/josh/josh-commands-project.ts +1 -1
- package/scripts/lane/lane-child-marker.ts +16 -2
- package/scripts/lane/lane-cli.ts +32 -14
- package/scripts/lane/lane-report.ts +10 -4
- package/scripts/propagate/propagate-plan.ts +185 -0
- package/scripts/propagate/propagate-run.ts +5 -1
- package/scripts/propagate/propagate-steps.ts +16 -1
- package/scripts/propagate/propagate-targets.ts +13 -2
- package/scripts/propagate/propagate.ts +60 -42
- package/scripts/registry-migration/migrate-logic.ts +1 -0
- package/scripts/release/github-release.ts +1 -1
- package/scripts/review/review-attest.ts +44 -0
- package/scripts/review/review-brief-cli.ts +49 -2
- package/scripts/review/review-brief.ts +46 -1
- package/scripts/review/review-stamps.ts +7 -0
- package/scripts/rules/implementation-cut.ts +1 -1
- package/scripts/rules/issue-fold.ts +1 -2
- package/scripts/rules/lane-carry-conflict.ts +1 -2
- package/scripts/rules/lane-park.ts +1 -2
- package/scripts/rules/pre-gate-cut.ts +2 -2
- package/scripts/run/run-headless.ts +22 -6
- package/scripts/run/run-parent-cut-hook.ts +144 -0
- package/scripts/run/run-progress-read.ts +2 -1
- package/scripts/run/run-progress.ts +21 -8
- package/scripts/run/run-ship-cli.ts +6 -74
- package/scripts/run/run-ship-preflight.ts +87 -0
- package/scripts/run/run-ship-review-steps.ts +5 -26
- package/scripts/run/run-ship-review.ts +9 -0
- package/scripts/run/run-ship-scoped.ts +44 -0
- package/scripts/run/run-ship-stage.ts +5 -1
- package/scripts/run/run-ship-steps.ts +105 -0
- package/scripts/run/run-ship.ts +2 -0
- package/scripts/run/run-wake-cli.ts +2 -2
- package/scripts/run/run-wake-describe.ts +19 -1
- package/scripts/run/run-watcher-hook.ts +1 -1
- package/scripts/time-runtime/time-bundle-call.ts +2 -2
- package/scripts/version/npm-registry.ts +97 -0
- package/scripts/version/version-commands.ts +5 -4
- package/scripts/version/version-remote.ts +26 -12
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
lane_child_marker,
|
|
3
3
|
run_issue_number
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WQ4OSBSS.js";
|
|
5
5
|
import {
|
|
6
6
|
PLATFORM_TEMP_ROOT,
|
|
7
7
|
cost_blocks,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
time_density_hook,
|
|
14
14
|
time_shell,
|
|
15
15
|
time_transcript_line
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-7VPDUBRN.js";
|
|
17
17
|
import {
|
|
18
18
|
ENV_FILE_NAME,
|
|
19
19
|
LANE_SEAT_KEY,
|
|
@@ -153,7 +153,7 @@ var git_utilities = {
|
|
|
153
153
|
};
|
|
154
154
|
|
|
155
155
|
// scripts/git/git-push-transport.ts
|
|
156
|
-
import { execa } from "execa";
|
|
156
|
+
import { execa as execa2 } from "execa";
|
|
157
157
|
|
|
158
158
|
// scripts/git/git-execa-error.ts
|
|
159
159
|
function get_exit_code(error) {
|
|
@@ -166,25 +166,20 @@ function has_timed_out(error) {
|
|
|
166
166
|
if (typeof error !== "object" || error === null || !("timedOut" in error)) return false;
|
|
167
167
|
return error.timedOut === true;
|
|
168
168
|
}
|
|
169
|
+
var TIMEOUT_EXIT_CODE = "timeout";
|
|
169
170
|
function create_spawn_error(command, exit_code) {
|
|
170
171
|
const exit_code_string = exit_code === void 0 ? "unknown" : String(exit_code);
|
|
171
172
|
const error_message = `git ${command} exited with code ${exit_code_string}`;
|
|
172
173
|
return new Error(error_message, { cause: { exit_code: exit_code_string } });
|
|
173
174
|
}
|
|
174
175
|
|
|
175
|
-
// scripts/git/git-
|
|
176
|
-
|
|
177
|
-
var PUSH_TIMEOUT_SECONDS = 120;
|
|
178
|
-
var PUSH_TIMEOUT_MS = PUSH_TIMEOUT_SECONDS * MS_PER_SECOND;
|
|
179
|
-
var PUSH_TIMEOUT_LABEL = `${String(PUSH_TIMEOUT_SECONDS)}s`;
|
|
180
|
-
var PUSH_TIMEOUT_MESSAGE = "git push timed out";
|
|
181
|
-
var PUSH_TIMEOUT_EXIT_CODE = "timeout";
|
|
176
|
+
// scripts/git/git-ssh-keepalive.ts
|
|
177
|
+
import { execa } from "execa";
|
|
182
178
|
var SSH_KEEPALIVE_OPTIONS = "-o ServerAliveInterval=15 -o ServerAliveCountMax=3";
|
|
183
179
|
var SSH_COMMAND_VARIABLE = "GIT_SSH_COMMAND";
|
|
184
180
|
var SSH_LEGACY_VARIABLE = "GIT_SSH";
|
|
185
181
|
var KEEPALIVE_SSH_COMMAND = `ssh ${SSH_KEEPALIVE_OPTIONS}`;
|
|
186
182
|
var SSH_COMMAND_CONFIG_KEY = "core.sshCommand";
|
|
187
|
-
var PUSH_SUBCOMMAND = "push";
|
|
188
183
|
function to_environment_value(name) {
|
|
189
184
|
return process.env[name]?.trim() ?? "";
|
|
190
185
|
}
|
|
@@ -202,19 +197,33 @@ async function has_configured_ssh_command() {
|
|
|
202
197
|
return false;
|
|
203
198
|
}
|
|
204
199
|
}
|
|
205
|
-
async function
|
|
200
|
+
async function to_environment() {
|
|
206
201
|
const should_keep_alive = !await has_configured_ssh_command();
|
|
202
|
+
return should_keep_alive ? { [SSH_COMMAND_VARIABLE]: KEEPALIVE_SSH_COMMAND } : {};
|
|
203
|
+
}
|
|
204
|
+
var git_ssh_keepalive = {
|
|
205
|
+
to_environment
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// scripts/git/git-push-transport.ts
|
|
209
|
+
var MS_PER_SECOND = 1e3;
|
|
210
|
+
var PUSH_TIMEOUT_SECONDS = 120;
|
|
211
|
+
var PUSH_TIMEOUT_MS = PUSH_TIMEOUT_SECONDS * MS_PER_SECOND;
|
|
212
|
+
var PUSH_TIMEOUT_LABEL = `${String(PUSH_TIMEOUT_SECONDS)}s`;
|
|
213
|
+
var PUSH_TIMEOUT_MESSAGE = "git push timed out";
|
|
214
|
+
var PUSH_SUBCOMMAND = "push";
|
|
215
|
+
async function to_push_options() {
|
|
207
216
|
return {
|
|
208
217
|
stdio: "inherit",
|
|
209
218
|
timeout: PUSH_TIMEOUT_MS,
|
|
210
|
-
env:
|
|
219
|
+
env: await git_ssh_keepalive.to_environment()
|
|
211
220
|
};
|
|
212
221
|
}
|
|
213
222
|
async function did_push_time_out(arguments_list) {
|
|
214
223
|
const git_command_bin = git_utilities.get_git_command_for_spawn();
|
|
215
224
|
const options = await to_push_options();
|
|
216
225
|
try {
|
|
217
|
-
await
|
|
226
|
+
await execa2(git_command_bin, [PUSH_SUBCOMMAND, ...arguments_list], options);
|
|
218
227
|
return false;
|
|
219
228
|
} catch (error) {
|
|
220
229
|
if (has_timed_out(error)) return true;
|
|
@@ -229,7 +238,7 @@ function to_retry_notice(arguments_list) {
|
|
|
229
238
|
}
|
|
230
239
|
function create_timeout_error(arguments_list) {
|
|
231
240
|
const message = `${PUSH_TIMEOUT_MESSAGE} twice (${PUSH_TIMEOUT_LABEL} each). Re-run it by hand: ${to_manual_command(arguments_list)}`;
|
|
232
|
-
return new Error(message, { cause: { exit_code:
|
|
241
|
+
return new Error(message, { cause: { exit_code: TIMEOUT_EXIT_CODE } });
|
|
233
242
|
}
|
|
234
243
|
async function push(arguments_list) {
|
|
235
244
|
if (!await did_push_time_out(arguments_list)) return;
|
|
@@ -242,23 +251,56 @@ var git_push_transport = {
|
|
|
242
251
|
};
|
|
243
252
|
|
|
244
253
|
// scripts/git/git-spawn.ts
|
|
245
|
-
import { execa as
|
|
254
|
+
import { execa as execa3 } from "execa";
|
|
246
255
|
async function read(arguments_) {
|
|
247
256
|
const git_cmd = git_utilities.get_git_command_for_spawn();
|
|
248
|
-
const { stdout } = await
|
|
257
|
+
const { stdout } = await execa3(git_cmd, arguments_);
|
|
249
258
|
return stdout.trimEnd();
|
|
250
259
|
}
|
|
260
|
+
var REMOTE_TIMEOUT_MS = PUSH_TIMEOUT_MS;
|
|
261
|
+
var MS_PER_SECOND2 = 1e3;
|
|
262
|
+
function to_remote_error(command, error, timeout_ms) {
|
|
263
|
+
if (!has_timed_out(error)) return create_spawn_error(command, get_exit_code(error));
|
|
264
|
+
const seconds = String(Math.round(timeout_ms / MS_PER_SECOND2));
|
|
265
|
+
return new Error(`git ${command} timed out after ${seconds}s`, {
|
|
266
|
+
cause: { exit_code: TIMEOUT_EXIT_CODE }
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
async function spawn_remote(arguments_, options) {
|
|
270
|
+
const git_cmd = git_utilities.get_git_command_for_spawn();
|
|
271
|
+
try {
|
|
272
|
+
const { stdout } = await execa3(git_cmd, arguments_, options);
|
|
273
|
+
return typeof stdout === "string" ? stdout.trimEnd() : "";
|
|
274
|
+
} catch (error) {
|
|
275
|
+
throw to_remote_error(arguments_[0] ?? "", error, options.timeout);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
async function read_remote(arguments_, timeout_ms = REMOTE_TIMEOUT_MS) {
|
|
279
|
+
return await spawn_remote(arguments_, {
|
|
280
|
+
timeout: timeout_ms,
|
|
281
|
+
env: await git_ssh_keepalive.to_environment()
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
async function with_output_remote(command, arguments_list) {
|
|
285
|
+
await spawn_remote([command, ...arguments_list], {
|
|
286
|
+
stdio: "inherit",
|
|
287
|
+
timeout: REMOTE_TIMEOUT_MS,
|
|
288
|
+
env: await git_ssh_keepalive.to_environment()
|
|
289
|
+
});
|
|
290
|
+
}
|
|
251
291
|
async function with_output(command, arguments_list) {
|
|
252
292
|
const git_command_bin = git_utilities.get_git_command_for_spawn();
|
|
253
293
|
try {
|
|
254
|
-
await
|
|
294
|
+
await execa3(git_command_bin, [command, ...arguments_list], { stdio: "inherit" });
|
|
255
295
|
} catch (error) {
|
|
256
296
|
throw create_spawn_error(command, get_exit_code(error));
|
|
257
297
|
}
|
|
258
298
|
}
|
|
259
299
|
var git_spawn = {
|
|
260
300
|
read,
|
|
261
|
-
|
|
301
|
+
read_remote,
|
|
302
|
+
with_output,
|
|
303
|
+
with_output_remote
|
|
262
304
|
};
|
|
263
305
|
|
|
264
306
|
// scripts/git/git-command.ts
|
|
@@ -433,7 +475,7 @@ async function push2() {
|
|
|
433
475
|
}
|
|
434
476
|
}
|
|
435
477
|
async function pull_fast_forward() {
|
|
436
|
-
await git_spawn.
|
|
478
|
+
await git_spawn.with_output_remote("pull", ["--ff-only"]);
|
|
437
479
|
}
|
|
438
480
|
var SHORT_NAME_FORMAT = "--format=%(refname:short)";
|
|
439
481
|
var REMOTES_FLAG = "--remotes";
|
|
@@ -840,18 +882,18 @@ function trimmed(value) {
|
|
|
840
882
|
const result = value?.trim();
|
|
841
883
|
return result === void 0 || result.length === EMPTY_LENGTH ? void 0 : result;
|
|
842
884
|
}
|
|
843
|
-
function override_value(role, field,
|
|
885
|
+
function override_value(role, field, environment2) {
|
|
844
886
|
const key = ENV_KEYS[role][field];
|
|
845
|
-
const value = trimmed(
|
|
887
|
+
const value = trimmed(environment2[key]);
|
|
846
888
|
if (value !== void 0) return { key, value };
|
|
847
889
|
if (role !== WORKER) return { key, value: void 0 };
|
|
848
890
|
const legacy = LEGACY_WORKER_KEYS[field];
|
|
849
|
-
const legacy_value = trimmed(
|
|
891
|
+
const legacy_value = trimmed(environment2[legacy]);
|
|
850
892
|
return legacy_value === void 0 ? { key, value: void 0 } : { key: legacy, value: legacy_value };
|
|
851
893
|
}
|
|
852
|
-
function model_override(role,
|
|
894
|
+
function model_override(role, environment2, provider) {
|
|
853
895
|
const key = ENV_KEYS[role].model;
|
|
854
|
-
return provider === OPENAI_PROVIDER ? { key, value: void 0 } : override_value(role, "model",
|
|
896
|
+
return provider === OPENAI_PROVIDER ? { key, value: void 0 } : override_value(role, "model", environment2);
|
|
855
897
|
}
|
|
856
898
|
function rejection(key, value, expected) {
|
|
857
899
|
return { kind: "rejected", note: `${key}=${value} ${expected}, so the agent was not started` };
|
|
@@ -860,35 +902,35 @@ function resolved_effort(override, fallback) {
|
|
|
860
902
|
const parsed = EFFORT_SCHEMA.safeParse(override.value ?? fallback);
|
|
861
903
|
return parsed.success ? { kind: "effort", effort: parsed.data } : rejection(override.key, override.value ?? "", "is not an allowed effort");
|
|
862
904
|
}
|
|
863
|
-
function has_session(
|
|
864
|
-
return keys.some((key) => trimmed(
|
|
905
|
+
function has_session(environment2, keys) {
|
|
906
|
+
return keys.some((key) => trimmed(environment2[key]) !== void 0);
|
|
865
907
|
}
|
|
866
908
|
function session_rejection(is_conflicting) {
|
|
867
909
|
const note = is_conflicting ? "both Codex and Claude Code sessions were detected" : "no Codex or Claude Code session was detected";
|
|
868
910
|
return { kind: "rejected", note };
|
|
869
911
|
}
|
|
870
912
|
var HANDED_PROVIDER_KEY = "JOSH_AGENT_PROVIDER";
|
|
871
|
-
function handed_provider(
|
|
872
|
-
const value = trimmed(
|
|
913
|
+
function handed_provider(environment2) {
|
|
914
|
+
const value = trimmed(environment2[HANDED_PROVIDER_KEY]);
|
|
873
915
|
if (value === void 0) return session_rejection(false);
|
|
874
916
|
const parsed = PROVIDER_SCHEMA.safeParse(value);
|
|
875
917
|
return parsed.success ? { kind: "provider", provider: parsed.data } : rejection(HANDED_PROVIDER_KEY, value, "is not an allowed provider");
|
|
876
918
|
}
|
|
877
|
-
function detected_provider(
|
|
878
|
-
const has_codex = has_session(
|
|
879
|
-
const has_claude = has_session(
|
|
919
|
+
function detected_provider(environment2) {
|
|
920
|
+
const has_codex = has_session(environment2, [CODEX_SESSION_KEY]);
|
|
921
|
+
const has_claude = has_session(environment2, agent_session_environment.PARENT_SESSION_KEYS);
|
|
880
922
|
if (has_codex === has_claude) return has_codex ? session_rejection(true) : void 0;
|
|
881
923
|
return { kind: "provider", provider: has_codex ? OPENAI_PROVIDER : ANTHROPIC_PROVIDER };
|
|
882
924
|
}
|
|
883
|
-
function resolve_provider(
|
|
884
|
-
return detected_provider(
|
|
925
|
+
function resolve_provider(environment2 = process.env) {
|
|
926
|
+
return detected_provider(environment2) ?? handed_provider(environment2);
|
|
885
927
|
}
|
|
886
|
-
function has_completion_callback(
|
|
887
|
-
const selected = resolve_provider(
|
|
928
|
+
function has_completion_callback(environment2 = process.env) {
|
|
929
|
+
const selected = resolve_provider(environment2);
|
|
888
930
|
return selected.kind !== "provider" || selected.provider !== OPENAI_PROVIDER;
|
|
889
931
|
}
|
|
890
|
-
function handoff_environment(
|
|
891
|
-
const selected = resolve_provider(
|
|
932
|
+
function handoff_environment(environment2 = process.env) {
|
|
933
|
+
const selected = resolve_provider(environment2);
|
|
892
934
|
return selected.kind === "provider" ? { [HANDED_PROVIDER_KEY]: selected.provider } : {};
|
|
893
935
|
}
|
|
894
936
|
function validate(profile, model_key) {
|
|
@@ -902,19 +944,19 @@ function phase_effort(role, phase, fallback) {
|
|
|
902
944
|
if (!parsed.success) return fallback;
|
|
903
945
|
return PHASE_EFFORT[role]?.[parsed.data] ?? fallback;
|
|
904
946
|
}
|
|
905
|
-
function overridden_effort(profile, phase,
|
|
906
|
-
const parsed = EFFORT_SCHEMA.safeParse(override_value(profile.role, "effort",
|
|
947
|
+
function overridden_effort(profile, phase, environment2) {
|
|
948
|
+
const parsed = EFFORT_SCHEMA.safeParse(override_value(profile.role, "effort", environment2).value);
|
|
907
949
|
return parsed.success ? parsed.data : phase_effort(profile.role, phase, profile.effort);
|
|
908
950
|
}
|
|
909
|
-
function with_phase_effort(profile, phase,
|
|
910
|
-
return { ...profile, effort: overridden_effort(profile, phase,
|
|
951
|
+
function with_phase_effort(profile, phase, environment2 = process.env) {
|
|
952
|
+
return { ...profile, effort: overridden_effort(profile, phase, environment2) };
|
|
911
953
|
}
|
|
912
|
-
function resolve(role,
|
|
913
|
-
const selected = resolve_provider(
|
|
954
|
+
function resolve(role, environment2 = process.env, phase) {
|
|
955
|
+
const selected = resolve_provider(environment2);
|
|
914
956
|
if (selected.kind === "rejected") return selected;
|
|
915
957
|
const defaults = PROVIDER_PROFILES[selected.provider][role];
|
|
916
|
-
const model = model_override(role,
|
|
917
|
-
const effort = override_value(role, "effort",
|
|
958
|
+
const model = model_override(role, environment2, selected.provider);
|
|
959
|
+
const effort = override_value(role, "effort", environment2);
|
|
918
960
|
const resolved = resolved_effort(effort, phase_effort(role, phase, defaults.effort));
|
|
919
961
|
if (resolved.kind === "rejected") return resolved;
|
|
920
962
|
const profile = {
|
|
@@ -1312,10 +1354,10 @@ function load_handoff(handoff_path, max_bytes) {
|
|
|
1312
1354
|
}
|
|
1313
1355
|
return { kind: "ok", handoff };
|
|
1314
1356
|
}
|
|
1315
|
-
function describe_list(
|
|
1316
|
-
if (items.length === 0) return `${
|
|
1357
|
+
function describe_list(label2, items) {
|
|
1358
|
+
if (items.length === 0) return `${label2}: ${EMPTY_LIST_NOTE}`;
|
|
1317
1359
|
const bullets = items.map((item) => ` - ${item}`).join("\n");
|
|
1318
|
-
return `${
|
|
1360
|
+
return `${label2}:
|
|
1319
1361
|
${bullets}`;
|
|
1320
1362
|
}
|
|
1321
1363
|
function describe_handoff(handoff) {
|
|
@@ -1671,6 +1713,7 @@ var IN_PROGRESS_LABEL = "in-progress";
|
|
|
1671
1713
|
var NEEDS_DECISION_LABEL = "needs-decision";
|
|
1672
1714
|
var RUN_SOLO_LABEL = "run:solo";
|
|
1673
1715
|
var RUN_LANE_LABEL = "run:lane";
|
|
1716
|
+
var PRIORITY_HIGH_LABEL = "priority:high";
|
|
1674
1717
|
var NEEDS_HUMAN_REVIEW_LABEL = "needs-human-review";
|
|
1675
1718
|
var ALREADY_DONE_LABEL = "already-done";
|
|
1676
1719
|
var INTERRUPT_ROUTE_LABEL = "route:interrupt";
|
|
@@ -1740,6 +1783,11 @@ var WORKFLOW_LABELS = [
|
|
|
1740
1783
|
color: "0e8a16",
|
|
1741
1784
|
description: "Judged safe to run beside others in a backlogrun"
|
|
1742
1785
|
},
|
|
1786
|
+
{
|
|
1787
|
+
name: PRIORITY_HIGH_LABEL,
|
|
1788
|
+
color: "e99695",
|
|
1789
|
+
description: "Offered first in a backlogrun; only a person removes it"
|
|
1790
|
+
},
|
|
1743
1791
|
...FILING_ROUTE_LABELS,
|
|
1744
1792
|
...DEPTH_LABELS
|
|
1745
1793
|
];
|
|
@@ -1766,11 +1814,11 @@ var REPOSITORY_LABELS = [
|
|
|
1766
1814
|
...RELEASE_CLASSIFICATION_LABELS
|
|
1767
1815
|
];
|
|
1768
1816
|
function has_any_label(labels, wanted) {
|
|
1769
|
-
return (labels ?? []).some((
|
|
1817
|
+
return (labels ?? []).some((label2) => wanted.has(label2.name.toLowerCase()));
|
|
1770
1818
|
}
|
|
1771
1819
|
function label_name_of(labels, wanted) {
|
|
1772
1820
|
const target = wanted.toLowerCase();
|
|
1773
|
-
return labels.find((
|
|
1821
|
+
return labels.find((label2) => label2.toLowerCase() === target);
|
|
1774
1822
|
}
|
|
1775
1823
|
function has_label_name(labels, wanted) {
|
|
1776
1824
|
return label_name_of(labels, wanted) !== void 0;
|
|
@@ -2003,14 +2051,14 @@ function main_worktree(repository_path) {
|
|
|
2003
2051
|
if (path.basename(git_directory) !== GIT_DIRECTORY) return repository_path;
|
|
2004
2052
|
return path.dirname(git_directory);
|
|
2005
2053
|
}
|
|
2006
|
-
function discover_repositories(repository_path,
|
|
2054
|
+
function discover_repositories(repository_path, environment2 = process.env) {
|
|
2007
2055
|
const main2 = main_worktree(repository_path);
|
|
2008
2056
|
const current_owner2 = resolve_current_owner(main2);
|
|
2009
2057
|
if (current_owner2 === void 0) return /* @__PURE__ */ new Map();
|
|
2010
2058
|
return repo_map_logic.build_repository_map(
|
|
2011
2059
|
scan_siblings(path.dirname(main2)),
|
|
2012
2060
|
current_owner2,
|
|
2013
|
-
|
|
2061
|
+
environment2[OVERRIDE_ENV_KEY]
|
|
2014
2062
|
);
|
|
2015
2063
|
}
|
|
2016
2064
|
var repo_discovery = {
|
|
@@ -2038,36 +2086,97 @@ function current_owner(repository_path = process.cwd()) {
|
|
|
2038
2086
|
}
|
|
2039
2087
|
var repo_party = { FIRST_PARTY, THIRD_PARTY, UNKNOWN, classify: classify3, current_owner, target_owner };
|
|
2040
2088
|
|
|
2041
|
-
// scripts/lane/lane-
|
|
2042
|
-
import {
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
var
|
|
2047
|
-
var
|
|
2048
|
-
var
|
|
2049
|
-
var
|
|
2050
|
-
|
|
2051
|
-
|
|
2089
|
+
// scripts/lane/lane-reap.ts
|
|
2090
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
2091
|
+
var PGREP_COMMAND = "pgrep";
|
|
2092
|
+
var MATCH_FULL_COMMAND_LINE = "-f";
|
|
2093
|
+
var CHILDREN_OF_FLAG = "-P";
|
|
2094
|
+
var PS_COMMAND = "/bin/ps";
|
|
2095
|
+
var PARENT_FORMAT = ["-o", "ppid=", "-p"];
|
|
2096
|
+
var TERMINATE_SIGNAL = "SIGTERM";
|
|
2097
|
+
var PROBE_TIMEOUT_MS = 2e3;
|
|
2098
|
+
var LOWEST_CHILD_PID = 2;
|
|
2099
|
+
function parse_pids(printed) {
|
|
2100
|
+
return printed.split("\n").map((line) => Number(line.trim())).filter((pid) => Number.isSafeInteger(pid) && pid >= LOWEST_CHILD_PID);
|
|
2052
2101
|
}
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2102
|
+
function run_probe(command, args) {
|
|
2103
|
+
try {
|
|
2104
|
+
return execFileSync2(command, [...args], {
|
|
2105
|
+
encoding: "utf8",
|
|
2106
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
2107
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2108
|
+
});
|
|
2109
|
+
} catch {
|
|
2110
|
+
return "";
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
function parent_of(pid) {
|
|
2114
|
+
return parse_pids(run_probe(PS_COMMAND, [...PARENT_FORMAT, String(pid)]))[0];
|
|
2115
|
+
}
|
|
2116
|
+
function terminate(pid) {
|
|
2117
|
+
try {
|
|
2118
|
+
process.kill(pid, TERMINATE_SIGNAL);
|
|
2119
|
+
return true;
|
|
2120
|
+
} catch {
|
|
2121
|
+
return false;
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
var SYSTEM_PROBES = {
|
|
2125
|
+
matching: (pattern) => parse_pids(run_probe(PGREP_COMMAND, [MATCH_FULL_COMMAND_LINE, pattern])),
|
|
2126
|
+
children_of: (pid) => parse_pids(run_probe(PGREP_COMMAND, [CHILDREN_OF_FLAG, String(pid)])),
|
|
2127
|
+
parent_of,
|
|
2128
|
+
terminate
|
|
2129
|
+
};
|
|
2130
|
+
function ancestry_of(pid, probes) {
|
|
2131
|
+
const ancestry = /* @__PURE__ */ new Set([pid]);
|
|
2132
|
+
let current = probes.parent_of(pid);
|
|
2133
|
+
while (current !== void 0 && !ancestry.has(current)) {
|
|
2134
|
+
ancestry.add(current);
|
|
2135
|
+
current = probes.parent_of(current);
|
|
2136
|
+
}
|
|
2137
|
+
return ancestry;
|
|
2138
|
+
}
|
|
2139
|
+
function own_ancestry(probes = SYSTEM_PROBES) {
|
|
2140
|
+
return ancestry_of(process.pid, probes);
|
|
2141
|
+
}
|
|
2142
|
+
function tree_of(roots, probes) {
|
|
2143
|
+
const tree = [];
|
|
2144
|
+
const pending = [...roots];
|
|
2145
|
+
let next = pending.shift();
|
|
2146
|
+
while (next !== void 0) {
|
|
2147
|
+
if (!tree.includes(next)) {
|
|
2148
|
+
tree.push(next);
|
|
2149
|
+
pending.push(...probes.children_of(next));
|
|
2150
|
+
}
|
|
2151
|
+
next = pending.shift();
|
|
2152
|
+
}
|
|
2153
|
+
return tree;
|
|
2154
|
+
}
|
|
2155
|
+
function reap_child(issue, probes = SYSTEM_PROBES) {
|
|
2156
|
+
const own = own_ancestry(probes);
|
|
2157
|
+
const pattern = lane_child_invocation.process_pattern(issue);
|
|
2158
|
+
const roots = probes.matching(pattern).filter((pid) => !own.has(pid));
|
|
2159
|
+
const doomed = tree_of(roots, probes).filter((pid) => !own.has(pid));
|
|
2160
|
+
return doomed.filter((pid) => probes.terminate(pid));
|
|
2161
|
+
}
|
|
2162
|
+
var lane_reap = {
|
|
2163
|
+
own_ancestry,
|
|
2164
|
+
parse_pids,
|
|
2165
|
+
reap_child
|
|
2166
|
+
};
|
|
2058
2167
|
|
|
2059
2168
|
// scripts/josh/process-identity.ts
|
|
2060
|
-
import { execFileSync as
|
|
2169
|
+
import { execFileSync as execFileSync3, spawnSync } from "node:child_process";
|
|
2061
2170
|
import { randomUUID } from "node:crypto";
|
|
2062
2171
|
import { readFileSync as readFileSync3, rmSync } from "node:fs";
|
|
2063
2172
|
import { createServer } from "node:net";
|
|
2064
2173
|
import path2 from "node:path";
|
|
2065
|
-
var
|
|
2174
|
+
var PS_COMMAND2 = "/bin/ps";
|
|
2066
2175
|
var FORMAT_FLAG = "-o";
|
|
2067
2176
|
var START_TIME_FORMAT = "lstart=";
|
|
2068
2177
|
var PID_FLAG = "-p";
|
|
2069
2178
|
var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
|
|
2070
|
-
var
|
|
2179
|
+
var PROBE_TIMEOUT_MS2 = 2e3;
|
|
2071
2180
|
var LIVENESS_SIGNAL = 0;
|
|
2072
2181
|
var LOWEST_REAL_PID = 1;
|
|
2073
2182
|
var PROC_START_FIELD_INDEX = 19;
|
|
@@ -2101,12 +2210,12 @@ function read_proc_start(pid) {
|
|
|
2101
2210
|
}
|
|
2102
2211
|
function read_ps_start(pid) {
|
|
2103
2212
|
try {
|
|
2104
|
-
const printed =
|
|
2105
|
-
|
|
2213
|
+
const printed = execFileSync3(
|
|
2214
|
+
PS_COMMAND2,
|
|
2106
2215
|
[FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
|
|
2107
2216
|
{
|
|
2108
2217
|
encoding: "utf8",
|
|
2109
|
-
timeout:
|
|
2218
|
+
timeout: PROBE_TIMEOUT_MS2,
|
|
2110
2219
|
stdio: ["ignore", "pipe", "ignore"],
|
|
2111
2220
|
env: PROBE_ENVIRONMENT
|
|
2112
2221
|
}
|
|
@@ -2184,7 +2293,7 @@ function beacon_target(token) {
|
|
|
2184
2293
|
function is_live_beacon(target) {
|
|
2185
2294
|
return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
|
|
2186
2295
|
stdio: "ignore",
|
|
2187
|
-
timeout:
|
|
2296
|
+
timeout: PROBE_TIMEOUT_MS2
|
|
2188
2297
|
}).status === 0;
|
|
2189
2298
|
}
|
|
2190
2299
|
function has_matching_start(pid, recorded_start, read2) {
|
|
@@ -2224,984 +2333,1002 @@ var process_identity = {
|
|
|
2224
2333
|
resolve_own_start
|
|
2225
2334
|
};
|
|
2226
2335
|
|
|
2227
|
-
// scripts/
|
|
2228
|
-
import {
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
var
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
cwd,
|
|
2236
|
-
encoding: "utf8",
|
|
2237
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
2238
|
-
timeout: PROBE_TIMEOUT_MS2
|
|
2239
|
-
});
|
|
2240
|
-
return output.trim().split("\n");
|
|
2336
|
+
// scripts/run/run-carry.ts
|
|
2337
|
+
import { z as z5 } from "zod";
|
|
2338
|
+
|
|
2339
|
+
// scripts/run/run-carry-streak.ts
|
|
2340
|
+
var NO_INCREMENT = 0;
|
|
2341
|
+
var OUTAGE_FOLD_WINDOW_MS = 12e4;
|
|
2342
|
+
function has_increment(value) {
|
|
2343
|
+
return (value ?? NO_INCREMENT) > NO_INCREMENT;
|
|
2241
2344
|
}
|
|
2242
|
-
function
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
return own !== void 0 && common !== void 0 && own !== common ? common : void 0;
|
|
2345
|
+
function next_failures(carry, change) {
|
|
2346
|
+
if (has_increment(change.merged)) return NO_INCREMENT;
|
|
2347
|
+
return carry.failures + (change.failures ?? NO_INCREMENT);
|
|
2246
2348
|
}
|
|
2247
|
-
function
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
}
|
|
2349
|
+
function is_within_fold_window(last_outage_at, now) {
|
|
2350
|
+
if (last_outage_at === void 0) return false;
|
|
2351
|
+
const last = Date.parse(last_outage_at);
|
|
2352
|
+
if (Number.isNaN(last)) return false;
|
|
2353
|
+
return now.getTime() - last <= OUTAGE_FOLD_WINDOW_MS;
|
|
2253
2354
|
}
|
|
2254
|
-
function
|
|
2255
|
-
|
|
2256
|
-
return read_directories(cwd)[COMMON_GIT_DIRECTORY];
|
|
2257
|
-
} catch {
|
|
2258
|
-
return void 0;
|
|
2259
|
-
}
|
|
2355
|
+
function folded_outage(carry) {
|
|
2356
|
+
return { outages: carry.outages, last_outage_at: carry.last_outage_at };
|
|
2260
2357
|
}
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
var POLL_INTERVAL_MS = 200;
|
|
2265
|
-
function lock_path(prefix, cwd = process.cwd()) {
|
|
2266
|
-
return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd);
|
|
2358
|
+
function counted_outage(carry, change, now) {
|
|
2359
|
+
const outages = carry.outages + (change.outages ?? NO_INCREMENT);
|
|
2360
|
+
return { outages, last_outage_at: now.toISOString() };
|
|
2267
2361
|
}
|
|
2268
|
-
function
|
|
2269
|
-
if (
|
|
2270
|
-
|
|
2271
|
-
return JSON.parse(raw);
|
|
2272
|
-
} catch {
|
|
2273
|
-
return void 0;
|
|
2362
|
+
function next_outage(carry, change, now) {
|
|
2363
|
+
if (has_increment(change.outages)) {
|
|
2364
|
+
return is_within_fold_window(carry.last_outage_at, now) ? folded_outage(carry) : counted_outage(carry, change, now);
|
|
2274
2365
|
}
|
|
2366
|
+
const is_reachable = has_increment(change.merged) || has_increment(change.failures);
|
|
2367
|
+
return is_reachable ? { outages: NO_INCREMENT, last_outage_at: void 0 } : folded_outage(carry);
|
|
2275
2368
|
}
|
|
2276
|
-
function
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
try {
|
|
2284
|
-
linkSync(aside, target);
|
|
2285
|
-
} catch {
|
|
2286
|
-
}
|
|
2369
|
+
function next_state(carry, change, now) {
|
|
2370
|
+
const outage = next_outage(carry, change, now);
|
|
2371
|
+
return {
|
|
2372
|
+
failures: next_failures(carry, change),
|
|
2373
|
+
outages: outage.outages,
|
|
2374
|
+
last_outage_at: outage.last_outage_at
|
|
2375
|
+
};
|
|
2287
2376
|
}
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2377
|
+
var run_carry_streak = { OUTAGE_FOLD_WINDOW_MS, next_state };
|
|
2378
|
+
|
|
2379
|
+
// scripts/run/run-carry-change.ts
|
|
2380
|
+
var NO_INCREMENT2 = 0;
|
|
2381
|
+
function next_done(carry, done) {
|
|
2382
|
+
if (done === void 0) return carry.done;
|
|
2383
|
+
const current = carry.done ?? [];
|
|
2384
|
+
return current.includes(done) ? current : [...current, done];
|
|
2292
2385
|
}
|
|
2293
|
-
function
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
renameSync(target, aside);
|
|
2297
|
-
return aside;
|
|
2298
|
-
} catch {
|
|
2299
|
-
return void 0;
|
|
2300
|
-
}
|
|
2386
|
+
function next_merged_issues(carry, issue) {
|
|
2387
|
+
if (issue === void 0) return carry.merged_issues;
|
|
2388
|
+
return [...carry.merged_issues ?? [], issue];
|
|
2301
2389
|
}
|
|
2302
|
-
function
|
|
2303
|
-
const
|
|
2304
|
-
|
|
2305
|
-
const aside = move_aside(target);
|
|
2306
|
-
if (aside === void 0) return;
|
|
2307
|
-
if (stamp_file.read_stamp_text(aside) !== raw) restore(aside, target);
|
|
2308
|
-
rmSync2(aside, { force: true });
|
|
2390
|
+
function is_duplicate_merge(carry, change) {
|
|
2391
|
+
const issue = change.merged_issue;
|
|
2392
|
+
return issue !== void 0 && carry.merged_issues?.includes(issue) === true;
|
|
2309
2393
|
}
|
|
2310
|
-
function
|
|
2311
|
-
|
|
2312
|
-
return
|
|
2394
|
+
function next_counts(carry, change) {
|
|
2395
|
+
const cuts = change.cuts ?? NO_INCREMENT2;
|
|
2396
|
+
return {
|
|
2397
|
+
merged: carry.merged + (change.merged ?? NO_INCREMENT2),
|
|
2398
|
+
filed: carry.filed + (change.filed ?? NO_INCREMENT2),
|
|
2399
|
+
cuts: carry.cuts + cuts,
|
|
2400
|
+
is_handed_off: cuts > NO_INCREMENT2
|
|
2401
|
+
};
|
|
2313
2402
|
}
|
|
2314
|
-
function
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2403
|
+
function apply_change(target, carry, change, now = /* @__PURE__ */ new Date()) {
|
|
2404
|
+
if (is_duplicate_merge(carry, change)) return carry;
|
|
2405
|
+
const streak = run_carry_streak.next_state(carry, change, now);
|
|
2406
|
+
const next = {
|
|
2407
|
+
...carry,
|
|
2408
|
+
...next_counts(carry, change),
|
|
2409
|
+
merged_issues: next_merged_issues(carry, change.merged_issue),
|
|
2410
|
+
failures: streak.failures,
|
|
2411
|
+
outages: streak.outages,
|
|
2412
|
+
last_outage_at: streak.last_outage_at,
|
|
2413
|
+
done: next_done(carry, change.done),
|
|
2414
|
+
retrospective: change.retrospective === true || carry.retrospective
|
|
2415
|
+
};
|
|
2416
|
+
stamp_file.write_stamp(target, next);
|
|
2417
|
+
return next;
|
|
2319
2418
|
}
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2419
|
+
var run_carry_change = { apply_change };
|
|
2420
|
+
|
|
2421
|
+
// scripts/backlog/backlog-budget-cli.ts
|
|
2422
|
+
import { fileURLToPath } from "node:url";
|
|
2423
|
+
|
|
2424
|
+
// scripts/git/changed-paths.ts
|
|
2425
|
+
function to_paths(raw) {
|
|
2426
|
+
return raw.split("\n").map((line) => line.trim()).filter((line) => line !== "");
|
|
2327
2427
|
}
|
|
2328
|
-
async function
|
|
2329
|
-
if (
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
release(target);
|
|
2334
|
-
}
|
|
2428
|
+
async function read_changed_paths(is_staged) {
|
|
2429
|
+
if (is_staged) return to_paths(await git_command.diff_cached_names());
|
|
2430
|
+
const tracked = to_paths(await git_command.diff_main_names());
|
|
2431
|
+
const untracked = to_paths(await git_command.untracked_names());
|
|
2432
|
+
return [...tracked, ...untracked];
|
|
2335
2433
|
}
|
|
2336
|
-
var
|
|
2434
|
+
var changed_paths = { read_changed_paths, to_paths };
|
|
2337
2435
|
|
|
2338
|
-
// scripts/
|
|
2339
|
-
var
|
|
2340
|
-
var
|
|
2341
|
-
var
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
target,
|
|
2347
|
-
WORKTREE_LOCK_MAX_WAIT_MS
|
|
2348
|
-
);
|
|
2349
|
-
if (output === void 0) {
|
|
2350
|
-
throw new Error(
|
|
2351
|
-
`git ${arguments_.join(" ")}: timed out waiting for the work-tree lock ${target}`
|
|
2352
|
-
);
|
|
2353
|
-
}
|
|
2354
|
-
return output;
|
|
2355
|
-
}
|
|
2356
|
-
async function worktree_list() {
|
|
2357
|
-
return await git_spawn.read([WORKTREE, "list", PORCELAIN_FLAG]);
|
|
2358
|
-
}
|
|
2359
|
-
async function worktree_add(directory, branch_name, start_point) {
|
|
2360
|
-
const flags = start_point === void 0 ? ["add"] : ["add", "--no-track", "-b", branch_name];
|
|
2361
|
-
return await locked([WORKTREE, ...flags, directory, start_point ?? branch_name]);
|
|
2362
|
-
}
|
|
2363
|
-
async function worktree_add_detached(directory, commit2) {
|
|
2364
|
-
return await locked([WORKTREE, "add", "--detach", directory, commit2]);
|
|
2436
|
+
// scripts/josh/path-decision.ts
|
|
2437
|
+
var STAGED_FLAG = "--staged";
|
|
2438
|
+
var JSON_FLAG = "--json";
|
|
2439
|
+
var KNOWN_FLAGS = [STAGED_FLAG, JSON_FLAG];
|
|
2440
|
+
var FAILURE_EXIT_CODE = 1;
|
|
2441
|
+
var MAX_LISTED_PATHS = 5;
|
|
2442
|
+
function has_unknown_flag(argv, known) {
|
|
2443
|
+
return argv.some((argument) => !known.includes(argument));
|
|
2365
2444
|
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2445
|
+
function parse_options(argv) {
|
|
2446
|
+
if (has_unknown_flag(argv, KNOWN_FLAGS)) return void 0;
|
|
2447
|
+
return { is_staged: argv.includes(STAGED_FLAG), is_json: argv.includes(JSON_FLAG) };
|
|
2368
2448
|
}
|
|
2369
|
-
|
|
2370
|
-
|
|
2449
|
+
function format_path_list(paths) {
|
|
2450
|
+
const listed = paths.slice(0, MAX_LISTED_PATHS).join(", ");
|
|
2451
|
+
if (paths.length <= MAX_LISTED_PATHS) return listed;
|
|
2452
|
+
return `${listed}, +${String(paths.length - MAX_LISTED_PATHS)} more`;
|
|
2371
2453
|
}
|
|
2372
|
-
|
|
2373
|
-
|
|
2454
|
+
function print_decision(key, answer, reason, is_json) {
|
|
2455
|
+
if (is_json) {
|
|
2456
|
+
console.info(JSON.stringify({ [key]: answer, reason }));
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2459
|
+
console.info(answer);
|
|
2460
|
+
console.error(reason);
|
|
2374
2461
|
}
|
|
2375
|
-
async function
|
|
2376
|
-
|
|
2462
|
+
async function run_path_decision(argv, command) {
|
|
2463
|
+
const options = parse_options(argv);
|
|
2464
|
+
if (options === void 0) {
|
|
2465
|
+
console.error(command.usage);
|
|
2466
|
+
return FAILURE_EXIT_CODE;
|
|
2467
|
+
}
|
|
2468
|
+
const paths = await changed_paths.read_changed_paths(options.is_staged);
|
|
2469
|
+
const answer = command.decide(paths);
|
|
2470
|
+
print_decision(command.key, answer, command.explain(paths, answer), options.is_json);
|
|
2471
|
+
return 0;
|
|
2377
2472
|
}
|
|
2378
|
-
var
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2473
|
+
var path_decision = {
|
|
2474
|
+
format_path_list,
|
|
2475
|
+
has_unknown_flag,
|
|
2476
|
+
JSON_FLAG,
|
|
2477
|
+
KNOWN_FLAGS,
|
|
2478
|
+
MAX_LISTED_PATHS,
|
|
2479
|
+
parse_options,
|
|
2480
|
+
print_decision,
|
|
2481
|
+
run_path_decision,
|
|
2482
|
+
STAGED_FLAG
|
|
2386
2483
|
};
|
|
2387
2484
|
|
|
2388
|
-
// scripts/
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
var QUOTE_CHARACTERS = /* @__PURE__ */ new Set(['"', "'"]);
|
|
2397
|
-
var MIN_QUOTED_LENGTH = 2;
|
|
2398
|
-
var FIRST_CHARACTER_END = 1;
|
|
2399
|
-
var LAST_CHARACTER_START = -1;
|
|
2400
|
-
function strip_export(line) {
|
|
2401
|
-
const trimmed2 = line.trimStart();
|
|
2402
|
-
return trimmed2.startsWith(EXPORT_PREFIX) ? trimmed2.slice(EXPORT_PREFIX.length).trimStart() : trimmed2;
|
|
2485
|
+
// scripts/lib/cli-flags.ts
|
|
2486
|
+
import { parseArgs } from "node:util";
|
|
2487
|
+
function refuse_unknown_flags(argv, known_flags, command) {
|
|
2488
|
+
const unknown = argv.filter((argument) => !known_flags.includes(argument));
|
|
2489
|
+
if (unknown.length === 0) return void 0;
|
|
2490
|
+
const usage = `Usage: josh ${command} [${known_flags.join("] [")}]`;
|
|
2491
|
+
return `Unknown argument(s): ${unknown.join(" ")}
|
|
2492
|
+
${usage}`;
|
|
2403
2493
|
}
|
|
2404
|
-
function
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2494
|
+
function parse_or_undefined(config) {
|
|
2495
|
+
try {
|
|
2496
|
+
return parseArgs(config);
|
|
2497
|
+
} catch {
|
|
2498
|
+
return void 0;
|
|
2499
|
+
}
|
|
2408
2500
|
}
|
|
2409
|
-
|
|
2410
|
-
|
|
2501
|
+
var cli_flags = { refuse_unknown_flags, parse_or_undefined };
|
|
2502
|
+
|
|
2503
|
+
// scripts/backlog/backlog-budget-cli.ts
|
|
2504
|
+
var ARGV_OFFSET = 2;
|
|
2505
|
+
var SUCCESS_EXIT_CODE = 0;
|
|
2506
|
+
var FAILURE_EXIT_CODE2 = 1;
|
|
2507
|
+
var JSON_KEY = "budget";
|
|
2508
|
+
var USAGE = `Usage: josh backlog:budget --answer <${backlog_budget.ANSWERS.join("|")}> --started <ISO-8601> [--active <ISO-8601>, required unless the watch is off] [--merged <count>] [--running <count>] [--max <count>] [--idle <minutes>, 0 to turn the watch off] [--json]`;
|
|
2509
|
+
var OPTIONS = {
|
|
2510
|
+
active: { type: "string" },
|
|
2511
|
+
answer: { type: "string" },
|
|
2512
|
+
idle: { type: "string" },
|
|
2513
|
+
json: { type: "boolean" },
|
|
2514
|
+
max: { type: "string" },
|
|
2515
|
+
merged: { type: "string" },
|
|
2516
|
+
running: { type: "string" },
|
|
2517
|
+
started: { type: "string" }
|
|
2518
|
+
};
|
|
2519
|
+
function read_arguments(argv) {
|
|
2520
|
+
return cli_flags.parse_or_undefined({ args: [...argv], options: OPTIONS, strict: true })?.values;
|
|
2411
2521
|
}
|
|
2412
|
-
function
|
|
2413
|
-
return
|
|
2522
|
+
function text_of(value) {
|
|
2523
|
+
return typeof value === "string" ? value : void 0;
|
|
2414
2524
|
}
|
|
2415
|
-
function
|
|
2416
|
-
return
|
|
2525
|
+
function to_answer(raw) {
|
|
2526
|
+
return backlog_budget.ANSWERS.find((answer) => answer === raw);
|
|
2417
2527
|
}
|
|
2418
|
-
function
|
|
2419
|
-
|
|
2420
|
-
|
|
2528
|
+
function to_time_ms(raw) {
|
|
2529
|
+
if (raw === void 0) return void 0;
|
|
2530
|
+
const parsed = Date.parse(raw);
|
|
2531
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
2421
2532
|
}
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
if (!
|
|
2425
|
-
|
|
2533
|
+
var COUNT_PATTERN = /^\d+$/u;
|
|
2534
|
+
function to_count(raw) {
|
|
2535
|
+
if (raw === void 0 || !COUNT_PATTERN.test(raw)) return void 0;
|
|
2536
|
+
const parsed = Number(raw);
|
|
2537
|
+
return Number.isSafeInteger(parsed) ? parsed : void 0;
|
|
2426
2538
|
}
|
|
2427
|
-
function
|
|
2428
|
-
return
|
|
2539
|
+
function is_readable(raw, parsed) {
|
|
2540
|
+
return raw === void 0 || parsed !== void 0;
|
|
2429
2541
|
}
|
|
2430
|
-
|
|
2431
|
-
|
|
2542
|
+
var COUNT_NAMES = ["idle", "max", "merged", "running"];
|
|
2543
|
+
function counts_of(values) {
|
|
2544
|
+
return {
|
|
2545
|
+
idle: to_count(text_of(values.idle)),
|
|
2546
|
+
max: to_count(text_of(values.max)),
|
|
2547
|
+
merged: to_count(text_of(values.merged)),
|
|
2548
|
+
running: to_count(text_of(values.running))
|
|
2549
|
+
};
|
|
2432
2550
|
}
|
|
2433
|
-
function
|
|
2434
|
-
|
|
2435
|
-
return line === void 0 ? void 0 : assignment_value(line);
|
|
2551
|
+
function are_counts_readable(values, counts) {
|
|
2552
|
+
return COUNT_NAMES.every((name) => is_readable(text_of(values[name]), counts[name]));
|
|
2436
2553
|
}
|
|
2437
|
-
|
|
2438
|
-
|
|
2554
|
+
var NO_IDLE_MINUTES = 0;
|
|
2555
|
+
function to_idle_ms(idle_minutes) {
|
|
2556
|
+
if (idle_minutes === void 0) return backlog_budget.DEFAULT_IDLE_MS;
|
|
2557
|
+
if (idle_minutes === NO_IDLE_MINUTES) return void 0;
|
|
2558
|
+
return idle_minutes * backlog_budget.MS_PER_MINUTE;
|
|
2439
2559
|
}
|
|
2440
|
-
function
|
|
2441
|
-
|
|
2442
|
-
return
|
|
2560
|
+
function is_watch_readable(values) {
|
|
2561
|
+
if (to_idle_ms(to_count(text_of(values.idle))) === void 0) return true;
|
|
2562
|
+
return text_of(values.active) !== void 0;
|
|
2443
2563
|
}
|
|
2444
|
-
function
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2564
|
+
function are_values_readable(values) {
|
|
2565
|
+
return is_readable(text_of(values.active), to_time_ms(text_of(values.active))) && is_watch_readable(values) && are_counts_readable(values, counts_of(values));
|
|
2566
|
+
}
|
|
2567
|
+
function input_of(values, base) {
|
|
2568
|
+
const counts = counts_of(values);
|
|
2449
2569
|
return {
|
|
2450
|
-
|
|
2451
|
-
|
|
2570
|
+
...base,
|
|
2571
|
+
active_at_ms: to_time_ms(text_of(values.active)) ?? base.started_at_ms,
|
|
2572
|
+
merged: counts.merged ?? 0,
|
|
2573
|
+
running: counts.running ?? 0,
|
|
2574
|
+
max_issues: counts.max,
|
|
2575
|
+
idle_budget_ms: to_idle_ms(counts.idle)
|
|
2452
2576
|
};
|
|
2453
2577
|
}
|
|
2454
|
-
function
|
|
2455
|
-
const
|
|
2456
|
-
|
|
2457
|
-
|
|
2578
|
+
function build_input(values, now_ms) {
|
|
2579
|
+
const answer = to_answer(text_of(values.answer));
|
|
2580
|
+
if (answer === void 0) return void 0;
|
|
2581
|
+
const started_at_ms = to_time_ms(text_of(values.started));
|
|
2582
|
+
if (started_at_ms === void 0) return void 0;
|
|
2583
|
+
if (!are_values_readable(values)) return void 0;
|
|
2584
|
+
return input_of(values, { answer, now_ms, started_at_ms });
|
|
2458
2585
|
}
|
|
2459
|
-
function
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
role: read_assignment(content, LANE_ROLE_KEY),
|
|
2463
|
-
model: read_assignment(content, LANE_MODEL_KEY),
|
|
2464
|
-
effort: read_assignment(content, LANE_EFFORT_KEY)
|
|
2465
|
-
});
|
|
2586
|
+
function refuse() {
|
|
2587
|
+
console.error(USAGE);
|
|
2588
|
+
return FAILURE_EXIT_CODE2;
|
|
2466
2589
|
}
|
|
2467
|
-
function
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2590
|
+
function run(argv, now_ms = Date.now()) {
|
|
2591
|
+
const values = read_arguments(argv);
|
|
2592
|
+
if (values === void 0) return refuse();
|
|
2593
|
+
const input = build_input(values, now_ms);
|
|
2594
|
+
if (input === void 0) return refuse();
|
|
2595
|
+
const { verdict, reason } = backlog_budget.decide(input);
|
|
2596
|
+
if (values.json === true) {
|
|
2597
|
+
console.info(
|
|
2598
|
+
JSON.stringify({ [JSON_KEY]: verdict, reason, is_finish: backlog_budget.is_finish(input) })
|
|
2599
|
+
);
|
|
2600
|
+
return SUCCESS_EXIT_CODE;
|
|
2601
|
+
}
|
|
2602
|
+
path_decision.print_decision(JSON_KEY, verdict, reason, false);
|
|
2603
|
+
return SUCCESS_EXIT_CODE;
|
|
2472
2604
|
}
|
|
2473
|
-
function
|
|
2474
|
-
|
|
2475
|
-
const lines = split_lines(content);
|
|
2476
|
-
const last = lines.findLastIndex((entry) => is_key_line(entry, key));
|
|
2477
|
-
const body = last === -1 ? [...lines, assignment] : replace_assignment(lines, last, assignment, key);
|
|
2478
|
-
return `${body.join("\n")}
|
|
2479
|
-
`;
|
|
2480
|
-
}
|
|
2481
|
-
function lane_file_content(root_content, seat) {
|
|
2482
|
-
return upsert_assignment(root_content, LANE_SEAT_KEY, String(seat));
|
|
2483
|
-
}
|
|
2484
|
-
function with_lane_output(content, output, profile) {
|
|
2485
|
-
const recorded = upsert_assignment(content, LANE_OUTPUT_KEY, `"${output}"`);
|
|
2486
|
-
if (profile === void 0) return recorded;
|
|
2487
|
-
const with_provider = upsert_assignment(recorded, LANE_PROVIDER_KEY, profile.provider);
|
|
2488
|
-
const with_role = upsert_assignment(with_provider, LANE_ROLE_KEY, profile.role);
|
|
2489
|
-
const with_model = upsert_assignment(with_role, LANE_MODEL_KEY, profile.model);
|
|
2490
|
-
return upsert_assignment(with_model, LANE_EFFORT_KEY, profile.effort);
|
|
2605
|
+
function main(argv) {
|
|
2606
|
+
process.exitCode = run(argv);
|
|
2491
2607
|
}
|
|
2492
|
-
var
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
read_root_seed,
|
|
2505
|
-
with_lane_output
|
|
2608
|
+
var backlog_budget_cli = {
|
|
2609
|
+
JSON_KEY,
|
|
2610
|
+
OPTIONS,
|
|
2611
|
+
SUCCESS_EXIT_CODE,
|
|
2612
|
+
USAGE,
|
|
2613
|
+
build_input,
|
|
2614
|
+
main,
|
|
2615
|
+
read_arguments,
|
|
2616
|
+
run,
|
|
2617
|
+
to_answer,
|
|
2618
|
+
to_count,
|
|
2619
|
+
to_time_ms
|
|
2506
2620
|
};
|
|
2621
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET));
|
|
2507
2622
|
|
|
2508
|
-
// scripts/
|
|
2509
|
-
var
|
|
2510
|
-
var
|
|
2511
|
-
var
|
|
2512
|
-
var
|
|
2513
|
-
|
|
2514
|
-
|
|
2623
|
+
// scripts/run/run-invocation.ts
|
|
2624
|
+
var BACKLOG_COMMAND = "backlogrun";
|
|
2625
|
+
var KNOWN_FLAGS2 = ["--max", "--idle"];
|
|
2626
|
+
var ONLY_FLAG = "--only";
|
|
2627
|
+
var ISSUE_PREFIX = "#";
|
|
2628
|
+
var TOKEN_SEPARATOR = " ";
|
|
2629
|
+
var FIRST_TOKEN = 0;
|
|
2630
|
+
var FIRST_ARGUMENT_INDEX = 1;
|
|
2631
|
+
var VALUE_OFFSET = 1;
|
|
2632
|
+
var FLAG_PAIR_LENGTH = 2;
|
|
2633
|
+
var ONLY_STEP = 1;
|
|
2634
|
+
var EMPTY_LENGTH2 = 0;
|
|
2635
|
+
var NOT_FOUND2 = -1;
|
|
2636
|
+
function tokens_of(invocation) {
|
|
2637
|
+
return invocation.split(TOKEN_SEPARATOR).filter((token) => token.length > EMPTY_LENGTH2);
|
|
2515
2638
|
}
|
|
2516
|
-
function
|
|
2517
|
-
const
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
return {
|
|
2639
|
+
function flag_token(token, raw) {
|
|
2640
|
+
const flag = KNOWN_FLAGS2.find((known) => known === token);
|
|
2641
|
+
const value = backlog_budget_cli.to_count(raw);
|
|
2642
|
+
if (flag === void 0 || value === void 0) return void 0;
|
|
2643
|
+
return `${flag} ${String(value)}`;
|
|
2521
2644
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
};
|
|
2527
|
-
function held_seat(content) {
|
|
2528
|
-
if (content === void 0) return EMPTY_SEAT;
|
|
2529
|
-
return seat_from_content(content) ?? EMPTY_SEAT;
|
|
2645
|
+
function read_flag(tokens, index) {
|
|
2646
|
+
const token = tokens[index] ?? "";
|
|
2647
|
+
if (token === ONLY_FLAG) return { part: ONLY_FLAG, advance: ONLY_STEP };
|
|
2648
|
+
const part = flag_token(token, tokens[index + VALUE_OFFSET]);
|
|
2649
|
+
return part === void 0 ? void 0 : { part, advance: FLAG_PAIR_LENGTH };
|
|
2530
2650
|
}
|
|
2531
|
-
function
|
|
2532
|
-
|
|
2651
|
+
function flag_tokens(tokens, start) {
|
|
2652
|
+
const rendered = [];
|
|
2653
|
+
let index = start;
|
|
2654
|
+
while (index < tokens.length) {
|
|
2655
|
+
const read2 = read_flag(tokens, index);
|
|
2656
|
+
if (read2 === void 0) return void 0;
|
|
2657
|
+
rendered.push(read2.part);
|
|
2658
|
+
index += read2.advance;
|
|
2659
|
+
}
|
|
2660
|
+
return rendered;
|
|
2533
2661
|
}
|
|
2534
|
-
function
|
|
2535
|
-
if (!
|
|
2536
|
-
const
|
|
2537
|
-
|
|
2662
|
+
function issue_of(token) {
|
|
2663
|
+
if (!token.startsWith(ISSUE_PREFIX)) return void 0;
|
|
2664
|
+
const digits = token.slice(ISSUE_PREFIX.length);
|
|
2665
|
+
if (!run_issue_number.ISSUE_NUMBER_PATTERN.test(digits)) return void 0;
|
|
2666
|
+
const issue = Number(digits);
|
|
2667
|
+
return Number.isSafeInteger(issue) ? issue : void 0;
|
|
2538
2668
|
}
|
|
2539
|
-
function
|
|
2540
|
-
|
|
2669
|
+
function take_leading_prefixed(args) {
|
|
2670
|
+
const stop = args.findIndex((token) => !token.startsWith(ISSUE_PREFIX));
|
|
2671
|
+
return args.slice(FIRST_TOKEN, stop === NOT_FOUND2 ? args.length : stop);
|
|
2541
2672
|
}
|
|
2542
|
-
function
|
|
2543
|
-
const
|
|
2544
|
-
const
|
|
2545
|
-
const
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
issue
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
seat: held.seat,
|
|
2552
|
-
development_port: held.development_port,
|
|
2553
|
-
preview_port: held.preview_port,
|
|
2554
|
-
output,
|
|
2555
|
-
profile,
|
|
2556
|
-
is_stranded
|
|
2557
|
-
};
|
|
2673
|
+
function leading_issues(tokens) {
|
|
2674
|
+
const issues = [];
|
|
2675
|
+
const prefixed = take_leading_prefixed(tokens.slice(FIRST_ARGUMENT_INDEX));
|
|
2676
|
+
for (const token of prefixed) {
|
|
2677
|
+
const issue = issue_of(token);
|
|
2678
|
+
if (issue === void 0) return void 0;
|
|
2679
|
+
issues.push(issue);
|
|
2680
|
+
}
|
|
2681
|
+
return issues;
|
|
2558
2682
|
}
|
|
2559
|
-
function
|
|
2560
|
-
return
|
|
2683
|
+
function issue_token(issue) {
|
|
2684
|
+
return `${ISSUE_PREFIX}${String(issue)}`;
|
|
2561
2685
|
}
|
|
2562
|
-
function
|
|
2563
|
-
|
|
2564
|
-
const directory = line_value(lines, WORKTREE_PREFIX);
|
|
2565
|
-
const branch2 = line_value(lines, BRANCH_PREFIX);
|
|
2566
|
-
const issue = branch_issue(branch2);
|
|
2567
|
-
if (directory === void 0 || branch2 === void 0 || issue === void 0) return void 0;
|
|
2568
|
-
if (!is_lane_directory(root, issue, directory)) return void 0;
|
|
2569
|
-
return build_lane(issue, branch2, directory, is_gone(directory));
|
|
2686
|
+
function joined(command, rendered) {
|
|
2687
|
+
return [command, ...rendered].join(TOKEN_SEPARATOR);
|
|
2570
2688
|
}
|
|
2571
|
-
function
|
|
2572
|
-
|
|
2689
|
+
function rebuilt_backlog(tokens) {
|
|
2690
|
+
const issues = leading_issues(tokens);
|
|
2691
|
+
if (issues === void 0) return void 0;
|
|
2692
|
+
const flags = flag_tokens(tokens, FIRST_ARGUMENT_INDEX + issues.length);
|
|
2693
|
+
if (flags === void 0) return void 0;
|
|
2694
|
+
return joined(BACKLOG_COMMAND, [...issues.map((issue) => issue_token(issue)), ...flags]);
|
|
2573
2695
|
}
|
|
2574
|
-
|
|
2575
|
-
const
|
|
2576
|
-
|
|
2696
|
+
function rebuild(invocation) {
|
|
2697
|
+
const tokens = tokens_of(invocation);
|
|
2698
|
+
if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return void 0;
|
|
2699
|
+
return rebuilt_backlog(tokens);
|
|
2577
2700
|
}
|
|
2578
|
-
|
|
2579
|
-
|
|
2701
|
+
function issue_numbers(invocation) {
|
|
2702
|
+
const tokens = tokens_of(invocation);
|
|
2703
|
+
if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return void 0;
|
|
2704
|
+
const issues = leading_issues(tokens);
|
|
2705
|
+
if (issues === void 0 || issues.length === EMPTY_LENGTH2) return void 0;
|
|
2706
|
+
return issues;
|
|
2580
2707
|
}
|
|
2581
|
-
|
|
2582
|
-
const
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
return lanes.toSorted((left, right) => Number(left.issue) - Number(right.issue));
|
|
2708
|
+
function has_only(invocation) {
|
|
2709
|
+
const tokens = tokens_of(invocation);
|
|
2710
|
+
if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return false;
|
|
2711
|
+
return tokens.slice(FIRST_ARGUMENT_INDEX).includes(ONLY_FLAG);
|
|
2586
2712
|
}
|
|
2587
|
-
|
|
2588
|
-
|
|
2713
|
+
var run_invocation = {
|
|
2714
|
+
has_only,
|
|
2715
|
+
issue_numbers,
|
|
2716
|
+
rebuild
|
|
2717
|
+
};
|
|
2718
|
+
|
|
2719
|
+
// scripts/run/run-carry.ts
|
|
2720
|
+
var CARRY_PREFIX = "josh-run-carry-";
|
|
2721
|
+
var REPOSITORY_DIRECTORY_INDEX = 1;
|
|
2722
|
+
var CARRY_MAX_AGE_HOURS = backlog_budget.WHOLE_RUN_BUDGET_HOURS;
|
|
2723
|
+
var CARRY_MAX_AGE_MS = backlog_budget.WHOLE_RUN_BUDGET_MS;
|
|
2724
|
+
var NO_INCREMENT3 = 0;
|
|
2725
|
+
var MAX_CUTS = 6;
|
|
2726
|
+
var END_COMMAND2 = "pnpm josh run:carry --end";
|
|
2727
|
+
var RESUME_COMMAND = "pnpm josh run:carry --resume";
|
|
2728
|
+
var READ_COMMAND2 = "pnpm josh run:carry --json";
|
|
2729
|
+
var OWNER_ARGUMENT = '--owner "$PPID"';
|
|
2730
|
+
var NONE_READ2 = { kind: "none" };
|
|
2731
|
+
var UNREADABLE_READ3 = { kind: "unreadable" };
|
|
2732
|
+
var NO_OWNER = {};
|
|
2733
|
+
var run_carry_schema = z5.object({
|
|
2734
|
+
invocation: z5.string(),
|
|
2735
|
+
started_at: z5.string(),
|
|
2736
|
+
merged: z5.number(),
|
|
2737
|
+
merged_issues: z5.array(z5.number()).optional(),
|
|
2738
|
+
filed: z5.number(),
|
|
2739
|
+
cuts: z5.number(),
|
|
2740
|
+
// Defaulted, so a record written before this field existed parses with a zero streak rather than
|
|
2741
|
+
// failing to read — the same backward-compatibility the optional owner fields below carry.
|
|
2742
|
+
failures: z5.number().default(0),
|
|
2743
|
+
// Defaulted for the same backward-compatibility as `failures` (joshuafolkken/kit#2240).
|
|
2744
|
+
outages: z5.number().default(0),
|
|
2745
|
+
// Optional, so a record written before the outage fold existed still parses (joshuafolkken/kit#2317).
|
|
2746
|
+
last_outage_at: z5.string().optional(),
|
|
2747
|
+
// Optional, so a record written by the previous shape still parses. Read as "no owner declared",
|
|
2748
|
+
// which is the not-provably-live answer rather than a live one.
|
|
2749
|
+
owner_pid: z5.number().optional(),
|
|
2750
|
+
owner_start: z5.string().optional(),
|
|
2751
|
+
is_handed_off: z5.boolean().optional(),
|
|
2752
|
+
done: z5.array(z5.number()).optional(),
|
|
2753
|
+
// Optional, so a record written before the retrospective existed still parses (joshuafolkken/kit#2328).
|
|
2754
|
+
retrospective: z5.boolean().optional()
|
|
2755
|
+
});
|
|
2756
|
+
function carry_path(git_directory) {
|
|
2757
|
+
return stamp_file.stamp_path(CARRY_PREFIX, git_directory);
|
|
2758
|
+
}
|
|
2759
|
+
async function repository_directory() {
|
|
2760
|
+
const directories = await git_command.git_directories();
|
|
2761
|
+
return directories[REPOSITORY_DIRECTORY_INDEX];
|
|
2762
|
+
}
|
|
2763
|
+
function parse_carry(raw) {
|
|
2764
|
+
try {
|
|
2765
|
+
const parsed = run_carry_schema.safeParse(JSON.parse(raw));
|
|
2766
|
+
return parsed.success ? parsed.data : void 0;
|
|
2767
|
+
} catch {
|
|
2768
|
+
return void 0;
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
function is_expired2(carry, now) {
|
|
2772
|
+
const started = Date.parse(carry.started_at);
|
|
2773
|
+
if (Number.isNaN(started)) return true;
|
|
2774
|
+
return now.getTime() - started > CARRY_MAX_AGE_MS;
|
|
2775
|
+
}
|
|
2776
|
+
function classify4(raw, now) {
|
|
2777
|
+
if (raw === void 0) return NONE_READ2;
|
|
2778
|
+
const carry = parse_carry(raw);
|
|
2779
|
+
if (carry === void 0) return UNREADABLE_READ3;
|
|
2780
|
+
return { kind: is_expired2(carry, now) ? "expired" : "carried", carry };
|
|
2781
|
+
}
|
|
2782
|
+
function read_carry(target, now = /* @__PURE__ */ new Date()) {
|
|
2783
|
+
return classify4(stamp_file.read_stamp_text(target), now);
|
|
2784
|
+
}
|
|
2785
|
+
function owner_of(pid, read2 = process_identity.read_start) {
|
|
2786
|
+
return { pid, start: read2(pid) };
|
|
2787
|
+
}
|
|
2788
|
+
function fresh_carry(invocation, owner, now) {
|
|
2789
|
+
return {
|
|
2790
|
+
invocation,
|
|
2791
|
+
started_at: now.toISOString(),
|
|
2792
|
+
merged: NO_INCREMENT3,
|
|
2793
|
+
filed: NO_INCREMENT3,
|
|
2794
|
+
cuts: NO_INCREMENT3,
|
|
2795
|
+
failures: NO_INCREMENT3,
|
|
2796
|
+
outages: NO_INCREMENT3,
|
|
2797
|
+
owner_pid: owner.pid,
|
|
2798
|
+
owner_start: owner.start
|
|
2799
|
+
};
|
|
2800
|
+
}
|
|
2801
|
+
function begin_carry(target, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
|
|
2802
|
+
const carry = fresh_carry(invocation, owner, now);
|
|
2803
|
+
return stamp_file.create_stamp(target, carry) ? carry : void 0;
|
|
2589
2804
|
}
|
|
2590
|
-
function
|
|
2591
|
-
|
|
2805
|
+
function replace_carry(target, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
|
|
2806
|
+
stamp_file.remove_stamp(target);
|
|
2807
|
+
return begin_carry(target, invocation, owner, now);
|
|
2592
2808
|
}
|
|
2593
|
-
function
|
|
2594
|
-
|
|
2809
|
+
function adopt_carry(target, carry, owner = NO_OWNER) {
|
|
2810
|
+
const next = {
|
|
2811
|
+
...carry,
|
|
2812
|
+
owner_pid: owner.pid,
|
|
2813
|
+
owner_start: owner.start,
|
|
2814
|
+
is_handed_off: false
|
|
2815
|
+
};
|
|
2816
|
+
stamp_file.remove_stamp(target);
|
|
2817
|
+
return stamp_file.create_stamp(target, next) ? next : void 0;
|
|
2595
2818
|
}
|
|
2596
|
-
|
|
2597
|
-
return
|
|
2819
|
+
function is_owner_live(carry) {
|
|
2820
|
+
return process_identity.is_same_process(carry.owner_pid, carry.owner_start) !== false;
|
|
2598
2821
|
}
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
find_open_lane,
|
|
2602
|
-
list_lanes,
|
|
2603
|
-
main_repository_root,
|
|
2604
|
-
parse_block,
|
|
2605
|
-
read_environment,
|
|
2606
|
-
unreadable_lanes,
|
|
2607
|
-
used_seats
|
|
2608
|
-
};
|
|
2609
|
-
|
|
2610
|
-
// scripts/backlog/backlog-budget-cli.ts
|
|
2611
|
-
import { fileURLToPath } from "node:url";
|
|
2612
|
-
|
|
2613
|
-
// scripts/git/changed-paths.ts
|
|
2614
|
-
function to_paths(raw) {
|
|
2615
|
-
return raw.split("\n").map((line) => line.trim()).filter((line) => line !== "");
|
|
2822
|
+
function is_owned_by(carry, owner) {
|
|
2823
|
+
return carry.owner_pid === owner.pid && carry.owner_start === owner.start;
|
|
2616
2824
|
}
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
const tracked = to_paths(await git_command.diff_main_names());
|
|
2620
|
-
const untracked = to_paths(await git_command.untracked_names());
|
|
2621
|
-
return [...tracked, ...untracked];
|
|
2825
|
+
function is_foreign_live_owner(carry, owner) {
|
|
2826
|
+
return is_owner_live(carry) && !is_owned_by(carry, owner);
|
|
2622
2827
|
}
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
// scripts/josh/path-decision.ts
|
|
2626
|
-
var STAGED_FLAG = "--staged";
|
|
2627
|
-
var JSON_FLAG = "--json";
|
|
2628
|
-
var KNOWN_FLAGS = [STAGED_FLAG, JSON_FLAG];
|
|
2629
|
-
var FAILURE_EXIT_CODE = 1;
|
|
2630
|
-
var MAX_LISTED_PATHS = 5;
|
|
2631
|
-
function has_unknown_flag(argv, known) {
|
|
2632
|
-
return argv.some((argument) => !known.includes(argument));
|
|
2828
|
+
function is_handed_off_to(carry, invocation) {
|
|
2829
|
+
return carry.is_handed_off === true && carry.invocation === invocation;
|
|
2633
2830
|
}
|
|
2634
|
-
function
|
|
2635
|
-
if (
|
|
2636
|
-
|
|
2831
|
+
function classify_claim(carry, request) {
|
|
2832
|
+
if (is_handed_off_to(carry, request.invocation)) return "resume";
|
|
2833
|
+
if (is_foreign_live_owner(carry, request.owner)) return "busy";
|
|
2834
|
+
if (carry.invocation !== request.invocation) return "mismatch";
|
|
2835
|
+
return request.is_adoption ? "resume" : "standing";
|
|
2637
2836
|
}
|
|
2638
|
-
function
|
|
2639
|
-
|
|
2640
|
-
if (paths.length <= MAX_LISTED_PATHS) return listed;
|
|
2641
|
-
return `${listed}, +${String(paths.length - MAX_LISTED_PATHS)} more`;
|
|
2837
|
+
function is_count_refused(carry, owner) {
|
|
2838
|
+
return carry.is_handed_off === true || is_foreign_live_owner(carry, owner);
|
|
2642
2839
|
}
|
|
2643
|
-
function
|
|
2644
|
-
|
|
2645
|
-
console.info(JSON.stringify({ [key]: answer, reason }));
|
|
2646
|
-
return;
|
|
2647
|
-
}
|
|
2648
|
-
console.info(answer);
|
|
2649
|
-
console.error(reason);
|
|
2840
|
+
function is_at_cut_cap(carry) {
|
|
2841
|
+
return carry.cuts >= MAX_CUTS;
|
|
2650
2842
|
}
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
if (options === void 0) {
|
|
2654
|
-
console.error(command.usage);
|
|
2655
|
-
return FAILURE_EXIT_CODE;
|
|
2656
|
-
}
|
|
2657
|
-
const paths = await changed_paths.read_changed_paths(options.is_staged);
|
|
2658
|
-
const answer = command.decide(paths);
|
|
2659
|
-
print_decision(command.key, answer, command.explain(paths, answer), options.is_json);
|
|
2660
|
-
return 0;
|
|
2843
|
+
function end_carry(target) {
|
|
2844
|
+
stamp_file.remove_stamp(target);
|
|
2661
2845
|
}
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
JSON_FLAG,
|
|
2666
|
-
KNOWN_FLAGS,
|
|
2667
|
-
MAX_LISTED_PATHS,
|
|
2668
|
-
parse_options,
|
|
2669
|
-
print_decision,
|
|
2670
|
-
run_path_decision,
|
|
2671
|
-
STAGED_FLAG
|
|
2672
|
-
};
|
|
2673
|
-
|
|
2674
|
-
// scripts/lib/cli-flags.ts
|
|
2675
|
-
import { parseArgs } from "node:util";
|
|
2676
|
-
function refuse_unknown_flags(argv, known_flags, command) {
|
|
2677
|
-
const unknown = argv.filter((argument) => !known_flags.includes(argument));
|
|
2678
|
-
if (unknown.length === 0) return void 0;
|
|
2679
|
-
const usage = `Usage: josh ${command} [${known_flags.join("] [")}]`;
|
|
2680
|
-
return `Unknown argument(s): ${unknown.join(" ")}
|
|
2681
|
-
${usage}`;
|
|
2846
|
+
function retrospective_done_of(read2) {
|
|
2847
|
+
if (read2.kind !== "carried" && read2.kind !== "expired") return false;
|
|
2848
|
+
return read2.carry.retrospective === true;
|
|
2682
2849
|
}
|
|
2683
|
-
function
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2850
|
+
function remaining_of(carry) {
|
|
2851
|
+
if (carry === void 0) return void 0;
|
|
2852
|
+
const declared = run_invocation.issue_numbers(carry.invocation);
|
|
2853
|
+
if (declared === void 0) return void 0;
|
|
2854
|
+
const done = carry.done ?? [];
|
|
2855
|
+
return declared.filter((issue) => !done.includes(issue));
|
|
2689
2856
|
}
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
var ARGV_OFFSET = 2;
|
|
2694
|
-
var SUCCESS_EXIT_CODE = 0;
|
|
2695
|
-
var FAILURE_EXIT_CODE2 = 1;
|
|
2696
|
-
var JSON_KEY = "budget";
|
|
2697
|
-
var USAGE = `Usage: josh backlog:budget --answer <${backlog_budget.ANSWERS.join("|")}> --started <ISO-8601> [--active <ISO-8601>, required unless the watch is off] [--merged <count>] [--running <count>] [--max <count>] [--idle <minutes>, 0 to turn the watch off] [--json]`;
|
|
2698
|
-
var OPTIONS = {
|
|
2699
|
-
active: { type: "string" },
|
|
2700
|
-
answer: { type: "string" },
|
|
2701
|
-
idle: { type: "string" },
|
|
2702
|
-
json: { type: "boolean" },
|
|
2703
|
-
max: { type: "string" },
|
|
2704
|
-
merged: { type: "string" },
|
|
2705
|
-
running: { type: "string" },
|
|
2706
|
-
started: { type: "string" }
|
|
2707
|
-
};
|
|
2708
|
-
function read_arguments(argv) {
|
|
2709
|
-
return cli_flags.parse_or_undefined({ args: [...argv], options: OPTIONS, strict: true })?.values;
|
|
2857
|
+
function done_note(carry) {
|
|
2858
|
+
const done = carry.done ?? [];
|
|
2859
|
+
return done.length === 0 ? "" : `, issues ${done.join(", ")} done`;
|
|
2710
2860
|
}
|
|
2711
|
-
function
|
|
2712
|
-
return
|
|
2861
|
+
function describe_carry(carry) {
|
|
2862
|
+
return `${carry.invocation} started ${carry.started_at}; ${String(carry.merged)} merged, ${String(carry.filed)} filed, ${String(carry.failures)} failed in a row, ${String(carry.outages)} outage(s) in a row, ${String(carry.cuts)} cut(s) crossed${done_note(carry)}`;
|
|
2713
2863
|
}
|
|
2714
|
-
function
|
|
2715
|
-
return
|
|
2864
|
+
function expired_message(carry) {
|
|
2865
|
+
return `The ${String(CARRY_MAX_AGE_HOURS)}-hour whole-run bound is spent: ${describe_carry(carry)}. Clear it with \`${END_COMMAND2}\`.`;
|
|
2716
2866
|
}
|
|
2717
|
-
function
|
|
2718
|
-
|
|
2719
|
-
const parsed = Date.parse(raw);
|
|
2720
|
-
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
2867
|
+
function mismatch_message(carry, invocation) {
|
|
2868
|
+
return `A different invocation is carried here \u2014 ${describe_carry(carry)}. This one is \`${invocation}\`. End the standing record with \`${END_COMMAND2}\` once you know its run is over, then begin again.`;
|
|
2721
2869
|
}
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
if (raw === void 0 || !COUNT_PATTERN.test(raw)) return void 0;
|
|
2725
|
-
const parsed = Number(raw);
|
|
2726
|
-
return Number.isSafeInteger(parsed) ? parsed : void 0;
|
|
2870
|
+
function busy_message2(carry) {
|
|
2871
|
+
return `A live run holds this budget \u2014 ${describe_carry(carry)}, owner pid ${String(carry.owner_pid)} still running. Nothing was established. Wait for that run, or end its record with \`${END_COMMAND2}\` once you know it is over.`;
|
|
2727
2872
|
}
|
|
2728
|
-
function
|
|
2729
|
-
return
|
|
2873
|
+
function standing_message(carry) {
|
|
2874
|
+
return `A run record is standing here that no cut handed off \u2014 ${describe_carry(carry)}. Nothing was established. Carry that budget with \`${RESUME_COMMAND} "${carry.invocation}" ${OWNER_ARGUMENT}\`, or discard it with \`${END_COMMAND2}\` and begin again.`;
|
|
2730
2875
|
}
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
merged: to_count(text_of(values.merged)),
|
|
2737
|
-
running: to_count(text_of(values.running))
|
|
2738
|
-
};
|
|
2876
|
+
function count_refused_message(carry) {
|
|
2877
|
+
if (carry.is_handed_off === true) {
|
|
2878
|
+
return `This budget was handed off at a cut and is waiting for its successor \u2014 ${describe_carry(carry)}. Nothing was counted; the cutting session must not advance a handed-off budget.`;
|
|
2879
|
+
}
|
|
2880
|
+
return `A live run owns this budget \u2014 ${describe_carry(carry)}, owner pid ${String(carry.owner_pid)} still running. Nothing was counted; only its owner advances the budget.`;
|
|
2739
2881
|
}
|
|
2740
|
-
function
|
|
2741
|
-
return
|
|
2882
|
+
function lost_message() {
|
|
2883
|
+
return `Another process established a run record here first, so nothing was established. Read it with \`${READ_COMMAND2}\`.`;
|
|
2742
2884
|
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
if (idle_minutes === void 0) return backlog_budget.DEFAULT_IDLE_MS;
|
|
2746
|
-
if (idle_minutes === NO_IDLE_MINUTES) return void 0;
|
|
2747
|
-
return idle_minutes * backlog_budget.MS_PER_MINUTE;
|
|
2885
|
+
function nothing_to_resume_message() {
|
|
2886
|
+
return `Nothing is carried here, so there is no budget to resume. Begin one with \`pnpm josh run:carry --begin "<invocation>"\`.`;
|
|
2748
2887
|
}
|
|
2749
|
-
function
|
|
2750
|
-
|
|
2751
|
-
return text_of(values.active) !== void 0;
|
|
2888
|
+
function unreadable_message3() {
|
|
2889
|
+
return `A run record is here but could not be read; clear it with \`${END_COMMAND2}\` once you know no run is using it.`;
|
|
2752
2890
|
}
|
|
2753
|
-
function
|
|
2754
|
-
return
|
|
2891
|
+
function unknown_message3() {
|
|
2892
|
+
return "This repository\u2019s git directory could not be read, so no run record was established.";
|
|
2755
2893
|
}
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2894
|
+
var run_carry = {
|
|
2895
|
+
CARRY_MAX_AGE_HOURS,
|
|
2896
|
+
CARRY_MAX_AGE_MS,
|
|
2897
|
+
END_COMMAND: END_COMMAND2,
|
|
2898
|
+
MAX_CUTS,
|
|
2899
|
+
NO_OWNER,
|
|
2900
|
+
RESUME_COMMAND,
|
|
2901
|
+
adopt_carry,
|
|
2902
|
+
apply_change: run_carry_change.apply_change,
|
|
2903
|
+
begin_carry,
|
|
2904
|
+
busy_message: busy_message2,
|
|
2905
|
+
carry_path,
|
|
2906
|
+
classify: classify4,
|
|
2907
|
+
classify_claim,
|
|
2908
|
+
count_refused_message,
|
|
2909
|
+
is_at_cut_cap,
|
|
2910
|
+
describe_carry,
|
|
2911
|
+
end_carry,
|
|
2912
|
+
expired_message,
|
|
2913
|
+
mismatch_message,
|
|
2914
|
+
fresh_carry,
|
|
2915
|
+
is_count_refused,
|
|
2916
|
+
is_expired: is_expired2,
|
|
2917
|
+
is_foreign_live_owner,
|
|
2918
|
+
is_owner_live,
|
|
2919
|
+
lost_message,
|
|
2920
|
+
nothing_to_resume_message,
|
|
2921
|
+
owner_of,
|
|
2922
|
+
parse_carry,
|
|
2923
|
+
read_carry,
|
|
2924
|
+
remaining_of,
|
|
2925
|
+
replace_carry,
|
|
2926
|
+
repository_directory,
|
|
2927
|
+
retrospective_done_of,
|
|
2928
|
+
standing_message,
|
|
2929
|
+
unknown_message: unknown_message3,
|
|
2930
|
+
unreadable_message: unreadable_message3
|
|
2931
|
+
};
|
|
2932
|
+
|
|
2933
|
+
// scripts/lane/lane-registry.ts
|
|
2934
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
2935
|
+
import path3 from "node:path";
|
|
2936
|
+
|
|
2937
|
+
// scripts/git/git-ls-remote.ts
|
|
2938
|
+
var LS_REMOTE_COMMAND = "ls-remote";
|
|
2939
|
+
var HEADS_FLAG = "--heads";
|
|
2940
|
+
var ORIGIN_REMOTE = "origin";
|
|
2941
|
+
var HEADS_REF_PREFIX = "refs/heads/";
|
|
2942
|
+
function ls_remote_branch_arguments(branch_name) {
|
|
2943
|
+
return [LS_REMOTE_COMMAND, HEADS_FLAG, ORIGIN_REMOTE, `${HEADS_REF_PREFIX}${branch_name}`];
|
|
2766
2944
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2945
|
+
|
|
2946
|
+
// scripts/git/repository-lock.ts
|
|
2947
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
2948
|
+
import { linkSync, renameSync, rmSync as rmSync2 } from "node:fs";
|
|
2949
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
2950
|
+
|
|
2951
|
+
// scripts/git/git-common-directory.ts
|
|
2952
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
2953
|
+
var OWN_GIT_DIRECTORY = 0;
|
|
2954
|
+
var COMMON_GIT_DIRECTORY = 1;
|
|
2955
|
+
var PROBE_TIMEOUT_MS3 = 2e3;
|
|
2956
|
+
function read_directories(cwd) {
|
|
2957
|
+
const git = git_utilities.get_git_command_for_spawn();
|
|
2958
|
+
const output = execFileSync4(git, [...git_command.GIT_DIRECTORY_ARGUMENTS], {
|
|
2959
|
+
cwd,
|
|
2960
|
+
encoding: "utf8",
|
|
2961
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
2962
|
+
timeout: PROBE_TIMEOUT_MS3
|
|
2963
|
+
});
|
|
2964
|
+
return output.trim().split("\n");
|
|
2774
2965
|
}
|
|
2775
|
-
function
|
|
2776
|
-
|
|
2777
|
-
|
|
2966
|
+
function select_linked(directories) {
|
|
2967
|
+
const own = directories[OWN_GIT_DIRECTORY];
|
|
2968
|
+
const common = directories[COMMON_GIT_DIRECTORY];
|
|
2969
|
+
return own !== void 0 && common !== void 0 && own !== common ? common : void 0;
|
|
2778
2970
|
}
|
|
2779
|
-
function
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
const { verdict, reason } = backlog_budget.decide(input);
|
|
2785
|
-
if (values.json === true) {
|
|
2786
|
-
console.info(
|
|
2787
|
-
JSON.stringify({ [JSON_KEY]: verdict, reason, is_finish: backlog_budget.is_finish(input) })
|
|
2788
|
-
);
|
|
2789
|
-
return SUCCESS_EXIT_CODE;
|
|
2971
|
+
function resolve2(cwd) {
|
|
2972
|
+
try {
|
|
2973
|
+
return select_linked(read_directories(cwd));
|
|
2974
|
+
} catch {
|
|
2975
|
+
return void 0;
|
|
2790
2976
|
}
|
|
2791
|
-
path_decision.print_decision(JSON_KEY, verdict, reason, false);
|
|
2792
|
-
return SUCCESS_EXIT_CODE;
|
|
2793
2977
|
}
|
|
2794
|
-
function
|
|
2795
|
-
|
|
2978
|
+
function repository(cwd) {
|
|
2979
|
+
try {
|
|
2980
|
+
return read_directories(cwd)[COMMON_GIT_DIRECTORY];
|
|
2981
|
+
} catch {
|
|
2982
|
+
return void 0;
|
|
2983
|
+
}
|
|
2796
2984
|
}
|
|
2797
|
-
var
|
|
2798
|
-
JSON_KEY,
|
|
2799
|
-
OPTIONS,
|
|
2800
|
-
SUCCESS_EXIT_CODE,
|
|
2801
|
-
USAGE,
|
|
2802
|
-
build_input,
|
|
2803
|
-
main,
|
|
2804
|
-
read_arguments,
|
|
2805
|
-
run,
|
|
2806
|
-
to_answer,
|
|
2807
|
-
to_count,
|
|
2808
|
-
to_time_ms
|
|
2809
|
-
};
|
|
2810
|
-
if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET));
|
|
2985
|
+
var git_common_directory = { repository, resolve: resolve2, select_linked };
|
|
2811
2986
|
|
|
2812
|
-
// scripts/
|
|
2813
|
-
var
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
var ISSUE_PREFIX = "#";
|
|
2817
|
-
var TOKEN_SEPARATOR = " ";
|
|
2818
|
-
var FIRST_TOKEN = 0;
|
|
2819
|
-
var FIRST_ARGUMENT_INDEX = 1;
|
|
2820
|
-
var VALUE_OFFSET = 1;
|
|
2821
|
-
var FLAG_PAIR_LENGTH = 2;
|
|
2822
|
-
var ONLY_STEP = 1;
|
|
2823
|
-
var EMPTY_LENGTH2 = 0;
|
|
2824
|
-
var NOT_FOUND2 = -1;
|
|
2825
|
-
function tokens_of(invocation) {
|
|
2826
|
-
return invocation.split(TOKEN_SEPARATOR).filter((token) => token.length > EMPTY_LENGTH2);
|
|
2827
|
-
}
|
|
2828
|
-
function flag_token(token, raw) {
|
|
2829
|
-
const flag = KNOWN_FLAGS2.find((known) => known === token);
|
|
2830
|
-
const value = backlog_budget_cli.to_count(raw);
|
|
2831
|
-
if (flag === void 0 || value === void 0) return void 0;
|
|
2832
|
-
return `${flag} ${String(value)}`;
|
|
2833
|
-
}
|
|
2834
|
-
function read_flag(tokens, index) {
|
|
2835
|
-
const token = tokens[index] ?? "";
|
|
2836
|
-
if (token === ONLY_FLAG) return { part: ONLY_FLAG, advance: ONLY_STEP };
|
|
2837
|
-
const part = flag_token(token, tokens[index + VALUE_OFFSET]);
|
|
2838
|
-
return part === void 0 ? void 0 : { part, advance: FLAG_PAIR_LENGTH };
|
|
2987
|
+
// scripts/git/repository-lock.ts
|
|
2988
|
+
var POLL_INTERVAL_MS = 200;
|
|
2989
|
+
function lock_path(prefix, cwd = process.cwd()) {
|
|
2990
|
+
return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd);
|
|
2839
2991
|
}
|
|
2840
|
-
function
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
rendered.push(read2.part);
|
|
2847
|
-
index += read2.advance;
|
|
2992
|
+
function parse_owner(raw) {
|
|
2993
|
+
if (raw === void 0) return void 0;
|
|
2994
|
+
try {
|
|
2995
|
+
return JSON.parse(raw);
|
|
2996
|
+
} catch {
|
|
2997
|
+
return void 0;
|
|
2848
2998
|
}
|
|
2849
|
-
return rendered;
|
|
2850
2999
|
}
|
|
2851
|
-
function
|
|
2852
|
-
|
|
2853
|
-
const digits = token.slice(ISSUE_PREFIX.length);
|
|
2854
|
-
if (!run_issue_number.ISSUE_NUMBER_PATTERN.test(digits)) return void 0;
|
|
2855
|
-
const issue = Number(digits);
|
|
2856
|
-
return Number.isSafeInteger(issue) ? issue : void 0;
|
|
3000
|
+
function read_owner(target) {
|
|
3001
|
+
return parse_owner(stamp_file.read_stamp_text(target));
|
|
2857
3002
|
}
|
|
2858
|
-
function
|
|
2859
|
-
|
|
2860
|
-
return args.slice(FIRST_TOKEN, stop === NOT_FOUND2 ? args.length : stop);
|
|
3003
|
+
function is_owner_gone(owner) {
|
|
3004
|
+
return process_identity.is_same_process(owner.pid, owner.process_start) === false;
|
|
2861
3005
|
}
|
|
2862
|
-
function
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
const issue = issue_of(token);
|
|
2867
|
-
if (issue === void 0) return void 0;
|
|
2868
|
-
issues.push(issue);
|
|
3006
|
+
function restore(aside, target) {
|
|
3007
|
+
try {
|
|
3008
|
+
linkSync(aside, target);
|
|
3009
|
+
} catch {
|
|
2869
3010
|
}
|
|
2870
|
-
return issues;
|
|
2871
3011
|
}
|
|
2872
|
-
function
|
|
2873
|
-
|
|
3012
|
+
function stale_record(target, is_gone2) {
|
|
3013
|
+
const raw = stamp_file.read_stamp_text(target);
|
|
3014
|
+
const owner = parse_owner(raw);
|
|
3015
|
+
return owner !== void 0 && is_gone2(owner) ? raw : void 0;
|
|
2874
3016
|
}
|
|
2875
|
-
function
|
|
2876
|
-
|
|
3017
|
+
function move_aside(target) {
|
|
3018
|
+
const aside = `${target}.${String(process.pid)}.${randomUUID2()}`;
|
|
3019
|
+
try {
|
|
3020
|
+
renameSync(target, aside);
|
|
3021
|
+
return aside;
|
|
3022
|
+
} catch {
|
|
3023
|
+
return void 0;
|
|
3024
|
+
}
|
|
2877
3025
|
}
|
|
2878
|
-
function
|
|
2879
|
-
const
|
|
2880
|
-
if (
|
|
2881
|
-
const
|
|
2882
|
-
if (
|
|
2883
|
-
|
|
3026
|
+
function clear_stale(target, is_gone2 = is_owner_gone) {
|
|
3027
|
+
const raw = stale_record(target, is_gone2);
|
|
3028
|
+
if (raw === void 0) return;
|
|
3029
|
+
const aside = move_aside(target);
|
|
3030
|
+
if (aside === void 0) return;
|
|
3031
|
+
if (stamp_file.read_stamp_text(aside) !== raw) restore(aside, target);
|
|
3032
|
+
rmSync2(aside, { force: true });
|
|
2884
3033
|
}
|
|
2885
|
-
function
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
return rebuilt_backlog(tokens);
|
|
3034
|
+
function claim(target) {
|
|
3035
|
+
clear_stale(target);
|
|
3036
|
+
return stamp_file.create_stamp(target, process_identity.own_fields());
|
|
2889
3037
|
}
|
|
2890
|
-
function
|
|
2891
|
-
const
|
|
2892
|
-
if (
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
return issues;
|
|
3038
|
+
function release(target) {
|
|
3039
|
+
const owner = read_owner(target);
|
|
3040
|
+
if (owner !== void 0 && process_identity.is_own_process(owner.pid, owner.process_start)) {
|
|
3041
|
+
stamp_file.remove_stamp(target);
|
|
3042
|
+
}
|
|
2896
3043
|
}
|
|
2897
|
-
function
|
|
2898
|
-
const
|
|
2899
|
-
|
|
2900
|
-
|
|
3044
|
+
async function acquire(target, max_wait_ms) {
|
|
3045
|
+
const deadline = Date.now() + max_wait_ms;
|
|
3046
|
+
while (!claim(target)) {
|
|
3047
|
+
if (Date.now() >= deadline) return false;
|
|
3048
|
+
await sleep(POLL_INTERVAL_MS);
|
|
3049
|
+
}
|
|
3050
|
+
return true;
|
|
2901
3051
|
}
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
}
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
3052
|
+
async function with_lock(work, target, max_wait_ms) {
|
|
3053
|
+
if (!await acquire(target, max_wait_ms)) return void 0;
|
|
3054
|
+
try {
|
|
3055
|
+
return await work();
|
|
3056
|
+
} finally {
|
|
3057
|
+
release(target);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
var repository_lock = { clear_stale, lock_path, with_lock };
|
|
2910
3061
|
|
|
2911
|
-
// scripts/
|
|
2912
|
-
var
|
|
2913
|
-
var
|
|
2914
|
-
|
|
2915
|
-
|
|
3062
|
+
// scripts/git/git-worktree.ts
|
|
3063
|
+
var WORKTREE = "worktree";
|
|
3064
|
+
var WORKTREE_LOCK_PREFIX = "josh-worktree-lock-";
|
|
3065
|
+
var WORKTREE_LOCK_MAX_WAIT_MS = 12e4;
|
|
3066
|
+
async function locked(arguments_) {
|
|
3067
|
+
const target = repository_lock.lock_path(WORKTREE_LOCK_PREFIX);
|
|
3068
|
+
const output = await repository_lock.with_lock(
|
|
3069
|
+
async () => await git_spawn.read(arguments_),
|
|
3070
|
+
target,
|
|
3071
|
+
WORKTREE_LOCK_MAX_WAIT_MS
|
|
3072
|
+
);
|
|
3073
|
+
if (output === void 0) {
|
|
3074
|
+
throw new Error(
|
|
3075
|
+
`git ${arguments_.join(" ")}: timed out waiting for the work-tree lock ${target}`
|
|
3076
|
+
);
|
|
3077
|
+
}
|
|
3078
|
+
return output;
|
|
3079
|
+
}
|
|
3080
|
+
async function worktree_list() {
|
|
3081
|
+
return await git_spawn.read([WORKTREE, "list", PORCELAIN_FLAG]);
|
|
2916
3082
|
}
|
|
2917
|
-
function
|
|
2918
|
-
|
|
2919
|
-
return
|
|
3083
|
+
async function worktree_add(directory, branch_name, start_point) {
|
|
3084
|
+
const flags = start_point === void 0 ? ["add"] : ["add", "--no-track", "-b", branch_name];
|
|
3085
|
+
return await locked([WORKTREE, ...flags, directory, start_point ?? branch_name]);
|
|
2920
3086
|
}
|
|
2921
|
-
function
|
|
2922
|
-
|
|
2923
|
-
const last = Date.parse(last_outage_at);
|
|
2924
|
-
if (Number.isNaN(last)) return false;
|
|
2925
|
-
return now.getTime() - last <= OUTAGE_FOLD_WINDOW_MS;
|
|
3087
|
+
async function worktree_add_detached(directory, commit2) {
|
|
3088
|
+
return await locked([WORKTREE, "add", "--detach", directory, commit2]);
|
|
2926
3089
|
}
|
|
2927
|
-
function
|
|
2928
|
-
return
|
|
3090
|
+
async function worktree_remove(directory) {
|
|
3091
|
+
return await locked([WORKTREE, "remove", "--force", directory]);
|
|
2929
3092
|
}
|
|
2930
|
-
function
|
|
2931
|
-
|
|
2932
|
-
return { outages, last_outage_at: now.toISOString() };
|
|
3093
|
+
async function worktree_prune() {
|
|
3094
|
+
return await locked([WORKTREE, "prune"]);
|
|
2933
3095
|
}
|
|
2934
|
-
function
|
|
2935
|
-
|
|
2936
|
-
return is_within_fold_window(carry.last_outage_at, now) ? folded_outage(carry) : counted_outage(carry, change, now);
|
|
2937
|
-
}
|
|
2938
|
-
const is_reachable = has_increment(change.merged) || has_increment(change.failures);
|
|
2939
|
-
return is_reachable ? { outages: NO_INCREMENT, last_outage_at: void 0 } : folded_outage(carry);
|
|
3096
|
+
async function ls_remote_branch(branch_name) {
|
|
3097
|
+
return await git_spawn.read(ls_remote_branch_arguments(branch_name));
|
|
2940
3098
|
}
|
|
2941
|
-
function
|
|
2942
|
-
|
|
2943
|
-
return {
|
|
2944
|
-
failures: next_failures(carry, change),
|
|
2945
|
-
outages: outage.outages,
|
|
2946
|
-
last_outage_at: outage.last_outage_at
|
|
2947
|
-
};
|
|
3099
|
+
async function branch_delete(branch_name) {
|
|
3100
|
+
return await git_spawn.read(["branch", "-D", branch_name]);
|
|
2948
3101
|
}
|
|
2949
|
-
var
|
|
3102
|
+
var git_worktree = {
|
|
3103
|
+
branch_delete,
|
|
3104
|
+
ls_remote_branch,
|
|
3105
|
+
worktree_add,
|
|
3106
|
+
worktree_add_detached,
|
|
3107
|
+
worktree_list,
|
|
3108
|
+
worktree_prune,
|
|
3109
|
+
worktree_remove
|
|
3110
|
+
};
|
|
2950
3111
|
|
|
2951
|
-
// scripts/
|
|
2952
|
-
var
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
3112
|
+
// scripts/lane/lane-environment.ts
|
|
3113
|
+
var LANE_OUTPUT_KEY = "JOSH_LANE_OUTPUT";
|
|
3114
|
+
var LANE_PROVIDER_KEY = "JOSH_LANE_AGENT_PROVIDER";
|
|
3115
|
+
var LANE_ROLE_KEY = "JOSH_LANE_AGENT_ROLE";
|
|
3116
|
+
var LANE_MODEL_KEY = "JOSH_LANE_AGENT_MODEL";
|
|
3117
|
+
var LANE_EFFORT_KEY = "JOSH_LANE_AGENT_EFFORT";
|
|
3118
|
+
var ASSIGNMENT_SEPARATOR = "=";
|
|
3119
|
+
var EXPORT_PREFIX = "export ";
|
|
3120
|
+
var QUOTE_CHARACTERS = /* @__PURE__ */ new Set(['"', "'"]);
|
|
3121
|
+
var MIN_QUOTED_LENGTH = 2;
|
|
3122
|
+
var FIRST_CHARACTER_END = 1;
|
|
3123
|
+
var LAST_CHARACTER_START = -1;
|
|
3124
|
+
function strip_export(line) {
|
|
3125
|
+
const trimmed2 = line.trimStart();
|
|
3126
|
+
return trimmed2.startsWith(EXPORT_PREFIX) ? trimmed2.slice(EXPORT_PREFIX.length).trimStart() : trimmed2;
|
|
2957
3127
|
}
|
|
2958
|
-
function
|
|
2959
|
-
|
|
2960
|
-
|
|
3128
|
+
function is_key_line(line, key) {
|
|
3129
|
+
const body = strip_export(line);
|
|
3130
|
+
if (!body.startsWith(key)) return false;
|
|
3131
|
+
return body.slice(key.length).trimStart().startsWith(ASSIGNMENT_SEPARATOR);
|
|
2961
3132
|
}
|
|
2962
|
-
function
|
|
2963
|
-
|
|
2964
|
-
return issue !== void 0 && carry.merged_issues?.includes(issue) === true;
|
|
3133
|
+
function is_seed_line(line) {
|
|
3134
|
+
return is_key_line(line, PORT_SEED_KEY);
|
|
2965
3135
|
}
|
|
2966
|
-
function
|
|
2967
|
-
|
|
2968
|
-
return {
|
|
2969
|
-
merged: carry.merged + (change.merged ?? NO_INCREMENT2),
|
|
2970
|
-
filed: carry.filed + (change.filed ?? NO_INCREMENT2),
|
|
2971
|
-
cuts: carry.cuts + cuts,
|
|
2972
|
-
is_handed_off: cuts > NO_INCREMENT2
|
|
2973
|
-
};
|
|
3136
|
+
function is_seat_line(line) {
|
|
3137
|
+
return is_key_line(line, LANE_SEAT_KEY);
|
|
2974
3138
|
}
|
|
2975
|
-
function
|
|
2976
|
-
|
|
2977
|
-
const streak = run_carry_streak.next_state(carry, change, now);
|
|
2978
|
-
const next = {
|
|
2979
|
-
...carry,
|
|
2980
|
-
...next_counts(carry, change),
|
|
2981
|
-
merged_issues: next_merged_issues(carry, change.merged_issue),
|
|
2982
|
-
failures: streak.failures,
|
|
2983
|
-
outages: streak.outages,
|
|
2984
|
-
last_outage_at: streak.last_outage_at,
|
|
2985
|
-
done: next_done(carry, change.done),
|
|
2986
|
-
retrospective: change.retrospective === true || carry.retrospective
|
|
2987
|
-
};
|
|
2988
|
-
stamp_file.write_stamp(target, next);
|
|
2989
|
-
return next;
|
|
3139
|
+
function is_output_line(line) {
|
|
3140
|
+
return is_key_line(line, LANE_OUTPUT_KEY);
|
|
2990
3141
|
}
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
var CARRY_PREFIX = "josh-run-carry-";
|
|
2995
|
-
var REPOSITORY_DIRECTORY_INDEX = 1;
|
|
2996
|
-
var CARRY_MAX_AGE_HOURS = backlog_budget.WHOLE_RUN_BUDGET_HOURS;
|
|
2997
|
-
var CARRY_MAX_AGE_MS = backlog_budget.WHOLE_RUN_BUDGET_MS;
|
|
2998
|
-
var NO_INCREMENT3 = 0;
|
|
2999
|
-
var MAX_CUTS = 6;
|
|
3000
|
-
var END_COMMAND2 = "pnpm josh run:carry --end";
|
|
3001
|
-
var RESUME_COMMAND = "pnpm josh run:carry --resume";
|
|
3002
|
-
var READ_COMMAND2 = "pnpm josh run:carry --json";
|
|
3003
|
-
var OWNER_ARGUMENT = '--owner "$PPID"';
|
|
3004
|
-
var NONE_READ2 = { kind: "none" };
|
|
3005
|
-
var UNREADABLE_READ3 = { kind: "unreadable" };
|
|
3006
|
-
var NO_OWNER = {};
|
|
3007
|
-
var run_carry_schema = z5.object({
|
|
3008
|
-
invocation: z5.string(),
|
|
3009
|
-
started_at: z5.string(),
|
|
3010
|
-
merged: z5.number(),
|
|
3011
|
-
merged_issues: z5.array(z5.number()).optional(),
|
|
3012
|
-
filed: z5.number(),
|
|
3013
|
-
cuts: z5.number(),
|
|
3014
|
-
// Defaulted, so a record written before this field existed parses with a zero streak rather than
|
|
3015
|
-
// failing to read — the same backward-compatibility the optional owner fields below carry.
|
|
3016
|
-
failures: z5.number().default(0),
|
|
3017
|
-
// Defaulted for the same backward-compatibility as `failures` (joshuafolkken/kit#2240).
|
|
3018
|
-
outages: z5.number().default(0),
|
|
3019
|
-
// Optional, so a record written before the outage fold existed still parses (joshuafolkken/kit#2317).
|
|
3020
|
-
last_outage_at: z5.string().optional(),
|
|
3021
|
-
// Optional, so a record written by the previous shape still parses. Read as "no owner declared",
|
|
3022
|
-
// which is the not-provably-live answer rather than a live one.
|
|
3023
|
-
owner_pid: z5.number().optional(),
|
|
3024
|
-
owner_start: z5.string().optional(),
|
|
3025
|
-
is_handed_off: z5.boolean().optional(),
|
|
3026
|
-
done: z5.array(z5.number()).optional(),
|
|
3027
|
-
// Optional, so a record written before the retrospective existed still parses (joshuafolkken/kit#2328).
|
|
3028
|
-
retrospective: z5.boolean().optional()
|
|
3029
|
-
});
|
|
3030
|
-
function carry_path(git_directory) {
|
|
3031
|
-
return stamp_file.stamp_path(CARRY_PREFIX, git_directory);
|
|
3142
|
+
function split_lines(content) {
|
|
3143
|
+
const trimmed2 = content.trimEnd();
|
|
3144
|
+
return trimmed2.length === 0 ? [] : trimmed2.split("\n");
|
|
3032
3145
|
}
|
|
3033
|
-
|
|
3034
|
-
const
|
|
3035
|
-
return
|
|
3146
|
+
function is_quoted(raw) {
|
|
3147
|
+
const first = raw.slice(0, FIRST_CHARACTER_END);
|
|
3148
|
+
if (!QUOTE_CHARACTERS.has(first)) return false;
|
|
3149
|
+
return raw.length >= MIN_QUOTED_LENGTH && raw.endsWith(first);
|
|
3036
3150
|
}
|
|
3037
|
-
function
|
|
3038
|
-
|
|
3039
|
-
const parsed = run_carry_schema.safeParse(JSON.parse(raw));
|
|
3040
|
-
return parsed.success ? parsed.data : void 0;
|
|
3041
|
-
} catch {
|
|
3042
|
-
return void 0;
|
|
3043
|
-
}
|
|
3151
|
+
function unquote(raw) {
|
|
3152
|
+
return is_quoted(raw) ? raw.slice(FIRST_CHARACTER_END, LAST_CHARACTER_START) : raw;
|
|
3044
3153
|
}
|
|
3045
|
-
function
|
|
3046
|
-
|
|
3047
|
-
if (Number.isNaN(started)) return true;
|
|
3048
|
-
return now.getTime() - started > CARRY_MAX_AGE_MS;
|
|
3154
|
+
function assignment_value(line) {
|
|
3155
|
+
return unquote(line.slice(line.indexOf(ASSIGNMENT_SEPARATOR) + FIRST_CHARACTER_END).trim());
|
|
3049
3156
|
}
|
|
3050
|
-
function
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
if (carry === void 0) return UNREADABLE_READ3;
|
|
3054
|
-
return { kind: is_expired2(carry, now) ? "expired" : "carried", carry };
|
|
3157
|
+
function read_assignment(content, key) {
|
|
3158
|
+
const line = split_lines(content).findLast((entry) => is_key_line(entry, key));
|
|
3159
|
+
return line === void 0 ? void 0 : assignment_value(line);
|
|
3055
3160
|
}
|
|
3056
|
-
function
|
|
3057
|
-
return
|
|
3161
|
+
function read_root_seed(content) {
|
|
3162
|
+
return ports.resolve_seed({ [PORT_SEED_KEY]: read_assignment(content, PORT_SEED_KEY) });
|
|
3058
3163
|
}
|
|
3059
|
-
function
|
|
3060
|
-
|
|
3164
|
+
function read_lane_seat(content) {
|
|
3165
|
+
const raw = read_assignment(content, LANE_SEAT_KEY);
|
|
3166
|
+
return raw === void 0 ? void 0 : ports.resolve_lane({ [LANE_SEAT_KEY]: raw });
|
|
3061
3167
|
}
|
|
3062
|
-
function
|
|
3168
|
+
function read_lane_ports(content) {
|
|
3169
|
+
const environment2 = {
|
|
3170
|
+
[PORT_SEED_KEY]: read_assignment(content, PORT_SEED_KEY),
|
|
3171
|
+
[LANE_SEAT_KEY]: read_assignment(content, LANE_SEAT_KEY)
|
|
3172
|
+
};
|
|
3063
3173
|
return {
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
merged: NO_INCREMENT3,
|
|
3067
|
-
filed: NO_INCREMENT3,
|
|
3068
|
-
cuts: NO_INCREMENT3,
|
|
3069
|
-
failures: NO_INCREMENT3,
|
|
3070
|
-
outages: NO_INCREMENT3,
|
|
3071
|
-
owner_pid: owner.pid,
|
|
3072
|
-
owner_start: owner.start
|
|
3174
|
+
development: ports.resolve_development_port(environment2),
|
|
3175
|
+
preview: ports.resolve_preview_port(environment2)
|
|
3073
3176
|
};
|
|
3074
3177
|
}
|
|
3075
|
-
function
|
|
3076
|
-
const
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
function replace_carry(target, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
|
|
3080
|
-
stamp_file.remove_stamp(target);
|
|
3081
|
-
return begin_carry(target, invocation, owner, now);
|
|
3082
|
-
}
|
|
3083
|
-
function adopt_carry(target, carry, owner = NO_OWNER) {
|
|
3084
|
-
const next = {
|
|
3085
|
-
...carry,
|
|
3086
|
-
owner_pid: owner.pid,
|
|
3087
|
-
owner_start: owner.start,
|
|
3088
|
-
is_handed_off: false
|
|
3089
|
-
};
|
|
3090
|
-
stamp_file.remove_stamp(target);
|
|
3091
|
-
return stamp_file.create_stamp(target, next) ? next : void 0;
|
|
3178
|
+
function read_lane_output(content) {
|
|
3179
|
+
const line = split_lines(content).findLast((entry) => is_output_line(entry));
|
|
3180
|
+
const raw = line === void 0 ? void 0 : assignment_value(line);
|
|
3181
|
+
return raw === void 0 || raw.length === 0 ? void 0 : raw;
|
|
3092
3182
|
}
|
|
3093
|
-
function
|
|
3094
|
-
return
|
|
3183
|
+
function read_lane_profile(content) {
|
|
3184
|
+
return agent_role_profile.parse({
|
|
3185
|
+
provider: read_assignment(content, LANE_PROVIDER_KEY),
|
|
3186
|
+
role: read_assignment(content, LANE_ROLE_KEY),
|
|
3187
|
+
model: read_assignment(content, LANE_MODEL_KEY),
|
|
3188
|
+
effort: read_assignment(content, LANE_EFFORT_KEY)
|
|
3189
|
+
});
|
|
3095
3190
|
}
|
|
3096
|
-
function
|
|
3097
|
-
return
|
|
3191
|
+
function replace_assignment(lines, keep, assignment, key) {
|
|
3192
|
+
return lines.flatMap((entry, index) => {
|
|
3193
|
+
if (index === keep) return [assignment];
|
|
3194
|
+
return is_key_line(entry, key) ? [] : [entry];
|
|
3195
|
+
});
|
|
3098
3196
|
}
|
|
3099
|
-
function
|
|
3100
|
-
|
|
3197
|
+
function upsert_assignment(content, key, value) {
|
|
3198
|
+
const assignment = `${key}${ASSIGNMENT_SEPARATOR}${value}`;
|
|
3199
|
+
const lines = split_lines(content);
|
|
3200
|
+
const last = lines.findLastIndex((entry) => is_key_line(entry, key));
|
|
3201
|
+
const body = last === -1 ? [...lines, assignment] : replace_assignment(lines, last, assignment, key);
|
|
3202
|
+
return `${body.join("\n")}
|
|
3203
|
+
`;
|
|
3101
3204
|
}
|
|
3102
|
-
function
|
|
3103
|
-
return
|
|
3205
|
+
function lane_file_content(root_content, seat) {
|
|
3206
|
+
return upsert_assignment(root_content, LANE_SEAT_KEY, String(seat));
|
|
3104
3207
|
}
|
|
3105
|
-
function
|
|
3106
|
-
|
|
3107
|
-
if (
|
|
3108
|
-
|
|
3109
|
-
|
|
3208
|
+
function with_lane_output(content, output, profile) {
|
|
3209
|
+
const recorded = upsert_assignment(content, LANE_OUTPUT_KEY, `"${output}"`);
|
|
3210
|
+
if (profile === void 0) return recorded;
|
|
3211
|
+
const with_provider = upsert_assignment(recorded, LANE_PROVIDER_KEY, profile.provider);
|
|
3212
|
+
const with_role = upsert_assignment(with_provider, LANE_ROLE_KEY, profile.role);
|
|
3213
|
+
const with_model = upsert_assignment(with_role, LANE_MODEL_KEY, profile.model);
|
|
3214
|
+
return upsert_assignment(with_model, LANE_EFFORT_KEY, profile.effort);
|
|
3110
3215
|
}
|
|
3111
|
-
|
|
3112
|
-
|
|
3216
|
+
var lane_environment = {
|
|
3217
|
+
LANE_OUTPUT_KEY,
|
|
3218
|
+
LANE_PROVIDER_KEY,
|
|
3219
|
+
LANE_ROLE_KEY,
|
|
3220
|
+
is_output_line,
|
|
3221
|
+
is_seat_line,
|
|
3222
|
+
is_seed_line,
|
|
3223
|
+
lane_file_content,
|
|
3224
|
+
read_lane_output,
|
|
3225
|
+
read_lane_profile,
|
|
3226
|
+
read_lane_ports,
|
|
3227
|
+
read_lane_seat,
|
|
3228
|
+
read_root_seed,
|
|
3229
|
+
with_lane_output
|
|
3230
|
+
};
|
|
3231
|
+
|
|
3232
|
+
// scripts/lane/lane-registry.ts
|
|
3233
|
+
var WORKTREE_PREFIX = "worktree ";
|
|
3234
|
+
var BRANCH_PREFIX = "branch refs/heads/";
|
|
3235
|
+
var BLOCK_SEPARATOR = "\n\n";
|
|
3236
|
+
var ISSUE_PATTERN = /^[1-9]\d*$/u;
|
|
3237
|
+
function line_value(lines, prefix) {
|
|
3238
|
+
return lines.find((line) => line.startsWith(prefix))?.slice(prefix.length);
|
|
3113
3239
|
}
|
|
3114
|
-
function
|
|
3115
|
-
|
|
3240
|
+
function seat_from_content(content) {
|
|
3241
|
+
const seat = lane_environment.read_lane_seat(content);
|
|
3242
|
+
if (seat === void 0) return void 0;
|
|
3243
|
+
const port_pair = lane_environment.read_lane_ports(content);
|
|
3244
|
+
return { seat, development_port: port_pair.development, preview_port: port_pair.preview };
|
|
3116
3245
|
}
|
|
3117
|
-
|
|
3118
|
-
|
|
3246
|
+
var EMPTY_SEAT = {
|
|
3247
|
+
seat: void 0,
|
|
3248
|
+
development_port: void 0,
|
|
3249
|
+
preview_port: void 0
|
|
3250
|
+
};
|
|
3251
|
+
function held_seat(content) {
|
|
3252
|
+
if (content === void 0) return EMPTY_SEAT;
|
|
3253
|
+
return seat_from_content(content) ?? EMPTY_SEAT;
|
|
3119
3254
|
}
|
|
3120
|
-
function
|
|
3121
|
-
|
|
3122
|
-
return read2.carry.retrospective === true;
|
|
3255
|
+
function read_environment(directory) {
|
|
3256
|
+
return file_reader.read_if_readable(path3.join(directory, ENV_FILE_NAME));
|
|
3123
3257
|
}
|
|
3124
|
-
function
|
|
3125
|
-
if (
|
|
3126
|
-
const
|
|
3127
|
-
|
|
3128
|
-
const done = carry.done ?? [];
|
|
3129
|
-
return declared.filter((issue) => !done.includes(issue));
|
|
3258
|
+
function branch_issue(branch2) {
|
|
3259
|
+
if (!branch2?.endsWith(lane_paths.LANE_BRANCH_SUFFIX)) return void 0;
|
|
3260
|
+
const issue = branch2.slice(0, -lane_paths.LANE_BRANCH_SUFFIX.length);
|
|
3261
|
+
return ISSUE_PATTERN.test(issue) ? issue : void 0;
|
|
3130
3262
|
}
|
|
3131
|
-
function
|
|
3132
|
-
|
|
3133
|
-
return done.length === 0 ? "" : `, issues ${done.join(", ")} done`;
|
|
3263
|
+
function is_gone(directory) {
|
|
3264
|
+
return !existsSync2(directory);
|
|
3134
3265
|
}
|
|
3135
|
-
function
|
|
3136
|
-
|
|
3266
|
+
function build_lane(issue, branch2, directory, is_stranded) {
|
|
3267
|
+
const content = is_stranded ? void 0 : read_environment(directory);
|
|
3268
|
+
const held = held_seat(content);
|
|
3269
|
+
const output = content === void 0 ? void 0 : lane_environment.read_lane_output(content);
|
|
3270
|
+
const profile = content === void 0 ? void 0 : lane_environment.read_lane_profile(content);
|
|
3271
|
+
return {
|
|
3272
|
+
issue,
|
|
3273
|
+
branch: branch2,
|
|
3274
|
+
directory,
|
|
3275
|
+
seat: held.seat,
|
|
3276
|
+
development_port: held.development_port,
|
|
3277
|
+
preview_port: held.preview_port,
|
|
3278
|
+
output,
|
|
3279
|
+
profile,
|
|
3280
|
+
is_stranded
|
|
3281
|
+
};
|
|
3137
3282
|
}
|
|
3138
|
-
function
|
|
3139
|
-
return
|
|
3283
|
+
function is_lane_directory(root, issue, directory) {
|
|
3284
|
+
return directory === lane_paths.lane_directory(root, issue);
|
|
3140
3285
|
}
|
|
3141
|
-
function
|
|
3142
|
-
|
|
3286
|
+
function parse_block(block, root) {
|
|
3287
|
+
const lines = block.split("\n");
|
|
3288
|
+
const directory = line_value(lines, WORKTREE_PREFIX);
|
|
3289
|
+
const branch2 = line_value(lines, BRANCH_PREFIX);
|
|
3290
|
+
const issue = branch_issue(branch2);
|
|
3291
|
+
if (directory === void 0 || branch2 === void 0 || issue === void 0) return void 0;
|
|
3292
|
+
if (!is_lane_directory(root, issue, directory)) return void 0;
|
|
3293
|
+
return build_lane(issue, branch2, directory, is_gone(directory));
|
|
3143
3294
|
}
|
|
3144
|
-
function
|
|
3145
|
-
return
|
|
3295
|
+
function is_lane(lane) {
|
|
3296
|
+
return lane !== void 0;
|
|
3146
3297
|
}
|
|
3147
|
-
function
|
|
3148
|
-
|
|
3298
|
+
async function worktree_blocks() {
|
|
3299
|
+
const listing = await git_worktree.worktree_list();
|
|
3300
|
+
return listing.split(BLOCK_SEPARATOR);
|
|
3149
3301
|
}
|
|
3150
|
-
function
|
|
3151
|
-
|
|
3152
|
-
return `This budget was handed off at a cut and is waiting for its successor \u2014 ${describe_carry(carry)}. Nothing was counted; the cutting session must not advance a handed-off budget.`;
|
|
3153
|
-
}
|
|
3154
|
-
return `A live run owns this budget \u2014 ${describe_carry(carry)}, owner pid ${String(carry.owner_pid)} still running. Nothing was counted; only its owner advances the budget.`;
|
|
3302
|
+
async function main_repository_root() {
|
|
3303
|
+
return repo_discovery.main_worktree(await git_command.repository_root());
|
|
3155
3304
|
}
|
|
3156
|
-
function
|
|
3157
|
-
|
|
3305
|
+
async function list_lanes() {
|
|
3306
|
+
const root = lane_paths.lane_root(await main_repository_root());
|
|
3307
|
+
const blocks = await worktree_blocks();
|
|
3308
|
+
const lanes = blocks.map((block) => parse_block(block, root)).filter(is_lane);
|
|
3309
|
+
return lanes.toSorted((left, right) => Number(left.issue) - Number(right.issue));
|
|
3158
3310
|
}
|
|
3159
|
-
function
|
|
3160
|
-
return
|
|
3311
|
+
function used_seats(lanes) {
|
|
3312
|
+
return lanes.map((lane) => lane.seat).filter((seat) => seat !== void 0);
|
|
3161
3313
|
}
|
|
3162
|
-
function
|
|
3163
|
-
return
|
|
3314
|
+
function unreadable_lanes(lanes) {
|
|
3315
|
+
return lanes.filter((lane) => !lane.is_stranded && lane.seat === void 0);
|
|
3164
3316
|
}
|
|
3165
|
-
function
|
|
3166
|
-
return
|
|
3317
|
+
function find_lane(lanes, issue) {
|
|
3318
|
+
return lanes.find((lane) => lane.issue === issue);
|
|
3167
3319
|
}
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
classify: classify4,
|
|
3181
|
-
classify_claim,
|
|
3182
|
-
count_refused_message,
|
|
3183
|
-
is_at_cut_cap,
|
|
3184
|
-
describe_carry,
|
|
3185
|
-
end_carry,
|
|
3186
|
-
expired_message,
|
|
3187
|
-
mismatch_message,
|
|
3188
|
-
fresh_carry,
|
|
3189
|
-
is_count_refused,
|
|
3190
|
-
is_expired: is_expired2,
|
|
3191
|
-
is_foreign_live_owner,
|
|
3192
|
-
is_owner_live,
|
|
3193
|
-
lost_message,
|
|
3194
|
-
nothing_to_resume_message,
|
|
3195
|
-
owner_of,
|
|
3196
|
-
parse_carry,
|
|
3197
|
-
read_carry,
|
|
3198
|
-
remaining_of,
|
|
3199
|
-
replace_carry,
|
|
3200
|
-
repository_directory,
|
|
3201
|
-
retrospective_done_of,
|
|
3202
|
-
standing_message,
|
|
3203
|
-
unknown_message: unknown_message3,
|
|
3204
|
-
unreadable_message: unreadable_message3
|
|
3320
|
+
async function find_open_lane(issue) {
|
|
3321
|
+
return find_lane(await list_lanes(), issue);
|
|
3322
|
+
}
|
|
3323
|
+
var lane_registry = {
|
|
3324
|
+
find_lane,
|
|
3325
|
+
find_open_lane,
|
|
3326
|
+
list_lanes,
|
|
3327
|
+
main_repository_root,
|
|
3328
|
+
parse_block,
|
|
3329
|
+
read_environment,
|
|
3330
|
+
unreadable_lanes,
|
|
3331
|
+
used_seats
|
|
3205
3332
|
};
|
|
3206
3333
|
|
|
3207
3334
|
// scripts/run/run-progress-clock.ts
|
|
@@ -3348,9 +3475,9 @@ var run_progress_clock = {
|
|
|
3348
3475
|
// scripts/run/run-watcher-guard.ts
|
|
3349
3476
|
var WATCHER_TICK_MS = 3e4;
|
|
3350
3477
|
var TICK_MULTIPLIER = 3;
|
|
3351
|
-
var
|
|
3478
|
+
var MS_PER_SECOND3 = 1e3;
|
|
3352
3479
|
var STALE_THRESHOLD_MS = WATCHER_TICK_MS * TICK_MULTIPLIER;
|
|
3353
|
-
var STALE_THRESHOLD_S = STALE_THRESHOLD_MS /
|
|
3480
|
+
var STALE_THRESHOLD_S = STALE_THRESHOLD_MS / MS_PER_SECOND3;
|
|
3354
3481
|
var STALE_NOTE = `Lane children are in-flight but the progress watcher has not pinged in the last ${String(STALE_THRESHOLD_S)}s \u2014 run \`pnpm josh run:progress --wait\` in the background before proceeding`;
|
|
3355
3482
|
var OK_RESULT = { kind: "ok" };
|
|
3356
3483
|
async function has_lanes_in_flight() {
|
|
@@ -3369,6 +3496,114 @@ var run_watcher_guard = {
|
|
|
3369
3496
|
has_lanes_in_flight
|
|
3370
3497
|
};
|
|
3371
3498
|
|
|
3499
|
+
// scripts/run/run-headless.ts
|
|
3500
|
+
var HEADLESS_ENV_KEY = "JOSH_RUN_HEADLESS";
|
|
3501
|
+
var HEADLESS_VALUE = "1";
|
|
3502
|
+
function environment() {
|
|
3503
|
+
return { [HEADLESS_ENV_KEY]: HEADLESS_VALUE };
|
|
3504
|
+
}
|
|
3505
|
+
function is_headless(source = process.env) {
|
|
3506
|
+
return source[HEADLESS_ENV_KEY] === HEADLESS_VALUE;
|
|
3507
|
+
}
|
|
3508
|
+
function is_driving(read2) {
|
|
3509
|
+
return read2?.kind === "carried" && read2.carry.is_handed_off !== true;
|
|
3510
|
+
}
|
|
3511
|
+
async function read_carry_here() {
|
|
3512
|
+
const repository2 = await run_carry.repository_directory();
|
|
3513
|
+
return repository2 === void 0 ? void 0 : run_carry.read_carry(run_carry.carry_path(repository2));
|
|
3514
|
+
}
|
|
3515
|
+
async function must_keep_waiting(source = process.env) {
|
|
3516
|
+
const is_candidate2 = is_headless(source) && lane_child_marker.marked_issue(source) === void 0;
|
|
3517
|
+
if (!is_candidate2 || !await run_watcher_guard.has_lanes_in_flight()) return false;
|
|
3518
|
+
return is_driving(await read_carry_here());
|
|
3519
|
+
}
|
|
3520
|
+
async function current_carry() {
|
|
3521
|
+
const read2 = await read_carry_here();
|
|
3522
|
+
return read2?.kind === "carried" ? read2.carry : void 0;
|
|
3523
|
+
}
|
|
3524
|
+
function is_owned_here(carry, ancestry) {
|
|
3525
|
+
return carry.owner_pid !== void 0 && ancestry().has(carry.owner_pid);
|
|
3526
|
+
}
|
|
3527
|
+
function driven_here(read2, ancestry) {
|
|
3528
|
+
if (read2?.kind !== "carried" || !is_driving(read2)) return void 0;
|
|
3529
|
+
return is_owned_here(read2.carry, ancestry) ? read2.carry : void 0;
|
|
3530
|
+
}
|
|
3531
|
+
async function driving_carry(source = process.env, ancestry = lane_reap.own_ancestry) {
|
|
3532
|
+
if (lane_child_marker.marked_issue(source) !== void 0) return void 0;
|
|
3533
|
+
return driven_here(await read_carry_here(), ancestry);
|
|
3534
|
+
}
|
|
3535
|
+
async function is_backlog_parent(source = process.env, ancestry = lane_reap.own_ancestry) {
|
|
3536
|
+
return await driving_carry(source, ancestry) !== void 0;
|
|
3537
|
+
}
|
|
3538
|
+
var run_headless = {
|
|
3539
|
+
HEADLESS_ENV_KEY,
|
|
3540
|
+
current_carry,
|
|
3541
|
+
driving_carry,
|
|
3542
|
+
environment,
|
|
3543
|
+
is_backlog_parent,
|
|
3544
|
+
is_headless,
|
|
3545
|
+
is_owned_here,
|
|
3546
|
+
must_keep_waiting
|
|
3547
|
+
};
|
|
3548
|
+
|
|
3549
|
+
// scripts/issue/issue-cite.ts
|
|
3550
|
+
var GITHUB_URL_PREFIX = "https://github.com/";
|
|
3551
|
+
var ISSUE_PATH = "/issues/";
|
|
3552
|
+
var SUMMARY_SEPARATOR = " \u2014 ";
|
|
3553
|
+
var REPO_QUALIFIED = /^([^\s/#]+\/[^\s/#]+)#(\d+)$/u;
|
|
3554
|
+
var BARE_NUMBER = /^#?(\d+)$/u;
|
|
3555
|
+
function issue_url(slug, number) {
|
|
3556
|
+
return `${GITHUB_URL_PREFIX}${slug}${ISSUE_PATH}${number}`;
|
|
3557
|
+
}
|
|
3558
|
+
function citation_line(slug, number, summary) {
|
|
3559
|
+
return `[#${number}](${issue_url(slug, number)})${SUMMARY_SEPARATOR}${summary}`;
|
|
3560
|
+
}
|
|
3561
|
+
function citer(slug, titles) {
|
|
3562
|
+
return function cite(number) {
|
|
3563
|
+
if (slug === void 0) return `#${number}`;
|
|
3564
|
+
const title = titles.get(number);
|
|
3565
|
+
return title === void 0 ? `[#${number}](${issue_url(slug, number)})` : citation_line(slug, number, title);
|
|
3566
|
+
};
|
|
3567
|
+
}
|
|
3568
|
+
function qualified_target(token) {
|
|
3569
|
+
const match = REPO_QUALIFIED.exec(token);
|
|
3570
|
+
if (match === null) return void 0;
|
|
3571
|
+
const [, repo = "", number = ""] = match;
|
|
3572
|
+
return { number, repo };
|
|
3573
|
+
}
|
|
3574
|
+
function bare_target(token, default_repo) {
|
|
3575
|
+
const match = BARE_NUMBER.exec(token);
|
|
3576
|
+
if (match === null) return void 0;
|
|
3577
|
+
const [, number = ""] = match;
|
|
3578
|
+
return { number, repo: default_repo };
|
|
3579
|
+
}
|
|
3580
|
+
function parse_target(token, default_repo) {
|
|
3581
|
+
return qualified_target(token) ?? bare_target(token, default_repo);
|
|
3582
|
+
}
|
|
3583
|
+
function label(target) {
|
|
3584
|
+
return target.repo === void 0 ? `#${target.number}` : `${target.repo}#${target.number}`;
|
|
3585
|
+
}
|
|
3586
|
+
function missing_line(target) {
|
|
3587
|
+
return `\u2716 ${label(target)}: issue does not resolve \u2014 check the number and the repository`;
|
|
3588
|
+
}
|
|
3589
|
+
function unreadable_line(target) {
|
|
3590
|
+
return `\u2716 ${label(target)}: could not be read \u2014 a rate limit, expired auth, or a dropped connection`;
|
|
3591
|
+
}
|
|
3592
|
+
function no_repo_line(target) {
|
|
3593
|
+
return `\u2716 ${label(target)}: could not read this repository \u2014 check gh auth and the origin remote`;
|
|
3594
|
+
}
|
|
3595
|
+
var issue_cite = {
|
|
3596
|
+
SUMMARY_SEPARATOR,
|
|
3597
|
+
citation_line,
|
|
3598
|
+
citer,
|
|
3599
|
+
issue_url,
|
|
3600
|
+
label,
|
|
3601
|
+
missing_line,
|
|
3602
|
+
no_repo_line,
|
|
3603
|
+
parse_target,
|
|
3604
|
+
unreadable_line
|
|
3605
|
+
};
|
|
3606
|
+
|
|
3372
3607
|
// scripts/git/git-gh-api-path.ts
|
|
3373
3608
|
var FULL_PAGE_QUERY = "?per_page=100";
|
|
3374
3609
|
function repo_api_path(repo) {
|
|
@@ -3431,6 +3666,35 @@ var git_gh_api_path = {
|
|
|
3431
3666
|
commit_status_api_path
|
|
3432
3667
|
};
|
|
3433
3668
|
|
|
3669
|
+
// scripts/lib/error-message.ts
|
|
3670
|
+
function message_of(error) {
|
|
3671
|
+
return error instanceof Error ? error.message : String(error);
|
|
3672
|
+
}
|
|
3673
|
+
var error_text = { message_of };
|
|
3674
|
+
|
|
3675
|
+
// scripts/git/git-gh-exec.ts
|
|
3676
|
+
import { execa as execa5, execaSync as execaSync2 } from "execa";
|
|
3677
|
+
|
|
3678
|
+
// scripts/git/git-gh-check.ts
|
|
3679
|
+
import { execa as execa4 } from "execa";
|
|
3680
|
+
var GH_NOT_INSTALLED_MSG = "gh CLI is not installed. Install it from https://cli.github.com/";
|
|
3681
|
+
var gh_check = {};
|
|
3682
|
+
async function run_gh_check() {
|
|
3683
|
+
try {
|
|
3684
|
+
await execa4("gh", ["--version"]);
|
|
3685
|
+
} catch {
|
|
3686
|
+
delete gh_check.promise;
|
|
3687
|
+
throw new Error(GH_NOT_INSTALLED_MSG);
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
async function check_gh_installed() {
|
|
3691
|
+
gh_check.promise ??= run_gh_check();
|
|
3692
|
+
await gh_check.promise;
|
|
3693
|
+
}
|
|
3694
|
+
|
|
3695
|
+
// scripts/git/git-gh-failure.ts
|
|
3696
|
+
import { z as z7 } from "zod";
|
|
3697
|
+
|
|
3434
3698
|
// scripts/git/parse-json-array.ts
|
|
3435
3699
|
var MALFORMED_JSON = /* @__PURE__ */ Symbol("malformed-json");
|
|
3436
3700
|
function parse_json_loose(raw_json) {
|
|
@@ -3471,34 +3735,7 @@ var parse_json = {
|
|
|
3471
3735
|
read_json_listing
|
|
3472
3736
|
};
|
|
3473
3737
|
|
|
3474
|
-
// scripts/lib/error-message.ts
|
|
3475
|
-
function message_of(error) {
|
|
3476
|
-
return error instanceof Error ? error.message : String(error);
|
|
3477
|
-
}
|
|
3478
|
-
var error_text = { message_of };
|
|
3479
|
-
|
|
3480
|
-
// scripts/git/git-gh-exec.ts
|
|
3481
|
-
import { execa as execa4, execaSync as execaSync2 } from "execa";
|
|
3482
|
-
|
|
3483
|
-
// scripts/git/git-gh-check.ts
|
|
3484
|
-
import { execa as execa3 } from "execa";
|
|
3485
|
-
var GH_NOT_INSTALLED_MSG = "gh CLI is not installed. Install it from https://cli.github.com/";
|
|
3486
|
-
var gh_check = {};
|
|
3487
|
-
async function run_gh_check() {
|
|
3488
|
-
try {
|
|
3489
|
-
await execa3("gh", ["--version"]);
|
|
3490
|
-
} catch {
|
|
3491
|
-
delete gh_check.promise;
|
|
3492
|
-
throw new Error(GH_NOT_INSTALLED_MSG);
|
|
3493
|
-
}
|
|
3494
|
-
}
|
|
3495
|
-
async function check_gh_installed() {
|
|
3496
|
-
gh_check.promise ??= run_gh_check();
|
|
3497
|
-
await gh_check.promise;
|
|
3498
|
-
}
|
|
3499
|
-
|
|
3500
3738
|
// scripts/git/git-gh-failure.ts
|
|
3501
|
-
import { z as z7 } from "zod";
|
|
3502
3739
|
var error_document_schema = z7.object({ status: z7.union([z7.string(), z7.number()]).optional() }).catch({});
|
|
3503
3740
|
var GH_FAILURE_FIELD = "gh_failure";
|
|
3504
3741
|
function has_gh_failure(error) {
|
|
@@ -3568,7 +3805,7 @@ async function exec_gh_command(arguments_, timeout_ms, cwd) {
|
|
|
3568
3805
|
await check_gh_installed();
|
|
3569
3806
|
const options = to_spawn_options(timeout_ms, cwd);
|
|
3570
3807
|
try {
|
|
3571
|
-
const { stdout } = await
|
|
3808
|
+
const { stdout } = await execa5("gh", arguments_, options);
|
|
3572
3809
|
return stdout.trimEnd();
|
|
3573
3810
|
} catch (error) {
|
|
3574
3811
|
throw to_gh_error(error);
|
|
@@ -3578,7 +3815,7 @@ async function exec_gh_command_with_stdin(input) {
|
|
|
3578
3815
|
await check_gh_installed();
|
|
3579
3816
|
const options = { input: input.stdin_body, ...to_spawn_options(input.timeout_ms, input.cwd) };
|
|
3580
3817
|
try {
|
|
3581
|
-
const { stdout } = await
|
|
3818
|
+
const { stdout } = await execa5("gh", input.args, options);
|
|
3582
3819
|
return stdout.trimEnd();
|
|
3583
3820
|
} catch (error) {
|
|
3584
3821
|
throw to_gh_error(error);
|
|
@@ -3596,7 +3833,7 @@ async function exec_gh_api_status(path4, timeout_ms) {
|
|
|
3596
3833
|
const options = to_spawn_options(timeout_ms);
|
|
3597
3834
|
try {
|
|
3598
3835
|
await check_gh_installed();
|
|
3599
|
-
const { stdout } = await
|
|
3836
|
+
const { stdout } = await execa5("gh", ["api", "--include", "--silent", path4], options);
|
|
3600
3837
|
return parse_status_line(stdout);
|
|
3601
3838
|
} catch (error) {
|
|
3602
3839
|
return status_of_failure(error);
|
|
@@ -3677,6 +3914,7 @@ var git_gh_exec = {
|
|
|
3677
3914
|
export {
|
|
3678
3915
|
shell_segments,
|
|
3679
3916
|
bash_triggers,
|
|
3917
|
+
issue_cite,
|
|
3680
3918
|
run_progress_clock,
|
|
3681
3919
|
tail_commands,
|
|
3682
3920
|
filing_cap,
|
|
@@ -3686,7 +3924,6 @@ export {
|
|
|
3686
3924
|
agent_role_profile,
|
|
3687
3925
|
backlog_budget,
|
|
3688
3926
|
git_command,
|
|
3689
|
-
lane_child_invocation,
|
|
3690
3927
|
run_hold,
|
|
3691
3928
|
run_cut,
|
|
3692
3929
|
run_tail,
|
|
@@ -3706,6 +3943,12 @@ export {
|
|
|
3706
3943
|
lane_park,
|
|
3707
3944
|
repo_origin,
|
|
3708
3945
|
repo_party,
|
|
3946
|
+
process_identity,
|
|
3947
|
+
run_invocation,
|
|
3948
|
+
run_carry,
|
|
3949
|
+
lane_registry,
|
|
3950
|
+
run_watcher_guard,
|
|
3951
|
+
run_headless,
|
|
3709
3952
|
FULL_PAGE_QUERY,
|
|
3710
3953
|
git_gh_api_path,
|
|
3711
3954
|
error_text,
|
|
@@ -3714,10 +3957,5 @@ export {
|
|
|
3714
3957
|
parse_json_object_safe,
|
|
3715
3958
|
gh_failure,
|
|
3716
3959
|
has_stderr_field,
|
|
3717
|
-
git_gh_exec
|
|
3718
|
-
process_identity,
|
|
3719
|
-
lane_registry,
|
|
3720
|
-
run_invocation,
|
|
3721
|
-
run_carry,
|
|
3722
|
-
run_watcher_guard
|
|
3960
|
+
git_gh_exec
|
|
3723
3961
|
};
|