patch-cc 0.6.0__tar.gz → 0.6.1__tar.gz

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 (45) hide show
  1. {patch_cc-0.6.0 → patch_cc-0.6.1}/PKG-INFO +1 -1
  2. {patch_cc-0.6.0 → patch_cc-0.6.1}/docs/PLAYBOOK.md +39 -12
  3. {patch_cc-0.6.0 → patch_cc-0.6.1}/docs/corpus.md +9 -0
  4. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/__init__.py +1 -1
  5. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/streaming.py +36 -82
  6. {patch_cc-0.6.0 → patch_cc-0.6.1}/.github/workflows/ci.yml +0 -0
  7. {patch_cc-0.6.0 → patch_cc-0.6.1}/.github/workflows/release-watch.yml +0 -0
  8. {patch_cc-0.6.0 → patch_cc-0.6.1}/.github/workflows/release.yml +0 -0
  9. {patch_cc-0.6.0 → patch_cc-0.6.1}/.gitignore +0 -0
  10. {patch_cc-0.6.0 → patch_cc-0.6.1}/AGENTS.md +0 -0
  11. {patch_cc-0.6.0 → patch_cc-0.6.1}/CLAUDE.md +0 -0
  12. {patch_cc-0.6.0 → patch_cc-0.6.1}/LICENSE +0 -0
  13. {patch_cc-0.6.0 → patch_cc-0.6.1}/README.md +0 -0
  14. {patch_cc-0.6.0 → patch_cc-0.6.1}/docs/CONDUCT.md +0 -0
  15. {patch_cc-0.6.0 → patch_cc-0.6.1}/docs/INTERNALS.md +0 -0
  16. {patch_cc-0.6.0 → patch_cc-0.6.1}/docs/demo.gif +0 -0
  17. {patch_cc-0.6.0 → patch_cc-0.6.1}/pyproject.toml +0 -0
  18. {patch_cc-0.6.0 → patch_cc-0.6.1}/scripts/corpus.py +0 -0
  19. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/bun/__init__.py +0 -0
  20. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/bun/blob.py +0 -0
  21. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/bun/container.py +0 -0
  22. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/bun/elf.py +0 -0
  23. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/bun/errors.py +0 -0
  24. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/bun/macho.py +0 -0
  25. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/cache.py +0 -0
  26. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/cli.py +0 -0
  27. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/codex/__init__.py +0 -0
  28. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/codex/gateway.py +0 -0
  29. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/codex/models.py +0 -0
  30. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/codex/oauth.py +0 -0
  31. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/codex/translate.py +0 -0
  32. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/doctor.py +0 -0
  33. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/js.py +0 -0
  34. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/locate.py +0 -0
  35. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/menu.py +0 -0
  36. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patcher.py +0 -0
  37. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/__init__.py +0 -0
  38. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/agents.py +0 -0
  39. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/base.py +0 -0
  40. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/chrome.py +0 -0
  41. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/codex.py +0 -0
  42. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/output.py +0 -0
  43. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/patches/thinking.py +0 -0
  44. {patch_cc-0.6.0 → patch_cc-0.6.1}/src/patch_cc/ui.py +0 -0
  45. {patch_cc-0.6.0 → patch_cc-0.6.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: patch-cc
3
- Version: 0.6.0
3
+ Version: 0.6.1
4
4
  Summary: Interactive patcher for the Claude Code native binary
5
5
  Project-URL: Homepage, https://github.com/anfreire/patch-cc
6
6
  Project-URL: Repository, https://github.com/anfreire/patch-cc
@@ -123,6 +123,20 @@ The tree removes the *mechanical* fragility. It does not decide these:
123
123
  the bundle one identity, the point where that path is fed, where a twin of
124
124
  the path owes one per step, each a claim only the patch needs.
125
125
  `live-thinking` is the worked case ([below](#live-thinking--streamingpy)).
126
+ - **Anchor on the fact, not on a consumer of it.** When upstream keeps a fact
127
+ under a name of its own — a setting, a header, a store field — and every
128
+ site that acts on it sits downstream of one read, default or flip *that
129
+ read* and leave the sites alone: the sites are where upstream respells
130
+ things, the name is what it keeps. `display-mode` paid for the lesson on
131
+ 2.1.277. It defaulted the request's thinking display at the site that chose
132
+ it, reached through the env-var read that shared the value's `let`
133
+ (comma-fusion, the minifier's) and identified as the consequence of a
134
+ ternary whose alternative was `void 0` (the branch layout, upstream's); the
135
+ build flipped the branches and grew a `"highlights"` mode inside the value,
136
+ and the step found nothing with every anchor standing — while the fact,
137
+ `showThinkingSummaries`, was one member read in one spelling on every build
138
+ in the corpus. Where a value *must* be identified at its site, ask what it
139
+ can *be* (`js.values`), never which branch it sits on.
126
140
  - **Match an identity by the weakest claim that still proves it; hold a rewrite
127
141
  to the exact node.** The two jobs pull in opposite directions.
128
142
  `thinking-inline`'s null-guard neutralises only a `return` that answers
@@ -505,8 +519,9 @@ Most patches are one rewrite. `live-thinking` is five named sub-steps, because
505
519
  a single hit count cannot tell "all landed" from "half silently drifted", and
506
520
  each records its own `candidates`/`applied`:
507
521
 
508
- - **`display-mode`** — the request asks the API for summarised thinking text;
509
- without it the stream carries signatures and no words.
522
+ - **`display-mode`** — the `showThinkingSummaries` setting defaults on, so the
523
+ request asks the API for summarised thinking text; without it the stream
524
+ carries signatures and no words.
510
525
  - **`reducer`** — the stream reducer is found together with the options bag it
511
526
  is handed the live tool-use setter in, and our binding of that setter is
512
527
  added to the bag.
@@ -881,15 +896,24 @@ for you. Each entry: what it changes, the stable anchor, and where it lives.
881
896
  drew beside the landed block for as long as the answer streamed. A
882
897
  tool-use entry at the same index is left exactly as the twin leaves it,
883
898
  and a list with nothing to drop is returned as it was.
884
- - **`display-mode`** defaults the request's thinking display to
885
- `"summarized"`; without it the API only streams summary text when the
886
- `showThinkingSummaries` setting is on. Two shapes used to be spelled out —
887
- the inline env check and the 2.1.216 form that hoists it behind
888
- feature-helper calls. They are one edit: the display value gains a
889
- default, and whatever guards reach it are untouched because they are never
890
- matched. The env-var *name* is the witness; whatever reads it is never
891
- described, so a hoisted `process.env` (the same migration that killed
892
- `org-label` on 2.1.228) costs nothing here.
899
+ - **`display-mode`** defaults the `showThinkingSummaries` setting on. Upstream
900
+ asks the API for `"summarized"` exactly when that setting is on, and routes
901
+ every consequence the request's display, the beta header it withholds
902
+ while summaries are on, the `updates` display the request otherwise falls
903
+ back to off one read of it, so that read
904
+ gains a default (`(settings().showThinkingSummaries??!0)`) and the request
905
+ is never touched. Every member read of the name, as `spinner-tips` reads
906
+ its setting, and a write is skipped for the reason it gives; the read is
907
+ one on every build in the corpus, spelled `settings().name??!1` on all of
908
+ them, and none of that is claimed. An explicit `false` in the user's
909
+ settings still wins. Until 2.1.277 this step defaulted the request's
910
+ display value instead, reached through the `CLAUDE_CODE_DISABLE_THINKING`
911
+ read that shared its `let` and identified as the consequence of a ternary
912
+ whose alternative was `void 0`; that build flipped the branches
913
+ (`!x?void 0:…`) and grew a `"highlights"` mode inside the chosen value,
914
+ and the step read *found nothing* with every anchor standing. Both claims
915
+ were syntax between the anchors ([What still takes
916
+ judgement](#what-still-takes-judgement)).
893
917
 
894
918
  **What is deliberately not done.** No state of ours: upstream's store carries
895
919
  a `streamingThinking` slot with a setter and a thirty-second linger, written
@@ -936,7 +960,10 @@ for you. Each entry: what it changes, the stable anchor, and where it lives.
936
960
  slots (2.1.257 — not the compiler arriving, which had cached the
937
961
  conversation render since 2.1.247, but this component joining it). The
938
962
  reducer half, anchored on the API's event strings, has not moved since it
939
- became an insertion at dispatch points. Prefer claims upstream cannot drop
963
+ became an insertion at dispatch points. The display default broke once
964
+ (2.1.277), on the branch layout of the ternary that chose the request's
965
+ value, and moved off the request onto the setting upstream chooses it from.
966
+ Prefer claims upstream cannot drop
940
967
  without paying for them — a dispatch string, a store's field name, the twin's
941
968
  own list — over claims only this patch needs, which is what CONDUCT's *ride
942
969
  what upstream ships working* asks. What was cut, and why each piece was a
@@ -90,6 +90,15 @@ never the size:
90
90
  | `2.1.267` | 217 MB | `0399c793ff571d5946ef923d80b4f330d05ac4b6842a6b0775468f5d389403c0` |
91
91
  | `2.1.268` | 219 MB | `9691a2b7bd796712ca8cffb8e32e54ff7fc45b662540233171a16a94a0425653` |
92
92
  | `2.1.269` | 220 MB | `25e44883f54419569a3d739f38cbbdaebe83b09895da0f343e1b003710a4775b` |
93
+ | `2.1.270` | 224 MB | `3a624a5a7cd79bbad4d32bd7db36f1197ecf458bc5bf1e2aed81834a01ad3ef0` |
94
+ | `2.1.271` | 227 MB | `5e7b6fc24d0e124f68e99a0641c47b662945c6d197d768d7ad7a72cbf1897f58` |
95
+ | `2.1.272` | 227 MB | `d81396a668eb76fbddb49a2a5841f1b5d7af96b4c1f6500ced92f2c988f5bcd4` |
96
+ | `2.1.273` | 229 MB | `6c752e2cc7c110c9df15f26d8d134d438c5ae95dbd610efc1a308bf7f9c5f6c1` |
97
+ | `2.1.274` | 231 MB | `15e2d05148f801b5774032faad87e624ecd172e9903288bda448b892eb58fa07` |
98
+ | `2.1.275` | 232 MB | `13586f3150a7ca1655f36e1dba759fb404e0f7cf7021d4a3dcd5e6f604e56156` |
99
+ | `2.1.276` | 232 MB | `8a56c8a14bd3cb246e2bdb7e60aefe0f609bff78c8bbcc5ea6b1817c111c6145` |
100
+ | `2.1.277` | 234 MB | `722210f05ba494d8f6df69423c4d4f2960900f7a007d0532851c7a36e375cab7` |
101
+ | `2.1.278` | 234 MB | `5c4735937844e84f8a93306e841a5b0e12252909b07870f789b190468da147ab` |
93
102
 
94
103
  This set covers the span the playbook's tree-move measurements were taken over
95
104
  (`2.1.210` → `2.1.233`), the 2.1.242 split, the 2.1.246 stream-store
@@ -1,3 +1,3 @@
1
1
  """patch-cc: an interactive patcher for the Claude Code native binary."""
2
2
 
3
- __version__ = "0.6.0"
3
+ __version__ = "0.6.1"
@@ -21,8 +21,10 @@ memoization fashion, and each repair bought exactly one build: every one of
21
21
  those was a claim only this patch needed (the builds and the spellings are in
22
22
  docs/PLAYBOOK.md). The reducer half, anchored on the API's own event strings,
23
23
  has not moved since it became an insertion at dispatch points. Only that half
24
- is left, plus the one request-side default that makes the API stream summary
25
- text at all.
24
+ is left, plus the one setting default that makes the API stream summary text
25
+ at all -- which broke once itself (2.1.277), on the spelling of the ternary
26
+ that chose the request's display, and now rests on the setting upstream
27
+ chooses it from.
26
28
 
27
29
  Two facts about upstream's list are relied on, both measured on the corpus.
28
30
  The renderer keys a virtual message off its block's ``id`` when the block has
@@ -43,98 +45,50 @@ from .. import js
43
45
  from ..js import Edit, Source
44
46
  from .base import GROUP_OUTPUT, Options, Outcome, Patch
45
47
 
46
- # -------------------------------------------------------------- display mode
48
+ # --------------------------------------------------------- summaries setting
47
49
 
48
- #: The env var *name* is the witness; whatever expression reads it is
49
- #: upstream's to spell, and is never described here. Spelling such a path is
50
- #: what killed `org-label` on 2.1.228, and this is the same variable one
51
- #: migration behind.
52
- _DISABLE_THINKING = "CLAUDE_CODE_DISABLE_THINKING"
53
- _DISPLAY = "display"
54
- _SUMMARIZED = '"summarized"'
55
-
56
-
57
- def _defaulting(read: js.Node) -> js.Node:
58
- """The value a `display` read stands for -- itself, or the ``??`` around it.
59
-
60
- Two spellings of one value: a bare read, or a read upstream has already
61
- given a fallback of its own. The coalesce is a node the grammar names,
62
- where splitting the text on ``??`` was a claim about an operator free to
63
- appear anywhere else in the expression -- and the same split then rebuilt
64
- the replacement, so one stray ``??`` in front would have been silently
65
- dropped from what we wrote back.
66
- """
67
- parent = read.parent
68
- if parent is not None and parent.type == "binary_expression":
69
- operator = parent.child_by_field_name("operator")
70
- if (
71
- operator is not None
72
- and js.text(operator) == "??"
73
- and parent.child_by_field_name("left") == read
74
- ):
75
- return parent
76
- return read
77
-
78
-
79
- def _chooses(node: js.Node) -> bool:
80
- """Is this the ``display`` read the request's thinking value is chosen from?
81
-
82
- The read is the identity and :func:`_defaulting` is what the arm is, so the
83
- property is a field of a member read rather than the tail of a spelling --
84
- ``.display`` at the end of some text says nothing about what precedes it,
85
- which is the half upstream regenerates every build.
86
- """
87
- if not js.reads(node, _DISPLAY):
88
- return False
89
- value = _defaulting(node)
90
- chosen = value.parent
91
- return (
92
- chosen is not None
93
- and chosen.type == "ternary_expression"
94
- and chosen.child_by_field_name("consequence") == value
95
- and (alternative := chosen.child_by_field_name("alternative")) is not None
96
- and js.text(alternative) == "void 0"
97
- )
50
+ #: The setting upstream reads to decide whether a request asks the API for
51
+ #: summarised thinking text -- a name upstream wrote and publishes in its
52
+ #: settings schema, and the one fact every consequence is routed off: the
53
+ #: request's `display`, the beta header withheld while it is on, the `updates`
54
+ #: display the request otherwise falls back to. The request site those reach
55
+ #: is where upstream respells things; the name is what it keeps.
56
+ _SHOW_SUMMARIES = "showThinkingSummaries"
98
57
 
99
58
 
100
59
  def _step_display_mode(source: Source, outcome: Outcome) -> Source:
101
- """Default the thinking request to `summarized`.
60
+ """Default the `showThinkingSummaries` setting on.
102
61
 
103
62
  Without a display mode in the request the API streams signature-only (or
104
63
  late) thinking, so the live row starves -- worst on short thinks. Upstream
105
- only asks for summaries when the `showThinkingSummaries` setting is on;
106
- default it on instead.
107
-
108
- Two shapes used to be spelled out here -- an inline env check, and the
109
- 2.1.216 form that hoists it into its own variable and gates the display
110
- behind extra feature-helper calls. They are one edit: the display value
111
- gains a default. Whatever guards reach it, and in whatever order the
112
- declaration lists them, is untouched because it is never matched.
64
+ asks for ``"summarized"`` exactly when this setting is on, so the setting's
65
+ read gains a default and the request is never touched: what the display
66
+ value becomes, where it is chosen and how that choice is spelled are
67
+ upstream's. 2.1.277 respelled all three at once -- the ternary that chose
68
+ the value flipped its branches and grew a ``"highlights"`` mode inside the
69
+ chosen side -- and the locator that stood here, reached through the env-var
70
+ read sharing the value's ``let`` (comma-fusion, the minifier's) and asking
71
+ for the consequence of a ternary whose alternative was ``void 0`` (the
72
+ branch layout, upstream's), found nothing with every anchor standing.
73
+
74
+ The read is one on every build in the corpus, spelled ``settings().name??!1``
75
+ on all of them, and none of that is claimed: every member read is defaulted,
76
+ as `spinner-tips` reads its setting, and a write is left alone for the
77
+ reason it gives. An explicit ``false`` in the user's settings still wins,
78
+ which the request-side default this replaced could not honour.
113
79
  """
114
80
  step = outcome.step("display-mode")
115
81
  edits = []
116
- seen: set[int] = set()
117
-
118
- for node in source.find(_DISABLE_THINKING):
119
- declaration = js.up(node, "lexical_declaration", "variable_declaration")
120
- if declaration is None or declaration.id in seen:
121
- continue
122
- # The value itself, not the ternary that chooses it: what is edited is
123
- # what identified it, so there is no second reach for the same child.
124
- display = js.first(declaration, _chooses)
125
- if display is None:
82
+ for node in source.find(_SHOW_SUMMARIES):
83
+ read = node.parent
84
+ if read is None or not js.reads(read, _SHOW_SUMMARIES) or js.written(read):
126
85
  continue
127
- seen.add(declaration.id)
128
- value = _defaulting(display)
129
86
  step.candidates += 1
130
87
  step.applied += 1
131
- # Built from the read, so the default we write is a default *of that
132
- # read* whichever of the two shapes this build ships. An upstream that
133
- # already asks for summaries is the goal achieved, not a rewrite owed.
134
- summarized = f"{js.text(display)}??{_SUMMARIZED}"
135
- if js.text(value) == summarized:
136
- continue
137
- edits.append(Edit.replace(value, summarized))
88
+ # Parenthesised, so it is a default *of that read* inside whatever
89
+ # expression this build spells around it: a bare ``??`` may not stand
90
+ # beside ``&&`` or ``||``.
91
+ edits.append(Edit.replace(read, f"({js.text(read)}??!0)"))
138
92
  return source.apply(edits)
139
93
 
140
94
 
@@ -508,7 +462,7 @@ PATCHES = [
508
462
  f'case"{_THINKING_DELTA}"',
509
463
  f'case"{_THINKING_TYPES[0]}"',
510
464
  f'"{_CONTENT_BLOCK_START}"',
511
- _DISABLE_THINKING,
465
+ _SHOW_SUMMARIES,
512
466
  ),
513
467
  ),
514
468
  ]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes