Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
cccdafa
faster prek
angela-tarantula Apr 25, 2026
d83ce62
Validate prek config
angela-tarantula Apr 25, 2026
78c050d
RemoveOp can't delete document
angela-tarantula Apr 26, 2026
9aab929
no more concept of a missing document mid-patch
angela-tarantula Apr 26, 2026
bc4b834
docs improvements for api reference
angela-tarantula Apr 27, 2026
527af7a
more docs edits
angela-tarantula Apr 27, 2026
464068d
reorg api ref
angela-tarantula Apr 27, 2026
ef13111
simplify api ref
angela-tarantula Apr 27, 2026
bd24f9f
docs improvements fro schema.py and applying inplace
angela-tarantula Apr 27, 2026
6ae7ef7
remove OperationValidationError
angela-tarantula Apr 27, 2026
1192707
more docs edits
angela-tarantula Apr 27, 2026
18fdb1e
fix textlint in prek
angela-tarantula Apr 27, 2026
d2ddc71
backend docs nits
angela-tarantula Apr 27, 2026
c7b71f1
better limiitations doc
angela-tarantula Apr 27, 2026
46213e6
standard ops docs clearer
angela-tarantula Apr 27, 2026
820fe90
show off model fields in docs too
angela-tarantula Apr 27, 2026
9f4821e
get rid of STANDARD_OPS
angela-tarantula Apr 27, 2026
ef1258c
stronger exception contracts
angela-tarantula Apr 29, 2026
3358d8d
rogue nits
angela-tarantula Apr 29, 2026
feca668
clear registry docstrings
angela-tarantula Apr 29, 2026
a1f688e
remove OperationNotRecognized
angela-tarantula Apr 29, 2026
9d6b132
docs for jsonpatch
angela-tarantula Apr 29, 2026
e926c8d
PatchValidationError back to 422
angela-tarantula Jul 4, 2026
ec4ee7a
r/o vs r/w prek groups
angela-tarantula Jul 4, 2026
4ede620
avoid npx/uv unpinned deps
angela-tarantula Jul 4, 2026
2aa198e
mypy for all supported versions before CI; use UV_PROJECT_ENVIRONMENT…
angela-tarantula Jul 4, 2026
30cb6b7
faster checkov
angela-tarantula Jul 4, 2026
6235b0b
yamllint respects gitignore now
angela-tarantula Jul 4, 2026
bbbd905
prek final touches
angela-tarantula Jul 4, 2026
225f4b6
change prek workflow
angela-tarantula Jul 4, 2026
251b13f
dependabot-managed lint dependencies
angela-tarantula Jul 4, 2026
f84bd25
fail-on-change
angela-tarantula Jul 4, 2026
f0f6267
fix lint issues
angela-tarantula Jul 5, 2026
9ae6e56
documentation guidelines
angela-tarantula Jul 5, 2026
625cdce
new agents guide location
angela-tarantula Jul 5, 2026
b853ab4
scaffold new paradigm of stronger agent holdout tests
angela-tarantula Jul 5, 2026
93b40bb
upload to codecov even on test failure
angela-tarantula Jul 5, 2026
767fbb0
exception traceback in tests
angela-tarantula Jul 5, 2026
a00c681
new subtest
angela-tarantula Jul 5, 2026
058a6b2
finally remove OperationNotRecognized
angela-tarantula Jul 5, 2026
6b21f3b
avoid mixed inheritance in exceptions, declutter PatchError
angela-tarantula Jul 5, 2026
93dc797
bump codecov
angela-tarantula Jul 5, 2026
83a3e98
accept-patch for 415
angela-tarantula Jul 5, 2026
b015787
InvalidPatchTarget and InvalidPatchResult
angela-tarantula Jul 5, 2026
9894e14
fix fuzzer regression
angela-tarantula Jul 5, 2026
acc6716
InvalidPatchTarget is a TypeError, not PatchError
angela-tarantula Jul 5, 2026
395efc9
fix lint issues
angela-tarantula Jul 5, 2026
74bf9e1
fix linter/codecov issue
angela-tarantula Jul 5, 2026
2a1c818
better naming for lower cognitive load
angela-tarantula Jul 5, 2026
6c19b1c
fuzzer refactor
angela-tarantula Jul 5, 2026
c9b3a6f
bump deps
angela-tarantula Jul 5, 2026
b0ca29a
free-threading support, opt-in jsonpath-strictness
angela-tarantula Jul 6, 2026
5b03054
structured PatchErrors
angela-tarantula Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .clusterfuzzlite/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#checkov:skip=CKV_DOCKER_2: OSS-Fuzz build image; one-shot `compile` step, not a long-running service
#checkov:skip=CKV_DOCKER_3: matches upstream oss-fuzz-base/base-builder, which also runs as root for `compile`
FROM gcr.io/oss-fuzz-base/base-builder-python@sha256:c5fd81433b8ceec0335387187152e856e401fa09e859ba778008e63be14d0701

# Pin dependencies
Expand Down
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ updates:
schedule:
interval: "monthly"

# Node-based lint tools
- package-ecosystem: "npm"
directory: "/tools"
cooldown:
default-days: 7
groups:
lint-tools:
patterns:
- "*"
schedule:
interval: "monthly"

# .clusterfuzzlite/requirements-bootstrap.txt.
- package-ecosystem: "pip"
directory: "/.clusterfuzzlite"
Expand All @@ -55,5 +67,7 @@ updates:

- package-ecosystem: docker
directory: /.clusterfuzzlite
cooldown:
default-days: 7
schedule:
interval: daily
8 changes: 8 additions & 0 deletions .github/linters/.checkov.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
---
directory:
- .github
- examples/openapi
- .clusterfuzzlite
framework:
- github_actions
- openapi
- dockerfile
skip-check:
# Demo and snapshot OpenAPI specs intentionally omit global auth requirements.
- CKV_OPENAPI_4
Expand Down
7 changes: 6 additions & 1 deletion .github/linters/.jscpd.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
"threshold": 5,
"minLines": 20,
"minTokens": 120,
"format": ["python"]
"format": ["python"],
"ignore": [
"tests/agents/official_recipes.py",
"examples/recipes.py",
"examples/recipes2.py"
]
}
3 changes: 3 additions & 0 deletions .github/linters/.yamllint.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
---
extends: default

ignore-from-file: .gitignore

rules:
line-length:
max: 120
level: warning
comments: disable
comments-indentation: disable
indentation: disable
truthy:
check-keys: false
4 changes: 3 additions & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ written as they are, with security and auditability as defaults.
change generated OpenAPI.
- Implementation script:
[`scripts/update_openapi_snapshots.py`](../../scripts/update_openapi_snapshots.py).
- Local refresh: invoke `prek` hooks or direct script execution.
- Local refresh: invoke `prek` hooks or direct script execution. The script also
supports `--fail-on-change` for hook-style callers that want writes to fail
the current run.
- CI model:
[`dependabot-update-openapi-snapshots.yml`](dependabot-update-openapi-snapshots.yml)
regenerates snapshots on Dependabot dependency updates and commits only when
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/dependabot-update-openapi-snapshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
persist-credentials: false

- name: Setup uv
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: true
cache-dependency-glob: |
Expand All @@ -45,6 +45,8 @@ jobs:
run: uv sync --frozen --no-default-groups --group snapshots

- name: Regenerate OpenAPI snapshots
# Omit --fail-on-change here: this workflow wants rewritten snapshot
# files so it can commit and push them back to the PR branch.
run: uv run python scripts/update_openapi_snapshots.py

- name: Create GitHub App token
Expand All @@ -54,6 +56,7 @@ jobs:
app-id: ${{ vars.SNAPSHOT_APP_ID }}
private-key: ${{ secrets.SNAPSHOT_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: jsonpatchx
permission-contents: write

- name: Configure git remote with GitHub App token
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
persist-credentials: false

- name: Setup uv
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: true
cache-dependency-glob: |
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ jobs:
with:
fetch-depth: 0
persist-credentials: false
- name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
- name: Validate prek config
run:
uv run --only-group hooks prek validate-config .pre-commit-config.yaml
- name: 🧹 run superlinter
uses: super-linter/super-linter@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0
uses: super-linter/super-linter@4ce20838b8ab83717e78138c5b3a1407148e0918 # v8.7.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_GITHUB_PULL_REQUEST_SUMMARY_COMMENT: false
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
persist-credentials: false

- name: Setup uv
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: true
enable-cache: false
cache-dependency-glob: |
pyproject.toml
uv.lock
Expand Down
53 changes: 45 additions & 8 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.12", "3.13", "3.14"]
python-version: ["3.12", "3.13", "3.13t", "3.14", "3.14t"]

steps:
- name: 🔒 harden runner
Expand All @@ -36,16 +36,42 @@ jobs:
submodules: recursive

- name: Setup uv
uses: astral-sh/setup-uv@cec208311dfd045dd5311c1add060b2062131d57 # v8.0.0
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock

# matrix.python-version carries a trailing "t" for free-threaded builds
# (e.g. "3.13t"), which mypy's --python-version does not accept and
# which must never get `jsonpatchx[strict-jsonpath]` installed (its
# iregexp-check dependency segfaults on import under free-threaded
# Python). Compute the base version and the strict extra here so later
# steps do not have to re-derive them.
- name: Compute base Python version and strict-jsonpath extra
id: pyver
shell: bash
run: |
PYVER="${{ matrix.python-version }}"
if [[ "$PYVER" == *t ]]; then
echo "base=${PYVER%t}" >> "$GITHUB_OUTPUT"
echo "extra_args=" >> "$GITHUB_OUTPUT"
else
echo "base=$PYVER" >> "$GITHUB_OUTPUT"
echo "extra_args=--extra strict-jsonpath" >> "$GITHUB_OUTPUT"
fi

- name: Install Dependencies
run: uv sync --frozen --no-default-groups --group ci
env:
EXTRA_ARGS: ${{ steps.pyver.outputs.extra_args }}
run: |
# EXTRA_ARGS is intentionally unquoted: it must word-split into
# zero or two argv tokens (`--extra strict-jsonpath`), not pass as
# one quoted string.
# shellcheck disable=SC2086
uv sync --frozen --no-default-groups --group ci $EXTRA_ARGS

- name: Ruff
run: uv run ruff check
Expand All @@ -54,21 +80,32 @@ jobs:
run: uv run ruff format --check .

- name: Mypy
run: uv run mypy --python-version "${{ matrix.python-version }}" .
env:
BASE_PYTHON_VERSION: ${{ steps.pyver.outputs.base }}
run: uv run mypy --python-version "$BASE_PYTHON_VERSION" .

- name: Test
id: test
run: |
uv run pytest \
--cov=jsonpatchx \
--cov-report=xml:coverage.xml

# Upload coverage to Codecov whenever tests run (pass or fail).
# Dependabot PRs skip this upload. Supporting uploads there would require
# an additional Dependabot-scoped CODECOV_TOKEN secret.
# Free-threaded legs (3.13t, 3.14t) skip this too: they never install
# jsonpatchx[strict-jsonpath], but jsonpatchx's own source has no code
# path gated on that extra, so their jsonpatchx coverage is identical to
# their non-t sibling's and would only add a duplicate flag.
- name: Upload coverage to Codecov
if:
${{ github.event_name != 'pull_request' ||
github.event.pull_request.user.login != 'dependabot[bot]' }}
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
if: |
!cancelled() &&
(steps.test.outcome == 'success' || steps.test.outcome == 'failure') &&
!endsWith(matrix.python-version, 't') &&
(github.event_name != 'pull_request' ||
github.event.pull_request.user.login != 'dependabot[bot]')
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
files: ./coverage.xml
flags: py-${{ matrix.python-version }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
private-key: ${{ secrets.SCORECARD_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: ${{ github.event.repository.name }}
permission-administration: read

- uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ fuzzers/corpus/**/[0-9a-f][0-9a-f][0-9a-f][0-9a-f]*

# Virtual environments
.venv
.venv-py*
node_modules/

# draft files
*temp_*
Expand All @@ -30,3 +32,6 @@ tmp/**

# other
**/.DS_Store

# Claude Code local state (settings overrides, agent worktrees)
.claude/
Loading
Loading