diff --git a/CACHE_PROTOCOL.md b/CACHE_PROTOCOL.md index c7f00b5..469ecec 100644 --- a/CACHE_PROTOCOL.md +++ b/CACHE_PROTOCOL.md @@ -58,9 +58,15 @@ Temporary files left by a killed process do not block later claims. ## Compatibility limits -This coordination protocol requires all concurrent writers to be upgraded. -Older clients can still read the version-1 file, but an older writer ignores the -claims and can still overwrite newer entries. Network/distributed filesystems, +Coordination requires every writer to use the new protocol. Published npm +`patchling <=0.3.1` and Python `patchling <=0.9.4` ignore these claims and can +overwrite newer entries. While any older writer remains active, give upgraded +clients separate cache files, such as `.patchling-cache-node.json` and +`.patchling-cache-python.json`, or disable disk caching. Stop all processes using +the old file before copying it to a new path. Merging the JS fix does not upgrade +installed npm clients. + +Older clients can still read the version-1 file. Network/distributed filesystems, cache-path aliases, and external deletion or modification of active claims are outside this local-filesystem coordination contract. A loaded instance is an in-memory snapshot; reopen it (or successfully flush local changes) to see other diff --git a/CHANGELOG.md b/CHANGELOG.md index b3b97d7..b1561b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,23 @@ # Changelog -## [0.3.1] — Unreleased +## [0.3.2] — Unreleased -Stricter UTF-8 tail handling, a guard against Python-style option names in `filterRelevant`, a typed `SmartApplyError` for smartapply refusals, and a new default model to replace a retired one. No change to `generateDiff` or to what `smartapply` writes. +Reject incomplete OpenAI-compatible completions and preserve concurrent disk-cache writes. This version prepares the fixes merged in #16 for a future npm release; it has not been published. + +### Behavior changes + +- **Incomplete completions reject.** A stream must end with `[DONE]` or a recognized successful terminal finish reason. EOF without either, or `finish_reason: length` / `content_filter`, rejects with an error named `IncompleteCompletionError`; length/filter failures also reject on the non-streaming path. Callers that previously accepted partial output now receive an error. `onToken` may already have delivered partial text: commit file changes only after the completion promise resolves. Partial streams are not automatically retried. Reader cleanup cannot delay the result or original error. +- **Disk-cache flushes merge only locally changed records under a shared Node/Python lock protocol.** The cache remains `{ version: 1, entries }` with unchanged keys and records. A persistent `.lock/` directory coordinates upgraded writers; lock acquisition waits at most two seconds apart from filesystem-call latency. A failed direct Node `flush()` rejects and keeps unsaved entries retryable; `filterRelevant` logs cache failures and continues. Browser and memory-only caches are unchanged. See [cache coordination and recovery](CACHE_PROTOCOL.md). +- **Mixed-version writers still need separate cache files.** Published npm `patchling <=0.3.1` and Python `patchling <=0.9.4` ignore the claims and can overwrite newer entries. While any older writer remains active, use a separate cache file for upgraded clients or disable disk caching. Stop processes using the old file before copying it to another path. Merging this version does not upgrade installed npm clients. + +### Repository-only changes + +- The homepage captures its mode and model choices at run start. Model catalogs retry after temporary failures and discard stale responses when credentials change; credential changes also clear rendered picker choices. +- Offline regressions cover completion termination and cancellation, cache contention/recovery and independent Node/Python writers, and homepage run/catalog state. The version bump does not publish npm or deploy the website. + +## [0.3.1] — 2026-10-31 + +Published on npm from `b8b7936a2f38f0e3536f29206c3b0b29ba1a57a2`, including stricter UTF-8 tail handling, a guard against Python-style option names in `filterRelevant`, typed `SmartApplyError` refusals, patched Node runtime requirements, and the replacement default model. The default-model-only reference in draft #15 is not the published tarball and remains marked **NOT FOR MERGE**. ### Behavior changes diff --git a/README.md b/README.md index 60de1a6..7ba481a 100644 --- a/README.md +++ b/README.md @@ -75,9 +75,14 @@ changes only after the completion promise resolves. Partial streams are not automatically retried, avoiding replay of a possibly billed request. Disk-backed relevance caches retain version-1 JSON and coordinate updated -Node/Python writers. See [cache coordination and compatibility](CACHE_PROTOCOL.md) -for lock recovery, timeout behavior, and the requirement to upgrade concurrent -writers together. Browser and memory-only caches keep their existing behavior. +Node/Python writers through a persistent `.lock/` sidecar directory. Published +npm `patchling <=0.3.1` and Python `patchling <=0.9.4` ignore the claims and can +overwrite newer entries: use separate cache files or disable disk caching while +any older writer remains active. Stop writers before copying an old cache to a +new path. Merging the JS fix does not upgrade installed npm clients. See +[cache coordination and compatibility](https://github.com/255BITS/patchling/blob/main/CACHE_PROTOCOL.md) +for lock recovery and timeout behavior. Browser and memory-only caches keep +their existing behavior. ## Configuration diff --git a/package-lock.json b/package-lock.json index da9670b..0fecaba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "patchling", - "version": "0.3.1", + "version": "0.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "patchling", - "version": "0.3.1", + "version": "0.3.2", "license": "MIT", "devDependencies": { "@types/node": "^20.19.43", diff --git a/package.json b/package.json index a33cc22..eba16a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "patchling", - "version": "0.3.1", + "version": "0.3.2", "description": "Natural-language code transformation as a browser-first JS primitive: generateDiff turns a plain-English goal into a git diff, and smartapply melds it into your source even when git apply would reject it. Wired to NanoGPT. Formerly gptdiff-js.", "type": "module", "main": "src/index.js",