@joshuafolkken/kit 1.1094.0 → 1.1136.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/agents/investigator.md +17 -0
- package/.claude/settings.json +1 -0
- package/.claude/skills/workflow-commands/SKILL.md +1 -1
- package/.claude/skills/workflow-commands/background-commands.md +36 -85
- package/.claude/skills/workflow-commands/backlogrun-progress.md +31 -34
- package/.claude/skills/workflow-commands/backlogrun-steps.md +2 -2
- package/.claude/skills/workflow-commands/delegation.md +5 -1
- package/.claude/skills/workflow-commands/fullrun.md +5 -4
- package/.claude/skills/workflow-commands/halfrun.md +5 -4
- package/.claude/skills/workflow-commands/latest-gate.md +7 -15
- package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
- package/.claude/skills/workflow-commands/split-assessment.md +4 -18
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +4 -4
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +7 -8
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +1 -3
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +10 -9
- package/.github/workflows/sonar-qube.yml +17 -13
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +4 -11
- package/CLAUDE.md +24 -17
- package/GEMINI.md +4 -13
- package/README.md +8 -3
- package/SECURITY.md +2 -0
- package/cspell/index.yaml +4 -0
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +24 -17
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +33 -9
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-OIZUHPJI.js → chunk-FO2I7UT7.js} +1 -1
- package/dist/hooks/{chunk-NKOG3XAV.js → chunk-GDU26K3J.js} +11 -3
- package/dist/hooks/{chunk-O4LL4HTI.js → chunk-HANSKHES.js} +2 -2
- package/dist/hooks/{chunk-3C4YCCEF.js → chunk-HBKZLITF.js} +4 -4
- package/dist/hooks/{chunk-UD24EAIL.js → chunk-JKKTVDAG.js} +1984 -146
- package/dist/hooks/{chunk-M2XDCUKD.js → chunk-KBXZLMRH.js} +89 -1803
- package/dist/hooks/{chunk-IL27YTPH.js → chunk-KOKOAV6D.js} +2 -2
- package/dist/hooks/{chunk-7ZPFAVR7.js → chunk-LJBLGHEH.js} +59 -19
- package/dist/hooks/{chunk-E54KGFEQ.js → chunk-NFZGFGOR.js} +1 -1
- package/dist/hooks/{chunk-KHWHKJOM.js → chunk-RFWWUI5F.js} +4 -4
- package/dist/hooks/codex-hook-adapter.js +12 -47
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +175 -173
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/stop-guard.js +17 -12
- package/dist/josh.js +87 -31
- package/dist/version/index.js +36 -20
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +23 -5
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow.md +1 -0
- package/scripts/backlog/backlog-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -16
- package/scripts/backlog/backlog-offer-cli.ts +6 -14
- package/scripts/backlog/backlog-plan.ts +29 -18
- package/scripts/backlog/backlog-ready.ts +20 -7
- package/scripts/config-merge/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- package/scripts/cost-runtime/cost-cli.ts +3 -7
- package/scripts/delegation/delegation-policy.ts +9 -1
- package/scripts/delegation/investigation-guard.ts +1 -1
- package/scripts/delegation/investigation-reads.ts +105 -19
- package/scripts/doctor/doctor-consumer.ts +3 -5
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/capped-print.ts +74 -0
- package/scripts/document/document-byte-budget.ts +1 -0
- package/scripts/document/document-section-cli.ts +4 -3
- package/scripts/document/entry-read-budget.ts +13 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +7 -0
- package/scripts/document/read-set-point-of-use.ts +8 -3
- package/scripts/document/read-set-trim.ts +3 -1
- package/scripts/epic/epic-audit.ts +3 -18
- package/scripts/gate/scoped-green.ts +25 -14
- package/scripts/gh/git-gh-issue-list.ts +12 -11
- package/scripts/gh/git-gh-issue-write.ts +4 -1
- package/scripts/gh/git-gh-pr-auto-merge.ts +4 -1
- package/scripts/git/git-command.ts +6 -1
- package/scripts/git/git-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- package/scripts/git/stash/stash-pop-args.ts +1 -6
- package/scripts/init/claude-kit-only-settings.ts +29 -0
- package/scripts/init/init-copy-content.ts +8 -2
- package/scripts/init/init-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +6 -22
- package/scripts/init/init.ts +11 -68
- package/scripts/init/initial-commit.ts +24 -0
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +3 -6
- package/scripts/init/start-exec.ts +16 -3
- package/scripts/init/start-steps.ts +10 -13
- package/scripts/issue/defect-rate-cli.ts +61 -20
- package/scripts/issue/issue-backlinks.ts +7 -14
- package/scripts/issue/issue-cite.ts +12 -6
- package/scripts/issue/issue-file.ts +5 -12
- package/scripts/issue/issue-read-cli.ts +1 -0
- package/scripts/issue/issue-report-failures.ts +6 -2
- package/scripts/issue/issue-state-cli.ts +1 -1
- package/scripts/issue/markdown-section.ts +21 -6
- package/scripts/issue/measure-rerun-cli.ts +73 -14
- package/scripts/josh/josh-commands-lane.ts +1 -1
- package/scripts/josh/josh-commands-project.ts +8 -1
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/lane/lane-await.ts +89 -15
- package/scripts/lane/lane-cli.ts +11 -13
- package/scripts/lane/lane-close.ts +4 -1
- package/scripts/lane/lane-launch-cli.ts +10 -16
- package/scripts/lane/openai-review-broker.ts +4 -1
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- package/scripts/lines/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -3
- package/scripts/propagate/propagate-git.ts +3 -8
- package/scripts/refactor/refactor-scan.ts +2 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -19
- package/scripts/registry-migration/migrate.ts +6 -5
- package/scripts/release/github-release-cli.ts +14 -3
- package/scripts/release/github-release-environment.ts +1 -0
- package/scripts/release/github-release.ts +103 -17
- package/scripts/release/release-publish.ts +36 -2
- package/scripts/release/release-worktree.ts +97 -2
- package/scripts/review/review-checkout.ts +3 -2
- package/scripts/review/review-record-cli.ts +9 -16
- package/scripts/rules/early-heartbeat.ts +4 -3
- package/scripts/rules/lane-park.ts +9 -0
- package/scripts/rules/stop-rules.ts +7 -4
- package/scripts/run/run-carry-args.ts +8 -12
- package/scripts/run/run-carry-cli.ts +3 -1
- package/scripts/run/run-carry-conversation.ts +94 -0
- package/scripts/run/run-carry-reclaim.ts +37 -0
- package/scripts/run/run-carry.ts +21 -5
- package/scripts/run/run-cut-args.ts +1 -6
- package/scripts/run/run-ending-cli.ts +1 -5
- package/scripts/run/run-entry-cli.ts +40 -9
- package/scripts/run/run-entry-stop.ts +104 -0
- package/scripts/run/run-event-stream-emit.ts +7 -2
- package/scripts/run/run-hold.ts +4 -1
- package/scripts/run/run-liveness-cli.ts +1 -5
- package/scripts/run/run-merge-cli.ts +2 -10
- package/scripts/run/run-merge-steps.ts +4 -1
- package/scripts/run/run-parent-cut-hook.ts +4 -1
- package/scripts/run/run-prep-cli.ts +4 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +31 -29
- package/scripts/run/run-progress-clock.ts +4 -1
- package/scripts/run/run-ship-cli.ts +8 -16
- package/scripts/run/run-ship-probe.ts +4 -1
- package/scripts/run/run-status-cli.ts +2 -15
- package/scripts/run/run-tidy-lanes.ts +4 -1
- package/scripts/run/run-wake-cli.ts +2 -10
- package/scripts/run/run-watcher-guard.ts +9 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- package/scripts/sync/sync-ai-files.ts +4 -0
- package/scripts/test/test-declared-changed.ts +13 -16
- package/scripts/test/test-declared.ts +3 -7
- package/scripts/test/test-related.ts +1 -6
- package/scripts/test/test-unit-guard.ts +21 -7
- package/scripts/time-runtime/time-spans.ts +4 -0
- package/scripts/version/version-commands.ts +11 -1
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +1 -0
- package/templates/workflows/github-release.yml +14 -28
- package/tsconfig.sonar.json +4 -22
|
@@ -1,32 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ALREADY_DONE_LABEL,
|
|
3
|
-
BREAKING_CHANGE_LABEL,
|
|
4
|
-
BUGFIX_LABEL,
|
|
5
3
|
CONTEXT_CUT_THRESHOLD,
|
|
6
|
-
ENHANCEMENT_LABEL,
|
|
7
|
-
FULL_PAGE_QUERY,
|
|
8
4
|
IN_PROGRESS_LABEL,
|
|
9
5
|
NEEDS_DECISION_LABEL,
|
|
10
6
|
NEEDS_HUMAN_REVIEW_LABEL,
|
|
7
|
+
PORCELAIN_FLAG,
|
|
11
8
|
RECENT_REQUEST_WINDOW,
|
|
12
|
-
RELEASE_CLASSIFICATION_NAMES,
|
|
13
9
|
agent_role_profile,
|
|
14
|
-
agent_session_environment,
|
|
15
10
|
bash_triggers,
|
|
11
|
+
cli_flags,
|
|
16
12
|
error_text,
|
|
17
13
|
filing_cap,
|
|
18
|
-
gh_failure,
|
|
19
14
|
git_command,
|
|
20
15
|
git_common_directory,
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
git_gh_command,
|
|
17
|
+
git_gh_issue_read,
|
|
18
|
+
git_gh_pr_read,
|
|
19
|
+
git_spawn_sync,
|
|
23
20
|
has_any_label,
|
|
24
|
-
has_stderr_field,
|
|
25
21
|
issue_cite,
|
|
26
22
|
lane_background,
|
|
27
23
|
lane_park,
|
|
28
24
|
lane_registry,
|
|
29
|
-
|
|
25
|
+
open_issue_schema,
|
|
26
|
+
own_session,
|
|
30
27
|
parse_json_object_safe,
|
|
31
28
|
read_json_listing,
|
|
32
29
|
repo_origin,
|
|
@@ -38,31 +35,31 @@ import {
|
|
|
38
35
|
run_tail,
|
|
39
36
|
shell_segments,
|
|
40
37
|
tail_commands
|
|
41
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-JKKTVDAG.js";
|
|
42
39
|
import {
|
|
43
40
|
find_local_bin_upwards
|
|
44
41
|
} from "./chunk-3V37IID6.js";
|
|
45
42
|
import {
|
|
46
43
|
batch_outcome
|
|
47
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-KOKOAV6D.js";
|
|
48
45
|
import {
|
|
49
46
|
investigation_refusal
|
|
50
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-RFWWUI5F.js";
|
|
51
48
|
import {
|
|
52
49
|
duplicate_read_outcome
|
|
53
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-HBKZLITF.js";
|
|
54
51
|
import {
|
|
55
52
|
investigation_reads
|
|
56
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-LJBLGHEH.js";
|
|
57
54
|
import {
|
|
58
55
|
lane_guard_policy,
|
|
59
56
|
time_batch_guard
|
|
60
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-HANSKHES.js";
|
|
61
58
|
import {
|
|
62
59
|
hook_decision,
|
|
63
60
|
lane_child_marker,
|
|
64
61
|
run_issue_number
|
|
65
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-NFZGFGOR.js";
|
|
66
63
|
import {
|
|
67
64
|
PLATFORM_TEMP_ROOT,
|
|
68
65
|
cost_attribute,
|
|
@@ -74,7 +71,7 @@ import {
|
|
|
74
71
|
lane_paths,
|
|
75
72
|
stamp_file,
|
|
76
73
|
time_shell
|
|
77
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-GDU26K3J.js";
|
|
78
75
|
|
|
79
76
|
// scripts/rules/direct-filing.ts
|
|
80
77
|
var DIRECT_FILING_REASON = '\u26D4 direct filing: an Issue is filed with `pnpm josh issue:file "<title>" --body-file <path> --depth <0|1|2> [--route <route>] [--label <name>] [--repo <owner/repo>]`, never with `gh api \u2026/issues` or `gh issue create`. The command runs every filing step in order \u2014 the duplicate scout, the body lint and its classification labels, the depth and `route:` labels, the `## Origin` check when filing into another repository, and `epic:bundle` after the create \u2014 so none of them is a step to remember. When the scout prints candidates it holds the filing: read each, then reissue with `--distinct <N,\u2026>` for the ones that are separate deliverables. Reference: `docs/josh-commands-automation.md` \u2192 "`josh issue:file`". **This rule fires on every occurrence, not once per run.**';
|
|
@@ -298,7 +295,8 @@ function is_life_fresh(target, threshold_ms) {
|
|
|
298
295
|
try {
|
|
299
296
|
const pinged_ms = parse_pinged_at(raw);
|
|
300
297
|
return pinged_ms !== void 0 && Date.now() - pinged_ms < threshold_ms;
|
|
301
|
-
} catch {
|
|
298
|
+
} catch (error) {
|
|
299
|
+
error_text.trace_swallowed("run_progress_clock.is_life_fresh", error);
|
|
302
300
|
return false;
|
|
303
301
|
}
|
|
304
302
|
}
|
|
@@ -442,7 +440,7 @@ function decide(call, run2, can_record) {
|
|
|
442
440
|
if (can_record) ARM_RECORD.record(target, lands_ms);
|
|
443
441
|
return false;
|
|
444
442
|
}
|
|
445
|
-
var EARLY_HEARTBEAT_REASON =
|
|
443
|
+
var EARLY_HEARTBEAT_REASON = "\u26D4 early heartbeat: this call arms a wait timer of its own, and the progress clock is not yours to keep. `pnpm josh run:progress --wait` keeps it for you (`JOSH_PROGRESS_INTERVAL_MINUTES`, or `josh.progress_interval_minutes` in `package.json`, default 20 minutes): start it once in the background and it reports the five labelled lines to the run's event stream on its own, without waking you \u2014 relay nothing, and start it again only after it exits, which it does when newly runnable work arrives. Two timers armed at once is what produced reports 3\u20135 minutes apart on a 15-minute setting (joshuafolkken/kit#1570): a new one was armed on the turn a timer fired and again on the turn a child's completion woke the run, and `--mark` recorded each report without anything refusing the early ones. **An explicit ask is not a heartbeat**: if the person asked for progress now, run `pnpm josh run:progress --once`, which prints the five labelled lines whatever the clock says. If you are waiting on something rather than on a clock, wait on the thing itself \u2014 `pnpm josh followup` waits for CI. The procedure is `.claude/skills/workflow-commands/backlogrun.md` \u2192 \"Progress while the run is quiet\". **This rule fires on every early arm, not once per run**, so reissuing the same sleep will be refused again.";
|
|
446
444
|
var PROGRESS_NAMES = /* @__PURE__ */ new Set(["run:progress"]);
|
|
447
445
|
var WATCH_FLAG = /(?:^|\s)--(?:wait|once)(?=\s|$)/u;
|
|
448
446
|
function is_progress_watch_segment(segment) {
|
|
@@ -671,7 +669,6 @@ var git_force = {
|
|
|
671
669
|
|
|
672
670
|
// scripts/cost-runtime/cost-cli.ts
|
|
673
671
|
import { fileURLToPath } from "node:url";
|
|
674
|
-
import { parseArgs } from "node:util";
|
|
675
672
|
|
|
676
673
|
// scripts/cost-runtime/codex-usage.ts
|
|
677
674
|
import { globSync, readFileSync as readFileSync2 } from "node:fs";
|
|
@@ -896,25 +893,6 @@ var cost_verdict = {
|
|
|
896
893
|
report_over
|
|
897
894
|
};
|
|
898
895
|
|
|
899
|
-
// scripts/cost-runtime/own-session.ts
|
|
900
|
-
var NOT_FOUND = -1;
|
|
901
|
-
function session_id_of(environment) {
|
|
902
|
-
const value = environment[agent_session_environment.SESSION_ID_KEY];
|
|
903
|
-
return value === void 0 || value === "" ? void 0 : value;
|
|
904
|
-
}
|
|
905
|
-
function select_own_session(files, environment) {
|
|
906
|
-
const session_id = session_id_of(environment);
|
|
907
|
-
if (session_id === void 0) {
|
|
908
|
-
return { kind: "own", index: cost_transcript.latest_own_index(files) };
|
|
909
|
-
}
|
|
910
|
-
const index = files.findIndex((file) => file.session_id === session_id);
|
|
911
|
-
return index === NOT_FOUND ? { kind: "absent", session_id } : { kind: "own", index };
|
|
912
|
-
}
|
|
913
|
-
var own_session = {
|
|
914
|
-
session_id_of,
|
|
915
|
-
select_own_session
|
|
916
|
-
};
|
|
917
|
-
|
|
918
896
|
// scripts/cost-runtime/transcript-cwd.ts
|
|
919
897
|
import path3 from "node:path";
|
|
920
898
|
function resolve(target, cwd) {
|
|
@@ -958,12 +936,8 @@ var PARSE_ARGS_OPTIONS = {
|
|
|
958
936
|
path: { type: "string" }
|
|
959
937
|
};
|
|
960
938
|
function parse_options(argv) {
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
return to_options(values);
|
|
964
|
-
} catch {
|
|
965
|
-
return void 0;
|
|
966
|
-
}
|
|
939
|
+
const values = cli_flags.values_of(argv, PARSE_ARGS_OPTIONS);
|
|
940
|
+
return values === void 0 ? void 0 : to_options(values);
|
|
967
941
|
}
|
|
968
942
|
function report_empty(cwd, session_id) {
|
|
969
943
|
const searched = cost_transcript.searched_directories(cost_transcript.transcript_directories(cwd));
|
|
@@ -2026,16 +2000,10 @@ import path5 from "node:path";
|
|
|
2026
2000
|
import { existsSync as existsSync2 } from "node:fs";
|
|
2027
2001
|
import path4 from "node:path";
|
|
2028
2002
|
|
|
2029
|
-
// scripts/lib/spawn-exit.ts
|
|
2030
|
-
function read_spawn_stdout(result) {
|
|
2031
|
-
return result.stdout ?? "";
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
2003
|
// scripts/version/kit-descriptor.ts
|
|
2035
2004
|
var KIT_PACKAGE_NAME = "@joshuafolkken/kit";
|
|
2036
2005
|
|
|
2037
2006
|
// scripts/doctor/doctor-consumer.ts
|
|
2038
|
-
import { execaSync } from "execa";
|
|
2039
2007
|
import { z as z6 } from "zod";
|
|
2040
2008
|
var NODE_MODULES = "node_modules";
|
|
2041
2009
|
var SETTINGS_PATH = path4.join(".claude", "settings.json");
|
|
@@ -2077,11 +2045,9 @@ function is_plugin_declared(root) {
|
|
|
2077
2045
|
return parsed.success && parsed.data.enabledPlugins?.[PLUGIN_ID] === true;
|
|
2078
2046
|
}
|
|
2079
2047
|
function configured_hooks_path(root) {
|
|
2080
|
-
const
|
|
2081
|
-
reject: false,
|
|
2048
|
+
const value = git_spawn_sync.read(["-C", root, "config", "--get", "core.hooksPath"], {
|
|
2082
2049
|
timeout: GIT_TIMEOUT_MS
|
|
2083
2050
|
});
|
|
2084
|
-
const value = read_spawn_stdout(result).trim();
|
|
2085
2051
|
return value === "" ? void 0 : value;
|
|
2086
2052
|
}
|
|
2087
2053
|
function claude_md_state(root) {
|
|
@@ -2141,6 +2107,7 @@ function report_consumer_setup(root) {
|
|
|
2141
2107
|
var doctor_consumer = {
|
|
2142
2108
|
claude_md_line,
|
|
2143
2109
|
claude_md_state,
|
|
2110
|
+
configured_hooks_path,
|
|
2144
2111
|
hooks_path_line,
|
|
2145
2112
|
is_kit_consumer,
|
|
2146
2113
|
is_plugin_declared,
|
|
@@ -2543,9 +2510,6 @@ var shell_body_trigger = {
|
|
|
2543
2510
|
keeps_body_safe
|
|
2544
2511
|
};
|
|
2545
2512
|
|
|
2546
|
-
// scripts/test/test-declared-changed.ts
|
|
2547
|
-
import { execFileSync } from "node:child_process";
|
|
2548
|
-
|
|
2549
2513
|
// scripts/gate/project-checks.ts
|
|
2550
2514
|
import { existsSync as existsSync4, globSync as globSync2, readFileSync as readFileSync4 } from "node:fs";
|
|
2551
2515
|
import path7 from "node:path";
|
|
@@ -2553,7 +2517,6 @@ import path7 from "node:path";
|
|
|
2553
2517
|
// scripts/init/project-profile.ts
|
|
2554
2518
|
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync3 } from "node:fs";
|
|
2555
2519
|
import path6 from "node:path";
|
|
2556
|
-
import { execaSync as execaSync2 } from "execa";
|
|
2557
2520
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", ".svelte-kit"]);
|
|
2558
2521
|
var WEB_EXTENSIONS = /* @__PURE__ */ new Set([".html", ".css", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
2559
2522
|
var TYPESCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx"]);
|
|
@@ -2644,11 +2607,8 @@ function scan_files(root) {
|
|
|
2644
2607
|
return { has_web, has_typescript };
|
|
2645
2608
|
}
|
|
2646
2609
|
function has_github_remote(root) {
|
|
2647
|
-
const
|
|
2648
|
-
|
|
2649
|
-
reject: false
|
|
2650
|
-
});
|
|
2651
|
-
return result.exitCode === 0 && repo_origin.parse_origin_url(result.stdout) !== void 0;
|
|
2610
|
+
const url = git_spawn_sync.origin_url(root);
|
|
2611
|
+
return url !== void 0 && repo_origin.parse_origin_url(url) !== void 0;
|
|
2652
2612
|
}
|
|
2653
2613
|
function inspect_project(root, requested) {
|
|
2654
2614
|
const profile = resolve_profile(root, requested);
|
|
@@ -2874,15 +2834,9 @@ function path_of(line) {
|
|
|
2874
2834
|
return arrow === -1 ? body : body.slice(arrow + RENAME_ARROW.length);
|
|
2875
2835
|
}
|
|
2876
2836
|
function read_changed_paths_sync() {
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
2881
|
-
});
|
|
2882
|
-
return output.split("\n").filter((line) => line.length > STATUS_PREFIX_LENGTH).map((line) => path_of(line));
|
|
2883
|
-
} catch {
|
|
2884
|
-
return [];
|
|
2885
|
-
}
|
|
2837
|
+
const output = git_spawn_sync.run(["status", PORCELAIN_FLAG], { timeout: 0 });
|
|
2838
|
+
if (output.exit_code !== 0) return [];
|
|
2839
|
+
return output.stdout.split("\n").filter((line) => line.length > STATUS_PREFIX_LENGTH).map((line) => path_of(line));
|
|
2886
2840
|
}
|
|
2887
2841
|
var injected = {};
|
|
2888
2842
|
function source_paths() {
|
|
@@ -3344,1680 +3298,11 @@ var delivered_rules = {
|
|
|
3344
3298
|
};
|
|
3345
3299
|
|
|
3346
3300
|
// scripts/run/run-watcher-hook.ts
|
|
3347
|
-
import { z as
|
|
3301
|
+
import { z as z12 } from "zod";
|
|
3348
3302
|
|
|
3349
3303
|
// scripts/run/run-progress-read.ts
|
|
3350
3304
|
import { loadavg } from "node:os";
|
|
3351
3305
|
|
|
3352
|
-
// scripts/gh/git-gh-helpers.ts
|
|
3353
|
-
function parse_pr_state_string(result) {
|
|
3354
|
-
const trimmed = result.trim();
|
|
3355
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
3356
|
-
}
|
|
3357
|
-
function is_pr_already_exists_message(error_message) {
|
|
3358
|
-
return error_message.toLowerCase().includes("already exists");
|
|
3359
|
-
}
|
|
3360
|
-
function get_error_message_with_stderr(error) {
|
|
3361
|
-
if (!(error instanceof Error)) return String(error);
|
|
3362
|
-
if (has_stderr_field(error) && error.stderr.length > 0) return `${error.message}
|
|
3363
|
-
${error.stderr}`;
|
|
3364
|
-
return error.message;
|
|
3365
|
-
}
|
|
3366
|
-
function handle_pr_create_error(error) {
|
|
3367
|
-
const error_message = get_error_message_with_stderr(error);
|
|
3368
|
-
if (is_pr_already_exists_message(error_message)) {
|
|
3369
|
-
throw new Error("PR_ALREADY_EXISTS");
|
|
3370
|
-
}
|
|
3371
|
-
throw error;
|
|
3372
|
-
}
|
|
3373
|
-
var git_gh_helpers = {
|
|
3374
|
-
parse_pr_state_string,
|
|
3375
|
-
get_error_message_with_stderr,
|
|
3376
|
-
handle_pr_create_error
|
|
3377
|
-
};
|
|
3378
|
-
|
|
3379
|
-
// scripts/git/schemas.ts
|
|
3380
|
-
import { z as z8 } from "zod";
|
|
3381
|
-
var package_name_schema = z8.object({ name: z8.string().min(1) });
|
|
3382
|
-
var rollup_item_schema = z8.looseObject({
|
|
3383
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
|
|
3384
|
-
__typename: z8.string().optional(),
|
|
3385
|
-
state: z8.string().optional(),
|
|
3386
|
-
status: z8.string().optional(),
|
|
3387
|
-
conclusion: z8.string().optional(),
|
|
3388
|
-
name: z8.string().optional(),
|
|
3389
|
-
context: z8.string().optional()
|
|
3390
|
-
});
|
|
3391
|
-
var pr_raw_schema = z8.object({
|
|
3392
|
-
statusCheckRollup: z8.array(rollup_item_schema).optional(),
|
|
3393
|
-
mergeStateStatus: z8.string().optional(),
|
|
3394
|
-
reviewDecision: z8.string().optional()
|
|
3395
|
-
});
|
|
3396
|
-
var pull_comment_schema = z8.object({
|
|
3397
|
-
body: z8.string().optional(),
|
|
3398
|
-
html_url: z8.string().optional(),
|
|
3399
|
-
user: z8.object({ login: z8.string().optional() }).optional()
|
|
3400
|
-
});
|
|
3401
|
-
var ai_review_pull_comment_schema = z8.object({
|
|
3402
|
-
body: z8.string().optional(),
|
|
3403
|
-
url: z8.string().optional(),
|
|
3404
|
-
author: z8.object({ login: z8.string().optional() }).optional()
|
|
3405
|
-
});
|
|
3406
|
-
var pr_info_schema = z8.object({
|
|
3407
|
-
mergeable: z8.union([z8.boolean(), z8.string()]).nullable().optional(),
|
|
3408
|
-
mergeStateStatus: z8.string().nullable().optional(),
|
|
3409
|
-
state: z8.string().optional()
|
|
3410
|
-
});
|
|
3411
|
-
var epic_issue_schema = z8.object({
|
|
3412
|
-
number: z8.number(),
|
|
3413
|
-
body: z8.string().optional()
|
|
3414
|
-
});
|
|
3415
|
-
var blocking_issue_schema = z8.object({
|
|
3416
|
-
number: z8.number(),
|
|
3417
|
-
state: z8.string().optional(),
|
|
3418
|
-
repository_url: z8.string().optional()
|
|
3419
|
-
});
|
|
3420
|
-
var blocked_by_schema = z8.object({
|
|
3421
|
-
nodes: z8.array(blocking_issue_schema).default([]),
|
|
3422
|
-
totalCount: z8.number().optional()
|
|
3423
|
-
}).optional();
|
|
3424
|
-
var epic_child_schema = z8.object({
|
|
3425
|
-
state: z8.string().optional(),
|
|
3426
|
-
blockedBy: blocked_by_schema
|
|
3427
|
-
});
|
|
3428
|
-
var rest_comment_schema = z8.looseObject({
|
|
3429
|
-
body: z8.string().nullish(),
|
|
3430
|
-
html_url: z8.string().optional(),
|
|
3431
|
-
user: z8.looseObject({ login: z8.string().optional() }).nullish()
|
|
3432
|
-
});
|
|
3433
|
-
var issue_label_schema = z8.object({ name: z8.string() });
|
|
3434
|
-
var epic_subject_schema = z8.object({
|
|
3435
|
-
number: z8.number(),
|
|
3436
|
-
state: z8.string().optional(),
|
|
3437
|
-
labels: z8.array(issue_label_schema).optional(),
|
|
3438
|
-
body: z8.string().optional()
|
|
3439
|
-
});
|
|
3440
|
-
var open_issue_schema = z8.object({
|
|
3441
|
-
number: z8.number(),
|
|
3442
|
-
title: z8.string(),
|
|
3443
|
-
labels: z8.array(issue_label_schema).optional(),
|
|
3444
|
-
createdAt: z8.string(),
|
|
3445
|
-
blockedBy: blocked_by_schema
|
|
3446
|
-
});
|
|
3447
|
-
|
|
3448
|
-
// scripts/gh/git-gh-issue-rest.ts
|
|
3449
|
-
import { z as z9 } from "zod";
|
|
3450
|
-
|
|
3451
|
-
// scripts/gh/git-gh-rest-state.ts
|
|
3452
|
-
var MERGED_STATE = "MERGED";
|
|
3453
|
-
function to_gh_state(state) {
|
|
3454
|
-
return state?.toUpperCase();
|
|
3455
|
-
}
|
|
3456
|
-
|
|
3457
|
-
// scripts/gh/git-gh-issue-rest.ts
|
|
3458
|
-
var rest_issue_schema = z9.looseObject({
|
|
3459
|
-
number: z9.number(),
|
|
3460
|
-
issue_dependencies_summary: z9.looseObject({ total_blocked_by: z9.number().optional() }).nullish(),
|
|
3461
|
-
// Present only on a pull request, which this endpoint serves as readily as an issue.
|
|
3462
|
-
pull_request: z9.looseObject({ merged_at: z9.string().nullish() }).nullish()
|
|
3463
|
-
});
|
|
3464
|
-
var REPOSITORY_URL = /\/repos\/([\w.-]+\/[\w.-]+)$/u;
|
|
3465
|
-
var REPOSITORY_URL_GROUP = 1;
|
|
3466
|
-
var BLOCKED_BY_FIELD = "blockedBy";
|
|
3467
|
-
var BLOCKED_BY_COUNT_FIELD = "blocked_by_count";
|
|
3468
|
-
var STATE_FIELD = "state";
|
|
3469
|
-
var BODY_FIELD = "body";
|
|
3470
|
-
var FIELD_SEPARATOR = ",";
|
|
3471
|
-
var EMPTY_BODY = "";
|
|
3472
|
-
var REST_FIELD_NAMES = /* @__PURE__ */ new Map([
|
|
3473
|
-
["url", "html_url"],
|
|
3474
|
-
["createdAt", "created_at"]
|
|
3475
|
-
]);
|
|
3476
|
-
var NOT_AN_ISSUE_MESSAGE = "gh api answered something other than an issue object";
|
|
3477
|
-
var NOT_AN_ISSUE_LISTING_MESSAGE = "gh api answered something other than an issue listing";
|
|
3478
|
-
var NOT_A_BLOCKER_LISTING_MESSAGE = "gh api answered something other than a blocked-by listing";
|
|
3479
|
-
function rest_field_name(field) {
|
|
3480
|
-
return REST_FIELD_NAMES.get(field) ?? field;
|
|
3481
|
-
}
|
|
3482
|
-
function split_fields(fields) {
|
|
3483
|
-
return fields.split(FIELD_SEPARATOR).map((field) => field.trim()).filter((field) => field.length > 0);
|
|
3484
|
-
}
|
|
3485
|
-
function to_issue_state(rest, value) {
|
|
3486
|
-
if (typeof rest.pull_request?.merged_at === "string") return MERGED_STATE;
|
|
3487
|
-
return typeof value === "string" ? to_gh_state(value) : value;
|
|
3488
|
-
}
|
|
3489
|
-
function total_blocked_by(rest) {
|
|
3490
|
-
return rest.issue_dependencies_summary?.total_blocked_by;
|
|
3491
|
-
}
|
|
3492
|
-
function to_gh_field_value(field, rest) {
|
|
3493
|
-
if (field === BLOCKED_BY_COUNT_FIELD) return total_blocked_by(rest);
|
|
3494
|
-
const value = rest[rest_field_name(field)];
|
|
3495
|
-
if (field === STATE_FIELD) return to_issue_state(rest, value);
|
|
3496
|
-
return field === BODY_FIELD ? value ?? EMPTY_BODY : value;
|
|
3497
|
-
}
|
|
3498
|
-
function parse_rest_issue(rest_json) {
|
|
3499
|
-
const parsed = parse_json_object_safe(rest_json, rest_issue_schema);
|
|
3500
|
-
if (parsed === void 0) throw new Error(NOT_AN_ISSUE_MESSAGE);
|
|
3501
|
-
return parsed;
|
|
3502
|
-
}
|
|
3503
|
-
function is_pull_request(rest) {
|
|
3504
|
-
return rest.pull_request !== void 0 && rest.pull_request !== null;
|
|
3505
|
-
}
|
|
3506
|
-
function parse_rest_issues(rest_json) {
|
|
3507
|
-
const parsed = parse_json_array_or_undefined(rest_json, rest_issue_schema);
|
|
3508
|
-
if (parsed === void 0) throw new Error(NOT_AN_ISSUE_LISTING_MESSAGE);
|
|
3509
|
-
return parsed;
|
|
3510
|
-
}
|
|
3511
|
-
function empty_blocked_by() {
|
|
3512
|
-
return { nodes: [], totalCount: 0 };
|
|
3513
|
-
}
|
|
3514
|
-
function repo_of_url(repository_url) {
|
|
3515
|
-
const match = REPOSITORY_URL.exec(repository_url ?? "");
|
|
3516
|
-
return match?.[REPOSITORY_URL_GROUP];
|
|
3517
|
-
}
|
|
3518
|
-
function to_blocked_by(blockers_json, exact_total) {
|
|
3519
|
-
const parsed = parse_json_array_or_undefined(blockers_json, blocking_issue_schema);
|
|
3520
|
-
if (parsed === void 0) throw new Error(NOT_A_BLOCKER_LISTING_MESSAGE);
|
|
3521
|
-
const nodes = parsed.map((blocker) => ({ ...blocker, state: to_gh_state(blocker.state) }));
|
|
3522
|
-
return { nodes, totalCount: exact_total ?? nodes.length };
|
|
3523
|
-
}
|
|
3524
|
-
function to_gh_issue(rest, fields, blocked_by) {
|
|
3525
|
-
return Object.fromEntries(
|
|
3526
|
-
fields.map((field) => [
|
|
3527
|
-
field,
|
|
3528
|
-
field === BLOCKED_BY_FIELD ? blocked_by : to_gh_field_value(field, rest)
|
|
3529
|
-
])
|
|
3530
|
-
);
|
|
3531
|
-
}
|
|
3532
|
-
function to_field_text(value) {
|
|
3533
|
-
if (typeof value === "string") return value;
|
|
3534
|
-
return value === void 0 || value === null ? EMPTY_BODY : JSON.stringify(value);
|
|
3535
|
-
}
|
|
3536
|
-
var CLOSED = "CLOSED";
|
|
3537
|
-
function reference_of_blocker(node, fallback_repo) {
|
|
3538
|
-
const repo = repo_of_url(node.repository_url) ?? fallback_repo;
|
|
3539
|
-
if (node.state === void 0) return { repo, number: node.number };
|
|
3540
|
-
return { repo, number: node.number, state: node.state.toUpperCase() === CLOSED ? CLOSED : "OPEN" };
|
|
3541
|
-
}
|
|
3542
|
-
var git_gh_issue_rest = {
|
|
3543
|
-
empty_blocked_by,
|
|
3544
|
-
repo_of_url,
|
|
3545
|
-
reference_of_blocker,
|
|
3546
|
-
split_fields,
|
|
3547
|
-
is_pull_request,
|
|
3548
|
-
parse_rest_issue,
|
|
3549
|
-
parse_rest_issues,
|
|
3550
|
-
total_blocked_by,
|
|
3551
|
-
to_blocked_by,
|
|
3552
|
-
to_gh_issue,
|
|
3553
|
-
to_field_text
|
|
3554
|
-
};
|
|
3555
|
-
|
|
3556
|
-
// scripts/gh/git-gh-reachability.ts
|
|
3557
|
-
var RATE_LIMITED_STATUS = 429;
|
|
3558
|
-
var SERVER_ERROR_FLOOR = 500;
|
|
3559
|
-
function is_retryable_status(status) {
|
|
3560
|
-
if (status >= SERVER_ERROR_FLOOR) return true;
|
|
3561
|
-
return status === RATE_LIMITED_STATUS;
|
|
3562
|
-
}
|
|
3563
|
-
function classify_status(status) {
|
|
3564
|
-
if (status === void 0) return "unreachable";
|
|
3565
|
-
return is_retryable_status(status) ? "unreachable" : "reachable";
|
|
3566
|
-
}
|
|
3567
|
-
var gh_reachability = { classify_status };
|
|
3568
|
-
|
|
3569
|
-
// scripts/gh/git-gh-issue-read.ts
|
|
3570
|
-
async function read_blocked_by_listing(issue_number, repo, exact_total) {
|
|
3571
|
-
const json = await git_gh_exec.exec_gh_api({
|
|
3572
|
-
path: `${git_gh_api_path.blocked_by_api_path(issue_number, repo)}${git_gh_api_path.FULL_PAGE_QUERY}`
|
|
3573
|
-
});
|
|
3574
|
-
return git_gh_issue_rest.to_blocked_by(json, exact_total);
|
|
3575
|
-
}
|
|
3576
|
-
async function read_blocked_by(issue_number, rest, repo) {
|
|
3577
|
-
if (git_gh_issue_rest.is_pull_request(rest)) return git_gh_issue_rest.empty_blocked_by();
|
|
3578
|
-
const exact_total = git_gh_issue_rest.total_blocked_by(rest);
|
|
3579
|
-
if (exact_total === 0) return git_gh_issue_rest.empty_blocked_by();
|
|
3580
|
-
return await read_blocked_by_listing(issue_number, repo, exact_total);
|
|
3581
|
-
}
|
|
3582
|
-
function mark_followup(error) {
|
|
3583
|
-
if (!(error instanceof Error)) return error;
|
|
3584
|
-
const failure = gh_failure.failure_of(error);
|
|
3585
|
-
if (failure === void 0) return error;
|
|
3586
|
-
return gh_failure.attach(error, { ...failure, is_followup: true });
|
|
3587
|
-
}
|
|
3588
|
-
async function read_relations(issue_number, rest, repo) {
|
|
3589
|
-
try {
|
|
3590
|
-
return await read_blocked_by(issue_number, rest, repo);
|
|
3591
|
-
} catch (error) {
|
|
3592
|
-
throw mark_followup(error);
|
|
3593
|
-
}
|
|
3594
|
-
}
|
|
3595
|
-
async function read_issue_fields(issue_number, fields, repo) {
|
|
3596
|
-
const rest = git_gh_issue_rest.parse_rest_issue(
|
|
3597
|
-
await git_gh_exec.exec_gh_api({ path: git_gh_api_path.issue_api_path(issue_number, repo) })
|
|
3598
|
-
);
|
|
3599
|
-
const requested = git_gh_issue_rest.split_fields(fields);
|
|
3600
|
-
const blocked_by = requested.includes(BLOCKED_BY_FIELD) ? await read_relations(issue_number, rest, repo) : void 0;
|
|
3601
|
-
return git_gh_issue_rest.to_gh_issue(rest, requested, blocked_by);
|
|
3602
|
-
}
|
|
3603
|
-
var NOT_FOUND_STATUS = 404;
|
|
3604
|
-
function is_number_unresolved(failure) {
|
|
3605
|
-
return failure.status === NOT_FOUND_STATUS && failure.is_followup !== true;
|
|
3606
|
-
}
|
|
3607
|
-
function to_unreadable_reason(status) {
|
|
3608
|
-
return gh_reachability.classify_status(status) === "unreachable" ? "unreachable" : "rejected";
|
|
3609
|
-
}
|
|
3610
|
-
function to_read_failure(error) {
|
|
3611
|
-
const failure = gh_failure.failure_of(error);
|
|
3612
|
-
if (failure === void 0) return { kind: "unreadable", reason: "malformed", status: void 0 };
|
|
3613
|
-
if (is_number_unresolved(failure)) return { kind: "missing" };
|
|
3614
|
-
return {
|
|
3615
|
-
kind: "unreadable",
|
|
3616
|
-
reason: to_unreadable_reason(failure.status),
|
|
3617
|
-
status: failure.status
|
|
3618
|
-
};
|
|
3619
|
-
}
|
|
3620
|
-
async function issue_view_json_classified(issue_number, fields, repo) {
|
|
3621
|
-
try {
|
|
3622
|
-
const issue = await read_issue_fields(issue_number, fields, repo);
|
|
3623
|
-
return { kind: "read", json: JSON.stringify(issue) };
|
|
3624
|
-
} catch (error) {
|
|
3625
|
-
return to_read_failure(error);
|
|
3626
|
-
}
|
|
3627
|
-
}
|
|
3628
|
-
async function issue_view_field_classified(issue_number, field, repo) {
|
|
3629
|
-
try {
|
|
3630
|
-
const issue = await read_issue_fields(issue_number, field, repo);
|
|
3631
|
-
return { kind: "read", text: git_gh_issue_rest.to_field_text(issue[field]) };
|
|
3632
|
-
} catch (error) {
|
|
3633
|
-
return to_read_failure(error);
|
|
3634
|
-
}
|
|
3635
|
-
}
|
|
3636
|
-
async function issue_view_field(issue_number, field, repo) {
|
|
3637
|
-
const read2 = await issue_view_field_classified(issue_number, field, repo);
|
|
3638
|
-
return read2.kind === "read" ? read2.text : void 0;
|
|
3639
|
-
}
|
|
3640
|
-
async function issue_get_title(issue_number, repo) {
|
|
3641
|
-
const result = await issue_view_field(issue_number, "title", repo);
|
|
3642
|
-
return result === void 0 ? void 0 : git_gh_helpers.parse_pr_state_string(result);
|
|
3643
|
-
}
|
|
3644
|
-
async function issue_get_body(issue_number, repo) {
|
|
3645
|
-
return await issue_view_field(issue_number, "body", repo);
|
|
3646
|
-
}
|
|
3647
|
-
async function issue_get_body_classified(issue_number, repo) {
|
|
3648
|
-
return await issue_view_field_classified(issue_number, "body", repo);
|
|
3649
|
-
}
|
|
3650
|
-
async function issue_view_json(issue_number, fields, repo) {
|
|
3651
|
-
const read2 = await issue_view_json_classified(issue_number, fields, repo);
|
|
3652
|
-
return read2.kind === "read" ? read2.json : void 0;
|
|
3653
|
-
}
|
|
3654
|
-
var STATE_AND_RELATIONS_FIELDS = "number,state,labels,blockedBy";
|
|
3655
|
-
async function issue_get_state_and_relations(issue_number, repo) {
|
|
3656
|
-
return await issue_view_json(issue_number, STATE_AND_RELATIONS_FIELDS, repo);
|
|
3657
|
-
}
|
|
3658
|
-
async function issue_get_state_and_relations_classified(issue_number, repo) {
|
|
3659
|
-
return await issue_view_json_classified(issue_number, STATE_AND_RELATIONS_FIELDS, repo);
|
|
3660
|
-
}
|
|
3661
|
-
function is_unreachable_read(failure) {
|
|
3662
|
-
return failure.kind === "unreadable" && failure.reason === "unreachable";
|
|
3663
|
-
}
|
|
3664
|
-
var PLAN_FIELDS = "number,title,body,state,url,labels,blockedBy";
|
|
3665
|
-
async function issue_get_plan_fields(issue_number) {
|
|
3666
|
-
return await issue_view_json(issue_number, PLAN_FIELDS);
|
|
3667
|
-
}
|
|
3668
|
-
async function issue_get_plan_fields_classified(issue_number) {
|
|
3669
|
-
return await issue_view_json_classified(issue_number, PLAN_FIELDS);
|
|
3670
|
-
}
|
|
3671
|
-
async function issue_get_labels_and_body(issue_number) {
|
|
3672
|
-
return await issue_view_json(issue_number, "number,state,labels,body");
|
|
3673
|
-
}
|
|
3674
|
-
async function issue_list_comments(issue_number) {
|
|
3675
|
-
const path10 = `${git_gh_api_path.issue_comments_api_path(issue_number)}${git_gh_api_path.FULL_PAGE_QUERY}`;
|
|
3676
|
-
try {
|
|
3677
|
-
return await git_gh_exec.exec_gh_api({ path: path10, should_paginate: true });
|
|
3678
|
-
} catch {
|
|
3679
|
-
return void 0;
|
|
3680
|
-
}
|
|
3681
|
-
}
|
|
3682
|
-
async function has_no_relations_endpoint(issue_number, repo) {
|
|
3683
|
-
const status = await git_gh_exec.exec_gh_api_status(
|
|
3684
|
-
git_gh_api_path.blocked_by_api_path(issue_number, repo)
|
|
3685
|
-
);
|
|
3686
|
-
return status === NOT_FOUND_STATUS;
|
|
3687
|
-
}
|
|
3688
|
-
async function issue_blocked_by_references(issue_number, own_repo, repo) {
|
|
3689
|
-
try {
|
|
3690
|
-
const listing = await read_blocked_by_listing(issue_number, repo);
|
|
3691
|
-
return listing.nodes.map((blocker) => git_gh_issue_rest.reference_of_blocker(blocker, own_repo));
|
|
3692
|
-
} catch (error) {
|
|
3693
|
-
if (await has_no_relations_endpoint(issue_number, repo)) return [];
|
|
3694
|
-
throw error;
|
|
3695
|
-
}
|
|
3696
|
-
}
|
|
3697
|
-
async function issue_blocked_by_numbers(issue_number, repo) {
|
|
3698
|
-
const references = await issue_blocked_by_references(issue_number, "", repo);
|
|
3699
|
-
return references.map((blocker) => blocker.number);
|
|
3700
|
-
}
|
|
3701
|
-
var git_gh_issue_read = {
|
|
3702
|
-
issue_blocked_by_numbers,
|
|
3703
|
-
issue_blocked_by_references,
|
|
3704
|
-
issue_get_title,
|
|
3705
|
-
issue_get_body,
|
|
3706
|
-
issue_get_body_classified,
|
|
3707
|
-
issue_view_json,
|
|
3708
|
-
issue_view_json_classified,
|
|
3709
|
-
issue_get_state_and_relations,
|
|
3710
|
-
issue_get_state_and_relations_classified,
|
|
3711
|
-
is_unreachable_read,
|
|
3712
|
-
issue_get_plan_fields,
|
|
3713
|
-
issue_get_plan_fields_classified,
|
|
3714
|
-
issue_get_labels_and_body,
|
|
3715
|
-
issue_list_comments
|
|
3716
|
-
};
|
|
3717
|
-
|
|
3718
|
-
// scripts/gh/git-gh-issue-list.ts
|
|
3719
|
-
var PER_PAGE = 100;
|
|
3720
|
-
var FIRST_PAGE = 1;
|
|
3721
|
-
var DEFAULT_STATE = "open";
|
|
3722
|
-
var DEFAULT_SORT = "created";
|
|
3723
|
-
var LISTING_DIRECTION = "direction=desc";
|
|
3724
|
-
function listing_query(request) {
|
|
3725
|
-
const state = request.state ?? DEFAULT_STATE;
|
|
3726
|
-
const sort = request.sort ?? DEFAULT_SORT;
|
|
3727
|
-
return `state=${state}&sort=${sort}&${LISTING_DIRECTION}`;
|
|
3728
|
-
}
|
|
3729
|
-
function listing_path(request, page) {
|
|
3730
|
-
const label = request.label === void 0 ? "" : `&labels=${encodeURIComponent(request.label)}`;
|
|
3731
|
-
const paging = `&per_page=${String(PER_PAGE)}&page=${String(page)}`;
|
|
3732
|
-
return `${git_gh_api_path.issues_api_path(request.repo)}?${listing_query(request)}${label}${paging}`;
|
|
3733
|
-
}
|
|
3734
|
-
var DIGIT_PATTERN = /\d/u;
|
|
3735
|
-
function has_token_occurrence(body, term) {
|
|
3736
|
-
let index = body.indexOf(term);
|
|
3737
|
-
while (index !== -1) {
|
|
3738
|
-
if (!DIGIT_PATTERN.test(body.charAt(index + term.length))) return true;
|
|
3739
|
-
index = body.indexOf(term, index + 1);
|
|
3740
|
-
}
|
|
3741
|
-
return false;
|
|
3742
|
-
}
|
|
3743
|
-
function matches_body(rest, term) {
|
|
3744
|
-
if (term === void 0) return true;
|
|
3745
|
-
const { body } = rest;
|
|
3746
|
-
return typeof body === "string" && has_token_occurrence(body, term);
|
|
3747
|
-
}
|
|
3748
|
-
function is_selected(rest, request) {
|
|
3749
|
-
return !git_gh_issue_rest.is_pull_request(rest) && matches_body(rest, request.body_term);
|
|
3750
|
-
}
|
|
3751
|
-
async function fetch_page(request, page) {
|
|
3752
|
-
const path10 = listing_path(request, page);
|
|
3753
|
-
const rows = git_gh_issue_rest.parse_rest_issues(await git_gh_exec.exec_gh_api({ path: path10 }));
|
|
3754
|
-
return {
|
|
3755
|
-
selected: rows.filter((row) => is_selected(row, request)),
|
|
3756
|
-
is_full: rows.length >= PER_PAGE
|
|
3757
|
-
};
|
|
3758
|
-
}
|
|
3759
|
-
var MAX_PAGES = 5;
|
|
3760
|
-
var MAX_SCANNED = MAX_PAGES * PER_PAGE;
|
|
3761
|
-
function wants_more(has_more, selected_count, limit) {
|
|
3762
|
-
return has_more && selected_count < limit;
|
|
3763
|
-
}
|
|
3764
|
-
async function fetch_selected(request) {
|
|
3765
|
-
const selected = [];
|
|
3766
|
-
let page = FIRST_PAGE;
|
|
3767
|
-
let has_more = true;
|
|
3768
|
-
while (page <= MAX_PAGES && wants_more(has_more, selected.length, request.limit)) {
|
|
3769
|
-
const result = await fetch_page(request, page);
|
|
3770
|
-
selected.push(...result.selected);
|
|
3771
|
-
has_more = result.is_full;
|
|
3772
|
-
page += 1;
|
|
3773
|
-
}
|
|
3774
|
-
return {
|
|
3775
|
-
rows: selected.slice(0, request.limit),
|
|
3776
|
-
is_capped: wants_more(has_more, selected.length, request.limit)
|
|
3777
|
-
};
|
|
3778
|
-
}
|
|
3779
|
-
async function read_relations2(rows, repo) {
|
|
3780
|
-
const relations = [];
|
|
3781
|
-
for (const row of rows) {
|
|
3782
|
-
relations.push(await read_blocked_by(String(row.number), row, repo));
|
|
3783
|
-
}
|
|
3784
|
-
return relations;
|
|
3785
|
-
}
|
|
3786
|
-
async function issue_list(request) {
|
|
3787
|
-
try {
|
|
3788
|
-
const { rows, is_capped } = await fetch_selected(request);
|
|
3789
|
-
const fields = git_gh_issue_rest.split_fields(request.json_fields);
|
|
3790
|
-
const relations = fields.includes(BLOCKED_BY_FIELD) ? await read_relations2(rows, request.repo) : void 0;
|
|
3791
|
-
const mapped = rows.map(
|
|
3792
|
-
(row, index) => git_gh_issue_rest.to_gh_issue(row, fields, relations?.[index])
|
|
3793
|
-
);
|
|
3794
|
-
return { json: JSON.stringify(mapped), is_capped };
|
|
3795
|
-
} catch {
|
|
3796
|
-
return { json: void 0, is_capped: false };
|
|
3797
|
-
}
|
|
3798
|
-
}
|
|
3799
|
-
var git_gh_issue_list = {
|
|
3800
|
-
issue_list
|
|
3801
|
-
};
|
|
3802
|
-
|
|
3803
|
-
// scripts/gh/git-gh-issue-write.ts
|
|
3804
|
-
var PATCH_METHOD = "PATCH";
|
|
3805
|
-
var DELETE_METHOD2 = "DELETE";
|
|
3806
|
-
var HTML_URL_FILTER = ".html_url";
|
|
3807
|
-
var ID_FILTER = ".id";
|
|
3808
|
-
var LABELS_SEGMENT = "/labels";
|
|
3809
|
-
var COMMENTS_SEGMENT = "/comments";
|
|
3810
|
-
var CLOSED_STATE = "closed";
|
|
3811
|
-
var COLOR_HASH = "#";
|
|
3812
|
-
async function did_write_succeed(write) {
|
|
3813
|
-
try {
|
|
3814
|
-
await write();
|
|
3815
|
-
return true;
|
|
3816
|
-
} catch {
|
|
3817
|
-
return false;
|
|
3818
|
-
}
|
|
3819
|
-
}
|
|
3820
|
-
async function issue_edit_body(issue_number, body) {
|
|
3821
|
-
return await git_gh_exec.exec_gh_api({
|
|
3822
|
-
path: git_gh_api_path.issue_api_path(issue_number),
|
|
3823
|
-
method: PATCH_METHOD,
|
|
3824
|
-
body: JSON.stringify({ body }),
|
|
3825
|
-
jq_filter: HTML_URL_FILTER
|
|
3826
|
-
});
|
|
3827
|
-
}
|
|
3828
|
-
async function issue_comment(issue_number, body) {
|
|
3829
|
-
return await git_gh_exec.exec_gh_api({
|
|
3830
|
-
path: `${git_gh_api_path.issue_api_path(issue_number)}${COMMENTS_SEGMENT}`,
|
|
3831
|
-
body: JSON.stringify({ body }),
|
|
3832
|
-
jq_filter: HTML_URL_FILTER
|
|
3833
|
-
});
|
|
3834
|
-
}
|
|
3835
|
-
async function issue_try_comment(issue_number, body) {
|
|
3836
|
-
return await did_write_succeed(async () => await issue_comment(issue_number, body));
|
|
3837
|
-
}
|
|
3838
|
-
async function issue_close(issue_number, comment) {
|
|
3839
|
-
return await did_write_succeed(async () => {
|
|
3840
|
-
if (comment !== void 0) await issue_comment(issue_number, comment);
|
|
3841
|
-
await git_gh_exec.exec_gh_api({
|
|
3842
|
-
path: git_gh_api_path.issue_api_path(issue_number),
|
|
3843
|
-
method: PATCH_METHOD,
|
|
3844
|
-
body: JSON.stringify({ state: CLOSED_STATE })
|
|
3845
|
-
});
|
|
3846
|
-
});
|
|
3847
|
-
}
|
|
3848
|
-
function to_label_color(color) {
|
|
3849
|
-
return color.startsWith(COLOR_HASH) ? color.slice(COLOR_HASH.length) : color;
|
|
3850
|
-
}
|
|
3851
|
-
async function label_ensure(input) {
|
|
3852
|
-
try {
|
|
3853
|
-
await git_gh_exec.exec_gh_api({
|
|
3854
|
-
path: `${git_gh_api_path.repo_api_path()}${LABELS_SEGMENT}`,
|
|
3855
|
-
body: JSON.stringify({
|
|
3856
|
-
name: input.name,
|
|
3857
|
-
color: to_label_color(input.color),
|
|
3858
|
-
description: input.description
|
|
3859
|
-
})
|
|
3860
|
-
});
|
|
3861
|
-
} catch {
|
|
3862
|
-
}
|
|
3863
|
-
}
|
|
3864
|
-
function issue_create_request(input) {
|
|
3865
|
-
const { labels } = input;
|
|
3866
|
-
return {
|
|
3867
|
-
path: git_gh_api_path.issues_api_path(input.repo),
|
|
3868
|
-
body: JSON.stringify({
|
|
3869
|
-
title: input.title,
|
|
3870
|
-
...labels !== void 0 && { labels },
|
|
3871
|
-
body: input.body
|
|
3872
|
-
}),
|
|
3873
|
-
jq_filter: HTML_URL_FILTER
|
|
3874
|
-
};
|
|
3875
|
-
}
|
|
3876
|
-
async function issue_create_with_label(input) {
|
|
3877
|
-
return await git_gh_exec.exec_gh_api(
|
|
3878
|
-
issue_create_request({ title: input.title, body: input.body, labels: [input.label] })
|
|
3879
|
-
);
|
|
3880
|
-
}
|
|
3881
|
-
async function issue_add_label(issue_number, label) {
|
|
3882
|
-
return await did_write_succeed(
|
|
3883
|
-
async () => await git_gh_exec.exec_gh_api({
|
|
3884
|
-
path: `${git_gh_api_path.issue_api_path(issue_number)}${LABELS_SEGMENT}`,
|
|
3885
|
-
body: JSON.stringify({ labels: [label] })
|
|
3886
|
-
})
|
|
3887
|
-
);
|
|
3888
|
-
}
|
|
3889
|
-
async function issue_remove_label(issue_number, label) {
|
|
3890
|
-
const labels_path = `${git_gh_api_path.issue_api_path(issue_number)}${LABELS_SEGMENT}`;
|
|
3891
|
-
await git_gh_exec.exec_gh_api({
|
|
3892
|
-
path: `${labels_path}/${encodeURIComponent(label)}`,
|
|
3893
|
-
method: DELETE_METHOD2
|
|
3894
|
-
});
|
|
3895
|
-
}
|
|
3896
|
-
async function read_issue_id(issue_number) {
|
|
3897
|
-
const raw = await git_gh_exec.exec_gh_api({
|
|
3898
|
-
path: git_gh_api_path.issue_api_path(issue_number),
|
|
3899
|
-
jq_filter: ID_FILTER
|
|
3900
|
-
});
|
|
3901
|
-
const issue_id = Number(raw.trim());
|
|
3902
|
-
if (!Number.isSafeInteger(issue_id) || issue_id <= 0) {
|
|
3903
|
-
throw new Error(`gh api answered no database id for issue #${issue_number}`);
|
|
3904
|
-
}
|
|
3905
|
-
return issue_id;
|
|
3906
|
-
}
|
|
3907
|
-
async function issue_add_blocked_by(issue_number, blocker) {
|
|
3908
|
-
return await did_write_succeed(async () => {
|
|
3909
|
-
const issue_id = await read_issue_id(blocker);
|
|
3910
|
-
await git_gh_exec.exec_gh_api({
|
|
3911
|
-
path: git_gh_api_path.blocked_by_api_path(issue_number),
|
|
3912
|
-
body: JSON.stringify({ issue_id })
|
|
3913
|
-
});
|
|
3914
|
-
});
|
|
3915
|
-
}
|
|
3916
|
-
async function issue_remove_blocked_by(issue_number, blocker) {
|
|
3917
|
-
return await did_write_succeed(async () => {
|
|
3918
|
-
const issue_id = await read_issue_id(blocker);
|
|
3919
|
-
const relations_path = git_gh_api_path.blocked_by_api_path(issue_number);
|
|
3920
|
-
await git_gh_exec.exec_gh_api({
|
|
3921
|
-
path: `${relations_path}/${String(issue_id)}`,
|
|
3922
|
-
method: DELETE_METHOD2
|
|
3923
|
-
});
|
|
3924
|
-
});
|
|
3925
|
-
}
|
|
3926
|
-
var git_gh_issue_write = {
|
|
3927
|
-
issue_edit_body,
|
|
3928
|
-
issue_comment,
|
|
3929
|
-
issue_try_comment,
|
|
3930
|
-
issue_close,
|
|
3931
|
-
label_ensure,
|
|
3932
|
-
issue_create_request,
|
|
3933
|
-
issue_create_with_label,
|
|
3934
|
-
issue_add_label,
|
|
3935
|
-
issue_remove_label,
|
|
3936
|
-
issue_add_blocked_by,
|
|
3937
|
-
issue_remove_blocked_by
|
|
3938
|
-
};
|
|
3939
|
-
|
|
3940
|
-
// scripts/gh/git-gh-issue.ts
|
|
3941
|
-
var NUMBER_AND_BODY_FIELDS = "number,body";
|
|
3942
|
-
var BACKLOG_SCAN_FIELDS = `number,title,body,${BLOCKED_BY_COUNT_FIELD}`;
|
|
3943
|
-
var NUMBER_TITLE_AND_LABELS_FIELDS = "number,title,labels";
|
|
3944
|
-
var SUMMARY_FIELDS = "number,title,labels,createdAt";
|
|
3945
|
-
var PICKUP_FIELDS = `${SUMMARY_FIELDS},blockedBy`;
|
|
3946
|
-
var { issue_list: issue_list2 } = git_gh_issue_list;
|
|
3947
|
-
async function issue_list_recent(limit) {
|
|
3948
|
-
return await issue_list2({ json_fields: SUMMARY_FIELDS, limit });
|
|
3949
|
-
}
|
|
3950
|
-
async function issue_list_open_bodies(limit) {
|
|
3951
|
-
return await issue_list2({ json_fields: BACKLOG_SCAN_FIELDS, limit });
|
|
3952
|
-
}
|
|
3953
|
-
async function issue_list_recently_closed(limit) {
|
|
3954
|
-
return await issue_list2({
|
|
3955
|
-
json_fields: NUMBER_TITLE_AND_LABELS_FIELDS,
|
|
3956
|
-
limit,
|
|
3957
|
-
state: "closed",
|
|
3958
|
-
sort: "updated"
|
|
3959
|
-
});
|
|
3960
|
-
}
|
|
3961
|
-
async function issue_search_body(term, limit) {
|
|
3962
|
-
return await issue_list2({
|
|
3963
|
-
json_fields: NUMBER_AND_BODY_FIELDS,
|
|
3964
|
-
limit,
|
|
3965
|
-
body_term: term
|
|
3966
|
-
});
|
|
3967
|
-
}
|
|
3968
|
-
async function issue_list_by_label(label, limit) {
|
|
3969
|
-
return await issue_list2({ json_fields: NUMBER_AND_BODY_FIELDS, limit, label });
|
|
3970
|
-
}
|
|
3971
|
-
async function issue_list_by_label_summary(label, limit, options) {
|
|
3972
|
-
return await issue_list2({
|
|
3973
|
-
json_fields: options?.json_fields ?? PICKUP_FIELDS,
|
|
3974
|
-
limit,
|
|
3975
|
-
label
|
|
3976
|
-
});
|
|
3977
|
-
}
|
|
3978
|
-
async function issue_list_by_label_in_repo(label, limit, repo) {
|
|
3979
|
-
return await issue_list2({ json_fields: SUMMARY_FIELDS, limit, label, repo });
|
|
3980
|
-
}
|
|
3981
|
-
var git_gh_issue = {
|
|
3982
|
-
...git_gh_issue_read,
|
|
3983
|
-
...git_gh_issue_write,
|
|
3984
|
-
issue_list_recent,
|
|
3985
|
-
issue_list_by_label,
|
|
3986
|
-
issue_list_by_label_in_repo,
|
|
3987
|
-
issue_list_by_label_summary,
|
|
3988
|
-
issue_search_body,
|
|
3989
|
-
issue_list_open_bodies,
|
|
3990
|
-
issue_list_recently_closed
|
|
3991
|
-
};
|
|
3992
|
-
|
|
3993
|
-
// scripts/ci/pr-classification.ts
|
|
3994
|
-
import { readFileSync as readFileSync5 } from "node:fs";
|
|
3995
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
3996
|
-
import { z as z10 } from "zod";
|
|
3997
|
-
var CLASSIFICATION_SET = new Set(RELEASE_CLASSIFICATION_NAMES);
|
|
3998
|
-
var ISSUE_BUG_LABEL = "bug";
|
|
3999
|
-
var DECLARATION_PREFIX = "- \u30EA\u30EA\u30FC\u30B9\u5206\u985E: ";
|
|
4000
|
-
var DECLARATION = new RegExp(`^${DECLARATION_PREFIX}(.+)$`, "gmu");
|
|
4001
|
-
var LEGACY_LABELS = /* @__PURE__ */ new Set(["semver-major", "semver-minor"]);
|
|
4002
|
-
var LABEL = z10.object({ name: z10.string() });
|
|
4003
|
-
var USER = z10.object({ login: z10.string() });
|
|
4004
|
-
var PULL_REQUEST = z10.object({ number: z10.number(), user: USER });
|
|
4005
|
-
var EVENT = z10.object({
|
|
4006
|
-
pull_request: PULL_REQUEST,
|
|
4007
|
-
repository: z10.object({ full_name: z10.string() })
|
|
4008
|
-
});
|
|
4009
|
-
function classification_error(labels, author) {
|
|
4010
|
-
const legacy = labels.filter((label) => LEGACY_LABELS.has(label.toLowerCase()));
|
|
4011
|
-
if (legacy.length > 0) return `Remove legacy release labels: ${legacy.join(", ")}`;
|
|
4012
|
-
const selected = labels.filter((label) => CLASSIFICATION_SET.has(label.toLowerCase()));
|
|
4013
|
-
if (selected.length > 1) {
|
|
4014
|
-
return `Choose exactly one release classification; found: ${selected.join(", ")}`;
|
|
4015
|
-
}
|
|
4016
|
-
if (selected.length === 1 || author.endsWith("[bot]")) return void 0;
|
|
4017
|
-
return `Choose one release classification: ${RELEASE_CLASSIFICATION_NAMES.join(", ")}`;
|
|
4018
|
-
}
|
|
4019
|
-
function declaration(label) {
|
|
4020
|
-
return `${DECLARATION_PREFIX}${label}`;
|
|
4021
|
-
}
|
|
4022
|
-
function is_classification(value) {
|
|
4023
|
-
return CLASSIFICATION_SET.has(value);
|
|
4024
|
-
}
|
|
4025
|
-
function release_candidates(candidates) {
|
|
4026
|
-
if (!candidates.includes(BREAKING_CHANGE_LABEL)) return candidates;
|
|
4027
|
-
return candidates.filter((candidate) => candidate !== ENHANCEMENT_LABEL);
|
|
4028
|
-
}
|
|
4029
|
-
function issue_candidates(issue_json) {
|
|
4030
|
-
const issue = z10.object({ labels: z10.array(LABEL), body: z10.string().nullable() }).parse(JSON.parse(issue_json));
|
|
4031
|
-
const names = issue.labels.map((label) => label.name.toLowerCase());
|
|
4032
|
-
const declared = [...(issue.body ?? "").matchAll(DECLARATION)].map((match) => match[1] ?? "");
|
|
4033
|
-
const candidates = [...release_candidates([...names, ...declared].filter(is_classification))];
|
|
4034
|
-
const unknown = declared.filter((value) => !is_classification(value));
|
|
4035
|
-
if (unknown.length > 0) throw new Error(`Unknown release classification: ${unknown.join(", ")}`);
|
|
4036
|
-
if (names.includes(ISSUE_BUG_LABEL) && !candidates.includes(BREAKING_CHANGE_LABEL)) {
|
|
4037
|
-
candidates.push(BUGFIX_LABEL);
|
|
4038
|
-
}
|
|
4039
|
-
return candidates;
|
|
4040
|
-
}
|
|
4041
|
-
function select_issue_classification(issue_json) {
|
|
4042
|
-
const candidates = issue_candidates(issue_json);
|
|
4043
|
-
const selected = [...new Set(candidates)];
|
|
4044
|
-
const [label] = selected;
|
|
4045
|
-
if (label === void 0 || selected.length > 1) {
|
|
4046
|
-
throw new Error(
|
|
4047
|
-
`Choose one release classification before opening the PR: ${RELEASE_CLASSIFICATION_NAMES.join(", ")}; found: ${selected.join(", ") || "none"}. Add "${DECLARATION_PREFIX}<label>" to the Issue body.`
|
|
4048
|
-
);
|
|
4049
|
-
}
|
|
4050
|
-
return label;
|
|
4051
|
-
}
|
|
4052
|
-
function fetch_current_labels(repository, pull_number) {
|
|
4053
|
-
const path10 = `repos/${repository}/issues/${String(pull_number)}/labels`;
|
|
4054
|
-
try {
|
|
4055
|
-
const names = git_gh_exec.exec_gh_api_sync({ path: path10, jq_filter: ".[].name" });
|
|
4056
|
-
return names.split("\n").filter((name) => name !== "");
|
|
4057
|
-
} catch (error) {
|
|
4058
|
-
const detail = error_text.message_of(error);
|
|
4059
|
-
throw new Error(`Could not read the pull request labels: ${detail}`, { cause: error });
|
|
4060
|
-
}
|
|
4061
|
-
}
|
|
4062
|
-
function check_event(event_path, read_labels = fetch_current_labels) {
|
|
4063
|
-
const event = EVENT.parse(JSON.parse(readFileSync5(event_path, "utf8")));
|
|
4064
|
-
const labels = read_labels(event.repository.full_name, event.pull_request.number);
|
|
4065
|
-
return classification_error(labels, event.pull_request.user.login);
|
|
4066
|
-
}
|
|
4067
|
-
if (process.argv[1] === fileURLToPath2(import.meta.url)) {
|
|
4068
|
-
const event_path = process.env["GITHUB_EVENT_PATH"];
|
|
4069
|
-
if (!event_path) throw new Error("GITHUB_EVENT_PATH is required");
|
|
4070
|
-
const error = check_event(event_path);
|
|
4071
|
-
if (error) {
|
|
4072
|
-
console.error(`::error::${error}`);
|
|
4073
|
-
process.exitCode = 1;
|
|
4074
|
-
}
|
|
4075
|
-
}
|
|
4076
|
-
var pr_classification = {
|
|
4077
|
-
classification_error,
|
|
4078
|
-
check_event,
|
|
4079
|
-
fetch_current_labels,
|
|
4080
|
-
declaration,
|
|
4081
|
-
is_classification,
|
|
4082
|
-
select_issue_classification
|
|
4083
|
-
};
|
|
4084
|
-
|
|
4085
|
-
// scripts/lib/poll.ts
|
|
4086
|
-
async function sleep(duration_ms) {
|
|
4087
|
-
await new Promise((resolve2) => {
|
|
4088
|
-
setTimeout(resolve2, duration_ms);
|
|
4089
|
-
});
|
|
4090
|
-
}
|
|
4091
|
-
async function wait_between(wait, interval_ms, attempt, attempts) {
|
|
4092
|
-
if (attempt < attempts - 1) await wait(interval_ms);
|
|
4093
|
-
}
|
|
4094
|
-
async function poll_until(is_done, options) {
|
|
4095
|
-
const wait = options.sleeper ?? sleep;
|
|
4096
|
-
for (let attempt = 0; attempt < options.attempts; attempt += 1) {
|
|
4097
|
-
if (await is_done()) return true;
|
|
4098
|
-
await wait_between(wait, options.interval_ms, attempt, options.attempts);
|
|
4099
|
-
}
|
|
4100
|
-
return false;
|
|
4101
|
-
}
|
|
4102
|
-
var poll = { poll_until, sleep };
|
|
4103
|
-
|
|
4104
|
-
// scripts/gh/git-gh-pr.ts
|
|
4105
|
-
import { z as z14 } from "zod";
|
|
4106
|
-
|
|
4107
|
-
// scripts/gh/git-gh-pr-rest.ts
|
|
4108
|
-
import { z as z11 } from "zod";
|
|
4109
|
-
var rest_repo_schema = z11.looseObject({ full_name: z11.string().optional() }).nullish();
|
|
4110
|
-
var rest_pull_side_schema = z11.looseObject({ repo: rest_repo_schema });
|
|
4111
|
-
var rest_pull_schema = z11.looseObject({
|
|
4112
|
-
number: z11.number(),
|
|
4113
|
-
html_url: z11.string().optional(),
|
|
4114
|
-
body: z11.string().nullish(),
|
|
4115
|
-
state: z11.string().optional(),
|
|
4116
|
-
merged: z11.boolean().nullish(),
|
|
4117
|
-
merged_at: z11.string().nullish(),
|
|
4118
|
-
mergeable: z11.boolean().nullish(),
|
|
4119
|
-
mergeable_state: z11.string().optional(),
|
|
4120
|
-
// `sha` is the head commit, which is what both halves of the merge-gate rollup are keyed by —
|
|
4121
|
-
// REST hangs the check runs and the status contexts off the commit rather than off the pull
|
|
4122
|
-
// request (joshuafolkken/kit#1028).
|
|
4123
|
-
head: z11.looseObject({ ref: z11.string().optional(), sha: z11.string().optional(), repo: rest_repo_schema }).nullish(),
|
|
4124
|
-
base: rest_pull_side_schema.nullish(),
|
|
4125
|
-
// `node_id` is what the GraphQL auto-merge mutation addresses a pull request by, and `auto_merge`
|
|
4126
|
-
// is `null` until auto-merge is enabled — both read by `git-gh-pr-auto-merge.ts`
|
|
4127
|
-
// (joshuafolkken/kit#2497).
|
|
4128
|
-
node_id: z11.string().optional(),
|
|
4129
|
-
auto_merge: z11.looseObject({}).nullish()
|
|
4130
|
-
});
|
|
4131
|
-
var NOT_A_PULL_MESSAGE = "gh api answered something other than a pull request object";
|
|
4132
|
-
var NOT_A_PULL_LISTING_MESSAGE = "gh api answered something other than a pull request listing";
|
|
4133
|
-
var NOT_A_COMMENT_LISTING_MESSAGE = "gh api answered something other than a comment listing";
|
|
4134
|
-
var OPEN_STATE2 = "open";
|
|
4135
|
-
var EMPTY_BODY2 = "";
|
|
4136
|
-
function parse_rest_pull(rest_json) {
|
|
4137
|
-
const parsed = parse_json_object_safe(rest_json, rest_pull_schema);
|
|
4138
|
-
if (parsed === void 0) throw new Error(NOT_A_PULL_MESSAGE);
|
|
4139
|
-
return parsed;
|
|
4140
|
-
}
|
|
4141
|
-
function parse_rest_pulls(rest_json) {
|
|
4142
|
-
const parsed = parse_json_array_or_undefined(rest_json, rest_pull_schema);
|
|
4143
|
-
if (parsed === void 0) throw new Error(NOT_A_PULL_LISTING_MESSAGE);
|
|
4144
|
-
return parsed;
|
|
4145
|
-
}
|
|
4146
|
-
function select_pull(pulls) {
|
|
4147
|
-
return pulls.find((pull) => pull.state === OPEN_STATE2) ?? pulls[0];
|
|
4148
|
-
}
|
|
4149
|
-
function is_merged(pull) {
|
|
4150
|
-
return pull.merged === true || typeof pull.merged_at === "string";
|
|
4151
|
-
}
|
|
4152
|
-
function to_pr_state(pull) {
|
|
4153
|
-
return is_merged(pull) ? MERGED_STATE : to_gh_state(pull.state);
|
|
4154
|
-
}
|
|
4155
|
-
function to_repo_name(side) {
|
|
4156
|
-
return side?.repo?.full_name;
|
|
4157
|
-
}
|
|
4158
|
-
function is_same_repository_head(pull) {
|
|
4159
|
-
const head_repo = to_repo_name(pull.head);
|
|
4160
|
-
return head_repo !== void 0 && head_repo === to_repo_name(pull.base);
|
|
4161
|
-
}
|
|
4162
|
-
function to_pr_info(pull) {
|
|
4163
|
-
return {
|
|
4164
|
-
mergeable: pull.mergeable,
|
|
4165
|
-
mergeStateStatus: to_gh_state(pull.mergeable_state),
|
|
4166
|
-
state: to_pr_state(pull)
|
|
4167
|
-
};
|
|
4168
|
-
}
|
|
4169
|
-
function to_pr_comments(rest_json) {
|
|
4170
|
-
const parsed = parse_json_array_or_undefined(rest_json, rest_comment_schema);
|
|
4171
|
-
if (parsed === void 0) throw new Error(NOT_A_COMMENT_LISTING_MESSAGE);
|
|
4172
|
-
return parsed.map((comment) => ({
|
|
4173
|
-
body: comment.body ?? EMPTY_BODY2,
|
|
4174
|
-
url: comment.html_url,
|
|
4175
|
-
author: { login: comment.user?.login }
|
|
4176
|
-
}));
|
|
4177
|
-
}
|
|
4178
|
-
var git_gh_pr_rest = {
|
|
4179
|
-
parse_rest_pull,
|
|
4180
|
-
parse_rest_pulls,
|
|
4181
|
-
select_pull,
|
|
4182
|
-
is_same_repository_head,
|
|
4183
|
-
is_merged,
|
|
4184
|
-
to_pr_state,
|
|
4185
|
-
to_pr_info,
|
|
4186
|
-
to_pr_comments
|
|
4187
|
-
};
|
|
4188
|
-
|
|
4189
|
-
// scripts/gh/git-gh-pr-read.ts
|
|
4190
|
-
var pr_number_by_branch = /* @__PURE__ */ new Map();
|
|
4191
|
-
var LOOKUP_QUERY = "state=all&sort=created&direction=desc&per_page=100";
|
|
4192
|
-
var COMMENTS_QUERY = FULL_PAGE_QUERY;
|
|
4193
|
-
var OWNER_PLACEHOLDER = "{owner}";
|
|
4194
|
-
var NO_PULL_REQUEST_MESSAGE = "gh api found no pull request for branch";
|
|
4195
|
-
var UNREADABLE_PULL_REQUEST_MESSAGE = "gh api could not read the pull requests for branch";
|
|
4196
|
-
function lookup_path(branch_name) {
|
|
4197
|
-
const head = `${OWNER_PLACEHOLDER}:${encodeURIComponent(branch_name)}`;
|
|
4198
|
-
return `${git_gh_api_path.pulls_api_path()}?head=${head}&${LOOKUP_QUERY}`;
|
|
4199
|
-
}
|
|
4200
|
-
async function fetch_pr_number(branch_name) {
|
|
4201
|
-
const json = await git_gh_exec.exec_gh_api({ path: lookup_path(branch_name) });
|
|
4202
|
-
return git_gh_pr_rest.select_pull(git_gh_pr_rest.parse_rest_pulls(json))?.number;
|
|
4203
|
-
}
|
|
4204
|
-
var pending_pr_number_by_branch = /* @__PURE__ */ new Map();
|
|
4205
|
-
async function fetch_pr_number_read(branch_name) {
|
|
4206
|
-
try {
|
|
4207
|
-
const pr_number = await fetch_pr_number(branch_name);
|
|
4208
|
-
if (pr_number === void 0) return { kind: "missing" };
|
|
4209
|
-
pr_number_by_branch.set(branch_name, pr_number);
|
|
4210
|
-
return { kind: "read", pr_number };
|
|
4211
|
-
} catch (error) {
|
|
4212
|
-
return { kind: "unreadable", cause: error };
|
|
4213
|
-
}
|
|
4214
|
-
}
|
|
4215
|
-
async function start_pr_number_read(branch_name) {
|
|
4216
|
-
const pending = pending_pr_number_by_branch.get(branch_name);
|
|
4217
|
-
if (pending !== void 0) return await pending;
|
|
4218
|
-
const lookup = fetch_pr_number_read(branch_name);
|
|
4219
|
-
pending_pr_number_by_branch.set(branch_name, lookup);
|
|
4220
|
-
try {
|
|
4221
|
-
return await lookup;
|
|
4222
|
-
} finally {
|
|
4223
|
-
pending_pr_number_by_branch.delete(branch_name);
|
|
4224
|
-
}
|
|
4225
|
-
}
|
|
4226
|
-
function forget_pr_numbers() {
|
|
4227
|
-
pr_number_by_branch.clear();
|
|
4228
|
-
pending_pr_number_by_branch.clear();
|
|
4229
|
-
}
|
|
4230
|
-
async function read_pr_number(branch_name) {
|
|
4231
|
-
const cached = pr_number_by_branch.get(branch_name);
|
|
4232
|
-
if (cached !== void 0) return { kind: "read", pr_number: cached };
|
|
4233
|
-
return await start_pr_number_read(branch_name);
|
|
4234
|
-
}
|
|
4235
|
-
async function resolve_pr_number(branch_name) {
|
|
4236
|
-
const read2 = await read_pr_number(branch_name);
|
|
4237
|
-
return read2.kind === "read" ? read2.pr_number : void 0;
|
|
4238
|
-
}
|
|
4239
|
-
function to_unreadable_error(branch_name, cause) {
|
|
4240
|
-
return new Error(`${UNREADABLE_PULL_REQUEST_MESSAGE}: ${branch_name}`, { cause });
|
|
4241
|
-
}
|
|
4242
|
-
async function require_pr_number(branch_name) {
|
|
4243
|
-
const read2 = await read_pr_number(branch_name);
|
|
4244
|
-
if (read2.kind === "read") return read2.pr_number;
|
|
4245
|
-
if (read2.kind === "missing") throw new Error(`${NO_PULL_REQUEST_MESSAGE}: ${branch_name}`);
|
|
4246
|
-
throw to_unreadable_error(branch_name, read2.cause);
|
|
4247
|
-
}
|
|
4248
|
-
async function read_pull(pr_number) {
|
|
4249
|
-
const json = await git_gh_exec.exec_gh_api({
|
|
4250
|
-
path: git_gh_api_path.pull_api_path(String(pr_number))
|
|
4251
|
-
});
|
|
4252
|
-
return git_gh_pr_rest.parse_rest_pull(json);
|
|
4253
|
-
}
|
|
4254
|
-
async function read_pull_of_branch(branch_name) {
|
|
4255
|
-
const pr_number = await resolve_pr_number(branch_name);
|
|
4256
|
-
if (pr_number === void 0) return void 0;
|
|
4257
|
-
try {
|
|
4258
|
-
return await read_pull(pr_number);
|
|
4259
|
-
} catch {
|
|
4260
|
-
return void 0;
|
|
4261
|
-
}
|
|
4262
|
-
}
|
|
4263
|
-
async function pr_exists(branch_name) {
|
|
4264
|
-
const read2 = await read_pr_number(branch_name);
|
|
4265
|
-
if (read2.kind === "unreadable") throw to_unreadable_error(branch_name, read2.cause);
|
|
4266
|
-
return read2.kind === "read";
|
|
4267
|
-
}
|
|
4268
|
-
async function pr_get_number(branch_name) {
|
|
4269
|
-
return await resolve_pr_number(branch_name);
|
|
4270
|
-
}
|
|
4271
|
-
async function pr_get_url(branch_name) {
|
|
4272
|
-
const pull = await read_pull_of_branch(branch_name);
|
|
4273
|
-
if (pull?.html_url === void 0) return void 0;
|
|
4274
|
-
return git_gh_helpers.parse_pr_state_string(pull.html_url);
|
|
4275
|
-
}
|
|
4276
|
-
async function pr_get_merge_state(branch_name) {
|
|
4277
|
-
const pull = await read_pull_of_branch(branch_name);
|
|
4278
|
-
if (pull === void 0) return void 0;
|
|
4279
|
-
return {
|
|
4280
|
-
is_merged: git_gh_pr_rest.is_merged(pull),
|
|
4281
|
-
merged_at: pull.merged_at ?? void 0,
|
|
4282
|
-
head_sha: pull.head?.sha
|
|
4283
|
-
};
|
|
4284
|
-
}
|
|
4285
|
-
async function pr_get_body(branch_name) {
|
|
4286
|
-
const pull = await read_pull_of_branch(branch_name);
|
|
4287
|
-
const body = pull?.body;
|
|
4288
|
-
return typeof body === "string" && body.length > 0 ? body : void 0;
|
|
4289
|
-
}
|
|
4290
|
-
async function pr_view(branch_name) {
|
|
4291
|
-
const pull = await read_pull_of_branch(branch_name);
|
|
4292
|
-
if (pull === void 0) return "";
|
|
4293
|
-
return JSON.stringify(git_gh_pr_rest.to_pr_info(pull));
|
|
4294
|
-
}
|
|
4295
|
-
async function read_comments(branch_name, to_path, to_json) {
|
|
4296
|
-
const pr_number = await resolve_pr_number(branch_name);
|
|
4297
|
-
if (pr_number === void 0) return void 0;
|
|
4298
|
-
const path10 = `${to_path(String(pr_number))}${COMMENTS_QUERY}`;
|
|
4299
|
-
try {
|
|
4300
|
-
return to_json(await git_gh_exec.exec_gh_api({ path: path10, should_paginate: true }));
|
|
4301
|
-
} catch {
|
|
4302
|
-
return void 0;
|
|
4303
|
-
}
|
|
4304
|
-
}
|
|
4305
|
-
function to_comments_json(raw) {
|
|
4306
|
-
return JSON.stringify(git_gh_pr_rest.to_pr_comments(raw));
|
|
4307
|
-
}
|
|
4308
|
-
function as_served(raw) {
|
|
4309
|
-
return raw;
|
|
4310
|
-
}
|
|
4311
|
-
async function pr_get_comments(branch_name) {
|
|
4312
|
-
return await read_comments(branch_name, git_gh_api_path.issue_comments_api_path, to_comments_json);
|
|
4313
|
-
}
|
|
4314
|
-
async function pr_get_review_comments(branch_name) {
|
|
4315
|
-
return await read_comments(branch_name, git_gh_api_path.pull_comments_api_path, as_served);
|
|
4316
|
-
}
|
|
4317
|
-
var git_gh_pr_read = {
|
|
4318
|
-
pr_exists,
|
|
4319
|
-
pr_get_number,
|
|
4320
|
-
pr_get_url,
|
|
4321
|
-
pr_get_body,
|
|
4322
|
-
pr_get_merge_state,
|
|
4323
|
-
pr_view,
|
|
4324
|
-
pr_get_comments,
|
|
4325
|
-
pr_get_review_comments
|
|
4326
|
-
};
|
|
4327
|
-
|
|
4328
|
-
// scripts/gh/git-gh-pr-review.ts
|
|
4329
|
-
import { z as z12 } from "zod";
|
|
4330
|
-
var REVIEW_APPROVED = "APPROVED";
|
|
4331
|
-
var REVIEW_CHANGES_REQUESTED = "CHANGES_REQUESTED";
|
|
4332
|
-
var REVIEW_NONE = "";
|
|
4333
|
-
var STATE_CHANGING_REVIEWS = /* @__PURE__ */ new Set([REVIEW_APPROVED, REVIEW_CHANGES_REQUESTED]);
|
|
4334
|
-
var rest_review_schema = z12.looseObject({
|
|
4335
|
-
state: z12.string().optional(),
|
|
4336
|
-
user: z12.looseObject({ login: z12.string().optional() }).nullish()
|
|
4337
|
-
});
|
|
4338
|
-
var NOT_A_REVIEW_LISTING = "gh api answered something other than a review listing";
|
|
4339
|
-
function parse_rest_reviews(reviews_json) {
|
|
4340
|
-
const parsed = parse_json_array_or_undefined(reviews_json, rest_review_schema);
|
|
4341
|
-
if (parsed === void 0) throw new Error(NOT_A_REVIEW_LISTING);
|
|
4342
|
-
return parsed;
|
|
4343
|
-
}
|
|
4344
|
-
var UNATTRIBUTED_REVIEWER = "(no author)";
|
|
4345
|
-
function read_reviewer(review) {
|
|
4346
|
-
const login = review.user?.login;
|
|
4347
|
-
return typeof login === "string" && login.length > 0 ? login : UNATTRIBUTED_REVIEWER;
|
|
4348
|
-
}
|
|
4349
|
-
function read_state_changing(review) {
|
|
4350
|
-
const state = review.state?.toUpperCase();
|
|
4351
|
-
return state !== void 0 && STATE_CHANGING_REVIEWS.has(state) ? state : void 0;
|
|
4352
|
-
}
|
|
4353
|
-
function fold_latest_states(reviews) {
|
|
4354
|
-
const latest = /* @__PURE__ */ new Map();
|
|
4355
|
-
for (const review of reviews) {
|
|
4356
|
-
const state = read_state_changing(review);
|
|
4357
|
-
if (state !== void 0) latest.set(read_reviewer(review), state);
|
|
4358
|
-
}
|
|
4359
|
-
return latest;
|
|
4360
|
-
}
|
|
4361
|
-
function to_review_decision(reviews_json) {
|
|
4362
|
-
const latest = new Set(fold_latest_states(parse_rest_reviews(reviews_json)).values());
|
|
4363
|
-
if (latest.has(REVIEW_CHANGES_REQUESTED)) return REVIEW_CHANGES_REQUESTED;
|
|
4364
|
-
return latest.has(REVIEW_APPROVED) ? REVIEW_APPROVED : REVIEW_NONE;
|
|
4365
|
-
}
|
|
4366
|
-
var git_gh_pr_review = { to_review_decision };
|
|
4367
|
-
|
|
4368
|
-
// scripts/gh/git-gh-pr-rollup.ts
|
|
4369
|
-
import { z as z13 } from "zod";
|
|
4370
|
-
var STATUS_CONTEXT_TYPE_NAME = "StatusContext";
|
|
4371
|
-
var TYPE_NAME_KEY = "__typename";
|
|
4372
|
-
var rollup_element_schema = z13.looseObject({});
|
|
4373
|
-
var check_runs_page_schema = z13.looseObject({
|
|
4374
|
-
// Required, not optional: GitHub always names the key, and accepting a page without one would
|
|
4375
|
-
// answer an empty rollup — which `git-pr-followup.ts` reports as "this branch has no checks".
|
|
4376
|
-
check_runs: z13.array(rollup_element_schema)
|
|
4377
|
-
});
|
|
4378
|
-
var id_holder_schema = z13.object({ id: z13.number() });
|
|
4379
|
-
var status_page_schema = z13.looseObject({
|
|
4380
|
-
statuses: z13.array(rollup_element_schema)
|
|
4381
|
-
});
|
|
4382
|
-
var NOT_A_CHECK_RUNS_LISTING = "gh api answered something other than a check run listing";
|
|
4383
|
-
var NOT_A_STATUS_LISTING = "gh api answered something other than a commit status listing";
|
|
4384
|
-
function read_pages(raw_json, schema, message) {
|
|
4385
|
-
const pages = parse_json_array_or_undefined(raw_json, schema);
|
|
4386
|
-
if (pages === void 0) throw new Error(message);
|
|
4387
|
-
return pages;
|
|
4388
|
-
}
|
|
4389
|
-
var NO_SUITE = -1;
|
|
4390
|
-
function read_id(value) {
|
|
4391
|
-
const parsed = id_holder_schema.safeParse(value);
|
|
4392
|
-
return parsed.success ? parsed.data.id : void 0;
|
|
4393
|
-
}
|
|
4394
|
-
function check_run_group_key(run2) {
|
|
4395
|
-
const { name, app } = run2;
|
|
4396
|
-
if (typeof name !== "string") return void 0;
|
|
4397
|
-
return JSON.stringify([name, read_id(app)]);
|
|
4398
|
-
}
|
|
4399
|
-
function read_rank(run2) {
|
|
4400
|
-
const id = read_id(run2);
|
|
4401
|
-
if (id === void 0) return void 0;
|
|
4402
|
-
return { suite: read_id(run2["check_suite"]) ?? NO_SUITE, run: id };
|
|
4403
|
-
}
|
|
4404
|
-
function is_ranked_above(candidate, current) {
|
|
4405
|
-
if (candidate.suite !== current.suite) return candidate.suite > current.suite;
|
|
4406
|
-
return candidate.run > current.run;
|
|
4407
|
-
}
|
|
4408
|
-
function should_replace(previous, rank) {
|
|
4409
|
-
const previous_rank = previous === void 0 ? void 0 : read_rank(previous);
|
|
4410
|
-
return previous_rank === void 0 || is_ranked_above(rank, previous_rank);
|
|
4411
|
-
}
|
|
4412
|
-
function remember_newest_run(run2, newest) {
|
|
4413
|
-
const key = check_run_group_key(run2);
|
|
4414
|
-
const rank = read_rank(run2);
|
|
4415
|
-
if (key === void 0 || rank === void 0) return;
|
|
4416
|
-
if (should_replace(newest.get(key), rank)) newest.set(key, run2);
|
|
4417
|
-
}
|
|
4418
|
-
function is_newest_run(run2, newest) {
|
|
4419
|
-
const key = check_run_group_key(run2);
|
|
4420
|
-
if (key === void 0 || read_rank(run2) === void 0) return true;
|
|
4421
|
-
return newest.get(key) === run2;
|
|
4422
|
-
}
|
|
4423
|
-
function to_check_run_items(check_runs_json) {
|
|
4424
|
-
const pages = read_pages(check_runs_json, check_runs_page_schema, NOT_A_CHECK_RUNS_LISTING);
|
|
4425
|
-
const runs = pages.flatMap((page) => page.check_runs);
|
|
4426
|
-
const newest = /* @__PURE__ */ new Map();
|
|
4427
|
-
for (const run2 of runs) remember_newest_run(run2, newest);
|
|
4428
|
-
return runs.filter((run2) => is_newest_run(run2, newest));
|
|
4429
|
-
}
|
|
4430
|
-
function to_status_context_items(status_json) {
|
|
4431
|
-
const pages = read_pages(status_json, status_page_schema, NOT_A_STATUS_LISTING);
|
|
4432
|
-
return pages.flatMap((page) => page.statuses).map((status) => ({ ...status, [TYPE_NAME_KEY]: STATUS_CONTEXT_TYPE_NAME }));
|
|
4433
|
-
}
|
|
4434
|
-
function to_status_check_rollup(input) {
|
|
4435
|
-
return [
|
|
4436
|
-
...to_check_run_items(input.check_runs_json),
|
|
4437
|
-
...to_status_context_items(input.status_json)
|
|
4438
|
-
];
|
|
4439
|
-
}
|
|
4440
|
-
var git_gh_pr_rollup = {
|
|
4441
|
-
to_status_check_rollup
|
|
4442
|
-
};
|
|
4443
|
-
|
|
4444
|
-
// scripts/gh/git-gh-pr-snapshot.ts
|
|
4445
|
-
var NO_HEAD_SHA_MESSAGE = "gh api answered a pull request with no head commit";
|
|
4446
|
-
async function read_object_pages(path10) {
|
|
4447
|
-
return await git_gh_exec.exec_gh_api({
|
|
4448
|
-
path: `${path10}${FULL_PAGE_QUERY}`,
|
|
4449
|
-
should_paginate: true,
|
|
4450
|
-
should_slurp: true
|
|
4451
|
-
});
|
|
4452
|
-
}
|
|
4453
|
-
async function read_array_pages(path10) {
|
|
4454
|
-
return await git_gh_exec.exec_gh_api({
|
|
4455
|
-
path: `${path10}${FULL_PAGE_QUERY}`,
|
|
4456
|
-
should_paginate: true
|
|
4457
|
-
});
|
|
4458
|
-
}
|
|
4459
|
-
function read_head_sha(pull) {
|
|
4460
|
-
const sha = pull.head?.sha;
|
|
4461
|
-
if (sha === void 0) throw new Error(NO_HEAD_SHA_MESSAGE);
|
|
4462
|
-
return sha;
|
|
4463
|
-
}
|
|
4464
|
-
async function read_status_check_rollup(commit_sha) {
|
|
4465
|
-
const [check_runs_json, status_json] = await Promise.all([
|
|
4466
|
-
read_object_pages(git_gh_api_path.commit_check_runs_api_path(commit_sha)),
|
|
4467
|
-
read_object_pages(git_gh_api_path.commit_status_api_path(commit_sha))
|
|
4468
|
-
]);
|
|
4469
|
-
return git_gh_pr_rollup.to_status_check_rollup({ check_runs_json, status_json });
|
|
4470
|
-
}
|
|
4471
|
-
async function pr_get_review_decision(pr_number) {
|
|
4472
|
-
const path10 = git_gh_api_path.pull_reviews_api_path(String(pr_number));
|
|
4473
|
-
return git_gh_pr_review.to_review_decision(await read_array_pages(path10));
|
|
4474
|
-
}
|
|
4475
|
-
async function build_checks_fields(pull) {
|
|
4476
|
-
return {
|
|
4477
|
-
statusCheckRollup: await read_status_check_rollup(read_head_sha(pull)),
|
|
4478
|
-
mergeStateStatus: to_gh_state(pull.mergeable_state)
|
|
4479
|
-
};
|
|
4480
|
-
}
|
|
4481
|
-
async function resolve_pull(branch_name) {
|
|
4482
|
-
const pr_number = await require_pr_number(branch_name);
|
|
4483
|
-
return { pr_number, pull: await read_pull(pr_number) };
|
|
4484
|
-
}
|
|
4485
|
-
async function pr_get_checks_snapshot(branch_name) {
|
|
4486
|
-
const { pr_number, pull } = await resolve_pull(branch_name);
|
|
4487
|
-
return { pr_number, snapshot_json: JSON.stringify(await build_checks_fields(pull)) };
|
|
4488
|
-
}
|
|
4489
|
-
async function pr_get_state_snapshot(branch_name) {
|
|
4490
|
-
const { pr_number, pull } = await resolve_pull(branch_name);
|
|
4491
|
-
const [fields, review_decision] = await Promise.all([
|
|
4492
|
-
build_checks_fields(pull),
|
|
4493
|
-
pr_get_review_decision(pr_number)
|
|
4494
|
-
]);
|
|
4495
|
-
return JSON.stringify({ ...fields, reviewDecision: review_decision });
|
|
4496
|
-
}
|
|
4497
|
-
var git_gh_pr_snapshot = {
|
|
4498
|
-
pr_get_state_snapshot,
|
|
4499
|
-
pr_get_checks_snapshot,
|
|
4500
|
-
pr_get_review_decision
|
|
4501
|
-
};
|
|
4502
|
-
|
|
4503
|
-
// scripts/gh/git-gh-pr.ts
|
|
4504
|
-
var HTML_URL_FILTER2 = ".html_url";
|
|
4505
|
-
var PUT_METHOD = "PUT";
|
|
4506
|
-
var PATCH_METHOD2 = "PATCH";
|
|
4507
|
-
var MERGE_COMMIT_METHOD = "merge";
|
|
4508
|
-
var MERGE_REQUEST_TIMEOUT_MS = 18e4;
|
|
4509
|
-
var MERGE_UNCONFIRMED_MESSAGE = "gh api could not read the pull request back after the merge request failed";
|
|
4510
|
-
var MERGE_READ_BACK_ATTEMPTS = 3;
|
|
4511
|
-
var MERGE_READ_BACK_INTERVAL_MS = 1e3;
|
|
4512
|
-
var PR_NUMBER_PATTERN = /\/pull\/([1-9]\d*)$/u;
|
|
4513
|
-
var LABELS_SEGMENT2 = "/labels";
|
|
4514
|
-
var PR_LABELS = z14.array(z14.object({ name: z14.string() }));
|
|
4515
|
-
async function add_pr_classification(number, label) {
|
|
4516
|
-
await git_gh_exec.exec_gh_api({
|
|
4517
|
-
path: `${git_gh_api_path.issue_api_path(number)}${LABELS_SEGMENT2}`,
|
|
4518
|
-
body: JSON.stringify({ labels: [label] })
|
|
4519
|
-
});
|
|
4520
|
-
}
|
|
4521
|
-
async function pr_get_classification(branch_name) {
|
|
4522
|
-
const number = await require_pr_number(branch_name);
|
|
4523
|
-
const response = await git_gh_exec.exec_gh_api({
|
|
4524
|
-
path: `${git_gh_api_path.issue_api_path(String(number))}${LABELS_SEGMENT2}`
|
|
4525
|
-
});
|
|
4526
|
-
const names = PR_LABELS.parse(JSON.parse(response)).map((label) => label.name.toLowerCase());
|
|
4527
|
-
const selected = names.filter((name) => pr_classification.is_classification(name));
|
|
4528
|
-
if (selected.length === 0) return void 0;
|
|
4529
|
-
const error = pr_classification.classification_error(names, "human");
|
|
4530
|
-
if (error !== void 0) throw new Error(error);
|
|
4531
|
-
return selected[0];
|
|
4532
|
-
}
|
|
4533
|
-
async function pr_ensure_classification(branch_name, label) {
|
|
4534
|
-
if (await pr_get_classification(branch_name) !== void 0) return;
|
|
4535
|
-
const number = await require_pr_number(branch_name);
|
|
4536
|
-
await add_pr_classification(String(number), label);
|
|
4537
|
-
}
|
|
4538
|
-
async function post_pull_request(title, body) {
|
|
4539
|
-
const base = await git_command.get_default_branch();
|
|
4540
|
-
const head = await git_command.branch();
|
|
4541
|
-
forget_pr_numbers();
|
|
4542
|
-
try {
|
|
4543
|
-
return await git_gh_exec.exec_gh_api({
|
|
4544
|
-
path: git_gh_api_path.pulls_api_path(),
|
|
4545
|
-
body: JSON.stringify({ title, body, head, base }),
|
|
4546
|
-
jq_filter: HTML_URL_FILTER2
|
|
4547
|
-
});
|
|
4548
|
-
} catch (error) {
|
|
4549
|
-
return git_gh_helpers.handle_pr_create_error(error);
|
|
4550
|
-
}
|
|
4551
|
-
}
|
|
4552
|
-
async function pr_create(title, body, label) {
|
|
4553
|
-
const classification_error2 = pr_classification.classification_error([label], "human");
|
|
4554
|
-
if (classification_error2 !== void 0) throw new Error(classification_error2);
|
|
4555
|
-
const url = await post_pull_request(title, body);
|
|
4556
|
-
const number = PR_NUMBER_PATTERN.exec(url)?.[1];
|
|
4557
|
-
if (number === void 0) throw new Error(`Could not identify the created pull request: ${url}`);
|
|
4558
|
-
await add_pr_classification(number, label);
|
|
4559
|
-
return url;
|
|
4560
|
-
}
|
|
4561
|
-
async function pr_comment(branch_name, body) {
|
|
4562
|
-
const pr_number = await require_pr_number(branch_name);
|
|
4563
|
-
return await git_gh_issue_write.issue_comment(String(pr_number), body);
|
|
4564
|
-
}
|
|
4565
|
-
async function pr_update_body(branch_name, body) {
|
|
4566
|
-
const pr_number = await require_pr_number(branch_name);
|
|
4567
|
-
await git_gh_exec.exec_gh_api({
|
|
4568
|
-
path: git_gh_api_path.pull_api_path(String(pr_number)),
|
|
4569
|
-
method: PATCH_METHOD2,
|
|
4570
|
-
body: JSON.stringify({ body })
|
|
4571
|
-
});
|
|
4572
|
-
}
|
|
4573
|
-
async function put_merge(pr_number) {
|
|
4574
|
-
await git_gh_exec.exec_gh_api({
|
|
4575
|
-
path: git_gh_api_path.pull_merge_api_path(String(pr_number)),
|
|
4576
|
-
method: PUT_METHOD,
|
|
4577
|
-
body: JSON.stringify({ merge_method: MERGE_COMMIT_METHOD }),
|
|
4578
|
-
timeout_ms: MERGE_REQUEST_TIMEOUT_MS
|
|
4579
|
-
});
|
|
4580
|
-
}
|
|
4581
|
-
async function read_merge_state(pr_number) {
|
|
4582
|
-
try {
|
|
4583
|
-
return git_gh_pr_rest.is_merged(await read_pull(pr_number));
|
|
4584
|
-
} catch (error) {
|
|
4585
|
-
console.warn(`Could not read the pull request back: ${String(error)}`);
|
|
4586
|
-
return void 0;
|
|
4587
|
-
}
|
|
4588
|
-
}
|
|
4589
|
-
async function sleep_between_read_backs(attempt) {
|
|
4590
|
-
if (attempt < MERGE_READ_BACK_ATTEMPTS - 1) await poll.sleep(MERGE_READ_BACK_INTERVAL_MS);
|
|
4591
|
-
}
|
|
4592
|
-
async function has_merge_landed(pr_number, merge_error) {
|
|
4593
|
-
for (let attempt = 0; attempt < MERGE_READ_BACK_ATTEMPTS; attempt += 1) {
|
|
4594
|
-
const is_merged2 = await read_merge_state(pr_number);
|
|
4595
|
-
if (is_merged2 !== void 0) return is_merged2;
|
|
4596
|
-
await sleep_between_read_backs(attempt);
|
|
4597
|
-
}
|
|
4598
|
-
throw new Error(MERGE_UNCONFIRMED_MESSAGE, { cause: merge_error });
|
|
4599
|
-
}
|
|
4600
|
-
async function pr_merge(branch_name) {
|
|
4601
|
-
const pr_number = await require_pr_number(branch_name);
|
|
4602
|
-
try {
|
|
4603
|
-
await put_merge(pr_number);
|
|
4604
|
-
} catch (error) {
|
|
4605
|
-
if (!await has_merge_landed(pr_number, error)) throw error;
|
|
4606
|
-
}
|
|
4607
|
-
}
|
|
4608
|
-
var git_gh_pr = {
|
|
4609
|
-
...git_gh_pr_read,
|
|
4610
|
-
...git_gh_pr_snapshot,
|
|
4611
|
-
pr_create,
|
|
4612
|
-
pr_get_classification,
|
|
4613
|
-
pr_ensure_classification,
|
|
4614
|
-
pr_comment,
|
|
4615
|
-
pr_merge,
|
|
4616
|
-
pr_update_body
|
|
4617
|
-
};
|
|
4618
|
-
|
|
4619
|
-
// scripts/gh/git-gh-pr-auto-merge.ts
|
|
4620
|
-
var GRAPHQL_PATH = "graphql";
|
|
4621
|
-
var OPEN_PULLS_QUERY = `${git_gh_api_path.FULL_PAGE_QUERY}&state=open`;
|
|
4622
|
-
var MISSING_NODE_ID_MESSAGE = "gh api answered a pull request without a node_id";
|
|
4623
|
-
var ENABLE_AUTO_MERGE_MUTATION = "mutation($id: ID!) { enablePullRequestAutoMerge(input: { pullRequestId: $id, mergeMethod: MERGE }) { clientMutationId } }";
|
|
4624
|
-
async function pr_enable_auto_merge(branch_name) {
|
|
4625
|
-
const pull = await read_pull(await require_pr_number(branch_name));
|
|
4626
|
-
if (pull.node_id === void 0) throw new Error(MISSING_NODE_ID_MESSAGE);
|
|
4627
|
-
await git_gh_exec.exec_gh_api({
|
|
4628
|
-
path: GRAPHQL_PATH,
|
|
4629
|
-
body: JSON.stringify({ query: ENABLE_AUTO_MERGE_MUTATION, variables: { id: pull.node_id } })
|
|
4630
|
-
});
|
|
4631
|
-
}
|
|
4632
|
-
async function pr_is_merged(branch_name) {
|
|
4633
|
-
try {
|
|
4634
|
-
return git_gh_pr_rest.is_merged(await read_pull(await require_pr_number(branch_name)));
|
|
4635
|
-
} catch {
|
|
4636
|
-
return false;
|
|
4637
|
-
}
|
|
4638
|
-
}
|
|
4639
|
-
function head_reference_of(pull) {
|
|
4640
|
-
return pull.head?.ref ?? "";
|
|
4641
|
-
}
|
|
4642
|
-
function has_head_prefix(pull, prefix) {
|
|
4643
|
-
return git_gh_pr_rest.is_same_repository_head(pull) && head_reference_of(pull).startsWith(prefix);
|
|
4644
|
-
}
|
|
4645
|
-
function to_open_pull(pull) {
|
|
4646
|
-
return {
|
|
4647
|
-
number: pull.number,
|
|
4648
|
-
head_ref: head_reference_of(pull),
|
|
4649
|
-
has_auto_merge: pull.auto_merge !== null && pull.auto_merge !== void 0
|
|
4650
|
-
};
|
|
4651
|
-
}
|
|
4652
|
-
async function pr_list_open_with_head_prefix(prefix) {
|
|
4653
|
-
const json = await git_gh_exec.exec_gh_api({
|
|
4654
|
-
path: `${git_gh_api_path.pulls_api_path()}${OPEN_PULLS_QUERY}`,
|
|
4655
|
-
should_paginate: true
|
|
4656
|
-
});
|
|
4657
|
-
return git_gh_pr_rest.parse_rest_pulls(json).filter((pull) => has_head_prefix(pull, prefix)).map((pull) => to_open_pull(pull));
|
|
4658
|
-
}
|
|
4659
|
-
var git_gh_pr_auto_merge = {
|
|
4660
|
-
pr_enable_auto_merge,
|
|
4661
|
-
pr_is_merged,
|
|
4662
|
-
pr_list_open_with_head_prefix
|
|
4663
|
-
};
|
|
4664
|
-
|
|
4665
|
-
// scripts/gh/git-gh-repo.ts
|
|
4666
|
-
async function repo_get_name_with_owner() {
|
|
4667
|
-
try {
|
|
4668
|
-
const result = await git_gh_exec.exec_gh_api({
|
|
4669
|
-
path: git_gh_api_path.repo_api_path(),
|
|
4670
|
-
jq_filter: ".full_name"
|
|
4671
|
-
});
|
|
4672
|
-
return git_gh_helpers.parse_pr_state_string(result);
|
|
4673
|
-
} catch {
|
|
4674
|
-
return void 0;
|
|
4675
|
-
}
|
|
4676
|
-
}
|
|
4677
|
-
var git_gh_repo = {
|
|
4678
|
-
repo_get_name_with_owner
|
|
4679
|
-
};
|
|
4680
|
-
|
|
4681
|
-
// scripts/gh/git-pr-checks-parse.ts
|
|
4682
|
-
var CHECK_STATUS_PASS = "pass";
|
|
4683
|
-
var CHECK_STATUS_PENDING = "pending";
|
|
4684
|
-
var CHECK_STATUS_FAIL = "fail";
|
|
4685
|
-
var CHECK_STATUS_MISSING = "missing";
|
|
4686
|
-
var PASSING_CONCLUSIONS = /* @__PURE__ */ new Set(["success", "skipped", "neutral"]);
|
|
4687
|
-
var KEY_TYPE_NAME = "__typename";
|
|
4688
|
-
var KEY_STATE = "state";
|
|
4689
|
-
var KEY_STATUS = "status";
|
|
4690
|
-
var KEY_CONCLUSION = "conclusion";
|
|
4691
|
-
var KEY_NAME = "name";
|
|
4692
|
-
var KEY_CONTEXT = "context";
|
|
4693
|
-
function read_string(value) {
|
|
4694
|
-
if (typeof value !== "string") return void 0;
|
|
4695
|
-
const trimmed = value.trim();
|
|
4696
|
-
if (trimmed.length === 0) return void 0;
|
|
4697
|
-
return trimmed;
|
|
4698
|
-
}
|
|
4699
|
-
var PENDING_STATUS_STATES = /* @__PURE__ */ new Set(["pending", "expected"]);
|
|
4700
|
-
function parse_status_context(item) {
|
|
4701
|
-
const state = read_string(item[KEY_STATE])?.toLowerCase();
|
|
4702
|
-
if (state === "success") return CHECK_STATUS_PASS;
|
|
4703
|
-
if (state !== void 0 && PENDING_STATUS_STATES.has(state)) return CHECK_STATUS_PENDING;
|
|
4704
|
-
return CHECK_STATUS_FAIL;
|
|
4705
|
-
}
|
|
4706
|
-
function is_passing_conclusion(item) {
|
|
4707
|
-
const conclusion = read_string(item[KEY_CONCLUSION])?.toLowerCase();
|
|
4708
|
-
return conclusion !== void 0 && PASSING_CONCLUSIONS.has(conclusion);
|
|
4709
|
-
}
|
|
4710
|
-
function parse_check_run(item) {
|
|
4711
|
-
const status = read_string(item[KEY_STATUS])?.toLowerCase();
|
|
4712
|
-
if (status !== "completed") return CHECK_STATUS_PENDING;
|
|
4713
|
-
return is_passing_conclusion(item) ? CHECK_STATUS_PASS : CHECK_STATUS_FAIL;
|
|
4714
|
-
}
|
|
4715
|
-
function parse_rollup_status(item) {
|
|
4716
|
-
const type_name = read_string(item[KEY_TYPE_NAME]);
|
|
4717
|
-
if (type_name === "StatusContext") return parse_status_context(item);
|
|
4718
|
-
return parse_check_run(item);
|
|
4719
|
-
}
|
|
4720
|
-
function read_rollup_array(parsed) {
|
|
4721
|
-
const result = pr_raw_schema.safeParse(parsed);
|
|
4722
|
-
if (!result.success) return [];
|
|
4723
|
-
return result.data.statusCheckRollup ?? [];
|
|
4724
|
-
}
|
|
4725
|
-
function parse_rollup_item(item) {
|
|
4726
|
-
const name = read_string(item[KEY_NAME]) ?? read_string(item[KEY_CONTEXT]);
|
|
4727
|
-
if (name === void 0) return void 0;
|
|
4728
|
-
return { name, status: parse_rollup_status(item) };
|
|
4729
|
-
}
|
|
4730
|
-
function parse_rollup_checks(raw_json) {
|
|
4731
|
-
const parsed = json_value.parse_or_undefined(raw_json);
|
|
4732
|
-
const rollup = read_rollup_array(parsed);
|
|
4733
|
-
const checks = [];
|
|
4734
|
-
for (const item of rollup) {
|
|
4735
|
-
const parsed_item = parse_rollup_item(item);
|
|
4736
|
-
if (parsed_item !== void 0) checks.push(parsed_item);
|
|
4737
|
-
}
|
|
4738
|
-
return checks;
|
|
4739
|
-
}
|
|
4740
|
-
function parse_pr_state_snapshot(raw_json) {
|
|
4741
|
-
const parsed = json_value.parse_or_undefined(raw_json);
|
|
4742
|
-
const result = pr_raw_schema.safeParse(parsed);
|
|
4743
|
-
const data = result.success ? result.data : void 0;
|
|
4744
|
-
return {
|
|
4745
|
-
rollup: parse_rollup_checks(raw_json),
|
|
4746
|
-
merge_state_status: read_string(data?.mergeStateStatus),
|
|
4747
|
-
review_decision: read_string(data?.reviewDecision)
|
|
4748
|
-
};
|
|
4749
|
-
}
|
|
4750
|
-
|
|
4751
|
-
// scripts/gh/git-pr-checks-eval.ts
|
|
4752
|
-
var DEFAULT_REQUIRED_CHECKS = ["SonarQube"];
|
|
4753
|
-
var CODERABBIT_CHECK_NAME = "CodeRabbit";
|
|
4754
|
-
var REQUIRED_CHECKS_ENV_VAR = "JOSH_REQUIRED_CHECKS";
|
|
4755
|
-
function parse_required_checks() {
|
|
4756
|
-
const raw = process.env[REQUIRED_CHECKS_ENV_VAR];
|
|
4757
|
-
if (!raw) return DEFAULT_REQUIRED_CHECKS;
|
|
4758
|
-
return raw.split(",").map((check4) => check4.trim()).filter((check4) => check4.length > 0);
|
|
4759
|
-
}
|
|
4760
|
-
var REQUIRED_CHECKS = parse_required_checks();
|
|
4761
|
-
var MERGE_STATE_CLEAN = "CLEAN";
|
|
4762
|
-
var MERGE_STATE_UNSTABLE = "UNSTABLE";
|
|
4763
|
-
var MERGE_STATE_DIRTY = "DIRTY";
|
|
4764
|
-
var REVIEW_CHANGES_REQUESTED2 = "CHANGES_REQUESTED";
|
|
4765
|
-
var CHECK_SUITE_SEPARATOR = " / ";
|
|
4766
|
-
var FAILURE_MESSAGE_PREFIX = "PR checks failed";
|
|
4767
|
-
var FAILURE_REASON_REVIEW = "review requested changes";
|
|
4768
|
-
var FAILURE_REASON_CHECKS = "failed checks";
|
|
4769
|
-
var FAILURE_REASON_CONFLICT = "merge conflict";
|
|
4770
|
-
function is_required_match(check_name, required_name) {
|
|
4771
|
-
if (check_name === required_name) return true;
|
|
4772
|
-
return check_name.startsWith(`${required_name}${CHECK_SUITE_SEPARATOR}`);
|
|
4773
|
-
}
|
|
4774
|
-
function find_required_check(checks, required_name) {
|
|
4775
|
-
return checks.find((check4) => is_required_match(check4.name, required_name));
|
|
4776
|
-
}
|
|
4777
|
-
function read_required_statuses(checks) {
|
|
4778
|
-
return REQUIRED_CHECKS.map(
|
|
4779
|
-
(name) => find_required_check(checks, name)?.status ?? CHECK_STATUS_MISSING
|
|
4780
|
-
);
|
|
4781
|
-
}
|
|
4782
|
-
function is_review_blocked(review_decision) {
|
|
4783
|
-
return review_decision === REVIEW_CHANGES_REQUESTED2;
|
|
4784
|
-
}
|
|
4785
|
-
function is_merge_conflict(merge_state_status) {
|
|
4786
|
-
return merge_state_status === MERGE_STATE_DIRTY;
|
|
4787
|
-
}
|
|
4788
|
-
function evaluate_failure_state(input) {
|
|
4789
|
-
if (is_merge_conflict(input.merge_state_status) || is_review_blocked(input.review_decision) || input.failed_checks.length > 0) {
|
|
4790
|
-
return "failure";
|
|
4791
|
-
}
|
|
4792
|
-
return void 0;
|
|
4793
|
-
}
|
|
4794
|
-
function is_merge_state_clean(merge_state_status) {
|
|
4795
|
-
return merge_state_status === MERGE_STATE_CLEAN;
|
|
4796
|
-
}
|
|
4797
|
-
function is_every_required_passing(statuses) {
|
|
4798
|
-
return statuses.every((status) => status === CHECK_STATUS_PASS);
|
|
4799
|
-
}
|
|
4800
|
-
function is_coderabbit_check(check_name) {
|
|
4801
|
-
return is_required_match(check_name, CODERABBIT_CHECK_NAME);
|
|
4802
|
-
}
|
|
4803
|
-
function is_unstable_only_from_coderabbit(snapshot) {
|
|
4804
|
-
if (snapshot.merge_state_status !== MERGE_STATE_UNSTABLE) return false;
|
|
4805
|
-
const non_passing = snapshot.rollup.filter((check4) => check4.status !== CHECK_STATUS_PASS);
|
|
4806
|
-
if (non_passing.length === 0) return false;
|
|
4807
|
-
return non_passing.every((check4) => is_coderabbit_check(check4.name));
|
|
4808
|
-
}
|
|
4809
|
-
function is_required_check(check_name) {
|
|
4810
|
-
return REQUIRED_CHECKS.some((required) => is_required_match(check_name, required));
|
|
4811
|
-
}
|
|
4812
|
-
function is_blocking_failure(check4) {
|
|
4813
|
-
if (check4.status !== CHECK_STATUS_FAIL) return false;
|
|
4814
|
-
return !is_coderabbit_check(check4.name) || is_required_check(check4.name);
|
|
4815
|
-
}
|
|
4816
|
-
function collect_blocking_failures(snapshot) {
|
|
4817
|
-
return snapshot.rollup.filter((check4) => is_blocking_failure(check4)).map((check4) => check4.name);
|
|
4818
|
-
}
|
|
4819
|
-
function is_mergeable_state(snapshot) {
|
|
4820
|
-
if (is_merge_state_clean(snapshot.merge_state_status)) return true;
|
|
4821
|
-
return is_unstable_only_from_coderabbit(snapshot);
|
|
4822
|
-
}
|
|
4823
|
-
function collect_failure_reasons(snapshot) {
|
|
4824
|
-
const reasons = [];
|
|
4825
|
-
if (is_merge_conflict(snapshot.merge_state_status)) reasons.push(FAILURE_REASON_CONFLICT);
|
|
4826
|
-
if (is_review_blocked(snapshot.review_decision)) reasons.push(FAILURE_REASON_REVIEW);
|
|
4827
|
-
const failed = collect_blocking_failures(snapshot);
|
|
4828
|
-
if (failed.length > 0) reasons.push(`${FAILURE_REASON_CHECKS}: ${failed.join(", ")}`);
|
|
4829
|
-
return reasons;
|
|
4830
|
-
}
|
|
4831
|
-
function describe_pr_failure(snapshot) {
|
|
4832
|
-
const reasons = collect_failure_reasons(snapshot);
|
|
4833
|
-
if (reasons.length === 0) return `${FAILURE_MESSAGE_PREFIX}.`;
|
|
4834
|
-
return `${FAILURE_MESSAGE_PREFIX} (${reasons.join("; ")}).`;
|
|
4835
|
-
}
|
|
4836
|
-
function evaluate_pr_state(snapshot) {
|
|
4837
|
-
const statuses = read_required_statuses(snapshot.rollup);
|
|
4838
|
-
const failure = evaluate_failure_state({
|
|
4839
|
-
review_decision: snapshot.review_decision,
|
|
4840
|
-
failed_checks: collect_blocking_failures(snapshot),
|
|
4841
|
-
merge_state_status: snapshot.merge_state_status
|
|
4842
|
-
});
|
|
4843
|
-
if (failure !== void 0) return failure;
|
|
4844
|
-
if (is_mergeable_state(snapshot) && is_every_required_passing(statuses)) {
|
|
4845
|
-
return "success";
|
|
4846
|
-
}
|
|
4847
|
-
return "pending";
|
|
4848
|
-
}
|
|
4849
|
-
function is_review_decision_decisive(snapshot) {
|
|
4850
|
-
return evaluate_pr_state(snapshot) !== "pending";
|
|
4851
|
-
}
|
|
4852
|
-
|
|
4853
|
-
// scripts/gh/git-pr-checks.ts
|
|
4854
|
-
var SECONDS_TO_MS = 1e3;
|
|
4855
|
-
var CHECK_WAIT_INTERVAL_MS = 1e4;
|
|
4856
|
-
var DEFAULT_TIMEOUT_SECONDS = 1920;
|
|
4857
|
-
function compute_max_attempts(timeout_seconds, interval_ms) {
|
|
4858
|
-
return Math.ceil(timeout_seconds / (interval_ms / SECONDS_TO_MS)) + 1;
|
|
4859
|
-
}
|
|
4860
|
-
var DEFAULT_MAX_ATTEMPTS = compute_max_attempts(DEFAULT_TIMEOUT_SECONDS, CHECK_WAIT_INTERVAL_MS);
|
|
4861
|
-
function get_configured_max_attempts() {
|
|
4862
|
-
const environment_seconds = Number(process.env["JOSH_CI_TIMEOUT_SECONDS"]);
|
|
4863
|
-
return Number.isFinite(environment_seconds) && environment_seconds > 0 ? compute_max_attempts(environment_seconds, CHECK_WAIT_INTERVAL_MS) : DEFAULT_MAX_ATTEMPTS;
|
|
4864
|
-
}
|
|
4865
|
-
var CHECK_MAX_ATTEMPTS = get_configured_max_attempts();
|
|
4866
|
-
var DEFAULT_STABLE_READS = 2;
|
|
4867
|
-
var MAX_CONSECUTIVE_READ_FAILURES = 3;
|
|
4868
|
-
var PR_CHECKS_TIMEOUT_MESSAGE = "Timed out while waiting for PR checks to complete.";
|
|
4869
|
-
function is_pr_checks_timeout(error) {
|
|
4870
|
-
return error instanceof Error && error.message === PR_CHECKS_TIMEOUT_MESSAGE;
|
|
4871
|
-
}
|
|
4872
|
-
var SHOULD_ALWAYS_READ_REVIEW_DECISION = () => true;
|
|
4873
|
-
var MERGE_GATE_EVALUATOR = {
|
|
4874
|
-
evaluate: evaluate_pr_state,
|
|
4875
|
-
describe: describe_pr_failure,
|
|
4876
|
-
should_read_review_decision: is_review_decision_decisive
|
|
4877
|
-
};
|
|
4878
|
-
function advance_stable_count(previous, state) {
|
|
4879
|
-
return state === "success" ? previous + 1 : 0;
|
|
4880
|
-
}
|
|
4881
|
-
function classify_poll_result(input) {
|
|
4882
|
-
const state = input.evaluator.evaluate(input.snapshot);
|
|
4883
|
-
if (state === "failure") throw new Error(input.evaluator.describe(input.snapshot));
|
|
4884
|
-
const next_stable_count = advance_stable_count(input.stable_count, state);
|
|
4885
|
-
return {
|
|
4886
|
-
is_done: next_stable_count >= input.required_stable_reads,
|
|
4887
|
-
next_stable_count
|
|
4888
|
-
};
|
|
4889
|
-
}
|
|
4890
|
-
async function read_pr_state(input, evaluator) {
|
|
4891
|
-
try {
|
|
4892
|
-
const snapshot = await input.options.fetcher(
|
|
4893
|
-
input.options.branch_name,
|
|
4894
|
-
evaluator.should_read_review_decision ?? SHOULD_ALWAYS_READ_REVIEW_DECISION
|
|
4895
|
-
);
|
|
4896
|
-
return { kind: "read", snapshot };
|
|
4897
|
-
} catch (error) {
|
|
4898
|
-
return { kind: "unreadable", cause: error };
|
|
4899
|
-
}
|
|
4900
|
-
}
|
|
4901
|
-
async function sleep_before_next_attempt(input) {
|
|
4902
|
-
if (input.attempt < input.options.max_attempts - 1) {
|
|
4903
|
-
await poll.sleep(input.options.interval_ms);
|
|
4904
|
-
}
|
|
4905
|
-
}
|
|
4906
|
-
async function retry_after_unreadable(input, cause) {
|
|
4907
|
-
const next_failure_count = input.failure_count + 1;
|
|
4908
|
-
if (next_failure_count >= MAX_CONSECUTIVE_READ_FAILURES) throw cause;
|
|
4909
|
-
console.warn(
|
|
4910
|
-
`Could not read the PR state (${String(next_failure_count)}/${String(MAX_CONSECUTIVE_READ_FAILURES)}); asking again on the next poll: ${String(cause)}`
|
|
4911
|
-
);
|
|
4912
|
-
await sleep_before_next_attempt(input);
|
|
4913
|
-
return { next_stable_count: 0, next_failure_count, read_failure: cause };
|
|
4914
|
-
}
|
|
4915
|
-
function to_exhaustion_error(last_read_failure) {
|
|
4916
|
-
return last_read_failure ?? new Error(PR_CHECKS_TIMEOUT_MESSAGE);
|
|
4917
|
-
}
|
|
4918
|
-
async function attempt_pr_success_poll(input) {
|
|
4919
|
-
const evaluator = input.options.evaluator ?? MERGE_GATE_EVALUATOR;
|
|
4920
|
-
const read2 = await read_pr_state(input, evaluator);
|
|
4921
|
-
if (read2.kind === "unreadable") return await retry_after_unreadable(input, read2.cause);
|
|
4922
|
-
const classification = classify_poll_result({
|
|
4923
|
-
snapshot: read2.snapshot,
|
|
4924
|
-
stable_count: input.stable_count,
|
|
4925
|
-
required_stable_reads: input.options.required_stable_reads,
|
|
4926
|
-
evaluator
|
|
4927
|
-
});
|
|
4928
|
-
if (classification.is_done) {
|
|
4929
|
-
return { snapshot: read2.snapshot, next_stable_count: 0, next_failure_count: 0 };
|
|
4930
|
-
}
|
|
4931
|
-
await sleep_before_next_attempt(input);
|
|
4932
|
-
return { next_stable_count: classification.next_stable_count, next_failure_count: 0 };
|
|
4933
|
-
}
|
|
4934
|
-
async function wait_for_pr_success(options) {
|
|
4935
|
-
let carried = { next_stable_count: 0, next_failure_count: 0 };
|
|
4936
|
-
for (let attempt = 0; attempt < options.max_attempts; attempt += 1) {
|
|
4937
|
-
console.info(`Checking PR status\u2026 (${String(attempt + 1)}/${String(options.max_attempts)})`);
|
|
4938
|
-
carried = await attempt_pr_success_poll({
|
|
4939
|
-
options,
|
|
4940
|
-
stable_count: carried.next_stable_count,
|
|
4941
|
-
failure_count: carried.next_failure_count,
|
|
4942
|
-
attempt
|
|
4943
|
-
});
|
|
4944
|
-
if (carried.snapshot !== void 0) return carried.snapshot;
|
|
4945
|
-
}
|
|
4946
|
-
throw to_exhaustion_error(carried.read_failure);
|
|
4947
|
-
}
|
|
4948
|
-
async function default_fetch_pr_state(branch_name, should_read_review_decision = SHOULD_ALWAYS_READ_REVIEW_DECISION) {
|
|
4949
|
-
const checks = await git_gh_pr_snapshot.pr_get_checks_snapshot(branch_name);
|
|
4950
|
-
const snapshot = parse_pr_state_snapshot(checks.snapshot_json);
|
|
4951
|
-
if (!should_read_review_decision(snapshot)) return snapshot;
|
|
4952
|
-
const decision = await git_gh_pr_snapshot.pr_get_review_decision(checks.pr_number);
|
|
4953
|
-
return { ...snapshot, review_decision: read_string(decision) };
|
|
4954
|
-
}
|
|
4955
|
-
|
|
4956
|
-
// scripts/gh/git-pr-checks-watch.ts
|
|
4957
|
-
var PR_CHECKS_WATCH_TIMEOUT_MS = 12e4;
|
|
4958
|
-
var WATCH_TIMED_OUT_NOTE = "\u23F1\uFE0F pr checks --watch timed out.";
|
|
4959
|
-
var NO_CHECKS_MESSAGE = "gh api reported no checks on the branch";
|
|
4960
|
-
var CHECKS_FAILED_MESSAGE = "gh api reported a failing check on the branch";
|
|
4961
|
-
function is_awaited_check(check4) {
|
|
4962
|
-
return !is_coderabbit_check(check4.name) || is_required_check(check4.name);
|
|
4963
|
-
}
|
|
4964
|
-
function evaluate_checks_settled(snapshot) {
|
|
4965
|
-
const awaited = snapshot.rollup.filter((check4) => is_awaited_check(check4));
|
|
4966
|
-
const considered = awaited.length === 0 ? snapshot.rollup : awaited;
|
|
4967
|
-
if (considered.length === 0 || considered.some((check4) => check4.status === CHECK_STATUS_PENDING)) {
|
|
4968
|
-
return "pending";
|
|
4969
|
-
}
|
|
4970
|
-
return snapshot.rollup.some((check4) => check4.status === CHECK_STATUS_FAIL) ? "failure" : "success";
|
|
4971
|
-
}
|
|
4972
|
-
function describe_checks_failure(snapshot) {
|
|
4973
|
-
const failed = snapshot.rollup.filter((check4) => check4.status === CHECK_STATUS_FAIL);
|
|
4974
|
-
return `${CHECKS_FAILED_MESSAGE}: ${failed.map((check4) => check4.name).join(", ")}`;
|
|
4975
|
-
}
|
|
4976
|
-
var SHOULD_NEVER_READ_REVIEW_DECISION = () => false;
|
|
4977
|
-
var CHECKS_SETTLED_EVALUATOR = {
|
|
4978
|
-
evaluate: evaluate_checks_settled,
|
|
4979
|
-
describe: describe_checks_failure,
|
|
4980
|
-
should_read_review_decision: SHOULD_NEVER_READ_REVIEW_DECISION
|
|
4981
|
-
};
|
|
4982
|
-
async function watch_until_settled(branch_name) {
|
|
4983
|
-
await wait_for_pr_success({
|
|
4984
|
-
branch_name,
|
|
4985
|
-
fetcher: default_fetch_pr_state,
|
|
4986
|
-
interval_ms: CHECK_WAIT_INTERVAL_MS,
|
|
4987
|
-
max_attempts: compute_max_attempts(
|
|
4988
|
-
PR_CHECKS_WATCH_TIMEOUT_MS / SECONDS_TO_MS,
|
|
4989
|
-
CHECK_WAIT_INTERVAL_MS
|
|
4990
|
-
),
|
|
4991
|
-
required_stable_reads: DEFAULT_STABLE_READS,
|
|
4992
|
-
evaluator: CHECKS_SETTLED_EVALUATOR
|
|
4993
|
-
});
|
|
4994
|
-
}
|
|
4995
|
-
async function fail_when_no_checks(branch_name) {
|
|
4996
|
-
const snapshot = await default_fetch_pr_state(branch_name, SHOULD_NEVER_READ_REVIEW_DECISION);
|
|
4997
|
-
if (snapshot.rollup.length === 0) throw new Error(NO_CHECKS_MESSAGE);
|
|
4998
|
-
}
|
|
4999
|
-
async function pr_checks_watch(branch_name) {
|
|
5000
|
-
try {
|
|
5001
|
-
await watch_until_settled(branch_name);
|
|
5002
|
-
return { timed_out: false };
|
|
5003
|
-
} catch (error) {
|
|
5004
|
-
if (!is_pr_checks_timeout(error)) throw error;
|
|
5005
|
-
await fail_when_no_checks(branch_name);
|
|
5006
|
-
console.info(WATCH_TIMED_OUT_NOTE);
|
|
5007
|
-
return { timed_out: true };
|
|
5008
|
-
}
|
|
5009
|
-
}
|
|
5010
|
-
var git_pr_checks_watch = { pr_checks_watch };
|
|
5011
|
-
|
|
5012
|
-
// scripts/gh/git-gh-command.ts
|
|
5013
|
-
var git_gh_command = {
|
|
5014
|
-
...git_gh_pr,
|
|
5015
|
-
...git_gh_pr_auto_merge,
|
|
5016
|
-
pr_checks_watch: git_pr_checks_watch.pr_checks_watch,
|
|
5017
|
-
...git_gh_issue,
|
|
5018
|
-
...git_gh_repo
|
|
5019
|
-
};
|
|
5020
|
-
|
|
5021
3306
|
// scripts/epic/epic-busy.ts
|
|
5022
3307
|
var LISTING_LIMIT = 100;
|
|
5023
3308
|
var PARKED_LABELS = /* @__PURE__ */ new Set([NEEDS_DECISION_LABEL, ALREADY_DONE_LABEL]);
|
|
@@ -5080,30 +3365,30 @@ var epic_busy = {
|
|
|
5080
3365
|
};
|
|
5081
3366
|
|
|
5082
3367
|
// scripts/run/run-liveness.ts
|
|
5083
|
-
import { readFileSync as
|
|
3368
|
+
import { readFileSync as readFileSync5, realpathSync, statSync } from "node:fs";
|
|
5084
3369
|
import { homedir, tmpdir } from "node:os";
|
|
5085
3370
|
import path8 from "node:path";
|
|
5086
|
-
import { setTimeout as
|
|
3371
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
5087
3372
|
|
|
5088
3373
|
// scripts/agent/agent-event.ts
|
|
5089
|
-
import { z as
|
|
3374
|
+
import { z as z9 } from "zod";
|
|
5090
3375
|
|
|
5091
3376
|
// scripts/agent/claude-result-event.ts
|
|
5092
|
-
import { z as
|
|
5093
|
-
var RESULT_EVENT_SCHEMA =
|
|
5094
|
-
type:
|
|
5095
|
-
is_error:
|
|
5096
|
-
subtype:
|
|
5097
|
-
num_turns:
|
|
5098
|
-
permission_denials:
|
|
5099
|
-
result:
|
|
5100
|
-
session_id:
|
|
5101
|
-
usage:
|
|
3377
|
+
import { z as z8 } from "zod";
|
|
3378
|
+
var RESULT_EVENT_SCHEMA = z8.looseObject({
|
|
3379
|
+
type: z8.literal("result"),
|
|
3380
|
+
is_error: z8.unknown().optional(),
|
|
3381
|
+
subtype: z8.unknown().optional(),
|
|
3382
|
+
num_turns: z8.unknown().optional(),
|
|
3383
|
+
permission_denials: z8.unknown().optional(),
|
|
3384
|
+
result: z8.unknown().optional(),
|
|
3385
|
+
session_id: z8.unknown().optional(),
|
|
3386
|
+
usage: z8.unknown().optional()
|
|
5102
3387
|
});
|
|
5103
|
-
var USAGE_SCHEMA =
|
|
5104
|
-
input_tokens:
|
|
5105
|
-
cache_read_input_tokens:
|
|
5106
|
-
output_tokens:
|
|
3388
|
+
var USAGE_SCHEMA = z8.looseObject({
|
|
3389
|
+
input_tokens: z8.unknown().optional(),
|
|
3390
|
+
cache_read_input_tokens: z8.unknown().optional(),
|
|
3391
|
+
output_tokens: z8.unknown().optional()
|
|
5107
3392
|
});
|
|
5108
3393
|
function usable_reason(value) {
|
|
5109
3394
|
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
@@ -5142,31 +3427,31 @@ function decode(value) {
|
|
|
5142
3427
|
var claude_result_event = { decode };
|
|
5143
3428
|
|
|
5144
3429
|
// scripts/agent/agent-event.ts
|
|
5145
|
-
var TEXT_BLOCK_SCHEMA =
|
|
5146
|
-
var CLAUDE_MESSAGE_SCHEMA =
|
|
5147
|
-
var CLAUDE_INIT_SCHEMA =
|
|
5148
|
-
var CLAUDE_ASSISTANT_SCHEMA =
|
|
5149
|
-
type:
|
|
3430
|
+
var TEXT_BLOCK_SCHEMA = z9.looseObject({ type: z9.literal("text"), text: z9.string() });
|
|
3431
|
+
var CLAUDE_MESSAGE_SCHEMA = z9.looseObject({ content: z9.array(z9.unknown()).optional() });
|
|
3432
|
+
var CLAUDE_INIT_SCHEMA = z9.looseObject({ type: z9.literal("system"), subtype: z9.literal("init") });
|
|
3433
|
+
var CLAUDE_ASSISTANT_SCHEMA = z9.looseObject({
|
|
3434
|
+
type: z9.literal("assistant"),
|
|
5150
3435
|
message: CLAUDE_MESSAGE_SCHEMA
|
|
5151
3436
|
});
|
|
5152
|
-
var USAGE_SCHEMA2 =
|
|
5153
|
-
input_tokens:
|
|
5154
|
-
cached_input_tokens:
|
|
5155
|
-
output_tokens:
|
|
3437
|
+
var USAGE_SCHEMA2 = z9.looseObject({
|
|
3438
|
+
input_tokens: z9.number().optional(),
|
|
3439
|
+
cached_input_tokens: z9.number().optional(),
|
|
3440
|
+
output_tokens: z9.number().optional()
|
|
5156
3441
|
});
|
|
5157
|
-
var CODEX_START_SCHEMA =
|
|
5158
|
-
var CODEX_PROGRESS_SCHEMA =
|
|
5159
|
-
type:
|
|
5160
|
-
item:
|
|
3442
|
+
var CODEX_START_SCHEMA = z9.looseObject({ type: z9.enum(["thread.started", "turn.started"]) });
|
|
3443
|
+
var CODEX_PROGRESS_SCHEMA = z9.looseObject({
|
|
3444
|
+
type: z9.enum(["item.started", "item.updated", "item.completed"]),
|
|
3445
|
+
item: z9.looseObject({ type: z9.string(), text: z9.string().optional() }).optional()
|
|
5161
3446
|
});
|
|
5162
|
-
var CODEX_COMPLETE_SCHEMA =
|
|
5163
|
-
type:
|
|
3447
|
+
var CODEX_COMPLETE_SCHEMA = z9.looseObject({
|
|
3448
|
+
type: z9.literal("turn.completed"),
|
|
5164
3449
|
usage: USAGE_SCHEMA2.optional()
|
|
5165
3450
|
});
|
|
5166
|
-
var CODEX_FAILURE_SCHEMA =
|
|
5167
|
-
type:
|
|
5168
|
-
error:
|
|
5169
|
-
message:
|
|
3451
|
+
var CODEX_FAILURE_SCHEMA = z9.looseObject({
|
|
3452
|
+
type: z9.enum(["turn.failed", "error"]),
|
|
3453
|
+
error: z9.looseObject({ message: z9.string().optional() }).optional(),
|
|
3454
|
+
message: z9.string().optional()
|
|
5170
3455
|
});
|
|
5171
3456
|
var EMPTY_STATE = {
|
|
5172
3457
|
provider: void 0,
|
|
@@ -5257,7 +3542,7 @@ function describe(state) {
|
|
|
5257
3542
|
var agent_event = { describe, read };
|
|
5258
3543
|
|
|
5259
3544
|
// scripts/issue/issue-state.ts
|
|
5260
|
-
import { z as
|
|
3545
|
+
import { z as z10 } from "zod";
|
|
5261
3546
|
var NO_LABELS = "(none)";
|
|
5262
3547
|
var LABEL_SEPARATOR = ", ";
|
|
5263
3548
|
var STATE_LABEL = "state: ";
|
|
@@ -5267,9 +3552,9 @@ var YES = "yes";
|
|
|
5267
3552
|
var NO = "no";
|
|
5268
3553
|
var ISSUE_LABEL = "issue: ";
|
|
5269
3554
|
var HUMAN_REVIEW_LABELS = /* @__PURE__ */ new Set([NEEDS_HUMAN_REVIEW_LABEL]);
|
|
5270
|
-
var label_schema =
|
|
5271
|
-
var issue_state_schema =
|
|
5272
|
-
state:
|
|
3555
|
+
var label_schema = z10.looseObject({ name: z10.string() });
|
|
3556
|
+
var issue_state_schema = z10.looseObject({
|
|
3557
|
+
state: z10.string(),
|
|
5273
3558
|
labels: label_schema.array().optional()
|
|
5274
3559
|
});
|
|
5275
3560
|
function parse_issue_state(json) {
|
|
@@ -5317,7 +3602,7 @@ var DEFAULT_SILENT_MINUTES = 30;
|
|
|
5317
3602
|
var DEFAULT_GAP_SECONDS = 5;
|
|
5318
3603
|
var MS_PER_MINUTE3 = 6e4;
|
|
5319
3604
|
var MS_PER_SECOND2 = 1e3;
|
|
5320
|
-
var
|
|
3605
|
+
var OPEN_STATE2 = "OPEN";
|
|
5321
3606
|
var STATE_FIELDS = "state,labels";
|
|
5322
3607
|
var REASONS = {
|
|
5323
3608
|
[ALIVE_VERDICT]: "The unit is still working: its output moved, or a process of the child is alive.",
|
|
@@ -5405,7 +3690,7 @@ function read_agent_state(output_path) {
|
|
|
5405
3690
|
const safe_path = to_safe_path(output_path);
|
|
5406
3691
|
if (safe_path === void 0) return void 0;
|
|
5407
3692
|
try {
|
|
5408
|
-
const state = agent_event.read(
|
|
3693
|
+
const state = agent_event.read(readFileSync5(safe_path, "utf8"));
|
|
5409
3694
|
return state.provider === void 0 ? void 0 : state;
|
|
5410
3695
|
} catch {
|
|
5411
3696
|
return void 0;
|
|
@@ -5419,7 +3704,7 @@ async function read_output_frozen(request) {
|
|
|
5419
3704
|
const first = sample_output(request.output_path);
|
|
5420
3705
|
if (first === void 0) return void 0;
|
|
5421
3706
|
if (request.now_ms - first.mtime_ms < request.silent_window_ms) return false;
|
|
5422
|
-
await
|
|
3707
|
+
await sleep(request.gap_ms);
|
|
5423
3708
|
const second = sample_output(request.output_path);
|
|
5424
3709
|
if (second === void 0) return void 0;
|
|
5425
3710
|
return second.mtime_ms === first.mtime_ms && second.size === first.size;
|
|
@@ -5436,7 +3721,7 @@ async function read_child_settled(issue, repo) {
|
|
|
5436
3721
|
if (json === void 0) return void 0;
|
|
5437
3722
|
const state = issue_state.parse_issue_state(json);
|
|
5438
3723
|
if (state === void 0) return void 0;
|
|
5439
|
-
return state.state !==
|
|
3724
|
+
return state.state !== OPEN_STATE2 || carries_settled_label(state.labels);
|
|
5440
3725
|
}
|
|
5441
3726
|
async function read_traces(request) {
|
|
5442
3727
|
const [is_initial_child_settled, is_output_frozen, is_tree_dirty] = await Promise.all([
|
|
@@ -5476,14 +3761,14 @@ var run_liveness = {
|
|
|
5476
3761
|
|
|
5477
3762
|
// scripts/lane/lane-report.ts
|
|
5478
3763
|
var NO_LANES2 = "No lanes are open.";
|
|
5479
|
-
var
|
|
3764
|
+
var OPEN_STATE3 = "open";
|
|
5480
3765
|
var STRANDED_STATE = "stranded";
|
|
5481
3766
|
var UNREADABLE_STATE = "unreadable";
|
|
5482
3767
|
var UNKNOWN_VALUE = "-";
|
|
5483
3768
|
var COLUMN_SEPARATOR = " ";
|
|
5484
3769
|
function lane_state(lane) {
|
|
5485
3770
|
if (lane.is_stranded) return STRANDED_STATE;
|
|
5486
|
-
return lane.seat === void 0 ? UNREADABLE_STATE :
|
|
3771
|
+
return lane.seat === void 0 ? UNREADABLE_STATE : OPEN_STATE3;
|
|
5487
3772
|
}
|
|
5488
3773
|
function value_or_unknown(value) {
|
|
5489
3774
|
return value === void 0 ? UNKNOWN_VALUE : String(value);
|
|
@@ -5527,7 +3812,7 @@ function describe_opened(lane) {
|
|
|
5527
3812
|
}
|
|
5528
3813
|
var lane_report = {
|
|
5529
3814
|
NO_LANES: NO_LANES2,
|
|
5530
|
-
OPEN_STATE:
|
|
3815
|
+
OPEN_STATE: OPEN_STATE3,
|
|
5531
3816
|
STRANDED_STATE,
|
|
5532
3817
|
UNREADABLE_STATE,
|
|
5533
3818
|
describe_lane,
|
|
@@ -5537,7 +3822,7 @@ var lane_report = {
|
|
|
5537
3822
|
};
|
|
5538
3823
|
|
|
5539
3824
|
// scripts/run/run-preflight.ts
|
|
5540
|
-
import { z as
|
|
3825
|
+
import { z as z11 } from "zod";
|
|
5541
3826
|
var CLEAN_VERDICT = "clean";
|
|
5542
3827
|
var RECLAIM_VERDICT = "reclaim";
|
|
5543
3828
|
var RESUME_VERDICT = "resume";
|
|
@@ -5547,7 +3832,7 @@ var OPEN_PR = "open";
|
|
|
5547
3832
|
var MERGED_PR = "merged";
|
|
5548
3833
|
var CLOSED_PR = "closed";
|
|
5549
3834
|
var NO_CHILD_WORK = { branch_name: void 0, pr_state: NO_PR };
|
|
5550
|
-
var
|
|
3835
|
+
var pr_info_schema = z11.object({ state: z11.string().optional() });
|
|
5551
3836
|
var GH_PR_STATES = /* @__PURE__ */ new Map([
|
|
5552
3837
|
["CLOSED", CLOSED_PR],
|
|
5553
3838
|
["MERGED", MERGED_PR],
|
|
@@ -5626,12 +3911,12 @@ function decide5(tree, child, issue) {
|
|
|
5626
3911
|
}
|
|
5627
3912
|
function read_pr_field(raw) {
|
|
5628
3913
|
try {
|
|
5629
|
-
return
|
|
3914
|
+
return pr_info_schema.parse(JSON.parse(raw)).state;
|
|
5630
3915
|
} catch {
|
|
5631
3916
|
return void 0;
|
|
5632
3917
|
}
|
|
5633
3918
|
}
|
|
5634
|
-
function
|
|
3919
|
+
function to_pr_state(raw) {
|
|
5635
3920
|
const state = read_pr_field(raw);
|
|
5636
3921
|
return (state === void 0 ? void 0 : GH_PR_STATES.get(state)) ?? NO_PR;
|
|
5637
3922
|
}
|
|
@@ -5643,17 +3928,17 @@ async function read_tree_state() {
|
|
|
5643
3928
|
]);
|
|
5644
3929
|
return { branch: current, default_branch, is_dirty };
|
|
5645
3930
|
}
|
|
5646
|
-
async function
|
|
3931
|
+
async function read_pr_state(branch_name) {
|
|
5647
3932
|
if (!await git_gh_pr_read.pr_exists(branch_name)) return NO_PR;
|
|
5648
3933
|
const raw = await git_gh_pr_read.pr_view(branch_name);
|
|
5649
3934
|
if (raw === "") throw new Error(`${UNREADABLE_PR_MESSAGE}${branch_name}`);
|
|
5650
|
-
return
|
|
3935
|
+
return to_pr_state(raw);
|
|
5651
3936
|
}
|
|
5652
3937
|
function is_pr_open(state) {
|
|
5653
3938
|
return state === OPEN_PR;
|
|
5654
3939
|
}
|
|
5655
3940
|
async function read_pr_of_branch(branch_name) {
|
|
5656
|
-
return { branch_name, pr_state: await
|
|
3941
|
+
return { branch_name, pr_state: await read_pr_state(branch_name) };
|
|
5657
3942
|
}
|
|
5658
3943
|
function pick_child_state(reads) {
|
|
5659
3944
|
const decided = reads.find((read2) => is_pr_decided(read2.pr_state));
|
|
@@ -5728,8 +4013,8 @@ var run_preflight = {
|
|
|
5728
4013
|
check: check2,
|
|
5729
4014
|
decide: decide5,
|
|
5730
4015
|
read_child_state,
|
|
5731
|
-
read_pr_state
|
|
5732
|
-
to_pr_state
|
|
4016
|
+
read_pr_state,
|
|
4017
|
+
to_pr_state
|
|
5733
4018
|
};
|
|
5734
4019
|
|
|
5735
4020
|
// scripts/run/run-progress-read.ts
|
|
@@ -5829,7 +4114,7 @@ var TICK_MULTIPLIER = 3;
|
|
|
5829
4114
|
var MS_PER_SECOND3 = 1e3;
|
|
5830
4115
|
var STALE_THRESHOLD_MS = WATCHER_TICK_MS * TICK_MULTIPLIER;
|
|
5831
4116
|
var STALE_THRESHOLD_S = STALE_THRESHOLD_MS / MS_PER_SECOND3;
|
|
5832
|
-
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`;
|
|
4117
|
+
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. It reports to the run event stream on its own and exits only when newly runnable work arrives, so start it once and relay nothing`;
|
|
5833
4118
|
var OK_RESULT = { kind: "ok" };
|
|
5834
4119
|
async function owes_watcher() {
|
|
5835
4120
|
if (!await run_headless.is_backlog_parent()) return false;
|
|
@@ -5849,7 +4134,7 @@ var run_watcher_guard = {
|
|
|
5849
4134
|
// scripts/run/run-watcher-hook.ts
|
|
5850
4135
|
var SWITCH_ENV_KEY2 = "JOSH_WATCHER_GUARD";
|
|
5851
4136
|
var STAMP_PREFIX2 = "josh-watcher-guard-";
|
|
5852
|
-
var payload_schema =
|
|
4137
|
+
var payload_schema = z12.object({ transcript_path: z12.string().min(1) });
|
|
5853
4138
|
function transcript_of(raw_payload) {
|
|
5854
4139
|
try {
|
|
5855
4140
|
const parsed = payload_schema.safeParse(JSON.parse(raw_payload));
|
|
@@ -5910,7 +4195,8 @@ async function refusal_for(transcript, now_ms, state) {
|
|
|
5910
4195
|
function is_unit_call(raw_payload) {
|
|
5911
4196
|
try {
|
|
5912
4197
|
return (hook_decision.parse_hook_payload(raw_payload)?.agent_id ?? "") !== "";
|
|
5913
|
-
} catch {
|
|
4198
|
+
} catch (error) {
|
|
4199
|
+
error_text.trace_swallowed("run_parent_cut_hook.is_unit_call", error);
|
|
5914
4200
|
return false;
|
|
5915
4201
|
}
|
|
5916
4202
|
}
|