@joshuafolkken/kit 1.887.0 → 1.929.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/workflow-commands/backlogrun-progress.md +13 -12
- package/.claude/skills/workflow-commands/backlogrun-steps.md +2 -1
- package/.claude/skills/workflow-commands/fullrun-steps.md +4 -2
- package/.claude/skills/workflow-commands/halfrun.md +3 -1
- package/.claude/skills/workflow-commands/kickoff.md +5 -3
- package/.claude/skills/workflow-commands/observation-filing.md +3 -1
- package/.claude/skills/workflow-commands/prerequisite.md +3 -1
- package/.claude/skills/workflow-commands/target-repository.md +1 -1
- package/.github/pull_request_template.md +12 -0
- package/.github/release.yml +3 -0
- package/.github/workflows/ci.yml +8 -0
- package/.github/workflows/production.yml +10 -1
- package/.github/workflows/publish.yml +72 -2
- package/CLAUDE.md +2 -0
- package/README.md +2 -1
- package/dist/CLAUDE.md +2 -0
- package/dist/CLAUDE.static.md +8 -0
- package/dist/hooks/batch-guard.js +6 -6
- package/dist/hooks/{chunk-264QY6KS.js → chunk-2PGRQ62K.js} +25 -10
- package/dist/hooks/chunk-3V37IID6.js +82 -0
- package/dist/hooks/{chunk-36UE53LS.js → chunk-7XQ6TK3R.js} +2 -2
- package/dist/hooks/{chunk-PRDCNGA6.js → chunk-BNFG2IFK.js} +4 -4
- package/dist/hooks/{chunk-VGYSA2NT.js → chunk-GQ3EVWHY.js} +22 -3
- package/dist/hooks/{chunk-Y5OYCU2F.js → chunk-I3JP3D4A.js} +3 -3
- package/dist/hooks/{chunk-6MQCXEEA.js → chunk-LCJZE42I.js} +25 -88
- package/dist/hooks/{chunk-ZBK4XRAS.js → chunk-NJZSO7BK.js} +3 -3
- package/dist/hooks/{chunk-SSX23SJ2.js → chunk-RKUAD3I6.js} +1 -0
- package/dist/hooks/{chunk-FRJKVSK3.js → chunk-ROULPSQC.js} +2 -2
- package/dist/hooks/{chunk-FNFOLFFV.js → chunk-SXPTRFPG.js} +2 -2
- package/dist/hooks/{chunk-FXAKJKTB.js → chunk-WPALEIRX.js} +1 -1
- package/dist/hooks/{chunk-4OXFU3MK.js → chunk-YO43HEPY.js} +634 -156
- package/dist/hooks/codex-hook-adapter.js +13 -12
- package/dist/hooks/duplicate-read-guard.js +7 -7
- package/dist/hooks/format-edited.js +4 -3
- package/dist/hooks/investigation-guard.js +7 -7
- package/dist/hooks/pretool-guard.js +12 -11
- package/dist/hooks/session-lang.js +2 -2
- package/dist/hooks/stop-guard.js +5 -5
- package/dist/josh.js +156 -20
- package/eslint/base.js +4 -1
- package/package.json +72 -18
- package/playwright.config.ts +9 -17
- package/ports/index.d.ts +1 -0
- package/ports/index.js +1 -0
- package/ports/web-server.d.ts +5 -0
- package/ports/web-server.js +73 -0
- package/prettier/index.js +3 -8
- package/prettier/static.d.ts +3 -0
- package/prettier/static.js +10 -0
- package/prompts/collaboration-workflow/issue-template.md +11 -4
- package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
- package/prompts/collaboration-workflow/wip-cap.md +2 -2
- package/prompts/review.md +2 -2
- package/prompts/testing-guide.md +1 -0
- package/scripts/agent/agent-role-profile.ts +11 -0
- package/scripts/build/build-claude-md.ts +6 -1
- package/scripts/ci/pr-classification.ts +114 -0
- package/scripts/document/document-byte-budget.ts +3 -2
- package/scripts/gate/gate-report.ts +2 -0
- package/scripts/gate/gate-steps.ts +50 -0
- package/scripts/gate/project-checks.ts +145 -0
- package/scripts/gate/verification-gate.ts +14 -43
- package/scripts/git/git-common-directory.ts +9 -1
- package/scripts/git/git-gh-pr-rollup.ts +29 -1
- package/scripts/git/git-gh-pr.ts +61 -1
- package/scripts/git/git-pr.ts +62 -13
- package/scripts/git/issue-labels.ts +9 -0
- package/scripts/init/distributed-paths.ts +9 -5
- package/scripts/init/hook-command-bootstrap.ts +40 -8
- package/scripts/init/hook-command-rewrite.ts +7 -3
- package/scripts/init/init-actions.ts +94 -7
- package/scripts/init/init-ai-copy.ts +107 -19
- package/scripts/init/init-logic-workspace.ts +38 -5
- package/scripts/init/init-logic.ts +1 -0
- package/scripts/init/init-static.ts +55 -0
- package/scripts/init/init.ts +97 -30
- package/scripts/init/project-profile-cli.ts +14 -0
- package/scripts/init/project-profile.ts +158 -0
- package/scripts/init/start.ts +30 -0
- package/scripts/issue/issue-bug-label.ts +13 -0
- package/scripts/issue/issue-classification.ts +74 -0
- package/scripts/issue/issue-lint-cli.ts +10 -3
- package/scripts/issue/markdown-section.ts +38 -4
- package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +27 -1
- package/scripts/josh/josh-command-map.ts +3 -0
- package/scripts/josh/josh-commands-development.ts +8 -15
- package/scripts/josh/josh-commands-project.ts +14 -1
- package/scripts/josh/josh-logic.ts +13 -0
- package/scripts/josh/run-github-prerequisite.ts +32 -0
- package/scripts/lane/lane-await.ts +8 -1
- package/scripts/lane/openai-lane-ship.ts +30 -0
- package/scripts/lane/openai-lane-supervisor.ts +35 -8
- package/scripts/lane/openai-review-broker.ts +260 -0
- package/scripts/lint/cspell-cached.ts +21 -0
- package/scripts/lint/format.ts +68 -0
- package/scripts/lint/lint-parallel.ts +30 -1
- package/scripts/observations/observations-flush.ts +1 -1
- package/scripts/package/production-dependency-graph.ts +68 -0
- package/scripts/package/verify-optional-eslint-install.ts +62 -0
- package/scripts/release/github-release-cli.ts +11 -0
- package/scripts/release/github-release.ts +220 -0
- package/scripts/release/publish-tag-cli.ts +8 -0
- package/scripts/release/publish-tag.ts +11 -0
- package/scripts/release/release-publish.ts +7 -2
- package/scripts/rules/delivered-rules.ts +2 -0
- package/scripts/rules/issue-bug-label.ts +85 -0
- package/scripts/rules/issue-filing-args.ts +50 -0
- package/scripts/run/run-merge-cli.ts +19 -0
- package/scripts/run/run-merge.ts +9 -1
- package/scripts/run/run-ship-cli.ts +20 -0
- package/scripts/run/run-ship-detach.ts +180 -14
- package/scripts/run/run-ship-review-steps.ts +45 -25
- package/scripts/run/run-step-cli.ts +11 -1
- package/scripts/run/run-step.ts +36 -8
- package/scripts/run/run-wake-session.ts +3 -1
- package/scripts/test/pilot-files.ts +0 -2
- package/scripts/test/skip-marker.ts +3 -0
- package/scripts/test/test-declared-changed.ts +2 -1
- package/scripts/test/test-declared-logic.ts +15 -10
- package/scripts/test/test-declared.ts +20 -8
- package/scripts/test/test-red-logic.ts +3 -3
- package/scripts/test/test-unit-guard.ts +24 -12
- package/templates/CLAUDE.static.md +8 -0
- package/templates/cursorrules.static +1 -0
- package/templates/pnpm-workspace.static.yaml +4 -0
- package/templates/prettierignore.static +12 -0
- package/templates/workflows/ci.yml +5 -0
|
@@ -213,7 +213,7 @@ single non-numeric line as the verdict.
|
|
|
213
213
|
`lane:await` watches local process presence and exits when any named child confirms-complete,
|
|
214
214
|
waking the parent at the actual completion rather than at the next heartbeat interval. **The
|
|
215
215
|
re-confirm delay and poll interval are the command's, not the agent's** — pass only the issue
|
|
216
|
-
numbers.
|
|
216
|
+
numbers. Without that wake (Codex), hand off instead — "A parent without a completion callback".
|
|
217
217
|
|
|
218
218
|
**A `lane:await` wake is a confirmed-gone process, so classify the ending at once — do not wait out
|
|
219
219
|
the silent-unit window** (joshuafolkken/kit#2277). `lane:await` exits only after the child's process
|
|
@@ -375,6 +375,11 @@ the check could not answer, and take `over`'s branch at that child.
|
|
|
375
375
|
only moment where **this** child's work is all written down: the PR is merged, the working tree is clean
|
|
376
376
|
on the default branch, and the epic's state on GitHub is complete.
|
|
377
377
|
|
|
378
|
+
### A parent without a completion callback hands off at its first dispatch
|
|
379
|
+
|
|
380
|
+
**A finished command never re-invokes a Codex parent, so after a dispatch `run:step` prints the `--cut`
|
|
381
|
+
below the cut cap, `wait` at it** (joshuafolkken/kit#2653): dispatch the wave, run it, end the turn.
|
|
382
|
+
|
|
378
383
|
### The lane child reuses this measurement mid-implementation
|
|
379
384
|
|
|
380
385
|
**The same `pnpm josh cost --over` measurement bounds a lane child's context _during_ implementation, not
|
|
@@ -534,20 +539,16 @@ to untangle**: `epic:next` detects it and exits with an error.
|
|
|
534
539
|
### The parent keeps no clock of its own — the watcher's exit is the wake
|
|
535
540
|
|
|
536
541
|
**After hand-off, the supervisor's driver owns the mechanical clock.** `backlog:drive` polls lane
|
|
537
|
-
completion and the backlog inside the detached process, without waking an AI parent
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
heartbeat lines, and `run:report` remains the final report source.
|
|
542
|
+
completion and the backlog inside the detached process, without waking an AI parent; the parent-turn
|
|
543
|
+
instructions below apply only to a returned judgment branch. `run:progress --wait` stays the heartbeat
|
|
544
|
+
source and `run:report` the final report.
|
|
541
545
|
|
|
542
|
-
**The numbers above are floors between asks, not a timer the parent sets
|
|
543
|
-
|
|
544
|
-
The watcher took the *reporting* out of the parent; the parent must not go on keeping the clock anyway,
|
|
545
|
-
or the two run side by side and the run pays for both.
|
|
546
|
+
**The numbers above are floors between asks, not a timer the parent sets** — one tick per turn, at the
|
|
547
|
+
largest context, is the cost `run:progress` removed.
|
|
546
548
|
|
|
547
549
|
The driver checks lane completion every five seconds and makes a new backlog offer no sooner than one
|
|
548
|
-
minute after the previous offer, except after collecting a child
|
|
549
|
-
|
|
550
|
-
exit as a prompt to act. The bounds above continue to apply to both processes.
|
|
550
|
+
minute after the previous offer, except after collecting a child — waits that cost no AI turns. The
|
|
551
|
+
watcher reports on its own interval, and a judgment session may take its exit as a prompt to act.
|
|
551
552
|
|
|
552
553
|
#### The wake exists only while something is in flight
|
|
553
554
|
|
|
@@ -535,7 +535,8 @@ ordinary way.
|
|
|
535
535
|
**So every cut is taken at a merge, which is what lets a resumed session state its own `--active`**: a
|
|
536
536
|
woken session picks the run up seconds after the merge the cut was taken at. The one shape that puts a
|
|
537
537
|
cut inside a watch — the backlog answering `exhausted` while this run's own children are still
|
|
538
|
-
merging — is the same, because the woken session has just merged a child.
|
|
538
|
+
merging — is the same, because the woken session has just merged a child. A Codex parent's cut is the one
|
|
539
|
+
taken at a dispatch instead (`backlogrun-progress.md` → "A parent without a completion callback").
|
|
539
540
|
|
|
540
541
|
**The 8-hour whole-run bound is untouched and still outranks all of this** — it is measured from the
|
|
541
542
|
record's `started_at` across every cut, so a run cannot watch its way past it in 30-minute pieces.
|
|
@@ -7,6 +7,8 @@ the run is at, and the sections below carry that step in full.
|
|
|
7
7
|
|
|
8
8
|
## The `fullrun #N` step list
|
|
9
9
|
|
|
10
|
+
Use `pnpm josh issue:lint` `labels:`; see `prompts/collaboration-workflow/issue-template.md`.
|
|
11
|
+
|
|
10
12
|
**Add `in-progress` the moment `run:hold` answered `hold`** (create if missing:
|
|
11
13
|
`gh api repos/{owner}/{repo}/labels -f name=in-progress -f color=0075ca -f description="Work is
|
|
12
14
|
actively in progress" --silent 2>/dev/null || true`, then `gh api
|
|
@@ -49,8 +51,8 @@ completion notification, then merges; if blockers are found it exits non-zero
|
|
|
49
51
|
`kickoff new` + `fullrun #N` in one run. Steps: (1) Derive an English title, or use the provided one.
|
|
50
52
|
**(1a) Run `pnpm josh issue:scout "<title>" [--body "<summary>"]` before creating the Issue** — a
|
|
51
53
|
candidate that covers the same work stops the run rather than filing a second Issue (`SKILL.md` → §2e).
|
|
52
|
-
(2) Create Issue: `gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=depth:<n>' -
|
|
53
|
-
body
|
|
54
|
+
(2) Create Issue: `gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=depth:<n>' -F
|
|
55
|
+
body=@<body-file>` (per `prompts/collaboration-workflow/issue-template.md`). Capture `<N>`. (3) Add
|
|
54
56
|
`in-progress` (as above). (4) Post the agreed plan in the session language: fill the body if blank,
|
|
55
57
|
otherwise add a comment. (5) If the working tree already has staged or modified files,
|
|
56
58
|
`git stash push -m "fullrun new: pre-existing changes"` first. (6) `git switch main && git pull`. (7)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# `halfrun` — the manifest (implement + verify, stop before commit)
|
|
2
2
|
|
|
3
|
+
When this run files a new Issue, run `pnpm josh issue:lint <body-file>` and apply every label in its `labels:` answer at creation; `prompts/collaboration-workflow/issue-template.md` is the single source for this classification. Keep the existing `depth` and `route` labels.
|
|
4
|
+
|
|
3
5
|
`halfrun` sits between `kickoff` (plan only) and `fullrun` (full execution with auto-merge). It
|
|
4
6
|
implements the change and runs the full verification gate, then **stops before commit** — nothing is
|
|
5
7
|
committed, pushed, or opened as a PR — so the user manually verifies the change (typically by exercising
|
|
@@ -52,7 +54,7 @@ back with fixes, treat each as a new round: implement, re-run `pnpm josh gate`,
|
|
|
52
54
|
`halfrun new` or `halfrun new "<title>"`: `kickoff new` + `halfrun #<N>` (no Issue exists yet). Steps
|
|
53
55
|
mirror `fullrun new` (1)–(8): derive an English title (or use the provided one) → **run `pnpm josh
|
|
54
56
|
issue:scout "<title>" [--body "<summary>"]` before creating the Issue** (`SKILL.md` → §2e) → create the
|
|
55
|
-
Issue (`gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=depth:<n>' -
|
|
57
|
+
Issue (`gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=depth:<n>' -F body=@<body-file>`,
|
|
56
58
|
body per `prompts/collaboration-workflow/issue-template.md`) → add `in-progress` → post the agreed plan → stash
|
|
57
59
|
any pre-existing changes with `git stash push -m "halfrun new: pre-existing changes"`, popped by
|
|
58
60
|
message with `pnpm josh stash:pop "halfrun new: pre-existing changes"`, never a positional `git stash pop` →
|
|
@@ -47,13 +47,13 @@ split is found.
|
|
|
47
47
|
title. **(1a) Run `pnpm josh issue:scout "<title>" [--body "<summary>"]` before creating the Issue** —
|
|
48
48
|
a candidate that covers the same work stops the run rather than filing a second Issue (`SKILL.md` →
|
|
49
49
|
§2e). (2) Create Issue: `gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=depth:<n>'
|
|
50
|
-
-
|
|
50
|
+
-F body=@<body-file>` (body per `prompts/collaboration-workflow/issue-template.md`). Capture `<N>`. (3)
|
|
51
51
|
Post the plan in the session language, using the same body/comment logic as `kickoff #<N>`. (4) Send
|
|
52
52
|
Telegram notification. (5) **Stop** — do not implement. **Multi-issue split path**: (1) For each
|
|
53
53
|
independent deliverable, derive a focused English title, **run `pnpm josh issue:scout "<sub-title>"`
|
|
54
54
|
on it** (`SKILL.md` → §2e), and create a separate Issue with the `route:split` label: `gh api
|
|
55
55
|
repos/{owner}/{repo}/issues -f title="<sub-title>" -f 'labels[]=route:split' -f 'labels[]=depth:<n>'
|
|
56
|
-
-
|
|
56
|
+
-F body=@<body-file>`. Capture each Issue number. **When the split is filed into a repository other than
|
|
57
57
|
the one this session is running in**, every child body gets the `## Origin` backlink described in the
|
|
58
58
|
cross-package rule the AI documents keep resident, the epic body carries the same link as prose or a
|
|
59
59
|
plain bullet (never as a checkbox row, which would disable its auto-close), and the originating Issue
|
|
@@ -66,7 +66,7 @@ split is found.
|
|
|
66
66
|
josh epic:check <E>`. Only where `josh` is unavailable, fall back to the manual procedure: ensure the
|
|
67
67
|
label exists (`gh api repos/{owner}/{repo}/labels -f name=epic -f color=5319e7 -f description="Tracks
|
|
68
68
|
a batch of child issues from one split" --silent 2>/dev/null || true`), then create the epic with `gh
|
|
69
|
-
api repos/{owner}/{repo}/issues -f title="<epic-title>" -f 'labels[]=epic' -
|
|
69
|
+
api repos/{owner}/{repo}/issues -f title="<epic-title>" -f 'labels[]=epic' -F body=@<body-file>`. Its body
|
|
70
70
|
follows the epic format in `prompts/collaboration-workflow/issue-template.md` — split rationale,
|
|
71
71
|
dependencies, the `backlogrun` command, and a child task list in task-list syntax (`- [ ] #N`). The epic
|
|
72
72
|
exists as the **non-closing home for the split rationale**. When the children have no required order,
|
|
@@ -80,3 +80,5 @@ split is found.
|
|
|
80
80
|
**database id**, not its issue number; a failure here is non-fatal). Never fold the relation into the
|
|
81
81
|
creation call. (3) Send Telegram notification listing all created issues. (4) Present the command
|
|
82
82
|
`backlogrun #<E> --only`. (5) **Stop** — do not implement.
|
|
83
|
+
|
|
84
|
+
Before filing, run `pnpm josh issue:lint <body-file>` and apply every label in its `labels:` answer at creation, following `prompts/collaboration-workflow/issue-template.md` for classification.
|
|
@@ -29,6 +29,8 @@ backlog pool (`backlogrun-steps.md` → "What one invocation approves").
|
|
|
29
29
|
|
|
30
30
|
The detail below is read at the filing decision, and the marker suite pins the rules here.
|
|
31
31
|
|
|
32
|
+
Before filing an observation, run `pnpm josh issue:lint <body-file>` and apply every label in its `labels:` answer at creation; `prompts/collaboration-workflow/issue-template.md` is the single source. Keep the depth label.
|
|
33
|
+
|
|
32
34
|
### The depth test — a discretionary filing cites the product work it blocked
|
|
33
35
|
|
|
34
36
|
**A run that has just spent an hour inside the workflow tooling files findings about the workflow
|
|
@@ -55,7 +57,7 @@ cap's branch-2 filing all pass through a `gh api … issues` call, and the depth
|
|
|
55
57
|
beside whatever `route:` label that call already carries.
|
|
56
58
|
|
|
57
59
|
```bash
|
|
58
|
-
gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=depth:1' -
|
|
60
|
+
gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=depth:1' -F body=@<body-file>
|
|
59
61
|
gh api repos/{owner}/{repo}/issues/<N>/labels -f 'labels[]=depth:1' # an Issue already filed
|
|
60
62
|
```
|
|
61
63
|
|
|
@@ -25,8 +25,10 @@ stays countable by filing route afterwards. **This paragraph belongs to the prer
|
|
|
25
25
|
the table** — the label means a filing the run is *blocked by*, so the observation row carries no
|
|
26
26
|
`route:` label of its own (§2i):
|
|
27
27
|
|
|
28
|
+
Before that call, run `pnpm josh issue:lint <body-file>` and apply every label in its `labels:` answer at creation; `prompts/collaboration-workflow/issue-template.md` is the single source. Keep `route:tier-a` and `depth`.
|
|
29
|
+
|
|
28
30
|
```bash
|
|
29
|
-
gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=route:tier-a' -f 'labels[]=depth:<n>' -
|
|
31
|
+
gh api repos/{owner}/{repo}/issues -f title="<title>" -f 'labels[]=route:tier-a' -f 'labels[]=depth:<n>' -F body=@<body-file>
|
|
30
32
|
```
|
|
31
33
|
|
|
32
34
|
Every "file the prerequisite" below means that labelled filing, and it always happens **first**: the
|
|
@@ -41,7 +41,7 @@ backlogrun joshuafolkken/kit#858 --only
|
|
|
41
41
|
never clone. The one exception is the split path's epic, since `pnpm josh epic` only writes the
|
|
42
42
|
repository it runs in — run it in that repository's checkout, or fall back to `gh api
|
|
43
43
|
repos/<owner/repo>/labels …` followed by `gh api repos/<owner/repo>/issues -f title="<epic-title>" -f
|
|
44
|
-
'labels[]=epic' -
|
|
44
|
+
'labels[]=epic' -F body=@<body-file>`, and report that `epic:check` could not be run. The promote arm has
|
|
45
45
|
no such fallback: with no checkout there, file the children and stop.
|
|
46
46
|
- **The implementing entries require a checkout and never create one — when the target is another
|
|
47
47
|
repository.** A prefix naming the session's own repository changes nothing (`fullrun kit#412` in the
|
|
@@ -1 +1,13 @@
|
|
|
1
1
|
closes #
|
|
2
|
+
|
|
3
|
+
## Release classification
|
|
4
|
+
|
|
5
|
+
Add exactly one label before merging:
|
|
6
|
+
|
|
7
|
+
- `breaking-change` — any incompatible change, even when it also adds a feature or fixes a bug
|
|
8
|
+
- `enhancement` — a compatible new feature or improvement
|
|
9
|
+
- `bugfix` — a compatible fix
|
|
10
|
+
- `other-change` — documentation, dependencies, or maintenance included in Other Changes
|
|
11
|
+
- `ignore-for-release` — omit this pull request from the changelog
|
|
12
|
+
|
|
13
|
+
Automated pull requests without a classification label are treated as Other Changes. If an automated pull request needs another classification or exclusion, add that one label.
|
package/.github/release.yml
CHANGED
package/.github/workflows/ci.yml
CHANGED
|
@@ -6,6 +6,7 @@ on:
|
|
|
6
6
|
|
|
7
7
|
pull_request:
|
|
8
8
|
branches: [main]
|
|
9
|
+
types: [opened, synchronize, reopened, labeled, unlabeled]
|
|
9
10
|
|
|
10
11
|
# A push run is grouped by the commit it carries, so a later push to main never cancels an earlier
|
|
11
12
|
# one. Without the sha every push to main shares one group — `github.ref` is `refs/heads/main` for
|
|
@@ -351,6 +352,10 @@ jobs:
|
|
|
351
352
|
- name: Run verification gate
|
|
352
353
|
run: pnpm josh gate --verbose --no-unit
|
|
353
354
|
|
|
355
|
+
- name: Check release classification
|
|
356
|
+
if: github.event_name == 'pull_request'
|
|
357
|
+
run: pnpm josh pr:classification
|
|
358
|
+
|
|
354
359
|
# The other half of the gate, on a runner of its own. It carries the same setup steps as
|
|
355
360
|
# `static-checks` rather than sharing them: a GitHub job is its own machine, so every job that
|
|
356
361
|
# needs Node sets Node up, and this workflow already writes that preamble once per job. The
|
|
@@ -425,6 +430,9 @@ jobs:
|
|
|
425
430
|
- name: Run unit tests
|
|
426
431
|
run: pnpm josh test:unit
|
|
427
432
|
|
|
433
|
+
- name: Verify optional ESLint consumer install
|
|
434
|
+
run: pnpm exec tsx scripts/package/verify-optional-eslint-install.ts
|
|
435
|
+
|
|
428
436
|
# **The required status check. `Checks` is a name the branch ruleset already requires, and this job
|
|
429
437
|
# is what keeps that name meaning what it meant** (joshuafolkken/kit#1226) — every check the single
|
|
430
438
|
# `Checks` job used to run has passed. It runs no checks itself; it reads the two halves' results.
|
|
@@ -2,9 +2,18 @@ name: Release to Production
|
|
|
2
2
|
on:
|
|
3
3
|
repository_dispatch:
|
|
4
4
|
types: [new-tag-created]
|
|
5
|
+
workflow_call:
|
|
6
|
+
inputs:
|
|
7
|
+
tag:
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
5
10
|
|
|
6
11
|
jobs:
|
|
7
12
|
update-branch:
|
|
13
|
+
if: github.repository != 'joshuafolkken/kit' || inputs.tag != ''
|
|
14
|
+
concurrency:
|
|
15
|
+
group: production-update
|
|
16
|
+
queue: max
|
|
8
17
|
runs-on: ubuntu-latest
|
|
9
18
|
permissions:
|
|
10
19
|
contents: write
|
|
@@ -24,7 +33,7 @@ jobs:
|
|
|
24
33
|
# repository_dispatch always runs on the default branch, so the event ref
|
|
25
34
|
# resolves to that branch, not the released tag. Use the tag carried in the
|
|
26
35
|
# dispatch payload (set by auto-tag.yml) as the merge source instead.
|
|
27
|
-
REF_NAME: ${{ github.event.client_payload.tag }}
|
|
36
|
+
REF_NAME: ${{ inputs.tag || github.event.client_payload.tag }}
|
|
28
37
|
run: |
|
|
29
38
|
if [ -z "$REF_NAME" ]; then
|
|
30
39
|
echo "::error::new-tag-created dispatch carried no tag payload; aborting." >&2
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
name: Publish
|
|
2
|
+
run-name: Publish ${{ github.event.client_payload.tag }}
|
|
2
3
|
|
|
3
4
|
on:
|
|
4
5
|
repository_dispatch:
|
|
@@ -6,6 +7,9 @@ on:
|
|
|
6
7
|
|
|
7
8
|
jobs:
|
|
8
9
|
publish-github:
|
|
10
|
+
concurrency:
|
|
11
|
+
group: package-publish
|
|
12
|
+
queue: max
|
|
9
13
|
runs-on: ubuntu-latest
|
|
10
14
|
timeout-minutes: 10
|
|
11
15
|
permissions:
|
|
@@ -36,11 +40,24 @@ jobs:
|
|
|
36
40
|
|
|
37
41
|
- run: pnpm install --frozen-lockfile --ignore-scripts
|
|
38
42
|
|
|
39
|
-
-
|
|
43
|
+
- name: Select GitHub Packages tag
|
|
44
|
+
id: publish-tag
|
|
45
|
+
run: |
|
|
46
|
+
version=$(node -p "require('./package.json').version")
|
|
47
|
+
latest=$(cd "$RUNNER_TEMP" && npm view @joshuafolkken/kit dist-tags.latest --registry https://npm.pkg.github.com)
|
|
48
|
+
tag=$(pnpm exec tsx scripts/release/publish-tag-cli.ts "$version" "$latest")
|
|
49
|
+
echo "tag=$tag" >> "$GITHUB_OUTPUT"
|
|
50
|
+
env:
|
|
51
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
52
|
+
|
|
53
|
+
- run: pnpm publish --no-git-checks --tag ${{ steps.publish-tag.outputs.tag }} --registry https://npm.pkg.github.com
|
|
40
54
|
env:
|
|
41
55
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
42
56
|
|
|
43
57
|
publish-npm:
|
|
58
|
+
concurrency:
|
|
59
|
+
group: package-publish
|
|
60
|
+
queue: max
|
|
44
61
|
runs-on: ubuntu-latest
|
|
45
62
|
timeout-minutes: 10
|
|
46
63
|
permissions:
|
|
@@ -72,5 +89,58 @@ jobs:
|
|
|
72
89
|
|
|
73
90
|
- run: pnpm pack --out "$RUNNER_TEMP/kit.tgz"
|
|
74
91
|
|
|
92
|
+
- name: Select npm tag
|
|
93
|
+
id: publish-tag
|
|
94
|
+
run: |
|
|
95
|
+
version=$(node -p "require('./package.json').version")
|
|
96
|
+
latest=$(cd "$RUNNER_TEMP" && npm view @joshuafolkken/kit dist-tags.latest --registry https://registry.npmjs.org)
|
|
97
|
+
tag=$(pnpm exec tsx scripts/release/publish-tag-cli.ts "$version" "$latest")
|
|
98
|
+
echo "tag=$tag" >> "$GITHUB_OUTPUT"
|
|
99
|
+
|
|
75
100
|
- name: Publish to npm
|
|
76
|
-
run: cd "$RUNNER_TEMP" && npm publish kit.tgz --access public --tag
|
|
101
|
+
run: cd "$RUNNER_TEMP" && npm publish kit.tgz --access public --tag ${{ steps.publish-tag.outputs.tag }} --registry https://registry.npmjs.org --userconfig /dev/null
|
|
102
|
+
|
|
103
|
+
update-production:
|
|
104
|
+
needs: [publish-github, publish-npm]
|
|
105
|
+
permissions:
|
|
106
|
+
contents: write
|
|
107
|
+
uses: ./.github/workflows/production.yml
|
|
108
|
+
with:
|
|
109
|
+
tag: ${{ github.event.client_payload.tag }}
|
|
110
|
+
|
|
111
|
+
create-release:
|
|
112
|
+
needs: [publish-github, publish-npm, update-production]
|
|
113
|
+
runs-on: ubuntu-latest
|
|
114
|
+
timeout-minutes: 65
|
|
115
|
+
permissions:
|
|
116
|
+
actions: read
|
|
117
|
+
contents: write
|
|
118
|
+
steps:
|
|
119
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
120
|
+
with:
|
|
121
|
+
ref: ${{ github.event.client_payload.tag }}
|
|
122
|
+
fetch-depth: 0
|
|
123
|
+
|
|
124
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
125
|
+
with:
|
|
126
|
+
node-version: 24
|
|
127
|
+
|
|
128
|
+
- name: Resolve pnpm version
|
|
129
|
+
id: pnpm-version
|
|
130
|
+
run: |
|
|
131
|
+
version=$(node -p "const m = require('./package.json'); m.packageManager?.match(/^pnpm@([^+]+)/)?.[1] ?? (m.devEngines?.packageManager?.name === 'pnpm' ? m.devEngines.packageManager.version?.split('+')[0] : 'latest') ?? 'latest'")
|
|
132
|
+
test -n "$version"
|
|
133
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
134
|
+
|
|
135
|
+
- uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
|
|
136
|
+
with:
|
|
137
|
+
version: ${{ steps.pnpm-version.outputs.version }}
|
|
138
|
+
install: false
|
|
139
|
+
|
|
140
|
+
- run: pnpm install --frozen-lockfile --ignore-scripts
|
|
141
|
+
|
|
142
|
+
- name: Publish GitHub Release
|
|
143
|
+
run: pnpm exec tsx scripts/release/github-release-cli.ts
|
|
144
|
+
env:
|
|
145
|
+
GH_TOKEN: ${{ github.token }}
|
|
146
|
+
RELEASE_TAG: ${{ github.event.client_payload.tag }}
|
package/CLAUDE.md
CHANGED
|
@@ -108,6 +108,7 @@ For every code modification, in order:
|
|
|
108
108
|
|
|
109
109
|
- **Tests are required for ALL code changes** (bug fixes, timing/animation fixes and refactors included): bug fix → regression test; UI/animation/timing → E2E for the observable change; logic/utility → unit; refactor → tests pinning existing behavior BEFORE the change (`prompts/refactoring.md`).
|
|
110
110
|
- **Non-runtime updates (pre-approved manual-only exception)**: a change touching no executable runtime code path may proceed with manual verification — declare it in Step 0 and state why. It covers docs, non-executable config, editor/IDE files, and cosmetic asset swaps with no selector/path change; the mechanically exempt (`*.md`, `.editorconfig`, `.idea/**`, `.vscode/**`, `prompts/**`) are recognized by the command below, and the rest stay the exemption a person declares. A test infeasible for a runtime change needs its reason stated and user approval.
|
|
111
|
+
- **static の HTML/CSS 例外:** `package.json` に `josh.profile: static` が記録され、変更が HTML/CSS だけなら自動テストの代わりにブラウザーで表示を確認する。対象ページを開き、想定する画面幅でレイアウト・リンク・HTML 内の操作を確認し、観察結果を報告する。HTML/CSS と同時に変更した場合も、JavaScript と TypeScript のファイルには自動テストが必要。`pnpm josh test:declared` はこの場合だけ理由を添えて `exempt` と表示する。
|
|
111
112
|
- **The commit stage answers this mechanically**: `pnpm josh test:declared` prints `required` / `exempt` / `satisfied` from the changed paths, and a runtime change with no test is refused at `pnpm josh git -y` on `required` — add the declared test or declare the non-runtime exception, then reissue (`prompts/collaboration-workflow/rule-delivery.md`).
|
|
112
113
|
- **Read a target's line headroom before editing: `pnpm josh lines <path>`** — near the limit, `Target` carries the splitting plan.
|
|
113
114
|
|
|
@@ -121,6 +122,7 @@ For every code modification, in order:
|
|
|
121
122
|
Run the full verification set **in order**; do not skip, reorder, or report completion on a failed or skipped step without the user agreeing. Inside a `fullrun` / `backlogrun` the gate runs beside the review and the merge chain (`workflow-commands` skill → §2, `prompts/review.md`).
|
|
122
123
|
|
|
123
124
|
0. **Test gate** — no tests added? Continue only under the non-runtime exception (Step 0) or explicit approval; otherwise stop and add tests.
|
|
125
|
+
static プロファイルの HTML/CSS だけの変更には、Step 0 の手動ブラウザー確認を適用できる。
|
|
124
126
|
1. **Refactor** — `prompts/refactoring.md`, until no high/medium items remain.
|
|
125
127
|
2. **`pnpm josh gate`** — lint, type check, spell check and unit tests concurrently. One gate per run; while implementing re-run a single check by name (`pnpm josh lint:related` / `pnpm josh cspell:dot` / `pnpm josh test:related`).
|
|
126
128
|
3. **Self-review** — a subagent runs `/code-review` per `prompts/review.md` (never a main-line `Skill` load); level from the changed paths, at most two rounds, high/medium findings resolved. `prompts/review.md` → "Review round cap".
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Shared toolchain config and CLI for TypeScript projects — ESLint, Prettier, Ty
|
|
|
7
7
|
|
|
8
8
|
## Prerequisites
|
|
9
9
|
|
|
10
|
-
- [Node.js](https://nodejs.org/) with [pnpm](https://pnpm.io/)
|
|
10
|
+
- [Node.js](https://nodejs.org/) 22.19.0 or later with [pnpm](https://pnpm.io/) — [getting-started.md](./docs/getting-started.md) covers installing both
|
|
11
11
|
- [gh CLI](https://cli.github.com/) for `josh version` and existing GitHub Packages consumers. It is not required to install kit from public npm; see [authentication.md](./docs/authentication.md) for setup when needed.
|
|
12
12
|
|
|
13
13
|
## Quick start
|
|
@@ -24,6 +24,7 @@ Using the kit inside a project? See [docs/package.md](./docs/package.md).
|
|
|
24
24
|
| Guide | What it covers |
|
|
25
25
|
| ----------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
26
26
|
| [why.md](./docs/why.md) | Why kit exists — the AI-development problems it solves, for practitioners |
|
|
27
|
+
| [getting-started.md](./docs/getting-started.md) | First install for an `index.html` site or a non-Node project, without Git |
|
|
27
28
|
| [authentication.md](./docs/authentication.md) | GitHub Packages auth for existing projects |
|
|
28
29
|
| [cli.md](./docs/cli.md) | Install and use the global `josh` CLI |
|
|
29
30
|
| [package.md](./docs/package.md) | Use the kit as a project devDependency — configs, prompts, scripts, `josh init` |
|
package/dist/CLAUDE.md
CHANGED
|
@@ -108,6 +108,7 @@ For every code modification, in order:
|
|
|
108
108
|
|
|
109
109
|
- **Tests are required for ALL code changes** (bug fixes, timing/animation fixes and refactors included): bug fix → regression test; UI/animation/timing → E2E for the observable change; logic/utility → unit; refactor → tests pinning existing behavior BEFORE the change (`node_modules/@joshuafolkken/kit/prompts/refactoring.md`).
|
|
110
110
|
- **Non-runtime updates (pre-approved manual-only exception)**: a change touching no executable runtime code path may proceed with manual verification — declare it in Step 0 and state why. It covers docs, non-executable config, editor/IDE files, and cosmetic asset swaps with no selector/path change; the mechanically exempt (`*.md`, `.editorconfig`, `.idea/**`, `.vscode/**`, `prompts/**`) are recognized by the command below, and the rest stay the exemption a person declares. A test infeasible for a runtime change needs its reason stated and user approval.
|
|
111
|
+
- **static の HTML/CSS 例外:** `package.json` に `josh.profile: static` が記録され、変更が HTML/CSS だけなら自動テストの代わりにブラウザーで表示を確認する。対象ページを開き、想定する画面幅でレイアウト・リンク・HTML 内の操作を確認し、観察結果を報告する。HTML/CSS と同時に変更した場合も、JavaScript と TypeScript のファイルには自動テストが必要。`pnpm josh test:declared` はこの場合だけ理由を添えて `exempt` と表示する。
|
|
111
112
|
- **The commit stage answers this mechanically**: `pnpm josh test:declared` prints `required` / `exempt` / `satisfied` from the changed paths, and a runtime change with no test is refused at `pnpm josh git -y` on `required` — add the declared test or declare the non-runtime exception, then reissue (`node_modules/@joshuafolkken/kit/prompts/collaboration-workflow/rule-delivery.md`).
|
|
112
113
|
- **Read a target's line headroom before editing: `pnpm josh lines <path>`** — near the limit, `Target` carries the splitting plan.
|
|
113
114
|
|
|
@@ -121,6 +122,7 @@ For every code modification, in order:
|
|
|
121
122
|
Run the full verification set **in order**; do not skip, reorder, or report completion on a failed or skipped step without the user agreeing. Inside a `fullrun` / `backlogrun` the gate runs beside the review and the merge chain (`workflow-commands` skill → §2, `node_modules/@joshuafolkken/kit/prompts/review.md`).
|
|
122
123
|
|
|
123
124
|
0. **Test gate** — no tests added? Continue only under the non-runtime exception (Step 0) or explicit approval; otherwise stop and add tests.
|
|
125
|
+
static プロファイルの HTML/CSS だけの変更には、Step 0 の手動ブラウザー確認を適用できる。
|
|
124
126
|
1. **Refactor** — `node_modules/@joshuafolkken/kit/prompts/refactoring.md`, until no high/medium items remain.
|
|
125
127
|
2. **`pnpm josh gate`** — lint, type check, spell check and unit tests concurrently. One gate per run; while implementing re-run a single check by name (`pnpm josh lint:related` / `pnpm josh cspell:dot` / `pnpm josh test:related`).
|
|
126
128
|
3. **Self-review** — a subagent runs `/code-review` per `node_modules/@joshuafolkken/kit/prompts/review.md` (never a main-line `Skill` load); level from the changed paths, at most two rounds, high/medium findings resolved. `node_modules/@joshuafolkken/kit/prompts/review.md` → "Review round cap".
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Project instructions
|
|
2
|
+
|
|
3
|
+
- 既存のファイルと利用者の設定を尊重し、変更する前に内容を確認する。
|
|
4
|
+
- 変更には検証を付け、実行した結果を報告する。
|
|
5
|
+
- HTML、CSS、JavaScript のファイルがある場合は Prettier で整形する。
|
|
6
|
+
- 画面に見える変更をした場合はブラウザーで表示と操作を確認する。
|
|
7
|
+
- JavaScript または TypeScript の動作を変更した場合は、その動作を確認する自動テストを追加する。
|
|
8
|
+
- Git や GitHub を使う場合だけ、それぞれのワークフローを利用する。
|
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
load_environment_file,
|
|
10
10
|
notice_refusal_path,
|
|
11
11
|
refusal_path
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-ROULPSQC.js";
|
|
13
|
+
import "./chunk-7XQ6TK3R.js";
|
|
14
|
+
import "./chunk-SXPTRFPG.js";
|
|
15
|
+
import "./chunk-2PGRQ62K.js";
|
|
16
|
+
import "./chunk-WPALEIRX.js";
|
|
17
|
+
import "./chunk-RKUAD3I6.js";
|
|
18
18
|
export {
|
|
19
19
|
DISABLED_VALUES,
|
|
20
20
|
SWITCH_ENV_KEY,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ENV_FILE_NAME
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RKUAD3I6.js";
|
|
4
4
|
|
|
5
5
|
// scripts/lib/json-value.ts
|
|
6
6
|
function parse_or_undefined(text) {
|
|
@@ -684,6 +684,12 @@ var FILTER_ARGUMENTS = "[filters...]";
|
|
|
684
684
|
var MATCH_ARGUMENTS = "[--match]";
|
|
685
685
|
var PATH_ARGUMENTS = "<path...>";
|
|
686
686
|
var DEV_COMMANDS = {
|
|
687
|
+
"pr:classification": {
|
|
688
|
+
script: "scripts/ci/pr-classification.ts",
|
|
689
|
+
description: "Require one release classification on a pull request",
|
|
690
|
+
category: "Development",
|
|
691
|
+
reference: ["", "automation", ["none"]]
|
|
692
|
+
},
|
|
687
693
|
[GATE_COMMAND]: {
|
|
688
694
|
script: "scripts/gate/verification-gate.ts",
|
|
689
695
|
description: "Run lint, type check, spell check and unit tests concurrently",
|
|
@@ -727,14 +733,7 @@ var DEV_COMMANDS = {
|
|
|
727
733
|
reference: ["", "developer", ["none"]]
|
|
728
734
|
},
|
|
729
735
|
format: {
|
|
730
|
-
|
|
731
|
-
// whenever a non-autofixable error remains, so putting it first behind `&&` would mean one
|
|
732
|
-
// unused variable anywhere in the tree stops prettier from running at all.
|
|
733
|
-
shell: [
|
|
734
|
-
"sh",
|
|
735
|
-
"-c",
|
|
736
|
-
`pnpm exec prettier --write . && pnpm exec eslint . --fix ${ESLINT_CACHE_FLAGS.join(" ")}`
|
|
737
|
-
],
|
|
736
|
+
script: "scripts/lint/format.ts",
|
|
738
737
|
description: "Format code with prettier and eslint",
|
|
739
738
|
category: "Development",
|
|
740
739
|
reference: ["", "developer", ["files", "processes"]]
|
|
@@ -1003,12 +1002,25 @@ var MAINTENANCE_COMMANDS = {
|
|
|
1003
1002
|
};
|
|
1004
1003
|
|
|
1005
1004
|
// scripts/josh/josh-commands-project.ts
|
|
1005
|
+
var PROFILE_ARGUMENTS = "[--profile static|node]";
|
|
1006
1006
|
var PROJECT_COMMANDS = {
|
|
1007
|
+
profile: {
|
|
1008
|
+
script: "scripts/init/project-profile-cli.ts",
|
|
1009
|
+
description: "Show the project profile and the reason for it",
|
|
1010
|
+
category: "Project",
|
|
1011
|
+
reference: [PROFILE_ARGUMENTS, "developer", ["files"]]
|
|
1012
|
+
},
|
|
1013
|
+
start: {
|
|
1014
|
+
script: "scripts/init/start.ts",
|
|
1015
|
+
description: "Initialize a project for the GitHub Issue workflow",
|
|
1016
|
+
category: "Project",
|
|
1017
|
+
reference: [PROFILE_ARGUMENTS, "developer", ["files", "git", "network"]]
|
|
1018
|
+
},
|
|
1007
1019
|
init: {
|
|
1008
1020
|
script: "scripts/init/init.ts",
|
|
1009
1021
|
description: "Initialize config in a new project",
|
|
1010
1022
|
category: "Project",
|
|
1011
|
-
reference: [
|
|
1023
|
+
reference: [PROFILE_ARGUMENTS, "developer", ["files", "processes"]]
|
|
1012
1024
|
},
|
|
1013
1025
|
sync: {
|
|
1014
1026
|
script: "scripts/sync/sync.ts",
|
|
@@ -1242,11 +1254,14 @@ var ALIASES = {
|
|
|
1242
1254
|
c: "check",
|
|
1243
1255
|
pt: "port",
|
|
1244
1256
|
i: "init",
|
|
1257
|
+
pf: "profile",
|
|
1258
|
+
st: "start",
|
|
1245
1259
|
sy: "sync",
|
|
1246
1260
|
rmi: "registry:migrate",
|
|
1247
1261
|
sys: "sync:scope",
|
|
1248
1262
|
g: "git",
|
|
1249
1263
|
gp: "pr",
|
|
1264
|
+
prc: "pr:classification",
|
|
1250
1265
|
fu: "followup",
|
|
1251
1266
|
nf: "notify",
|
|
1252
1267
|
obf: "observations:flush",
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// scripts/build/local-bin.ts
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
// scripts/lib/schemas.ts
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
var overrides_snapshot_schema = z.record(z.string(), z.string());
|
|
9
|
+
var package_version_schema = z.object({ version: z.string() });
|
|
10
|
+
var package_named_version_schema = z.looseObject({ name: z.string(), version: z.string() });
|
|
11
|
+
var package_with_version_schema = z.looseObject({ version: z.string() });
|
|
12
|
+
var ls_global_dependency_schema = z.looseObject({ version: z.string() });
|
|
13
|
+
var ls_global_dependencies_schema = z.record(z.string(), ls_global_dependency_schema).optional();
|
|
14
|
+
var pnpm_ls_global_schema = z.array(
|
|
15
|
+
z.looseObject({
|
|
16
|
+
dependencies: ls_global_dependencies_schema
|
|
17
|
+
})
|
|
18
|
+
);
|
|
19
|
+
var vscode_settings_schema = z.record(z.string(), z.unknown());
|
|
20
|
+
var with_scripts_schema = z.looseObject({
|
|
21
|
+
scripts: z.record(z.string(), z.string()).optional()
|
|
22
|
+
});
|
|
23
|
+
var with_development_deps_schema = z.looseObject({
|
|
24
|
+
devDependencies: z.record(z.string(), z.string()).optional()
|
|
25
|
+
});
|
|
26
|
+
var with_package_manager_schema = z.looseObject({
|
|
27
|
+
packageManager: z.string().optional()
|
|
28
|
+
});
|
|
29
|
+
var with_development_engine_schema = z.looseObject({
|
|
30
|
+
devEngines: z.record(z.string(), z.unknown()).optional()
|
|
31
|
+
});
|
|
32
|
+
var bin_entry_schema = z.union([z.string(), z.record(z.string(), z.string())]).optional();
|
|
33
|
+
var package_bin_schema = z.looseObject({ bin: bin_entry_schema });
|
|
34
|
+
var json_object_schema = z.record(z.string(), z.unknown());
|
|
35
|
+
var string_array_schema = z.array(z.string());
|
|
36
|
+
var string_record_schema = z.record(z.string(), z.string());
|
|
37
|
+
|
|
38
|
+
// scripts/build/local-bin.ts
|
|
39
|
+
var NODE_MODULES = "node_modules";
|
|
40
|
+
var BIN_DIR = ".bin";
|
|
41
|
+
var WINDOWS_PLATFORM = "win32";
|
|
42
|
+
var WINDOWS_SHIM_SUFFIX = ".cmd";
|
|
43
|
+
var PACKAGE_JSON = "package.json";
|
|
44
|
+
function resolve_local_bin(project_root, bin_name) {
|
|
45
|
+
const shim = process.platform === WINDOWS_PLATFORM ? `${bin_name}${WINDOWS_SHIM_SUFFIX}` : bin_name;
|
|
46
|
+
return path.join(project_root, NODE_MODULES, BIN_DIR, shim);
|
|
47
|
+
}
|
|
48
|
+
function ancestor_directories(start_directory) {
|
|
49
|
+
const directories = [];
|
|
50
|
+
let current = start_directory;
|
|
51
|
+
while (!directories.includes(current)) {
|
|
52
|
+
directories.push(current);
|
|
53
|
+
current = path.dirname(current);
|
|
54
|
+
}
|
|
55
|
+
return directories;
|
|
56
|
+
}
|
|
57
|
+
function find_local_bin_upwards(start_directory, bin_name) {
|
|
58
|
+
return ancestor_directories(start_directory).map((directory) => resolve_local_bin(directory, bin_name)).find((candidate) => existsSync(candidate));
|
|
59
|
+
}
|
|
60
|
+
function read_bin_entry(manifest_path, package_name, bin_name) {
|
|
61
|
+
const { bin } = package_bin_schema.parse(JSON.parse(readFileSync(manifest_path, "utf8")));
|
|
62
|
+
if (typeof bin === "string") return bin_name === path.basename(package_name) ? bin : void 0;
|
|
63
|
+
return bin?.[bin_name];
|
|
64
|
+
}
|
|
65
|
+
function resolve_package_bin(base_directory, package_name, bin_name) {
|
|
66
|
+
try {
|
|
67
|
+
const resolve_from = createRequire(path.join(base_directory, PACKAGE_JSON));
|
|
68
|
+
const manifest_path = resolve_from.resolve(`${package_name}/${PACKAGE_JSON}`);
|
|
69
|
+
const bin_entry = read_bin_entry(manifest_path, package_name, bin_name);
|
|
70
|
+
if (bin_entry === void 0) return void 0;
|
|
71
|
+
const cli_entry = path.join(path.dirname(manifest_path), bin_entry);
|
|
72
|
+
return existsSync(cli_entry) ? cli_entry : void 0;
|
|
73
|
+
} catch {
|
|
74
|
+
return void 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
resolve_local_bin,
|
|
80
|
+
find_local_bin_upwards,
|
|
81
|
+
resolve_package_bin
|
|
82
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
lane_child_marker
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SXPTRFPG.js";
|
|
4
4
|
import {
|
|
5
5
|
time_bundle_call,
|
|
6
6
|
time_format,
|
|
7
7
|
time_round_trips,
|
|
8
8
|
time_spans,
|
|
9
9
|
time_transcript_line
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2PGRQ62K.js";
|
|
11
11
|
|
|
12
12
|
// scripts/lane/lane-guard-policy.ts
|
|
13
13
|
var DEFAULT_MODE = "refuse";
|