@joshuafolkken/kit 1.1128.0 → 1.1136.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.claude/agents/investigator.md +17 -0
  2. package/.claude/settings.json +1 -0
  3. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
  4. package/.claude/skills/workflow-commands/delegation.md +5 -1
  5. package/SECURITY.md +1 -0
  6. package/dist/hooks/batch-guard.js +4 -4
  7. package/dist/hooks/{chunk-77J7IEQM.js → chunk-FO2I7UT7.js} +1 -1
  8. package/dist/hooks/{chunk-4JZDP5X5.js → chunk-GDU26K3J.js} +9 -1
  9. package/dist/hooks/{chunk-QVLT52OV.js → chunk-HANSKHES.js} +2 -2
  10. package/dist/hooks/{chunk-5SD2YM7Z.js → chunk-HBKZLITF.js} +4 -4
  11. package/dist/hooks/{chunk-AIOIOMPX.js → chunk-JKKTVDAG.js} +128 -61
  12. package/dist/hooks/{chunk-M7QKEKWO.js → chunk-KBXZLMRH.js} +9 -28
  13. package/dist/hooks/{chunk-XYUIQOW3.js → chunk-KOKOAV6D.js} +2 -2
  14. package/dist/hooks/{chunk-NXYMNPUQ.js → chunk-LJBLGHEH.js} +59 -19
  15. package/dist/hooks/{chunk-MKVGBQPA.js → chunk-NFZGFGOR.js} +1 -1
  16. package/dist/hooks/{chunk-7HVB7SZG.js → chunk-RFWWUI5F.js} +4 -4
  17. package/dist/hooks/codex-hook-adapter.js +10 -10
  18. package/dist/hooks/duplicate-read-guard.js +5 -5
  19. package/dist/hooks/format-edited.js +2 -2
  20. package/dist/hooks/inputs.json +199 -198
  21. package/dist/hooks/investigation-guard.js +5 -5
  22. package/dist/hooks/pretool-guard.js +9 -9
  23. package/dist/hooks/stop-guard.js +3 -3
  24. package/dist/josh.js +8 -1
  25. package/package.json +6 -4
  26. package/scripts/delegation/delegation-policy.ts +9 -1
  27. package/scripts/delegation/investigation-guard.ts +1 -1
  28. package/scripts/delegation/investigation-reads.ts +105 -19
  29. package/scripts/document/capped-print.ts +74 -0
  30. package/scripts/document/document-section-cli.ts +4 -3
  31. package/scripts/gate/scoped-green.ts +25 -14
  32. package/scripts/init/claude-kit-only-settings.ts +29 -0
  33. package/scripts/init/init-copy-content.ts +8 -2
  34. package/scripts/init/initial-commit.ts +24 -0
  35. package/scripts/init/start-exec.ts +16 -3
  36. package/scripts/init/start-steps.ts +8 -12
  37. package/scripts/issue/issue-read-cli.ts +1 -0
  38. package/scripts/issue/issue-report-failures.ts +6 -2
  39. package/scripts/issue/issue-state-cli.ts +1 -1
  40. package/scripts/josh/josh-commands-lane.ts +1 -1
  41. package/scripts/josh/josh-commands-project.ts +7 -0
  42. package/scripts/lane/lane-await.ts +46 -2
  43. package/scripts/lane/lane-cli.ts +11 -13
  44. package/scripts/release/github-release-environment.ts +1 -0
  45. package/scripts/release/github-release.ts +103 -17
  46. package/scripts/run/run-carry-cli.ts +3 -1
  47. package/scripts/run/run-carry-conversation.ts +94 -0
  48. package/scripts/run/run-carry-reclaim.ts +37 -0
  49. package/scripts/run/run-carry.ts +21 -5
  50. package/scripts/run/run-merge-steps.ts +4 -1
  51. package/scripts/test/test-related.ts +1 -6
  52. package/scripts/test/test-unit-guard.ts +21 -7
  53. package/scripts/time-runtime/time-spans.ts +4 -0
  54. package/templates/workflows/github-release.yml +13 -25
@@ -79,6 +79,24 @@ function has_unit_tests(project_directory: string): boolean {
79
79
  return matches.length > 0
80
80
  }
81
81
 
82
+ // The guard's decision for one project, asked here once so the run, the scoped record and the gate's
83
+ // precondition can never disagree about whether this project's vitest runs (joshuafolkken/kit#3136).
84
+ function guard_action(project_directory: string): GuardAction {
85
+ return resolve_guard_action(
86
+ is_vitest_installed(project_directory),
87
+ has_unit_tests(project_directory),
88
+ project_checks.is_basic(project_directory),
89
+ )
90
+ }
91
+
92
+ // **A skip is the project having no unit suite, so no unit check can ever vouch for its tree.** The
93
+ // failing branch is not one: it is a broken suite, and it is left to fail where it is reported.
94
+ function is_skipping(project_directory: string): boolean {
95
+ const action = guard_action(project_directory)
96
+
97
+ return action === SKIP_ACTION || action === SKIP_NO_TESTS_ACTION
98
+ }
99
+
82
100
  // A lane's port allocation belongs to its development and preview servers, not to unit fixtures.
83
101
  // Passing it into Vitest makes every case that deliberately omits or replaces the seed inherit the
84
102
  // checkout's seat instead. Keep the rest of the caller's environment, including CI and PATH guards.
@@ -155,13 +173,7 @@ async function run_guarded_vitest(
155
173
  command_label: string = UNIT_COMMAND_LABEL,
156
174
  announcement?: string,
157
175
  ): Promise<number> {
158
- const is_installed = is_vitest_installed(project_directory)
159
- const has_tests = has_unit_tests(project_directory)
160
- const action = resolve_guard_action(
161
- is_installed,
162
- has_tests,
163
- project_checks.is_basic(project_directory),
164
- )
176
+ const action = guard_action(project_directory)
165
177
 
166
178
  if (action !== 'run') return report_no_run(action, command_label)
167
179
  if (announcement !== undefined) process.stdout.write(`${announcement}\n`)
@@ -185,6 +197,8 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
185
197
 
186
198
  const test_unit_guard = {
187
199
  SKIP_MARKER,
200
+ guard_action,
201
+ is_skipping,
188
202
  resolve_guard_action,
189
203
  is_vitest_installed,
190
204
  has_unit_tests,
@@ -138,6 +138,9 @@ interface ToolCall {
138
138
  // second write to one file is independent work, a read of a file just written is not
139
139
  // (joshuafolkken/kit#1509).
140
140
  is_writing: boolean
141
+ // The conservative write answer `is_read_only_call` asks of a live call, carried so a reader of the
142
+ // transcript asks the same read-only question as the guard (joshuafolkken/kit#3139).
143
+ may_write: boolean
141
144
  // Whether this is a subagent launch whose prompt builds on an earlier launch's finding
142
145
  // (joshuafolkken/kit#1854). Carried for the reason every field here is — the prompt it is read from
143
146
  // is the input, and a span keeps none. `time-agent-bundles.ts` reads it.
@@ -474,6 +477,7 @@ function to_spans(events: ReadonlyArray<TimelineEvent>, finished: FinishedAt): A
474
477
  is_bundleable: event.is_bundleable,
475
478
  targets: event.targets,
476
479
  is_writing: event.is_writing,
480
+ may_write: event.may_write,
477
481
  has_prior_reference: event.has_prior_reference,
478
482
  writes: event.writes,
479
483
  message_id: event.message_id,
@@ -1,14 +1,13 @@
1
1
  name: GitHub Release
2
2
 
3
3
  # Creates the GitHub Release, with notes generated from `.github/release.yml`, for each tag
4
- # `josh release` cuts (joshuafolkken/kit#3007). A repository with a Publish workflow gets its release
5
- # once that workflow has succeeded for the tag; one without it gets the release when auto-tag.yml
6
- # announces the tag. kit's own release is the `create-release` job of its publish.yml, which runs the
7
- # same `josh release:github`, so this file is distributed but never runs in kit.
4
+ # `josh release` cuts (joshuafolkken/kit#3007). It starts when auto-tag.yml announces the tag; a
5
+ # repository with a Publish workflow gets its release once that workflow has succeeded for the tag,
6
+ # waited for inside `josh release:github`. A `workflow_run` on Publish is not used: a Publish run
7
+ # started by the GITHUB_TOKEN never fires one (joshuafolkken/kit#3138). kit's own release is the
8
+ # `create-release` job of its publish.yml, which runs the same `josh release:github`, so this file is
9
+ # distributed but never runs in kit.
8
10
  on:
9
- workflow_run:
10
- workflows: [Publish]
11
- types: [completed]
12
11
  repository_dispatch:
13
12
  types: [new-tag-created]
14
13
 
@@ -17,12 +16,6 @@ on:
17
16
 
18
17
  jobs:
19
18
  release:
20
- # The Publish run is titled `Publish <tag>`; its head branch is not the tag when it was started by
21
- # repository_dispatch, so the title is where the tag is read from.
22
- if: >-
23
- (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' &&
24
- startsWith(github.event.workflow_run.display_title, 'Publish v')) ||
25
- github.event_name == 'repository_dispatch'
26
19
  runs-on: ubuntu-latest
27
20
  timeout-minutes: 65
28
21
  permissions:
@@ -36,23 +29,17 @@ jobs:
36
29
  fetch-depth: 0
37
30
  persist-credentials: false
38
31
 
39
- # A repository with a Publish workflow is released from the workflow_run above, after its
40
- # publication, so the tag announcement is left alone there and one tag never starts two releases.
32
+ # A repository with a Publish workflow waits for that workflow's `Publish <tag>` run to succeed
33
+ # before releasing; the announcement is the only trigger, so one tag never starts two releases.
41
34
  - name: Select release tag
42
35
  id: release
43
36
  env:
44
- EVENT_NAME: ${{ github.event_name }}
45
- RUN_TITLE: ${{ github.event.workflow_run.display_title }}
46
- RUN_WORKFLOW: ${{ github.event.workflow_run.workflow_id }}
47
37
  DISPATCH_TAG: ${{ github.event.client_payload.tag }}
48
38
  run: |
49
- if [ "$EVENT_NAME" = workflow_run ]; then
50
- echo "tag=${RUN_TITLE#Publish }" >> "$GITHUB_OUTPUT"
51
- echo "workflow=$RUN_WORKFLOW" >> "$GITHUB_OUTPUT"
52
- elif [ -f .github/workflows/publish.yml ]; then
53
- echo "ℹ️ publish.yml releases this tag once it has published, skipping"
54
- else
55
- echo "tag=$DISPATCH_TAG" >> "$GITHUB_OUTPUT"
39
+ echo "tag=$DISPATCH_TAG" >> "$GITHUB_OUTPUT"
40
+ if [ -f .github/workflows/publish.yml ]; then
41
+ echo "workflow=publish.yml" >> "$GITHUB_OUTPUT"
42
+ echo "await=true" >> "$GITHUB_OUTPUT"
56
43
  fi
57
44
 
58
45
  - name: Setup Node.js
@@ -77,3 +64,4 @@ jobs:
77
64
  GH_TOKEN: ${{ github.token }}
78
65
  RELEASE_TAG: ${{ steps.release.outputs.tag }}
79
66
  RELEASE_WORKFLOW: ${{ steps.release.outputs.workflow }}
67
+ RELEASE_AWAIT_PUBLISH: ${{ steps.release.outputs.await }}