@joshuafolkken/kit 1.1370.0 → 1.1379.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 (61) hide show
  1. package/.claude/skills/dependency-update/SKILL.md +6 -3
  2. package/.claude/skills/workflow-commands/backlogrun-steps.md +1 -1
  3. package/.claude/skills/workflow-commands/backlogrun.md +6 -4
  4. package/README.md +11 -36
  5. package/dist/commands/document-section-cli.js +1 -1
  6. package/dist/hooks/batch-guard.js +6 -6
  7. package/dist/hooks/{chunk-NZBHG6FW.js → chunk-4RWRP3FF.js} +5 -5
  8. package/dist/hooks/{chunk-R6CRQEAL.js → chunk-546X4PX3.js} +3 -3
  9. package/dist/hooks/{chunk-DZWZ3DKY.js → chunk-7ZM464OW.js} +3 -3
  10. package/dist/hooks/{chunk-GG72ANKI.js → chunk-DHSKBAQ2.js} +1 -1
  11. package/dist/hooks/{chunk-KPM4YIIX.js → chunk-E7LZL5AN.js} +3 -3
  12. package/dist/hooks/{chunk-4TW4MQUL.js → chunk-HGA4EG5S.js} +12 -12
  13. package/dist/hooks/{chunk-Z5TMJIPW.js → chunk-NBEAGPS4.js} +1 -1
  14. package/dist/hooks/{chunk-43G45XJF.js → chunk-PV3FWDSQ.js} +2 -2
  15. package/dist/hooks/{chunk-76RK6E3H.js → chunk-QARPP36N.js} +3 -3
  16. package/dist/hooks/{chunk-NZN2UFI6.js → chunk-RW4XMF47.js} +37 -1
  17. package/dist/hooks/{chunk-MXVQMLDP.js → chunk-TG2AB3W6.js} +50 -16
  18. package/dist/hooks/{chunk-TLJYAGZK.js → chunk-TORRSNDJ.js} +8 -5
  19. package/dist/hooks/{chunk-SYSRHRWU.js → chunk-YSDAH73S.js} +5 -33
  20. package/dist/hooks/codex-hook-adapter.js +13 -13
  21. package/dist/hooks/duplicate-read-guard.js +7 -7
  22. package/dist/hooks/format-edited.js +3 -3
  23. package/dist/hooks/inputs.json +227 -227
  24. package/dist/hooks/investigation-guard.js +7 -7
  25. package/dist/hooks/pretool-guard.js +12 -12
  26. package/dist/hooks/session-lang.js +3 -3
  27. package/dist/hooks/stop-guard.js +6 -6
  28. package/dist/josh.js +40 -5
  29. package/package.json +5 -5
  30. package/scripts/adopt/adopt-logic.ts +4 -1
  31. package/scripts/adopt/adopt.ts +7 -4
  32. package/scripts/cost-runtime/context-cut-payback.ts +9 -4
  33. package/scripts/cost-runtime/cost-pricing.ts +94 -33
  34. package/scripts/document/document-byte-budget.ts +1 -1
  35. package/scripts/document/document-scan.ts +4 -3
  36. package/scripts/document/read-set-pricing.ts +7 -5
  37. package/scripts/git/git-spawn-sync.ts +9 -1
  38. package/scripts/init/init-ai-copy.ts +10 -3
  39. package/scripts/init/init-copy-content.ts +8 -1
  40. package/scripts/init/security-policy.ts +79 -0
  41. package/scripts/josh/josh-commands-maintenance.ts +3 -0
  42. package/scripts/josh/josh-commands-project.ts +1 -1
  43. package/scripts/josh/josh-commands-run.ts +1 -1
  44. package/scripts/josh/josh-commands-versioning.ts +2 -1
  45. package/scripts/lint/cross-file-recheck.ts +155 -0
  46. package/scripts/lint/lint-parallel.ts +10 -9
  47. package/scripts/lint/lint-related-scope.ts +4 -4
  48. package/scripts/lint/lint-related.ts +1 -1
  49. package/scripts/propagate/propagate-run.ts +17 -1
  50. package/scripts/propagate/propagate-steps.ts +9 -1
  51. package/scripts/rules/decision-oracle-batch.ts +1 -1
  52. package/scripts/run/run-headless.ts +1 -0
  53. package/scripts/run/run-step-cli.ts +51 -3
  54. package/scripts/run/run-step.ts +49 -4
  55. package/scripts/sync/sync-ai-files.ts +2 -0
  56. package/scripts/version/latest-update.ts +20 -6
  57. package/scripts/version/peer-floor.ts +99 -0
  58. package/scripts/version/playwright-browsers.ts +109 -0
  59. package/scripts/version/publishable-range-check.ts +41 -4
  60. package/templates/SECURITY.md +23 -0
  61. package/scripts/lint/cycle-recheck.ts +0 -122
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: dependency-update
3
- description: Checks after `pnpm update`, `josh latest`, `pnpm josh overrides` or any dependency update — the `overrides` survived, the one expected `devEngines` change. Read it before reporting the pins intact or pinning a bump back.
3
+ description: Checks after `pnpm update`, `josh latest`, `josh adopt`, `pnpm josh overrides` or any dependency update — the `overrides` survived, the one expected `devEngines` change. Read it before reporting the pins intact or pinning a bump back.
4
4
  ---
5
5
 
6
6
  # After a dependency-update command
@@ -8,8 +8,9 @@ description: Checks after `pnpm update`, `josh latest`, `pnpm josh overrides` or
8
8
  `CLAUDE.md` → "Decision autonomy" keeps both prohibitions resident as Tier C — never touch `overrides`
9
9
  in either file, never touch `devEngines`, without explicit user approval. This skill is the other
10
10
  half: what you actually run to find out whether a command already touched them, and how to read the
11
- one change that is expected. It applies after `pnpm update`, `josh latest`, `pnpm josh overrides`,
12
- a Dependabot merge, or any other command that can rewrite dependency versions.
11
+ one change that is expected. It applies after `pnpm update`, `josh latest`, `josh adopt` (which runs
12
+ `josh latest` as one of its steps), `pnpm josh overrides`, a Dependabot merge, or any other command
13
+ that can rewrite dependency versions.
13
14
 
14
15
  This skill is the single source of the overrides protection's procedure;
15
16
  `prompts/collaboration-workflow/operating-rules.md` only points here. Overrides were added on
@@ -34,6 +35,8 @@ or any dependency-update command, verify the overrides in both `pnpm-workspace.y
34
35
  git diff -- pnpm-workspace.yaml package.json
35
36
  ```
36
37
 
38
+ (after `josh adopt`, which has already committed and returned to the default branch, compare the
39
+ pull-request branch instead: `git diff <default>...<branch> -- pnpm-workspace.yaml package.json`)
37
40
  and confirm the effective `overrides:` block in `pnpm-workspace.yaml` and any historical
38
41
  `pnpm.overrides` declarations in `package.json` are untouched, **and** that `devDependencies`
39
42
  versions still respect the effective overrides. If any entry was removed, modified, or bumped past
@@ -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,12 +9,12 @@ import {
9
9
  load_environment_file,
10
10
  notice_refusal_path,
11
11
  refusal_path
12
- } from "./chunk-DZWZ3DKY.js";
13
- import "./chunk-GG72ANKI.js";
14
- import "./chunk-KPM4YIIX.js";
15
- import "./chunk-TLJYAGZK.js";
16
- import "./chunk-Z5TMJIPW.js";
17
- import "./chunk-NZN2UFI6.js";
12
+ } from "./chunk-7ZM464OW.js";
13
+ import "./chunk-DHSKBAQ2.js";
14
+ import "./chunk-E7LZL5AN.js";
15
+ import "./chunk-TORRSNDJ.js";
16
+ import "./chunk-NBEAGPS4.js";
17
+ import "./chunk-RW4XMF47.js";
18
18
  import "./chunk-NEC4AT4Z.js";
19
19
  export {
20
20
  DISABLED_VALUES,
@@ -1,18 +1,18 @@
1
1
  import {
2
2
  investigation_reads
3
- } from "./chunk-76RK6E3H.js";
3
+ } from "./chunk-QARPP36N.js";
4
4
  import {
5
5
  lane_guard_policy
6
- } from "./chunk-GG72ANKI.js";
6
+ } from "./chunk-DHSKBAQ2.js";
7
7
  import {
8
8
  hook_decision
9
- } from "./chunk-KPM4YIIX.js";
9
+ } from "./chunk-E7LZL5AN.js";
10
10
  import {
11
11
  time_spans
12
- } from "./chunk-TLJYAGZK.js";
12
+ } from "./chunk-TORRSNDJ.js";
13
13
  import {
14
14
  json_value
15
- } from "./chunk-NZN2UFI6.js";
15
+ } from "./chunk-RW4XMF47.js";
16
16
 
17
17
  // scripts/delegation/duplicate-read-guard.ts
18
18
  import { statSync } from "node:fs";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  investigation_reads
3
- } from "./chunk-76RK6E3H.js";
3
+ } from "./chunk-QARPP36N.js";
4
4
  import {
5
5
  lane_guard_policy
6
- } from "./chunk-GG72ANKI.js";
6
+ } from "./chunk-DHSKBAQ2.js";
7
7
  import {
8
8
  hook_decision
9
- } from "./chunk-KPM4YIIX.js";
9
+ } from "./chunk-E7LZL5AN.js";
10
10
 
11
11
  // scripts/delegation/investigation-guard.ts
12
12
  import { text } from "node:stream/consumers";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  lane_guard_policy
3
- } from "./chunk-GG72ANKI.js";
3
+ } from "./chunk-DHSKBAQ2.js";
4
4
  import {
5
5
  hook_decision
6
- } from "./chunk-KPM4YIIX.js";
6
+ } from "./chunk-E7LZL5AN.js";
7
7
  import {
8
8
  time_batch_guard
9
- } from "./chunk-TLJYAGZK.js";
9
+ } from "./chunk-TORRSNDJ.js";
10
10
 
11
11
  // scripts/hooks/batch-guard.ts
12
12
  import { text } from "node:stream/consumers";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  lane_child_marker
3
- } from "./chunk-Z5TMJIPW.js";
3
+ } from "./chunk-NBEAGPS4.js";
4
4
 
5
5
  // scripts/lane/lane-guard-policy.ts
6
6
  var DEFAULT_MODE = "refuse";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  time_density_hook,
3
3
  time_hook_transcript
4
- } from "./chunk-TLJYAGZK.js";
4
+ } from "./chunk-TORRSNDJ.js";
5
5
  import {
6
6
  josh_environment_file
7
- } from "./chunk-Z5TMJIPW.js";
7
+ } from "./chunk-NBEAGPS4.js";
8
8
  import {
9
9
  json_value
10
- } from "./chunk-NZN2UFI6.js";
10
+ } from "./chunk-RW4XMF47.js";
11
11
  import {
12
12
  stamp_file
13
13
  } from "./chunk-NEC4AT4Z.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  duplicate_read_outcome
3
- } from "./chunk-NZBHG6FW.js";
3
+ } from "./chunk-4RWRP3FF.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-TG2AB3W6.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-YSDAH73S.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-7ZM464OW.js";
51
51
  import {
52
52
  investigation_refusal
53
- } from "./chunk-R6CRQEAL.js";
53
+ } from "./chunk-546X4PX3.js";
54
54
  import {
55
55
  investigation_reads
56
- } from "./chunk-76RK6E3H.js";
56
+ } from "./chunk-QARPP36N.js";
57
57
  import {
58
58
  lane_guard_policy
59
- } from "./chunk-GG72ANKI.js";
59
+ } from "./chunk-DHSKBAQ2.js";
60
60
  import {
61
61
  hook_decision
62
- } from "./chunk-KPM4YIIX.js";
62
+ } from "./chunk-E7LZL5AN.js";
63
63
  import {
64
64
  cost_attribute,
65
65
  cost_blocks,
@@ -67,10 +67,10 @@ import {
67
67
  time_batch_guard,
68
68
  time_density_hook,
69
69
  time_shell
70
- } from "./chunk-TLJYAGZK.js";
70
+ } from "./chunk-TORRSNDJ.js";
71
71
  import {
72
72
  lane_child_marker
73
- } from "./chunk-Z5TMJIPW.js";
73
+ } from "./chunk-NBEAGPS4.js";
74
74
  import {
75
75
  PORCELAIN_FLAG,
76
76
  cli_flags,
@@ -84,7 +84,7 @@ import {
84
84
  lane_paths,
85
85
  own_session,
86
86
  run_carry
87
- } from "./chunk-NZN2UFI6.js";
87
+ } from "./chunk-RW4XMF47.js";
88
88
  import {
89
89
  PLATFORM_TEMP_ROOT,
90
90
  PROBE_TIMEOUT_MS,
@@ -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`.
@@ -2,7 +2,7 @@ import {
2
2
  ENV_FILE_NAME,
3
3
  issue_number_shape,
4
4
  lane_paths
5
- } from "./chunk-NZN2UFI6.js";
5
+ } from "./chunk-RW4XMF47.js";
6
6
 
7
7
  // scripts/josh/josh-environment-file.ts
8
8
  function load_environment_file() {
@@ -5,11 +5,11 @@ import {
5
5
  import {
6
6
  ESLINT_EDIT_CACHE_FLAGS,
7
7
  time_density_hook
8
- } from "./chunk-TLJYAGZK.js";
8
+ } from "./chunk-TORRSNDJ.js";
9
9
  import {
10
10
  file_reader,
11
11
  json_value
12
- } from "./chunk-NZN2UFI6.js";
12
+ } from "./chunk-RW4XMF47.js";
13
13
  import {
14
14
  HOOK_PROCESS_TIMEOUT_MS
15
15
  } from "./chunk-NEC4AT4Z.js";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  hook_decision
3
- } from "./chunk-KPM4YIIX.js";
3
+ } from "./chunk-E7LZL5AN.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-TORRSNDJ.js";
11
11
  import {
12
12
  cost_transcript
13
- } from "./chunk-NZN2UFI6.js";
13
+ } from "./chunk-RW4XMF47.js";
14
14
 
15
15
  // scripts/delegation/investigation-reads.ts
16
16
  import path2 from "node:path";
@@ -521,6 +521,37 @@ function read_spawn_stderr(result) {
521
521
 
522
522
  // scripts/git/git-spawn-sync.ts
523
523
  import { execaSync } from "execa";
524
+
525
+ // scripts/git/git-location-environment.ts
526
+ var GIT_LOCATION_VARIABLES = [
527
+ "GIT_ALTERNATE_OBJECT_DIRECTORIES",
528
+ "GIT_COMMON_DIR",
529
+ "GIT_DIR",
530
+ "GIT_INDEX_FILE",
531
+ "GIT_NAMESPACE",
532
+ "GIT_OBJECT_DIRECTORY",
533
+ "GIT_WORK_TREE"
534
+ ];
535
+ function location_free_environment() {
536
+ return Object.fromEntries(GIT_LOCATION_VARIABLES.map((name) => [name, void 0]));
537
+ }
538
+ function forget(name) {
539
+ Reflect.deleteProperty(process.env, name);
540
+ }
541
+ function restore_one(name, value) {
542
+ if (value === void 0) forget(name);
543
+ else process.env[name] = value;
544
+ }
545
+ function clear_git_location_variables() {
546
+ const previous = GIT_LOCATION_VARIABLES.map((name) => [name, process.env[name]]);
547
+ for (const [name] of previous) forget(name);
548
+ return () => {
549
+ for (const [name, value] of previous) restore_one(name, value);
550
+ };
551
+ }
552
+ var git_location_environment = { clear_git_location_variables, location_free_environment };
553
+
554
+ // scripts/git/git-spawn-sync.ts
524
555
  var SUCCESS_EXIT_CODE = 0;
525
556
  var C_LOCALE = { LC_ALL: "C", LANGUAGE: "C" };
526
557
  function run2(args, options = {}) {
@@ -541,7 +572,10 @@ function read2(args, options = {}) {
541
572
  return result.exit_code === SUCCESS_EXIT_CODE ? result.stdout.trim() : void 0;
542
573
  }
543
574
  function origin_url(cwd) {
544
- return read2(["config", "--get", "remote.origin.url"], { cwd });
575
+ return read2(["config", "--get", "remote.origin.url"], {
576
+ cwd,
577
+ env: git_location_environment.location_free_environment()
578
+ });
545
579
  }
546
580
  function toplevel(timeout = GIT_TIMEOUT_MS) {
547
581
  return run2(["rev-parse", "--show-toplevel"], { env: C_LOCALE, timeout });
@@ -2392,6 +2426,8 @@ export {
2392
2426
  git_utilities,
2393
2427
  has_timed_out,
2394
2428
  git_spawn,
2429
+ GIT_LOCATION_VARIABLES,
2430
+ git_location_environment,
2395
2431
  git_spawn_sync,
2396
2432
  git_command,
2397
2433
  stamp_record,
@@ -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-YSDAH73S.js";
12
12
  import {
13
13
  error_text
14
14
  } from "./chunk-CDY4NFQG.js";
@@ -30,10 +30,10 @@ import {
30
30
  time_density_hook,
31
31
  time_shell,
32
32
  time_transcript_line
33
- } from "./chunk-TLJYAGZK.js";
33
+ } from "./chunk-TORRSNDJ.js";
34
34
  import {
35
35
  lane_child_marker
36
- } from "./chunk-Z5TMJIPW.js";
36
+ } from "./chunk-NBEAGPS4.js";
37
37
  import {
38
38
  agent_session_environment,
39
39
  backlog_budget,
@@ -44,7 +44,7 @@ import {
44
44
  process_identity,
45
45
  run_carry,
46
46
  stamp_record
47
- } from "./chunk-NZN2UFI6.js";
47
+ } from "./chunk-RW4XMF47.js";
48
48
  import {
49
49
  COMMAND_TIMEOUT_MS,
50
50
  stamp_file
@@ -503,29 +503,56 @@ var run_hold = {
503
503
  // scripts/cost-runtime/cost-pricing.ts
504
504
  var CACHE_WRITE_5M_MULTIPLIER = 1.25;
505
505
  var CACHE_WRITE_1H_MULTIPLIER = 2;
506
- var CACHE_READ_MULTIPLIER = 0.1;
506
+ var DEFAULT_CACHE_READ_MULTIPLIER = 0.1;
507
+ var HALVED_CACHE_READ_MULTIPLIER = 0.05;
508
+ var QUARTERED_CACHE_READ_MULTIPLIER = 0.025;
507
509
  var TOKENS_PER_MILLION = 1e6;
510
+ var LONG_PROMPT_SUFFIX = ":long-prompt";
511
+ var LONG_PROMPT_THRESHOLD = 1e5;
508
512
  var MODEL_PRICES = {
513
+ "claude-fable-5-1": {
514
+ input: 10,
515
+ output: 50,
516
+ cache_read_multiplier: QUARTERED_CACHE_READ_MULTIPLIER
517
+ },
518
+ "claude-mythos-5-1": {
519
+ input: 10,
520
+ output: 50,
521
+ cache_read_multiplier: QUARTERED_CACHE_READ_MULTIPLIER
522
+ },
509
523
  "claude-fable-5": { input: 10, output: 50 },
510
524
  "claude-mythos-5": { input: 10, output: 50 },
525
+ "claude-opus-5-5": { input: 4, output: 20, cache_read_multiplier: HALVED_CACHE_READ_MULTIPLIER },
511
526
  "claude-opus-5": { input: 5, output: 25 },
512
527
  "claude-opus-4-8": { input: 5, output: 25 },
513
528
  "claude-opus-4-7": { input: 5, output: 25 },
514
529
  "claude-opus-4-6": { input: 5, output: 25 },
530
+ "claude-sonnet-5-5": {
531
+ input: 2,
532
+ output: 10,
533
+ cache_read_multiplier: HALVED_CACHE_READ_MULTIPLIER
534
+ },
515
535
  "claude-sonnet-5": { input: 2, output: 10 },
516
536
  "claude-sonnet-4-6": { input: 3, output: 15 },
537
+ "claude-haiku-5-5": { input: 0.1, output: 0.5 },
538
+ [`claude-haiku-5-5${LONG_PROMPT_SUFFIX}`]: { input: 0.5, output: 2.5 },
517
539
  "claude-haiku-4-5": { input: 1, output: 5 }
518
540
  };
519
541
  var CONTEXT_MARKER = "[";
520
- function resolve_price(model) {
542
+ var DATE_SUFFIX = /-\d{8}$/u;
543
+ function known_id(model) {
521
544
  const base = model.split(CONTEXT_MARKER)[0] ?? model;
522
- const direct = MODEL_PRICES[base];
523
- if (direct !== void 0) return direct;
524
- const [matched] = Object.keys(MODEL_PRICES).filter((id) => base.startsWith(id)).toSorted((left, right) => right.length - left.length);
525
- return matched === void 0 ? void 0 : MODEL_PRICES[matched];
545
+ return [base, base.replace(DATE_SUFFIX, "")].find((id) => Object.hasOwn(MODEL_PRICES, id));
546
+ }
547
+ function resolve_price(model) {
548
+ const id = known_id(model);
549
+ return id === void 0 ? void 0 : MODEL_PRICES[id];
550
+ }
551
+ function cache_read_multiplier(price) {
552
+ return price.cache_read_multiplier ?? DEFAULT_CACHE_READ_MULTIPLIER;
526
553
  }
527
554
  function estimate_cost(totals, price) {
528
- const weighted_input = totals.input_tokens + totals.cache_write_5m_tokens * CACHE_WRITE_5M_MULTIPLIER + totals.cache_write_1h_tokens * CACHE_WRITE_1H_MULTIPLIER + totals.cache_read_tokens * CACHE_READ_MULTIPLIER;
555
+ const weighted_input = totals.input_tokens + totals.cache_write_5m_tokens * CACHE_WRITE_5M_MULTIPLIER + totals.cache_write_1h_tokens * CACHE_WRITE_1H_MULTIPLIER + totals.cache_read_tokens * cache_read_multiplier(price);
529
556
  return (weighted_input * price.input + totals.output_tokens * price.output) / TOKENS_PER_MILLION;
530
557
  }
531
558
  function priced(tokens, rate) {
@@ -542,7 +569,7 @@ function estimate_composition(totals, price) {
542
569
  totals.cache_write_1h_tokens * CACHE_WRITE_1H_MULTIPLIER,
543
570
  price.input
544
571
  ),
545
- cache_read_usd: priced(totals.cache_read_tokens * CACHE_READ_MULTIPLIER, price.input),
572
+ cache_read_usd: priced(totals.cache_read_tokens * cache_read_multiplier(price), price.input),
546
573
  output_usd: priced(totals.output_tokens, price.output)
547
574
  };
548
575
  }
@@ -551,11 +578,17 @@ function to_model_cost(model, totals) {
551
578
  if (price === void 0) return { model, totals };
552
579
  return { model, totals, cost_usd: estimate_cost(totals, price) };
553
580
  }
581
+ function billed_model(usage) {
582
+ const long_id = `${known_id(usage.model) ?? usage.model}${LONG_PROMPT_SUFFIX}`;
583
+ const is_long = cost_usage.billed_input(usage.totals) > LONG_PROMPT_THRESHOLD;
584
+ return is_long && Object.hasOwn(MODEL_PRICES, long_id) ? long_id : usage.model;
585
+ }
554
586
  function cost_by_model(records) {
555
587
  const grouped = /* @__PURE__ */ new Map();
556
588
  for (const record of records) {
557
- const running = grouped.get(record.model) ?? cost_usage.EMPTY_TOTALS;
558
- grouped.set(record.model, cost_usage.add_totals(running, record.totals));
589
+ const model = billed_model(record);
590
+ const running = grouped.get(model) ?? cost_usage.EMPTY_TOTALS;
591
+ grouped.set(model, cost_usage.add_totals(running, record.totals));
559
592
  }
560
593
  return [...grouped].map(([model, totals]) => to_model_cost(model, totals));
561
594
  }
@@ -571,7 +604,8 @@ function cost_of(records) {
571
604
  var cost_pricing = {
572
605
  CACHE_WRITE_5M_MULTIPLIER,
573
606
  CACHE_WRITE_1H_MULTIPLIER,
574
- CACHE_READ_MULTIPLIER,
607
+ DEFAULT_CACHE_READ_MULTIPLIER,
608
+ LONG_PROMPT_THRESHOLD,
575
609
  resolve_price,
576
610
  estimate_cost,
577
611
  estimate_composition,
@@ -584,7 +618,7 @@ var cost_pricing = {
584
618
  var POST_CUT_CONTEXT = 6e4;
585
619
  var EXPECTED_REMAINING_REQUESTS = 10;
586
620
  function write_over_read() {
587
- return cost_pricing.CACHE_WRITE_5M_MULTIPLIER / cost_pricing.CACHE_READ_MULTIPLIER;
621
+ return cost_pricing.CACHE_WRITE_5M_MULTIPLIER / cost_pricing.DEFAULT_CACHE_READ_MULTIPLIER;
588
622
  }
589
623
  function break_even_context(remaining = EXPECTED_REMAINING_REQUESTS) {
590
624
  if (remaining <= 0) return Infinity;
@@ -6,7 +6,7 @@ import {
6
6
  process_owner_schema,
7
7
  run_carry,
8
8
  time_instant
9
- } from "./chunk-NZN2UFI6.js";
9
+ } from "./chunk-RW4XMF47.js";
10
10
  import {
11
11
  PLATFORM_TEMP_ROOT,
12
12
  PROBE_TIMEOUT_MS,
@@ -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
 
@@ -1882,7 +1882,10 @@ var MAINTENANCE_COMMANDS = {
1882
1882
  script: "scripts/version/latest-update.ts",
1883
1883
  description: "Update all dependencies to latest",
1884
1884
  category: "Maintenance",
1885
- reference: ["", "developer", ["files", "network"]]
1885
+ reference: ["", "developer", ["files", "network"]],
1886
+ // `JOSH_PLAYWRIGHT_BROWSERS` widens the browsers a Playwright bump installs, and a project
1887
+ // keeps that setting in its `.env`.
1888
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
1886
1889
  }
1887
1890
  };
1888
1891
 
@@ -1970,7 +1973,7 @@ var PROJECT_COMMANDS = {
1970
1973
  },
1971
1974
  adopt: {
1972
1975
  script: "scripts/adopt/adopt.ts",
1973
- description: "Upgrade every installed @joshuafolkken toolkit here and open the pull request",
1976
+ description: "Upgrade the @joshuafolkken toolkits and other dependencies here, open the PR",
1974
1977
  category: "Project",
1975
1978
  reference: ["[--dry-run]", "developer", ["files", "git", "network", "processes"]]
1976
1979
  }
@@ -1996,7 +1999,7 @@ var VERSIONING_COMMANDS = {
1996
1999
  // before chaining here, exactly as it already does for `latest:update`.
1997
2000
  ranges: {
1998
2001
  script: "scripts/version/publishable-range-check.ts",
1999
- description: "Check that every published dependency range still resolves for a consumer",
2002
+ description: "Check that every published dependency range still resolves for a consumer and no peer range falls below an installed toolkit",
2000
2003
  category: "Versioning",
2001
2004
  reference: ["", "developer", ["network"]]
2002
2005
  },