@joshuafolkken/kit 1.1370.0 → 1.1373.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 (36) hide show
  1. package/.claude/skills/workflow-commands/backlogrun-steps.md +1 -1
  2. package/.claude/skills/workflow-commands/backlogrun.md +6 -4
  3. package/README.md +11 -36
  4. package/dist/commands/document-section-cli.js +1 -1
  5. package/dist/hooks/batch-guard.js +3 -3
  6. package/dist/hooks/{chunk-43G45XJF.js → chunk-7UBFU3CL.js} +1 -1
  7. package/dist/hooks/{chunk-KPM4YIIX.js → chunk-7WKYHEGU.js} +1 -1
  8. package/dist/hooks/{chunk-4TW4MQUL.js → chunk-AKGCP4LX.js} +9 -9
  9. package/dist/hooks/{chunk-NZBHG6FW.js → chunk-BZMPVFDY.js} +3 -3
  10. package/dist/hooks/{chunk-76RK6E3H.js → chunk-JCRDBQXB.js} +2 -2
  11. package/dist/hooks/{chunk-DZWZ3DKY.js → chunk-JGW24KKM.js} +2 -2
  12. package/dist/hooks/{chunk-TLJYAGZK.js → chunk-SLSFIWTX.js} +1 -1
  13. package/dist/hooks/{chunk-SYSRHRWU.js → chunk-UTHMB4O2.js} +1 -0
  14. package/dist/hooks/{chunk-R6CRQEAL.js → chunk-V4TKZHER.js} +2 -2
  15. package/dist/hooks/{chunk-MXVQMLDP.js → chunk-YLBBSSTF.js} +2 -2
  16. package/dist/hooks/codex-hook-adapter.js +10 -10
  17. package/dist/hooks/duplicate-read-guard.js +4 -4
  18. package/dist/hooks/format-edited.js +2 -2
  19. package/dist/hooks/inputs.json +190 -190
  20. package/dist/hooks/investigation-guard.js +4 -4
  21. package/dist/hooks/pretool-guard.js +9 -9
  22. package/dist/hooks/session-lang.js +1 -1
  23. package/dist/hooks/stop-guard.js +4 -4
  24. package/dist/josh.js +1 -1
  25. package/package.json +4 -4
  26. package/scripts/document/document-scan.ts +4 -3
  27. package/scripts/josh/josh-commands-run.ts +1 -1
  28. package/scripts/lint/cross-file-recheck.ts +155 -0
  29. package/scripts/lint/lint-parallel.ts +10 -9
  30. package/scripts/lint/lint-related-scope.ts +4 -4
  31. package/scripts/lint/lint-related.ts +1 -1
  32. package/scripts/rules/decision-oracle-batch.ts +1 -1
  33. package/scripts/run/run-headless.ts +1 -0
  34. package/scripts/run/run-step-cli.ts +51 -3
  35. package/scripts/run/run-step.ts +49 -4
  36. package/scripts/lint/cycle-recheck.ts +0 -122
@@ -70,7 +70,7 @@ and `--filed 1`, and **`--cut` is the session's last write**.
70
70
 
71
71
  | It answers | What the run does |
72
72
  | --- | --- |
73
- | `began` | Report the plan and run the decision pass |
73
+ | `began` | Report the plan and run the decision pass, then run what the bare `pnpm josh run:step` prints — an empty plan or a `none` from `backlog:next` included, which the driver's idle watch ends, never the session |
74
74
  | `resumed` | Take the budget from `--json`, report the plan again, read `backlogrun-progress.md` → "Resuming after a cut" |
75
75
  | `busy` / `mismatch` / `unreadable` / `unknown` | **Stop; do not open a lane** — report what it printed; never resume into another invocation's record |
76
76
  | `over` | **End the conversation**; retype the invocation in a fresh session |
@@ -13,7 +13,8 @@ that same backlog. **`--only` stops it after the named list**, draining nothing.
13
13
 
14
14
  **The loop's current position is computed, not carried in the conversation.** `pnpm josh run:step <N>`
15
15
  reads where the run is from the event stream, the carry record and the issue state, and prints the next
16
- single action — a runnable command, or the one point a person has to judge.
16
+ single action — a runnable command, or the one point a person has to judge. **With no `<N>` it answers
17
+ for the parent itself**, from the carry record alone.
17
18
 
18
19
  **A named item may be a single issue or an epic.** A single-issue item is one `fullrun`; **a named epic runs its children in
19
20
  dependency order across the free lanes, and the run does not advance to the next named item until
@@ -40,10 +41,11 @@ is still that one invocation (`backlogrun-steps.md` → "The session cut is insi
40
41
  `run:lane` in the same pass.
41
42
  5. **Named issues run first, in order** — each as a delegated `fullrun`, one at a time, then the pool;
42
43
  `--only` stops after the list.
43
- 6. **The loop belongs to the supervisor** — `run:wake` runs `backlog:drive`, which returns a branch to
44
- an AI session only when it needs judgment.
44
+ 6. **The loop belongs to the supervisor — hand it over with what the bare `pnpm josh run:step`
45
+ prints**, whatever the plan held: `run:wake` runs `backlog:drive`, which returns a branch to an AI
46
+ session only when it needs judgment.
45
47
  7. **End the record when the run ends** — `run:report`, then `run:carry --end` (or `--end --stopped
46
- "<reason>"`) and `run:wake --stop`.
48
+ "<reason>"`) and `run:wake --stop`. An empty plan is not that end; the driver's idle watch decides it.
47
49
 
48
50
  ## The route table
49
51
 
package/README.md CHANGED
@@ -1,34 +1,25 @@
1
1
  # @joshuafolkken/kit
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@joshuafolkken/kit)](https://www.npmjs.com/package/@joshuafolkken/kit)
4
- [![CI](https://github.com/joshuafolkken/kit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/joshuafolkken/kit/actions/workflows/ci.yml)
5
- [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=joshuafolkken_kit&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=joshuafolkken_kit)
6
-
7
3
  **AI assistant setup, plus an optional GitHub workflow.**
8
4
 
9
- kit gives Claude Code or Codex your project's rules and checks. With the workflow, the agent takes each change from Issue to merged PR.
5
+ kit gives Claude Code or Codex your project's rules and checks.
6
+
7
+ ## The workflow
8
+
9
+ Type `backlogrun` and the agent takes the Issues you name from plan to merged PR — in parallel, unattended. A live board shows where each one stands:
10
+
11
+ ![The backlogrun board: ten Issues running side by side, seven already merged, each with its stage and elapsed time](./docs/images/backlogrun-board.png)
12
+
13
+ [Every keyword, including the ones that stop for you earlier](./docs/how-to/run-issues.md)
10
14
 
11
15
  ## Sound familiar?
12
16
 
13
17
  [The whole story](./docs/why.md)
14
18
 
15
- ### Working with an AI agent
16
-
17
19
  - [I keep repeating the same instructions](./docs/why.md#i-keep-repeating-the-same-instructions)
18
20
  - [The agent does things I never asked for](./docs/why.md#the-agent-does-things-i-never-asked-for)
19
- - [Reviewing every change is a chore](./docs/why.md#reviewing-every-change-is-a-chore)
20
-
21
- ### With the GitHub workflow
22
-
23
21
  - [Wiring AI up to GitHub is a chore](./docs/why.md#wiring-ai-up-to-github-is-a-chore)
24
- - [Writing Issues is a chore](./docs/why.md#writing-issues-is-a-chore)
25
- - [Big requests come back sloppy](./docs/why.md#big-requests-come-back-sloppy)
26
-
27
- ### Writing TypeScript
28
-
29
22
  - [Done doesn't mean done](./docs/why.md#done-doesnt-mean-done)
30
- - [Quality slips with every change](./docs/why.md#quality-slips-with-every-change)
31
- - [Updating dependencies keeps breaking things](./docs/why.md#updating-dependencies-keeps-breaking-things)
32
23
 
33
24
  ## Quick start
34
25
 
@@ -54,24 +45,8 @@ pnpm --allow-build=esbuild dlx @joshuafolkken/kit init
54
45
 
55
46
  Next: [tutorial](./docs/tutorial.md#without-github-one-change-checked-locally)
56
47
 
57
- ## The workflow
58
-
59
- | You type | The agent |
60
- | ------------ | ------------------------------------------------ |
61
- | `kickoff` | Writes the plan on the Issue, then stops |
62
- | `halfrun` | Implements and self-reviews, stops before commit |
63
- | `prrun` | Opens a green pull request, stops before merge |
64
- | `fullrun` | Plans if needed, implements through to merge |
65
- | `backlogrun` | Runs many Issues unattended |
66
-
67
- [Each keyword in full](./docs/how-to/run-issues.md) · [Telegram notifications when a run needs you](./docs/how-to/set-up-notifications.md)
68
-
69
48
  ## Docs
70
49
 
71
- [How-to](./docs/how-to.md) · [Commands](./docs/josh-commands.md) · [Troubleshooting](./docs/troubleshooting.md) · [All docs](./docs/overview.md)
72
-
73
- [app-kit](https://github.com/joshuafolkken/app-kit) · [game-kit](https://github.com/joshuafolkken/game-kit) · [Releases](https://github.com/joshuafolkken/kit/releases) · [Security](./SECURITY.md) · [Contributing](./docs/maintainers/README.md) · [MIT](./LICENSE)
50
+ [How-to](./docs/how-to.md) · [All docs](./docs/overview.md)
74
51
 
75
- [![Node.js](https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjoshuafolkken%2Fkit%2Fmain%2Fpackage.json&search=%22node%22%3A%20%22%5C%5E%28%5B0-9%5D%2B%5C.%5B0-9%5D%2B%29%5B0-9.%5D%2A%20%5C%7C%5C%7C%20%5C%5E%28%5B0-9%5D%2B%29%5B0-9.%5D%2A%20%5C%7C%5C%7C%20%3E%3D%28%5B0-9%5D%2B%29&replace=%5E%241%20%7C%20%5E%242%20%7C%20%3E%3D%243&logo=nodedotjs&label=Node.js)](https://nodejs.org/)
76
- [![TypeScript](https://img.shields.io/npm/dependency-version/@joshuafolkken/kit/peer/typescript?logo=typescript)](https://www.typescriptlang.org/)
77
- [![pnpm](https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fraw.githubusercontent.com%2Fjoshuafolkken%2Fkit%2Fmain%2Fpackage.json&search=pnpm%40%28%5B0-9.%5D%2B%29&replace=%241&logo=pnpm&label=pnpm)](https://pnpm.io/)
52
+ [app-kit](https://github.com/joshuafolkken/app-kit) · [game-kit](https://github.com/joshuafolkken/game-kit) · [Releases](https://github.com/joshuafolkken/kit/releases) · [Contributing](./docs/maintainers/README.md)
@@ -117,7 +117,7 @@ var SECTION_PATTERN = /(?<![\w./:`-])(?<tick>`?)(?<file>[\w./-]+\.md)\k<tick>\s*
117
117
  var ADJACENT_PATTERN = /["「](?<heading>[^"「」]+)["」]\s+(?:above|below)\b/gu;
118
118
  var BARE_ARROW_PATTERN = /→\s*(?:§\w+,\s*)?["「](?<heading>[^"「」]+)["」]/gu;
119
119
  var LINK_TARGET_PATTERN = /\]\([^)\s]*\)/gu;
120
- var LINK_PATTERN = /\]\(([\w./-]+\.md)(?:#[\w-]+)?\)/gu;
120
+ var LINK_PATTERN = /\]\(([\w./-]+\.(?:md|png|jpe?g|gif|svg|webp))(?:#[\w-]+)?\)/gu;
121
121
  var PLACEHOLDER_FILES = /* @__PURE__ */ new Set(["x.md", "foo.md", "file.md", "path.md"]);
122
122
  function matches(text, pattern) {
123
123
  return [...text.matchAll(pattern)];
@@ -9,10 +9,10 @@ import {
9
9
  load_environment_file,
10
10
  notice_refusal_path,
11
11
  refusal_path
12
- } from "./chunk-DZWZ3DKY.js";
12
+ } from "./chunk-JGW24KKM.js";
13
13
  import "./chunk-GG72ANKI.js";
14
- import "./chunk-KPM4YIIX.js";
15
- import "./chunk-TLJYAGZK.js";
14
+ import "./chunk-7WKYHEGU.js";
15
+ import "./chunk-SLSFIWTX.js";
16
16
  import "./chunk-Z5TMJIPW.js";
17
17
  import "./chunk-NZN2UFI6.js";
18
18
  import "./chunk-NEC4AT4Z.js";
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  ESLINT_EDIT_CACHE_FLAGS,
7
7
  time_density_hook
8
- } from "./chunk-TLJYAGZK.js";
8
+ } from "./chunk-SLSFIWTX.js";
9
9
  import {
10
10
  file_reader,
11
11
  json_value
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  time_density_hook,
3
3
  time_hook_transcript
4
- } from "./chunk-TLJYAGZK.js";
4
+ } from "./chunk-SLSFIWTX.js";
5
5
  import {
6
6
  josh_environment_file
7
7
  } from "./chunk-Z5TMJIPW.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  duplicate_read_outcome
3
- } from "./chunk-NZBHG6FW.js";
3
+ } from "./chunk-BZMPVFDY.js";
4
4
  import {
5
5
  ALREADY_DONE_LABEL,
6
6
  CONTEXT_CUT_THRESHOLD,
@@ -28,7 +28,7 @@ import {
28
28
  session_cite,
29
29
  shell_segments,
30
30
  tail_commands
31
- } from "./chunk-MXVQMLDP.js";
31
+ } from "./chunk-YLBBSSTF.js";
32
32
  import {
33
33
  ancestor_directories,
34
34
  find_local_bin_upwards
@@ -41,25 +41,25 @@ import {
41
41
  lane_registry,
42
42
  repo_origin,
43
43
  run_headless
44
- } from "./chunk-SYSRHRWU.js";
44
+ } from "./chunk-UTHMB4O2.js";
45
45
  import {
46
46
  error_text
47
47
  } from "./chunk-CDY4NFQG.js";
48
48
  import {
49
49
  batch_outcome
50
- } from "./chunk-DZWZ3DKY.js";
50
+ } from "./chunk-JGW24KKM.js";
51
51
  import {
52
52
  investigation_refusal
53
- } from "./chunk-R6CRQEAL.js";
53
+ } from "./chunk-V4TKZHER.js";
54
54
  import {
55
55
  investigation_reads
56
- } from "./chunk-76RK6E3H.js";
56
+ } from "./chunk-JCRDBQXB.js";
57
57
  import {
58
58
  lane_guard_policy
59
59
  } from "./chunk-GG72ANKI.js";
60
60
  import {
61
61
  hook_decision
62
- } from "./chunk-KPM4YIIX.js";
62
+ } from "./chunk-7WKYHEGU.js";
63
63
  import {
64
64
  cost_attribute,
65
65
  cost_blocks,
@@ -67,7 +67,7 @@ import {
67
67
  time_batch_guard,
68
68
  time_density_hook,
69
69
  time_shell
70
- } from "./chunk-TLJYAGZK.js";
70
+ } from "./chunk-SLSFIWTX.js";
71
71
  import {
72
72
  lane_child_marker
73
73
  } from "./chunk-Z5TMJIPW.js";
@@ -1661,7 +1661,7 @@ var BATCH_ORACLES = [
1661
1661
  {
1662
1662
  name: "run:step",
1663
1663
  decision: "The run\u2019s next single action, computed from the event stream, carry and issue state",
1664
- args: ISSUE_N_ARG,
1664
+ args: `[${ISSUE_N_ARG}]`,
1665
1665
  // The non-command answers: `run:step` prints a runnable command for a phase with one to run, and
1666
1666
  // one of these verdicts otherwise. A command line is not a vocabulary token, exactly as an issue
1667
1667
  // number is not one for `backlog:next`.
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  investigation_reads
3
- } from "./chunk-76RK6E3H.js";
3
+ } from "./chunk-JCRDBQXB.js";
4
4
  import {
5
5
  lane_guard_policy
6
6
  } from "./chunk-GG72ANKI.js";
7
7
  import {
8
8
  hook_decision
9
- } from "./chunk-KPM4YIIX.js";
9
+ } from "./chunk-7WKYHEGU.js";
10
10
  import {
11
11
  time_spans
12
- } from "./chunk-TLJYAGZK.js";
12
+ } from "./chunk-SLSFIWTX.js";
13
13
  import {
14
14
  json_value
15
15
  } from "./chunk-NZN2UFI6.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  hook_decision
3
- } from "./chunk-KPM4YIIX.js";
3
+ } from "./chunk-7WKYHEGU.js";
4
4
  import {
5
5
  cost_blocks,
6
6
  time_batch_guard,
7
7
  time_bundle_call,
8
8
  time_shell,
9
9
  time_spans
10
- } from "./chunk-TLJYAGZK.js";
10
+ } from "./chunk-SLSFIWTX.js";
11
11
  import {
12
12
  cost_transcript
13
13
  } from "./chunk-NZN2UFI6.js";
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-GG72ANKI.js";
4
4
  import {
5
5
  hook_decision
6
- } from "./chunk-KPM4YIIX.js";
6
+ } from "./chunk-7WKYHEGU.js";
7
7
  import {
8
8
  time_batch_guard
9
- } from "./chunk-TLJYAGZK.js";
9
+ } from "./chunk-SLSFIWTX.js";
10
10
 
11
11
  // scripts/hooks/batch-guard.ts
12
12
  import { text } from "node:stream/consumers";
@@ -533,7 +533,7 @@ var RUN_COMMANDS = {
533
533
  script: "scripts/run/run-step-cli.ts",
534
534
  description: "Print the run\u2019s next single action, computed from the event stream, carry record and issue state",
535
535
  category: "AI tools",
536
- reference: ["<issue>", "automation", ["network", "files"]]
536
+ reference: ["[<issue>]", "automation", ["network", "files"]]
537
537
  }
538
538
  };
539
539
 
@@ -1346,6 +1346,7 @@ async function is_backlog_parent(source = process.env, ancestry = lane_reap.own_
1346
1346
  var run_headless = {
1347
1347
  HEADLESS_ENV_KEY,
1348
1348
  current_carry,
1349
+ driven_here,
1349
1350
  driving_carry,
1350
1351
  environment: environment2,
1351
1352
  is_backlog_parent,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  investigation_reads
3
- } from "./chunk-76RK6E3H.js";
3
+ } from "./chunk-JCRDBQXB.js";
4
4
  import {
5
5
  lane_guard_policy
6
6
  } from "./chunk-GG72ANKI.js";
7
7
  import {
8
8
  hook_decision
9
- } from "./chunk-KPM4YIIX.js";
9
+ } from "./chunk-7WKYHEGU.js";
10
10
 
11
11
  // scripts/delegation/investigation-guard.ts
12
12
  import { text } from "node:stream/consumers";
@@ -8,7 +8,7 @@ import {
8
8
  repo_origin,
9
9
  repository_lock,
10
10
  run_ship_stage
11
- } from "./chunk-SYSRHRWU.js";
11
+ } from "./chunk-UTHMB4O2.js";
12
12
  import {
13
13
  error_text
14
14
  } from "./chunk-CDY4NFQG.js";
@@ -30,7 +30,7 @@ import {
30
30
  time_density_hook,
31
31
  time_shell,
32
32
  time_transcript_line
33
- } from "./chunk-TLJYAGZK.js";
33
+ } from "./chunk-SLSFIWTX.js";
34
34
  import {
35
35
  lane_child_marker
36
36
  } from "./chunk-Z5TMJIPW.js";
@@ -1,29 +1,29 @@
1
1
  #!/usr/bin/env tsx
2
2
  import {
3
3
  pretool_guard
4
- } from "./chunk-4TW4MQUL.js";
5
- import "./chunk-NZBHG6FW.js";
4
+ } from "./chunk-AKGCP4LX.js";
5
+ import "./chunk-BZMPVFDY.js";
6
6
  import {
7
7
  bounded_pool
8
- } from "./chunk-MXVQMLDP.js";
8
+ } from "./chunk-YLBBSSTF.js";
9
9
  import {
10
10
  build_envelope,
11
11
  compose_context,
12
12
  format_edited_payload
13
- } from "./chunk-43G45XJF.js";
13
+ } from "./chunk-7UBFU3CL.js";
14
14
  import "./chunk-JBBMAPC4.js";
15
- import "./chunk-SYSRHRWU.js";
15
+ import "./chunk-UTHMB4O2.js";
16
16
  import "./chunk-CDY4NFQG.js";
17
- import "./chunk-DZWZ3DKY.js";
18
- import "./chunk-R6CRQEAL.js";
19
- import "./chunk-76RK6E3H.js";
17
+ import "./chunk-JGW24KKM.js";
18
+ import "./chunk-V4TKZHER.js";
19
+ import "./chunk-JCRDBQXB.js";
20
20
  import "./chunk-GG72ANKI.js";
21
21
  import {
22
22
  hook_decision
23
- } from "./chunk-KPM4YIIX.js";
23
+ } from "./chunk-7WKYHEGU.js";
24
24
  import {
25
25
  time_density_hook
26
- } from "./chunk-TLJYAGZK.js";
26
+ } from "./chunk-SLSFIWTX.js";
27
27
  import "./chunk-Z5TMJIPW.js";
28
28
  import {
29
29
  json_value
@@ -9,11 +9,11 @@ import {
9
9
  is_enabled,
10
10
  notice_refusal_path,
11
11
  refusal_path
12
- } from "./chunk-NZBHG6FW.js";
13
- import "./chunk-76RK6E3H.js";
12
+ } from "./chunk-BZMPVFDY.js";
13
+ import "./chunk-JCRDBQXB.js";
14
14
  import "./chunk-GG72ANKI.js";
15
- import "./chunk-KPM4YIIX.js";
16
- import "./chunk-TLJYAGZK.js";
15
+ import "./chunk-7WKYHEGU.js";
16
+ import "./chunk-SLSFIWTX.js";
17
17
  import "./chunk-Z5TMJIPW.js";
18
18
  import "./chunk-NZN2UFI6.js";
19
19
  import "./chunk-NEC4AT4Z.js";
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  report_no_payload,
4
4
  run_hook
5
- } from "./chunk-43G45XJF.js";
5
+ } from "./chunk-7UBFU3CL.js";
6
6
  import "./chunk-JBBMAPC4.js";
7
- import "./chunk-TLJYAGZK.js";
7
+ import "./chunk-SLSFIWTX.js";
8
8
  import "./chunk-NZN2UFI6.js";
9
9
  import "./chunk-NEC4AT4Z.js";
10
10