patch-cc 0.2.1__tar.gz → 0.2.2__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.
- {patch_cc-0.2.1 → patch_cc-0.2.2}/PKG-INFO +1 -1
- {patch_cc-0.2.1 → patch_cc-0.2.2}/docs/PLAYBOOK.md +28 -3
- {patch_cc-0.2.1 → patch_cc-0.2.2}/pyproject.toml +1 -1
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/__init__.py +1 -1
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/agents.py +2 -1
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/base.py +13 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/thinking.py +7 -6
- {patch_cc-0.2.1 → patch_cc-0.2.2}/.github/workflows/ci.yml +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/.github/workflows/release.yml +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/.gitignore +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/AGENTS.md +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/CLAUDE.md +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/LICENSE +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/README.md +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/docs/CONDUCT.md +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/docs/INTERNALS.md +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/docs/demo.gif +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/bun/__init__.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/bun/blob.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/bun/container.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/bun/elf.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/bun/errors.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/bun/macho.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/cache.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/cli.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/codex/__init__.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/codex/gateway.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/codex/models.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/codex/oauth.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/codex/translate.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/doctor.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/locate.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/menu.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patcher.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/__init__.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/chrome.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/codex.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/output.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/patches/streaming.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/src/patch_cc/ui.py +0 -0
- {patch_cc-0.2.1 → patch_cc-0.2.2}/uv.lock +0 -0
|
@@ -17,10 +17,35 @@ constantly. These rules are what keep matchers alive:
|
|
|
17
17
|
literals, `case` labels, prop names, or control-flow shape.
|
|
18
18
|
- Match the *semantic shape* of a function body, not its symbol names.
|
|
19
19
|
- When upstream ships more than one shape for the same feature, add a second
|
|
20
|
-
narrow branch — don't widen one regex until it over-matches.
|
|
20
|
+
narrow branch — don't widen one regex until it over-matches. A different
|
|
21
|
+
*spelling* of one shape is not a second shape, and does not earn a branch; see
|
|
22
|
+
"applied to, not reached through" below for where that line falls.
|
|
21
23
|
- Accept statement variants a minifier flips between. The thinking gate broke
|
|
22
24
|
on 2.1.216 solely because `if(x)return null;` became `if(x){return null}` —
|
|
23
25
|
matchers should allow both from day one.
|
|
26
|
+
- **Applied to, not reached through.** Match what a helper is applied to; say
|
|
27
|
+
nothing about how it is reached. The callee of a zod schema is pure minifier
|
|
28
|
+
noise — the persisted `effortLevel` reads `E.enum(` on 2.1.216, `A.enum(`,
|
|
29
|
+
`b.enum(`, `v.enum(`, `w.enum(` through 2.1.223, then `Ir(` on 2.1.224 — and
|
|
30
|
+
every matcher that named any of it dated itself to one build. 2.1.224 is the
|
|
31
|
+
proof: `.enum([` dropped from 241 sites to 23 in a single release, because the
|
|
32
|
+
spelling tracks which *module* a schema lives in (bundled namespace alias vs
|
|
33
|
+
bare standalone factory), never what the schema is. So the callee is
|
|
34
|
+
`base.ARRAY_CALL` — whatever sits between the prop name and the array literal,
|
|
35
|
+
bounded only by statement and block edges — and no spelling is enumerated.
|
|
36
|
+
Enumerating the spellings seen so far only defers the same break to the next
|
|
37
|
+
one; that is the boundary of the narrow-branch rule above.
|
|
38
|
+
- **Dissolving the callee raises what the surviving anchors must carry**, and
|
|
39
|
+
that debt is per-site, never general. `effortLevel:` plus its level array is
|
|
40
|
+
unique on every build. `model:` plus an array is *not* — 6 sites on
|
|
41
|
+
2.1.216–220, 12 on 2.1.221–224 — so `MODEL_ENUM`'s
|
|
42
|
+
``.optional().describe(`Optional model override`` tail is its sole
|
|
43
|
+
discriminator, not belt-and-braces. Trimmed, the matcher finds three sites, two
|
|
44
|
+
of them the settings-scope enum `["user","project","local"]`, and
|
|
45
|
+
`codex-models` splices Codex ids into it. Measure an anchor's match count on
|
|
46
|
+
every backup before removing any part of it: under the older, tighter callee
|
|
47
|
+
that same probe read 1 on all 8 builds, so a measurement taken before the
|
|
48
|
+
callee was dissolved does not survive it.
|
|
24
49
|
- Match an optional brace **pair** conditionally (`(\{)?…(?(1)\})`), never as
|
|
25
50
|
two independent `\{?` / `\}?`. A lone optional closing brace eats the
|
|
26
51
|
*enclosing* block's `}` on the unbraced shape, and a rewrite that emits its
|
|
@@ -41,8 +66,8 @@ Anything the binary can enumerate for us, it does:
|
|
|
41
66
|
`agentType:"<name>",whenToUse:` carrying `source:"built-in"` in the same
|
|
42
67
|
object (`agents.discover_agents`). Definitions whose `whenToUse` begins with
|
|
43
68
|
`"Internal` are plumbing and are not offered.
|
|
44
|
-
- **Model aliases** come from the Task tool's own input schema: the
|
|
45
|
-
|
|
69
|
+
- **Model aliases** come from the Task tool's own input schema: the `model`
|
|
70
|
+
enum whose describe-string starts
|
|
46
71
|
`Optional model override` — `agents.MODEL_ENUM`, one compiled anchor because
|
|
47
72
|
`codex-models` splices the chosen Codex ids into the very group
|
|
48
73
|
`discover_models` reads back out.
|
|
@@ -17,6 +17,7 @@ import re
|
|
|
17
17
|
from dataclasses import dataclass
|
|
18
18
|
|
|
19
19
|
from .base import (
|
|
20
|
+
ARRAY_CALL,
|
|
20
21
|
GROUP_MODELS,
|
|
21
22
|
GROUP_OUTPUT,
|
|
22
23
|
IDENT,
|
|
@@ -156,7 +157,7 @@ _DEF_WINDOW = 3000
|
|
|
156
157
|
#: why that ordering is load-bearing). Matched separately, the two would drift
|
|
157
158
|
#: apart on the next upstream reshape, and only one of them would be repaired.
|
|
158
159
|
MODEL_ENUM = compile_js(
|
|
159
|
-
rf'model:{
|
|
160
|
+
rf'model:{ARRAY_CALL}((?:"{_MODEL_CHARS}+",?)+)\]\)\.optional\(\)'
|
|
160
161
|
rf'\.describe\([`"]Optional model override'
|
|
161
162
|
)
|
|
162
163
|
#: Used only if the Task-tool schema anchor ever disappears.
|
|
@@ -277,6 +277,19 @@ def compile_js(pattern: str, flags: int = 0) -> re.Pattern[str]:
|
|
|
277
277
|
# Matches a minified identifier, the JS `[A-Za-z_$][\w$]*` idiom.
|
|
278
278
|
IDENT = r"[A-Za-z_$][\w$]*"
|
|
279
279
|
|
|
280
|
+
#: From a schema's property name to the *opening* of the array literal it is
|
|
281
|
+
#: built from -- the ``([`` included, so a site composes this as
|
|
282
|
+
#: ``prop:{ARRAY_CALL}`` and never spells the call open itself.
|
|
283
|
+
#:
|
|
284
|
+
#: Whatever expression the build reaches the factory through is skipped
|
|
285
|
+
#: unmodelled, because the callee is minifier noise that churns every few
|
|
286
|
+
#: releases (``E.enum(`` ... ``w.enum(`` ... ``Ir(`` for one unchanged schema).
|
|
287
|
+
#: Lazy but not unbounded: ``[^;{}]`` cannot cross a statement or block edge,
|
|
288
|
+
#: and the spans it actually spends are 47-51 and 88-92 characters on every
|
|
289
|
+
#: build we hold. What the surviving anchors must carry instead -- which is a
|
|
290
|
+
#: debt this raises, per site: docs/PLAYBOOK.md.
|
|
291
|
+
ARRAY_CALL = r"[^;{}]*?\(\["
|
|
292
|
+
|
|
280
293
|
|
|
281
294
|
def switch_case_end(content: str, start: int) -> int:
|
|
282
295
|
"""End offset of a ``switch`` arm beginning at ``start``.
|
|
@@ -32,6 +32,7 @@ from __future__ import annotations
|
|
|
32
32
|
import re
|
|
33
33
|
|
|
34
34
|
from .base import (
|
|
35
|
+
ARRAY_CALL,
|
|
35
36
|
GROUP_MODELS,
|
|
36
37
|
GROUP_OUTPUT,
|
|
37
38
|
IDENT,
|
|
@@ -219,7 +220,7 @@ _EFFORT_GATE = compile_js(
|
|
|
219
220
|
# then reverted by a Claude update) treats it as unset rather than failing the
|
|
220
221
|
# whole settings parse -- the property that makes this patch safe to lose.
|
|
221
222
|
_EFFORT_SCHEMA = compile_js(
|
|
222
|
-
rf'effortLevel:
|
|
223
|
+
rf'(effortLevel:{ARRAY_CALL})"low","medium","high","xhigh"(?:,"max")?(\]\))'
|
|
223
224
|
)
|
|
224
225
|
|
|
225
226
|
|
|
@@ -242,14 +243,14 @@ def _max_effort(content: str, _options: Options, outcome: Outcome) -> str:
|
|
|
242
243
|
|
|
243
244
|
output = _EFFORT_GATE.sub(widen_gate, content)
|
|
244
245
|
|
|
246
|
+
# No already-applied branch, unlike the gate above: the levels are spliced
|
|
247
|
+
# into the array the match found, so a bundle that already carries `max` is
|
|
248
|
+
# rewritten to itself. `widen_gate` needs one because its unconditional path
|
|
249
|
+
# also normalises the brace form, and would churn a bundle that was fine.
|
|
245
250
|
def widen_schema(match: re.Match[str]) -> str:
|
|
246
251
|
schema.candidates += 1
|
|
247
252
|
schema.applied += 1
|
|
248
|
-
|
|
249
|
-
return match.group(0)
|
|
250
|
-
return (
|
|
251
|
-
f'effortLevel:{match.group(1)}.enum(["low","medium","high","xhigh","max"])'
|
|
252
|
-
)
|
|
253
|
+
return f'{match.group(1)}"low","medium","high","xhigh","max"{match.group(2)}'
|
|
253
254
|
|
|
254
255
|
return _EFFORT_SCHEMA.sub(widen_schema, output)
|
|
255
256
|
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|