@joshuafolkken/kit 1.978.0 → 1.983.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 (69) hide show
  1. package/.claude/skills/epic-commands/SKILL.md +6 -5
  2. package/.claude/skills/workflow-commands/SKILL.md +9 -9
  3. package/.claude/skills/workflow-commands/background-commands.md +1 -1
  4. package/.claude/skills/workflow-commands/fullrun-steps.md +8 -8
  5. package/.claude/skills/workflow-commands/halfrun.md +4 -5
  6. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  7. package/.claude/skills/workflow-commands/issue-scout.md +21 -22
  8. package/.claude/skills/workflow-commands/kickoff.md +8 -9
  9. package/.claude/skills/workflow-commands/observation-filing.md +9 -10
  10. package/.claude/skills/workflow-commands/prerequisite.md +7 -6
  11. package/.claude/skills/workflow-commands/retrospective.md +5 -5
  12. package/.claude/skills/workflow-commands/rule-residency.md +2 -2
  13. package/.claude/skills/workflow-commands/split-assessment.md +4 -3
  14. package/.claude/skills/workflow-commands/target-repository.md +7 -6
  15. package/dist/hooks/batch-guard.js +4 -4
  16. package/dist/hooks/{chunk-ZPLXLJ7O.js → chunk-47SPMGOD.js} +16 -1
  17. package/dist/hooks/{chunk-BVMSPG3M.js → chunk-5JX6HXDX.js} +3 -3
  18. package/dist/hooks/{chunk-KQG4776P.js → chunk-APVOACVT.js} +1 -1
  19. package/dist/hooks/{chunk-2K52BRWV.js → chunk-ASUZGZFT.js} +2 -2
  20. package/dist/hooks/{chunk-CRGJTD6E.js → chunk-ERXMJJOV.js} +1 -1
  21. package/dist/hooks/{chunk-Q7LE77CO.js → chunk-IM3KM25Y.js} +31 -29
  22. package/dist/hooks/{chunk-BNGGEY3Z.js → chunk-LBXQHXMC.js} +129 -342
  23. package/dist/hooks/{chunk-NXL3SBXY.js → chunk-P3UX7SFN.js} +2 -2
  24. package/dist/hooks/{chunk-F6OM6SIG.js → chunk-RFPHKU7C.js} +12 -12
  25. package/dist/hooks/{chunk-ZYYSBNR6.js → chunk-ZT65LR3U.js} +4 -4
  26. package/dist/hooks/codex-hook-adapter.js +10 -10
  27. package/dist/hooks/duplicate-read-guard.js +5 -5
  28. package/dist/hooks/format-edited.js +2 -2
  29. package/dist/hooks/investigation-guard.js +5 -5
  30. package/dist/hooks/pretool-guard.js +9 -9
  31. package/dist/hooks/stop-guard.js +4 -4
  32. package/dist/josh.js +16 -1
  33. package/package.json +1 -1
  34. package/prompts/collaboration-workflow/epic-bundle.md +8 -8
  35. package/prompts/collaboration-workflow/issue-template.md +5 -5
  36. package/prompts/collaboration-workflow/rule-delivery.md +43 -30
  37. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  38. package/prompts/collaboration-workflow/wip-cap.md +3 -3
  39. package/prompts/review.md +11 -9
  40. package/scripts/delegation/delegation-policy.ts +9 -9
  41. package/scripts/document/document-byte-budget.ts +1 -1
  42. package/scripts/issue/issue-file-cli.ts +188 -0
  43. package/scripts/issue/issue-file.ts +192 -0
  44. package/scripts/issue/issue-lint-cli.ts +1 -1
  45. package/scripts/issue/issue-scout-cli.ts +41 -97
  46. package/scripts/issue/issue-scout-closed.ts +102 -0
  47. package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +9 -1
  48. package/scripts/josh/josh-command-map.ts +1 -0
  49. package/scripts/josh/josh-commands-issue.ts +11 -0
  50. package/scripts/josh/josh-commands-project.ts +5 -1
  51. package/scripts/propagate/propagate-run.ts +1 -0
  52. package/scripts/propagate/propagate-select.ts +72 -0
  53. package/scripts/propagate/propagate-targets.ts +5 -3
  54. package/scripts/propagate/propagate.ts +86 -24
  55. package/scripts/rules/bash-triggers.ts +19 -6
  56. package/scripts/rules/delivered-rules.ts +28 -32
  57. package/scripts/rules/direct-filing.ts +38 -0
  58. package/scripts/rules/filing-cap.ts +11 -8
  59. package/scripts/rules/issue-fold.ts +4 -4
  60. package/scripts/rules/oracle-consulted.ts +4 -4
  61. package/scripts/rules/oracle-firing.ts +13 -16
  62. package/scripts/rules/rule-body-guard.ts +6 -9
  63. package/scripts/rules/stop-rules.ts +3 -2
  64. package/scripts/test/pilot-files.ts +0 -1
  65. package/scripts/version/fresh-metadata-cache.ts +36 -0
  66. package/scripts/version/latest-update.ts +2 -1
  67. package/scripts/rules/issue-bug-label.ts +0 -85
  68. package/scripts/rules/issue-filing-args.ts +0 -50
  69. package/scripts/rules/issue-scout.ts +0 -64
@@ -1,50 +0,0 @@
1
- const SHELL_WORD = /(?:[^\s'"]|'[^']*'|"[^"]*")+/gu
2
- const QUOTE = /['"]/gu
3
- const RAW_FIELDS = new Set(['-f', '--raw-field'])
4
- const FILE_FIELDS = new Set(['-F', '--field'])
5
- const LABEL_OPTIONS = new Set(['-l', '--label'])
6
- const BODY_FILE_OPTIONS = new Set(['--body-file'])
7
- const INLINE_BODY_OPTIONS = new Set(['-b', '--body'])
8
- const BODY_FILE_PREFIX = 'body=@'
9
-
10
- function words_of(command: string): Array<string> {
11
- return [...command.matchAll(SHELL_WORD)].map((match) => match[0].replaceAll(QUOTE, ''))
12
- }
13
-
14
- function values_after(words: ReadonlyArray<string>, flags: ReadonlySet<string>): Array<string> {
15
- return words.flatMap((word, index) => {
16
- const value = words[index + 1]
17
-
18
- return value !== undefined && flags.has(word) ? [value] : []
19
- })
20
- }
21
-
22
- function has_inline_body(words: ReadonlyArray<string>): boolean {
23
- const has_raw = values_after(words, RAW_FIELDS).some((value) => value.startsWith('body='))
24
-
25
- return has_raw || values_after(words, INLINE_BODY_OPTIONS).length > 0
26
- }
27
-
28
- function body_file(command: string): string | undefined {
29
- const words = words_of(command)
30
- const fields = values_after(words, FILE_FIELDS).filter((value) => value.startsWith('body='))
31
- const options = values_after(words, BODY_FILE_OPTIONS)
32
-
33
- if (has_inline_body(words) || fields.length + options.length !== 1) return undefined
34
-
35
- return fields[0]?.startsWith(BODY_FILE_PREFIX)
36
- ? fields[0].slice(BODY_FILE_PREFIX.length)
37
- : options[0]
38
- }
39
-
40
- function has_label(command: string, label: string): boolean {
41
- const words = words_of(command)
42
- const fields = [...values_after(words, RAW_FIELDS), ...values_after(words, FILE_FIELDS)]
43
- const options = values_after(words, LABEL_OPTIONS).flatMap((value) => value.split(','))
44
-
45
- return fields.includes(`labels[]=${label}`) || options.includes(label)
46
- }
47
-
48
- const issue_filing_args = { body_file, has_label, words_of }
49
-
50
- export { issue_filing_args }
@@ -1,64 +0,0 @@
1
- import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
2
- import { bash_triggers } from './bash-triggers'
3
- import { shell_segments } from './shell-segments'
4
- import { tail_commands } from './tail-commands'
5
-
6
- // The trigger and the delivered text behind the `issue-scout` row of `delivered-rules.ts`
7
- // (joshuafolkken/kit#2119).
8
- //
9
- // **A filing without `pnpm josh issue:scout` in front of it, refused at the filing itself.** §2e
10
- // requires the scout before every `gh api … issues` call, and a duplicate is likeliest for the work
11
- // that just finished — the one case self-restraint is least able to catch. The input is mechanical —
12
- // did the run already run the scout — so it is a delivered rule rather than resident prose.
13
- //
14
- // **It is `issue-comments`'s shape, not the WIP cap's.** Like that row it is once per run with an
15
- // `already_satisfied` stand-down read off the tail, and the refusal hands over the command rather than
16
- // asking the run to "scout first" — a body-only read is refused so the reissue makes the comments
17
- // present, and here a scout-less filing is refused so the reissue makes the scout present. **No new
18
- // delivery path**: the trigger is `bash_triggers.is_issue_filing`, reused verbatim.
19
-
20
- // `pnpm josh issue:scout`, the one act the rule asks for. The alias `isc` is expanded where the
21
- // command is read, so the canonical name matches both spellings (joshuafolkken/kit#1789).
22
- const SCOUT_NAMES: ReadonlySet<string> = new Set(['issue:scout'])
23
-
24
- // Keeping the rule: a call that runs the scout. Segment-wise, so a spelling quoted inside a filing's
25
- // own body is not read as the scout that filing skipped.
26
- function runs_the_scout(command: string): boolean {
27
- return shell_segments
28
- .segments_of(command)
29
- .some((segment) => shell_segments.is_josh_command(segment, SCOUT_NAMES))
30
- }
31
-
32
- // The `already_satisfied` stand-down: the run has already scouted, so this filing asks for nothing new.
33
- // The tool-name gate the row's trigger applies has already passed, so `call` only marks the shape; the
34
- // answer is entirely in the tail.
35
- function already_scouted(tail: string, _call: GuardedCall): boolean {
36
- return tail_commands.prior_bash_commands(tail).some((command) => runs_the_scout(command))
37
- }
38
-
39
- // The instruction in the shape a refusal can carry: what the call skipped, why it matters most here,
40
- // and the command that fixes it. The duplicate risk is named because it is the half that makes the
41
- // rule believable — the filing most likely to duplicate is the one about work that just finished.
42
- const ISSUE_SCOUT_REASON =
43
- '⛔ issue scout: this files an Issue with no `pnpm josh issue:scout` earlier in the run. A ' +
44
- 'duplicate is likeliest for the work that just finished, which is exactly where self-restraint is ' +
45
- 'weakest. Reissue after scouting: `pnpm josh issue:scout "<title>"` (add `--body "<one-line ' +
46
- 'summary, citing #N where the work follows one>"` so the epic half can answer), then read its ' +
47
- '`Duplicates:` — an **open** candidate covering the same work stops the run rather than filing a ' +
48
- 'second Issue, and a `(closed)` one means the work is already done — before reissuing this filing. ' +
49
- 'The procedure is `.claude/skills/workflow-commands/SKILL.md` → §2e. It fires once per run and ' +
50
- 'cannot repeat on the call in hand.'
51
-
52
- // The enumeration row itself, so `delivered-rules.ts` spreads one entry rather than restating the
53
- // trigger and reason it already single-sources here. Once per run with the stand-down above.
54
- const ROW = {
55
- id: 'issue-scout',
56
- is_trigger: bash_triggers.on_bash_command(bash_triggers.is_issue_filing),
57
- reason: ISSUE_SCOUT_REASON,
58
- already_satisfied: already_scouted,
59
- keeps: bash_triggers.on_bash_command(runs_the_scout),
60
- }
61
-
62
- const issue_scout = { ISSUE_SCOUT_REASON, ROW, already_scouted, runs_the_scout }
63
-
64
- export { issue_scout }