diffowl 0.1.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jesus Gutierrez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,415 @@
1
+ # DiffOwl
2
+
3
+ ```text
4
+ ,___,
5
+ (O,O)
6
+ /)_)
7
+ " "
8
+ ```
9
+
10
+ > **Local AI Code Review Agent**
11
+ >
12
+ > Build-time quality reviews, running locally, on your own terms.
13
+
14
+ DiffOwl is a lightweight CLI that integrates into your Git workflow to provide high-quality code reviews locally. Instead of rebuilding LLM integrations or managing provider keys from scratch, DiffOwl orchestrates a headless [OpenCode Server](https://opencode.ai/docs/server/) session, builds bounded local review context, and asks the local agent for structured findings.
15
+
16
+ ---
17
+
18
+ ## Features
19
+
20
+ - **Powered by OpenCode**: Integrates with OpenCode's local environment and configured providers while keeping DiffOwl's review workflow local and repeatable.
21
+ - **First-Class TypeScript Support**: Automatically extracts modified TypeScript AST nodes (functions, classes, interfaces, types, enums, methods, properties, and top-level const declarations) to feed rich, structured context to the AI reviewer.
22
+ - **Non-Blocking Git Hooks**: Runs post-commit reviews asynchronously in the background. It will never slow down or block your `git commit` operation.
23
+ - **Review Chat Handoff**: Reopen the OpenCode session behind the latest or any selected review with `diffowl chat`.
24
+ - **Review Depth Profiles**: Choose `shallow` or `default` context strategies to match fast hooks or normal reviews.
25
+ - **Intelligent File Filtering**: Supports `include` and `exclude` glob patterns to focus reviews on source directories while skipping build artifacts, lockfiles, and node modules.
26
+ - **Project-Specific Rules**: Inject custom guidelines directly into the reviewer's system prompt (e.g., "Check for SQL injection", "Ensure TypeScript types are explicit").
27
+ - **Interactive Model Selector**: Automatically queries OpenCode to present a clean, interactive list of your connected providers and models.
28
+ - **Local Reports**: Generates markdown reviews under `.diffowl/reviews/`, including hidden session metadata that makes reports chat-capable.
29
+ - **Agent-Assisted Resolution**: Includes an optional portable skill that lets coding agents investigate findings, fix confirmed issues, record dismissals, and archive handled reports.
30
+ - **Hook Log Retention**: Bounds accumulated hook logs without deleting review history.
31
+
32
+ ---
33
+
34
+ ## Quick Start
35
+
36
+ ### 1. Prerequisites
37
+
38
+ 1. **Verify Node.js 20 or newer is installed**:
39
+ ```bash
40
+ node --version
41
+ ```
42
+ 2. **Install OpenCode CLI**:
43
+ ```bash
44
+ npm install --global opencode-ai
45
+ ```
46
+ 3. **Authenticate a provider and confirm a model is available**:
47
+ ```bash
48
+ opencode
49
+ ```
50
+ In OpenCode, connect or authenticate a provider such as GitHub Copilot, OpenAI, or Ollama. Confirm that at least one model is available before continuing.
51
+
52
+ ### 2. Install DiffOwl
53
+
54
+ ```bash
55
+ npm install --global diffowl
56
+ ```
57
+
58
+ ### 3. Initialize DiffOwl in Your Repository
59
+
60
+ To set up DiffOwl for your project, navigate to your target git repository and run:
61
+
62
+ ```bash
63
+ diffowl init
64
+ ```
65
+
66
+ This will:
67
+
68
+ 1. Start an OpenCode server if needed and `server.auto_start` is enabled.
69
+ 2. Fetch your connected providers and active models.
70
+ 3. Allow you to select a model interactively.
71
+ 4. Generate a `.diffowl.yml` configuration file in the current project.
72
+
73
+ > [!IMPORTANT]
74
+ > DiffOwl uses OpenCode's existing provider credentials. It does not configure provider keys itself. If initialization reports no active models, run `opencode`, connect or re-authenticate a provider, confirm a model is available, and rerun `diffowl init`.
75
+
76
+ ### 4. Run Your First Review
77
+
78
+ ```bash
79
+ diffowl review
80
+ ```
81
+
82
+ Read the latest report at `.diffowl/reviews/latest.md`, or install the optional resolution skill below to let a coding agent investigate and handle findings.
83
+
84
+ If a review reports an authentication or provider failure:
85
+
86
+ 1. Run `opencode`.
87
+ 2. Connect or re-authenticate the provider and confirm the configured model is available.
88
+ 3. Retry with `diffowl review`.
89
+
90
+ For a timeout, retry with less context:
91
+
92
+ ```bash
93
+ diffowl review --depth shallow
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Resolve Findings With an Agent
99
+
100
+ DiffOwl can use an inexpensive model for review generation while a stronger coding agent verifies and resolves the resulting findings. The optional `diffowl-resolve` skill works with agents that support the open [Agent Skills](https://skills.sh/) format.
101
+
102
+ ### Install the skill
103
+
104
+ Install for the current project from GitHub:
105
+
106
+ ```bash
107
+ npx skills add gutierrezje/diffowl --skill diffowl-resolve
108
+ ```
109
+
110
+ Install globally for all projects:
111
+
112
+ ```bash
113
+ npx skills add gutierrezje/diffowl --skill diffowl-resolve --global
114
+ ```
115
+
116
+ From an npm-installed copy of DiffOwl:
117
+
118
+ ```bash
119
+ npx skills add "$(npm root --global)/diffowl" --skill diffowl-resolve
120
+ ```
121
+
122
+ Try the skill once without installing it:
123
+
124
+ ```bash
125
+ npx skills use gutierrezje/diffowl@diffowl-resolve
126
+ ```
127
+
128
+ The skills CLI detects supported agents and installs the skill into the appropriate location. Project installation is the default. Use `--global` when you want the skill available across repositories. Restart or reload your agent if it does not immediately discover newly installed skills.
129
+
130
+ ### Use the skill
131
+
132
+ First generate a review:
133
+
134
+ ```bash
135
+ diffowl review
136
+ ```
137
+
138
+ Then ask your coding agent in plain language:
139
+
140
+ ```text
141
+ Resolve the latest DiffOwl review.
142
+ ```
143
+
144
+ Other useful prompts:
145
+
146
+ ```text
147
+ Investigate finding 2 in the latest DiffOwl review.
148
+ Resolve all open DiffOwl reviews.
149
+ Check whether the older DiffOwl findings have already been fixed.
150
+ Archive fully resolved DiffOwl reviews.
151
+ ```
152
+
153
+ The agent will:
154
+
155
+ 1. Treat findings as candidates and verify them against the current code.
156
+ 2. Fix confirmed issues using the repository's normal workflow.
157
+ 3. Mark findings as fixed, already fixed, agent dismissed, user dismissed, deferred, or open.
158
+ 4. Append a `## Resolution` checklist without rewriting the generated review.
159
+ 5. Move fully handled timestamped reports into `.diffowl/reviews/resolved/`.
160
+
161
+ `latest.md` is only a copy of the newest report and is overwritten by future reviews. The skill updates the matching timestamped report as the durable record.
162
+
163
+ The generated review content remains unchanged. Resolution state is appended under `## Resolution`. To reopen the OpenCode session for an archived report, pass its explicit path:
164
+
165
+ ```bash
166
+ diffowl chat .diffowl/reviews/resolved/review-<timestamp>.md
167
+ ```
168
+
169
+ ### What the statuses mean
170
+
171
+ | Status | Meaning | Complete? |
172
+ | --------------- | ------------------------------------------------------------- | --------- |
173
+ | Fixed | The agent changed code or configuration and verified the fix. | Yes |
174
+ | Already fixed | Current code no longer exhibits the reported issue. | Yes |
175
+ | Agent dismissed | Investigation showed the finding was noise or incorrect. | Yes |
176
+ | User dismissed | You explicitly chose not to address the finding. | Yes |
177
+ | Deferred | The issue is valid but intentionally left for later. | No |
178
+ | Open | The finding has not been fully investigated. | No |
179
+
180
+ Reports containing deferred or open findings remain in `.diffowl/reviews/`. DiffOwl never deletes review history automatically.
181
+
182
+ ### Troubleshooting
183
+
184
+ - **No review exists:** Run `diffowl review` first, or install `diffowl hook install` and make a commit.
185
+ - **The agent does not load the skill:** Verify project installation with `npx skills list` or global installation with `npx skills list --global`, then restart or reload the agent.
186
+ - **The skill is installed for the wrong agent:** Reinstall with `--agent <agent-name>`, or use `--agent '*'` to install for every detected agent.
187
+ - **A hook review timed out:** Run the retry command shown by the next foreground DiffOwl command, or retry manually with `diffowl review --commit <sha> --depth shallow`.
188
+ - **You prefer manual resolution:** Edit code normally; the skill is optional and does not affect the DiffOwl CLI.
189
+
190
+ ---
191
+
192
+ ## CLI Reference
193
+
194
+ ### `diffowl` (or `diffowl review`)
195
+
196
+ Runs a code review on your repository.
197
+
198
+ - **Default**: Reviews the changes in the **last commit**.
199
+ - `--staged`: Reviews currently **staged changes** instead of the last commit.
200
+ - `--commit <ref>`: Reviews a specific commit ref instead of the last commit.
201
+ - `--hook`: Runs in background, non-blocking mode (used by Git hook).
202
+ - `--depth <depth>`: Overrides configured review depth. Valid values: `shallow`, `default`.
203
+ - `--reasoning <effort>`: Overrides configured OpenCode reasoning variant. Valid values: `auto`, `none`, `minimal`, `low`, `medium`, `high`, `max`, `xhigh`.
204
+ - `--verbose`: Includes suppressed findings and extra review details in the report.
205
+
206
+ Candidates below `min_confidence` or outside changed files are excluded from actionable finding counts and review status. When any are excluded, the report includes a short diagnostic summary and points to `diffowl chat` for investigation. Outside-file candidates are shown in full with `--verbose`; below-threshold candidates remain available in the OpenCode session.
207
+
208
+ Rendered findings have stable `Finding N` headings, making prompts such as “investigate finding 2” map directly to resolution checklist entries.
209
+
210
+ Review depth controls both how much local context DiffOwl preloads and how much exploration the reviewer is expected to do:
211
+
212
+ - `shallow`: Cheap, surface-level review. Uses a smaller diff-centered prompt with no AI tools enabled. It is expected to miss deeper issues, but can catch obvious local bugs such as off-by-one errors, inverted conditions, unsafe null handling, missing awaits, and implementation anti-patterns visible in the diff.
213
+ - `default`: Normal review. Includes changed TypeScript AST symbols, small file excerpts, related tests, and bounded Potential Call Flow snippets from `git grep`. Permissionless read/search tools are enabled for targeted exploration when context is incomplete; permission prompts are rejected.
214
+
215
+ ```bash
216
+ # Review last commit
217
+ diffowl
218
+
219
+ # Review staged files
220
+ diffowl review --staged
221
+
222
+ # Review a specific commit
223
+ diffowl review --commit abc1234
224
+
225
+ # Include suppressed outside-file findings in the report
226
+ diffowl review --staged --verbose
227
+
228
+ # Request a high reasoning variant for models that support it
229
+ diffowl review --staged --reasoning high
230
+ ```
231
+
232
+ ### `diffowl model`
233
+
234
+ View or interactively change the active AI model.
235
+
236
+ ```bash
237
+ # Interactively pick a model
238
+ diffowl model
239
+
240
+ # Manually set a model
241
+ diffowl model opencode-go/big-pickle
242
+ ```
243
+
244
+ ### `diffowl chat [report]`
245
+
246
+ Opens the OpenCode session associated with a review report. DiffOwl hands control to the OpenCode TUI rather than implementing a separate chat interface.
247
+
248
+ ```bash
249
+ # Interactively select a review
250
+ diffowl chat
251
+
252
+ # Open a specific timestamped report directly
253
+ diffowl chat review-2026-06-07T07-30-42-762Z.md
254
+
255
+ # Use an explicit relative or absolute report path
256
+ diffowl chat ./.diffowl/reviews/latest.md
257
+ ```
258
+
259
+ Without an argument, DiffOwl displays active and resolved timestamped reports newest first. Bare filenames are resolved under `.diffowl/reviews/`, so agents and scripts can open a report deterministically without using the picker. Each chat-capable report stores its OpenCode session ID and project root in YAML frontmatter. Reports created before this feature and documentation-only skip reports do not have an OpenCode session to reopen.
260
+
261
+ ### `diffowl hook install | status | uninstall`
262
+
263
+ Installs or removes a managed post-commit Git hook that runs reviews automatically and asynchronously in the background.
264
+
265
+ ```bash
266
+ # Install non-blocking post-commit review hook
267
+ diffowl hook install
268
+
269
+ # Check whether the hook is installed and up to date
270
+ diffowl hook status
271
+
272
+ # Uninstall the hook
273
+ diffowl hook uninstall
274
+ ```
275
+
276
+ _Runs reviews asynchronously in the background, saving execution output to `.diffowl/hook.log` and the latest report to `.diffowl/reviews/latest.md`. Hook reviews use the configured `context.depth`, return control to your terminal instantly, and avoid clobbering any existing post-commit hook scripts._
277
+
278
+ Only one hook review runs per project at a time. Each commit is recorded under `.diffowl/pending-reviews/`, and a background worker processes pending commits in order. Successful reviews remove their marker; failed reviews remain pending and are retried when a later commit triggers the hook. Review failures are recorded with their commit SHA in `.diffowl/last-hook-status.json` and reported on the next foreground review with commands to retry at default or shallow depth. Result files without a matching pending marker are removed automatically.
279
+
280
+ ### `diffowl server start | stop | status`
281
+
282
+ Manually manage the OpenCode server lifecycle.
283
+
284
+ ```bash
285
+ # Check if OpenCode serve is running
286
+ diffowl server status
287
+
288
+ # Start it manually
289
+ diffowl server start
290
+
291
+ # Stop the server
292
+ diffowl server stop
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Configuration (`.diffowl.yml`)
298
+
299
+ Your `.diffowl.yml` configures everything for DiffOwl in your project:
300
+
301
+ ```yaml
302
+ # Model to use for reviews (provider/model)
303
+ model: opencode-go/big-pickle
304
+
305
+ # OpenCode server settings
306
+ server:
307
+ port: 4096
308
+ auto_start: true
309
+
310
+ # Local review context strategy: shallow or default
311
+ context:
312
+ depth: default
313
+
314
+ # OpenCode model variant for reasoning/thinking effort.
315
+ # auto leaves the selected model/provider default alone.
316
+ reasoning:
317
+ effort: auto
318
+
319
+ # Hook log retention. Set to 0 for unlimited retention.
320
+ retention:
321
+ # Before each hook review, retain approximately this many KiB
322
+ # of previous hook.log output. The new run may exceed this target.
323
+ hook_log_kb: 1024
324
+
325
+ # Review timeout in seconds
326
+ timeout: 300
327
+
328
+ # Minimum confidence level of findings to report: low, medium, or high
329
+ min_confidence: medium
330
+
331
+ # Skip reviews when every changed file is documentation-like
332
+ skip_doc_only: false
333
+
334
+ # Include suppressed outside-file findings and extra details in reports
335
+ verbose: false
336
+
337
+ # Review scope
338
+ include:
339
+ - "src/**/*"
340
+ - "lib/**/*"
341
+
342
+ exclude:
343
+ - "**/*.test.*"
344
+ - "**/*.spec.*"
345
+ - "**/*.lock"
346
+ - "**/node_modules/**"
347
+ - "**/dist/**"
348
+ - "**/build/**"
349
+
350
+ # Custom project-specific review rules
351
+ rules:
352
+ - "Check for potential security vulnerabilities like SQL injection or SSRF"
353
+ - "Flag any hardcoded secrets, tokens, or private keys"
354
+ - "Suggest readability and architectural improvements where relevant"
355
+ ```
356
+
357
+ ---
358
+
359
+ ## Review Files
360
+
361
+ Each completed review starts with a timestamped report and an ephemeral `latest.md` copy. The optional resolution skill moves fully handled timestamped reports into the resolved archive:
362
+
363
+ ```text
364
+ .diffowl/reviews/review-<timestamp>.md # Durable timestamped report
365
+ .diffowl/reviews/latest.md # Ephemeral copy of the newest report
366
+ .diffowl/reviews/resolved/review-<timestamp>.md # Fully handled report archived by the skill
367
+ ```
368
+
369
+ Review reports include YAML frontmatter similar to:
370
+
371
+ ```yaml
372
+ ---
373
+ diffowl:
374
+ session_id: ses_...
375
+ project_root: /path/to/project
376
+ ---
377
+ ```
378
+
379
+ This metadata is used by `diffowl chat`. Agents may append a `## Resolution` section to timestamped reports, but should preserve the generated review body. DiffOwl does not delete review history automatically.
380
+
381
+ ---
382
+
383
+ ## Developing
384
+
385
+ Clone the repository and link the CLI globally:
386
+
387
+ ```bash
388
+ git clone https://github.com/gutierrezje/diffowl.git
389
+ cd diffowl
390
+ pnpm install
391
+ pnpm run build
392
+ pnpm link --global
393
+ ```
394
+
395
+ When making edits to `src/**`, rebuild to update the linked CLI and git hooks:
396
+
397
+ ```bash
398
+ pnpm run build
399
+ git add -p
400
+ diffowl review --staged
401
+ ```
402
+
403
+ To verify model discovery against an authenticated OpenCode server already running on port 4096:
404
+
405
+ ```bash
406
+ DIFFOWL_INTEGRATION=1 pnpm exec vitest run src/opencode/models.integration.test.ts
407
+ ```
408
+
409
+ Set `DIFFOWL_OPENCODE_PORT` when the server uses a different port. This live test is skipped during the normal test suite.
410
+
411
+ ---
412
+
413
+ ## License
414
+
415
+ MIT © [Jesus Gutierrez](https://github.com/gutierrezje)