@joshuafolkken/kit 1.1387.0 → 1.1453.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/epic-commands/SKILL.md +1 -1
- package/.claude/skills/epic-commands/epic-bundle.md +5 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +5 -3
- package/.claude/skills/workflow-commands/backlogrun-park.md +2 -0
- package/.claude/skills/workflow-commands/backlogrun-steps.md +13 -10
- package/.claude/skills/workflow-commands/backlogrun.md +3 -2
- package/.claude/skills/workflow-commands/chain-rule.md +4 -2
- package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
- package/.claude/skills/workflow-commands/halfrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-comments.md +6 -0
- package/.claude/skills/workflow-commands/kickoff.md +12 -13
- package/.claude/skills/workflow-commands/observation-filing.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +3 -2
- package/.claude/skills/workflow-commands/pre-gate-cut.md +5 -3
- package/.claude/skills/workflow-commands/prerequisite.md +6 -0
- package/.claude/skills/workflow-commands/retrospective.md +5 -5
- package/.claude/skills/workflow-commands/split-assessment.md +2 -2
- package/README.md +27 -4
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-2YSW3CXH.js → chunk-3C4XRYG6.js} +35 -11
- package/dist/hooks/{chunk-GJ7JPIHN.js → chunk-5C7L6FRC.js} +2704 -190
- package/dist/hooks/{chunk-FZ6FUSBM.js → chunk-723HKZO5.js} +1 -1
- package/dist/hooks/{chunk-STDSEPWU.js → chunk-D3NJXN5M.js} +4 -4
- package/dist/hooks/{chunk-NEC4AT4Z.js → chunk-DGT54IH5.js} +4 -0
- package/dist/hooks/{chunk-LMWBRJIP.js → chunk-EF5GQ6WS.js} +3 -3
- package/dist/hooks/{chunk-JBBMAPC4.js → chunk-IX6TTTI6.js} +4 -0
- package/dist/hooks/{chunk-IYVOLN6A.js → chunk-LBFYEOXJ.js} +3 -3
- package/dist/hooks/{chunk-SL4GQ2XP.js → chunk-MBJYQPEK.js} +106 -23
- package/dist/hooks/{chunk-WNFJLBXI.js → chunk-NO4AALP5.js} +3 -3
- package/dist/hooks/{chunk-J3KSS7II.js → chunk-OLMO72ON.js} +1 -1
- package/dist/hooks/{chunk-DCY2GWHC.js → chunk-SHYUQOIS.js} +5 -5
- package/dist/hooks/{chunk-EAQEGME7.js → chunk-UT7YC3N2.js} +1 -1
- package/dist/hooks/{chunk-EBSHN25W.js → chunk-W5ZKGTSY.js} +4 -4
- package/dist/hooks/{chunk-GNDJ7NJ7.js → chunk-Y3GKIKGW.js} +209 -56
- package/dist/hooks/{chunk-U32VSRNG.js → chunk-Z4XI7CZS.js} +89 -34
- package/dist/hooks/codex-hook-adapter.js +15 -15
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +5 -5
- package/dist/hooks/inputs.json +261 -201
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +14 -14
- package/dist/hooks/session-lang.js +69 -16
- package/dist/hooks/stop-guard.js +13 -38
- package/dist/josh.js +95 -19
- package/package.json +4 -3
- package/prompts/collaboration-workflow/issue-template.md +10 -8
- package/prompts/review.md +30 -4
- package/scripts/agent/claude-agent-argv.ts +13 -1
- package/scripts/auth/auth-setup-cli.ts +101 -0
- package/scripts/auth/claude-token-output.ts +78 -0
- package/scripts/auth/claude-token.ts +68 -0
- package/scripts/auto-ok/auto-ok-judge-cli.ts +125 -0
- package/scripts/auto-ok/auto-ok-judge-read.ts +95 -0
- package/scripts/auto-ok/auto-ok-judge-write.ts +109 -0
- package/scripts/auto-ok/auto-ok-judge.ts +67 -0
- package/scripts/backlog/backlog-drive-cli.ts +14 -0
- package/scripts/backlog/backlog-drive-epic.ts +24 -8
- package/scripts/backlog/backlog-drive-launch.ts +3 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +7 -2
- package/scripts/backlog/backlog-drive-named.ts +4 -2
- package/scripts/backlog/backlog-drive-unread.ts +56 -0
- package/scripts/backlog/backlog-drive.ts +38 -11
- package/scripts/backlog/backlog-overlap.ts +22 -5
- package/scripts/backlog/backlog-ready.ts +1 -3
- package/scripts/backlog/backlogrun-args.ts +13 -2
- package/scripts/backlog/backlogrun-cli.ts +91 -19
- package/scripts/backlog/backlogrun-launch.ts +24 -0
- package/scripts/backlog/backlogrun-replace.ts +166 -0
- package/scripts/backlog/backlogrun-stop.ts +178 -0
- package/scripts/behavior/behavior-cli.ts +6 -1
- package/scripts/doctor/doctor-io.ts +60 -9
- package/scripts/doctor/doctor.ts +20 -1
- package/scripts/document/document-byte-budget.ts +3 -3
- package/scripts/epic/epic-bundle-cli.ts +8 -8
- package/scripts/epic/epic-bundle-referenced.ts +2 -5
- package/scripts/epic/epic-bundle.ts +39 -4
- package/scripts/exports/unused-members-cli.ts +2 -1
- package/scripts/followup/followup-checks-event.ts +82 -0
- package/scripts/followup/git-followup-finish.ts +16 -2
- package/scripts/followup/git-followup-workflow.ts +5 -2
- package/scripts/followup/git-pr-followup-checks.ts +18 -4
- package/scripts/followup/git-pr-followup-wrapup.ts +5 -0
- package/scripts/followup/git-pr-followup.ts +4 -1
- package/scripts/fresh-machine/fresh-machine-cli.ts +204 -0
- package/scripts/fresh-machine/fresh-machine-docker.ts +65 -0
- package/scripts/fresh-machine/fresh-machine-image.ts +62 -0
- package/scripts/fresh-machine/fresh-machine-log.ts +61 -0
- package/scripts/fresh-machine/fresh-machine-patterns.ts +175 -0
- package/scripts/fresh-machine/fresh-machine-run.ts +215 -0
- package/scripts/fresh-machine/fresh-machine-script.ts +45 -0
- package/scripts/fresh-machine/fresh-machine-spec.ts +57 -0
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +34 -0
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +31 -0
- package/scripts/gate/gate-report.ts +70 -15
- package/scripts/gate/project-checks.ts +18 -4
- package/scripts/gate/scoped-green.ts +2 -1
- package/scripts/gate/verification-gate.ts +4 -3
- package/scripts/gh/gh-author-association.ts +14 -0
- package/scripts/gh/git-gh-conditional.ts +66 -0
- package/scripts/gh/git-gh-exec.ts +1 -1
- package/scripts/gh/git-gh-issue-read.ts +6 -3
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +5 -1
- package/scripts/gh/git-gh-issue.ts +13 -1
- package/scripts/gh/git-pr-checks-eval.ts +13 -0
- package/scripts/gh/git-pr-checks-parse.ts +8 -1
- package/scripts/gh/git-pr-checks-watch.ts +11 -4
- package/scripts/gh/git-pr-checks.ts +36 -2
- package/scripts/git/git-command.ts +16 -4
- package/scripts/git/git-schemas.ts +1 -0
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/hooks/pretool-guard.ts +3 -1
- package/scripts/init/hook-command-rewrite.ts +31 -0
- package/scripts/init/init-actions.ts +7 -4
- package/scripts/init/init-ai-copy.ts +34 -11
- package/scripts/init/init-basic.ts +9 -4
- package/scripts/init/init-bootstrap.ts +6 -2
- package/scripts/init/init-dry-run-report.ts +150 -0
- package/scripts/init/init-dry-run.ts +189 -0
- package/scripts/init/init-install.ts +8 -1
- package/scripts/init/init-logic-toolchain.ts +76 -0
- package/scripts/init/init-logic.ts +2 -0
- package/scripts/init/init.ts +62 -42
- package/scripts/init/kit-setup-state.ts +11 -17
- package/scripts/init/own-formatter.ts +21 -0
- package/scripts/init/project-profile.ts +60 -12
- package/scripts/init/start-dry-run.ts +70 -0
- package/scripts/init/start-exec.ts +27 -1
- package/scripts/init/start-plan.ts +23 -3
- package/scripts/init/start-setup-pr.ts +13 -24
- package/scripts/init/start-steps.ts +62 -1
- package/scripts/init/start.ts +38 -17
- package/scripts/init/workflow-mark.ts +35 -0
- package/scripts/init/working-tree.ts +116 -0
- package/scripts/issue/issue-ack-cli.ts +84 -0
- package/scripts/issue/issue-auto-ok.ts +68 -99
- package/scripts/issue/issue-file-cli.ts +17 -17
- package/scripts/issue/issue-file.ts +1 -6
- package/scripts/issue/issue-labels.ts +46 -10
- package/scripts/issue/issue-release-cli.ts +69 -23
- package/scripts/issue/issue-release.ts +3 -1
- package/scripts/issue/issue-state-cli.ts +14 -4
- package/scripts/issue/issue-watch-diff.ts +152 -0
- package/scripts/issue/issue-watch-gate.ts +81 -0
- package/scripts/issue/issue-watch-hook.ts +54 -0
- package/scripts/issue/issue-watch.ts +240 -0
- package/scripts/issue/measure-rerun-cli.ts +3 -4
- package/scripts/josh/josh-command-map.ts +4 -0
- package/scripts/josh/josh-commands-ai.ts +11 -0
- package/scripts/josh/josh-commands-backlog.ts +2 -2
- package/scripts/josh/josh-commands-development.ts +1 -1
- package/scripts/josh/josh-commands-issue.ts +10 -3
- package/scripts/josh/josh-commands-lane.ts +11 -2
- package/scripts/josh/josh-commands-project.ts +26 -2
- package/scripts/josh/josh-verdict.ts +33 -4
- package/scripts/josh/process-identity.ts +32 -6
- package/scripts/lane/claude-lane-broker.ts +142 -0
- package/scripts/lane/lane-await.ts +6 -2
- package/scripts/lane/lane-broker-server.ts +69 -0
- package/scripts/lane/lane-cache.ts +37 -7
- package/scripts/lane/lane-capacity.ts +8 -6
- package/scripts/lane/lane-child-invocation.ts +1 -0
- package/scripts/lane/lane-cli.ts +15 -1
- package/scripts/lane/lane-close.ts +15 -6
- package/scripts/lane/lane-dispatch.ts +36 -10
- package/scripts/lane/lane-environment.ts +1 -1
- package/scripts/lane/lane-launch-cli.ts +13 -4
- package/scripts/lane/lane-ledger.ts +21 -3
- package/scripts/lane/lane-measure-cli.ts +10 -2
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-preserve.ts +49 -0
- package/scripts/lane/lane-reap.ts +20 -5
- package/scripts/lane/lane-registry.ts +6 -0
- package/scripts/lane/lane-restart-cli.ts +51 -0
- package/scripts/lane/lane-restart.ts +175 -0
- package/scripts/lane/lane-session-broker.ts +363 -0
- package/scripts/lane/lane-spent.ts +195 -0
- package/scripts/lane/lane-stage-stats.ts +27 -3
- package/scripts/lane/lane-stop-stats.ts +96 -0
- package/scripts/lane/openai-lane-supervisor.ts +2 -2
- package/scripts/lane/process-tools.ts +31 -0
- package/scripts/lib/buffered-process.ts +36 -2
- package/scripts/lib/pnpm-reach.ts +27 -0
- package/scripts/lib/status-icons.ts +5 -1
- package/scripts/lint/lint-parallel.ts +19 -2
- package/scripts/observations/observation-ledger-home.ts +1 -0
- package/scripts/observations/observation-ledger-migrate.ts +3 -15
- package/scripts/release/release-issue-close.ts +133 -0
- package/scripts/release/release-publish.ts +12 -1
- package/scripts/repo/repository-labels.ts +11 -1
- package/scripts/review/comment-ranges.ts +199 -0
- package/scripts/review/review-attest-cli.ts +21 -6
- package/scripts/review/review-brief-cli.ts +24 -7
- package/scripts/review/review-code-tree.ts +119 -0
- package/scripts/review/review-comment-round.ts +114 -0
- package/scripts/review/review-record-cli.ts +39 -17
- package/scripts/review/review-round2-cli.ts +16 -5
- package/scripts/review/review-round2.ts +30 -10
- package/scripts/review/review-stamps.ts +22 -1
- package/scripts/rules/implementation-cut.ts +3 -3
- package/scripts/rules/pre-gate-cut.ts +1 -1
- package/scripts/run/board/run-board-checks.ts +42 -0
- package/scripts/run/board/run-board-cli.ts +2 -0
- package/scripts/run/board/run-board-every.ts +3 -1
- package/scripts/run/board/run-board-fit.ts +16 -5
- package/scripts/run/board/run-board-fresh.ts +64 -0
- package/scripts/run/board/run-board-header.ts +129 -53
- package/scripts/run/board/run-board-labels.ts +47 -4
- package/scripts/run/board/run-board-lane-event.ts +66 -0
- package/scripts/run/board/run-board-layout.ts +57 -9
- package/scripts/run/board/run-board-now.ts +234 -0
- package/scripts/run/board/run-board-operation-read.ts +75 -0
- package/scripts/run/board/run-board-operation.ts +150 -0
- package/scripts/run/board/run-board-phase.ts +26 -1
- package/scripts/run/board/run-board-plan.ts +4 -6
- package/scripts/run/board/run-board-read.ts +49 -3
- package/scripts/run/board/run-board-reason.ts +124 -0
- package/scripts/run/board/run-board-render-checks.ts +55 -0
- package/scripts/run/board/run-board-render-legend.ts +12 -3
- package/scripts/run/board/run-board-render-slot.ts +2 -2
- package/scripts/run/board/run-board-render-tail.ts +128 -0
- package/scripts/run/board/run-board-render-thanks.ts +50 -0
- package/scripts/run/board/run-board-render-title.ts +58 -0
- package/scripts/run/board/run-board-render.ts +96 -80
- package/scripts/run/board/run-board-row-yield.ts +32 -0
- package/scripts/run/board/run-board-setup.ts +61 -13
- package/scripts/run/board/run-board-state.ts +10 -0
- package/scripts/run/board/run-board-status.ts +66 -7
- package/scripts/run/board/run-board-thanks-csv.ts +71 -0
- package/scripts/run/board/run-board-thanks-read.ts +112 -0
- package/scripts/run/board/run-board-thanks.ts +53 -0
- package/scripts/run/board/run-board-tick.ts +50 -21
- package/scripts/run/board/run-board-usual.ts +44 -0
- package/scripts/run/carry/run-carry-args.ts +9 -1
- package/scripts/run/carry/run-carry-cli.ts +2 -45
- package/scripts/run/carry/run-carry-end.ts +73 -0
- package/scripts/run/carry/run-carry.ts +8 -1
- package/scripts/run/entry/run-entry-cli.ts +5 -0
- package/scripts/run/event/run-event-checks.ts +54 -0
- package/scripts/run/event/run-event-render.ts +2 -0
- package/scripts/run/event/run-event-scope.ts +1 -0
- package/scripts/run/event/run-event-setup.ts +55 -11
- package/scripts/run/event/run-event-stream.ts +27 -11
- package/scripts/run/merge/run-merge-cli.ts +7 -4
- package/scripts/run/merge/run-merge-ship.ts +61 -0
- package/scripts/run/merge/run-merge-steps.ts +7 -14
- package/scripts/run/merge/run-merge-token.ts +16 -2
- package/scripts/run/run-headless.ts +1 -0
- package/scripts/run/run-step.ts +2 -0
- package/scripts/run/ship/run-ship-cli.ts +22 -2
- package/scripts/run/ship/run-ship-return.ts +31 -13
- package/scripts/run/ship/run-ship-review-steps.ts +17 -4
- package/scripts/run/ship/run-ship-stage.ts +1 -0
- package/scripts/run/wake/run-wake-await.ts +130 -0
- package/scripts/run/wake/run-wake-cli.ts +60 -71
- package/scripts/run/wake/run-wake-describe.ts +34 -2
- package/scripts/run/wake/run-wake-driver.ts +11 -4
- package/scripts/run/wake/run-wake-session.ts +20 -3
- package/scripts/run/wake/run-wake-stop.ts +37 -0
- package/scripts/run/wake/run-wake-supervise.ts +44 -0
- package/scripts/sync/claude-settings-merge.ts +144 -0
- package/scripts/sync/sync-ai-files.ts +28 -3
- package/scripts/sync/sync.ts +15 -0
- package/scripts/test/project-test-script.ts +73 -0
- package/scripts/test/skip-marker.ts +14 -1
- package/scripts/test/test-related.ts +3 -2
- package/scripts/test/test-unit-guard.ts +78 -14
- package/scripts/time-runtime/time-reported-failure.ts +11 -3
- package/scripts/uninstall/distributed-files.ts +92 -0
- package/scripts/uninstall/uninstall-plan.ts +119 -0
- package/scripts/uninstall/uninstall-report.ts +61 -0
- package/scripts/uninstall/uninstall.ts +206 -0
- package/templates/AGENTS.basic.md +4 -0
- package/templates/GEMINI.basic.md +6 -0
- package/dist/hooks/chunk-6V5OPIUU.js +0 -13
- package/scripts/lane/openai-review-broker.ts +0 -262
- package/scripts/run/board/run-board-track.ts +0 -22
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
duplicate_read_outcome
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SHYUQOIS.js";
|
|
4
4
|
import {
|
|
5
5
|
ALREADY_DONE_LABEL,
|
|
6
6
|
CONTEXT_CUT_THRESHOLD,
|
|
@@ -9,10 +9,14 @@ import {
|
|
|
9
9
|
NEEDS_HUMAN_REVIEW_LABEL,
|
|
10
10
|
bash_triggers,
|
|
11
11
|
filing_cap,
|
|
12
|
+
git_gh_api_path,
|
|
12
13
|
git_gh_command,
|
|
14
|
+
git_gh_exec,
|
|
13
15
|
git_gh_issue_read,
|
|
14
16
|
git_gh_pr_read,
|
|
15
17
|
has_any_label,
|
|
18
|
+
has_stdout_field,
|
|
19
|
+
issue_watch_diff,
|
|
16
20
|
lane_background,
|
|
17
21
|
lane_park,
|
|
18
22
|
parse_json_object_or_undefined,
|
|
@@ -25,11 +29,15 @@ import {
|
|
|
25
29
|
session_cite,
|
|
26
30
|
shell_segments,
|
|
27
31
|
tail_commands
|
|
28
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-Y3GKIKGW.js";
|
|
29
33
|
import {
|
|
30
34
|
ancestor_directories,
|
|
31
|
-
find_local_bin_upwards
|
|
32
|
-
|
|
35
|
+
find_local_bin_upwards,
|
|
36
|
+
json_object_schema,
|
|
37
|
+
string_array_schema,
|
|
38
|
+
string_record_schema,
|
|
39
|
+
vscode_settings_schema
|
|
40
|
+
} from "./chunk-IX6TTTI6.js";
|
|
33
41
|
import {
|
|
34
42
|
agent_role_profile,
|
|
35
43
|
agent_session_role,
|
|
@@ -40,26 +48,27 @@ import {
|
|
|
40
48
|
run_event_scope,
|
|
41
49
|
run_event_stream,
|
|
42
50
|
run_event_stream_emit,
|
|
43
|
-
run_headless
|
|
44
|
-
|
|
51
|
+
run_headless,
|
|
52
|
+
session_language
|
|
53
|
+
} from "./chunk-Z4XI7CZS.js";
|
|
45
54
|
import {
|
|
46
55
|
error_text
|
|
47
56
|
} from "./chunk-CDY4NFQG.js";
|
|
48
57
|
import {
|
|
49
58
|
batch_outcome
|
|
50
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-EF5GQ6WS.js";
|
|
51
60
|
import {
|
|
52
61
|
investigation_refusal
|
|
53
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-LBFYEOXJ.js";
|
|
54
63
|
import {
|
|
55
64
|
investigation_reads
|
|
56
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-NO4AALP5.js";
|
|
57
66
|
import {
|
|
58
67
|
lane_guard_policy
|
|
59
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-UT7YC3N2.js";
|
|
60
69
|
import {
|
|
61
70
|
hook_decision
|
|
62
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-W5ZKGTSY.js";
|
|
63
72
|
import {
|
|
64
73
|
cost_attribute,
|
|
65
74
|
cost_blocks,
|
|
@@ -67,11 +76,12 @@ import {
|
|
|
67
76
|
time_batch_guard,
|
|
68
77
|
time_density_hook,
|
|
69
78
|
time_shell
|
|
70
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-MBJYQPEK.js";
|
|
71
80
|
import {
|
|
72
81
|
lane_child_marker
|
|
73
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-OLMO72ON.js";
|
|
74
83
|
import {
|
|
84
|
+
GIT_LOCATION_VARIABLES,
|
|
75
85
|
PORCELAIN_FLAG,
|
|
76
86
|
cli_flags,
|
|
77
87
|
cost_transcript,
|
|
@@ -84,13 +94,424 @@ import {
|
|
|
84
94
|
lane_paths,
|
|
85
95
|
own_session,
|
|
86
96
|
run_carry
|
|
87
|
-
} from "./chunk-
|
|
97
|
+
} from "./chunk-3C4XRYG6.js";
|
|
88
98
|
import {
|
|
89
99
|
PLATFORM_TEMP_ROOT,
|
|
90
100
|
PROBE_TIMEOUT_MS,
|
|
101
|
+
PROJECT_ROOT,
|
|
102
|
+
package_path,
|
|
91
103
|
platform_temporary,
|
|
92
104
|
stamp_file
|
|
93
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-DGT54IH5.js";
|
|
106
|
+
|
|
107
|
+
// scripts/gh/git-gh-conditional.ts
|
|
108
|
+
var NOT_MODIFIED_STATUS = 304;
|
|
109
|
+
var OK_STATUS = 200;
|
|
110
|
+
var INCLUDE_FLAG = "--include";
|
|
111
|
+
var HEADER_FLAG = "-H";
|
|
112
|
+
var IF_NONE_MATCH = "If-None-Match: ";
|
|
113
|
+
var HEADER_BODY_SEPARATOR = /\r?\n\r?\n/u;
|
|
114
|
+
var ETAG_HEADER = /^etag: *(?<etag>[^\r\n]+)/imu;
|
|
115
|
+
var UNCHANGED = { kind: "unchanged" };
|
|
116
|
+
var UNREADABLE = { kind: "unreadable" };
|
|
117
|
+
function to_args(path16, etag) {
|
|
118
|
+
const header = etag === void 0 ? [] : [HEADER_FLAG, `${IF_NONE_MATCH}${etag}`];
|
|
119
|
+
return ["api", INCLUDE_FLAG, ...header, path16];
|
|
120
|
+
}
|
|
121
|
+
function to_changed(output) {
|
|
122
|
+
const [headers = "", ...rest] = output.split(HEADER_BODY_SEPARATOR);
|
|
123
|
+
const etag = ETAG_HEADER.exec(headers)?.groups?.["etag"];
|
|
124
|
+
return { kind: "changed", etag, body: rest.join("\n\n") };
|
|
125
|
+
}
|
|
126
|
+
function to_read(output) {
|
|
127
|
+
return git_gh_exec.parse_status_line(output) === OK_STATUS ? to_changed(output) : UNREADABLE;
|
|
128
|
+
}
|
|
129
|
+
function failure_status(error) {
|
|
130
|
+
const cause = error instanceof Error ? error.cause : void 0;
|
|
131
|
+
return has_stdout_field(cause) ? git_gh_exec.parse_status_line(cause.stdout) : void 0;
|
|
132
|
+
}
|
|
133
|
+
async function read_conditional(path16, etag, timeout_ms) {
|
|
134
|
+
try {
|
|
135
|
+
return to_read(await git_gh_exec.exec_gh_command(to_args(path16, etag), timeout_ms));
|
|
136
|
+
} catch (error) {
|
|
137
|
+
return failure_status(error) === NOT_MODIFIED_STATUS ? UNCHANGED : UNREADABLE;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
var git_gh_conditional = { read_conditional, to_args };
|
|
141
|
+
|
|
142
|
+
// scripts/issue/issue-watch.ts
|
|
143
|
+
import { z } from "zod";
|
|
144
|
+
var RECORD_PREFIX = "josh-issue-watch-";
|
|
145
|
+
var CLOSED_STATE = "closed";
|
|
146
|
+
var record_schema = z.object({
|
|
147
|
+
issue: z.string(),
|
|
148
|
+
body: z.string(),
|
|
149
|
+
last_comment_id: z.number(),
|
|
150
|
+
acknowledged_at: z.string(),
|
|
151
|
+
checked_at: z.string(),
|
|
152
|
+
etag: z.string().optional(),
|
|
153
|
+
pending: z.string().optional(),
|
|
154
|
+
shown: z.string().optional()
|
|
155
|
+
});
|
|
156
|
+
var issue_schema = z.looseObject({ body: z.string().nullish(), state: z.string() });
|
|
157
|
+
var UNREADABLE2 = { kind: "unreadable" };
|
|
158
|
+
function record_path(root = PROJECT_ROOT) {
|
|
159
|
+
return stamp_file.stamp_path(RECORD_PREFIX, root);
|
|
160
|
+
}
|
|
161
|
+
function read_record(root) {
|
|
162
|
+
const raw = stamp_file.read_stamp_text(record_path(root));
|
|
163
|
+
return raw === void 0 ? void 0 : json_value.parse_with(raw, record_schema);
|
|
164
|
+
}
|
|
165
|
+
function write_record(record, root) {
|
|
166
|
+
stamp_file.replace_stamp(record_path(root), record);
|
|
167
|
+
return record;
|
|
168
|
+
}
|
|
169
|
+
function clear(root) {
|
|
170
|
+
stamp_file.remove_stamp(record_path(root));
|
|
171
|
+
}
|
|
172
|
+
async function read_snapshot(request2, body, etag) {
|
|
173
|
+
const comments = issue_watch_diff.parse_comments(
|
|
174
|
+
await git_gh_issue_read.issue_list_comments(request2.issue, request2.timeout_ms)
|
|
175
|
+
);
|
|
176
|
+
return comments === void 0 ? UNREADABLE2 : { kind: "read", snapshot: { body, comments }, etag };
|
|
177
|
+
}
|
|
178
|
+
async function fetch_issue(request2) {
|
|
179
|
+
const read2 = await git_gh_conditional.read_conditional(
|
|
180
|
+
git_gh_api_path.issue_api_path(request2.issue),
|
|
181
|
+
request2.etag,
|
|
182
|
+
request2.timeout_ms
|
|
183
|
+
);
|
|
184
|
+
if (read2.kind !== "changed") return read2;
|
|
185
|
+
const fields = json_value.parse_with(read2.body, issue_schema);
|
|
186
|
+
if (fields === void 0) return UNREADABLE2;
|
|
187
|
+
if (fields.state === CLOSED_STATE) return { kind: "closed" };
|
|
188
|
+
return await read_snapshot(request2, fields.body ?? "", read2.etag);
|
|
189
|
+
}
|
|
190
|
+
function fresh_record(issue, fetched, now, acknowledged_at = now.toISOString()) {
|
|
191
|
+
const baseline = issue_watch_diff.baseline_of(fetched.snapshot);
|
|
192
|
+
const checked_at = now.toISOString();
|
|
193
|
+
return { issue, ...baseline, acknowledged_at, checked_at, etag: fetched.etag };
|
|
194
|
+
}
|
|
195
|
+
async function record_baseline(issue, root, now = /* @__PURE__ */ new Date()) {
|
|
196
|
+
const fetched = await fetch_issue({ issue });
|
|
197
|
+
if (fetched.kind !== "read") return false;
|
|
198
|
+
write_record(fresh_record(issue, fetched, now), root);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
async function record_baseline_here(issue) {
|
|
202
|
+
return await record_baseline(issue, await git_command.repository_root());
|
|
203
|
+
}
|
|
204
|
+
async function clear_here() {
|
|
205
|
+
clear(await git_command.repository_root());
|
|
206
|
+
}
|
|
207
|
+
function with_fetched(record, fetched, checked_at) {
|
|
208
|
+
if (fetched.kind !== "read") return { ...record, checked_at };
|
|
209
|
+
const pending = issue_watch_diff.unread_diff(record, fetched.snapshot);
|
|
210
|
+
return { ...record, checked_at, etag: fetched.etag, pending };
|
|
211
|
+
}
|
|
212
|
+
function is_due(record, options, now) {
|
|
213
|
+
return now.getTime() - Date.parse(record.checked_at) >= options.interval_ms;
|
|
214
|
+
}
|
|
215
|
+
async function refresh(record, options, now, root) {
|
|
216
|
+
const fetched = await fetch_issue({
|
|
217
|
+
issue: record.issue,
|
|
218
|
+
etag: record.etag,
|
|
219
|
+
timeout_ms: options.timeout_ms
|
|
220
|
+
});
|
|
221
|
+
if (fetched.kind === "closed") {
|
|
222
|
+
clear(root);
|
|
223
|
+
return void 0;
|
|
224
|
+
}
|
|
225
|
+
return write_record(with_fetched(record, fetched, now.toISOString()), root);
|
|
226
|
+
}
|
|
227
|
+
async function poll(options, root) {
|
|
228
|
+
const record = read_record(root);
|
|
229
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
230
|
+
if (record === void 0 || !is_due(record, options, now)) return record;
|
|
231
|
+
return await refresh(record, options, now, root);
|
|
232
|
+
}
|
|
233
|
+
function mark_shown(record, root) {
|
|
234
|
+
return write_record({ ...record, shown: record.pending }, root);
|
|
235
|
+
}
|
|
236
|
+
async function acknowledge(root, now = /* @__PURE__ */ new Date()) {
|
|
237
|
+
const record = read_record(root);
|
|
238
|
+
if (record === void 0) return void 0;
|
|
239
|
+
const fetched = await fetch_issue({ issue: record.issue });
|
|
240
|
+
if (fetched.kind !== "read") return void 0;
|
|
241
|
+
const diff = issue_watch_diff.unread_diff(record, fetched.snapshot);
|
|
242
|
+
const acknowledged_at = diff === void 0 ? record.acknowledged_at : now.toISOString();
|
|
243
|
+
write_record(fresh_record(record.issue, fetched, now, acknowledged_at), root);
|
|
244
|
+
return { issue: record.issue, diff };
|
|
245
|
+
}
|
|
246
|
+
var issue_watch = {
|
|
247
|
+
acknowledge,
|
|
248
|
+
clear,
|
|
249
|
+
clear_here,
|
|
250
|
+
mark_shown,
|
|
251
|
+
poll,
|
|
252
|
+
read_record,
|
|
253
|
+
record_baseline,
|
|
254
|
+
record_baseline_here,
|
|
255
|
+
record_path
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
// scripts/review/review-attest.ts
|
|
259
|
+
import { randomBytes } from "node:crypto";
|
|
260
|
+
import { lstatSync } from "node:fs";
|
|
261
|
+
|
|
262
|
+
// scripts/review/review-checkout.ts
|
|
263
|
+
async function read_checkout() {
|
|
264
|
+
const [root, branch, head] = await Promise.all([
|
|
265
|
+
git_command.repository_root(),
|
|
266
|
+
git_command.branch(),
|
|
267
|
+
git_command.head_commit()
|
|
268
|
+
]);
|
|
269
|
+
return { root, branch, head };
|
|
270
|
+
}
|
|
271
|
+
function is_same_checkout(expected, actual) {
|
|
272
|
+
return expected.root === actual.root && expected.branch === actual.branch && expected.head === actual.head;
|
|
273
|
+
}
|
|
274
|
+
function describe_checkout(checkout) {
|
|
275
|
+
return `${checkout.root} (branch ${checkout.branch}, HEAD ${checkout.head})`;
|
|
276
|
+
}
|
|
277
|
+
var review_checkout = { describe_checkout, is_same_checkout, read_checkout };
|
|
278
|
+
|
|
279
|
+
// scripts/review/review-attest.ts
|
|
280
|
+
var POINTER_PREFIX = "josh-review-target-";
|
|
281
|
+
var EXPECT_PREFIX = "josh-review-expect-";
|
|
282
|
+
var ATTEST_PREFIX = "josh-review-attest-";
|
|
283
|
+
var NONCE_BYTES = 8;
|
|
284
|
+
var HOURS_BEFORE_STALE = 8;
|
|
285
|
+
var MILLISECONDS_PER_HOUR = 36e5;
|
|
286
|
+
var STALE_AFTER_MS = HOURS_BEFORE_STALE * MILLISECONDS_PER_HOUR;
|
|
287
|
+
function pointer_path(root = PROJECT_ROOT) {
|
|
288
|
+
return stamp_file.stamp_path(POINTER_PREFIX, root);
|
|
289
|
+
}
|
|
290
|
+
function expect_path(nonce) {
|
|
291
|
+
return stamp_file.stamp_path(EXPECT_PREFIX, nonce);
|
|
292
|
+
}
|
|
293
|
+
function attest_path(nonce) {
|
|
294
|
+
return stamp_file.stamp_path(ATTEST_PREFIX, nonce);
|
|
295
|
+
}
|
|
296
|
+
function read_json(source) {
|
|
297
|
+
const raw = stamp_file.read_stamp_text(source);
|
|
298
|
+
return raw === void 0 ? void 0 : json_value.parse_or_undefined(raw);
|
|
299
|
+
}
|
|
300
|
+
function string_field(value, key) {
|
|
301
|
+
const field = value[key];
|
|
302
|
+
return typeof field === "string" ? field : void 0;
|
|
303
|
+
}
|
|
304
|
+
function to_checkout(value) {
|
|
305
|
+
if (!json_value.is_record(value)) return void 0;
|
|
306
|
+
const root = string_field(value, "root");
|
|
307
|
+
const branch = string_field(value, "branch");
|
|
308
|
+
const head = string_field(value, "head");
|
|
309
|
+
if (root === void 0 || branch === void 0 || head === void 0) return void 0;
|
|
310
|
+
return { root, branch, head };
|
|
311
|
+
}
|
|
312
|
+
function to_pointer(value) {
|
|
313
|
+
if (!json_value.is_record(value)) return void 0;
|
|
314
|
+
const nonce = string_field(value, "nonce");
|
|
315
|
+
const taken_at = string_field(value, "taken_at");
|
|
316
|
+
if (nonce !== void 0 && taken_at !== void 0) return { nonce, taken_at };
|
|
317
|
+
return void 0;
|
|
318
|
+
}
|
|
319
|
+
function read_pointer(root) {
|
|
320
|
+
return to_pointer(read_json(pointer_path(root)));
|
|
321
|
+
}
|
|
322
|
+
function read_expectation(nonce) {
|
|
323
|
+
return to_checkout(read_json(expect_path(nonce)));
|
|
324
|
+
}
|
|
325
|
+
function read_attestation(nonce) {
|
|
326
|
+
return to_checkout(read_json(attest_path(nonce)));
|
|
327
|
+
}
|
|
328
|
+
function drop_records(pointer) {
|
|
329
|
+
if (pointer === void 0) return;
|
|
330
|
+
stamp_file.remove_stamp(expect_path(pointer.nonce));
|
|
331
|
+
stamp_file.remove_stamp(attest_path(pointer.nonce));
|
|
332
|
+
}
|
|
333
|
+
function is_stale(taken_at, now) {
|
|
334
|
+
const taken = Date.parse(taken_at);
|
|
335
|
+
return Number.isNaN(taken) || now - taken > STALE_AFTER_MS;
|
|
336
|
+
}
|
|
337
|
+
function record_target(checkout, root) {
|
|
338
|
+
const nonce = randomBytes(NONCE_BYTES).toString("hex");
|
|
339
|
+
const taken_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
340
|
+
drop_records(read_pointer(root));
|
|
341
|
+
stamp_file.write_stamp(expect_path(nonce), { ...checkout, taken_at });
|
|
342
|
+
stamp_file.write_stamp(pointer_path(root), { nonce, taken_at });
|
|
343
|
+
return nonce;
|
|
344
|
+
}
|
|
345
|
+
function attest(nonce, actual) {
|
|
346
|
+
const expected = read_expectation(nonce);
|
|
347
|
+
if (expected === void 0) return { status: "missing", nonce, actual };
|
|
348
|
+
stamp_file.write_stamp(attest_path(nonce), { ...actual, taken_at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
349
|
+
if (review_checkout.is_same_checkout(expected, actual)) {
|
|
350
|
+
return { status: "ok", nonce, expected, actual };
|
|
351
|
+
}
|
|
352
|
+
return { status: "mismatch", nonce, expected, actual };
|
|
353
|
+
}
|
|
354
|
+
function not_required() {
|
|
355
|
+
return { status: "not-required" };
|
|
356
|
+
}
|
|
357
|
+
function verdict_for(nonce) {
|
|
358
|
+
const expected = read_expectation(nonce);
|
|
359
|
+
if (expected === void 0) return { status: "missing", nonce };
|
|
360
|
+
const actual = read_attestation(nonce);
|
|
361
|
+
if (actual === void 0) return { status: "missing", nonce, expected };
|
|
362
|
+
if (review_checkout.is_same_checkout(expected, actual)) {
|
|
363
|
+
return { status: "ok", nonce, expected, actual };
|
|
364
|
+
}
|
|
365
|
+
return { status: "mismatch", nonce, expected, actual };
|
|
366
|
+
}
|
|
367
|
+
function check(now = Date.now(), root) {
|
|
368
|
+
const pointer = read_pointer(root);
|
|
369
|
+
if (pointer === void 0) return not_required();
|
|
370
|
+
const verdict = verdict_for(pointer.nonce);
|
|
371
|
+
if (verdict.status === "missing" && is_stale(pointer.taken_at, now)) return not_required();
|
|
372
|
+
return verdict;
|
|
373
|
+
}
|
|
374
|
+
function is_written_since(source, taken_at) {
|
|
375
|
+
try {
|
|
376
|
+
const stats = lstatSync(source);
|
|
377
|
+
return stats.isFile() && stats.mtimeMs >= Date.parse(taken_at);
|
|
378
|
+
} catch {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function is_reviewed_on(checkout, findings_path, root) {
|
|
383
|
+
const pointer = read_pointer(root);
|
|
384
|
+
if (pointer === void 0) return false;
|
|
385
|
+
const verdict = verdict_for(pointer.nonce);
|
|
386
|
+
if (verdict.status !== "ok" || verdict.expected?.branch !== checkout.branch) return false;
|
|
387
|
+
return is_written_since(findings_path, pointer.taken_at);
|
|
388
|
+
}
|
|
389
|
+
function is_briefed_since(written_at, root) {
|
|
390
|
+
const pointer = read_pointer(root);
|
|
391
|
+
return pointer !== void 0 && written_at >= pointer.taken_at;
|
|
392
|
+
}
|
|
393
|
+
async function check_here(now = Date.now()) {
|
|
394
|
+
return check(now, await git_command.repository_root());
|
|
395
|
+
}
|
|
396
|
+
function clear2(root) {
|
|
397
|
+
const pointer = read_pointer(root);
|
|
398
|
+
stamp_file.remove_stamp(pointer_path(root));
|
|
399
|
+
drop_records(pointer);
|
|
400
|
+
}
|
|
401
|
+
async function clear_here2() {
|
|
402
|
+
clear2(await git_command.repository_root());
|
|
403
|
+
}
|
|
404
|
+
var MISMATCH_VERDICT = "REVIEW TARGET MISMATCH";
|
|
405
|
+
function describe_side(label, checkout) {
|
|
406
|
+
if (checkout === void 0) return `${label}: unknown`;
|
|
407
|
+
return `${label}: ${review_checkout.describe_checkout(checkout)}`;
|
|
408
|
+
}
|
|
409
|
+
var MISSING_REASON = "The review left no attestation, so there is no evidence it read this checkout at all. A review that read the wrong tree finds nothing wrong and reports no findings, which is indistinguishable from a clean review \u2014 so an absent attestation is treated as no review (joshuafolkken/kit#1522).";
|
|
410
|
+
var MISMATCH_REASON = `${MISMATCH_VERDICT}: the review attested a different checkout from the one it was briefed on. Its findings \u2014 including "no findings" \u2014 describe another tree.`;
|
|
411
|
+
var REMEDY = "Re-run `/code-review` with the brief `pnpm josh review:brief` prints, against the checkout named above, and let it run `pnpm josh review:attest <nonce>` from there before it reports.";
|
|
412
|
+
function refusal_message(verdict) {
|
|
413
|
+
const reason = verdict.status === "mismatch" ? MISMATCH_REASON : MISSING_REASON;
|
|
414
|
+
return [
|
|
415
|
+
reason,
|
|
416
|
+
describe_side("Briefed on", verdict.expected),
|
|
417
|
+
describe_side("Reviewed", verdict.actual),
|
|
418
|
+
REMEDY
|
|
419
|
+
].join("\n");
|
|
420
|
+
}
|
|
421
|
+
var review_attest = {
|
|
422
|
+
attest,
|
|
423
|
+
attest_path,
|
|
424
|
+
check,
|
|
425
|
+
check_here,
|
|
426
|
+
clear: clear2,
|
|
427
|
+
clear_here: clear_here2,
|
|
428
|
+
expect_path,
|
|
429
|
+
is_briefed_since,
|
|
430
|
+
is_reviewed_on,
|
|
431
|
+
MISMATCH_VERDICT,
|
|
432
|
+
MISSING_REASON,
|
|
433
|
+
pointer_path,
|
|
434
|
+
read_attestation,
|
|
435
|
+
read_expectation,
|
|
436
|
+
read_pointer,
|
|
437
|
+
record_target,
|
|
438
|
+
refusal_message,
|
|
439
|
+
STALE_AFTER_MS
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
// scripts/issue/issue-watch-gate.ts
|
|
443
|
+
var EVERY_CALL_MS = 0;
|
|
444
|
+
function ack_command(issue) {
|
|
445
|
+
return `pnpm josh issue:ack ${issue}`;
|
|
446
|
+
}
|
|
447
|
+
function unread_message(record) {
|
|
448
|
+
return [
|
|
449
|
+
`A person updated issue ${session_cite.issue(record.issue)} after this run read it, and the run has not taken the update in:`,
|
|
450
|
+
record.pending ?? "",
|
|
451
|
+
`Read it, compare it with the acceptance criteria, fix what it changes, then run \`${ack_command(record.issue)}\` to record that it was read.`
|
|
452
|
+
].join("\n\n");
|
|
453
|
+
}
|
|
454
|
+
function review_message(record, briefed_at) {
|
|
455
|
+
return [
|
|
456
|
+
`Issue ${session_cite.issue(record.issue)} was updated after the review was briefed (taken in at ${record.acknowledged_at}, briefed at ${briefed_at}), so the review read the earlier specification.`,
|
|
457
|
+
"Re-run `/code-review` with a fresh `pnpm josh review:brief`, so the review reads the change against the updated issue."
|
|
458
|
+
].join("\n");
|
|
459
|
+
}
|
|
460
|
+
async function polled(root) {
|
|
461
|
+
return await issue_watch.poll({ interval_ms: EVERY_CALL_MS }, root);
|
|
462
|
+
}
|
|
463
|
+
async function unread_refusal(root) {
|
|
464
|
+
const record = await polled(root);
|
|
465
|
+
return record?.pending === void 0 ? void 0 : unread_message(record);
|
|
466
|
+
}
|
|
467
|
+
async function review_refusal(root) {
|
|
468
|
+
const record = await polled(root);
|
|
469
|
+
if (record === void 0) return void 0;
|
|
470
|
+
if (record.pending !== void 0) return unread_message(record);
|
|
471
|
+
const pointer = review_attest.read_pointer(root);
|
|
472
|
+
if (pointer === void 0 || record.acknowledged_at <= pointer.taken_at) return void 0;
|
|
473
|
+
return review_message(record, pointer.taken_at);
|
|
474
|
+
}
|
|
475
|
+
async function review_refusal_here() {
|
|
476
|
+
return await review_refusal(await git_command.repository_root());
|
|
477
|
+
}
|
|
478
|
+
async function assert_read_here() {
|
|
479
|
+
const refusal = await unread_refusal(await git_command.repository_root());
|
|
480
|
+
if (refusal !== void 0) throw new Error(refusal);
|
|
481
|
+
}
|
|
482
|
+
var issue_watch_gate = {
|
|
483
|
+
assert_read_here,
|
|
484
|
+
review_refusal,
|
|
485
|
+
review_refusal_here,
|
|
486
|
+
unread_message,
|
|
487
|
+
unread_refusal
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// scripts/issue/issue-watch-hook.ts
|
|
491
|
+
var POLL_INTERVAL_MS = 18e4;
|
|
492
|
+
var POLL_TIMEOUT_MS = 5e3;
|
|
493
|
+
function is_new_to_run(record) {
|
|
494
|
+
return record?.pending !== void 0 && record.pending !== record.shown;
|
|
495
|
+
}
|
|
496
|
+
async function new_update_reason(now) {
|
|
497
|
+
const record = await issue_watch.poll({
|
|
498
|
+
interval_ms: POLL_INTERVAL_MS,
|
|
499
|
+
timeout_ms: POLL_TIMEOUT_MS,
|
|
500
|
+
now
|
|
501
|
+
});
|
|
502
|
+
if (!is_new_to_run(record)) return void 0;
|
|
503
|
+
issue_watch.mark_shown(record);
|
|
504
|
+
return issue_watch_gate.unread_message(record);
|
|
505
|
+
}
|
|
506
|
+
async function watch_reason(now = /* @__PURE__ */ new Date()) {
|
|
507
|
+
try {
|
|
508
|
+
return await new_update_reason(now);
|
|
509
|
+
} catch (error) {
|
|
510
|
+
error_text.trace_swallowed("issue_watch_hook.watch_reason", error);
|
|
511
|
+
return void 0;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
var issue_watch_hook = { POLL_INTERVAL_MS, watch_reason };
|
|
94
515
|
|
|
95
516
|
// scripts/run/event/run-event-plan.ts
|
|
96
517
|
var KIND = run_event_stream.EVENT_KIND.PLAN;
|
|
@@ -224,7 +645,7 @@ function format_line(observations, timing) {
|
|
|
224
645
|
next: format_next_report(timing.now_ms, timing.interval_ms)
|
|
225
646
|
});
|
|
226
647
|
}
|
|
227
|
-
function
|
|
648
|
+
function is_due2(last_report_ms, now_ms, interval_ms) {
|
|
228
649
|
return now_ms - last_report_ms >= interval_ms;
|
|
229
650
|
}
|
|
230
651
|
function minutes_from(raw) {
|
|
@@ -255,14 +676,14 @@ var run_progress = {
|
|
|
255
676
|
format_next_report,
|
|
256
677
|
format_report,
|
|
257
678
|
is_disabled,
|
|
258
|
-
is_due,
|
|
679
|
+
is_due: is_due2,
|
|
259
680
|
minutes_from,
|
|
260
681
|
next_state,
|
|
261
682
|
observation_key
|
|
262
683
|
};
|
|
263
684
|
|
|
264
685
|
// scripts/run/progress/run-progress-clock.ts
|
|
265
|
-
import { z } from "zod";
|
|
686
|
+
import { z as z2 } from "zod";
|
|
266
687
|
var PROGRESS_PREFIX = "josh-run-progress-";
|
|
267
688
|
var LIFE_PREFIX = "josh-run-progress-life-";
|
|
268
689
|
var LOG_SUFFIX = ".log";
|
|
@@ -271,7 +692,7 @@ var MS_PER_MINUTE2 = 6e4;
|
|
|
271
692
|
var LOG_STALE_MINUTES = 90;
|
|
272
693
|
var LOG_STALE_MS = LOG_STALE_MINUTES * MS_PER_MINUTE2;
|
|
273
694
|
var BLOCK_SEPARATOR = "\n\n";
|
|
274
|
-
var report_stamp_schema =
|
|
695
|
+
var report_stamp_schema = z2.object({ reported_at: z2.string(), line: z2.string().optional() });
|
|
275
696
|
function parse_stamp(raw) {
|
|
276
697
|
const parsed = report_stamp_schema.safeParse(JSON.parse(raw));
|
|
277
698
|
if (!parsed.success) return void 0;
|
|
@@ -326,7 +747,7 @@ function stamp_target_of(git_directory) {
|
|
|
326
747
|
function life_target_of(git_directory) {
|
|
327
748
|
return stamp_file.stamp_path(LIFE_PREFIX, git_directory);
|
|
328
749
|
}
|
|
329
|
-
var life_schema =
|
|
750
|
+
var life_schema = z2.object({ alive: z2.literal(true), pinged_at: z2.string().optional() });
|
|
330
751
|
function begin_life(target) {
|
|
331
752
|
stamp_file.write_stamp(target, { alive: true, pinged_at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
332
753
|
}
|
|
@@ -386,10 +807,10 @@ var run_progress_clock = {
|
|
|
386
807
|
// scripts/run/progress/run-progress-config.ts
|
|
387
808
|
import { readFileSync } from "node:fs";
|
|
388
809
|
import path from "node:path";
|
|
389
|
-
import { z as
|
|
810
|
+
import { z as z3 } from "zod";
|
|
390
811
|
var PACKAGE_FILE = "package.json";
|
|
391
|
-
var package_schema =
|
|
392
|
-
josh:
|
|
812
|
+
var package_schema = z3.object({
|
|
813
|
+
josh: z3.object({ progress_interval_minutes: z3.number().positive() }).optional()
|
|
393
814
|
});
|
|
394
815
|
function read_declared_minutes(directory) {
|
|
395
816
|
try {
|
|
@@ -707,18 +1128,18 @@ import { fileURLToPath } from "node:url";
|
|
|
707
1128
|
// scripts/cost-runtime/codex-usage.ts
|
|
708
1129
|
import { globSync, readFileSync as readFileSync2 } from "node:fs";
|
|
709
1130
|
import path2 from "node:path";
|
|
710
|
-
import { z as
|
|
1131
|
+
import { z as z4 } from "zod";
|
|
711
1132
|
var THREAD_ID_PATTERN = /^[A-Za-z0-9-]+$/u;
|
|
712
|
-
var SESSION_META_SCHEMA =
|
|
713
|
-
type:
|
|
714
|
-
payload:
|
|
1133
|
+
var SESSION_META_SCHEMA = z4.looseObject({
|
|
1134
|
+
type: z4.literal("session_meta"),
|
|
1135
|
+
payload: z4.looseObject({ id: z4.string(), cwd: z4.string() })
|
|
715
1136
|
});
|
|
716
|
-
var TOTAL_USAGE_SCHEMA =
|
|
717
|
-
var TOKEN_COUNT_SCHEMA =
|
|
718
|
-
type:
|
|
719
|
-
payload:
|
|
720
|
-
type:
|
|
721
|
-
info:
|
|
1137
|
+
var TOTAL_USAGE_SCHEMA = z4.looseObject({ input_tokens: z4.number().nonnegative() });
|
|
1138
|
+
var TOKEN_COUNT_SCHEMA = z4.looseObject({
|
|
1139
|
+
type: z4.literal("event_msg"),
|
|
1140
|
+
payload: z4.looseObject({
|
|
1141
|
+
type: z4.literal("token_count"),
|
|
1142
|
+
info: z4.looseObject({
|
|
722
1143
|
total_token_usage: TOTAL_USAGE_SCHEMA,
|
|
723
1144
|
last_token_usage: TOTAL_USAGE_SCHEMA
|
|
724
1145
|
})
|
|
@@ -948,8 +1369,8 @@ function selected_threshold(values) {
|
|
|
948
1369
|
function threshold_option(over) {
|
|
949
1370
|
return over === void 0 ? {} : { over };
|
|
950
1371
|
}
|
|
951
|
-
function path_option(
|
|
952
|
-
return
|
|
1372
|
+
function path_option(path16) {
|
|
1373
|
+
return path16 === void 0 ? {} : { path: path16 };
|
|
953
1374
|
}
|
|
954
1375
|
function to_options(values) {
|
|
955
1376
|
if (values.cut === true && values.over !== void 0) return void 0;
|
|
@@ -1088,7 +1509,7 @@ var cost_format = {
|
|
|
1088
1509
|
};
|
|
1089
1510
|
|
|
1090
1511
|
// scripts/rules/implementation-cut-verdict.ts
|
|
1091
|
-
import { z as
|
|
1512
|
+
import { z as z5 } from "zod";
|
|
1092
1513
|
var VERDICT_CACHE_PREFIX = "josh-impl-cut-verdict-";
|
|
1093
1514
|
var VERDICT_REUSE_MS = 5e3;
|
|
1094
1515
|
var VERDICT_VALUES = [
|
|
@@ -1096,7 +1517,7 @@ var VERDICT_VALUES = [
|
|
|
1096
1517
|
"under",
|
|
1097
1518
|
"unmeasurable"
|
|
1098
1519
|
];
|
|
1099
|
-
var cache_schema =
|
|
1520
|
+
var cache_schema = z5.object({ read_at_ms: z5.number(), verdict: z5.enum(VERDICT_VALUES) });
|
|
1100
1521
|
function cache_path(directory) {
|
|
1101
1522
|
return stamp_file.stamp_path(VERDICT_CACHE_PREFIX, directory);
|
|
1102
1523
|
}
|
|
@@ -1173,7 +1594,7 @@ function is_over_threshold_edit(call, state = current_state()) {
|
|
|
1173
1594
|
return warrants_the_cut(state);
|
|
1174
1595
|
}
|
|
1175
1596
|
var THRESHOLD_TEXT = `${cost_format.format_tokens(CONTEXT_CUT_THRESHOLD)}-token`;
|
|
1176
|
-
var IMPLEMENTATION_CUT_REASON = `\u26D4 implementation-phase cut: this checkout is a lane dispatched for this issue, or a run holds it for this issue (joshuafolkken/kit#2760), and its recent-context cost has crossed the shared ${THRESHOLD_TEXT} threshold mid-implementation, so the thinking accumulated so far is now re-read on every later request. Take the cut before this edit. First write a handoff file at \`${run_cut_handoff.HANDOFF_PATH}\` (ignored, so it is never committed) with the Write tool \u2014 the user\u2019s instruction verbatim, what you have completed, what remains, and what you deliberately did not touch, as ${run_cut_handoff.HANDOFF_FORMAT} (Markdown is refused) \u2014 and pass it as \`--handoff <path>\`, so the fresh process resumes on the original instruction rather than the working tree alone (joshuafolkken/kit#2354); a resume that finds no instruction is refused \`incomplete\` rather than continuing blind. \`pnpm josh run:cut --impl <N> --handoff <path>\` ends this process and relaunches a fresh one that resumes back into implementation (\`resume-impl\`), dropping the accumulated context rather than carrying it \u2014 joshuafolkken/kit#1933 built the boundary and joshuafolkken/kit#2310 measured it firing 0 times because the verdict was only ever read at session entry, where the context has not yet grown. The verdict is \`pnpm josh cost --cut\`'s exactly \u2014 the same per-request billed-input statistic against the same threshold, never a second measurement. Issue \`pnpm josh run:cut --impl <N> --handoff <path>\` now and read the verdict: on \`cut\`, **end the turn immediately** \u2014
|
|
1597
|
+
var IMPLEMENTATION_CUT_REASON = `\u26D4 implementation-phase cut: this checkout is a lane dispatched for this issue, or a run holds it for this issue (joshuafolkken/kit#2760), and its recent-context cost has crossed the shared ${THRESHOLD_TEXT} threshold mid-implementation, so the thinking accumulated so far is now re-read on every later request. Take the cut before this edit. First write a handoff file at \`${run_cut_handoff.HANDOFF_PATH}\` (ignored, so it is never committed) with the Write tool \u2014 the user\u2019s instruction verbatim, what you have completed, what remains, and what you deliberately did not touch, as ${run_cut_handoff.HANDOFF_FORMAT} (Markdown is refused) \u2014 and pass it as \`--handoff <path>\`, so the fresh process resumes on the original instruction rather than the working tree alone (joshuafolkken/kit#2354); a resume that finds no instruction is refused \`incomplete\` rather than continuing blind. \`pnpm josh run:cut --impl <N> --handoff <path>\` ends this process and relaunches a fresh one that resumes back into implementation (\`resume-impl\`), dropping the accumulated context rather than carrying it \u2014 joshuafolkken/kit#1933 built the boundary and joshuafolkken/kit#2310 measured it firing 0 times because the verdict was only ever read at session entry, where the context has not yet grown. The verdict is \`pnpm josh cost --cut\`'s exactly \u2014 the same per-request billed-input statistic against the same threshold, never a second measurement. Issue \`pnpm josh run:cut --impl <N> --handoff <path>\` now and read the verdict: on \`cut\`, read what the command printed. Where it relaunched a fresh process, **end the turn immediately** \u2014 that process owns the run and continues implementing, so it must not be waited for, and **no Telegram is owed**: a cut that resumes itself leaves a person nothing to act on. Where it printed that nothing was relaunched, do what it prints, then end the turn; on \`not-a-lane\`, \`unready\`, \`busy\`, \`failed\` or \`unknown\`, this process carries the run on and the edit is simply the next call. Never relaunch a second process after \`busy\`. This fired because the dispatch mark names this lane or the run hold names this issue; a person working here carries no mark and holds no run, so sees no refusal, so there is no human-or-child judgement left to make. The procedure is \`.claude/skills/workflow-commands/pre-gate-cut.md\`. Reissue this edit once the cut has answered \u2014 an edit reissued right after this refusal passes, so \`busy\` / \`failed\` cannot wedge the run edit after edit; this fires again on the next threshold crossing rather than once per run.`;
|
|
1177
1598
|
var REISSUE_WINDOW_MS = 9e4;
|
|
1178
1599
|
function is_reissued_refusal(now_ms, delivered_at_ms) {
|
|
1179
1600
|
return now_ms - delivered_at_ms < REISSUE_WINDOW_MS;
|
|
@@ -1395,20 +1816,20 @@ var lane_carry_conflict = {
|
|
|
1395
1816
|
};
|
|
1396
1817
|
|
|
1397
1818
|
// scripts/agent/interactive-ask.ts
|
|
1398
|
-
import { z as
|
|
1819
|
+
import { z as z6 } from "zod";
|
|
1399
1820
|
var INTERACTIVE_TOOLS = /* @__PURE__ */ new Set(["AskUserQuestion"]);
|
|
1400
1821
|
function is_interactive_tool(name) {
|
|
1401
1822
|
return INTERACTIVE_TOOLS.has(name);
|
|
1402
1823
|
}
|
|
1403
|
-
var OPTION_SCHEMA =
|
|
1404
|
-
var QUESTION_SCHEMA =
|
|
1405
|
-
question:
|
|
1406
|
-
options:
|
|
1824
|
+
var OPTION_SCHEMA = z6.looseObject({ label: z6.string().optional() });
|
|
1825
|
+
var QUESTION_SCHEMA = z6.looseObject({
|
|
1826
|
+
question: z6.string().optional(),
|
|
1827
|
+
options: z6.array(OPTION_SCHEMA).optional()
|
|
1407
1828
|
});
|
|
1408
|
-
var ASK_INPUT_SCHEMA =
|
|
1409
|
-
var DENIAL_SCHEMA =
|
|
1410
|
-
tool_name:
|
|
1411
|
-
tool_input:
|
|
1829
|
+
var ASK_INPUT_SCHEMA = z6.looseObject({ questions: z6.array(QUESTION_SCHEMA).optional() });
|
|
1830
|
+
var DENIAL_SCHEMA = z6.looseObject({
|
|
1831
|
+
tool_name: z6.string().optional(),
|
|
1832
|
+
tool_input: z6.unknown().optional()
|
|
1412
1833
|
});
|
|
1413
1834
|
var UNKNOWN_QUESTION = "(question text unavailable)";
|
|
1414
1835
|
var OPTION_SEPARATOR = " / ";
|
|
@@ -2301,20 +2722,20 @@ import path4 from "node:path";
|
|
|
2301
2722
|
var KIT_PACKAGE_NAME = "@joshuafolkken/kit";
|
|
2302
2723
|
|
|
2303
2724
|
// scripts/doctor/doctor-consumer.ts
|
|
2304
|
-
import { z as
|
|
2725
|
+
import { z as z7 } from "zod";
|
|
2305
2726
|
var NODE_MODULES = "node_modules";
|
|
2306
2727
|
var SETTINGS_PATH = path4.join(".claude", "settings.json");
|
|
2307
2728
|
var CLAUDE_MD = "CLAUDE.md";
|
|
2308
2729
|
var PLUGIN_ID = "kit@kit";
|
|
2309
2730
|
var CLAUDE_MD_POINTER = `@${NODE_MODULES}/${KIT_PACKAGE_NAME}/dist/${CLAUDE_MD}`;
|
|
2310
2731
|
var SECRETLINT_BIN = path4.join(NODE_MODULES, ".bin", "secretlint");
|
|
2311
|
-
var manifest_schema =
|
|
2312
|
-
name:
|
|
2313
|
-
dependencies:
|
|
2314
|
-
devDependencies:
|
|
2732
|
+
var manifest_schema = z7.object({
|
|
2733
|
+
name: z7.string().optional(),
|
|
2734
|
+
dependencies: z7.record(z7.string(), z7.string()).optional(),
|
|
2735
|
+
devDependencies: z7.record(z7.string(), z7.string()).optional()
|
|
2315
2736
|
});
|
|
2316
|
-
var settings_schema =
|
|
2317
|
-
enabledPlugins:
|
|
2737
|
+
var settings_schema = z7.object({
|
|
2738
|
+
enabledPlugins: z7.record(z7.string(), z7.boolean()).optional()
|
|
2318
2739
|
});
|
|
2319
2740
|
var STATE_OK = "ok";
|
|
2320
2741
|
var STATE_TARGET_MISSING = "target-missing";
|
|
@@ -2358,9 +2779,9 @@ function is_secretlint_runnable(root) {
|
|
|
2358
2779
|
function status_line(is_ok, ok_text, warn_text) {
|
|
2359
2780
|
return is_ok ? ` \u2713 ${ok_text}` : ` \u26A0 ${warn_text}`;
|
|
2360
2781
|
}
|
|
2361
|
-
function plugin_line(
|
|
2782
|
+
function plugin_line(is_declared3) {
|
|
2362
2783
|
return status_line(
|
|
2363
|
-
|
|
2784
|
+
is_declared3,
|
|
2364
2785
|
"kit plugin declared (skills load in a trusted workspace; headless from its second session)",
|
|
2365
2786
|
"kit plugin not declared in .claude/settings.json \u2014 run `pnpm josh sync`"
|
|
2366
2787
|
);
|
|
@@ -2653,7 +3074,7 @@ function is_uncut_gate(command, state = current_state2()) {
|
|
|
2653
3074
|
if (!runs_the_gate(command) || uncut_lane_issue(state) === void 0) return false;
|
|
2654
3075
|
return warrants_the_cut2(state.context_verdict());
|
|
2655
3076
|
}
|
|
2656
|
-
var PRE_GATE_CUT_REASON = "\u26D4 pre-gate cut: this checkout is a lane dispatched for this issue and the gate is the boundary to cut at, so take the cut before running it. `pnpm josh run:cut <N>` ends this process and relaunches a fresh one that resumes from the gate, dropping the thinking built up while implementing rather than carrying it on every later request \u2014 joshuafolkken/kit#1839 measured 176K of 204K output riding across that boundary, and joshuafolkken/kit#1864 measured the step itself firing 0 times in 6 lane children while it was carried as prose. Issue `pnpm josh run:cut <N>` now, and read the verdict: on `cut`, **end the turn immediately** \u2014 the fresh process owns the run from there and must not be waited for; on `not-a-lane`, `unready`, `busy`, `failed` or `unknown`, this process carries the run on and the gate is simply the next call. Never relaunch a second process after `busy`. This fired because the dispatch mark names this lane; a person working here carries no mark and sees no refusal, so there is no human-or-child judgement left to make. The procedure is `.claude/skills/workflow-commands/pre-gate-cut.md`. Reissue the gate once the cut has answered \u2014 this fires once per run, so it cannot repeat on the call in hand.";
|
|
3077
|
+
var PRE_GATE_CUT_REASON = "\u26D4 pre-gate cut: this checkout is a lane dispatched for this issue and the gate is the boundary to cut at, so take the cut before running it. `pnpm josh run:cut <N>` ends this process and relaunches a fresh one that resumes from the gate, dropping the thinking built up while implementing rather than carrying it on every later request \u2014 joshuafolkken/kit#1839 measured 176K of 204K output riding across that boundary, and joshuafolkken/kit#1864 measured the step itself firing 0 times in 6 lane children while it was carried as prose. Issue `pnpm josh run:cut <N>` now, and read the verdict: on `cut`, **end the turn immediately** \u2014 the fresh process owns the run from there and must not be waited for, and **no Telegram is owed** for a cut that resumes itself; on `not-a-lane`, `unready`, `busy`, `failed` or `unknown`, this process carries the run on and the gate is simply the next call. Never relaunch a second process after `busy`. This fired because the dispatch mark names this lane; a person working here carries no mark and sees no refusal, so there is no human-or-child judgement left to make. The procedure is `.claude/skills/workflow-commands/pre-gate-cut.md`. Reissue the gate once the cut has answered \u2014 this fires once per run, so it cannot repeat on the call in hand.";
|
|
2657
3078
|
function reaches_the_pre_gate_boundary(call, _turn, run2) {
|
|
2658
3079
|
if (!bash_triggers.on_bash_command(asks_about_the_cut)(call)) return false;
|
|
2659
3080
|
return run2.some((issued) => bash_triggers.on_bash_command(claims_the_hold)(issued));
|
|
@@ -2701,7 +3122,7 @@ var MIN_APPENDED_PROSE = 120;
|
|
|
2701
3122
|
function adds_rule_prose(old_text, new_text) {
|
|
2702
3123
|
return prose_of(new_text).length - prose_of(old_text).length >= MIN_APPENDED_PROSE;
|
|
2703
3124
|
}
|
|
2704
|
-
function
|
|
3125
|
+
function string_field2(input, key) {
|
|
2705
3126
|
const value = input[key];
|
|
2706
3127
|
return typeof value === "string" ? value : "";
|
|
2707
3128
|
}
|
|
@@ -2711,13 +3132,13 @@ function read_existing(file_path) {
|
|
|
2711
3132
|
function texts_of(name, input, read2) {
|
|
2712
3133
|
if (name === WRITE_TOOL) {
|
|
2713
3134
|
return {
|
|
2714
|
-
old_text: read2(
|
|
2715
|
-
new_text:
|
|
3135
|
+
old_text: read2(string_field2(input, "file_path")),
|
|
3136
|
+
new_text: string_field2(input, "content")
|
|
2716
3137
|
};
|
|
2717
3138
|
}
|
|
2718
3139
|
return {
|
|
2719
|
-
old_text:
|
|
2720
|
-
new_text:
|
|
3140
|
+
old_text: string_field2(input, "old_string"),
|
|
3141
|
+
new_text: string_field2(input, "new_string")
|
|
2721
3142
|
};
|
|
2722
3143
|
}
|
|
2723
3144
|
function is_edit_tool2(name) {
|
|
@@ -2725,7 +3146,7 @@ function is_edit_tool2(name) {
|
|
|
2725
3146
|
}
|
|
2726
3147
|
function rule_document_input(call) {
|
|
2727
3148
|
if (!is_edit_tool2(call.name) || !json_value.is_record(call.input)) return void 0;
|
|
2728
|
-
return is_rule_document(
|
|
3149
|
+
return is_rule_document(string_field2(call.input, "file_path")) ? call.input : void 0;
|
|
2729
3150
|
}
|
|
2730
3151
|
function writes_rule_prose(call, read2 = read_existing) {
|
|
2731
3152
|
const input = rule_document_input(call);
|
|
@@ -2838,12 +3259,2070 @@ var shell_body_trigger = {
|
|
|
2838
3259
|
};
|
|
2839
3260
|
|
|
2840
3261
|
// scripts/gate/project-checks.ts
|
|
2841
|
-
import { existsSync as
|
|
3262
|
+
import { existsSync as existsSync7, globSync as globSync2, readFileSync as readFileSync6 } from "node:fs";
|
|
3263
|
+
import path13 from "node:path";
|
|
3264
|
+
|
|
3265
|
+
// scripts/init/own-formatter.ts
|
|
3266
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
3267
|
+
import path6 from "node:path";
|
|
3268
|
+
var OWN_FORMATTER_CONFIGS = [
|
|
3269
|
+
"biome.json",
|
|
3270
|
+
"biome.jsonc",
|
|
3271
|
+
"dprint.json",
|
|
3272
|
+
"dprint.jsonc",
|
|
3273
|
+
".dprint.json",
|
|
3274
|
+
".dprint.jsonc"
|
|
3275
|
+
];
|
|
3276
|
+
function find_config(root) {
|
|
3277
|
+
return OWN_FORMATTER_CONFIGS.find((name) => existsSync3(path6.join(root, name)));
|
|
3278
|
+
}
|
|
3279
|
+
var own_formatter = { find_config };
|
|
3280
|
+
|
|
3281
|
+
// scripts/init/project-profile.ts
|
|
3282
|
+
import { existsSync as existsSync6, readdirSync, readFileSync as readFileSync5 } from "node:fs";
|
|
3283
|
+
import path12 from "node:path";
|
|
3284
|
+
|
|
3285
|
+
// scripts/safe-chain/pack-hook.ts
|
|
3286
|
+
import { z as z8 } from "zod";
|
|
3287
|
+
var PACK_HOOK_FILE = ".pnpmfile.mjs";
|
|
3288
|
+
var manifest_schema2 = z8.looseObject({ private: z8.boolean().optional() });
|
|
3289
|
+
var MESSAGES = {
|
|
3290
|
+
written: ` \u2714 synced ${PACK_HOOK_FILE} (run \`pnpm install\` to refresh pnpmfileChecksum)`,
|
|
3291
|
+
unchanged: ` \u2714 unchanged ${PACK_HOOK_FILE}`,
|
|
3292
|
+
private: void 0,
|
|
3293
|
+
owned: ` \u26A0 skipped ${PACK_HOOK_FILE} \u2014 the project has its own pnpmfile; strip the safe-chain preinstall at pack time there`,
|
|
3294
|
+
withdrawn: ` \u26A0 removed ${PACK_HOOK_FILE} \u2014 it shadowed the project's own pnpmfile; strip the safe-chain preinstall at pack time there`
|
|
3295
|
+
};
|
|
3296
|
+
|
|
3297
|
+
// scripts/lib/yaml-document.ts
|
|
3298
|
+
import { load, loadAll, YAMLException } from "js-yaml";
|
|
3299
|
+
var EMPTY_YAML_REASON = "expected a document, but the input is empty";
|
|
3300
|
+
function load_yaml_or_empty(content) {
|
|
3301
|
+
try {
|
|
3302
|
+
return load(content);
|
|
3303
|
+
} catch (error) {
|
|
3304
|
+
if (error instanceof YAMLException && error.reason === EMPTY_YAML_REASON) return {};
|
|
3305
|
+
throw error;
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
function parse_yaml(content) {
|
|
3309
|
+
const raw = load_yaml_or_empty(content);
|
|
3310
|
+
if (raw === null || raw === void 0) return {};
|
|
3311
|
+
return json_object_schema.parse(raw);
|
|
3312
|
+
}
|
|
3313
|
+
function is_mapping_document(value) {
|
|
3314
|
+
return json_value.is_record(value);
|
|
3315
|
+
}
|
|
3316
|
+
function parse_yaml_documents(content) {
|
|
3317
|
+
if (content.trim().length === 0) return [];
|
|
3318
|
+
return loadAll(content).filter(is_mapping_document);
|
|
3319
|
+
}
|
|
3320
|
+
var yaml_document = { is_mapping_document, parse_yaml, parse_yaml_documents };
|
|
3321
|
+
|
|
3322
|
+
// scripts/version/release-age.ts
|
|
3323
|
+
import semver from "semver";
|
|
3324
|
+
import { z as z9 } from "zod";
|
|
3325
|
+
var workspace_age_schema = z9.object({ minimumReleaseAge: z9.number().int().nonnegative() });
|
|
3326
|
+
var release_times_schema = z9.record(z9.string(), z9.string());
|
|
3327
|
+
|
|
3328
|
+
// scripts/safe-chain/project-config.ts
|
|
3329
|
+
import { dump } from "js-yaml";
|
|
3330
|
+
import { z as z10 } from "zod";
|
|
3331
|
+
var PROJECT_CONFIG_FILE = ".aikido";
|
|
3332
|
+
var workspace_schema = z10.object({ minimumReleaseAgeExclude: z10.array(z10.string()).optional() });
|
|
3333
|
+
|
|
3334
|
+
// scripts/config-merge/json-format.ts
|
|
3335
|
+
var PRINT_WIDTH = 100;
|
|
3336
|
+
var TAB_WIDTH = 2;
|
|
3337
|
+
var ARRAY_CLOSE = /^\t*\],?$/u;
|
|
3338
|
+
function is_array_open(line) {
|
|
3339
|
+
return line.endsWith("[");
|
|
3340
|
+
}
|
|
3341
|
+
function is_leaf_element(line) {
|
|
3342
|
+
return !line.endsWith("{") && !line.endsWith("[");
|
|
3343
|
+
}
|
|
3344
|
+
function line_width(line) {
|
|
3345
|
+
const tabs = line.length - line.trimStart().length;
|
|
3346
|
+
return tabs * TAB_WIDTH + (line.length - tabs);
|
|
3347
|
+
}
|
|
3348
|
+
function flatten_elements(elements) {
|
|
3349
|
+
const scalars = elements.map((line) => line.trim().replace(/,$/u, ""));
|
|
3350
|
+
return `[${scalars.join(", ")}]`;
|
|
3351
|
+
}
|
|
3352
|
+
function collect_block(lines, start) {
|
|
3353
|
+
const close = lines.findIndex((line, index) => index > start && ARRAY_CLOSE.test(line));
|
|
3354
|
+
if (close === -1) return void 0;
|
|
3355
|
+
const elements = lines.slice(start + 1, close);
|
|
3356
|
+
if (elements.some((line) => !is_leaf_element(line))) return void 0;
|
|
3357
|
+
return { elements, close: lines[close] ?? "", end: close };
|
|
3358
|
+
}
|
|
3359
|
+
function try_inline(open, block) {
|
|
3360
|
+
const trailing_comma = block.close.trimStart() === "]," ? "," : "";
|
|
3361
|
+
const inlined = `${open.slice(0, -1)}${flatten_elements(block.elements)}${trailing_comma}`;
|
|
3362
|
+
return line_width(inlined) <= PRINT_WIDTH ? inlined : void 0;
|
|
3363
|
+
}
|
|
3364
|
+
function rewrite_at(lines, index, line) {
|
|
3365
|
+
const verbatim = { lines: [line], next: index + 1 };
|
|
3366
|
+
const block = is_array_open(line) ? collect_block(lines, index) : void 0;
|
|
3367
|
+
if (block === void 0) return verbatim;
|
|
3368
|
+
const inlined = try_inline(line, block);
|
|
3369
|
+
if (inlined === void 0) return verbatim;
|
|
3370
|
+
return { lines: [inlined], next: block.end + 1 };
|
|
3371
|
+
}
|
|
3372
|
+
function inline_short_arrays(text) {
|
|
3373
|
+
const lines = text.split("\n");
|
|
3374
|
+
const output = [];
|
|
3375
|
+
let index = 0;
|
|
3376
|
+
while (index < lines.length) {
|
|
3377
|
+
const rewrite = rewrite_at(lines, index, lines[index] ?? "");
|
|
3378
|
+
output.push(...rewrite.lines);
|
|
3379
|
+
index = rewrite.next;
|
|
3380
|
+
}
|
|
3381
|
+
return output.join("\n");
|
|
3382
|
+
}
|
|
3383
|
+
function format_json(value) {
|
|
3384
|
+
return `${inline_short_arrays(JSON.stringify(value, void 0, " "))}
|
|
3385
|
+
`;
|
|
3386
|
+
}
|
|
3387
|
+
function format_package_json(value) {
|
|
3388
|
+
return `${JSON.stringify(value, void 0, " ")}
|
|
3389
|
+
`;
|
|
3390
|
+
}
|
|
3391
|
+
var json_format = {
|
|
3392
|
+
format_json,
|
|
3393
|
+
format_package_json
|
|
3394
|
+
};
|
|
3395
|
+
|
|
3396
|
+
// scripts/safe-chain/preinstall-command.ts
|
|
3397
|
+
var INSTALL_GUIDE_ANCHOR = "installing-safe-chain";
|
|
3398
|
+
var INSTALL_GUIDE_URL = `https://github.com/joshuafolkken/kit/blob/main/SECURITY.md#${INSTALL_GUIDE_ANCHOR}`;
|
|
3399
|
+
var INTEGRATION_HINT = `Warning: safe-chain (@aikidosec/safe-chain) is not scanning this install because its shell integration is not active. Install it with the hash-verified steps at ${INSTALL_GUIDE_URL} - then restart your terminal.`;
|
|
3400
|
+
var LOCAL_INTEGRATION_CHECK_SOURCE = `if(!process.env.CI&&!process.env.GLOBAL_AGENT_HTTP_PROXY)console.warn('${INTEGRATION_HINT}')`;
|
|
3401
|
+
var SAFE_CHAIN_CMD = `node -e "${LOCAL_INTEGRATION_CHECK_SOURCE}"`;
|
|
3402
|
+
var LEGACY_PREINSTALL_RE = /^pnpm dlx @aikidosec\/safe-chain(?:@\S+)? setup-ci(?: && node -e "[^"]*")?$/u;
|
|
3403
|
+
function migrate_preinstall(value) {
|
|
3404
|
+
return LEGACY_PREINSTALL_RE.test(value) ? SAFE_CHAIN_CMD : value;
|
|
3405
|
+
}
|
|
3406
|
+
var safe_chain_preinstall = {
|
|
3407
|
+
SAFE_CHAIN_CMD,
|
|
3408
|
+
LOCAL_INTEGRATION_CHECK_SOURCE,
|
|
3409
|
+
INTEGRATION_HINT,
|
|
3410
|
+
INSTALL_GUIDE_ANCHOR,
|
|
3411
|
+
migrate_preinstall
|
|
3412
|
+
};
|
|
3413
|
+
|
|
3414
|
+
// scripts/init/distributed-paths.ts
|
|
3415
|
+
var KIT_PACKAGE_PATH_PREFIX = "node_modules/@joshuafolkken/kit/";
|
|
3416
|
+
var PROMPTS_PACKAGE_PREFIX = `${KIT_PACKAGE_PATH_PREFIX}prompts/`;
|
|
3417
|
+
var ESLINT_PACKAGE_PREFIX = `${KIT_PACKAGE_PATH_PREFIX}eslint/`;
|
|
3418
|
+
var GITHUB_REPO_BLOB_BASE = "https://github.com/joshuafolkken/kit/blob/main/";
|
|
3419
|
+
var GITHUB_REPO_TREE_BASE = "https://github.com/joshuafolkken/kit/tree/main/";
|
|
3420
|
+
var CLAUDE_MD_IMPORT_LINE = "@node_modules/@joshuafolkken/kit/dist/CLAUDE.md";
|
|
3421
|
+
var OLD_CLAUDE_MD_BOOTSTRAP = "> Fresh checkout: if kit is not installed, run `pnpm install` first, then reread this file before doing any other work.";
|
|
3422
|
+
var CLAUDE_MD_BOOTSTRAP = '> Fresh checkout: before `pnpm install`, run `pnpm config get "@joshuafolkken:registry"` from the project root to check the effective registry, including user-level settings. If it points to GitHub Packages, [set up authentication](https://github.com/joshuafolkken/kit/blob/main/docs/authentication.md#1-get-a-token-from-the-gh-cli) first. Then run `pnpm install` and reread this file before doing any other work.';
|
|
3423
|
+
function transform_prompt_paths(content) {
|
|
3424
|
+
return content.replaceAll(
|
|
3425
|
+
/`prompts\/([^`*]+)`/gu,
|
|
3426
|
+
(_match, prompt_path) => `\`${PROMPTS_PACKAGE_PREFIX}${prompt_path}\``
|
|
3427
|
+
);
|
|
3428
|
+
}
|
|
3429
|
+
function transform_eslint_paths(content) {
|
|
3430
|
+
return content.replaceAll(
|
|
3431
|
+
/`eslint\/([^`*]+)`/gu,
|
|
3432
|
+
(_match, eslint_path) => `\`${ESLINT_PACKAGE_PREFIX}${eslint_path}\``
|
|
3433
|
+
);
|
|
3434
|
+
}
|
|
3435
|
+
function transform_test_file_paths(content) {
|
|
3436
|
+
return content.replaceAll(
|
|
3437
|
+
/`([^`*]+\.(?:test|spec)\.ts)`/gu,
|
|
3438
|
+
(_match, test_path) => `\`${GITHUB_REPO_BLOB_BASE}${test_path}\``
|
|
3439
|
+
);
|
|
3440
|
+
}
|
|
3441
|
+
function github_url_base(reference_path) {
|
|
3442
|
+
return reference_path.endsWith("/") ? GITHUB_REPO_TREE_BASE : GITHUB_REPO_BLOB_BASE;
|
|
3443
|
+
}
|
|
3444
|
+
function transform_documentation_paths(content) {
|
|
3445
|
+
return content.replaceAll(
|
|
3446
|
+
/`(docs\/[^`*]*)`/gu,
|
|
3447
|
+
(_match, documentation_path) => `\`${github_url_base(documentation_path)}${documentation_path}\``
|
|
3448
|
+
);
|
|
3449
|
+
}
|
|
3450
|
+
function transform_distributed_paths(content) {
|
|
3451
|
+
const with_prompts = transform_prompt_paths(content);
|
|
3452
|
+
const with_eslint = transform_eslint_paths(with_prompts);
|
|
3453
|
+
const with_tests = transform_test_file_paths(with_eslint);
|
|
3454
|
+
return transform_documentation_paths(with_tests);
|
|
3455
|
+
}
|
|
3456
|
+
function ensure_claude_md_import(existing) {
|
|
3457
|
+
if (existing === void 0) return `${CLAUDE_MD_BOOTSTRAP}
|
|
3458
|
+
|
|
3459
|
+
${CLAUDE_MD_IMPORT_LINE}
|
|
3460
|
+
`;
|
|
3461
|
+
const updated = existing.replace(OLD_CLAUDE_MD_BOOTSTRAP, () => CLAUDE_MD_BOOTSTRAP);
|
|
3462
|
+
if (updated.includes(CLAUDE_MD_IMPORT_LINE)) {
|
|
3463
|
+
if (updated.includes(CLAUDE_MD_BOOTSTRAP)) return updated;
|
|
3464
|
+
return `${CLAUDE_MD_BOOTSTRAP}
|
|
3465
|
+
|
|
3466
|
+
${updated}`;
|
|
3467
|
+
}
|
|
3468
|
+
return `${CLAUDE_MD_BOOTSTRAP}
|
|
3469
|
+
|
|
3470
|
+
${CLAUDE_MD_IMPORT_LINE}
|
|
3471
|
+
|
|
3472
|
+
${updated}`;
|
|
3473
|
+
}
|
|
3474
|
+
var FULL_CLAUDE_MD_LINES = /* @__PURE__ */ new Set([
|
|
3475
|
+
CLAUDE_MD_BOOTSTRAP,
|
|
3476
|
+
OLD_CLAUDE_MD_BOOTSTRAP,
|
|
3477
|
+
CLAUDE_MD_IMPORT_LINE
|
|
3478
|
+
]);
|
|
3479
|
+
function remove_claude_md_import(content) {
|
|
3480
|
+
const lines = content.split("\n");
|
|
3481
|
+
return lines.filter((line, index) => {
|
|
3482
|
+
if (FULL_CLAUDE_MD_LINES.has(line)) return false;
|
|
3483
|
+
return line !== "" || !FULL_CLAUDE_MD_LINES.has(lines[index - 1] ?? "");
|
|
3484
|
+
}).join("\n");
|
|
3485
|
+
}
|
|
3486
|
+
var distributed_paths = {
|
|
3487
|
+
transform_prompt_paths,
|
|
3488
|
+
transform_distributed_paths,
|
|
3489
|
+
ensure_claude_md_import,
|
|
3490
|
+
remove_claude_md_import,
|
|
3491
|
+
CLAUDE_MD_IMPORT_LINE
|
|
3492
|
+
};
|
|
3493
|
+
|
|
3494
|
+
// scripts/init/init-logic-deploy-vps.ts
|
|
3495
|
+
import semver2 from "semver";
|
|
3496
|
+
var PNPM_INSTALL_PATTERN = /npm install -g pnpm@\d[\d.]{0,19}/gu;
|
|
3497
|
+
var PNPM12_INSTALL = "npm install -g pnpm@12.6.0";
|
|
3498
|
+
var MINIMUM_PNPM_VERSION = "12.1.0";
|
|
3499
|
+
var OLD_PNPM_CHECK_PATTERN = /^([ \t]*)if ! command -v pnpm &> \/dev\/null(?: \|\| \[ "\$PNPM_MAJOR" -lt \d+ \])?; then$/mu;
|
|
3500
|
+
var OLD_MAJOR_LINE_PATTERN = /^[ \t]*PNPM_MAJOR=\$\(pnpm --version 2>\/dev\/null \| cut -d\. -f1 \|\| echo "0"\)\n/mu;
|
|
3501
|
+
var VERSION_CHECK_MARKER = '[ "$PNPM_MINOR" -lt 1 ]';
|
|
3502
|
+
function replace_outdated_install(command) {
|
|
3503
|
+
const version = command.slice("npm install -g pnpm@".length);
|
|
3504
|
+
const valid_version = semver2.valid(version);
|
|
3505
|
+
if (valid_version === null) return command;
|
|
3506
|
+
return semver2.lt(valid_version, MINIMUM_PNPM_VERSION) ? PNPM12_INSTALL : command;
|
|
3507
|
+
}
|
|
3508
|
+
function build_version_check(indent) {
|
|
3509
|
+
return [
|
|
3510
|
+
`${indent}PNPM_VERSION=$(pnpm --version 2>/dev/null || echo "0.0.0")`,
|
|
3511
|
+
`${indent}PNPM_MAJOR=$(echo "$PNPM_VERSION" | cut -d. -f1)`,
|
|
3512
|
+
`${indent}PNPM_MINOR=$(echo "$PNPM_VERSION" | cut -d. -f2)`,
|
|
3513
|
+
`${indent}if [ "$PNPM_MAJOR" -lt 12 ] || { [ "$PNPM_MAJOR" -eq 12 ] && [ "$PNPM_MINOR" -lt 1 ]; }; then`
|
|
3514
|
+
].join("\n");
|
|
3515
|
+
}
|
|
3516
|
+
function patch_deploy_vps_pnpm(content) {
|
|
3517
|
+
const with_pnpm12 = content.replaceAll(
|
|
3518
|
+
PNPM_INSTALL_PATTERN,
|
|
3519
|
+
(command) => replace_outdated_install(command)
|
|
3520
|
+
);
|
|
3521
|
+
if (with_pnpm12.includes(VERSION_CHECK_MARKER)) return with_pnpm12;
|
|
3522
|
+
if (!OLD_PNPM_CHECK_PATTERN.test(with_pnpm12)) return with_pnpm12;
|
|
3523
|
+
return with_pnpm12.replace(OLD_MAJOR_LINE_PATTERN, "").replace(OLD_PNPM_CHECK_PATTERN, (_, indent) => build_version_check(indent));
|
|
3524
|
+
}
|
|
3525
|
+
var init_logic_deploy_vps = { patch_deploy_vps_pnpm };
|
|
3526
|
+
|
|
3527
|
+
// scripts/config-merge/list-patch.ts
|
|
3528
|
+
function is_matching(entry, matchers) {
|
|
3529
|
+
return matchers.some(
|
|
3530
|
+
(matcher) => typeof matcher === "string" ? matcher === entry : matcher.test(entry)
|
|
3531
|
+
);
|
|
3532
|
+
}
|
|
3533
|
+
function apply_remove(existing, remove) {
|
|
3534
|
+
if (remove === void 0 || remove.length === 0) return existing;
|
|
3535
|
+
return existing.filter((entry) => !is_matching(entry, remove));
|
|
3536
|
+
}
|
|
3537
|
+
function collect_additions(kept, ensure) {
|
|
3538
|
+
if (ensure === void 0) return [];
|
|
3539
|
+
return ensure.filter((entry) => !kept.includes(entry));
|
|
3540
|
+
}
|
|
3541
|
+
function apply_list_patch(existing, patch) {
|
|
3542
|
+
const kept = apply_remove(existing, patch.remove);
|
|
3543
|
+
const additions = collect_additions(kept, patch.ensure);
|
|
3544
|
+
const is_changed = additions.length > 0 || kept.length !== existing.length;
|
|
3545
|
+
return { next: [...additions, ...kept], is_changed };
|
|
3546
|
+
}
|
|
3547
|
+
var list_patch = {
|
|
3548
|
+
is_matching,
|
|
3549
|
+
apply_list_patch
|
|
3550
|
+
};
|
|
3551
|
+
|
|
3552
|
+
// scripts/config-merge/parse-jsonc.ts
|
|
3553
|
+
import { parseTree, printParseErrorCode } from "jsonc-parser";
|
|
3554
|
+
function property_key(property) {
|
|
3555
|
+
return String(property.children?.[0]?.value);
|
|
3556
|
+
}
|
|
3557
|
+
function node_value(node) {
|
|
3558
|
+
if (node === void 0) return void 0;
|
|
3559
|
+
const children = node.children ?? [];
|
|
3560
|
+
if (node.type === "array") return children.map((child) => node_value(child));
|
|
3561
|
+
if (node.type !== "object") return node.value;
|
|
3562
|
+
return Object.fromEntries(
|
|
3563
|
+
children.map((property) => [property_key(property), node_value(property.children?.[1])])
|
|
3564
|
+
);
|
|
3565
|
+
}
|
|
3566
|
+
function parse_jsonc(content) {
|
|
3567
|
+
const errors = [];
|
|
3568
|
+
const tree = parseTree(content, errors, { allowTrailingComma: true });
|
|
3569
|
+
const [first_error] = errors;
|
|
3570
|
+
if (first_error !== void 0) {
|
|
3571
|
+
throw new SyntaxError(
|
|
3572
|
+
`Invalid JSONC: ${printParseErrorCode(first_error.error)} at offset ${String(first_error.offset)}`
|
|
3573
|
+
);
|
|
3574
|
+
}
|
|
3575
|
+
return json_object_schema.parse(node_value(tree));
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
// scripts/config-merge/patch-json-key.ts
|
|
3579
|
+
import {
|
|
3580
|
+
createScanner,
|
|
3581
|
+
findNodeAtLocation,
|
|
3582
|
+
getNodeValue,
|
|
3583
|
+
parseTree as parseTree2,
|
|
3584
|
+
stripComments
|
|
3585
|
+
} from "jsonc-parser";
|
|
3586
|
+
var DOCUMENT_SUFFIX = "\n}\n";
|
|
3587
|
+
var DEFAULT_INDENT = " ";
|
|
3588
|
+
var LEADING_BLANKS = /^[\t ]*/u;
|
|
3589
|
+
var PREVIOUS_LINE_OFFSET = 2;
|
|
3590
|
+
var CRLF = "\r\n";
|
|
3591
|
+
var COMMA_PROBE_VALUE = 0;
|
|
3592
|
+
function render_value(key, value, has_trailing_comma) {
|
|
3593
|
+
const probe_key = `${key} `;
|
|
3594
|
+
const probe = has_trailing_comma ? { [key]: value, [probe_key]: COMMA_PROBE_VALUE } : { [key]: value };
|
|
3595
|
+
const document = json_format.format_json(probe);
|
|
3596
|
+
const prefix = `{
|
|
3597
|
+
${JSON.stringify(key)}: `;
|
|
3598
|
+
const suffix = has_trailing_comma ? `,
|
|
3599
|
+
${JSON.stringify(probe_key)}: ${String(COMMA_PROBE_VALUE)}${DOCUMENT_SUFFIX}` : DOCUMENT_SUFFIX;
|
|
3600
|
+
return document.slice(prefix.length, document.length - suffix.length);
|
|
3601
|
+
}
|
|
3602
|
+
function parse_root(content) {
|
|
3603
|
+
const root = parseTree2(content);
|
|
3604
|
+
return root?.type === "object" ? root : void 0;
|
|
3605
|
+
}
|
|
3606
|
+
function replace_range(content, range, text) {
|
|
3607
|
+
return content.slice(0, range.offset) + text + content.slice(range.offset + range.length);
|
|
3608
|
+
}
|
|
3609
|
+
function insert_at(content, offset, text) {
|
|
3610
|
+
return replace_range(content, { offset, length: 0 }, text);
|
|
3611
|
+
}
|
|
3612
|
+
function render_indent(value_text, unit) {
|
|
3613
|
+
if (unit === DEFAULT_INDENT || unit.length === 0) return value_text;
|
|
3614
|
+
return value_text.replaceAll(/^\t+/gmu, (tabs) => unit.repeat(tabs.length));
|
|
3615
|
+
}
|
|
3616
|
+
function eol_of(content) {
|
|
3617
|
+
return content.includes(CRLF) ? CRLF : "\n";
|
|
3618
|
+
}
|
|
3619
|
+
function fit_value(content, value_text, indent) {
|
|
3620
|
+
const indented = render_indent(value_text, indent);
|
|
3621
|
+
if (eol_of(content) === "\n") return indented;
|
|
3622
|
+
return indented.split("\n").join(CRLF);
|
|
3623
|
+
}
|
|
3624
|
+
function line_indent(content, offset) {
|
|
3625
|
+
const line_start = content.lastIndexOf("\n", offset - 1) + 1;
|
|
3626
|
+
return LEADING_BLANKS.exec(content.slice(line_start, offset))?.[0] ?? "";
|
|
3627
|
+
}
|
|
3628
|
+
function line_end(content, offset) {
|
|
3629
|
+
const index = content.indexOf("\n", offset);
|
|
3630
|
+
if (index === -1) return content.length;
|
|
3631
|
+
return index > offset && content[index - 1] === "\r" ? index - 1 : index;
|
|
3632
|
+
}
|
|
3633
|
+
function render_property(content, key, value_text, indent) {
|
|
3634
|
+
return `${JSON.stringify(key)}: ${fit_value(content, value_text, indent)}`;
|
|
3635
|
+
}
|
|
3636
|
+
function insertion_offset(content, root, value_end) {
|
|
3637
|
+
return Math.min(line_end(content, value_end), root.offset + root.length - 1);
|
|
3638
|
+
}
|
|
3639
|
+
function separator_offset(content, offset, limit) {
|
|
3640
|
+
const scanner = createScanner(content, true);
|
|
3641
|
+
scanner.setPosition(offset);
|
|
3642
|
+
scanner.scan();
|
|
3643
|
+
const at = scanner.getTokenOffset();
|
|
3644
|
+
return at < limit && content[at] === "," ? at : -1;
|
|
3645
|
+
}
|
|
3646
|
+
function has_separator_after(content, offset, limit) {
|
|
3647
|
+
return separator_offset(content, offset, limit) !== -1;
|
|
3648
|
+
}
|
|
3649
|
+
function property_key2(property) {
|
|
3650
|
+
const key = property.children?.[0]?.value;
|
|
3651
|
+
return typeof key === "string" ? key : void 0;
|
|
3652
|
+
}
|
|
3653
|
+
function target_value_end(property) {
|
|
3654
|
+
const value_node = property?.children?.[1];
|
|
3655
|
+
return value_node === void 0 ? void 0 : value_node.offset + value_node.length;
|
|
3656
|
+
}
|
|
3657
|
+
function contains_comment(content, node) {
|
|
3658
|
+
const text = content.slice(node.offset, node.offset + node.length);
|
|
3659
|
+
return stripComments(text) !== text;
|
|
3660
|
+
}
|
|
3661
|
+
function rebalanced_value(content, key, value_node, has_trailing_comma) {
|
|
3662
|
+
if (contains_comment(content, value_node)) return void 0;
|
|
3663
|
+
const indent = line_indent(content, value_node.offset);
|
|
3664
|
+
const rendered = fit_value(
|
|
3665
|
+
content,
|
|
3666
|
+
render_value(key, getNodeValue(value_node), has_trailing_comma),
|
|
3667
|
+
indent
|
|
3668
|
+
);
|
|
3669
|
+
const current = content.slice(value_node.offset, value_node.offset + value_node.length);
|
|
3670
|
+
return rendered === current ? void 0 : rendered;
|
|
3671
|
+
}
|
|
3672
|
+
function rebalance(content, property, has_trailing_comma) {
|
|
3673
|
+
const key = property_key2(property);
|
|
3674
|
+
const value_node = property.children?.[1];
|
|
3675
|
+
if (key === void 0 || value_node === void 0) return content;
|
|
3676
|
+
const rendered = rebalanced_value(content, key, value_node, has_trailing_comma);
|
|
3677
|
+
return rendered === void 0 ? content : replace_range(content, value_node, rendered);
|
|
3678
|
+
}
|
|
3679
|
+
function append_after(content, root, last, property) {
|
|
3680
|
+
const value_end = last.offset + last.length;
|
|
3681
|
+
const closing_brace = root.offset + root.length - 1;
|
|
3682
|
+
const separator = has_separator_after(content, value_end, closing_brace) ? "" : ",";
|
|
3683
|
+
const with_property = insert_at(content, insertion_offset(content, root, value_end), property);
|
|
3684
|
+
return insert_at(with_property, value_end, separator);
|
|
3685
|
+
}
|
|
3686
|
+
function insert_only_property(content, root, property) {
|
|
3687
|
+
const closing_brace = root.offset + root.length - 1;
|
|
3688
|
+
const lead = content[closing_brace - 1] === "\n" ? "" : eol_of(content);
|
|
3689
|
+
return insert_at(content, closing_brace, `${lead}${DEFAULT_INDENT}${property}${eol_of(content)}`);
|
|
3690
|
+
}
|
|
3691
|
+
function insert_property(content, root, key, value_text) {
|
|
3692
|
+
const last = root.children?.at(-1);
|
|
3693
|
+
if (last === void 0) {
|
|
3694
|
+
const only = render_property(content, key, value_text, DEFAULT_INDENT);
|
|
3695
|
+
return insert_only_property(content, root, only);
|
|
3696
|
+
}
|
|
3697
|
+
const indent = line_indent(content, last.offset);
|
|
3698
|
+
const property = `${eol_of(content)}${indent}${render_property(content, key, value_text, indent)}`;
|
|
3699
|
+
return rebalance(append_after(content, root, last, property), last, true);
|
|
3700
|
+
}
|
|
3701
|
+
function end_of_trailing_comment(content, end) {
|
|
3702
|
+
const stop = line_end(content, end);
|
|
3703
|
+
return content.slice(end, stop).trimStart().startsWith("//") ? stop : end;
|
|
3704
|
+
}
|
|
3705
|
+
function start_of_leading_comments(content, line_start, floor) {
|
|
3706
|
+
let start = line_start;
|
|
3707
|
+
while (start > floor) {
|
|
3708
|
+
const previous = content.lastIndexOf("\n", start - PREVIOUS_LINE_OFFSET) + 1;
|
|
3709
|
+
const is_comment_line = content.slice(previous, start).trimStart().startsWith("//");
|
|
3710
|
+
if (!is_comment_line || previous < floor) return start;
|
|
3711
|
+
start = previous;
|
|
3712
|
+
}
|
|
3713
|
+
return start;
|
|
3714
|
+
}
|
|
3715
|
+
function end_of_line_break(content, offset) {
|
|
3716
|
+
if (content[offset] === "\r" && content[offset + 1] === "\n") return offset + PREVIOUS_LINE_OFFSET;
|
|
3717
|
+
return content[offset] === "\n" ? offset + 1 : offset;
|
|
3718
|
+
}
|
|
3719
|
+
function body_range(content, root, target, separator_limit) {
|
|
3720
|
+
const value_end = target.offset + target.length;
|
|
3721
|
+
const comma = separator_limit === -1 ? -1 : separator_offset(content, value_end, separator_limit);
|
|
3722
|
+
const end = end_of_trailing_comment(content, comma === -1 ? value_end : comma + 1);
|
|
3723
|
+
const line_start = content.lastIndexOf("\n", target.offset - 1) + 1;
|
|
3724
|
+
const is_own_line = content.slice(line_start, target.offset).trim().length === 0;
|
|
3725
|
+
if (!is_own_line) return { offset: target.offset, length: end - target.offset };
|
|
3726
|
+
const start = start_of_leading_comments(content, line_start, root.offset + 1);
|
|
3727
|
+
return { offset: start, length: end_of_line_break(content, end) - start };
|
|
3728
|
+
}
|
|
3729
|
+
function ranges_for_last_property(content, root, previous, target) {
|
|
3730
|
+
const comma = separator_offset(content, previous.offset + previous.length, target.offset);
|
|
3731
|
+
const body = body_range(content, root, target, -1);
|
|
3732
|
+
return comma === -1 ? [body] : [{ offset: comma, length: 1 }, body];
|
|
3733
|
+
}
|
|
3734
|
+
function removal_ranges(content, root, index) {
|
|
3735
|
+
const children = root.children ?? [];
|
|
3736
|
+
const target = children[index];
|
|
3737
|
+
if (target === void 0) return [];
|
|
3738
|
+
const next = children[index + 1];
|
|
3739
|
+
if (next !== void 0) return [body_range(content, root, target, next.offset)];
|
|
3740
|
+
const previous = children[index - 1];
|
|
3741
|
+
if (previous === void 0) return [{ offset: root.offset, length: root.length }];
|
|
3742
|
+
return ranges_for_last_property(content, root, previous, target);
|
|
3743
|
+
}
|
|
3744
|
+
function property_index(root, key) {
|
|
3745
|
+
return (root.children ?? []).findIndex((child) => child.children?.[0]?.value === key);
|
|
3746
|
+
}
|
|
3747
|
+
function with_trailing_newline(content) {
|
|
3748
|
+
return content.endsWith("\n") ? content : `${content}
|
|
3749
|
+
`;
|
|
3750
|
+
}
|
|
3751
|
+
function is_followed_by_comma(content, root, key) {
|
|
3752
|
+
const children = root.children ?? [];
|
|
3753
|
+
const index = property_index(root, key);
|
|
3754
|
+
if (index < 0) return false;
|
|
3755
|
+
if (index < children.length - 1) return true;
|
|
3756
|
+
const value_end = target_value_end(children[index]);
|
|
3757
|
+
return value_end !== void 0 && has_separator_after(content, value_end, root.offset + root.length);
|
|
3758
|
+
}
|
|
3759
|
+
function set_json_key(content, key, value) {
|
|
3760
|
+
const root = parse_root(content);
|
|
3761
|
+
if (root === void 0) return content;
|
|
3762
|
+
const existing = findNodeAtLocation(root, [key]);
|
|
3763
|
+
const value_text = render_value(
|
|
3764
|
+
key,
|
|
3765
|
+
value,
|
|
3766
|
+
existing !== void 0 && is_followed_by_comma(content, root, key)
|
|
3767
|
+
);
|
|
3768
|
+
if (existing === void 0) {
|
|
3769
|
+
return with_trailing_newline(insert_property(content, root, key, value_text));
|
|
3770
|
+
}
|
|
3771
|
+
const indented = fit_value(content, value_text, line_indent(content, existing.offset));
|
|
3772
|
+
return with_trailing_newline(replace_range(content, existing, indented));
|
|
3773
|
+
}
|
|
3774
|
+
function resolve_parent(content, path16) {
|
|
3775
|
+
const root = parse_root(content);
|
|
3776
|
+
if (root === void 0) return void 0;
|
|
3777
|
+
const parent = path16.length > 1 ? findNodeAtLocation(root, path16.slice(0, -1)) : root;
|
|
3778
|
+
return parent?.type === "object" ? parent : void 0;
|
|
3779
|
+
}
|
|
3780
|
+
function cut_ranges(content, parent, ranges) {
|
|
3781
|
+
const ordered = ranges.toSorted((left, right) => right.offset - left.offset);
|
|
3782
|
+
let next = content;
|
|
3783
|
+
for (const range of ordered) {
|
|
3784
|
+
next = replace_range(next, range, range.offset === parent.offset ? "{}" : "");
|
|
3785
|
+
}
|
|
3786
|
+
return next;
|
|
3787
|
+
}
|
|
3788
|
+
function rebalance_new_last(content, path16) {
|
|
3789
|
+
const parent = resolve_parent(content, path16);
|
|
3790
|
+
const last = parent?.children?.at(-1);
|
|
3791
|
+
if (parent === void 0 || last === void 0) return content;
|
|
3792
|
+
return rebalance(content, last, has_separator_after(content, parent.offset, parent.offset));
|
|
3793
|
+
}
|
|
3794
|
+
function cut_property(content, parent, path16) {
|
|
3795
|
+
const index = property_index(parent, path16.at(-1) ?? "");
|
|
3796
|
+
const ranges = removal_ranges(content, parent, index);
|
|
3797
|
+
if (ranges.length === 0) return content;
|
|
3798
|
+
const cut = cut_ranges(content, parent, ranges);
|
|
3799
|
+
const did_end_object = index === (parent.children ?? []).length - 1;
|
|
3800
|
+
return did_end_object ? rebalance_new_last(cut, path16) : cut;
|
|
3801
|
+
}
|
|
3802
|
+
function remove_json_path(content, path16) {
|
|
3803
|
+
const parent = resolve_parent(content, path16);
|
|
3804
|
+
if (parent === void 0) return content;
|
|
3805
|
+
const next = cut_property(content, parent, path16);
|
|
3806
|
+
return next === content ? content : with_trailing_newline(next);
|
|
3807
|
+
}
|
|
3808
|
+
function remove_json_key(content, key) {
|
|
3809
|
+
return remove_json_path(content, [key]);
|
|
3810
|
+
}
|
|
3811
|
+
var patch_json_key = {
|
|
3812
|
+
set_json_key,
|
|
3813
|
+
remove_json_key,
|
|
3814
|
+
remove_json_path,
|
|
3815
|
+
eol_of,
|
|
3816
|
+
fit_value,
|
|
3817
|
+
line_indent
|
|
3818
|
+
};
|
|
3819
|
+
|
|
3820
|
+
// scripts/config-merge/patch-json-list.ts
|
|
3821
|
+
function normalize_list(value) {
|
|
3822
|
+
if (typeof value === "string") return [value];
|
|
3823
|
+
if (Array.isArray(value)) return value.map(String);
|
|
3824
|
+
return [];
|
|
3825
|
+
}
|
|
3826
|
+
function patch_json_list_field(content, options) {
|
|
3827
|
+
const parsed = parse_jsonc(content);
|
|
3828
|
+
const existing = normalize_list(parsed[options.field]);
|
|
3829
|
+
const { next, is_changed } = list_patch.apply_list_patch(existing, options);
|
|
3830
|
+
if (!is_changed) return content;
|
|
3831
|
+
return patch_json_key.set_json_key(content, options.field, [...next]);
|
|
3832
|
+
}
|
|
3833
|
+
var json_list = {
|
|
3834
|
+
patch_json_list_field
|
|
3835
|
+
};
|
|
3836
|
+
|
|
3837
|
+
// scripts/config-merge/patch-yaml-list.ts
|
|
3838
|
+
import { dump as dump2 } from "js-yaml";
|
|
3839
|
+
var { parse_yaml: parse_yaml2 } = yaml_document;
|
|
3840
|
+
function read_yaml_list_field(content, field) {
|
|
3841
|
+
const raw = parse_yaml2(content)[field];
|
|
3842
|
+
if (typeof raw === "string") return [raw];
|
|
3843
|
+
return Array.isArray(raw) ? string_array_schema.parse(raw) : [];
|
|
3844
|
+
}
|
|
3845
|
+
function replace_field(parsed, field, value) {
|
|
3846
|
+
return Object.fromEntries(
|
|
3847
|
+
Object.entries(parsed).map(([key, entry]) => [key, key === field ? [...value] : entry])
|
|
3848
|
+
);
|
|
3849
|
+
}
|
|
3850
|
+
function insert_after(parsed, field, value, anchor) {
|
|
3851
|
+
const entries = Object.entries(parsed);
|
|
3852
|
+
const index = entries.findIndex(([key]) => key === anchor);
|
|
3853
|
+
if (index === -1) return { ...parsed, [field]: [...value] };
|
|
3854
|
+
return Object.fromEntries([
|
|
3855
|
+
...entries.slice(0, index + 1),
|
|
3856
|
+
[field, [...value]],
|
|
3857
|
+
...entries.slice(index + 1)
|
|
3858
|
+
]);
|
|
3859
|
+
}
|
|
3860
|
+
function insert_new_field(parsed, field, value, position) {
|
|
3861
|
+
if (position === "front") return { [field]: [...value], ...parsed };
|
|
3862
|
+
if (position === "end") return { ...parsed, [field]: [...value] };
|
|
3863
|
+
return insert_after(parsed, field, value, position.after);
|
|
3864
|
+
}
|
|
3865
|
+
function place_field(parsed, field, value, position) {
|
|
3866
|
+
if (Object.hasOwn(parsed, field)) return replace_field(parsed, field, value);
|
|
3867
|
+
return insert_new_field(parsed, field, value, position);
|
|
3868
|
+
}
|
|
3869
|
+
function patch_yaml_list_field(content, options) {
|
|
3870
|
+
const parsed = parse_yaml2(content);
|
|
3871
|
+
const existing = read_yaml_list_field(content, options.field);
|
|
3872
|
+
const { next, is_changed } = list_patch.apply_list_patch(existing, options);
|
|
3873
|
+
if (!is_changed) return content;
|
|
3874
|
+
const placed = place_field(parsed, options.field, next, options.position ?? "front");
|
|
3875
|
+
return dump2(placed, options.quote_style === void 0 ? {} : { quoteStyle: options.quote_style });
|
|
3876
|
+
}
|
|
3877
|
+
var yaml_list = {
|
|
3878
|
+
patch_yaml_list_field,
|
|
3879
|
+
read_yaml_list_field
|
|
3880
|
+
};
|
|
3881
|
+
|
|
3882
|
+
// scripts/config-merge/index.ts
|
|
3883
|
+
var config_merge = {
|
|
3884
|
+
patch_yaml_list_field: yaml_list.patch_yaml_list_field,
|
|
3885
|
+
read_yaml_list_field: yaml_list.read_yaml_list_field,
|
|
3886
|
+
patch_json_list_field: json_list.patch_json_list_field
|
|
3887
|
+
};
|
|
3888
|
+
|
|
3889
|
+
// scripts/init/init-logic-migrate.ts
|
|
3890
|
+
var PREINSTALL_KEY = "preinstall";
|
|
3891
|
+
var JF_PREFIX = "jf-";
|
|
3892
|
+
var JOSH_PREFIX = "josh ";
|
|
3893
|
+
var PRE_JOSH_SCRIPT_VALUES = /* @__PURE__ */ new Map([
|
|
3894
|
+
["lint", "pnpm lint:prettier && pnpm lint:eslint"],
|
|
3895
|
+
["lint:prettier", "prettier --check ."],
|
|
3896
|
+
["lint:eslint", "eslint . --cache --cache-strategy content"],
|
|
3897
|
+
["format", "pnpm format:prettier && pnpm format:eslint"],
|
|
3898
|
+
["format:prettier", "prettier --write ."],
|
|
3899
|
+
["format:eslint", "eslint . --fix --cache --cache-strategy content"],
|
|
3900
|
+
["cspell", 'cspell lint --no-must-find-files --no-progress "**/*.{ts,js,md,yaml,yml,json}"'],
|
|
3901
|
+
["cspell:dot", "pnpm cspell . --dot"],
|
|
3902
|
+
["test:unit", "vitest run"],
|
|
3903
|
+
["lefthook:install", "lefthook install"],
|
|
3904
|
+
["lefthook:uninstall", "lefthook uninstall"],
|
|
3905
|
+
["lefthook:commit", "lefthook run pre-commit"],
|
|
3906
|
+
["lefthook:push", "lefthook run pre-push"],
|
|
3907
|
+
["main:sync", "git checkout main && git pull"],
|
|
3908
|
+
["main:merge", "git pull origin main"],
|
|
3909
|
+
["check:ci", "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --threshold error"]
|
|
3910
|
+
]);
|
|
3911
|
+
var RETIRED_MANAGED_SCRIPTS = /* @__PURE__ */ new Set([
|
|
3912
|
+
"git",
|
|
3913
|
+
"git:followup",
|
|
3914
|
+
"telegram:test",
|
|
3915
|
+
"audit:security",
|
|
3916
|
+
"prep",
|
|
3917
|
+
"issue:prep",
|
|
3918
|
+
"prevent-main-commit",
|
|
3919
|
+
"check-commit-message",
|
|
3920
|
+
"version:major",
|
|
3921
|
+
"version:minor",
|
|
3922
|
+
"version:patch",
|
|
3923
|
+
"version:current",
|
|
3924
|
+
"overrides:check",
|
|
3925
|
+
"test:e2e",
|
|
3926
|
+
"test",
|
|
3927
|
+
"latest",
|
|
3928
|
+
"latest:corepack",
|
|
3929
|
+
"latest:update",
|
|
3930
|
+
"check",
|
|
3931
|
+
"check:svelte",
|
|
3932
|
+
"check:svelte:ci",
|
|
3933
|
+
...PRE_JOSH_SCRIPT_VALUES.keys()
|
|
3934
|
+
]);
|
|
3935
|
+
function migrate_jf_value(value) {
|
|
3936
|
+
if (!value.startsWith(JF_PREFIX)) return value;
|
|
3937
|
+
return `${JOSH_PREFIX}${value.slice(JF_PREFIX.length)}`;
|
|
3938
|
+
}
|
|
3939
|
+
function migrate_script(key, value) {
|
|
3940
|
+
const migrated = migrate_jf_value(value);
|
|
3941
|
+
return key === PREINSTALL_KEY ? safe_chain_preinstall.migrate_preinstall(migrated) : migrated;
|
|
3942
|
+
}
|
|
3943
|
+
function apply_jf_migrations(scripts) {
|
|
3944
|
+
return Object.fromEntries(
|
|
3945
|
+
Object.entries(scripts).map(([key, value]) => [key, migrate_script(key, value)])
|
|
3946
|
+
);
|
|
3947
|
+
}
|
|
3948
|
+
function is_kit_written(key, value) {
|
|
3949
|
+
if (value.startsWith(JOSH_PREFIX) || value.startsWith(JF_PREFIX)) return true;
|
|
3950
|
+
return PRE_JOSH_SCRIPT_VALUES.get(key) === value;
|
|
3951
|
+
}
|
|
3952
|
+
function is_retired_script(key, value) {
|
|
3953
|
+
return RETIRED_MANAGED_SCRIPTS.has(key) && is_kit_written(key, value);
|
|
3954
|
+
}
|
|
3955
|
+
function remove_retired_scripts(scripts) {
|
|
3956
|
+
return Object.fromEntries(
|
|
3957
|
+
Object.entries(scripts).filter(([key, value]) => !is_retired_script(key, value))
|
|
3958
|
+
);
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
// scripts/init/init-logic-package-key-order.ts
|
|
3962
|
+
var PACKAGE_JSON_KEY_ORDER = [
|
|
3963
|
+
"name",
|
|
3964
|
+
"version",
|
|
3965
|
+
"description",
|
|
3966
|
+
"keywords",
|
|
3967
|
+
"homepage",
|
|
3968
|
+
"bugs",
|
|
3969
|
+
"license",
|
|
3970
|
+
"author",
|
|
3971
|
+
"contributors",
|
|
3972
|
+
"funding",
|
|
3973
|
+
"files",
|
|
3974
|
+
"main",
|
|
3975
|
+
"browser",
|
|
3976
|
+
"exports",
|
|
3977
|
+
"imports",
|
|
3978
|
+
"bin",
|
|
3979
|
+
"man",
|
|
3980
|
+
"directories",
|
|
3981
|
+
"repository",
|
|
3982
|
+
"type",
|
|
3983
|
+
"types",
|
|
3984
|
+
"typings",
|
|
3985
|
+
"typesVersions",
|
|
3986
|
+
"publishConfig",
|
|
3987
|
+
"private",
|
|
3988
|
+
"scripts",
|
|
3989
|
+
"config",
|
|
3990
|
+
"dependencies",
|
|
3991
|
+
"devDependencies",
|
|
3992
|
+
"peerDependencies",
|
|
3993
|
+
"peerDependenciesMeta",
|
|
3994
|
+
"bundleDependencies",
|
|
3995
|
+
"bundledDependencies",
|
|
3996
|
+
"optionalDependencies",
|
|
3997
|
+
"overrides",
|
|
3998
|
+
"resolutions",
|
|
3999
|
+
"packageManager",
|
|
4000
|
+
"engines",
|
|
4001
|
+
"devEngines",
|
|
4002
|
+
"os",
|
|
4003
|
+
"cpu",
|
|
4004
|
+
"size-limit",
|
|
4005
|
+
"pnpm"
|
|
4006
|
+
];
|
|
4007
|
+
|
|
4008
|
+
// scripts/init/kit-base-preset.ts
|
|
4009
|
+
var KIT_LEFTHOOK_PRESET = /@joshuafolkken\/[^/]+\/lefthook\//u;
|
|
4010
|
+
var KIT_CSPELL_PRESET = /@joshuafolkken\/[^/]+\/cspell(?:\/|$)/u;
|
|
4011
|
+
var KIT_TSCONFIG_PRESET = /@joshuafolkken\/[^/]+\/tsconfig\//u;
|
|
4012
|
+
var SVELTEKIT_PRESET = /(?<![\w-])sveltekit(?![\w-])/u;
|
|
4013
|
+
function has_match(entries, pattern) {
|
|
4014
|
+
return entries.some((entry) => pattern.test(entry));
|
|
4015
|
+
}
|
|
4016
|
+
function is_base_present(entries, subsystem_pattern) {
|
|
4017
|
+
return has_match(entries, subsystem_pattern) || has_match(entries, SVELTEKIT_PRESET);
|
|
4018
|
+
}
|
|
4019
|
+
function is_lefthook_base_present(entries) {
|
|
4020
|
+
return is_base_present(entries, KIT_LEFTHOOK_PRESET);
|
|
4021
|
+
}
|
|
4022
|
+
function is_cspell_base_present(entries) {
|
|
4023
|
+
return is_base_present(entries, KIT_CSPELL_PRESET);
|
|
4024
|
+
}
|
|
4025
|
+
function is_tsconfig_base_present(entries) {
|
|
4026
|
+
return is_base_present(entries, KIT_TSCONFIG_PRESET);
|
|
4027
|
+
}
|
|
4028
|
+
var kit_base_preset = {
|
|
4029
|
+
is_lefthook_base_present,
|
|
4030
|
+
is_cspell_base_present,
|
|
4031
|
+
is_tsconfig_base_present
|
|
4032
|
+
};
|
|
4033
|
+
|
|
4034
|
+
// scripts/init/tsconfig-preset-migration.ts
|
|
4035
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
2842
4036
|
import path7 from "node:path";
|
|
4037
|
+
var LEGACY_PRESET_ENTRY = /@joshuafolkken\/[^/]+\/tsconfig\/[^/]+\.jsonc$/u;
|
|
4038
|
+
var LEGACY_SUFFIX = ".jsonc";
|
|
4039
|
+
var CURRENT_SUFFIX = ".json";
|
|
4040
|
+
var EXTENDS_FIELD = "extends";
|
|
4041
|
+
function is_migration_target_present(base_directory, entry) {
|
|
4042
|
+
return existsSync4(path7.resolve(base_directory, entry));
|
|
4043
|
+
}
|
|
4044
|
+
function migrate_entry(base_directory, entry) {
|
|
4045
|
+
if (!LEGACY_PRESET_ENTRY.test(entry)) return entry;
|
|
4046
|
+
const migrated = `${entry.slice(0, -LEGACY_SUFFIX.length)}${CURRENT_SUFFIX}`;
|
|
4047
|
+
return is_migration_target_present(base_directory, migrated) ? migrated : entry;
|
|
4048
|
+
}
|
|
4049
|
+
function migrate_extends_value(base_directory, raw) {
|
|
4050
|
+
if (typeof raw === "string") return migrate_entry(base_directory, raw);
|
|
4051
|
+
if (Array.isArray(raw)) {
|
|
4052
|
+
return string_array_schema.parse(raw).map((entry) => migrate_entry(base_directory, entry));
|
|
4053
|
+
}
|
|
4054
|
+
return raw;
|
|
4055
|
+
}
|
|
4056
|
+
function migrate_preset_paths(content, base_directory) {
|
|
4057
|
+
const parsed = parse_jsonc(content);
|
|
4058
|
+
const raw = parsed[EXTENDS_FIELD];
|
|
4059
|
+
const migrated = migrate_extends_value(base_directory, raw);
|
|
4060
|
+
if (JSON.stringify(migrated) === JSON.stringify(raw)) return content;
|
|
4061
|
+
return patch_json_key.set_json_key(content, EXTENDS_FIELD, migrated);
|
|
4062
|
+
}
|
|
4063
|
+
var tsconfig_preset_migration = {
|
|
4064
|
+
migrate_preset_paths
|
|
4065
|
+
};
|
|
4066
|
+
|
|
4067
|
+
// scripts/init/init-logic-json-merge.ts
|
|
4068
|
+
function merge_json_extends(content, entry) {
|
|
4069
|
+
return config_merge.patch_json_list_field(content, { field: EXTENDS_FIELD, ensure: [entry] });
|
|
4070
|
+
}
|
|
4071
|
+
function read_extends_entries(content) {
|
|
4072
|
+
const raw = parse_jsonc(content)[EXTENDS_FIELD];
|
|
4073
|
+
if (typeof raw === "string") return [raw];
|
|
4074
|
+
if (Array.isArray(raw)) return string_array_schema.parse(raw);
|
|
4075
|
+
return [];
|
|
4076
|
+
}
|
|
4077
|
+
function merge_tsconfig_extends(content, entry, base_directory) {
|
|
4078
|
+
const migrated = tsconfig_preset_migration.migrate_preset_paths(content, base_directory);
|
|
4079
|
+
if (kit_base_preset.is_tsconfig_base_present(read_extends_entries(migrated))) return migrated;
|
|
4080
|
+
return merge_json_extends(migrated, entry);
|
|
4081
|
+
}
|
|
4082
|
+
function extract_compiler_options(content) {
|
|
4083
|
+
const parsed = parse_jsonc(content);
|
|
4084
|
+
const raw = parsed["compilerOptions"];
|
|
4085
|
+
if (raw === void 0) return {};
|
|
4086
|
+
return json_object_schema.parse(raw);
|
|
4087
|
+
}
|
|
4088
|
+
function is_redundant_option(value, key, base_options) {
|
|
4089
|
+
if (!Object.hasOwn(base_options, key)) return false;
|
|
4090
|
+
return JSON.stringify(base_options[key]) === JSON.stringify(value);
|
|
4091
|
+
}
|
|
4092
|
+
var COMPILER_OPTIONS_FIELD = "compilerOptions";
|
|
4093
|
+
function drop_redundant_options(content, redundant) {
|
|
4094
|
+
let current = content;
|
|
4095
|
+
for (const key of redundant) {
|
|
4096
|
+
current = patch_json_key.remove_json_path(current, [COMPILER_OPTIONS_FIELD, key]);
|
|
4097
|
+
}
|
|
4098
|
+
return current;
|
|
4099
|
+
}
|
|
4100
|
+
function serialize_stripped(content, kept, redundant) {
|
|
4101
|
+
if (Object.keys(kept).length === 0) {
|
|
4102
|
+
return patch_json_key.remove_json_key(content, COMPILER_OPTIONS_FIELD);
|
|
4103
|
+
}
|
|
4104
|
+
return drop_redundant_options(content, redundant);
|
|
4105
|
+
}
|
|
4106
|
+
function redundant_option_keys(current, base_options) {
|
|
4107
|
+
return Object.entries(current).filter(([key, value]) => is_redundant_option(value, key, base_options)).map(([key]) => key);
|
|
4108
|
+
}
|
|
4109
|
+
function strip_redundant_compiler_options(content, base_options) {
|
|
4110
|
+
const raw = parse_jsonc(content)[COMPILER_OPTIONS_FIELD];
|
|
4111
|
+
if (raw === void 0) return content;
|
|
4112
|
+
const current = json_object_schema.parse(raw);
|
|
4113
|
+
const redundant = redundant_option_keys(current, base_options);
|
|
4114
|
+
if (redundant.length === 0) return content;
|
|
4115
|
+
const kept = Object.entries(current).filter(([key]) => !redundant.includes(key));
|
|
4116
|
+
return serialize_stripped(content, Object.fromEntries(kept), redundant);
|
|
4117
|
+
}
|
|
4118
|
+
function merge_json_array_field(content, key, values) {
|
|
4119
|
+
const parsed = parse_jsonc(content);
|
|
4120
|
+
const existing = Object.hasOwn(parsed, key) ? string_array_schema.parse(parsed[key]) : [];
|
|
4121
|
+
const to_add = values.filter((value) => !existing.includes(value));
|
|
4122
|
+
if (to_add.length === 0) return content;
|
|
4123
|
+
return patch_json_key.set_json_key(content, key, [...existing, ...to_add]);
|
|
4124
|
+
}
|
|
4125
|
+
function missing_entries(existing, additions) {
|
|
4126
|
+
return Object.entries(additions).filter(([key]) => !Object.hasOwn(existing, key));
|
|
4127
|
+
}
|
|
4128
|
+
function merge_owned_entries(current, update) {
|
|
4129
|
+
const current_object = json_object_schema.safeParse(current);
|
|
4130
|
+
const update_object = json_object_schema.safeParse(update);
|
|
4131
|
+
if (!current_object.success || !update_object.success) return void 0;
|
|
4132
|
+
const owned = current_object.data;
|
|
4133
|
+
const missing = missing_entries(owned, update_object.data);
|
|
4134
|
+
if (missing.length === 0) return void 0;
|
|
4135
|
+
return { ...owned, ...Object.fromEntries(missing) };
|
|
4136
|
+
}
|
|
4137
|
+
function collect_applicable_updates(parsed, updates) {
|
|
4138
|
+
const resolved = Object.entries(updates).map(([key, value]) => [
|
|
4139
|
+
key,
|
|
4140
|
+
Object.hasOwn(parsed, key) ? merge_owned_entries(parsed[key], value) : value
|
|
4141
|
+
]);
|
|
4142
|
+
return Object.fromEntries(resolved.filter(([, merged]) => merged !== void 0));
|
|
4143
|
+
}
|
|
4144
|
+
function merge_json_object(content, updates) {
|
|
4145
|
+
const parsed = parse_jsonc(content);
|
|
4146
|
+
const applicable = collect_applicable_updates(parsed, updates);
|
|
4147
|
+
if (Object.keys(applicable).length === 0) return content;
|
|
4148
|
+
let current = content;
|
|
4149
|
+
for (const [key, value] of Object.entries(applicable)) {
|
|
4150
|
+
current = patch_json_key.set_json_key(current, key, value);
|
|
4151
|
+
}
|
|
4152
|
+
return current;
|
|
4153
|
+
}
|
|
4154
|
+
function serialize_package_json(value) {
|
|
4155
|
+
return json_format.format_package_json(value);
|
|
4156
|
+
}
|
|
4157
|
+
var SCRIPTS_PREPEND_KEYS = /* @__PURE__ */ new Set(["preinstall"]);
|
|
4158
|
+
function merge_package_scripts(content, scripts) {
|
|
4159
|
+
const parsed = parse_jsonc(content);
|
|
4160
|
+
const raw = parsed["scripts"];
|
|
4161
|
+
const existing = raw === void 0 ? {} : string_record_schema.parse(raw);
|
|
4162
|
+
const migrated = remove_retired_scripts(apply_jf_migrations(existing));
|
|
4163
|
+
const to_add = missing_entries(migrated, scripts);
|
|
4164
|
+
const did_migrate = JSON.stringify(migrated) !== JSON.stringify(existing);
|
|
4165
|
+
if (!did_migrate && to_add.length === 0) return content;
|
|
4166
|
+
const prepend = Object.fromEntries(to_add.filter(([k]) => SCRIPTS_PREPEND_KEYS.has(k)));
|
|
4167
|
+
const append = Object.fromEntries(to_add.filter(([k]) => !SCRIPTS_PREPEND_KEYS.has(k)));
|
|
4168
|
+
return serialize_package_json({ ...parsed, scripts: { ...prepend, ...migrated, ...append } });
|
|
4169
|
+
}
|
|
4170
|
+
function upgrade_safe_chain_preinstall(content) {
|
|
4171
|
+
const parsed = parse_jsonc(content);
|
|
4172
|
+
const raw = parsed["scripts"];
|
|
4173
|
+
if (raw === void 0) return content;
|
|
4174
|
+
const scripts = string_record_schema.parse(raw);
|
|
4175
|
+
const current = scripts["preinstall"];
|
|
4176
|
+
if (current === void 0) return content;
|
|
4177
|
+
const migrated = safe_chain_preinstall.migrate_preinstall(current);
|
|
4178
|
+
if (migrated === current) return content;
|
|
4179
|
+
return serialize_package_json({ ...parsed, scripts: { ...scripts, preinstall: migrated } });
|
|
4180
|
+
}
|
|
4181
|
+
function merge_development_dependencies(content, additions) {
|
|
4182
|
+
const parsed = parse_jsonc(content);
|
|
4183
|
+
const raw = parsed["devDependencies"];
|
|
4184
|
+
const existing = raw === void 0 ? {} : string_record_schema.parse(raw);
|
|
4185
|
+
const to_add = missing_entries(existing, additions);
|
|
4186
|
+
if (to_add.length === 0) return content;
|
|
4187
|
+
return serialize_package_json({
|
|
4188
|
+
...parsed,
|
|
4189
|
+
devDependencies: { ...existing, ...Object.fromEntries(to_add) }
|
|
4190
|
+
});
|
|
4191
|
+
}
|
|
4192
|
+
function merge_package_manager(content, value) {
|
|
4193
|
+
if (value.length === 0) return content;
|
|
4194
|
+
const parsed = parse_jsonc(content);
|
|
4195
|
+
if ("packageManager" in parsed) return content;
|
|
4196
|
+
return serialize_package_json({ ...parsed, packageManager: value });
|
|
4197
|
+
}
|
|
4198
|
+
function merge_development_engines(content, value) {
|
|
4199
|
+
const parsed = parse_jsonc(content);
|
|
4200
|
+
if ("devEngines" in parsed) return content;
|
|
4201
|
+
return serialize_package_json({ ...parsed, devEngines: value });
|
|
4202
|
+
}
|
|
4203
|
+
function has_package_scripts_marker(content, marker) {
|
|
4204
|
+
const parsed = parse_jsonc(content);
|
|
4205
|
+
const raw = parsed["scripts"];
|
|
4206
|
+
if (raw === void 0) return false;
|
|
4207
|
+
const scripts = string_record_schema.parse(raw);
|
|
4208
|
+
return Object.values(scripts).some((cmd) => cmd.includes(marker));
|
|
4209
|
+
}
|
|
4210
|
+
function merge_package_script_suffix(content, key, cmd) {
|
|
4211
|
+
const parsed = parse_jsonc(content);
|
|
4212
|
+
const raw = parsed["scripts"];
|
|
4213
|
+
if (raw === void 0) return content;
|
|
4214
|
+
const scripts = string_record_schema.parse(raw);
|
|
4215
|
+
const existing = scripts[key];
|
|
4216
|
+
if (existing === void 0 || existing.includes(cmd)) return content;
|
|
4217
|
+
const updated_value = existing.trim().length === 0 ? cmd : `${existing} && ${cmd}`;
|
|
4218
|
+
return serialize_package_json({ ...parsed, scripts: { ...scripts, [key]: updated_value } });
|
|
4219
|
+
}
|
|
4220
|
+
function replace_in_package_script(content, key, from, to) {
|
|
4221
|
+
const parsed = parse_jsonc(content);
|
|
4222
|
+
const raw = parsed["scripts"];
|
|
4223
|
+
if (raw === void 0) return content;
|
|
4224
|
+
const scripts = string_record_schema.parse(raw);
|
|
4225
|
+
const existing = scripts[key];
|
|
4226
|
+
if (!existing?.includes(from)) return content;
|
|
4227
|
+
return serialize_package_json({
|
|
4228
|
+
...parsed,
|
|
4229
|
+
// The replacer is a function so `to` is inserted verbatim: passed as a string, a `$&` or `$1`
|
|
4230
|
+
// inside it would be read as a substitution pattern rather than as the text it is.
|
|
4231
|
+
scripts: { ...scripts, [key]: existing.replace(from, () => to) }
|
|
4232
|
+
});
|
|
4233
|
+
}
|
|
4234
|
+
function remove_script_with_marker(content, key, marker) {
|
|
4235
|
+
const parsed = parse_jsonc(content);
|
|
4236
|
+
const raw = parsed["scripts"];
|
|
4237
|
+
if (raw === void 0) return content;
|
|
4238
|
+
const scripts = string_record_schema.parse(raw);
|
|
4239
|
+
if (!scripts[key]?.includes(marker)) return content;
|
|
4240
|
+
const rest = Object.fromEntries(Object.entries(scripts).filter(([k]) => k !== key));
|
|
4241
|
+
return serialize_package_json({ ...parsed, scripts: rest });
|
|
4242
|
+
}
|
|
4243
|
+
function sort_package_json_keys(content) {
|
|
4244
|
+
const parsed = parse_jsonc(content);
|
|
4245
|
+
const all_keys = Object.keys(parsed);
|
|
4246
|
+
const known = PACKAGE_JSON_KEY_ORDER.filter((k) => Object.hasOwn(parsed, k));
|
|
4247
|
+
const unknown = all_keys.filter((k) => !PACKAGE_JSON_KEY_ORDER.includes(k));
|
|
4248
|
+
const ordered = Object.fromEntries([...known, ...unknown].map((k) => [k, parsed[k]]));
|
|
4249
|
+
const serialized = serialize_package_json(ordered);
|
|
4250
|
+
const current = serialize_package_json(parsed);
|
|
4251
|
+
if (serialized === current) return content;
|
|
4252
|
+
return serialized;
|
|
4253
|
+
}
|
|
4254
|
+
var init_logic_json_merge = {
|
|
4255
|
+
merge_json_extends,
|
|
4256
|
+
merge_tsconfig_extends,
|
|
4257
|
+
extract_compiler_options,
|
|
4258
|
+
strip_redundant_compiler_options,
|
|
4259
|
+
merge_json_array_field,
|
|
4260
|
+
merge_json_object,
|
|
4261
|
+
merge_package_scripts,
|
|
4262
|
+
upgrade_safe_chain_preinstall,
|
|
4263
|
+
merge_package_script_suffix,
|
|
4264
|
+
replace_in_package_script,
|
|
4265
|
+
remove_script_with_marker,
|
|
4266
|
+
has_package_scripts_marker,
|
|
4267
|
+
merge_development_dependencies,
|
|
4268
|
+
merge_package_manager,
|
|
4269
|
+
merge_development_engines,
|
|
4270
|
+
sort_package_json_keys
|
|
4271
|
+
};
|
|
4272
|
+
|
|
4273
|
+
// scripts/init/kit-development-versions.ts
|
|
4274
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
4275
|
+
import { z as z11 } from "zod";
|
|
4276
|
+
var PACKAGE_JSON = "package.json";
|
|
4277
|
+
var kit_manifest_schema = z11.object({
|
|
4278
|
+
peerDependencies: z11.record(z11.string(), z11.string()).default({}),
|
|
4279
|
+
devDependencies: z11.record(z11.string(), z11.string())
|
|
4280
|
+
});
|
|
4281
|
+
function read_kit_manifest() {
|
|
4282
|
+
const content = readFileSync3(package_path(PACKAGE_JSON), "utf8");
|
|
4283
|
+
return kit_manifest_schema.parse(JSON.parse(content));
|
|
4284
|
+
}
|
|
4285
|
+
function versions_of(names) {
|
|
4286
|
+
const { devDependencies: versions } = read_kit_manifest();
|
|
4287
|
+
const entries = names.map((name) => {
|
|
4288
|
+
const version = versions[name];
|
|
4289
|
+
if (version === void 0) throw new Error(`Missing development version for ${name}`);
|
|
4290
|
+
return [name, version];
|
|
4291
|
+
});
|
|
4292
|
+
return Object.fromEntries(entries);
|
|
4293
|
+
}
|
|
4294
|
+
function peer_names() {
|
|
4295
|
+
return Object.keys(read_kit_manifest().peerDependencies);
|
|
4296
|
+
}
|
|
4297
|
+
var kit_development_versions = { peer_names, versions_of };
|
|
4298
|
+
|
|
4299
|
+
// scripts/init/init-logic-secretlint.ts
|
|
4300
|
+
var SECRETLINT_CONFIG_FILENAME = ".secretlintrc.json";
|
|
4301
|
+
var SECRETLINT_RULE_PRESET = "@secretlint/secretlint-rule-preset-recommend";
|
|
4302
|
+
var SECRETLINT_PACKAGES = ["secretlint", SECRETLINT_RULE_PRESET];
|
|
4303
|
+
function generate_secretlint_config() {
|
|
4304
|
+
const config = { rules: [{ id: SECRETLINT_RULE_PRESET }] };
|
|
4305
|
+
return `${JSON.stringify(config, void 0, " ")}
|
|
4306
|
+
`;
|
|
4307
|
+
}
|
|
4308
|
+
function get_secretlint_config_filename() {
|
|
4309
|
+
return SECRETLINT_CONFIG_FILENAME;
|
|
4310
|
+
}
|
|
4311
|
+
function merge_secretlint_development_deps(content) {
|
|
4312
|
+
return init_logic_json_merge.merge_development_dependencies(
|
|
4313
|
+
content,
|
|
4314
|
+
kit_development_versions.versions_of(SECRETLINT_PACKAGES)
|
|
4315
|
+
);
|
|
4316
|
+
}
|
|
4317
|
+
var init_logic_secretlint = {
|
|
4318
|
+
generate_secretlint_config,
|
|
4319
|
+
get_secretlint_config_filename,
|
|
4320
|
+
merge_secretlint_development_deps
|
|
4321
|
+
};
|
|
4322
|
+
|
|
4323
|
+
// scripts/init/init-logic-sonar.ts
|
|
4324
|
+
var SONAR_PROJECT_KEY_PLACEHOLDER = "{{PROJECT_KEY}}";
|
|
4325
|
+
var SONAR_ORGANIZATION_PLACEHOLDER = "{{ORGANIZATION}}";
|
|
4326
|
+
var SONAR_TEMPLATE_SRC = "templates/sonar-project.properties";
|
|
4327
|
+
var SONAR_TEMPLATE_DEST = "sonar-project.properties";
|
|
4328
|
+
var PROPERTY_LINE_PATTERN = /^([\w.]+)=/u;
|
|
4329
|
+
var MULTICRITERIA_KEY = "sonar.issue.ignore.multicriteria";
|
|
4330
|
+
var MULTICRITERIA_LINE_PATTERN = /^sonar\.issue\.ignore\.multicriteria=(.*)$/mu;
|
|
4331
|
+
function apply_sonar_template(content, project_key, organization) {
|
|
4332
|
+
return content.replaceAll(SONAR_PROJECT_KEY_PLACEHOLDER, () => project_key).replaceAll(SONAR_ORGANIZATION_PLACEHOLDER, () => organization);
|
|
4333
|
+
}
|
|
4334
|
+
function derive_sonar_identifiers(name_with_owner) {
|
|
4335
|
+
const [organization, repository, ...extra] = name_with_owner.trim().split("/");
|
|
4336
|
+
if (!organization || !repository || extra.length > 0) {
|
|
4337
|
+
throw new Error(`Invalid GitHub repository nameWithOwner: ${name_with_owner}`);
|
|
4338
|
+
}
|
|
4339
|
+
return {
|
|
4340
|
+
organization,
|
|
4341
|
+
project_key: `${organization}_${repository}`
|
|
4342
|
+
};
|
|
4343
|
+
}
|
|
4344
|
+
function get_sonar_template_source() {
|
|
4345
|
+
return SONAR_TEMPLATE_SRC;
|
|
4346
|
+
}
|
|
4347
|
+
function get_sonar_template_destination() {
|
|
4348
|
+
return SONAR_TEMPLATE_DEST;
|
|
4349
|
+
}
|
|
4350
|
+
function extract_properties_keys(content) {
|
|
4351
|
+
const keys = /* @__PURE__ */ new Set();
|
|
4352
|
+
for (const line of content.split("\n")) {
|
|
4353
|
+
const match = PROPERTY_LINE_PATTERN.exec(line);
|
|
4354
|
+
if (match?.[1] !== void 0) keys.add(match[1]);
|
|
4355
|
+
}
|
|
4356
|
+
return keys;
|
|
4357
|
+
}
|
|
4358
|
+
function get_multicriteria_value(content) {
|
|
4359
|
+
return MULTICRITERIA_LINE_PATTERN.exec(content)?.[1];
|
|
4360
|
+
}
|
|
4361
|
+
function get_multicriteria_ids(content) {
|
|
4362
|
+
return (get_multicriteria_value(content) ?? "").split(",").map((id) => id.trim()).filter(Boolean);
|
|
4363
|
+
}
|
|
4364
|
+
function get_property_value(content, key) {
|
|
4365
|
+
return content.split("\n").find((line) => line.startsWith(`${key}=`))?.slice(key.length + 1);
|
|
4366
|
+
}
|
|
4367
|
+
function has_criterion_conflict(existing, template, id) {
|
|
4368
|
+
return ["ruleKey", "resourceKey"].some((field) => {
|
|
4369
|
+
const key = `${MULTICRITERIA_KEY}.${id}.${field}`;
|
|
4370
|
+
const existing_value = get_property_value(existing, key);
|
|
4371
|
+
const template_value = get_property_value(template, key);
|
|
4372
|
+
return existing_value !== void 0 && template_value !== void 0 && existing_value !== template_value;
|
|
4373
|
+
});
|
|
4374
|
+
}
|
|
4375
|
+
function criterion_matches(existing, template, existing_id, template_id) {
|
|
4376
|
+
const template_prefix = `${MULTICRITERIA_KEY}.${template_id}`;
|
|
4377
|
+
const existing_prefix = `${MULTICRITERIA_KEY}.${existing_id}`;
|
|
4378
|
+
const rule = get_property_value(template, `${template_prefix}.ruleKey`);
|
|
4379
|
+
const resource = get_property_value(template, `${template_prefix}.resourceKey`);
|
|
4380
|
+
if (rule === void 0 || resource === void 0) return false;
|
|
4381
|
+
return rule === get_property_value(existing, `${existing_prefix}.ruleKey`) && resource === get_property_value(existing, `${existing_prefix}.resourceKey`);
|
|
4382
|
+
}
|
|
4383
|
+
function allocate_criterion_id(used_ids) {
|
|
4384
|
+
let next_index = 1;
|
|
4385
|
+
for (const id of used_ids) {
|
|
4386
|
+
const numeric_id = /^e(\d+)$/u.exec(id)?.[1];
|
|
4387
|
+
if (numeric_id !== void 0) next_index = Math.max(next_index, Number(numeric_id) + 1);
|
|
4388
|
+
}
|
|
4389
|
+
return `e${next_index.toString()}`;
|
|
4390
|
+
}
|
|
4391
|
+
function rename_criterion(template, id, replacement_id) {
|
|
4392
|
+
const ids = get_multicriteria_ids(template).map(
|
|
4393
|
+
(entry) => entry === id ? replacement_id : entry
|
|
4394
|
+
);
|
|
4395
|
+
const updated_list = template.replace(
|
|
4396
|
+
MULTICRITERIA_LINE_PATTERN,
|
|
4397
|
+
() => `${MULTICRITERIA_KEY}=${ids.join(",")}`
|
|
4398
|
+
);
|
|
4399
|
+
return updated_list.replaceAll(
|
|
4400
|
+
`${MULTICRITERIA_KEY}.${id}.`,
|
|
4401
|
+
() => `${MULTICRITERIA_KEY}.${replacement_id}.`
|
|
4402
|
+
);
|
|
4403
|
+
}
|
|
4404
|
+
function find_matching_criterion(existing, template, ids, id) {
|
|
4405
|
+
return ids.find((candidate) => criterion_matches(existing, template, candidate, id));
|
|
4406
|
+
}
|
|
4407
|
+
function resolve_multicriteria_conflicts(existing, template) {
|
|
4408
|
+
const existing_ids = get_multicriteria_ids(existing);
|
|
4409
|
+
const template_ids = get_multicriteria_ids(template);
|
|
4410
|
+
const reusable_ids = existing_ids.filter((id) => !template_ids.includes(id));
|
|
4411
|
+
let resolved = template;
|
|
4412
|
+
for (const id of template_ids) {
|
|
4413
|
+
if (!existing_ids.includes(id) || !has_criterion_conflict(existing, resolved, id)) continue;
|
|
4414
|
+
const matching_id = find_matching_criterion(existing, resolved, reusable_ids, id);
|
|
4415
|
+
const replacement_id = matching_id ?? allocate_criterion_id(/* @__PURE__ */ new Set([...existing_ids, ...get_multicriteria_ids(resolved)]));
|
|
4416
|
+
resolved = rename_criterion(resolved, id, replacement_id);
|
|
4417
|
+
}
|
|
4418
|
+
return resolved;
|
|
4419
|
+
}
|
|
4420
|
+
function merge_multicriteria_ids(existing, template_content) {
|
|
4421
|
+
const existing_value = get_multicriteria_value(existing);
|
|
4422
|
+
if (existing_value === void 0) return existing;
|
|
4423
|
+
const template_value = get_multicriteria_value(template_content);
|
|
4424
|
+
if (template_value === void 0) return existing;
|
|
4425
|
+
const existing_ids = get_multicriteria_ids(existing);
|
|
4426
|
+
const template_ids = get_multicriteria_ids(template_content);
|
|
4427
|
+
const merged_ids = [.../* @__PURE__ */ new Set([...existing_ids, ...template_ids])];
|
|
4428
|
+
if (merged_ids.join(",") === existing_value) return existing;
|
|
4429
|
+
return existing.replace(
|
|
4430
|
+
MULTICRITERIA_LINE_PATTERN,
|
|
4431
|
+
() => `${MULTICRITERIA_KEY}=${merged_ids.join(",")}`
|
|
4432
|
+
);
|
|
4433
|
+
}
|
|
4434
|
+
function merge_sonar_properties(existing, template_content) {
|
|
4435
|
+
const resolved_template = resolve_multicriteria_conflicts(existing, template_content);
|
|
4436
|
+
const merged_existing = merge_multicriteria_ids(existing, resolved_template);
|
|
4437
|
+
const existing_keys = extract_properties_keys(merged_existing);
|
|
4438
|
+
const lines_to_add = resolved_template.split("\n").filter((line) => {
|
|
4439
|
+
const key = PROPERTY_LINE_PATTERN.exec(line)?.[1];
|
|
4440
|
+
return key !== void 0 && !existing_keys.has(key);
|
|
4441
|
+
});
|
|
4442
|
+
if (lines_to_add.length === 0) return merged_existing;
|
|
4443
|
+
const normalized2 = merged_existing.endsWith("\n") ? merged_existing : `${merged_existing}
|
|
4444
|
+
`;
|
|
4445
|
+
return `${normalized2}
|
|
4446
|
+
${lines_to_add.join("\n")}
|
|
4447
|
+
`;
|
|
4448
|
+
}
|
|
4449
|
+
var init_logic_sonar = {
|
|
4450
|
+
apply_sonar_template,
|
|
4451
|
+
derive_sonar_identifiers,
|
|
4452
|
+
get_sonar_template_source,
|
|
4453
|
+
get_sonar_template_destination,
|
|
4454
|
+
merge_sonar_properties
|
|
4455
|
+
};
|
|
4456
|
+
|
|
4457
|
+
// scripts/init/init-logic-templates.ts
|
|
4458
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "node:fs";
|
|
4459
|
+
import path8 from "node:path";
|
|
4460
|
+
var ESLINT_VANILLA = `import { create_vanilla_config } from '@joshuafolkken/kit/eslint/vanilla'
|
|
4461
|
+
|
|
4462
|
+
export default create_vanilla_config({
|
|
4463
|
+
gitignore_path: new URL('./.gitignore', import.meta.url),
|
|
4464
|
+
tsconfig_root_dir: import.meta.dirname,
|
|
4465
|
+
})
|
|
4466
|
+
`;
|
|
4467
|
+
var DEFAULT_TAILWIND_STYLESHEET = "./src/routes/layout.css";
|
|
4468
|
+
var TAILWIND_STYLESHEET_PATTERN = /tailwindStylesheet"?:\s*['"]([^'"]+)['"]/u;
|
|
4469
|
+
var KIT_ESLINT_IMPORT_MARKER = "@joshuafolkken/kit/eslint/";
|
|
4470
|
+
var VANILLA_ESLINT_MARKERS = [
|
|
4471
|
+
"js.configs.recommended",
|
|
4472
|
+
"ts.configs.recommended",
|
|
4473
|
+
"svelte.configs.recommended"
|
|
4474
|
+
];
|
|
4475
|
+
var RULES_BLOCK_PATTERN = /rules\s*:\s*\{/gu;
|
|
4476
|
+
var RULES_INDENT_DEPTH = 3;
|
|
4477
|
+
var RULES_INDENT = " ".repeat(RULES_INDENT_DEPTH);
|
|
4478
|
+
var PLAYWRIGHT_TEMPLATE_PATH = package_path("playwright.config.ts");
|
|
4479
|
+
var VANILLA_WITH_RULES_TPL = `import { create_vanilla_config } from '@joshuafolkken/kit/eslint/vanilla'
|
|
4480
|
+
|
|
4481
|
+
export default [
|
|
4482
|
+
...create_vanilla_config({
|
|
4483
|
+
gitignore_path: new URL('./.gitignore', import.meta.url),
|
|
4484
|
+
tsconfig_root_dir: import.meta.dirname,
|
|
4485
|
+
}),
|
|
4486
|
+
{
|
|
4487
|
+
rules: {
|
|
4488
|
+
$RULES
|
|
4489
|
+
},
|
|
4490
|
+
},
|
|
4491
|
+
]
|
|
4492
|
+
`;
|
|
4493
|
+
var RULES_PLACEHOLDER = "$RULES";
|
|
4494
|
+
var NOT_FOUND = -1;
|
|
4495
|
+
function generate_eslint_config() {
|
|
4496
|
+
return ESLINT_VANILLA;
|
|
4497
|
+
}
|
|
4498
|
+
function is_vanilla_eslint_config(existing) {
|
|
4499
|
+
if (existing.includes(KIT_ESLINT_IMPORT_MARKER)) return false;
|
|
4500
|
+
return VANILLA_ESLINT_MARKERS.some((marker) => existing.includes(marker));
|
|
4501
|
+
}
|
|
4502
|
+
function update_brace_depth(char, depth) {
|
|
4503
|
+
if (char === "{") return depth + 1;
|
|
4504
|
+
if (char === "}") return depth - 1;
|
|
4505
|
+
return depth;
|
|
4506
|
+
}
|
|
4507
|
+
function find_matching_close_brace(source, open_index) {
|
|
4508
|
+
let depth = 0;
|
|
4509
|
+
for (let index = open_index; index < source.length; index += 1) {
|
|
4510
|
+
depth = update_brace_depth(source[index], depth);
|
|
4511
|
+
if (depth === 0 && source[index] === "}") return index;
|
|
4512
|
+
}
|
|
4513
|
+
return NOT_FOUND;
|
|
4514
|
+
}
|
|
4515
|
+
function extract_block_from_open(source, open_index) {
|
|
4516
|
+
const close = find_matching_close_brace(source, open_index);
|
|
4517
|
+
if (close === NOT_FOUND) return void 0;
|
|
4518
|
+
const inner = source.slice(open_index + 1, close).trim();
|
|
4519
|
+
return inner.length > 0 ? inner : void 0;
|
|
4520
|
+
}
|
|
4521
|
+
function extract_rules_inner_blocks(existing) {
|
|
4522
|
+
const blocks = [];
|
|
4523
|
+
for (const match of existing.matchAll(RULES_BLOCK_PATTERN)) {
|
|
4524
|
+
const open = match.index + match[0].length - 1;
|
|
4525
|
+
const inner = extract_block_from_open(existing, open);
|
|
4526
|
+
if (inner !== void 0) blocks.push(inner);
|
|
4527
|
+
}
|
|
4528
|
+
return blocks;
|
|
4529
|
+
}
|
|
4530
|
+
function indent_block(text, indent) {
|
|
4531
|
+
return text.split("\n").map((line) => line.length === 0 ? line : `${indent}${line.trimStart()}`).join("\n");
|
|
4532
|
+
}
|
|
4533
|
+
function apply_rules_template(rules_body) {
|
|
4534
|
+
const rules_block = indent_block(rules_body, RULES_INDENT);
|
|
4535
|
+
return VANILLA_WITH_RULES_TPL.replace(RULES_PLACEHOLDER, () => rules_block);
|
|
4536
|
+
}
|
|
4537
|
+
function merge_eslint_config(existing) {
|
|
4538
|
+
if (!is_vanilla_eslint_config(existing)) return existing;
|
|
4539
|
+
const rules_blocks = extract_rules_inner_blocks(existing);
|
|
4540
|
+
if (rules_blocks.length === 0) return generate_eslint_config();
|
|
4541
|
+
return apply_rules_template(rules_blocks.join(",\n"));
|
|
4542
|
+
}
|
|
4543
|
+
function detect_tailwind_stylesheet(project_root2) {
|
|
4544
|
+
return existsSync5(path8.join(project_root2, DEFAULT_TAILWIND_STYLESHEET)) ? DEFAULT_TAILWIND_STYLESHEET : void 0;
|
|
4545
|
+
}
|
|
4546
|
+
function generate_prettier_config(stylesheet) {
|
|
4547
|
+
const stylesheet_line = stylesheet === void 0 ? "" : ` tailwindStylesheet: '${stylesheet}',
|
|
4548
|
+
`;
|
|
4549
|
+
return `import { config } from '@joshuafolkken/kit/prettier'
|
|
4550
|
+
|
|
4551
|
+
export default {
|
|
4552
|
+
...config,
|
|
4553
|
+
${stylesheet_line}}
|
|
4554
|
+
`;
|
|
4555
|
+
}
|
|
4556
|
+
function existing_stylesheet(existing, project_root2) {
|
|
4557
|
+
const named = TAILWIND_STYLESHEET_PATTERN.exec(existing)?.[1];
|
|
4558
|
+
return named !== void 0 && existsSync5(path8.resolve(project_root2, named)) ? named : void 0;
|
|
4559
|
+
}
|
|
4560
|
+
function merge_prettier_config(existing, project_root2) {
|
|
4561
|
+
const stylesheet = existing_stylesheet(existing, project_root2) ?? detect_tailwind_stylesheet(project_root2);
|
|
4562
|
+
return generate_prettier_config(stylesheet);
|
|
4563
|
+
}
|
|
4564
|
+
function generate_playwright_config() {
|
|
4565
|
+
return readFileSync4(PLAYWRIGHT_TEMPLATE_PATH, "utf8");
|
|
4566
|
+
}
|
|
4567
|
+
var init_logic_templates = {
|
|
4568
|
+
generate_eslint_config,
|
|
4569
|
+
merge_eslint_config,
|
|
4570
|
+
detect_tailwind_stylesheet,
|
|
4571
|
+
generate_prettier_config,
|
|
4572
|
+
merge_prettier_config,
|
|
4573
|
+
generate_playwright_config
|
|
4574
|
+
};
|
|
4575
|
+
|
|
4576
|
+
// scripts/init/init-logic-toolchain.ts
|
|
4577
|
+
var CONSUMER_RESOLVED_TOOLS = [
|
|
4578
|
+
"eslint",
|
|
4579
|
+
"prettier",
|
|
4580
|
+
"typescript",
|
|
4581
|
+
"@playwright/test",
|
|
4582
|
+
"@ianvs/prettier-plugin-sort-imports",
|
|
4583
|
+
"prettier-plugin-svelte",
|
|
4584
|
+
"prettier-plugin-tailwindcss",
|
|
4585
|
+
"cspell",
|
|
4586
|
+
"@types/node"
|
|
4587
|
+
];
|
|
4588
|
+
var LEFTHOOK_DEVELOPMENT_DEPENDENCY = "lefthook";
|
|
4589
|
+
var DECLARING_FIELDS = [
|
|
4590
|
+
"dependencies",
|
|
4591
|
+
"devDependencies",
|
|
4592
|
+
"peerDependencies",
|
|
4593
|
+
"optionalDependencies"
|
|
4594
|
+
];
|
|
4595
|
+
function consumer_resolved_names(has_git2) {
|
|
4596
|
+
return has_git2 ? [...CONSUMER_RESOLVED_TOOLS, LEFTHOOK_DEVELOPMENT_DEPENDENCY] : CONSUMER_RESOLVED_TOOLS;
|
|
4597
|
+
}
|
|
4598
|
+
function get_toolchain_development_dependencies(has_git2) {
|
|
4599
|
+
return kit_development_versions.versions_of([
|
|
4600
|
+
...kit_development_versions.peer_names(),
|
|
4601
|
+
...consumer_resolved_names(has_git2)
|
|
4602
|
+
]);
|
|
4603
|
+
}
|
|
4604
|
+
function is_declared(manifest, name) {
|
|
4605
|
+
return DECLARING_FIELDS.some((field) => {
|
|
4606
|
+
const dependencies = manifest[field];
|
|
4607
|
+
return json_value.is_record(dependencies) && Object.hasOwn(dependencies, name);
|
|
4608
|
+
});
|
|
4609
|
+
}
|
|
4610
|
+
function merge_consumer_resolved_development_deps(content, has_git2) {
|
|
4611
|
+
const manifest = parse_jsonc(content);
|
|
4612
|
+
const missing = consumer_resolved_names(has_git2).filter((name) => !is_declared(manifest, name));
|
|
4613
|
+
return init_logic_json_merge.merge_development_dependencies(
|
|
4614
|
+
content,
|
|
4615
|
+
kit_development_versions.versions_of(missing)
|
|
4616
|
+
);
|
|
4617
|
+
}
|
|
4618
|
+
var init_logic_toolchain = {
|
|
4619
|
+
consumer_resolved_names,
|
|
4620
|
+
get_toolchain_development_dependencies,
|
|
4621
|
+
merge_consumer_resolved_development_deps
|
|
4622
|
+
};
|
|
4623
|
+
|
|
4624
|
+
// scripts/init/init-logic-workspace.ts
|
|
4625
|
+
function extract_yaml_top_level_keys(content) {
|
|
4626
|
+
return content.split("\n").flatMap((line) => {
|
|
4627
|
+
const key = /^([a-zA-Z][a-zA-Z0-9_-]*):/u.exec(line)?.[1];
|
|
4628
|
+
return key ?? [];
|
|
4629
|
+
});
|
|
4630
|
+
}
|
|
4631
|
+
function extract_yaml_block(content, key) {
|
|
4632
|
+
const pattern = new RegExp(String.raw`(^${key}:[^\n]*\n(?:(?:[ \t][^\n]*|)\n)*)`, "mu");
|
|
4633
|
+
return pattern.exec(content)?.[1]?.trimEnd() ?? "";
|
|
4634
|
+
}
|
|
4635
|
+
function append_user_blocks(base, user_keys, existing) {
|
|
4636
|
+
const user_blocks = user_keys.map((k) => extract_yaml_block(existing, k)).filter(Boolean).join("\n");
|
|
4637
|
+
const normalized2 = base.endsWith("\n") ? base : `${base}
|
|
4638
|
+
`;
|
|
4639
|
+
return `${normalized2}
|
|
4640
|
+
${user_blocks}
|
|
4641
|
+
`;
|
|
4642
|
+
}
|
|
4643
|
+
var DEPRECATED_KEYS = /* @__PURE__ */ new Set(["onlyBuiltDependencies"]);
|
|
4644
|
+
function remove_deprecated_yaml_key(content, key) {
|
|
4645
|
+
const block = extract_yaml_block(content, key);
|
|
4646
|
+
if (block.length === 0) return content;
|
|
4647
|
+
const removed = content.replaceAll(`${block}
|
|
4648
|
+
`, "");
|
|
4649
|
+
return removed.replaceAll(/\n{3,}/gu, "\n\n");
|
|
4650
|
+
}
|
|
4651
|
+
function remove_deprecated_yaml_keys(content) {
|
|
4652
|
+
let result = content;
|
|
4653
|
+
for (const key of DEPRECATED_KEYS) {
|
|
4654
|
+
result = remove_deprecated_yaml_key(result, key);
|
|
4655
|
+
}
|
|
4656
|
+
return `${result.trimEnd()}
|
|
4657
|
+
`;
|
|
4658
|
+
}
|
|
4659
|
+
var BUILD_PLACEHOLDER_PATTERN = /^([ \t]+)([^\s:#][^:#]*): set this to true or false$/gmu;
|
|
4660
|
+
var TEMPLATE_BUILD_PATTERN = /^[ \t]+(?<key>[^\s:#][^:#]*):[ \t]*(?<value>true|false)\b/u;
|
|
4661
|
+
function unquote(key) {
|
|
4662
|
+
return key.trim().replaceAll(/^['"]|['"]$/gu, "");
|
|
4663
|
+
}
|
|
4664
|
+
function template_build_values(template) {
|
|
4665
|
+
const lines = extract_yaml_block(template, "allowBuilds").split("\n");
|
|
4666
|
+
return new Map(
|
|
4667
|
+
lines.flatMap((line) => {
|
|
4668
|
+
const { key, value } = TEMPLATE_BUILD_PATTERN.exec(line)?.groups ?? {};
|
|
4669
|
+
return key && value ? [[unquote(key), value]] : [];
|
|
4670
|
+
})
|
|
4671
|
+
);
|
|
4672
|
+
}
|
|
4673
|
+
function answer_build_placeholders(existing, template) {
|
|
4674
|
+
const values = template_build_values(template);
|
|
4675
|
+
return existing.replaceAll(BUILD_PLACEHOLDER_PATTERN, (line, indent, key) => {
|
|
4676
|
+
const value = values.get(unquote(key));
|
|
4677
|
+
return value === void 0 ? line : `${indent}${key}: ${value}`;
|
|
4678
|
+
});
|
|
4679
|
+
}
|
|
4680
|
+
var BUILD_ENTRY_KEY_PATTERN = /^[ \t]+(?<key>[^\s:#][^:#]*):/u;
|
|
4681
|
+
function build_entry_key(line) {
|
|
4682
|
+
const key = BUILD_ENTRY_KEY_PATTERN.exec(line)?.groups?.["key"];
|
|
4683
|
+
return key === void 0 ? void 0 : unquote(key);
|
|
4684
|
+
}
|
|
4685
|
+
function build_entry_keys(block) {
|
|
4686
|
+
return new Set(block.split("\n").flatMap((line) => build_entry_key(line) ?? []));
|
|
4687
|
+
}
|
|
4688
|
+
var BLOCK_MAPPING_HEADER_PATTERN = /^allowBuilds:[ \t]*(?:#[^\n]*)?(?:\n|$)/u;
|
|
4689
|
+
var LEADING_INDENT_PATTERN = /^[ \t]+/u;
|
|
4690
|
+
function block_entry_indent(block) {
|
|
4691
|
+
const entry = block.split("\n").find((line) => build_entry_key(line) !== void 0);
|
|
4692
|
+
return entry === void 0 ? void 0 : LEADING_INDENT_PATTERN.exec(entry)?.[0];
|
|
4693
|
+
}
|
|
4694
|
+
function reindent(line, indent) {
|
|
4695
|
+
return indent === void 0 ? line : line.replace(LEADING_INDENT_PATTERN, () => indent);
|
|
4696
|
+
}
|
|
4697
|
+
function add_missing_build_entries(existing, template) {
|
|
4698
|
+
const block = extract_yaml_block(existing, "allowBuilds");
|
|
4699
|
+
if (!BLOCK_MAPPING_HEADER_PATTERN.test(block)) return existing;
|
|
4700
|
+
const present = build_entry_keys(block);
|
|
4701
|
+
const indent = block_entry_indent(block);
|
|
4702
|
+
const missing = extract_yaml_block(template, "allowBuilds").split("\n").filter((line) => {
|
|
4703
|
+
const key = build_entry_key(line);
|
|
4704
|
+
return key !== void 0 && !present.has(key);
|
|
4705
|
+
}).map((line) => reindent(line, indent));
|
|
4706
|
+
if (missing.length === 0) return existing;
|
|
4707
|
+
return existing.replace(block, () => [block, ...missing].join("\n"));
|
|
4708
|
+
}
|
|
4709
|
+
var MOVED_NPMRC_SETTINGS = [
|
|
4710
|
+
{ npmrc_key: "minimum-release-age", workspace_key: "minimumReleaseAge", value_pattern: /^\d+$/u },
|
|
4711
|
+
{ npmrc_key: "engine-strict", workspace_key: "engineStrict", value_pattern: /^(?:true|false)$/u }
|
|
4712
|
+
];
|
|
4713
|
+
function npmrc_value(npmrc, key) {
|
|
4714
|
+
const pattern = new RegExp(String.raw`^[ \t]*${key}[ \t]*=[ \t]*(\S+)[ \t]*$`, "gmu");
|
|
4715
|
+
return [...npmrc.matchAll(pattern)].at(-1)?.[1];
|
|
4716
|
+
}
|
|
4717
|
+
function carry_npmrc_setting(template, npmrc, setting) {
|
|
4718
|
+
const value = npmrc_value(npmrc, setting.npmrc_key);
|
|
4719
|
+
if (value === void 0 || !setting.value_pattern.test(value)) return template;
|
|
4720
|
+
const line_pattern = new RegExp(`^${setting.workspace_key}:.*$`, "mu");
|
|
4721
|
+
return template.replace(line_pattern, () => `${setting.workspace_key}: ${value}`);
|
|
4722
|
+
}
|
|
4723
|
+
function carry_npmrc_settings(template, npmrc) {
|
|
4724
|
+
let result = template;
|
|
4725
|
+
for (const setting of MOVED_NPMRC_SETTINGS) {
|
|
4726
|
+
result = carry_npmrc_setting(result, npmrc, setting);
|
|
4727
|
+
}
|
|
4728
|
+
return result;
|
|
4729
|
+
}
|
|
4730
|
+
function merge_workspace_yaml(existing, template) {
|
|
4731
|
+
if (!existing.trim()) return template;
|
|
4732
|
+
const normalized2 = existing.endsWith("\n") ? existing : `${existing}
|
|
4733
|
+
`;
|
|
4734
|
+
const answered = answer_build_placeholders(remove_deprecated_yaml_keys(normalized2), template);
|
|
4735
|
+
const cleaned = add_missing_build_entries(answered, template);
|
|
4736
|
+
if (!cleaned.trim()) return template;
|
|
4737
|
+
const existing_keys = new Set(extract_yaml_top_level_keys(cleaned));
|
|
4738
|
+
const new_keys = extract_yaml_top_level_keys(template).filter((k) => !existing_keys.has(k));
|
|
4739
|
+
if (new_keys.length === 0) return cleaned;
|
|
4740
|
+
return append_user_blocks(cleaned, new_keys, template);
|
|
4741
|
+
}
|
|
4742
|
+
var init_logic_workspace = { carry_npmrc_settings, merge_workspace_yaml, template_build_values };
|
|
4743
|
+
|
|
4744
|
+
// scripts/init/init-logic-yaml-merge.ts
|
|
4745
|
+
var CSPELL_IMPORT_FIELD = "import";
|
|
4746
|
+
var LEFTHOOK_EXTENDS_FIELD = "extends";
|
|
4747
|
+
var CSPELL_IMPORT_POSITION = { after: "version" };
|
|
4748
|
+
var CSPELL_QUOTE_STYLE = "double";
|
|
4749
|
+
function merge_yaml_list_entry(content, key, value) {
|
|
4750
|
+
return config_merge.patch_yaml_list_field(content, {
|
|
4751
|
+
field: key,
|
|
4752
|
+
ensure: [value],
|
|
4753
|
+
position: "front"
|
|
4754
|
+
});
|
|
4755
|
+
}
|
|
4756
|
+
function merge_lefthook_extends(content, value) {
|
|
4757
|
+
const entries = config_merge.read_yaml_list_field(content, LEFTHOOK_EXTENDS_FIELD);
|
|
4758
|
+
if (kit_base_preset.is_lefthook_base_present(entries)) return content;
|
|
4759
|
+
return merge_yaml_list_entry(content, LEFTHOOK_EXTENDS_FIELD, value);
|
|
4760
|
+
}
|
|
4761
|
+
function merge_cspell_import(content, value) {
|
|
4762
|
+
const entries = config_merge.read_yaml_list_field(content, CSPELL_IMPORT_FIELD);
|
|
4763
|
+
if (kit_base_preset.is_cspell_base_present(entries)) return content;
|
|
4764
|
+
return config_merge.patch_yaml_list_field(content, {
|
|
4765
|
+
field: CSPELL_IMPORT_FIELD,
|
|
4766
|
+
ensure: [value],
|
|
4767
|
+
position: CSPELL_IMPORT_POSITION,
|
|
4768
|
+
quote_style: CSPELL_QUOTE_STYLE
|
|
4769
|
+
});
|
|
4770
|
+
}
|
|
4771
|
+
var init_logic_yaml_merge = {
|
|
4772
|
+
merge_yaml_list_entry,
|
|
4773
|
+
merge_lefthook_extends,
|
|
4774
|
+
merge_cspell_import
|
|
4775
|
+
};
|
|
4776
|
+
|
|
4777
|
+
// scripts/init/init-logic.ts
|
|
4778
|
+
var DEV_ENGINES_VALUE = {
|
|
4779
|
+
packageManager: { name: "pnpm", version: ">=12.1.0", onFail: "download" }
|
|
4780
|
+
};
|
|
4781
|
+
var LEGACY_NPMRC_LINES = /* @__PURE__ */ new Set([
|
|
4782
|
+
"engine-strict=true",
|
|
4783
|
+
"minimum-release-age=1440",
|
|
4784
|
+
"confirmModulesPurge=false",
|
|
4785
|
+
"lockfile-include-tarball-url=true"
|
|
4786
|
+
]);
|
|
4787
|
+
var CSPELL_IMPORT = "@joshuafolkken/kit/cspell";
|
|
4788
|
+
var LEFTHOOK_INSTALL_CMD = "lefthook install";
|
|
4789
|
+
var { SAFE_CHAIN_CMD: SAFE_CHAIN_CMD2 } = safe_chain_preinstall;
|
|
4790
|
+
var FIX_GH_PACKAGES_CMD = "tsx node_modules/@joshuafolkken/kit/scripts/gh/fix-gh-packages.ts";
|
|
4791
|
+
var FIX_GH_PACKAGES_MARKER = "fix-gh-packages";
|
|
4792
|
+
var PREPARE_KEY = "prepare";
|
|
4793
|
+
var LEGACY_POSTINSTALL_KEY = "postinstall";
|
|
4794
|
+
var HOOK_INSTALL_WARNING = "lefthook install failed: git hooks are NOT installed. A set core.hooksPath is the usual cause. See https://github.com/joshuafolkken/kit/blob/main/docs/init.md#corehookspath-stops-lefthook-installing-anything";
|
|
4795
|
+
var LEFTHOOK_BINARY_GUARD = "command -v lefthook >/dev/null 2>&1";
|
|
4796
|
+
var GUARDED_LEFTHOOK_CMD = `${LEFTHOOK_BINARY_GUARD} && { ${LEFTHOOK_INSTALL_CMD} || echo '${HOOK_INSTALL_WARNING}' >&2; }`;
|
|
4797
|
+
var LEGACY_GUARDED_LEFTHOOK_CMD = `${LEFTHOOK_BINARY_GUARD} && ${LEFTHOOK_INSTALL_CMD}`;
|
|
4798
|
+
var GUARDED_FIX_GH_PACKAGES_CMD = `command -v tsx >/dev/null 2>&1 && ${FIX_GH_PACKAGES_CMD}`;
|
|
4799
|
+
var PREPARE_CMD = `(${GUARDED_LEFTHOOK_CMD} || true) && (${GUARDED_FIX_GH_PACKAGES_CMD} || true)`;
|
|
4800
|
+
var AI_COPY_FILES = [
|
|
4801
|
+
"AGENTS.md",
|
|
4802
|
+
"GEMINI.md",
|
|
4803
|
+
"CODE_OF_CONDUCT.md",
|
|
4804
|
+
".cursorrules",
|
|
4805
|
+
".coderabbit.yaml",
|
|
4806
|
+
".gitattributes",
|
|
4807
|
+
".mcp.json",
|
|
4808
|
+
".ncurc.json",
|
|
4809
|
+
".prettierignore",
|
|
4810
|
+
"SECURITY.md",
|
|
4811
|
+
"pnpm-workspace.yaml",
|
|
4812
|
+
"tsconfig.sonar.json",
|
|
4813
|
+
".github/workflows/auto-tag.yml",
|
|
4814
|
+
".github/workflows/production.yml",
|
|
4815
|
+
".github/workflows/sonar-qube.yml",
|
|
4816
|
+
".github/workflows/pr-classification.yml",
|
|
4817
|
+
// Called by `ci.yml` and `pr-classification.yml` as `uses: ./.github/actions/setup-pnpm`; without
|
|
4818
|
+
// it the consumer's jobs cannot resolve the action and their checks fail.
|
|
4819
|
+
".github/actions/setup-pnpm/action.yml",
|
|
4820
|
+
// The one place the workflows' Node.js version is written, called by every distributed workflow
|
|
4821
|
+
// that sets Node.js up.
|
|
4822
|
+
".github/actions/setup-node/action.yml",
|
|
4823
|
+
".github/pull_request_template.md",
|
|
4824
|
+
".github/release.yml",
|
|
4825
|
+
".github/dependabot.yml",
|
|
4826
|
+
".claude/settings.json",
|
|
4827
|
+
".codex/config.toml",
|
|
4828
|
+
".codex/hooks.json"
|
|
4829
|
+
];
|
|
4830
|
+
var AI_COPY_FILE_MAPPINGS = [
|
|
4831
|
+
{ src: "templates/workflows/ci.yml", dest: ".github/workflows/ci.yml" },
|
|
4832
|
+
// The counterpart to the distributed `.github/dependabot.yml`: without it a consumer receives
|
|
4833
|
+
// the machinery that opens Dependabot pull requests and none of the machinery that closes them,
|
|
4834
|
+
// so every github-actions bump sits green and unmerged.
|
|
4835
|
+
{
|
|
4836
|
+
src: "templates/workflows/dependabot-auto-merge.yml",
|
|
4837
|
+
dest: ".github/workflows/dependabot-auto-merge.yml"
|
|
4838
|
+
},
|
|
4839
|
+
// A template rather than a copy of kit's own file: kit releases from its publish.yml, so the file
|
|
4840
|
+
// must not run in kit as well.
|
|
4841
|
+
{ src: "templates/workflows/github-release.yml", dest: ".github/workflows/github-release.yml" }
|
|
4842
|
+
];
|
|
4843
|
+
var AI_COPY_DIRECTORIES = [];
|
|
4844
|
+
var LEFTHOOK_EXTENDS = "node_modules/@joshuafolkken/kit/lefthook/vanilla.yml";
|
|
4845
|
+
var TSCONFIG_EXTENDS = "./node_modules/@joshuafolkken/kit/tsconfig/base.json";
|
|
4846
|
+
var TSCONFIG_PRESET_FILENAME = "base.json";
|
|
4847
|
+
var TSCONFIG_EXCLUDE_FIELD = "exclude";
|
|
4848
|
+
var TSCONFIG_GENERATED_OUTPUT_EXCLUDE = [
|
|
4849
|
+
"node_modules",
|
|
4850
|
+
"build",
|
|
4851
|
+
"dist",
|
|
4852
|
+
"playwright-report",
|
|
4853
|
+
"test-results"
|
|
4854
|
+
];
|
|
4855
|
+
var TSCONFIG_SVELTEKIT_EXCLUDE = [
|
|
4856
|
+
"src/service-worker.js",
|
|
4857
|
+
"src/service-worker/**/*.js",
|
|
4858
|
+
"src/service-worker.ts",
|
|
4859
|
+
"src/service-worker/**/*.ts",
|
|
4860
|
+
"src/service-worker.d.ts",
|
|
4861
|
+
"src/service-worker/**/*.d.ts"
|
|
4862
|
+
];
|
|
4863
|
+
var TSCONFIG_EXCLUDE = [
|
|
4864
|
+
...TSCONFIG_GENERATED_OUTPUT_EXCLUDE,
|
|
4865
|
+
...TSCONFIG_SVELTEKIT_EXCLUDE
|
|
4866
|
+
];
|
|
4867
|
+
var VSCODE_EXTENSIONS_FILENAME = "extensions.json";
|
|
4868
|
+
var VSCODE_SETTINGS_FILENAME = "settings.json";
|
|
4869
|
+
var KIT_ONLY_VSCODE_SETTINGS_KEYS = /* @__PURE__ */ new Set([
|
|
4870
|
+
"sonarlint.connectedMode.project"
|
|
4871
|
+
]);
|
|
4872
|
+
var SUGGESTED_SCRIPTS_COMMON = {
|
|
4873
|
+
preinstall: SAFE_CHAIN_CMD2,
|
|
4874
|
+
prepare: PREPARE_CMD,
|
|
4875
|
+
josh: "josh"
|
|
4876
|
+
};
|
|
4877
|
+
function generate_tsconfig() {
|
|
4878
|
+
return json_format.format_json({
|
|
4879
|
+
extends: TSCONFIG_EXTENDS,
|
|
4880
|
+
compilerOptions: { types: ["node"] },
|
|
4881
|
+
[TSCONFIG_EXCLUDE_FIELD]: TSCONFIG_EXCLUDE
|
|
4882
|
+
});
|
|
4883
|
+
}
|
|
4884
|
+
function merge_tsconfig_exclude(content) {
|
|
4885
|
+
const field = TSCONFIG_EXCLUDE_FIELD;
|
|
4886
|
+
return init_logic_json_merge.merge_json_array_field(content, field, TSCONFIG_EXCLUDE);
|
|
4887
|
+
}
|
|
4888
|
+
function generate_lefthook_config() {
|
|
4889
|
+
return `extends:
|
|
4890
|
+
- ${LEFTHOOK_EXTENDS}
|
|
4891
|
+
`;
|
|
4892
|
+
}
|
|
4893
|
+
function generate_cspell_config() {
|
|
4894
|
+
return `version: "0.2"
|
|
4895
|
+
import:
|
|
4896
|
+
- "${CSPELL_IMPORT}"
|
|
4897
|
+
words: []
|
|
4898
|
+
ignorePaths: []
|
|
4899
|
+
`;
|
|
4900
|
+
}
|
|
4901
|
+
function append_missing_lines(existing, missing) {
|
|
4902
|
+
if (missing.length === 0) return existing;
|
|
4903
|
+
const prefix = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
|
|
4904
|
+
` : existing;
|
|
4905
|
+
return `${prefix}${missing.join("\n")}
|
|
4906
|
+
`;
|
|
4907
|
+
}
|
|
4908
|
+
function merge_npmrc(content) {
|
|
4909
|
+
const lines = content.split("\n");
|
|
4910
|
+
const kept = lines.filter((line) => !LEGACY_NPMRC_LINES.has(line.trim()));
|
|
4911
|
+
return kept.length === lines.length ? content : kept.join("\n");
|
|
4912
|
+
}
|
|
4913
|
+
function is_gitignore_pattern(line) {
|
|
4914
|
+
const trimmed = line.trim();
|
|
4915
|
+
return trimmed.length > 0 && !trimmed.startsWith("#");
|
|
4916
|
+
}
|
|
4917
|
+
function merge_gitignore(existing, template) {
|
|
4918
|
+
const existing_lines = new Set(existing.split("\n"));
|
|
4919
|
+
const missing = template.split("\n").filter((line) => is_gitignore_pattern(line) && !existing_lines.has(line));
|
|
4920
|
+
return append_missing_lines(existing, missing);
|
|
4921
|
+
}
|
|
4922
|
+
function get_tsconfig_extends_entry() {
|
|
4923
|
+
return TSCONFIG_EXTENDS;
|
|
4924
|
+
}
|
|
4925
|
+
function get_tsconfig_preset_filename() {
|
|
4926
|
+
return TSCONFIG_PRESET_FILENAME;
|
|
4927
|
+
}
|
|
4928
|
+
function get_tsconfig_exclude_entries() {
|
|
4929
|
+
return TSCONFIG_EXCLUDE;
|
|
4930
|
+
}
|
|
4931
|
+
function get_lefthook_extends_value() {
|
|
4932
|
+
return LEFTHOOK_EXTENDS;
|
|
4933
|
+
}
|
|
4934
|
+
function get_cspell_import_value() {
|
|
4935
|
+
return CSPELL_IMPORT;
|
|
4936
|
+
}
|
|
4937
|
+
function get_vscode_settings_filename() {
|
|
4938
|
+
return VSCODE_SETTINGS_FILENAME;
|
|
4939
|
+
}
|
|
4940
|
+
function strip_kit_only_vscode_settings(settings) {
|
|
4941
|
+
const entries = Object.entries(settings).filter(
|
|
4942
|
+
([key]) => !KIT_ONLY_VSCODE_SETTINGS_KEYS.has(key)
|
|
4943
|
+
);
|
|
4944
|
+
return Object.fromEntries(entries);
|
|
4945
|
+
}
|
|
4946
|
+
function strip_kit_only_vscode_settings_content(raw) {
|
|
4947
|
+
const parsed = vscode_settings_schema.parse(JSON.parse(raw));
|
|
4948
|
+
const stripped = strip_kit_only_vscode_settings(parsed);
|
|
4949
|
+
if (Object.keys(stripped).length === Object.keys(parsed).length) return raw;
|
|
4950
|
+
return json_format.format_json(stripped);
|
|
4951
|
+
}
|
|
4952
|
+
function get_development_engines_value() {
|
|
4953
|
+
return DEV_ENGINES_VALUE;
|
|
4954
|
+
}
|
|
4955
|
+
function get_ai_copy_files() {
|
|
4956
|
+
return AI_COPY_FILES;
|
|
4957
|
+
}
|
|
4958
|
+
function get_ai_copy_file_mappings() {
|
|
4959
|
+
return AI_COPY_FILE_MAPPINGS;
|
|
4960
|
+
}
|
|
4961
|
+
function get_ai_copy_directories() {
|
|
4962
|
+
return AI_COPY_DIRECTORIES;
|
|
4963
|
+
}
|
|
4964
|
+
function get_suggested_scripts() {
|
|
4965
|
+
return SUGGESTED_SCRIPTS_COMMON;
|
|
4966
|
+
}
|
|
4967
|
+
function get_suggested_scripts_for_content(content) {
|
|
4968
|
+
const scripts = get_suggested_scripts();
|
|
4969
|
+
const has_fix = init_logic_json_merge.has_package_scripts_marker(content, FIX_GH_PACKAGES_MARKER);
|
|
4970
|
+
if (!has_fix) return scripts;
|
|
4971
|
+
return Object.fromEntries(Object.entries(scripts).filter(([key]) => key !== PREPARE_KEY));
|
|
4972
|
+
}
|
|
4973
|
+
function upgrade_prepare_lefthook_warning(content) {
|
|
4974
|
+
return init_logic_json_merge.replace_in_package_script(
|
|
4975
|
+
content,
|
|
4976
|
+
PREPARE_KEY,
|
|
4977
|
+
LEGACY_GUARDED_LEFTHOOK_CMD,
|
|
4978
|
+
GUARDED_LEFTHOOK_CMD
|
|
4979
|
+
);
|
|
4980
|
+
}
|
|
4981
|
+
function merge_prepare_lifecycle_cmd(content) {
|
|
4982
|
+
const has_fix = init_logic_json_merge.has_package_scripts_marker(content, FIX_GH_PACKAGES_MARKER);
|
|
4983
|
+
if (has_fix) return content;
|
|
4984
|
+
return init_logic_json_merge.merge_package_script_suffix(content, PREPARE_KEY, PREPARE_CMD);
|
|
4985
|
+
}
|
|
4986
|
+
function strip_managed_postinstall(content) {
|
|
4987
|
+
return init_logic_json_merge.remove_script_with_marker(
|
|
4988
|
+
content,
|
|
4989
|
+
LEGACY_POSTINSTALL_KEY,
|
|
4990
|
+
FIX_GH_PACKAGES_CMD
|
|
4991
|
+
);
|
|
4992
|
+
}
|
|
4993
|
+
var init_logic = {
|
|
4994
|
+
...init_logic_templates,
|
|
4995
|
+
...init_logic_workspace,
|
|
4996
|
+
...init_logic_sonar,
|
|
4997
|
+
...init_logic_json_merge,
|
|
4998
|
+
...init_logic_secretlint,
|
|
4999
|
+
...init_logic_toolchain,
|
|
5000
|
+
...init_logic_yaml_merge,
|
|
5001
|
+
...init_logic_deploy_vps,
|
|
5002
|
+
...distributed_paths,
|
|
5003
|
+
generate_tsconfig,
|
|
5004
|
+
merge_tsconfig_exclude,
|
|
5005
|
+
get_tsconfig_exclude_entries,
|
|
5006
|
+
generate_lefthook_config,
|
|
5007
|
+
generate_cspell_config,
|
|
5008
|
+
merge_npmrc,
|
|
5009
|
+
merge_gitignore,
|
|
5010
|
+
get_tsconfig_extends_entry,
|
|
5011
|
+
get_tsconfig_preset_filename,
|
|
5012
|
+
get_lefthook_extends_value,
|
|
5013
|
+
get_cspell_import_value,
|
|
5014
|
+
get_vscode_settings_filename,
|
|
5015
|
+
strip_kit_only_vscode_settings,
|
|
5016
|
+
strip_kit_only_vscode_settings_content,
|
|
5017
|
+
VSCODE_EXTENSIONS_FILENAME,
|
|
5018
|
+
SAFE_CHAIN_CMD: SAFE_CHAIN_CMD2,
|
|
5019
|
+
GUARDED_LEFTHOOK_CMD,
|
|
5020
|
+
upgrade_prepare_lefthook_warning,
|
|
5021
|
+
get_development_engines_value,
|
|
5022
|
+
get_ai_copy_files,
|
|
5023
|
+
get_ai_copy_file_mappings,
|
|
5024
|
+
get_ai_copy_directories,
|
|
5025
|
+
get_suggested_scripts,
|
|
5026
|
+
get_suggested_scripts_for_content,
|
|
5027
|
+
merge_prepare_lifecycle_cmd,
|
|
5028
|
+
strip_managed_postinstall
|
|
5029
|
+
};
|
|
5030
|
+
|
|
5031
|
+
// scripts/sync/plugin-skill-directories.ts
|
|
5032
|
+
var PLUGIN_SKILL_DIRECTORIES = [
|
|
5033
|
+
".claude/skills/workflow-commands",
|
|
5034
|
+
".claude/skills/epic-commands",
|
|
5035
|
+
".claude/skills/dependency-update",
|
|
5036
|
+
".claude/skills/verify-ui"
|
|
5037
|
+
];
|
|
5038
|
+
|
|
5039
|
+
// scripts/sync/synced-paths.ts
|
|
5040
|
+
var SYNCED_ARTIFACT_PATHS = [
|
|
5041
|
+
"prettier.config.js",
|
|
5042
|
+
"playwright.config.ts",
|
|
5043
|
+
".github/workflows/deploy-vps.yml"
|
|
5044
|
+
];
|
|
5045
|
+
var SYNCED_CONFIG_PATHS = [
|
|
5046
|
+
".npmrc",
|
|
5047
|
+
".gitignore",
|
|
5048
|
+
"eslint.config.js",
|
|
5049
|
+
"tsconfig.json",
|
|
5050
|
+
"cspell.config.yaml",
|
|
5051
|
+
"lefthook.yml",
|
|
5052
|
+
".secretlintrc.json",
|
|
5053
|
+
".vscode/extensions.json",
|
|
5054
|
+
".vscode/settings.json",
|
|
5055
|
+
".vscode/tasks.json"
|
|
5056
|
+
];
|
|
5057
|
+
function get_synced_paths() {
|
|
5058
|
+
return [
|
|
5059
|
+
...SYNCED_ARTIFACT_PATHS,
|
|
5060
|
+
...SYNCED_CONFIG_PATHS,
|
|
5061
|
+
init_logic.get_sonar_template_destination()
|
|
5062
|
+
];
|
|
5063
|
+
}
|
|
5064
|
+
var synced_paths = { get_synced_paths };
|
|
5065
|
+
|
|
5066
|
+
// scripts/sync/managed-config-scope.ts
|
|
5067
|
+
var AI_COPY_FILES_LIST = "AI_COPY_FILES";
|
|
5068
|
+
var AI_COPY_FILE_MAPPINGS_LIST = "AI_COPY_FILE_MAPPINGS";
|
|
5069
|
+
var AI_COPY_DIRECTORIES_LIST = "AI_COPY_DIRECTORIES";
|
|
5070
|
+
var SYNCED_PATHS_LIST = "SYNCED_PATHS";
|
|
5071
|
+
var PLUGIN_SKILL_DIRECTORIES_LIST = "PLUGIN_SKILL_DIRECTORIES";
|
|
5072
|
+
var PATH_SEPARATOR = "/";
|
|
5073
|
+
function is_inside(path16, directory) {
|
|
5074
|
+
return path16 === directory || path16.startsWith(`${directory}${PATH_SEPARATOR}`);
|
|
5075
|
+
}
|
|
5076
|
+
function matches_file(path16) {
|
|
5077
|
+
return init_logic.get_ai_copy_files().includes(path16);
|
|
5078
|
+
}
|
|
5079
|
+
function matches_mapping(path16) {
|
|
5080
|
+
return init_logic.get_ai_copy_file_mappings().some((mapping) => mapping.src === path16 || mapping.dest === path16);
|
|
5081
|
+
}
|
|
5082
|
+
function matches_directory(path16) {
|
|
5083
|
+
return init_logic.get_ai_copy_directories().some((directory) => is_inside(path16, directory));
|
|
5084
|
+
}
|
|
5085
|
+
function matches_plugin_skill(path16) {
|
|
5086
|
+
return PLUGIN_SKILL_DIRECTORIES.some((directory) => is_inside(path16, directory));
|
|
5087
|
+
}
|
|
5088
|
+
function matches_synced_path(path16) {
|
|
5089
|
+
return synced_paths.get_synced_paths().includes(path16);
|
|
5090
|
+
}
|
|
5091
|
+
var MATCHERS = [
|
|
5092
|
+
{ list: AI_COPY_FILES_LIST, matches: matches_file },
|
|
5093
|
+
{ list: AI_COPY_FILE_MAPPINGS_LIST, matches: matches_mapping },
|
|
5094
|
+
{ list: AI_COPY_DIRECTORIES_LIST, matches: matches_directory },
|
|
5095
|
+
{ list: PLUGIN_SKILL_DIRECTORIES_LIST, matches: matches_plugin_skill },
|
|
5096
|
+
{ list: SYNCED_PATHS_LIST, matches: matches_synced_path }
|
|
5097
|
+
];
|
|
5098
|
+
function find_list(path16) {
|
|
5099
|
+
return MATCHERS.find((matcher) => matcher.matches(path16))?.list;
|
|
5100
|
+
}
|
|
5101
|
+
function to_hit(path16) {
|
|
5102
|
+
const list = find_list(path16);
|
|
5103
|
+
return list === void 0 ? void 0 : { path: path16, list };
|
|
5104
|
+
}
|
|
5105
|
+
function find_managed_paths(paths) {
|
|
5106
|
+
return paths.flatMap((path16) => to_hit(path16) ?? []);
|
|
5107
|
+
}
|
|
5108
|
+
function has_managed_path(paths) {
|
|
5109
|
+
return paths.some((path16) => find_list(path16) !== void 0);
|
|
5110
|
+
}
|
|
5111
|
+
function format_hit(hit) {
|
|
5112
|
+
return `${hit.path} (${hit.list})`;
|
|
5113
|
+
}
|
|
5114
|
+
function format_hits(hits) {
|
|
5115
|
+
return hits.map((hit) => format_hit(hit)).join("\n");
|
|
5116
|
+
}
|
|
5117
|
+
var managed_config_scope = {
|
|
5118
|
+
find_managed_paths,
|
|
5119
|
+
has_managed_path,
|
|
5120
|
+
format_hit,
|
|
5121
|
+
format_hits
|
|
5122
|
+
};
|
|
5123
|
+
|
|
5124
|
+
// scripts/init/session-language-environment.ts
|
|
5125
|
+
import path9 from "node:path";
|
|
5126
|
+
var CLAUDE_SETTINGS_PATH = path9.join(".claude", "settings.json");
|
|
5127
|
+
var KEY_LINE_PATTERN = new RegExp(
|
|
5128
|
+
String.raw`^\s*(?:export\s+)?${session_language.ENV_KEY}\s*=`,
|
|
5129
|
+
"mu"
|
|
5130
|
+
);
|
|
5131
|
+
|
|
5132
|
+
// scripts/config-merge/patch-json-array.ts
|
|
5133
|
+
import { findNodeAtLocation as findNodeAtLocation2, getNodeValue as getNodeValue2, parseTree as parseTree3 } from "jsonc-parser";
|
|
5134
|
+
|
|
5135
|
+
// scripts/init/vscode-tasks.ts
|
|
5136
|
+
import { z as z12 } from "zod";
|
|
5137
|
+
var task_array_schema = z12.array(json_object_schema);
|
|
5138
|
+
|
|
5139
|
+
// scripts/init/init-actions.ts
|
|
5140
|
+
var BASIC_PRETTIER_CONFIG = "prettier.config.mjs";
|
|
5141
|
+
|
|
5142
|
+
// scripts/managed-marker/managed-marker-logic.ts
|
|
5143
|
+
var MARKER_TOKEN = "josh-managed-workflow:";
|
|
5144
|
+
var MARKER_PREFIX = `# ${MARKER_TOKEN}`;
|
|
5145
|
+
|
|
5146
|
+
// scripts/init/claude-plugin-config.ts
|
|
5147
|
+
import path10 from "node:path";
|
|
5148
|
+
var MARKETPLACE_NAME = "kit";
|
|
5149
|
+
var PLUGIN_ID2 = "kit@kit";
|
|
5150
|
+
var MARKETPLACE_PATH = "./node_modules/@joshuafolkken/kit";
|
|
5151
|
+
var CLAUDE_SETTINGS_DESTINATION = path10.join(".claude", "settings.json");
|
|
5152
|
+
var PLUGIN_SETTINGS = {
|
|
5153
|
+
extraKnownMarketplaces: {
|
|
5154
|
+
[MARKETPLACE_NAME]: { source: { source: "directory", path: MARKETPLACE_PATH } }
|
|
5155
|
+
},
|
|
5156
|
+
enabledPlugins: { [PLUGIN_ID2]: true }
|
|
5157
|
+
};
|
|
5158
|
+
function inject_plugin_config(content) {
|
|
5159
|
+
return init_logic_json_merge.merge_json_object(content, PLUGIN_SETTINGS);
|
|
5160
|
+
}
|
|
5161
|
+
function apply_plugin_config_for_destination(destination_path, content) {
|
|
5162
|
+
return destination_path.endsWith(CLAUDE_SETTINGS_DESTINATION) ? inject_plugin_config(content) : content;
|
|
5163
|
+
}
|
|
5164
|
+
var claude_plugin_config = {
|
|
5165
|
+
PLUGIN_ID: PLUGIN_ID2,
|
|
5166
|
+
MARKETPLACE_PATH,
|
|
5167
|
+
CLAUDE_SETTINGS_DESTINATION,
|
|
5168
|
+
inject_plugin_config,
|
|
5169
|
+
apply_plugin_config_for_destination
|
|
5170
|
+
};
|
|
5171
|
+
|
|
5172
|
+
// scripts/init/hook-launch.ts
|
|
5173
|
+
var HOOK_DIST_DIR = "dist/hooks";
|
|
5174
|
+
var RUN_HOOK_SCRIPT = "scripts/hooks/run-hook.sh";
|
|
5175
|
+
var UNSET_OPTIONS = GIT_LOCATION_VARIABLES.map((name) => `-u ${name}`).join(" ");
|
|
5176
|
+
var ROOT_LOOKUP = "git rev-parse --show-toplevel";
|
|
5177
|
+
var PROJECT_ROOT_PREFIX = `project_root="$(env ${UNSET_OPTIONS} ${ROOT_LOOKUP} 2>/dev/null || ${ROOT_LOOKUP})" && cd "$project_root" && `;
|
|
5178
|
+
function hook_launch_command(name) {
|
|
5179
|
+
return `${PROJECT_ROOT_PREFIX}sh ${RUN_HOOK_SCRIPT} ${name}`;
|
|
5180
|
+
}
|
|
5181
|
+
function fallback_command(name) {
|
|
5182
|
+
return name.replace("-", ":");
|
|
5183
|
+
}
|
|
5184
|
+
var hook_launch = {
|
|
5185
|
+
fallback_command,
|
|
5186
|
+
HOOK_DIST_DIR,
|
|
5187
|
+
hook_launch_command,
|
|
5188
|
+
PROJECT_ROOT_PREFIX,
|
|
5189
|
+
RUN_HOOK_SCRIPT
|
|
5190
|
+
};
|
|
5191
|
+
|
|
5192
|
+
// scripts/init/hook-command-rewrite.ts
|
|
5193
|
+
var PNPM_JOSH_PREFIX = "pnpm josh ";
|
|
5194
|
+
var BUNDLE_INVOCATION = `node ${claude_plugin_config.MARKETPLACE_PATH}/dist/josh.js `;
|
|
5195
|
+
var RUN_HOOK_INVOCATION = `sh ${hook_launch.RUN_HOOK_SCRIPT} `;
|
|
5196
|
+
var CONSUMER_RUN_HOOK_INVOCATION = `sh ${claude_plugin_config.MARKETPLACE_PATH}/${hook_launch.RUN_HOOK_SCRIPT} `;
|
|
5197
|
+
var CONSUMER_PACKAGE_MANIFEST = `${claude_plugin_config.MARKETPLACE_PATH}/package.json`;
|
|
5198
|
+
var MISSING_INSTALL_NOTICE = "kit hooks inactive: run pnpm install, then reread CLAUDE.md";
|
|
5199
|
+
var MISSING_INSTALL_GUARD = `if [ ! -f ${CONSUMER_PACKAGE_MANIFEST} ]; then echo '${MISSING_INSTALL_NOTICE}' >&2; exit 0; fi; `;
|
|
5200
|
+
var PLAIN_KIT_COMMANDS = new Set(
|
|
5201
|
+
[
|
|
5202
|
+
"audit:provision",
|
|
5203
|
+
"batch:guard",
|
|
5204
|
+
"format:edited",
|
|
5205
|
+
"investigation:guard",
|
|
5206
|
+
"rule:guard",
|
|
5207
|
+
"session:lang"
|
|
5208
|
+
].map((command) => `${PNPM_JOSH_PREFIX}${command}`)
|
|
5209
|
+
);
|
|
5210
|
+
var PROJECT_ROOT_PREFIX2 = JSON.stringify(hook_launch.PROJECT_ROOT_PREFIX).slice(1, -1);
|
|
5211
|
+
|
|
5212
|
+
// scripts/init/security-policy.ts
|
|
5213
|
+
import path11 from "node:path";
|
|
5214
|
+
var SECURITY_MD = "SECURITY.md";
|
|
5215
|
+
var SECURITY_TEMPLATE = "templates/SECURITY.md";
|
|
5216
|
+
var REPOSITORY_PLACEHOLDER = "{{REPOSITORY}}";
|
|
5217
|
+
var KIT_ADVISORY_URL = "https://github.com/joshuafolkken/kit/security/advisories/new";
|
|
5218
|
+
var UNRESOLVED_REASON = "`origin` is not a GitHub repository `owner/repo` can be read from";
|
|
5219
|
+
var LINK_DELIMITER = /[\s()<>[\]]+/u;
|
|
5220
|
+
function repository_at(root) {
|
|
5221
|
+
const url = git_spawn_sync.origin_url(root);
|
|
5222
|
+
const identity = url === void 0 ? void 0 : repo_origin.parse_origin_url(url);
|
|
5223
|
+
return identity === void 0 ? void 0 : `${identity.owner}/${identity.repo}`;
|
|
5224
|
+
}
|
|
5225
|
+
function apply_repository(content, repository) {
|
|
5226
|
+
return content.replaceAll(REPOSITORY_PLACEHOLDER, () => repository);
|
|
5227
|
+
}
|
|
5228
|
+
function apply_repository_for_destination(destination_path, content) {
|
|
5229
|
+
if (path11.basename(destination_path) !== SECURITY_MD) return content;
|
|
5230
|
+
const repository = repository_at(path11.dirname(destination_path));
|
|
5231
|
+
if (repository === void 0) {
|
|
5232
|
+
throw new Error(`${SECURITY_MD} needs a GitHub origin to name the repository it reports to`);
|
|
5233
|
+
}
|
|
5234
|
+
return apply_repository(content, repository);
|
|
5235
|
+
}
|
|
5236
|
+
function does_report_to_kit(root) {
|
|
5237
|
+
const existing = file_reader.read_if_readable(path11.join(root, SECURITY_MD)) ?? "";
|
|
5238
|
+
return new Set(existing.split(LINK_DELIMITER)).has(KIT_ADVISORY_URL);
|
|
5239
|
+
}
|
|
5240
|
+
function unresolved_warning(root) {
|
|
5241
|
+
if (!does_report_to_kit(root)) return ` \u26A0 skipped ${SECURITY_MD} (${UNRESOLVED_REASON})`;
|
|
5242
|
+
return ` \u26A0 stale ${SECURITY_MD} still reports vulnerabilities to joshuafolkken/kit \u2014 replace it with your own policy or delete it (${UNRESOLVED_REASON})`;
|
|
5243
|
+
}
|
|
5244
|
+
function did_skip_unresolved(filename, root) {
|
|
5245
|
+
if (filename !== SECURITY_MD || repository_at(root) !== void 0) return false;
|
|
5246
|
+
console.warn(unresolved_warning(root));
|
|
5247
|
+
return true;
|
|
5248
|
+
}
|
|
5249
|
+
var security_policy = {
|
|
5250
|
+
SECURITY_MD,
|
|
5251
|
+
SECURITY_TEMPLATE,
|
|
5252
|
+
REPOSITORY_PLACEHOLDER,
|
|
5253
|
+
KIT_ADVISORY_URL,
|
|
5254
|
+
repository_at,
|
|
5255
|
+
apply_repository_for_destination,
|
|
5256
|
+
did_skip_unresolved
|
|
5257
|
+
};
|
|
5258
|
+
|
|
5259
|
+
// scripts/init/init-ai-copy.ts
|
|
5260
|
+
var WORKSPACE_YAML = "pnpm-workspace.yaml";
|
|
5261
|
+
var CLAUDE_MD_FILENAME = "CLAUDE.md";
|
|
5262
|
+
var PRETTIER_IGNORE = ".prettierignore";
|
|
5263
|
+
var GIT_ATTRIBUTES = ".gitattributes";
|
|
5264
|
+
var CODE_OF_CONDUCT = "CODE_OF_CONDUCT.md";
|
|
5265
|
+
var { SECURITY_MD: SECURITY_MD2 } = security_policy;
|
|
5266
|
+
var AGENTS_MD = "AGENTS.md";
|
|
5267
|
+
var GEMINI_MD = "GEMINI.md";
|
|
5268
|
+
var BASIC_AI_FILES = [
|
|
5269
|
+
AGENTS_MD,
|
|
5270
|
+
GEMINI_MD,
|
|
5271
|
+
PRETTIER_IGNORE,
|
|
5272
|
+
GIT_ATTRIBUTES,
|
|
5273
|
+
CODE_OF_CONDUCT,
|
|
5274
|
+
SECURITY_MD2,
|
|
5275
|
+
WORKSPACE_YAML
|
|
5276
|
+
];
|
|
5277
|
+
var BASIC_SOURCES = {
|
|
5278
|
+
[AGENTS_MD]: "templates/AGENTS.basic.md",
|
|
5279
|
+
[GEMINI_MD]: "templates/GEMINI.basic.md",
|
|
5280
|
+
[PRETTIER_IGNORE]: "templates/prettierignore.basic",
|
|
5281
|
+
[WORKSPACE_YAML]: "templates/pnpm-workspace.basic.yaml"
|
|
5282
|
+
};
|
|
5283
|
+
var CONSUMER_SOURCES = {
|
|
5284
|
+
[SECURITY_MD2]: security_policy.SECURITY_TEMPLATE
|
|
5285
|
+
};
|
|
5286
|
+
var BASIC_WORKFLOW_AI_FILES = [...BASIC_AI_FILES, ".claude/settings.json"];
|
|
5287
|
+
|
|
5288
|
+
// scripts/init/kit-written-paths.ts
|
|
5289
|
+
var MANIFEST_FILE = "package.json";
|
|
5290
|
+
var LOCKFILE = "pnpm-lock.yaml";
|
|
5291
|
+
var SETUP_ONLY_PATHS = /* @__PURE__ */ new Set([
|
|
5292
|
+
CLAUDE_MD_FILENAME,
|
|
5293
|
+
BASIC_PRETTIER_CONFIG,
|
|
5294
|
+
PROJECT_CONFIG_FILE,
|
|
5295
|
+
PACK_HOOK_FILE,
|
|
5296
|
+
MANIFEST_FILE,
|
|
5297
|
+
LOCKFILE
|
|
5298
|
+
]);
|
|
5299
|
+
function is_kit_written2(file_path) {
|
|
5300
|
+
return SETUP_ONLY_PATHS.has(file_path) || managed_config_scope.has_managed_path([file_path]);
|
|
5301
|
+
}
|
|
5302
|
+
function select(paths) {
|
|
5303
|
+
return paths.filter((file_path) => is_kit_written2(file_path));
|
|
5304
|
+
}
|
|
5305
|
+
var kit_written_paths = { is_kit_written: is_kit_written2, select };
|
|
5306
|
+
|
|
5307
|
+
// scripts/init/workflow-mark.ts
|
|
5308
|
+
var WORKFLOW_ENV = "JOSH_WORKFLOW";
|
|
5309
|
+
var GITHUB_WORKFLOW = "github";
|
|
5310
|
+
function is_requested(environment = process.env) {
|
|
5311
|
+
return environment[WORKFLOW_ENV] === GITHUB_WORKFLOW;
|
|
5312
|
+
}
|
|
5313
|
+
function is_recorded(manifest) {
|
|
5314
|
+
const josh = manifest?.["josh"];
|
|
5315
|
+
return json_value.is_record(josh) && josh["workflow"] === GITHUB_WORKFLOW;
|
|
5316
|
+
}
|
|
5317
|
+
function request(environment = process.env) {
|
|
5318
|
+
environment[WORKFLOW_ENV] = GITHUB_WORKFLOW;
|
|
5319
|
+
}
|
|
5320
|
+
function recorded_fields(has_workflow2) {
|
|
5321
|
+
return has_workflow2 ? { workflow: GITHUB_WORKFLOW } : {};
|
|
5322
|
+
}
|
|
5323
|
+
var workflow_mark = { is_requested, is_recorded, request, recorded_fields };
|
|
2843
5324
|
|
|
2844
5325
|
// scripts/init/project-profile.ts
|
|
2845
|
-
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync3 } from "node:fs";
|
|
2846
|
-
import path6 from "node:path";
|
|
2847
5326
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", "build", ".svelte-kit"]);
|
|
2848
5327
|
var WEB_EXTENSIONS = /* @__PURE__ */ new Set([".html", ".css", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
2849
5328
|
var TYPESCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx"]);
|
|
@@ -2875,9 +5354,9 @@ function requested_profile(args, usage = "josh init [--profile basic|full]") {
|
|
|
2875
5354
|
throw new Error("Profile must be basic or full");
|
|
2876
5355
|
}
|
|
2877
5356
|
function read_manifest(root) {
|
|
2878
|
-
const filename =
|
|
2879
|
-
if (!
|
|
2880
|
-
const parsed = JSON.parse(
|
|
5357
|
+
const filename = path12.join(root, "package.json");
|
|
5358
|
+
if (!existsSync6(filename)) return void 0;
|
|
5359
|
+
const parsed = JSON.parse(readFileSync5(filename, "utf8"));
|
|
2881
5360
|
if (!json_value.is_record(parsed)) throw new Error("package.json must contain an object");
|
|
2882
5361
|
return parsed;
|
|
2883
5362
|
}
|
|
@@ -2909,54 +5388,81 @@ function resolve_profile(root, requested) {
|
|
|
2909
5388
|
if (profile !== void 0) return { profile, reason: "package.json josh.profile" };
|
|
2910
5389
|
return inferred_profile(manifest);
|
|
2911
5390
|
}
|
|
5391
|
+
function is_ignored_directory(name) {
|
|
5392
|
+
return IGNORED_DIRECTORIES.has(name);
|
|
5393
|
+
}
|
|
2912
5394
|
function should_visit(entry) {
|
|
2913
|
-
return entry.isDirectory() && !
|
|
5395
|
+
return entry.isDirectory() && !is_ignored_directory(entry.name);
|
|
2914
5396
|
}
|
|
2915
5397
|
function scan_directory(directory, pending) {
|
|
2916
5398
|
const entries = readdirSync(directory, { withFileTypes: true });
|
|
2917
5399
|
pending.push(
|
|
2918
|
-
...entries.filter((entry) => should_visit(entry)).map((entry) =>
|
|
5400
|
+
...entries.filter((entry) => should_visit(entry)).map((entry) => path12.join(directory, entry.name))
|
|
2919
5401
|
);
|
|
2920
|
-
return entries.filter((entry) => entry.isFile()).map((entry) =>
|
|
5402
|
+
return entries.filter((entry) => entry.isFile()).map((entry) => path12.join(directory, entry.name));
|
|
2921
5403
|
}
|
|
2922
|
-
function
|
|
5404
|
+
function is_project_file(root, file) {
|
|
5405
|
+
const relative_path = path12.relative(root, file).split(path12.sep).join(path12.posix.sep);
|
|
5406
|
+
return !kit_written_paths.is_kit_written(relative_path);
|
|
5407
|
+
}
|
|
5408
|
+
function list_files(root) {
|
|
2923
5409
|
const pending = [root];
|
|
2924
|
-
const
|
|
5410
|
+
const files = [];
|
|
2925
5411
|
for (const directory of pending) {
|
|
2926
|
-
|
|
5412
|
+
files.push(...scan_directory(directory, pending));
|
|
2927
5413
|
}
|
|
2928
|
-
return
|
|
5414
|
+
return files;
|
|
5415
|
+
}
|
|
5416
|
+
function file_extensions(root) {
|
|
5417
|
+
return list_files(root).filter((file) => is_project_file(root, file)).map((file) => path12.extname(file));
|
|
2929
5418
|
}
|
|
2930
5419
|
function scan_files(root) {
|
|
2931
5420
|
const extensions = file_extensions(root);
|
|
2932
5421
|
const has_web = extensions.some((extension) => WEB_EXTENSIONS.has(extension));
|
|
5422
|
+
const should_use_prettier = has_web && own_formatter.find_config(root) === void 0;
|
|
2933
5423
|
const has_typescript = extensions.some((extension) => TYPESCRIPT_EXTENSIONS.has(extension));
|
|
2934
|
-
return {
|
|
5424
|
+
return { should_use_prettier, has_typescript };
|
|
2935
5425
|
}
|
|
2936
5426
|
function has_github_remote(root) {
|
|
2937
5427
|
const url = git_spawn_sync.origin_url(root);
|
|
2938
5428
|
return url !== void 0 && repo_origin.parse_origin_url(url) !== void 0;
|
|
2939
5429
|
}
|
|
5430
|
+
function has_git(root) {
|
|
5431
|
+
return existsSync6(path12.join(root, ".git"));
|
|
5432
|
+
}
|
|
5433
|
+
function has_workflow(root) {
|
|
5434
|
+
return workflow_mark.is_requested() || workflow_mark.is_recorded(read_manifest(root));
|
|
5435
|
+
}
|
|
2940
5436
|
function inspect_project(root, requested) {
|
|
2941
5437
|
const profile = resolve_profile(root, requested);
|
|
2942
5438
|
const files = scan_files(root);
|
|
2943
|
-
const
|
|
2944
|
-
return {
|
|
5439
|
+
const is_git = has_git(root);
|
|
5440
|
+
return {
|
|
5441
|
+
...profile,
|
|
5442
|
+
...files,
|
|
5443
|
+
has_git: is_git,
|
|
5444
|
+
has_github: is_git && has_github_remote(root),
|
|
5445
|
+
has_workflow: has_workflow(root)
|
|
5446
|
+
};
|
|
2945
5447
|
}
|
|
2946
5448
|
var project_profile = {
|
|
2947
5449
|
parse_profile,
|
|
2948
5450
|
resolve_profile,
|
|
5451
|
+
has_git,
|
|
2949
5452
|
inspect_project,
|
|
5453
|
+
is_ignored_directory,
|
|
5454
|
+
list_files,
|
|
2950
5455
|
requested_profile,
|
|
2951
5456
|
with_legacy_profile_names
|
|
2952
5457
|
};
|
|
2953
5458
|
|
|
2954
5459
|
// scripts/test/skip-marker.ts
|
|
2955
5460
|
var SKIP_MARKER = "\u2014 skipping";
|
|
5461
|
+
var NOT_USED_MARKER = "which this project does not use";
|
|
2956
5462
|
|
|
2957
5463
|
// scripts/gate/project-checks.ts
|
|
2958
|
-
import { z as
|
|
2959
|
-
var
|
|
5464
|
+
import { z as z13 } from "zod";
|
|
5465
|
+
var PACKAGE_JSON2 = "package.json";
|
|
2960
5466
|
var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
2961
5467
|
"node_modules",
|
|
2962
5468
|
".git",
|
|
@@ -2990,11 +5496,11 @@ var CSPELL_CONFIGS = [
|
|
|
2990
5496
|
];
|
|
2991
5497
|
var TYPE_CONFIGS = ["tsconfig.json", "jsconfig.json"];
|
|
2992
5498
|
var DEPENDENCY_FIELDS = ["dependencies", "devDependencies"];
|
|
2993
|
-
var object_schema =
|
|
5499
|
+
var object_schema = z13.record(z13.string(), z13.unknown());
|
|
2994
5500
|
function project_root(directory) {
|
|
2995
5501
|
return ancestor_directories.nearest(
|
|
2996
5502
|
directory,
|
|
2997
|
-
(candidate) =>
|
|
5503
|
+
(candidate) => existsSync7(path13.join(candidate, PACKAGE_JSON2))
|
|
2998
5504
|
) ?? directory;
|
|
2999
5505
|
}
|
|
3000
5506
|
function is_kit_repository(directory) {
|
|
@@ -3007,7 +5513,7 @@ function has_files(directory, pattern) {
|
|
|
3007
5513
|
return globSync2(pattern, { cwd: project_root(directory), exclude: is_ignored }).length > 0;
|
|
3008
5514
|
}
|
|
3009
5515
|
function has_config(directory, names) {
|
|
3010
|
-
return names.some((name) =>
|
|
5516
|
+
return names.some((name) => existsSync7(path13.join(project_root(directory), name)));
|
|
3011
5517
|
}
|
|
3012
5518
|
function has_bin(directory, bin_name) {
|
|
3013
5519
|
return find_local_bin_upwards(directory, bin_name) !== void 0;
|
|
@@ -3022,8 +5528,8 @@ function is_basic_manifest(manifest) {
|
|
|
3022
5528
|
}
|
|
3023
5529
|
function read_manifest2(directory) {
|
|
3024
5530
|
try {
|
|
3025
|
-
const manifest_path =
|
|
3026
|
-
return json_value.parse_or_undefined(
|
|
5531
|
+
const manifest_path = path13.join(project_root(directory), PACKAGE_JSON2);
|
|
5532
|
+
return json_value.parse_or_undefined(readFileSync6(manifest_path, "utf8"));
|
|
3027
5533
|
} catch {
|
|
3028
5534
|
return void 0;
|
|
3029
5535
|
}
|
|
@@ -3031,7 +5537,7 @@ function read_manifest2(directory) {
|
|
|
3031
5537
|
function is_basic(directory) {
|
|
3032
5538
|
return is_basic_manifest(read_manifest2(directory));
|
|
3033
5539
|
}
|
|
3034
|
-
function
|
|
5540
|
+
function is_declared2(directory, package_name) {
|
|
3035
5541
|
const manifest = object_schema.safeParse(read_manifest2(directory));
|
|
3036
5542
|
if (!manifest.success) return false;
|
|
3037
5543
|
return DEPENDENCY_FIELDS.some((field) => {
|
|
@@ -3040,11 +5546,14 @@ function is_declared(directory, package_name) {
|
|
|
3040
5546
|
});
|
|
3041
5547
|
}
|
|
3042
5548
|
function missing_tool_reason(directory, package_name, bin_name) {
|
|
3043
|
-
if (has_bin(directory, bin_name) ||
|
|
5549
|
+
if (has_bin(directory, bin_name) || is_declared2(directory, package_name)) return void 0;
|
|
3044
5550
|
return `${package_name} is not installed`;
|
|
3045
5551
|
}
|
|
3046
|
-
function skip_notice(
|
|
3047
|
-
return `josh ${
|
|
5552
|
+
function skip_notice(check5, reason) {
|
|
5553
|
+
return `josh ${check5}: ${reason} ${SKIP_MARKER} ${check5}, ${NOT_USED_MARKER}.`;
|
|
5554
|
+
}
|
|
5555
|
+
function ran_notice(check5) {
|
|
5556
|
+
return `josh ${check5}: ran and reported no problems.`;
|
|
3048
5557
|
}
|
|
3049
5558
|
function type_check_skip_reason(directory) {
|
|
3050
5559
|
if (!is_basic(directory)) return void 0;
|
|
@@ -3054,6 +5563,8 @@ function type_check_skip_reason(directory) {
|
|
|
3054
5563
|
}
|
|
3055
5564
|
function prettier_skip_reason(directory) {
|
|
3056
5565
|
if (!is_basic(directory)) return void 0;
|
|
5566
|
+
const formatter = own_formatter.find_config(project_root(directory));
|
|
5567
|
+
if (formatter !== void 0) return `${formatter} configures the project's own formatter`;
|
|
3057
5568
|
if (!has_files(directory, WEB_FILES)) return "no HTML, CSS or JavaScript files were found";
|
|
3058
5569
|
return missing_tool_reason(directory, "prettier", "prettier");
|
|
3059
5570
|
}
|
|
@@ -3076,6 +5587,8 @@ var project_checks = {
|
|
|
3076
5587
|
is_kit_repository,
|
|
3077
5588
|
prettier_skip_reason,
|
|
3078
5589
|
project_root,
|
|
5590
|
+
ran_notice,
|
|
5591
|
+
read_manifest: read_manifest2,
|
|
3079
5592
|
skip_notice,
|
|
3080
5593
|
type_check_skip_reason
|
|
3081
5594
|
};
|
|
@@ -3104,40 +5617,40 @@ var BASIC_REQUIRED_SUFFIXES = [
|
|
|
3104
5617
|
".toml"
|
|
3105
5618
|
];
|
|
3106
5619
|
function normalize(paths) {
|
|
3107
|
-
return paths.map((
|
|
5620
|
+
return paths.map((path16) => path16.trim()).filter((path16) => path16 !== "");
|
|
3108
5621
|
}
|
|
3109
|
-
function is_test_file(
|
|
3110
|
-
return TEST_SUFFIXES.some((suffix) =>
|
|
5622
|
+
function is_test_file(path16) {
|
|
5623
|
+
return TEST_SUFFIXES.some((suffix) => path16.endsWith(suffix));
|
|
3111
5624
|
}
|
|
3112
|
-
function is_basic_manual(
|
|
3113
|
-
const lower =
|
|
5625
|
+
function is_basic_manual(path16, is_basic2) {
|
|
5626
|
+
const lower = path16.toLowerCase();
|
|
3114
5627
|
return is_basic2 && BASIC_REQUIRED_SUFFIXES.every((suffix) => !lower.endsWith(suffix));
|
|
3115
5628
|
}
|
|
3116
|
-
function is_basic_visual(
|
|
3117
|
-
const lower =
|
|
5629
|
+
function is_basic_visual(path16) {
|
|
5630
|
+
const lower = path16.toLowerCase();
|
|
3118
5631
|
return BASIC_VISUAL_SUFFIXES.some((suffix) => lower.endsWith(suffix));
|
|
3119
5632
|
}
|
|
3120
|
-
function is_exempt(
|
|
3121
|
-
if (EXEMPT_PATHS.includes(
|
|
3122
|
-
return EXEMPT_SUFFIXES.some((suffix) =>
|
|
5633
|
+
function is_exempt(path16, is_basic2 = false) {
|
|
5634
|
+
if (EXEMPT_PATHS.includes(path16) || is_basic_manual(path16, is_basic2)) return true;
|
|
5635
|
+
return EXEMPT_SUFFIXES.some((suffix) => path16.endsWith(suffix)) || EXEMPT_PREFIXES.some((prefix) => path16.startsWith(prefix));
|
|
3123
5636
|
}
|
|
3124
|
-
function is_runtime(
|
|
3125
|
-
return !is_test_file(
|
|
5637
|
+
function is_runtime(path16, is_basic2 = false) {
|
|
5638
|
+
return !is_test_file(path16) && !is_exempt(path16, is_basic2);
|
|
3126
5639
|
}
|
|
3127
|
-
function
|
|
5640
|
+
function verdict_for2(paths, is_basic2 = false) {
|
|
3128
5641
|
const changed = normalize(paths);
|
|
3129
|
-
if (changed.some((
|
|
3130
|
-
if (changed.some((
|
|
5642
|
+
if (changed.some((path16) => is_test_file(path16))) return "satisfied";
|
|
5643
|
+
if (changed.some((path16) => is_runtime(path16, is_basic2))) return "required";
|
|
3131
5644
|
return "exempt";
|
|
3132
5645
|
}
|
|
3133
5646
|
function runtime_files(paths, is_basic2 = false) {
|
|
3134
|
-
return normalize(paths).filter((
|
|
5647
|
+
return normalize(paths).filter((path16) => is_runtime(path16, is_basic2));
|
|
3135
5648
|
}
|
|
3136
5649
|
function exempt_files(paths, is_basic2 = false) {
|
|
3137
|
-
return normalize(paths).filter((
|
|
5650
|
+
return normalize(paths).filter((path16) => is_exempt(path16, is_basic2));
|
|
3138
5651
|
}
|
|
3139
5652
|
function manual_check_files(paths, is_basic2) {
|
|
3140
|
-
return normalize(paths).filter((
|
|
5653
|
+
return normalize(paths).filter((path16) => is_exempt(path16, is_basic2) && !is_exempt(path16));
|
|
3141
5654
|
}
|
|
3142
5655
|
var test_declared_logic = {
|
|
3143
5656
|
EXEMPT_PATHS,
|
|
@@ -3150,7 +5663,7 @@ var test_declared_logic = {
|
|
|
3150
5663
|
is_test_file,
|
|
3151
5664
|
manual_check_files,
|
|
3152
5665
|
runtime_files,
|
|
3153
|
-
verdict_for
|
|
5666
|
+
verdict_for: verdict_for2
|
|
3154
5667
|
};
|
|
3155
5668
|
|
|
3156
5669
|
// scripts/test/test-declared-changed.ts
|
|
@@ -3492,30 +6005,30 @@ var epic_busy = {
|
|
|
3492
6005
|
};
|
|
3493
6006
|
|
|
3494
6007
|
// scripts/run/run-liveness.ts
|
|
3495
|
-
import { readFileSync as
|
|
6008
|
+
import { readFileSync as readFileSync7, realpathSync, statSync } from "node:fs";
|
|
3496
6009
|
import { homedir, tmpdir } from "node:os";
|
|
3497
|
-
import
|
|
6010
|
+
import path14 from "node:path";
|
|
3498
6011
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
3499
6012
|
|
|
3500
6013
|
// scripts/agent/agent-event.ts
|
|
3501
|
-
import { z as
|
|
6014
|
+
import { z as z15 } from "zod";
|
|
3502
6015
|
|
|
3503
6016
|
// scripts/agent/claude-result-event.ts
|
|
3504
|
-
import { z as
|
|
3505
|
-
var RESULT_EVENT_SCHEMA =
|
|
3506
|
-
type:
|
|
3507
|
-
is_error:
|
|
3508
|
-
subtype:
|
|
3509
|
-
num_turns:
|
|
3510
|
-
permission_denials:
|
|
3511
|
-
result:
|
|
3512
|
-
session_id:
|
|
3513
|
-
usage:
|
|
6017
|
+
import { z as z14 } from "zod";
|
|
6018
|
+
var RESULT_EVENT_SCHEMA = z14.looseObject({
|
|
6019
|
+
type: z14.literal("result"),
|
|
6020
|
+
is_error: z14.unknown().optional(),
|
|
6021
|
+
subtype: z14.unknown().optional(),
|
|
6022
|
+
num_turns: z14.unknown().optional(),
|
|
6023
|
+
permission_denials: z14.unknown().optional(),
|
|
6024
|
+
result: z14.unknown().optional(),
|
|
6025
|
+
session_id: z14.unknown().optional(),
|
|
6026
|
+
usage: z14.unknown().optional()
|
|
3514
6027
|
});
|
|
3515
|
-
var USAGE_SCHEMA =
|
|
3516
|
-
input_tokens:
|
|
3517
|
-
cache_read_input_tokens:
|
|
3518
|
-
output_tokens:
|
|
6028
|
+
var USAGE_SCHEMA = z14.looseObject({
|
|
6029
|
+
input_tokens: z14.unknown().optional(),
|
|
6030
|
+
cache_read_input_tokens: z14.unknown().optional(),
|
|
6031
|
+
output_tokens: z14.unknown().optional()
|
|
3519
6032
|
});
|
|
3520
6033
|
function usable_reason(value) {
|
|
3521
6034
|
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
@@ -3554,31 +6067,31 @@ function decode(value) {
|
|
|
3554
6067
|
var claude_result_event = { decode };
|
|
3555
6068
|
|
|
3556
6069
|
// scripts/agent/agent-event.ts
|
|
3557
|
-
var TEXT_BLOCK_SCHEMA =
|
|
3558
|
-
var CLAUDE_MESSAGE_SCHEMA =
|
|
3559
|
-
var CLAUDE_INIT_SCHEMA =
|
|
3560
|
-
var CLAUDE_ASSISTANT_SCHEMA =
|
|
3561
|
-
type:
|
|
6070
|
+
var TEXT_BLOCK_SCHEMA = z15.looseObject({ type: z15.literal("text"), text: z15.string() });
|
|
6071
|
+
var CLAUDE_MESSAGE_SCHEMA = z15.looseObject({ content: z15.array(z15.unknown()).optional() });
|
|
6072
|
+
var CLAUDE_INIT_SCHEMA = z15.looseObject({ type: z15.literal("system"), subtype: z15.literal("init") });
|
|
6073
|
+
var CLAUDE_ASSISTANT_SCHEMA = z15.looseObject({
|
|
6074
|
+
type: z15.literal("assistant"),
|
|
3562
6075
|
message: CLAUDE_MESSAGE_SCHEMA
|
|
3563
6076
|
});
|
|
3564
|
-
var USAGE_SCHEMA2 =
|
|
3565
|
-
input_tokens:
|
|
3566
|
-
cached_input_tokens:
|
|
3567
|
-
output_tokens:
|
|
6077
|
+
var USAGE_SCHEMA2 = z15.looseObject({
|
|
6078
|
+
input_tokens: z15.number().optional(),
|
|
6079
|
+
cached_input_tokens: z15.number().optional(),
|
|
6080
|
+
output_tokens: z15.number().optional()
|
|
3568
6081
|
});
|
|
3569
|
-
var CODEX_START_SCHEMA =
|
|
3570
|
-
var CODEX_PROGRESS_SCHEMA =
|
|
3571
|
-
type:
|
|
3572
|
-
item:
|
|
6082
|
+
var CODEX_START_SCHEMA = z15.looseObject({ type: z15.enum(["thread.started", "turn.started"]) });
|
|
6083
|
+
var CODEX_PROGRESS_SCHEMA = z15.looseObject({
|
|
6084
|
+
type: z15.enum(["item.started", "item.updated", "item.completed"]),
|
|
6085
|
+
item: z15.looseObject({ type: z15.string(), text: z15.string().optional() }).optional()
|
|
3573
6086
|
});
|
|
3574
|
-
var CODEX_COMPLETE_SCHEMA =
|
|
3575
|
-
type:
|
|
6087
|
+
var CODEX_COMPLETE_SCHEMA = z15.looseObject({
|
|
6088
|
+
type: z15.literal("turn.completed"),
|
|
3576
6089
|
usage: USAGE_SCHEMA2.optional()
|
|
3577
6090
|
});
|
|
3578
|
-
var CODEX_FAILURE_SCHEMA =
|
|
3579
|
-
type:
|
|
3580
|
-
error:
|
|
3581
|
-
message:
|
|
6091
|
+
var CODEX_FAILURE_SCHEMA = z15.looseObject({
|
|
6092
|
+
type: z15.enum(["turn.failed", "error"]),
|
|
6093
|
+
error: z15.looseObject({ message: z15.string().optional() }).optional(),
|
|
6094
|
+
message: z15.string().optional()
|
|
3582
6095
|
});
|
|
3583
6096
|
var EMPTY_STATE = {
|
|
3584
6097
|
provider: void 0,
|
|
@@ -3669,7 +6182,7 @@ function describe(state) {
|
|
|
3669
6182
|
var agent_event = { describe, read };
|
|
3670
6183
|
|
|
3671
6184
|
// scripts/issue/issue-state.ts
|
|
3672
|
-
import { z as
|
|
6185
|
+
import { z as z16 } from "zod";
|
|
3673
6186
|
var NO_LABELS = "(none)";
|
|
3674
6187
|
var LABEL_SEPARATOR = ", ";
|
|
3675
6188
|
var STATE_LABEL = "state: ";
|
|
@@ -3679,9 +6192,9 @@ var YES = "yes";
|
|
|
3679
6192
|
var NO = "no";
|
|
3680
6193
|
var ISSUE_LABEL = "issue: ";
|
|
3681
6194
|
var HUMAN_REVIEW_LABELS = /* @__PURE__ */ new Set([NEEDS_HUMAN_REVIEW_LABEL]);
|
|
3682
|
-
var label_schema =
|
|
3683
|
-
var issue_state_schema =
|
|
3684
|
-
state:
|
|
6195
|
+
var label_schema = z16.looseObject({ name: z16.string() });
|
|
6196
|
+
var issue_state_schema = z16.looseObject({
|
|
6197
|
+
state: z16.string(),
|
|
3685
6198
|
labels: label_schema.array().optional()
|
|
3686
6199
|
});
|
|
3687
6200
|
function parse_issue_state(json) {
|
|
@@ -3798,12 +6311,12 @@ var ALLOWED_ROOTS = [
|
|
|
3798
6311
|
)
|
|
3799
6312
|
];
|
|
3800
6313
|
function is_within(candidate, root) {
|
|
3801
|
-
const relative =
|
|
3802
|
-
return relative !== "" && !relative.startsWith("..") && !
|
|
6314
|
+
const relative = path14.relative(root, candidate);
|
|
6315
|
+
return relative !== "" && !relative.startsWith("..") && !path14.isAbsolute(relative);
|
|
3803
6316
|
}
|
|
3804
6317
|
function to_safe_path(output_path) {
|
|
3805
|
-
const normalized2 =
|
|
3806
|
-
if (!
|
|
6318
|
+
const normalized2 = path14.normalize(output_path);
|
|
6319
|
+
if (!path14.isAbsolute(normalized2)) return void 0;
|
|
3807
6320
|
return ALLOWED_ROOTS.some((root) => is_within(normalized2, root)) ? normalized2 : void 0;
|
|
3808
6321
|
}
|
|
3809
6322
|
function sample_output(output_path) {
|
|
@@ -3817,7 +6330,7 @@ function read_agent_state(output_path) {
|
|
|
3817
6330
|
const safe_path = to_safe_path(output_path);
|
|
3818
6331
|
if (safe_path === void 0) return void 0;
|
|
3819
6332
|
try {
|
|
3820
|
-
const state = agent_event.read(
|
|
6333
|
+
const state = agent_event.read(readFileSync7(safe_path, "utf8"));
|
|
3821
6334
|
return state.provider === void 0 ? void 0 : state;
|
|
3822
6335
|
} catch {
|
|
3823
6336
|
return void 0;
|
|
@@ -3827,12 +6340,12 @@ function describe_agent_state(output_path) {
|
|
|
3827
6340
|
const state = read_agent_state(output_path);
|
|
3828
6341
|
return state === void 0 ? void 0 : `agent: ${state.provider ?? "unknown"} ${agent_event.describe(state)}`;
|
|
3829
6342
|
}
|
|
3830
|
-
async function read_output_frozen(
|
|
3831
|
-
const first = sample_output(
|
|
6343
|
+
async function read_output_frozen(request2) {
|
|
6344
|
+
const first = sample_output(request2.output_path);
|
|
3832
6345
|
if (first === void 0) return void 0;
|
|
3833
|
-
if (
|
|
3834
|
-
await sleep(
|
|
3835
|
-
const second = sample_output(
|
|
6346
|
+
if (request2.now_ms - first.mtime_ms < request2.silent_window_ms) return false;
|
|
6347
|
+
await sleep(request2.gap_ms);
|
|
6348
|
+
const second = sample_output(request2.output_path);
|
|
3836
6349
|
if (second === void 0) return void 0;
|
|
3837
6350
|
return second.mtime_ms === first.mtime_ms && second.size === first.size;
|
|
3838
6351
|
}
|
|
@@ -3850,34 +6363,34 @@ async function read_child_settled(issue, repo) {
|
|
|
3850
6363
|
if (state === void 0) return void 0;
|
|
3851
6364
|
return state.state !== OPEN_STATE || carries_settled_label(state.labels);
|
|
3852
6365
|
}
|
|
3853
|
-
async function read_traces(
|
|
6366
|
+
async function read_traces(request2) {
|
|
3854
6367
|
const [is_initial_child_settled, is_output_frozen, is_tree_dirty] = await Promise.all([
|
|
3855
|
-
read_child_settled(
|
|
6368
|
+
read_child_settled(request2.issue, request2.repo),
|
|
3856
6369
|
read_output_frozen({
|
|
3857
|
-
gap_ms:
|
|
6370
|
+
gap_ms: request2.gap_ms ?? DEFAULT_GAP_SECONDS * MS_PER_SECOND2,
|
|
3858
6371
|
now_ms: Date.now(),
|
|
3859
|
-
output_path:
|
|
3860
|
-
silent_window_ms:
|
|
6372
|
+
output_path: request2.output_path,
|
|
6373
|
+
silent_window_ms: request2.silent_window_ms ?? DEFAULT_SILENT_MINUTES * MS_PER_MINUTE3
|
|
3861
6374
|
}),
|
|
3862
6375
|
run_hold.is_tree_dirty()
|
|
3863
6376
|
]);
|
|
3864
|
-
const agent_state = read_agent_state(
|
|
3865
|
-
const is_latest_child_settled = is_agent_state_finished(agent_state) ? await read_child_settled(
|
|
6377
|
+
const agent_state = read_agent_state(request2.output_path);
|
|
6378
|
+
const is_latest_child_settled = is_agent_state_finished(agent_state) ? await read_child_settled(request2.issue, request2.repo) : void 0;
|
|
3866
6379
|
const is_child_settled = is_latest_child_settled ?? is_initial_child_settled;
|
|
3867
6380
|
return {
|
|
3868
6381
|
agent_state,
|
|
3869
6382
|
is_child_settled,
|
|
3870
6383
|
is_output_frozen,
|
|
3871
6384
|
is_tree_dirty,
|
|
3872
|
-
process_trace:
|
|
6385
|
+
process_trace: request2.process_trace
|
|
3873
6386
|
};
|
|
3874
6387
|
}
|
|
3875
|
-
async function
|
|
3876
|
-
issue_number_shape.require_issue_number(
|
|
3877
|
-
return decide5(await read_traces(
|
|
6388
|
+
async function check2(request2) {
|
|
6389
|
+
issue_number_shape.require_issue_number(request2.issue);
|
|
6390
|
+
return decide5(await read_traces(request2));
|
|
3878
6391
|
}
|
|
3879
6392
|
var run_liveness = {
|
|
3880
|
-
check,
|
|
6393
|
+
check: check2,
|
|
3881
6394
|
decide: decide5,
|
|
3882
6395
|
describe_agent_state,
|
|
3883
6396
|
read_child_settled,
|
|
@@ -3949,7 +6462,7 @@ var lane_report = {
|
|
|
3949
6462
|
};
|
|
3950
6463
|
|
|
3951
6464
|
// scripts/run/run-preflight.ts
|
|
3952
|
-
import { z as
|
|
6465
|
+
import { z as z17 } from "zod";
|
|
3953
6466
|
var CLEAN_VERDICT = "clean";
|
|
3954
6467
|
var RECLAIM_VERDICT = "reclaim";
|
|
3955
6468
|
var RESUME_VERDICT = "resume";
|
|
@@ -3959,7 +6472,7 @@ var OPEN_PR = "open";
|
|
|
3959
6472
|
var MERGED_PR = "merged";
|
|
3960
6473
|
var CLOSED_PR = "closed";
|
|
3961
6474
|
var NO_CHILD_WORK = { branch_name: void 0, pr_state: NO_PR };
|
|
3962
|
-
var pr_info_schema =
|
|
6475
|
+
var pr_info_schema = z17.object({ state: z17.string().optional() });
|
|
3963
6476
|
var GH_PR_STATES = /* @__PURE__ */ new Map([
|
|
3964
6477
|
["CLOSED", CLOSED_PR],
|
|
3965
6478
|
["MERGED", MERGED_PR],
|
|
@@ -4122,7 +6635,7 @@ async function read_child_state(issue) {
|
|
|
4122
6635
|
);
|
|
4123
6636
|
return pick_child_state(reads.filter((read2) => read2 !== void 0));
|
|
4124
6637
|
}
|
|
4125
|
-
async function
|
|
6638
|
+
async function check3(issue) {
|
|
4126
6639
|
require_issue_number(issue);
|
|
4127
6640
|
const tree = await read_tree_state();
|
|
4128
6641
|
if (needs_reclaim(tree)) return decide6(tree, NO_CHILD_WORK, issue);
|
|
@@ -4133,7 +6646,7 @@ var run_preflight = {
|
|
|
4133
6646
|
RESUME_ADVICE,
|
|
4134
6647
|
MERGED_PR,
|
|
4135
6648
|
STASH_LABEL_PREFIX,
|
|
4136
|
-
check:
|
|
6649
|
+
check: check3,
|
|
4137
6650
|
decide: decide6,
|
|
4138
6651
|
read_child_state,
|
|
4139
6652
|
read_pr_state,
|
|
@@ -4204,16 +6717,16 @@ async function has_run_record() {
|
|
|
4204
6717
|
async function has_run_started(lanes) {
|
|
4205
6718
|
return lanes.length > 0 || await has_run_record();
|
|
4206
6719
|
}
|
|
4207
|
-
async function read_observations(
|
|
4208
|
-
const [children, lanes] = await Promise.all([read_children(
|
|
6720
|
+
async function read_observations(request2) {
|
|
6721
|
+
const [children, lanes] = await Promise.all([read_children(request2.repo), read_lanes()]);
|
|
4209
6722
|
if (children === void 0) return UNREADABLE_READ;
|
|
4210
6723
|
if (children.length === 0 && !await has_run_started(lanes)) return IDLE_READ;
|
|
4211
6724
|
const observations = {
|
|
4212
|
-
repo:
|
|
6725
|
+
repo: request2.repo,
|
|
4213
6726
|
children,
|
|
4214
6727
|
lanes,
|
|
4215
6728
|
load_average: loadavg()[FIRST_LOAD_AVERAGE] ?? 0,
|
|
4216
|
-
record_age_ms: read_record_age(
|
|
6729
|
+
record_age_ms: read_record_age(request2.output_paths, request2.now_ms)
|
|
4217
6730
|
};
|
|
4218
6731
|
return { kind: "observed", observations };
|
|
4219
6732
|
}
|
|
@@ -4232,7 +6745,7 @@ var run_progress_read = {
|
|
|
4232
6745
|
};
|
|
4233
6746
|
|
|
4234
6747
|
// scripts/run/run-watcher-hook.ts
|
|
4235
|
-
import { z as
|
|
6748
|
+
import { z as z18 } from "zod";
|
|
4236
6749
|
|
|
4237
6750
|
// scripts/run/run-watcher-guard.ts
|
|
4238
6751
|
var WATCHER_TICK_MS = 3e4;
|
|
@@ -4246,7 +6759,7 @@ async function owes_watcher() {
|
|
|
4246
6759
|
if (run_headless.is_headless() || !await run_headless.is_backlog_parent()) return false;
|
|
4247
6760
|
return await lane_registry.has_lanes_in_flight();
|
|
4248
6761
|
}
|
|
4249
|
-
async function
|
|
6762
|
+
async function check4(life_target) {
|
|
4250
6763
|
if (!await owes_watcher()) return OK_RESULT;
|
|
4251
6764
|
if (run_progress_clock.is_life_fresh(life_target, STALE_THRESHOLD_MS)) return OK_RESULT;
|
|
4252
6765
|
return { kind: "stale", note: STALE_NOTE };
|
|
@@ -4254,13 +6767,13 @@ async function check3(life_target) {
|
|
|
4254
6767
|
var run_watcher_guard = {
|
|
4255
6768
|
STALE_NOTE,
|
|
4256
6769
|
STALE_THRESHOLD_MS,
|
|
4257
|
-
check:
|
|
6770
|
+
check: check4
|
|
4258
6771
|
};
|
|
4259
6772
|
|
|
4260
6773
|
// scripts/run/run-watcher-hook.ts
|
|
4261
6774
|
var SWITCH_ENV_KEY2 = "JOSH_WATCHER_GUARD";
|
|
4262
6775
|
var STAMP_PREFIX2 = "josh-watcher-guard-";
|
|
4263
|
-
var payload_schema =
|
|
6776
|
+
var payload_schema = z18.object({ transcript_path: z18.string().min(1) });
|
|
4264
6777
|
function transcript_of(raw_payload) {
|
|
4265
6778
|
return json_value.parse_with(raw_payload, payload_schema)?.transcript_path;
|
|
4266
6779
|
}
|
|
@@ -4298,7 +6811,7 @@ function current_state3() {
|
|
|
4298
6811
|
}
|
|
4299
6812
|
var THRESHOLD_TEXT2 = `${cost_format.format_tokens(CONTEXT_CUT_THRESHOLD)}-token`;
|
|
4300
6813
|
var PARENT_CUT_REASON = `\u26D4 backlogrun parent hand-off: this session drives a \`backlogrun\` (it owns the live carry record) and its recent-context cost has crossed the shared ${THRESHOLD_TEXT2} threshold between merges, so every later request re-reads the accumulated context (joshuafolkken/kit#2947). Take the hand-off now rather than at the next merge: follow \`.claude/skills/workflow-commands/backlogrun-progress.md\` \u2192 "The hand-off" from its \`over\` branch \u2014 open no new lane and take no new child, read \`pnpm josh lane:list\`, make sure every lane in flight records an output path, then run \`pnpm josh run:carry --cut --owner "$PPID"\` and, unless it answers \`capped\`, \`pnpm josh run:wake\`, post the progress comment and end the turn. A lane nobody can poll means the cut does not happen; carry on and this asks again later. Reissue this call when the hand-off is done or cannot be taken \u2014 the guard stays quiet for a while after it refuses, so the hand-off calls themselves are not refused.`;
|
|
4301
|
-
async function
|
|
6814
|
+
async function is_due3(state) {
|
|
4302
6815
|
const carry = await state.carry();
|
|
4303
6816
|
if (carry === void 0 || run_headless.is_cut_capped(carry)) return false;
|
|
4304
6817
|
return state.verdict() === cost_verdict.OVER_VERDICT;
|
|
@@ -4310,7 +6823,7 @@ function is_quiet(target, now_ms) {
|
|
|
4310
6823
|
async function refusal_for(transcript, now_ms, state) {
|
|
4311
6824
|
const stamp = hook_decision.create_refusal_stamp(STAMP_PREFIX3);
|
|
4312
6825
|
const target = stamp.path(transcript);
|
|
4313
|
-
if (is_quiet(target, now_ms) || !await
|
|
6826
|
+
if (is_quiet(target, now_ms) || !await is_due3(state)) return void 0;
|
|
4314
6827
|
return stamp.record(target, now_ms) ? PARENT_CUT_REASON : void 0;
|
|
4315
6828
|
}
|
|
4316
6829
|
function is_unit_call(raw_payload) {
|
|
@@ -4338,7 +6851,7 @@ var run_parent_cut_hook = {
|
|
|
4338
6851
|
};
|
|
4339
6852
|
|
|
4340
6853
|
// scripts/hooks/step-zero-notice.ts
|
|
4341
|
-
import
|
|
6854
|
+
import path15 from "node:path";
|
|
4342
6855
|
var STAMP_PREFIX4 = "josh-step-zero-notice-";
|
|
4343
6856
|
var EDIT_TOOLS3 = /* @__PURE__ */ new Set(["Edit", "Write"]);
|
|
4344
6857
|
var PARENT_PREFIX = "..";
|
|
@@ -4353,9 +6866,9 @@ function edited_paths(tool_input) {
|
|
|
4353
6866
|
);
|
|
4354
6867
|
}
|
|
4355
6868
|
function is_runtime_file(file_path, root) {
|
|
4356
|
-
const relative =
|
|
4357
|
-
if (relative.startsWith(PARENT_PREFIX) ||
|
|
4358
|
-
return !test_declared_logic.is_exempt(relative.split(
|
|
6869
|
+
const relative = path15.relative(root, path15.resolve(root, file_path));
|
|
6870
|
+
if (relative.startsWith(PARENT_PREFIX) || path15.isAbsolute(relative)) return false;
|
|
6871
|
+
return !test_declared_logic.is_exempt(relative.split(path15.sep).join("/"));
|
|
4359
6872
|
}
|
|
4360
6873
|
function is_candidate2(raw_payload, root) {
|
|
4361
6874
|
const payload = hook_decision.parse_hook_payload(raw_payload);
|
|
@@ -4412,7 +6925,8 @@ async function mark_phase(outcome) {
|
|
|
4412
6925
|
}
|
|
4413
6926
|
async function async_reason(raw_payload) {
|
|
4414
6927
|
const watcher = await run_watcher_hook.watcher_hook_reason(raw_payload);
|
|
4415
|
-
|
|
6928
|
+
const cut = watcher ?? await run_parent_cut_hook.parent_cut_reason(raw_payload);
|
|
6929
|
+
return cut ?? await issue_watch_hook.watch_reason();
|
|
4416
6930
|
}
|
|
4417
6931
|
async function pretool_outcome_async(raw_payload) {
|
|
4418
6932
|
const base = guard_outcome(raw_payload);
|