@joshuafolkken/kit 1.983.0 → 1.1003.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/workflow-commands/backlogrun-child.md +4 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +1 -1
- package/.github/workflows/sonar-qube.yml +12 -2
- package/CLAUDE.md +2 -2
- package/README.md +30 -21
- package/dist/CLAUDE.md +2 -2
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-ZT65LR3U.js → chunk-4GDR2YTV.js} +4 -4
- package/dist/hooks/{chunk-ASUZGZFT.js → chunk-56LGMJJV.js} +2 -2
- package/dist/hooks/{chunk-LBXQHXMC.js → chunk-6PSTVOLH.js} +263 -74
- package/dist/hooks/{chunk-P3UX7SFN.js → chunk-A2H5I2VD.js} +2 -2
- package/dist/hooks/{chunk-ERXMJJOV.js → chunk-AWTFKKFW.js} +1 -1
- package/dist/hooks/{chunk-IM3KM25Y.js → chunk-EZLHXKJ6.js} +10 -7
- package/dist/hooks/{chunk-APVOACVT.js → chunk-GBJUERYK.js} +1 -1
- package/dist/hooks/{chunk-5JX6HXDX.js → chunk-KPZN42RT.js} +3 -3
- package/dist/hooks/{chunk-47SPMGOD.js → chunk-PAXMLGSS.js} +26 -7
- package/dist/hooks/{chunk-RFPHKU7C.js → chunk-WMIR5SNX.js} +3 -3
- package/dist/hooks/codex-hook-adapter.js +10 -10
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/stop-guard.js +98 -26
- package/dist/josh.js +5 -5
- package/package.json +5 -1
- package/prettier/basic.d.ts +3 -0
- package/prettier/basic.js +10 -0
- package/prettier/index.js +2 -2
- package/prettier/static.js +3 -10
- package/prompts/sonar-hotspot-handling.md +6 -0
- package/prompts/testing-guide.md +1 -1
- package/scripts/agent/agent-diagnostics.ts +1 -0
- package/scripts/agent/agent-role-profile.ts +1 -1
- package/scripts/behavior/behavior-rules.ts +8 -1
- package/scripts/build/build-claude-md.ts +13 -4
- package/scripts/ci/pr-classification.ts +11 -2
- package/scripts/document/document-byte-budget.ts +1 -1
- package/scripts/gate/gate-steps.ts +1 -1
- package/scripts/gate/project-checks.ts +12 -11
- package/scripts/gate/type-check-command.ts +1 -1
- package/scripts/git/git-branch.ts +14 -3
- package/scripts/git/git-command.ts +5 -2
- package/scripts/git/git-issue.ts +13 -5
- package/scripts/git/git-pr.ts +16 -10
- package/scripts/git/git-preflight.ts +138 -0
- package/scripts/git/telegram-notify.ts +21 -0
- package/scripts/hooks/stop-guard.ts +2 -0
- package/scripts/init/basic-path-migration.ts +24 -0
- package/scripts/init/distributed-paths.ts +22 -0
- package/scripts/init/init-actions.ts +27 -19
- package/scripts/init/init-ai-copy.ts +86 -28
- package/scripts/init/{init-static.ts → init-basic.ts} +6 -6
- package/scripts/init/init-bootstrap.ts +4 -3
- package/scripts/init/init-install.ts +1 -1
- package/scripts/init/init-logic-templates.ts +1 -1
- package/scripts/init/init-logic.ts +1 -1
- package/scripts/init/init.ts +41 -19
- package/scripts/init/kit-setup-state.ts +30 -0
- package/scripts/init/kit-written-paths.ts +33 -0
- package/scripts/init/project-profile-cli.ts +15 -1
- package/scripts/init/project-profile.ts +41 -12
- package/scripts/init/session-language-environment.ts +83 -0
- package/scripts/init/start-exec.ts +28 -0
- package/scripts/init/start-plan.ts +35 -13
- package/scripts/init/start-prompt.ts +22 -8
- package/scripts/init/start-setup-pr.ts +138 -0
- package/scripts/init/start-steps.ts +30 -30
- package/scripts/init/start.ts +7 -3
- package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +3 -3
- package/scripts/josh/josh-commands-development.ts +3 -3
- package/scripts/josh/josh-commands-project.ts +2 -2
- package/scripts/lane/lane-leftover.ts +143 -0
- package/scripts/lane/lane-open.ts +14 -1
- package/scripts/lint/cspell-cached.ts +3 -3
- package/scripts/lint/format.ts +1 -1
- package/scripts/lint/lint-parallel.ts +2 -2
- package/scripts/propagate/propagate-steps.ts +14 -1
- package/scripts/rules/filing-cap.ts +1 -0
- package/scripts/rules/issue-citation.ts +30 -1
- package/scripts/rules/last-prompt.ts +79 -0
- package/scripts/rules/stop-rules.ts +5 -3
- package/scripts/run/run-hold.ts +3 -3
- package/scripts/run/run-preflight.ts +75 -5
- package/scripts/run/run-progress-cli.ts +14 -2
- package/scripts/safe-chain/ci-installer-pin.ts +19 -12
- package/scripts/safe-chain/project-config.ts +1 -1
- package/scripts/sync/sync-ai-files.ts +204 -0
- package/scripts/sync/sync.ts +48 -184
- package/scripts/test/josh-harness-environment.ts +1 -1
- package/scripts/test/pilot-files.ts +0 -1
- package/scripts/test/test-declared-changed.ts +1 -1
- package/scripts/test/test-declared-logic.ts +55 -14
- package/scripts/test/test-declared.ts +23 -11
- package/scripts/test/test-unit-guard.ts +6 -6
- package/scripts/time-runtime/time-shell.ts +36 -2
- package/scripts-ai/git-workflow.ts +10 -0
- package/templates/CLAUDE.basic.md +8 -0
- package/templates/workflows/ci.yml +27 -0
- /package/{templates/CLAUDE.static.md → dist/CLAUDE.basic.md} +0 -0
- /package/templates/{cursorrules.static → cursorrules.basic} +0 -0
- /package/templates/{pnpm-workspace.static.yaml → pnpm-workspace.basic.yaml} +0 -0
- /package/templates/{prettierignore.static → prettierignore.basic} +0 -0
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
parse_json_array_or_undefined,
|
|
27
27
|
parse_json_object_safe,
|
|
28
28
|
read_json_listing,
|
|
29
|
+
repo_origin,
|
|
29
30
|
repo_party,
|
|
30
31
|
run_carry,
|
|
31
32
|
run_cut,
|
|
@@ -35,31 +36,31 @@ import {
|
|
|
35
36
|
run_watcher_guard,
|
|
36
37
|
shell_segments,
|
|
37
38
|
tail_commands
|
|
38
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-EZLHXKJ6.js";
|
|
39
40
|
import {
|
|
40
41
|
find_local_bin_upwards
|
|
41
42
|
} from "./chunk-3V37IID6.js";
|
|
42
43
|
import {
|
|
43
44
|
batch_outcome
|
|
44
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-A2H5I2VD.js";
|
|
45
46
|
import {
|
|
46
47
|
investigation_refusal
|
|
47
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-KPZN42RT.js";
|
|
48
49
|
import {
|
|
49
50
|
duplicate_read_outcome
|
|
50
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-4GDR2YTV.js";
|
|
51
52
|
import {
|
|
52
53
|
investigation_reads
|
|
53
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-WMIR5SNX.js";
|
|
54
55
|
import {
|
|
55
56
|
lane_guard_policy,
|
|
56
57
|
time_batch_guard
|
|
57
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-56LGMJJV.js";
|
|
58
59
|
import {
|
|
59
60
|
hook_decision,
|
|
60
61
|
lane_child_marker,
|
|
61
62
|
run_issue_number
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-GBJUERYK.js";
|
|
63
64
|
import {
|
|
64
65
|
PLATFORM_TEMP_ROOT,
|
|
65
66
|
cost_attribute,
|
|
@@ -70,7 +71,7 @@ import {
|
|
|
70
71
|
lane_paths,
|
|
71
72
|
stamp_file,
|
|
72
73
|
time_shell
|
|
73
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-PAXMLGSS.js";
|
|
74
75
|
|
|
75
76
|
// scripts/hooks/pretool-guard.ts
|
|
76
77
|
import { text } from "node:stream/consumers";
|
|
@@ -827,8 +828,8 @@ function selected_threshold(values) {
|
|
|
827
828
|
function threshold_option(over) {
|
|
828
829
|
return over === void 0 ? {} : { over };
|
|
829
830
|
}
|
|
830
|
-
function path_option(
|
|
831
|
-
return
|
|
831
|
+
function path_option(path7) {
|
|
832
|
+
return path7 === void 0 ? {} : { path: path7 };
|
|
832
833
|
}
|
|
833
834
|
function to_options(values) {
|
|
834
835
|
if (values.cut === true && values.over !== void 0) return void 0;
|
|
@@ -2009,9 +2010,133 @@ var shell_body_trigger = {
|
|
|
2009
2010
|
import { execFileSync } from "node:child_process";
|
|
2010
2011
|
|
|
2011
2012
|
// scripts/gate/project-checks.ts
|
|
2012
|
-
import { existsSync as
|
|
2013
|
+
import { existsSync as existsSync4, globSync as globSync2, readFileSync as readFileSync5 } from "node:fs";
|
|
2014
|
+
import path5 from "node:path";
|
|
2015
|
+
|
|
2016
|
+
// scripts/init/project-profile.ts
|
|
2017
|
+
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync4 } from "node:fs";
|
|
2013
2018
|
import path4 from "node:path";
|
|
2014
2019
|
|
|
2020
|
+
// scripts/version/kit-descriptor.ts
|
|
2021
|
+
var KIT_PACKAGE_NAME = "@joshuafolkken/kit";
|
|
2022
|
+
|
|
2023
|
+
// scripts/init/project-profile.ts
|
|
2024
|
+
import { execaSync } from "execa";
|
|
2025
|
+
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", ".svelte-kit"]);
|
|
2026
|
+
var WEB_EXTENSIONS = /* @__PURE__ */ new Set([".html", ".css", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
2027
|
+
var TYPESCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx"]);
|
|
2028
|
+
var PROFILE_ARG_LENGTH = 2;
|
|
2029
|
+
var PROFILE_NAMES = {
|
|
2030
|
+
basic: "basic",
|
|
2031
|
+
full: "full",
|
|
2032
|
+
static: "basic",
|
|
2033
|
+
node: "full"
|
|
2034
|
+
};
|
|
2035
|
+
function parse_profile(value) {
|
|
2036
|
+
return typeof value === "string" && Object.hasOwn(PROFILE_NAMES, value) ? PROFILE_NAMES[value] : void 0;
|
|
2037
|
+
}
|
|
2038
|
+
var LEGACY_NAMES = { basic: "static", full: "node" };
|
|
2039
|
+
function with_legacy_profile_names(args) {
|
|
2040
|
+
return args.map((argument, index) => {
|
|
2041
|
+
const profile = args[index - 1] === "--profile" ? parse_profile(argument) : void 0;
|
|
2042
|
+
return profile === void 0 ? argument : LEGACY_NAMES[profile];
|
|
2043
|
+
});
|
|
2044
|
+
}
|
|
2045
|
+
function is_profile_pair(args) {
|
|
2046
|
+
return args.length === PROFILE_ARG_LENGTH && args[0] === "--profile";
|
|
2047
|
+
}
|
|
2048
|
+
function requested_profile(args, usage = "josh init [--profile basic|full]") {
|
|
2049
|
+
if (args.length === 0) return void 0;
|
|
2050
|
+
if (!is_profile_pair(args)) throw new Error(`Usage: ${usage}`);
|
|
2051
|
+
const profile = parse_profile(args[1]);
|
|
2052
|
+
if (profile !== void 0) return profile;
|
|
2053
|
+
throw new Error("Profile must be basic or full");
|
|
2054
|
+
}
|
|
2055
|
+
function read_manifest(root) {
|
|
2056
|
+
const filename = path4.join(root, "package.json");
|
|
2057
|
+
if (!existsSync3(filename)) return void 0;
|
|
2058
|
+
const parsed = JSON.parse(readFileSync4(filename, "utf8"));
|
|
2059
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
2060
|
+
throw new Error("package.json must contain an object");
|
|
2061
|
+
}
|
|
2062
|
+
return parsed;
|
|
2063
|
+
}
|
|
2064
|
+
function is_record(value) {
|
|
2065
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2066
|
+
}
|
|
2067
|
+
function recorded_profile(manifest) {
|
|
2068
|
+
const { josh } = manifest;
|
|
2069
|
+
return is_record(josh) ? parse_profile(josh["profile"]) : void 0;
|
|
2070
|
+
}
|
|
2071
|
+
function has_build_script(value) {
|
|
2072
|
+
return is_record(value) && ("build" in value || "dev" in value);
|
|
2073
|
+
}
|
|
2074
|
+
function has_project_dependencies(value) {
|
|
2075
|
+
if (!is_record(value)) return false;
|
|
2076
|
+
return Object.keys(value).some((name) => name !== KIT_PACKAGE_NAME);
|
|
2077
|
+
}
|
|
2078
|
+
function inferred_profile(manifest) {
|
|
2079
|
+
if (has_project_dependencies(manifest["dependencies"]) || has_project_dependencies(manifest["devDependencies"])) {
|
|
2080
|
+
return { profile: "full", reason: "package dependencies" };
|
|
2081
|
+
}
|
|
2082
|
+
if (has_build_script(manifest["scripts"])) {
|
|
2083
|
+
return { profile: "full", reason: "build or dev script" };
|
|
2084
|
+
}
|
|
2085
|
+
return { profile: "basic", reason: "metadata-only package.json" };
|
|
2086
|
+
}
|
|
2087
|
+
function resolve_profile(root, requested) {
|
|
2088
|
+
if (requested !== void 0) return { profile: requested, reason: "explicit --profile" };
|
|
2089
|
+
const manifest = read_manifest(root);
|
|
2090
|
+
if (manifest === void 0) return { profile: "basic", reason: "no package.json" };
|
|
2091
|
+
const profile = recorded_profile(manifest);
|
|
2092
|
+
if (profile !== void 0) return { profile, reason: "package.json josh.profile" };
|
|
2093
|
+
return inferred_profile(manifest);
|
|
2094
|
+
}
|
|
2095
|
+
function should_visit(entry) {
|
|
2096
|
+
return entry.isDirectory() && !IGNORED_DIRECTORIES.has(entry.name);
|
|
2097
|
+
}
|
|
2098
|
+
function scan_directory(directory, pending) {
|
|
2099
|
+
const entries = readdirSync(directory, { withFileTypes: true });
|
|
2100
|
+
pending.push(
|
|
2101
|
+
...entries.filter((entry) => should_visit(entry)).map((entry) => path4.join(directory, entry.name))
|
|
2102
|
+
);
|
|
2103
|
+
return entries.filter((entry) => entry.isFile()).map((entry) => path4.extname(entry.name));
|
|
2104
|
+
}
|
|
2105
|
+
function file_extensions(root) {
|
|
2106
|
+
const pending = [root];
|
|
2107
|
+
const extensions = [];
|
|
2108
|
+
for (const directory of pending) {
|
|
2109
|
+
extensions.push(...scan_directory(directory, pending));
|
|
2110
|
+
}
|
|
2111
|
+
return extensions;
|
|
2112
|
+
}
|
|
2113
|
+
function scan_files(root) {
|
|
2114
|
+
const extensions = file_extensions(root);
|
|
2115
|
+
const has_web = extensions.some((extension) => WEB_EXTENSIONS.has(extension));
|
|
2116
|
+
const has_typescript = extensions.some((extension) => TYPESCRIPT_EXTENSIONS.has(extension));
|
|
2117
|
+
return { has_web, has_typescript };
|
|
2118
|
+
}
|
|
2119
|
+
function has_github_remote(root) {
|
|
2120
|
+
const result = execaSync("git", ["config", "--get", "remote.origin.url"], {
|
|
2121
|
+
cwd: root,
|
|
2122
|
+
reject: false
|
|
2123
|
+
});
|
|
2124
|
+
return result.exitCode === 0 && repo_origin.parse_origin_url(result.stdout) !== void 0;
|
|
2125
|
+
}
|
|
2126
|
+
function inspect_project(root, requested) {
|
|
2127
|
+
const profile = resolve_profile(root, requested);
|
|
2128
|
+
const files = scan_files(root);
|
|
2129
|
+
const has_git = existsSync3(path4.join(root, ".git"));
|
|
2130
|
+
return { ...profile, ...files, has_git, has_github: has_git && has_github_remote(root) };
|
|
2131
|
+
}
|
|
2132
|
+
var project_profile = {
|
|
2133
|
+
parse_profile,
|
|
2134
|
+
resolve_profile,
|
|
2135
|
+
inspect_project,
|
|
2136
|
+
requested_profile,
|
|
2137
|
+
with_legacy_profile_names
|
|
2138
|
+
};
|
|
2139
|
+
|
|
2015
2140
|
// scripts/test/skip-marker.ts
|
|
2016
2141
|
var SKIP_MARKER = "\u2014 skipping";
|
|
2017
2142
|
|
|
@@ -2054,8 +2179,8 @@ var DEPENDENCY_FIELDS = ["dependencies", "devDependencies"];
|
|
|
2054
2179
|
var object_schema = z5.record(z5.string(), z5.unknown());
|
|
2055
2180
|
function project_root(directory) {
|
|
2056
2181
|
let current = directory;
|
|
2057
|
-
while (!
|
|
2058
|
-
const parent =
|
|
2182
|
+
while (!existsSync4(path5.join(current, PACKAGE_JSON))) {
|
|
2183
|
+
const parent = path5.dirname(current);
|
|
2059
2184
|
if (parent === current) return directory;
|
|
2060
2185
|
current = parent;
|
|
2061
2186
|
}
|
|
@@ -2068,7 +2193,7 @@ function has_files(directory, pattern) {
|
|
|
2068
2193
|
return globSync2(pattern, { cwd: project_root(directory), exclude: is_ignored }).length > 0;
|
|
2069
2194
|
}
|
|
2070
2195
|
function has_config(directory, names) {
|
|
2071
|
-
return names.some((name) =>
|
|
2196
|
+
return names.some((name) => existsSync4(path5.join(project_root(directory), name)));
|
|
2072
2197
|
}
|
|
2073
2198
|
function has_bin(directory, bin_name) {
|
|
2074
2199
|
return find_local_bin_upwards(directory, bin_name) !== void 0;
|
|
@@ -2077,24 +2202,24 @@ function josh_settings(manifest) {
|
|
|
2077
2202
|
if (typeof manifest !== "object" || manifest === null || !("josh" in manifest)) return void 0;
|
|
2078
2203
|
return manifest.josh;
|
|
2079
2204
|
}
|
|
2080
|
-
function
|
|
2205
|
+
function is_basic_manifest(manifest) {
|
|
2081
2206
|
const josh = josh_settings(manifest);
|
|
2082
2207
|
if (typeof josh !== "object" || josh === null || !("profile" in josh)) return false;
|
|
2083
|
-
return josh.profile === "
|
|
2208
|
+
return project_profile.parse_profile(josh.profile) === "basic";
|
|
2084
2209
|
}
|
|
2085
|
-
function
|
|
2210
|
+
function read_manifest2(directory) {
|
|
2086
2211
|
try {
|
|
2087
|
-
const manifest_path =
|
|
2088
|
-
return JSON.parse(
|
|
2212
|
+
const manifest_path = path5.join(project_root(directory), PACKAGE_JSON);
|
|
2213
|
+
return JSON.parse(readFileSync5(manifest_path, "utf8"));
|
|
2089
2214
|
} catch {
|
|
2090
2215
|
return void 0;
|
|
2091
2216
|
}
|
|
2092
2217
|
}
|
|
2093
|
-
function
|
|
2094
|
-
return
|
|
2218
|
+
function is_basic(directory) {
|
|
2219
|
+
return is_basic_manifest(read_manifest2(directory));
|
|
2095
2220
|
}
|
|
2096
2221
|
function is_declared(directory, package_name) {
|
|
2097
|
-
const manifest = object_schema.safeParse(
|
|
2222
|
+
const manifest = object_schema.safeParse(read_manifest2(directory));
|
|
2098
2223
|
if (!manifest.success) return false;
|
|
2099
2224
|
return DEPENDENCY_FIELDS.some((field) => {
|
|
2100
2225
|
const dependencies = object_schema.safeParse(manifest.data[field]);
|
|
@@ -2109,18 +2234,18 @@ function skip_notice(check3, reason) {
|
|
|
2109
2234
|
return `josh ${check3}: ${reason} ${SKIP_MARKER} ${check3}.`;
|
|
2110
2235
|
}
|
|
2111
2236
|
function type_check_skip_reason(directory) {
|
|
2112
|
-
if (!
|
|
2237
|
+
if (!is_basic(directory)) return void 0;
|
|
2113
2238
|
if (!has_files(directory, TYPE_FILES)) return "no TypeScript files were found";
|
|
2114
2239
|
if (!has_config(directory, TYPE_CONFIGS)) return "no TypeScript configuration was found";
|
|
2115
2240
|
return missing_tool_reason(directory, "typescript", "tsc");
|
|
2116
2241
|
}
|
|
2117
2242
|
function prettier_skip_reason(directory) {
|
|
2118
|
-
if (!
|
|
2243
|
+
if (!is_basic(directory)) return void 0;
|
|
2119
2244
|
if (!has_files(directory, WEB_FILES)) return "no HTML, CSS or JavaScript files were found";
|
|
2120
2245
|
return missing_tool_reason(directory, "prettier", "prettier");
|
|
2121
2246
|
}
|
|
2122
2247
|
function eslint_skip_reason(directory) {
|
|
2123
|
-
if (!
|
|
2248
|
+
if (!is_basic(directory)) return void 0;
|
|
2124
2249
|
if (!has_files(directory, SCRIPT_FILES)) return "no JavaScript or TypeScript files were found";
|
|
2125
2250
|
if (!has_config(directory, ESLINT_CONFIGS)) return "no ESLint configuration was found";
|
|
2126
2251
|
return missing_tool_reason(directory, "eslint", "eslint");
|
|
@@ -2136,7 +2261,7 @@ var project_checks = {
|
|
|
2136
2261
|
has_bin,
|
|
2137
2262
|
has_config,
|
|
2138
2263
|
has_files,
|
|
2139
|
-
|
|
2264
|
+
is_basic,
|
|
2140
2265
|
prettier_skip_reason,
|
|
2141
2266
|
project_root,
|
|
2142
2267
|
skip_notice,
|
|
@@ -2148,34 +2273,59 @@ var TEST_SUFFIXES = [".e2e.ts", ".test.ts"];
|
|
|
2148
2273
|
var EXEMPT_PATHS = [".editorconfig"];
|
|
2149
2274
|
var EXEMPT_PREFIXES = [".idea/", ".vscode/", "prompts/"];
|
|
2150
2275
|
var EXEMPT_SUFFIXES = [".md"];
|
|
2151
|
-
var
|
|
2276
|
+
var BASIC_VISUAL_SUFFIXES = [".html", ".css"];
|
|
2277
|
+
var BASIC_REQUIRED_SUFFIXES = [
|
|
2278
|
+
".ts",
|
|
2279
|
+
".tsx",
|
|
2280
|
+
".mts",
|
|
2281
|
+
".cts",
|
|
2282
|
+
".js",
|
|
2283
|
+
".jsx",
|
|
2284
|
+
".mjs",
|
|
2285
|
+
".cjs",
|
|
2286
|
+
".svelte",
|
|
2287
|
+
".json",
|
|
2288
|
+
".jsonc",
|
|
2289
|
+
".json5",
|
|
2290
|
+
".yaml",
|
|
2291
|
+
".yml",
|
|
2292
|
+
".toml"
|
|
2293
|
+
];
|
|
2152
2294
|
function normalize(paths) {
|
|
2153
|
-
return paths.map((
|
|
2295
|
+
return paths.map((path7) => path7.trim()).filter((path7) => path7 !== "");
|
|
2296
|
+
}
|
|
2297
|
+
function is_test_file(path7) {
|
|
2298
|
+
return TEST_SUFFIXES.some((suffix) => path7.endsWith(suffix));
|
|
2154
2299
|
}
|
|
2155
|
-
function
|
|
2156
|
-
|
|
2300
|
+
function is_basic_manual(path7, is_basic2) {
|
|
2301
|
+
const lower = path7.toLowerCase();
|
|
2302
|
+
return is_basic2 && BASIC_REQUIRED_SUFFIXES.every((suffix) => !lower.endsWith(suffix));
|
|
2157
2303
|
}
|
|
2158
|
-
function
|
|
2159
|
-
|
|
2304
|
+
function is_basic_visual(path7) {
|
|
2305
|
+
const lower = path7.toLowerCase();
|
|
2306
|
+
return BASIC_VISUAL_SUFFIXES.some((suffix) => lower.endsWith(suffix));
|
|
2160
2307
|
}
|
|
2161
|
-
function is_exempt(
|
|
2162
|
-
if (EXEMPT_PATHS.includes(
|
|
2163
|
-
return EXEMPT_SUFFIXES.some((suffix) =>
|
|
2308
|
+
function is_exempt(path7, is_basic2 = false) {
|
|
2309
|
+
if (EXEMPT_PATHS.includes(path7) || is_basic_manual(path7, is_basic2)) return true;
|
|
2310
|
+
return EXEMPT_SUFFIXES.some((suffix) => path7.endsWith(suffix)) || EXEMPT_PREFIXES.some((prefix) => path7.startsWith(prefix));
|
|
2164
2311
|
}
|
|
2165
|
-
function is_runtime(
|
|
2166
|
-
return !is_test_file(
|
|
2312
|
+
function is_runtime(path7, is_basic2 = false) {
|
|
2313
|
+
return !is_test_file(path7) && !is_exempt(path7, is_basic2);
|
|
2167
2314
|
}
|
|
2168
|
-
function verdict_for(paths,
|
|
2315
|
+
function verdict_for(paths, is_basic2 = false) {
|
|
2169
2316
|
const changed = normalize(paths);
|
|
2170
|
-
if (changed.some((
|
|
2171
|
-
if (changed.some((
|
|
2317
|
+
if (changed.some((path7) => is_test_file(path7))) return "satisfied";
|
|
2318
|
+
if (changed.some((path7) => is_runtime(path7, is_basic2))) return "required";
|
|
2172
2319
|
return "exempt";
|
|
2173
2320
|
}
|
|
2174
|
-
function runtime_files(paths,
|
|
2175
|
-
return normalize(paths).filter((
|
|
2321
|
+
function runtime_files(paths, is_basic2 = false) {
|
|
2322
|
+
return normalize(paths).filter((path7) => is_runtime(path7, is_basic2));
|
|
2176
2323
|
}
|
|
2177
|
-
function exempt_files(paths,
|
|
2178
|
-
return normalize(paths).filter((
|
|
2324
|
+
function exempt_files(paths, is_basic2 = false) {
|
|
2325
|
+
return normalize(paths).filter((path7) => is_exempt(path7, is_basic2));
|
|
2326
|
+
}
|
|
2327
|
+
function manual_check_files(paths, is_basic2) {
|
|
2328
|
+
return normalize(paths).filter((path7) => is_exempt(path7, is_basic2) && !is_exempt(path7));
|
|
2179
2329
|
}
|
|
2180
2330
|
var test_declared_logic = {
|
|
2181
2331
|
EXEMPT_PATHS,
|
|
@@ -2183,9 +2333,11 @@ var test_declared_logic = {
|
|
|
2183
2333
|
EXEMPT_SUFFIXES,
|
|
2184
2334
|
TEST_SUFFIXES,
|
|
2185
2335
|
exempt_files,
|
|
2336
|
+
is_basic_visual,
|
|
2186
2337
|
is_exempt,
|
|
2187
2338
|
is_runtime,
|
|
2188
2339
|
is_test_file,
|
|
2340
|
+
manual_check_files,
|
|
2189
2341
|
runtime_files,
|
|
2190
2342
|
verdict_for
|
|
2191
2343
|
};
|
|
@@ -2214,7 +2366,7 @@ function source_paths() {
|
|
|
2214
2366
|
return injected.paths ?? read_changed_paths_sync();
|
|
2215
2367
|
}
|
|
2216
2368
|
function current_verdict(paths = source_paths()) {
|
|
2217
|
-
return test_declared_logic.verdict_for(paths, project_checks.
|
|
2369
|
+
return test_declared_logic.verdict_for(paths, project_checks.is_basic(process.cwd()));
|
|
2218
2370
|
}
|
|
2219
2371
|
function restore_injection(previous) {
|
|
2220
2372
|
if (previous === void 0) {
|
|
@@ -3056,9 +3208,9 @@ async function issue_get_labels_and_body(issue_number) {
|
|
|
3056
3208
|
return await issue_view_json(issue_number, "number,state,labels,body");
|
|
3057
3209
|
}
|
|
3058
3210
|
async function issue_list_comments(issue_number) {
|
|
3059
|
-
const
|
|
3211
|
+
const path7 = `${git_gh_api_path.issue_comments_api_path(issue_number)}${git_gh_api_path.FULL_PAGE_QUERY}`;
|
|
3060
3212
|
try {
|
|
3061
|
-
return await git_gh_exec.exec_gh_api({ path:
|
|
3213
|
+
return await git_gh_exec.exec_gh_api({ path: path7, should_paginate: true });
|
|
3062
3214
|
} catch {
|
|
3063
3215
|
return void 0;
|
|
3064
3216
|
}
|
|
@@ -3133,8 +3285,8 @@ function is_selected(rest, request) {
|
|
|
3133
3285
|
return !git_gh_issue_rest.is_pull_request(rest) && matches_body(rest, request.body_term);
|
|
3134
3286
|
}
|
|
3135
3287
|
async function fetch_page(request, page) {
|
|
3136
|
-
const
|
|
3137
|
-
const rows = git_gh_issue_rest.parse_rest_issues(await git_gh_exec.exec_gh_api({ path:
|
|
3288
|
+
const path7 = listing_path(request, page);
|
|
3289
|
+
const rows = git_gh_issue_rest.parse_rest_issues(await git_gh_exec.exec_gh_api({ path: path7 }));
|
|
3138
3290
|
return {
|
|
3139
3291
|
selected: rows.filter((row) => is_selected(row, request)),
|
|
3140
3292
|
is_full: rows.length >= PER_PAGE
|
|
@@ -3375,13 +3527,14 @@ var git_gh_issue = {
|
|
|
3375
3527
|
};
|
|
3376
3528
|
|
|
3377
3529
|
// scripts/ci/pr-classification.ts
|
|
3378
|
-
import { readFileSync as
|
|
3530
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
3379
3531
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
3380
|
-
import { execaSync } from "execa";
|
|
3532
|
+
import { execaSync as execaSync2 } from "execa";
|
|
3381
3533
|
import { z as z8 } from "zod";
|
|
3382
3534
|
var CLASSIFICATION_SET = new Set(RELEASE_CLASSIFICATION_NAMES);
|
|
3383
3535
|
var ISSUE_BUG_LABEL = "bug";
|
|
3384
|
-
var
|
|
3536
|
+
var DECLARATION_PREFIX = "- \u30EA\u30EA\u30FC\u30B9\u5206\u985E: ";
|
|
3537
|
+
var DECLARATION = new RegExp(`^${DECLARATION_PREFIX}(.+)$`, "gmu");
|
|
3385
3538
|
var LEGACY_LABELS = /* @__PURE__ */ new Set(["semver-major", "semver-minor"]);
|
|
3386
3539
|
var LABEL = z8.object({ name: z8.string() });
|
|
3387
3540
|
var USER = z8.object({ login: z8.string() });
|
|
@@ -3400,6 +3553,9 @@ function classification_error(labels, author) {
|
|
|
3400
3553
|
if (selected.length === 1 || author.endsWith("[bot]")) return void 0;
|
|
3401
3554
|
return `Choose one release classification: ${RELEASE_CLASSIFICATION_NAMES.join(", ")}`;
|
|
3402
3555
|
}
|
|
3556
|
+
function declaration(label) {
|
|
3557
|
+
return `${DECLARATION_PREFIX}${label}`;
|
|
3558
|
+
}
|
|
3403
3559
|
function is_classification(value) {
|
|
3404
3560
|
return CLASSIFICATION_SET.has(value);
|
|
3405
3561
|
}
|
|
@@ -3425,13 +3581,13 @@ function select_issue_classification(issue_json) {
|
|
|
3425
3581
|
const [label] = selected;
|
|
3426
3582
|
if (label === void 0 || selected.length > 1) {
|
|
3427
3583
|
throw new Error(
|
|
3428
|
-
`Choose one release classification before opening the PR: ${RELEASE_CLASSIFICATION_NAMES.join(", ")}; found: ${selected.join(", ") || "none"}. Add "
|
|
3584
|
+
`Choose one release classification before opening the PR: ${RELEASE_CLASSIFICATION_NAMES.join(", ")}; found: ${selected.join(", ") || "none"}. Add "${DECLARATION_PREFIX}<label>" to the Issue body.`
|
|
3429
3585
|
);
|
|
3430
3586
|
}
|
|
3431
3587
|
return label;
|
|
3432
3588
|
}
|
|
3433
3589
|
function fetch_current_labels(repository, pull_number) {
|
|
3434
|
-
const result =
|
|
3590
|
+
const result = execaSync2(
|
|
3435
3591
|
"gh",
|
|
3436
3592
|
["api", `repos/${repository}/issues/${String(pull_number)}/labels`, "--jq", ".[].name"],
|
|
3437
3593
|
{ reject: false }
|
|
@@ -3442,7 +3598,7 @@ function fetch_current_labels(repository, pull_number) {
|
|
|
3442
3598
|
return result.stdout.split("\n").filter((name) => name !== "");
|
|
3443
3599
|
}
|
|
3444
3600
|
function check_event(event_path, read_labels = fetch_current_labels) {
|
|
3445
|
-
const event = EVENT.parse(JSON.parse(
|
|
3601
|
+
const event = EVENT.parse(JSON.parse(readFileSync6(event_path, "utf8")));
|
|
3446
3602
|
const labels = read_labels(event.repository.full_name, event.pull_request.number);
|
|
3447
3603
|
return classification_error(labels, event.pull_request.user.login);
|
|
3448
3604
|
}
|
|
@@ -3458,6 +3614,7 @@ if (process.argv[1] === fileURLToPath2(import.meta.url)) {
|
|
|
3458
3614
|
var pr_classification = {
|
|
3459
3615
|
classification_error,
|
|
3460
3616
|
check_event,
|
|
3617
|
+
declaration,
|
|
3461
3618
|
is_classification,
|
|
3462
3619
|
select_issue_classification
|
|
3463
3620
|
};
|
|
@@ -3675,9 +3832,9 @@ async function pr_head_reference(pr_number) {
|
|
|
3675
3832
|
async function read_comments(branch_name, to_path, to_json) {
|
|
3676
3833
|
const pr_number = await resolve_pr_number(branch_name);
|
|
3677
3834
|
if (pr_number === void 0) return void 0;
|
|
3678
|
-
const
|
|
3835
|
+
const path7 = `${to_path(String(pr_number))}${COMMENTS_QUERY}`;
|
|
3679
3836
|
try {
|
|
3680
|
-
return to_json(await git_gh_exec.exec_gh_api({ path:
|
|
3837
|
+
return to_json(await git_gh_exec.exec_gh_api({ path: path7, should_paginate: true }));
|
|
3681
3838
|
} catch {
|
|
3682
3839
|
return void 0;
|
|
3683
3840
|
}
|
|
@@ -3825,16 +3982,16 @@ var git_gh_pr_rollup = {
|
|
|
3825
3982
|
|
|
3826
3983
|
// scripts/git/git-gh-pr-snapshot.ts
|
|
3827
3984
|
var NO_HEAD_SHA_MESSAGE = "gh api answered a pull request with no head commit";
|
|
3828
|
-
async function read_object_pages(
|
|
3985
|
+
async function read_object_pages(path7) {
|
|
3829
3986
|
return await git_gh_exec.exec_gh_api({
|
|
3830
|
-
path: `${
|
|
3987
|
+
path: `${path7}${FULL_PAGE_QUERY}`,
|
|
3831
3988
|
should_paginate: true,
|
|
3832
3989
|
should_slurp: true
|
|
3833
3990
|
});
|
|
3834
3991
|
}
|
|
3835
|
-
async function read_array_pages(
|
|
3992
|
+
async function read_array_pages(path7) {
|
|
3836
3993
|
return await git_gh_exec.exec_gh_api({
|
|
3837
|
-
path: `${
|
|
3994
|
+
path: `${path7}${FULL_PAGE_QUERY}`,
|
|
3838
3995
|
should_paginate: true
|
|
3839
3996
|
});
|
|
3840
3997
|
}
|
|
@@ -3851,8 +4008,8 @@ async function read_status_check_rollup(commit_sha) {
|
|
|
3851
4008
|
return git_gh_pr_rollup.to_status_check_rollup({ check_runs_json, status_json });
|
|
3852
4009
|
}
|
|
3853
4010
|
async function pr_get_review_decision(pr_number) {
|
|
3854
|
-
const
|
|
3855
|
-
return git_gh_pr_review.to_review_decision(await read_array_pages(
|
|
4011
|
+
const path7 = git_gh_api_path.pull_reviews_api_path(String(pr_number));
|
|
4012
|
+
return git_gh_pr_review.to_review_decision(await read_array_pages(path7));
|
|
3856
4013
|
}
|
|
3857
4014
|
async function build_checks_fields(pull) {
|
|
3858
4015
|
return {
|
|
@@ -4477,9 +4634,9 @@ var epic_busy = {
|
|
|
4477
4634
|
};
|
|
4478
4635
|
|
|
4479
4636
|
// scripts/run/run-liveness.ts
|
|
4480
|
-
import { readFileSync as
|
|
4637
|
+
import { readFileSync as readFileSync7, realpathSync, statSync } from "node:fs";
|
|
4481
4638
|
import { homedir, tmpdir } from "node:os";
|
|
4482
|
-
import
|
|
4639
|
+
import path6 from "node:path";
|
|
4483
4640
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
4484
4641
|
|
|
4485
4642
|
// scripts/agent/agent-event.ts
|
|
@@ -4794,12 +4951,12 @@ var ALLOWED_ROOTS = [
|
|
|
4794
4951
|
)
|
|
4795
4952
|
];
|
|
4796
4953
|
function is_within(candidate, root) {
|
|
4797
|
-
const relative =
|
|
4798
|
-
return relative !== "" && !relative.startsWith("..") && !
|
|
4954
|
+
const relative = path6.relative(root, candidate);
|
|
4955
|
+
return relative !== "" && !relative.startsWith("..") && !path6.isAbsolute(relative);
|
|
4799
4956
|
}
|
|
4800
4957
|
function to_safe_path(output_path) {
|
|
4801
|
-
const normalized2 =
|
|
4802
|
-
if (!
|
|
4958
|
+
const normalized2 = path6.normalize(output_path);
|
|
4959
|
+
if (!path6.isAbsolute(normalized2)) return void 0;
|
|
4803
4960
|
return ALLOWED_ROOTS.some((root) => is_within(normalized2, root)) ? normalized2 : void 0;
|
|
4804
4961
|
}
|
|
4805
4962
|
function sample_output(output_path) {
|
|
@@ -4813,7 +4970,7 @@ function read_agent_state(output_path) {
|
|
|
4813
4970
|
const safe_path = to_safe_path(output_path);
|
|
4814
4971
|
if (safe_path === void 0) return void 0;
|
|
4815
4972
|
try {
|
|
4816
|
-
const state = agent_event.read(
|
|
4973
|
+
const state = agent_event.read(readFileSync7(safe_path, "utf8"));
|
|
4817
4974
|
return state.provider === void 0 ? void 0 : state;
|
|
4818
4975
|
} catch {
|
|
4819
4976
|
return void 0;
|
|
@@ -4961,7 +5118,7 @@ var GH_PR_STATES = /* @__PURE__ */ new Map([
|
|
|
4961
5118
|
["MERGED", MERGED_PR],
|
|
4962
5119
|
["OPEN", OPEN_PR]
|
|
4963
5120
|
]);
|
|
4964
|
-
var CLEAN_REASON = "Nothing was left behind: the tree is clean, HEAD is on the default branch, and this issue has no branch
|
|
5121
|
+
var CLEAN_REASON = "Nothing was left behind: the tree is clean, HEAD is on the default branch, and this issue has no pull request and no branch holding work.";
|
|
4965
5122
|
var CLEAN_ADVICE = "Start the child.";
|
|
4966
5123
|
var RESUME_ADVICE = "Reuse the branch and run the whole verification gate from the start \u2014 refactor, `pnpm josh gate`, `/code-review` \u2014 never only the part the interrupted run had not reached. Nobody verified what it already committed.";
|
|
4967
5124
|
var PARK_ADVICE = "Park the child: add `needs-decision` and comment what was found. Do not delete the branch, do not reopen the pull request, and do not commit on top of it.";
|
|
@@ -5076,19 +5233,51 @@ function to_head_branch(name) {
|
|
|
5076
5233
|
const separator_index = name.indexOf(REMOTE_SEPARATOR);
|
|
5077
5234
|
return separator_index === NOT_FOUND_INDEX ? name : name.slice(separator_index + 1);
|
|
5078
5235
|
}
|
|
5236
|
+
function group_by_head(pairs) {
|
|
5237
|
+
const groups = /* @__PURE__ */ new Map();
|
|
5238
|
+
for (const [name, reference] of pairs) groups.set(name, [...groups.get(name) ?? [], reference]);
|
|
5239
|
+
return groups;
|
|
5240
|
+
}
|
|
5079
5241
|
async function read_branch_candidates(issue) {
|
|
5080
5242
|
const pattern = `${issue}${ISSUE_BRANCH_SUFFIX}`;
|
|
5081
5243
|
const [local, remote] = await Promise.all([
|
|
5082
5244
|
git_command.branch_names(pattern),
|
|
5083
5245
|
git_command.branch_names_remote(`${ANY_REMOTE_PREFIX}${pattern}`)
|
|
5084
5246
|
]);
|
|
5085
|
-
return
|
|
5247
|
+
return group_by_head([
|
|
5248
|
+
...local.map((name) => [name, name]),
|
|
5249
|
+
...remote.map((reference) => [to_head_branch(reference), reference])
|
|
5250
|
+
]);
|
|
5251
|
+
}
|
|
5252
|
+
async function has_commits_beyond(base, references) {
|
|
5253
|
+
const counts = await Promise.all(
|
|
5254
|
+
references.map(async (reference) => await git_command.commit_count_beyond(base, reference))
|
|
5255
|
+
);
|
|
5256
|
+
return counts.some((count) => count > 0);
|
|
5257
|
+
}
|
|
5258
|
+
async function is_held_dirty(name, lane) {
|
|
5259
|
+
if (lane?.branch !== name || lane.is_stranded) return false;
|
|
5260
|
+
return await run_hold.is_tree_dirty(lane.directory);
|
|
5261
|
+
}
|
|
5262
|
+
async function read_candidate(name, references, context) {
|
|
5263
|
+
const state = await read_pr_of_branch(name);
|
|
5264
|
+
if (state.pr_state !== NO_PR) return state;
|
|
5265
|
+
if (await has_commits_beyond(context.base, references)) return state;
|
|
5266
|
+
return await is_held_dirty(name, context.lane) ? state : void 0;
|
|
5086
5267
|
}
|
|
5087
5268
|
async function read_child_state(issue) {
|
|
5088
5269
|
const candidates = await read_branch_candidates(issue);
|
|
5089
|
-
return
|
|
5090
|
-
|
|
5270
|
+
if (candidates.size === 0) return NO_CHILD_WORK;
|
|
5271
|
+
const [base, lane] = await Promise.all([
|
|
5272
|
+
git_command.default_branch_reference(),
|
|
5273
|
+
lane_registry.find_open_lane(issue)
|
|
5274
|
+
]);
|
|
5275
|
+
const reads = await Promise.all(
|
|
5276
|
+
[...candidates].map(
|
|
5277
|
+
async ([name, references]) => await read_candidate(name, references, { base, lane })
|
|
5278
|
+
)
|
|
5091
5279
|
);
|
|
5280
|
+
return pick_child_state(reads.filter((read2) => read2 !== void 0));
|
|
5092
5281
|
}
|
|
5093
5282
|
async function check2(issue) {
|
|
5094
5283
|
require_issue_number(issue);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
lane_guard_policy,
|
|
3
3
|
time_batch_guard
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-56LGMJJV.js";
|
|
5
5
|
import {
|
|
6
6
|
hook_decision
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GBJUERYK.js";
|
|
8
8
|
|
|
9
9
|
// scripts/hooks/batch-guard.ts
|
|
10
10
|
import { text } from "node:stream/consumers";
|