@joshuafolkken/kit 1.1435.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.
Files changed (88) hide show
  1. package/.claude/skills/workflow-commands/backlogrun-park.md +2 -0
  2. package/.claude/skills/workflow-commands/backlogrun-steps.md +9 -7
  3. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  4. package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
  5. package/.claude/skills/workflow-commands/halfrun.md +1 -1
  6. package/.claude/skills/workflow-commands/kickoff.md +12 -13
  7. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  8. package/.claude/skills/workflow-commands/prerequisite.md +6 -0
  9. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  10. package/.claude/skills/workflow-commands/split-assessment.md +2 -2
  11. package/README.md +15 -17
  12. package/dist/hooks/batch-guard.js +6 -6
  13. package/dist/hooks/{chunk-3LE6VLSR.js → chunk-3C4XRYG6.js} +18 -5
  14. package/dist/hooks/{chunk-JXQBK323.js → chunk-5C7L6FRC.js} +131 -104
  15. package/dist/hooks/{chunk-EMB55BDF.js → chunk-D3NJXN5M.js} +2 -2
  16. package/dist/hooks/{chunk-7KMN5QB5.js → chunk-EF5GQ6WS.js} +3 -3
  17. package/dist/hooks/{chunk-2G5F2YCD.js → chunk-LBFYEOXJ.js} +3 -3
  18. package/dist/hooks/{chunk-XER6SSIB.js → chunk-MBJYQPEK.js} +16 -6
  19. package/dist/hooks/{chunk-QL6QTPWN.js → chunk-NO4AALP5.js} +3 -3
  20. package/dist/hooks/{chunk-4BHUPFKF.js → chunk-OLMO72ON.js} +1 -1
  21. package/dist/hooks/{chunk-MSYSUSY6.js → chunk-SHYUQOIS.js} +5 -5
  22. package/dist/hooks/{chunk-5SJSSCJG.js → chunk-UT7YC3N2.js} +1 -1
  23. package/dist/hooks/{chunk-MU4LJFIV.js → chunk-W5ZKGTSY.js} +3 -3
  24. package/dist/hooks/{chunk-YZXYOAZ3.js → chunk-Y3GKIKGW.js} +11 -5
  25. package/dist/hooks/{chunk-YW452ZAX.js → chunk-Z4XI7CZS.js} +2 -2
  26. package/dist/hooks/codex-hook-adapter.js +13 -13
  27. package/dist/hooks/duplicate-read-guard.js +7 -7
  28. package/dist/hooks/format-edited.js +3 -3
  29. package/dist/hooks/inputs.json +241 -240
  30. package/dist/hooks/investigation-guard.js +7 -7
  31. package/dist/hooks/pretool-guard.js +12 -12
  32. package/dist/hooks/session-lang.js +3 -3
  33. package/dist/hooks/stop-guard.js +6 -6
  34. package/dist/josh.js +33 -10
  35. package/package.json +1 -1
  36. package/prompts/collaboration-workflow/issue-template.md +10 -8
  37. package/prompts/review.md +8 -4
  38. package/scripts/auto-ok/auto-ok-judge-cli.ts +125 -0
  39. package/scripts/auto-ok/auto-ok-judge-read.ts +95 -0
  40. package/scripts/auto-ok/auto-ok-judge-write.ts +109 -0
  41. package/scripts/auto-ok/auto-ok-judge.ts +67 -0
  42. package/scripts/backlog/backlog-drive-cli.ts +14 -0
  43. package/scripts/backlog/backlog-drive.ts +22 -3
  44. package/scripts/document/document-byte-budget.ts +1 -1
  45. package/scripts/fresh-machine/fresh-machine-patterns.ts +60 -15
  46. package/scripts/gate/project-checks.ts +5 -2
  47. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  48. package/scripts/gh/git-gh-issue.ts +9 -0
  49. package/scripts/init/init-actions.ts +3 -3
  50. package/scripts/init/init-ai-copy.ts +1 -1
  51. package/scripts/init/init-basic.ts +1 -1
  52. package/scripts/init/init-bootstrap.ts +6 -2
  53. package/scripts/init/init-dry-run-report.ts +150 -0
  54. package/scripts/init/init-dry-run.ts +189 -0
  55. package/scripts/init/init-install.ts +8 -1
  56. package/scripts/init/init.ts +57 -19
  57. package/scripts/init/kit-setup-state.ts +11 -17
  58. package/scripts/init/own-formatter.ts +21 -0
  59. package/scripts/init/project-profile.ts +25 -6
  60. package/scripts/init/start-dry-run.ts +70 -0
  61. package/scripts/init/start-plan.ts +8 -3
  62. package/scripts/init/start-setup-pr.ts +13 -24
  63. package/scripts/init/start-steps.ts +16 -1
  64. package/scripts/init/start.ts +38 -18
  65. package/scripts/init/working-tree.ts +116 -0
  66. package/scripts/issue/issue-auto-ok.ts +68 -99
  67. package/scripts/issue/issue-file-cli.ts +17 -17
  68. package/scripts/issue/issue-file.ts +1 -6
  69. package/scripts/issue/issue-labels.ts +6 -2
  70. package/scripts/issue/issue-release-cli.ts +69 -23
  71. package/scripts/issue/issue-release.ts +3 -1
  72. package/scripts/josh/josh-commands-ai.ts +11 -0
  73. package/scripts/josh/josh-commands-issue.ts +3 -3
  74. package/scripts/josh/josh-commands-project.ts +2 -2
  75. package/scripts/josh/process-identity.ts +32 -6
  76. package/scripts/lane/lane-broker-server.ts +69 -0
  77. package/scripts/lane/lane-session-broker.ts +37 -14
  78. package/scripts/observations/observation-ledger-migrate.ts +3 -15
  79. package/scripts/release/release-issue-close.ts +133 -0
  80. package/scripts/release/release-publish.ts +12 -1
  81. package/scripts/repo/repository-labels.ts +11 -1
  82. package/scripts/review/comment-ranges.ts +199 -0
  83. package/scripts/review/review-brief-cli.ts +22 -5
  84. package/scripts/review/review-code-tree.ts +119 -0
  85. package/scripts/review/review-round2-cli.ts +16 -5
  86. package/scripts/review/review-round2.ts +30 -10
  87. package/scripts/review/review-stamps.ts +22 -1
  88. package/scripts/uninstall/distributed-files.ts +1 -1
@@ -9,14 +9,14 @@ import { review_level } from './review-level'
9
9
  //
10
10
  // **The two arms are the two states in which round 2's reason does not arise.** Round 2 exists
11
11
  // because round 1's *fix code* is unreviewed, and that is structural. Arm A applies where there is no fix code — the findings closed without an edit — so
12
- // the premise is absent rather than overridden. Arm B applies where the fix code neither executes,
13
- // nor instructs, nor ships, which is `review-level.ts`'s inert set: the same three ways a defect in
14
- // this repository escapes, read here for the fix delta instead of the whole change.
12
+ // the premise is absent rather than overridden. Arm B applies where the fix leaves what executes
13
+ // unchanged: `review-level.ts`'s inert set, documentation under `docs/` and the root `README.md`,
14
+ // `prompts/`, and source files whose only change is in comments (`review-code-tree.ts`).
15
15
  //
16
- // **The wider line — "the fix delta touches no runtime code path" — is not adopted**: as
17
- // `review-level.ts` records, documentation-only diffs carry real defects no test covers. A prompt
18
- // fix and a test fix are exactly where the review is the only detector, so exempting them would
19
- // remove the round in the case it earns its keep.
16
+ // **Arm B is wider than the review level's inert set, on purpose** (joshuafolkken/kit#3787). Round 1
17
+ // still reviews a documentation or prompt change in full, and the fix to its findings is still made;
18
+ // what goes unread is only that fix. `.claude/**`, `CLAUDE.md`, tests and configuration stay outside:
19
+ // a test fix can weaken the verification it belongs to, and nothing reads that but the review.
20
20
 
21
21
  type RoundTwoVerdict = 'required' | 'skip'
22
22
 
@@ -33,7 +33,11 @@ const NO_SNAPSHOT_REASON =
33
33
  const EMPTY_DELTA_REASON_PREFIX =
34
34
  'the fix delta is empty: round 1 wrote no fix code, so there is no unreviewed fix for a verification pass to read'
35
35
  const INERT_DELTA_REASON_PREFIX =
36
- 'every path round 1 fixed is inert — it neither executes, nor instructs, nor ships'
36
+ 'every path round 1 fixed leaves what executes unchanged — inert, documentation, a prompt, or a comment-only edit'
37
+ const README_PATH = 'README.md'
38
+ const DOCUMENTATION_PREFIX = 'docs/'
39
+ const MARKDOWN_EXTENSION = '.md'
40
+ const PROMPTS_PREFIX = 'prompts/'
37
41
  const BASE_MOVED_REASON =
38
42
  'the change base moved since round 1 was recorded, so the two file maps do not cover the same set of paths and their difference is not the fix delta — the round runs rather than reading that difference as one'
39
43
 
@@ -51,6 +55,9 @@ interface RoundTwoInput {
51
55
  is_round_one_closed: boolean
52
56
  snapshot: FileMapStamp | undefined
53
57
  tree: Record<string, string>
58
+ // The paths whose code round 1's fixes left as it was (`review_code_tree.comment_only`). Absent is
59
+ // none, which is what a run without a code record pays.
60
+ comment_only?: ReadonlyArray<string>
54
61
  }
55
62
 
56
63
  interface RoundTwoDecision {
@@ -86,13 +93,26 @@ function live_reason(deciding: ReadonlyArray<string>): string {
86
93
  return `round 1's fixes touched paths that execute, instruct or ship: ${path_decision.format_path_list(deciding)}`
87
94
  }
88
95
 
96
+ function is_documentation(relative: string): boolean {
97
+ if (relative === README_PATH || relative.startsWith(PROMPTS_PREFIX)) return true
98
+
99
+ return relative.startsWith(DOCUMENTATION_PREFIX) && relative.endsWith(MARKDOWN_EXTENSION)
100
+ }
101
+
102
+ function is_unexecuted(relative: string, comment_only: ReadonlyArray<string>): boolean {
103
+ if (review_level.is_inert(relative) || is_documentation(relative)) return true
104
+
105
+ return comment_only.includes(relative)
106
+ }
107
+
89
108
  function verdict_for_delta(
90
109
  delta: ReadonlyArray<string>,
91
110
  taken_at: string,
111
+ comment_only: ReadonlyArray<string> = [],
92
112
  ): { verdict: RoundTwoVerdict; reason: string } {
93
113
  if (delta.length === 0) return { verdict: SKIPPED_VERDICT, reason: empty_reason(taken_at) }
94
114
 
95
- const deciding = delta.filter((relative) => !review_level.is_inert(relative))
115
+ const deciding = delta.filter((relative) => !is_unexecuted(relative, comment_only))
96
116
 
97
117
  if (deciding.length === 0) return { verdict: SKIPPED_VERDICT, reason: inert_reason(delta) }
98
118
 
@@ -110,7 +130,7 @@ function decide(input: RoundTwoInput): RoundTwoDecision {
110
130
 
111
131
  const delta = file_map_stamp.changed_since(input.snapshot, input.tree)
112
132
 
113
- return { ...verdict_for_delta(delta, input.snapshot.taken_at), delta }
133
+ return { ...verdict_for_delta(delta, input.snapshot.taken_at, input.comment_only), delta }
114
134
  }
115
135
 
116
136
  const review_round2 = {
@@ -13,11 +13,17 @@ const TEST_RELATED_PREFIX = 'josh-test-related-stamp-'
13
13
  const GATE_PREFIX = 'josh-gate-stamp-'
14
14
  const IN_FLIGHT_PREFIX = 'josh-gate-running-'
15
15
  const ROUND_ONE_PREFIX = 'josh-review-round1-'
16
+ const ROUND_ONE_CODE_PREFIX = 'josh-review-round1-code-'
16
17
  const BRIEFED_PREFIX = 'josh-review-briefed-'
17
18
 
18
19
  const gate_stamp: FileMapStampAccess = file_map_stamp.create(GATE_PREFIX, PROJECT_ROOT)
19
20
  const in_flight_stamp: FileMapStampAccess = file_map_stamp.create(IN_FLIGHT_PREFIX, PROJECT_ROOT)
20
21
  const round_one_stamp: FileMapStampAccess = file_map_stamp.create(ROUND_ONE_PREFIX, PROJECT_ROOT)
22
+ // Written beside the round-1 snapshot: the comment-free digest of each source file (`review-code-tree.ts`).
23
+ const round_one_code_stamp: FileMapStampAccess = file_map_stamp.create(
24
+ ROUND_ONE_CODE_PREFIX,
25
+ PROJECT_ROOT,
26
+ )
21
27
  // Retaken on every brief: the round-1 snapshot is not the tree a later review read.
22
28
  const briefed_stamp: FileMapStampAccess = file_map_stamp.create(BRIEFED_PREFIX, PROJECT_ROOT)
23
29
  const lint_related_stamp: FileMapStampAccess = file_map_stamp.create(
@@ -29,24 +35,39 @@ const test_related_stamp: FileMapStampAccess = file_map_stamp.create(
29
35
  PROJECT_ROOT,
30
36
  )
31
37
 
38
+ // Swallowed: a code record left behind only ever sits beside an older snapshot, which the next
39
+ // round-1 brief replaces together with it.
40
+ function clear_round_one_code(target?: string): void {
41
+ try {
42
+ round_one_code_stamp.remove(target)
43
+ } catch {
44
+ /* the next round-1 brief overwrites it */
45
+ }
46
+ }
47
+
32
48
  // Called only from the end of a merged run: a leftover widens the next delta (safe), while an early
33
49
  // removal lets round 1 re-snapshot an already-fixed tree (unsafe). Swallowed — the PR already merged.
34
- function clear_round_one(target?: string): void {
50
+ function clear_round_one(target?: string, code_target?: string): void {
35
51
  try {
36
52
  round_one_stamp.remove(target)
37
53
  } catch {
38
54
  /* a record left behind widens the next round rather than narrowing it */
39
55
  }
56
+
57
+ clear_round_one_code(code_target)
40
58
  }
41
59
 
42
60
  const review_stamps = {
43
61
  briefed_stamp,
44
62
  clear_round_one,
63
+ clear_round_one_code,
45
64
  GATE_PREFIX,
46
65
  gate_stamp,
47
66
  IN_FLIGHT_PREFIX,
48
67
  in_flight_stamp,
49
68
  lint_related_stamp,
69
+ ROUND_ONE_CODE_PREFIX,
70
+ round_one_code_stamp,
50
71
  ROUND_ONE_PREFIX,
51
72
  round_one_stamp,
52
73
  test_related_stamp,
@@ -17,7 +17,7 @@ function widest_shape(profile: ProjectProfile): ProjectShape {
17
17
  return {
18
18
  profile,
19
19
  reason: 'josh uninstall',
20
- has_web: true,
20
+ should_use_prettier: true,
21
21
  has_typescript: true,
22
22
  has_git: true,
23
23
  has_github: true,