patchling 0.0.1__tar.gz → 0.8.0__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 (31) hide show
  1. patchling-0.8.0/LICENSE.txt +10 -0
  2. patchling-0.8.0/PKG-INFO +260 -0
  3. patchling-0.8.0/README.md +223 -0
  4. patchling-0.8.0/patchling/__init__.py +3 -0
  5. patchling-0.8.0/patchling/applydiff.py +327 -0
  6. patchling-0.8.0/patchling/core.py +1122 -0
  7. patchling-0.8.0/patchling/gptpatch.py +87 -0
  8. patchling-0.8.0/patchling/gptsummarize.py +196 -0
  9. patchling-0.8.0/patchling.egg-info/PKG-INFO +260 -0
  10. patchling-0.8.0/patchling.egg-info/SOURCES.txt +23 -0
  11. patchling-0.8.0/patchling.egg-info/entry_points.txt +5 -0
  12. patchling-0.8.0/patchling.egg-info/requires.txt +11 -0
  13. patchling-0.8.0/setup.py +46 -0
  14. patchling-0.8.0/tests/test_applydiff.py +171 -0
  15. patchling-0.8.0/tests/test_applydiff_edgecases.py +185 -0
  16. patchling-0.8.0/tests/test_diff_parse.py +35 -0
  17. patchling-0.8.0/tests/test_failing_case.py +25 -0
  18. patchling-0.8.0/tests/test_multidiff.py +50 -0
  19. patchling-0.8.0/tests/test_parse_diff_per_file.py +206 -0
  20. patchling-0.8.0/tests/test_smartapply.py +266 -0
  21. patchling-0.8.0/tests/test_strip_bad_ouput.py +124 -0
  22. patchling-0.8.0/tests/test_swallow_reasoning.py +176 -0
  23. patchling-0.0.1/PKG-INFO +0 -32
  24. patchling-0.0.1/README.md +0 -15
  25. patchling-0.0.1/patchling/__init__.py +0 -15
  26. patchling-0.0.1/patchling.egg-info/PKG-INFO +0 -32
  27. patchling-0.0.1/patchling.egg-info/SOURCES.txt +0 -7
  28. patchling-0.0.1/pyproject.toml +0 -27
  29. {patchling-0.0.1 → patchling-0.8.0}/patchling.egg-info/dependency_links.txt +0 -0
  30. {patchling-0.0.1 → patchling-0.8.0}/patchling.egg-info/top_level.txt +0 -0
  31. {patchling-0.0.1 → patchling-0.8.0}/setup.cfg +0 -0
@@ -0,0 +1,10 @@
1
+ # We help companies adapt to the AI age through product development and consulting. 255labs.xyz
2
+ This is free and unencumbered software released into the public domain.
3
+
4
+ Copyright 2025 255labs.xyz
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
+
10
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,260 @@
1
+ Metadata-Version: 2.4
2
+ Name: patchling
3
+ Version: 0.8.0
4
+ Summary: Natural-language code transformation as a library: generate unified diffs with LLMs and apply them resiliently with smartapply. Formerly gptdiff.
5
+ Home-page: https://github.com/255BITS/patchling-py
6
+ Author: 255labs
7
+ Project-URL: Documentation, https://patchling.255labs.xyz
8
+ Project-URL: Source, https://github.com/255BITS/patchling-py
9
+ Project-URL: Browser/Node runtime (npm), https://www.npmjs.com/package/patchling
10
+ Project-URL: Built with patchling (nanoodle), https://nanoodle.com
11
+ Keywords: patchling,smartapply,llm,diff,unified-diff,patch,code-transformation,ai,codegen,gptdiff
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Operating System :: OS Independent
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE.txt
17
+ Requires-Dist: openai>=1.0.0
18
+ Requires-Dist: tiktoken>=0.5.0
19
+ Requires-Dist: ai-agent-toolbox<1.0,>=0.2.0
20
+ Provides-Extra: test
21
+ Requires-Dist: pytest; extra == "test"
22
+ Requires-Dist: pytest-mock; extra == "test"
23
+ Provides-Extra: docs
24
+ Requires-Dist: mkdocs; extra == "docs"
25
+ Requires-Dist: mkdocs-material; extra == "docs"
26
+ Dynamic: author
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: keywords
32
+ Dynamic: license-file
33
+ Dynamic: project-url
34
+ Dynamic: provides-extra
35
+ Dynamic: requires-dist
36
+ Dynamic: summary
37
+
38
+ # Patchling
39
+
40
+ > _Formerly **gptdiff**. Same library, same API — `pip install patchling` (the `gptdiff` package still resolves during the transition)._
41
+
42
+ **Natural-language code transformation, as a library.** Hand Patchling a dict of files and a plain-English goal; get back a unified diff — and, via `smartapply`, the transformed files. It's a bounded primitive you embed inside your own software systems, not an open-ended coding agent.
43
+
44
+ ```python
45
+ from patchling import generate_diff, smartapply, build_environment
46
+
47
+ files = {"main.py": "def old_name():\n print('Need renaming')\n"}
48
+
49
+ diff = generate_diff(build_environment(files), "Rename old_name to new_name")
50
+ updated = smartapply(diff, files)
51
+
52
+ print(updated["main.py"])
53
+ ```
54
+
55
+ Files in, files out. No filesystem access required, no agent harness. The hard part — applying an LLM-generated diff that `git apply` would reject — is what `smartapply` solves: per-file, AI-assisted patch resolution that survives fuzzy hunks, renames, new files, and deletions.
56
+
57
+ 📚 Full documentation at [patchling.255labs.xyz](https://patchling.255labs.xyz)
58
+
59
+ Prefer the browser? **[patchling](https://github.com/255BITS/patchling)** is a JavaScript port of
60
+ `generateDiff` + `smartapply` — try the **[live demos →](https://255bits.github.io/patchling-examples/)**.
61
+
62
+ > **The patchling family** —
63
+ > **patchling** (you are here) ·
64
+ > [**patchling**](https://github.com/255BITS/patchling) (browser-first JS port) ·
65
+ > [**patchling-examples**](https://github.com/255BITS/patchling-examples) (live browser demos)
66
+
67
+ ---
68
+
69
+ ## The Patchling family
70
+
71
+ The same primitive exists for every runtime, and it powers a real product:
72
+
73
+ | Project | What it is |
74
+ |---------|------------|
75
+ | **patchling** (this repo) | Python library + CLI tools — [PyPI](https://pypi.org/project/patchling/) |
76
+ | **[patchling](https://github.com/255BITS/patchling)** | Zero-dependency ESM port for browser and Node — `generateDiff` + `smartapply` on in-memory file maps |
77
+ | **[nanoodle.com](https://nanoodle.com)** | Visual AI workflow editor built on patchling — no server, no signup, bring your own key. See the primitive working in production |
78
+ | **[Live demos](https://255bits.github.io/patchling-examples/)** | Browser examples: LLM-edited games, 3D scenes, stream overlays, AI characters |
79
+
80
+ Building for the browser? Start with [patchling](https://github.com/255BITS/patchling). Building a Python backend, pipeline, or your own agent? You're in the right repo.
81
+
82
+ ---
83
+
84
+ ## Quick Start
85
+
86
+ ### 1. Install
87
+
88
+ ```bash
89
+ pip install patchling
90
+ ```
91
+
92
+ ### 2. Set your API key
93
+
94
+ Works with any OpenAI-compatible endpoint. Get a key at [nano-gpt.com/api](https://nano-gpt.com/api), or point `GPTDIFF_LLM_BASE_URL` at your own provider.
95
+
96
+ ```bash
97
+ # Linux/macOS
98
+ export GPTDIFF_LLM_API_KEY='your-api-key'
99
+
100
+ # Windows
101
+ set GPTDIFF_LLM_API_KEY=your-api-key
102
+ ```
103
+
104
+ ### 3. Transform files in your code
105
+
106
+ ```python
107
+ from patchling import generate_diff, smartapply, build_environment
108
+
109
+ files = {
110
+ "models.py": "class User:\n name = CharField()",
111
+ "tests/test_models.py": "def test_user():\n User(name='Test').save()",
112
+ }
113
+
114
+ diff = generate_diff(
115
+ build_environment(files),
116
+ "Rename the 'name' field to 'username' across all layers",
117
+ )
118
+ files = smartapply(diff, files)
119
+ ```
120
+
121
+ The diff is plain unified-diff text — log it, review it, gate it behind approval, or apply it immediately. That's the point: your system stays in control of what changes and when.
122
+
123
+ See [examples/usage_example.py](examples/usage_example.py) for a runnable version.
124
+
125
+ ---
126
+
127
+ ## Core API
128
+
129
+ - `generate_diff(environment: str, goal: str, model: str = ...) -> str` — generates a unified diff implementing the goal. `model` defaults to the `GPTDIFF_MODEL` env var.
130
+ - `smartapply(diff_text: str, files: dict[str, str], model: str = ...) -> dict[str, str]` — applies a diff with AI-powered conflict resolution. Handles new files, deletions, and hunks that standard patching rejects. Returns a new dict; input is not mutated.
131
+ - `build_environment(files: dict[str, str]) -> str` — serializes a files dict into the environment string `generate_diff` expects.
132
+ - `load_project_files(path, cwd) -> dict` / `save_files(files, base_dir)` — optional filesystem helpers for when you *do* want to read/write a real project (respects `.gitignore` and `.gptignore`).
133
+
134
+ Full signatures, error handling, and edge cases: [API Reference](https://patchling.255labs.xyz/api).
135
+
136
+ **Pipeline example** — sequential transformations over an in-memory codebase:
137
+
138
+ ```python
139
+ from patchling import generate_diff, smartapply, build_environment
140
+
141
+ files = load_your_codebase() # dict of {path: content}
142
+
143
+ for task in [
144
+ "Add python type annotations",
145
+ "Convert string formatting to f-strings",
146
+ "Update deprecated API calls",
147
+ ]:
148
+ files = smartapply(generate_diff(build_environment(files), task), files)
149
+ ```
150
+
151
+ This is the pattern [nanoodle.com](https://nanoodle.com) runs in the browser (via [patchling](https://github.com/255BITS/patchling)): each workflow node is a bounded diff→apply step over an in-memory file map, and the app never touches a server.
152
+
153
+ ---
154
+
155
+ ## Choosing a Model
156
+
157
+ **Reasoning models** produce more accurate diffs for complex changes; **fast models** win for applying diffs and simple edits.
158
+
159
+ | Model | Best for | Notes |
160
+ |-------|----------|-------|
161
+ | `gemini-3-pro-preview` | Generating diffs | **Recommended default** |
162
+ | `gpt-4o` / `claude-sonnet-4-20250514` | Complex or context-sensitive changes | Slower, more careful |
163
+ | `gpt5-mini` | Applying diffs (`smartapply`) | Fast and reliable — best `GPTDIFF_SMARTAPPLY_MODEL` |
164
+ | `gemini-2.0-flash` | Simple text changes | Most cost-effective |
165
+
166
+ ```bash
167
+ export GPTDIFF_MODEL='gemini-3-pro-preview'
168
+ export GPTDIFF_SMARTAPPLY_MODEL='gpt5-mini'
169
+ ```
170
+
171
+ ### Environment variables
172
+
173
+ | Variable | Purpose | Default |
174
+ |----------|---------|---------|
175
+ | `GPTDIFF_LLM_API_KEY` | API key (required) | — |
176
+ | `GPTDIFF_MODEL` | Model for diff generation | `gemini-3-pro-preview` |
177
+ | `GPTDIFF_SMARTAPPLY_MODEL` | Model for applying diffs | `GPTDIFF_MODEL` |
178
+ | `GPTDIFF_LLM_BASE_URL` | OpenAI-compatible endpoint | `https://nano-gpt.com/api/v1/` |
179
+
180
+ ---
181
+
182
+ ## Command-Line Tools
183
+
184
+ The library also ships two CLIs for working on a real project directory.
185
+
186
+ > The former command names **`gptdiff`** and **`gptpatch`** still work as aliases for `patchling` and `patchling-apply`, so existing scripts don't break.
187
+
188
+ ### patchling
189
+
190
+ Describe a change; Patchling scans the project (respecting `.gitignore`/`.gptignore`), generates a diff, and optionally applies it:
191
+
192
+ | Command | What it does |
193
+ |---------|--------------|
194
+ | `patchling "prompt"` | Writes `prompt.txt` only — preview what would be sent |
195
+ | `patchling "prompt" --call` | Generates the diff into `diff.patch` for review |
196
+ | `patchling "prompt" --apply` | Generates and applies in one step |
197
+
198
+ ```bash
199
+ cd your-project
200
+ patchling "Add type hints to all functions" --apply
201
+
202
+ # Target specific paths
203
+ patchling "Add logging" src/api/ src/utils/helpers.py
204
+ ```
205
+
206
+ Useful flags: `--model`, `--temperature`, `--prepend <file>` (custom instructions), `--image <path>` (visual context), `--nobeep`. Full list: [CLI Reference](https://patchling.255labs.xyz/cli).
207
+
208
+ Because changes arrive as diffs, the CLI is git-native: review with `git diff`, keep with `git add -p`, discard with `git checkout .`.
209
+
210
+ ### patchling-apply
211
+
212
+ Applies an existing unified diff to a project — standard patch logic first, `smartapply` fallback when that fails:
213
+
214
+ ```bash
215
+ patchling-apply path/to/diff.patch
216
+ patchling-apply --diff "<diff text>"
217
+ ```
218
+
219
+ Options: `--project-dir`, `--model`, `--max_tokens`, `--nobeep`. Details: [patchling-apply docs](https://patchling.255labs.xyz/patchling-apply).
220
+
221
+ ### Agent loops
222
+
223
+ Because each invocation is bounded (one goal → one diff), the CLI composes into loops:
224
+
225
+ ```bash
226
+ while true; do
227
+ patchling "Add missing test cases for edge conditions" --apply
228
+ git add -A && git commit -m "Auto-improvement $(date +%H:%M)" 2>/dev/null
229
+ sleep 30
230
+ done
231
+ ```
232
+
233
+ One overnight test-coverage loop took a project from 18 to 127 test cases. Recipes and guardrails: [Automation Guide](https://patchling.255labs.xyz/examples/automation).
234
+
235
+ ---
236
+
237
+ ## Testing
238
+
239
+ ```bash
240
+ pip install -e .[test]
241
+ pytest tests/
242
+ ```
243
+
244
+ ## Documentation
245
+
246
+ Docs live at [patchling.255labs.xyz](https://patchling.255labs.xyz). To preview locally:
247
+
248
+ ```bash
249
+ pip install .[docs]
250
+ mkdocs serve
251
+ ```
252
+
253
+ ## Related projects
254
+
255
+ - [patchling](https://github.com/255BITS/patchling) — the browser/Node port
256
+ - [nanoodle.com](https://nanoodle.com) — visual AI workflow editor built on patchling
257
+ - [patchling live demos](https://255bits.github.io/patchling-examples/)
258
+ - [AI Agent Toolbox](https://github.com/255BITS/ai-agent-toolbox) — powers Patchling's tool-call parsing across models
259
+
260
+ MIT licensed. Built by [255labs](https://255labs.xyz).
@@ -0,0 +1,223 @@
1
+ # Patchling
2
+
3
+ > _Formerly **gptdiff**. Same library, same API — `pip install patchling` (the `gptdiff` package still resolves during the transition)._
4
+
5
+ **Natural-language code transformation, as a library.** Hand Patchling a dict of files and a plain-English goal; get back a unified diff — and, via `smartapply`, the transformed files. It's a bounded primitive you embed inside your own software systems, not an open-ended coding agent.
6
+
7
+ ```python
8
+ from patchling import generate_diff, smartapply, build_environment
9
+
10
+ files = {"main.py": "def old_name():\n print('Need renaming')\n"}
11
+
12
+ diff = generate_diff(build_environment(files), "Rename old_name to new_name")
13
+ updated = smartapply(diff, files)
14
+
15
+ print(updated["main.py"])
16
+ ```
17
+
18
+ Files in, files out. No filesystem access required, no agent harness. The hard part — applying an LLM-generated diff that `git apply` would reject — is what `smartapply` solves: per-file, AI-assisted patch resolution that survives fuzzy hunks, renames, new files, and deletions.
19
+
20
+ 📚 Full documentation at [patchling.255labs.xyz](https://patchling.255labs.xyz)
21
+
22
+ Prefer the browser? **[patchling](https://github.com/255BITS/patchling)** is a JavaScript port of
23
+ `generateDiff` + `smartapply` — try the **[live demos →](https://255bits.github.io/patchling-examples/)**.
24
+
25
+ > **The patchling family** —
26
+ > **patchling** (you are here) ·
27
+ > [**patchling**](https://github.com/255BITS/patchling) (browser-first JS port) ·
28
+ > [**patchling-examples**](https://github.com/255BITS/patchling-examples) (live browser demos)
29
+
30
+ ---
31
+
32
+ ## The Patchling family
33
+
34
+ The same primitive exists for every runtime, and it powers a real product:
35
+
36
+ | Project | What it is |
37
+ |---------|------------|
38
+ | **patchling** (this repo) | Python library + CLI tools — [PyPI](https://pypi.org/project/patchling/) |
39
+ | **[patchling](https://github.com/255BITS/patchling)** | Zero-dependency ESM port for browser and Node — `generateDiff` + `smartapply` on in-memory file maps |
40
+ | **[nanoodle.com](https://nanoodle.com)** | Visual AI workflow editor built on patchling — no server, no signup, bring your own key. See the primitive working in production |
41
+ | **[Live demos](https://255bits.github.io/patchling-examples/)** | Browser examples: LLM-edited games, 3D scenes, stream overlays, AI characters |
42
+
43
+ Building for the browser? Start with [patchling](https://github.com/255BITS/patchling). Building a Python backend, pipeline, or your own agent? You're in the right repo.
44
+
45
+ ---
46
+
47
+ ## Quick Start
48
+
49
+ ### 1. Install
50
+
51
+ ```bash
52
+ pip install patchling
53
+ ```
54
+
55
+ ### 2. Set your API key
56
+
57
+ Works with any OpenAI-compatible endpoint. Get a key at [nano-gpt.com/api](https://nano-gpt.com/api), or point `GPTDIFF_LLM_BASE_URL` at your own provider.
58
+
59
+ ```bash
60
+ # Linux/macOS
61
+ export GPTDIFF_LLM_API_KEY='your-api-key'
62
+
63
+ # Windows
64
+ set GPTDIFF_LLM_API_KEY=your-api-key
65
+ ```
66
+
67
+ ### 3. Transform files in your code
68
+
69
+ ```python
70
+ from patchling import generate_diff, smartapply, build_environment
71
+
72
+ files = {
73
+ "models.py": "class User:\n name = CharField()",
74
+ "tests/test_models.py": "def test_user():\n User(name='Test').save()",
75
+ }
76
+
77
+ diff = generate_diff(
78
+ build_environment(files),
79
+ "Rename the 'name' field to 'username' across all layers",
80
+ )
81
+ files = smartapply(diff, files)
82
+ ```
83
+
84
+ The diff is plain unified-diff text — log it, review it, gate it behind approval, or apply it immediately. That's the point: your system stays in control of what changes and when.
85
+
86
+ See [examples/usage_example.py](examples/usage_example.py) for a runnable version.
87
+
88
+ ---
89
+
90
+ ## Core API
91
+
92
+ - `generate_diff(environment: str, goal: str, model: str = ...) -> str` — generates a unified diff implementing the goal. `model` defaults to the `GPTDIFF_MODEL` env var.
93
+ - `smartapply(diff_text: str, files: dict[str, str], model: str = ...) -> dict[str, str]` — applies a diff with AI-powered conflict resolution. Handles new files, deletions, and hunks that standard patching rejects. Returns a new dict; input is not mutated.
94
+ - `build_environment(files: dict[str, str]) -> str` — serializes a files dict into the environment string `generate_diff` expects.
95
+ - `load_project_files(path, cwd) -> dict` / `save_files(files, base_dir)` — optional filesystem helpers for when you *do* want to read/write a real project (respects `.gitignore` and `.gptignore`).
96
+
97
+ Full signatures, error handling, and edge cases: [API Reference](https://patchling.255labs.xyz/api).
98
+
99
+ **Pipeline example** — sequential transformations over an in-memory codebase:
100
+
101
+ ```python
102
+ from patchling import generate_diff, smartapply, build_environment
103
+
104
+ files = load_your_codebase() # dict of {path: content}
105
+
106
+ for task in [
107
+ "Add python type annotations",
108
+ "Convert string formatting to f-strings",
109
+ "Update deprecated API calls",
110
+ ]:
111
+ files = smartapply(generate_diff(build_environment(files), task), files)
112
+ ```
113
+
114
+ This is the pattern [nanoodle.com](https://nanoodle.com) runs in the browser (via [patchling](https://github.com/255BITS/patchling)): each workflow node is a bounded diff→apply step over an in-memory file map, and the app never touches a server.
115
+
116
+ ---
117
+
118
+ ## Choosing a Model
119
+
120
+ **Reasoning models** produce more accurate diffs for complex changes; **fast models** win for applying diffs and simple edits.
121
+
122
+ | Model | Best for | Notes |
123
+ |-------|----------|-------|
124
+ | `gemini-3-pro-preview` | Generating diffs | **Recommended default** |
125
+ | `gpt-4o` / `claude-sonnet-4-20250514` | Complex or context-sensitive changes | Slower, more careful |
126
+ | `gpt5-mini` | Applying diffs (`smartapply`) | Fast and reliable — best `GPTDIFF_SMARTAPPLY_MODEL` |
127
+ | `gemini-2.0-flash` | Simple text changes | Most cost-effective |
128
+
129
+ ```bash
130
+ export GPTDIFF_MODEL='gemini-3-pro-preview'
131
+ export GPTDIFF_SMARTAPPLY_MODEL='gpt5-mini'
132
+ ```
133
+
134
+ ### Environment variables
135
+
136
+ | Variable | Purpose | Default |
137
+ |----------|---------|---------|
138
+ | `GPTDIFF_LLM_API_KEY` | API key (required) | — |
139
+ | `GPTDIFF_MODEL` | Model for diff generation | `gemini-3-pro-preview` |
140
+ | `GPTDIFF_SMARTAPPLY_MODEL` | Model for applying diffs | `GPTDIFF_MODEL` |
141
+ | `GPTDIFF_LLM_BASE_URL` | OpenAI-compatible endpoint | `https://nano-gpt.com/api/v1/` |
142
+
143
+ ---
144
+
145
+ ## Command-Line Tools
146
+
147
+ The library also ships two CLIs for working on a real project directory.
148
+
149
+ > The former command names **`gptdiff`** and **`gptpatch`** still work as aliases for `patchling` and `patchling-apply`, so existing scripts don't break.
150
+
151
+ ### patchling
152
+
153
+ Describe a change; Patchling scans the project (respecting `.gitignore`/`.gptignore`), generates a diff, and optionally applies it:
154
+
155
+ | Command | What it does |
156
+ |---------|--------------|
157
+ | `patchling "prompt"` | Writes `prompt.txt` only — preview what would be sent |
158
+ | `patchling "prompt" --call` | Generates the diff into `diff.patch` for review |
159
+ | `patchling "prompt" --apply` | Generates and applies in one step |
160
+
161
+ ```bash
162
+ cd your-project
163
+ patchling "Add type hints to all functions" --apply
164
+
165
+ # Target specific paths
166
+ patchling "Add logging" src/api/ src/utils/helpers.py
167
+ ```
168
+
169
+ Useful flags: `--model`, `--temperature`, `--prepend <file>` (custom instructions), `--image <path>` (visual context), `--nobeep`. Full list: [CLI Reference](https://patchling.255labs.xyz/cli).
170
+
171
+ Because changes arrive as diffs, the CLI is git-native: review with `git diff`, keep with `git add -p`, discard with `git checkout .`.
172
+
173
+ ### patchling-apply
174
+
175
+ Applies an existing unified diff to a project — standard patch logic first, `smartapply` fallback when that fails:
176
+
177
+ ```bash
178
+ patchling-apply path/to/diff.patch
179
+ patchling-apply --diff "<diff text>"
180
+ ```
181
+
182
+ Options: `--project-dir`, `--model`, `--max_tokens`, `--nobeep`. Details: [patchling-apply docs](https://patchling.255labs.xyz/patchling-apply).
183
+
184
+ ### Agent loops
185
+
186
+ Because each invocation is bounded (one goal → one diff), the CLI composes into loops:
187
+
188
+ ```bash
189
+ while true; do
190
+ patchling "Add missing test cases for edge conditions" --apply
191
+ git add -A && git commit -m "Auto-improvement $(date +%H:%M)" 2>/dev/null
192
+ sleep 30
193
+ done
194
+ ```
195
+
196
+ One overnight test-coverage loop took a project from 18 to 127 test cases. Recipes and guardrails: [Automation Guide](https://patchling.255labs.xyz/examples/automation).
197
+
198
+ ---
199
+
200
+ ## Testing
201
+
202
+ ```bash
203
+ pip install -e .[test]
204
+ pytest tests/
205
+ ```
206
+
207
+ ## Documentation
208
+
209
+ Docs live at [patchling.255labs.xyz](https://patchling.255labs.xyz). To preview locally:
210
+
211
+ ```bash
212
+ pip install .[docs]
213
+ mkdocs serve
214
+ ```
215
+
216
+ ## Related projects
217
+
218
+ - [patchling](https://github.com/255BITS/patchling) — the browser/Node port
219
+ - [nanoodle.com](https://nanoodle.com) — visual AI workflow editor built on patchling
220
+ - [patchling live demos](https://255bits.github.io/patchling-examples/)
221
+ - [AI Agent Toolbox](https://github.com/255BITS/ai-agent-toolbox) — powers Patchling's tool-call parsing across models
222
+
223
+ MIT licensed. Built by [255labs](https://255labs.xyz).
@@ -0,0 +1,3 @@
1
+ from .core import generate_diff, smartapply, load_project_files, build_environment, save_files
2
+
3
+ __all__ = ['generate_diff', 'smartapply', 'load_project_files', 'build_environment', 'save_files']