660 lines
22 KiB
Markdown
660 lines
22 KiB
Markdown
> [!IMPORTANT]
|
|
> **This entire repository is AI-generated.** The source code, tests, and
|
|
> documentation were produced through AI-assisted development.
|
|
>
|
|
> **Repository owner's two cents:**
|
|
> Like the previous text says this Repo is entirely slop coded.
|
|
> I guided the ai (gpt5.6-sol) as best as I could and got out the program I desired.
|
|
> Use this at your own risk, especially the AI integration.
|
|
> _No AI Agents were harmed during creation of this Program_
|
|
|
|
# diple
|
|
|
|
`diple` is a keyboard-first terminal interface for reading and responding to
|
|
GitHub pull request reviews. It is designed primarily for the person receiving
|
|
a review: it keeps the PR description, status, changed code, review threads,
|
|
and the actions needed to address feedback in one terminal application.
|
|
|
|
The project is under active development. GitHub write actions are guarded by
|
|
the permissions reported for the current user and ask for confirmation where
|
|
the result is consequential. The optional AI review feature is experimental,
|
|
disabled by default, and local-only.
|
|
|
|
## What diple does
|
|
|
|
### Pull request picker
|
|
|
|
- Loads open PRs assigned to the authenticated user across repositories.
|
|
- Groups the picker by repository.
|
|
- Can be restricted to one `owner/repository`.
|
|
- Can show every open PR in a selected repository.
|
|
- Uses a disk cache to display a recent snapshot immediately while live data
|
|
loads.
|
|
|
|
### Dashboard
|
|
|
|
- Shows the title, Markdown description, branches, author, assignees,
|
|
reviewers, labels, milestone, merge state, review decision, checks, change
|
|
statistics, submitted reviews, timeline activity, and PR conversation.
|
|
- Reports whether the PR has conflicts.
|
|
- Attempts to identify conflicting files with a read-only temporary Git
|
|
analysis. This does not inspect or modify the current Git or Jujutsu
|
|
checkout.
|
|
- Shows check-run annotations independently so a failure in one subsection
|
|
does not blank the rest of the dashboard.
|
|
- Provides a Health popup containing API, cache, persistence, conflict-scan,
|
|
rate-limit, write-capability, and AI-provider diagnostics.
|
|
|
|
### Review threads
|
|
|
|
- Displays review comments beside the exact review-time diff hunk when GitHub
|
|
provides it, even when the file has since changed.
|
|
- Syntax-highlights code using the file path to choose a lexer.
|
|
- Highlights the reviewed line range and exact changed spans.
|
|
- Wraps long source lines as continuation rows without inventing line numbers.
|
|
- Renders GitHub Flavored Markdown, including quoted replies, inline and
|
|
fenced code, lists, task lists, tables, links, emphasis, strikethrough,
|
|
emoji, and GitHub alerts.
|
|
- Renders GitHub suggestion blocks as syntax-highlighted removal/addition
|
|
previews.
|
|
- Shows deterministic per-author colors and read-only reaction counts.
|
|
- Folds resolved threads by default and distinguishes unread or updated local
|
|
state.
|
|
- After resolving the selected thread, keeps the cursor nearby by selecting
|
|
the next thread, or the previous thread when resolving the last one.
|
|
- Supports fuzzy path search; whitespace-separated terms may match separate
|
|
portions of the same path.
|
|
- Supports configurable status and within-status ordering.
|
|
|
|
### GitHub write actions
|
|
|
|
When GitHub reports that the authenticated user has permission, diple can:
|
|
|
|
- reply to review threads;
|
|
- resolve and unresolve review threads;
|
|
- edit the PR title, Markdown description, target branch, requested reviewers,
|
|
and assignees;
|
|
- enable or disable auto-merge; and
|
|
- merge immediately when the PR is eligible.
|
|
|
|
The UI explains unavailable actions through its write-capability gate.
|
|
Metadata and reply drafts are persisted locally so cancellation or a restart
|
|
does not silently discard work. Replies, thread resolution changes, and PR
|
|
metadata or people edits are also placed in a durable FIFO queue before they
|
|
are sent. If the most recent cached snapshot granted the action, it may be
|
|
queued while offline and is replayed automatically after connectivity returns.
|
|
Merge and auto-merge actions remain online-only.
|
|
|
|
Reactions are currently read-only. Assigning labels or milestones is not
|
|
implemented yet.
|
|
|
|
## Requirements
|
|
|
|
- Go 1.24 or newer to build from source.
|
|
- An authenticated [GitHub CLI](https://cli.github.com/) installation, or a
|
|
supported GitHub token environment variable.
|
|
- Git 2.38 or newer for conflicting-file discovery. The rest of the PR remains
|
|
usable if that optional scan cannot run.
|
|
- A terminal with reasonable Unicode support.
|
|
- Optional: an authenticated Codex CLI for experimental local AI review.
|
|
|
|
## Install and run
|
|
|
|
From a source checkout:
|
|
|
|
```sh
|
|
go install .
|
|
gh auth login
|
|
diple
|
|
```
|
|
|
|
Run without installing:
|
|
|
|
```sh
|
|
go run .
|
|
```
|
|
|
|
Use `go run .`, not `go run main.go`. The latter omits the other Go files in
|
|
the package.
|
|
|
|
By default, diple finds open PRs assigned to the authenticated user across all
|
|
repositories:
|
|
|
|
```sh
|
|
diple
|
|
```
|
|
|
|
Limit the picker to one repository:
|
|
|
|
```sh
|
|
diple --repo owner/repository
|
|
```
|
|
|
|
Include every open PR in that repository:
|
|
|
|
```sh
|
|
diple --repo owner/repository --all
|
|
```
|
|
|
|
Adjust polling or inspect all command-line options:
|
|
|
|
```sh
|
|
diple --poll 15s
|
|
diple --version
|
|
diple --help
|
|
```
|
|
|
|
Command-line options override configuration values. `GH_REPO` supplies the
|
|
default repository only when `--repo` is absent.
|
|
|
|
## Authentication
|
|
|
|
Credential lookup uses the first available value in this order:
|
|
|
|
1. `GH_TOKEN`
|
|
2. `GITHUB_TOKEN`
|
|
3. `GH_ENTERPRISE_TOKEN`
|
|
4. `GITHUB_ENTERPRISE_TOKEN`
|
|
5. the token returned by `gh auth token` for the endpoint host
|
|
|
|
For normal interactive use:
|
|
|
|
```sh
|
|
gh auth login
|
|
diple
|
|
```
|
|
|
|
For GitHub Enterprise Server, authenticate the host and provide its GraphQL
|
|
endpoint:
|
|
|
|
```sh
|
|
gh auth login --hostname github.example.com
|
|
diple \
|
|
--repo owner/repository \
|
|
--endpoint https://github.example.com/api/graphql
|
|
```
|
|
|
|
The token must have sufficient access to read the selected repositories.
|
|
Write actions additionally depend on the permissions GitHub reports for the
|
|
particular PR or thread.
|
|
|
|
## Navigation
|
|
|
|
The defaults are Vim-like and every binding is configurable.
|
|
|
|
- `j` / `k`: move down / up
|
|
- `h` / `l`: switch panes or move left / right in the active context
|
|
- `enter`: open or toggle the selected item
|
|
- `b`: go back outside text editing
|
|
- `d`: open the dashboard
|
|
- `tab`: hide or show the thread list
|
|
- `/`: fuzzy-search thread file paths
|
|
- `n` / `N`: next / previous unread thread
|
|
- `c`: reply to the selected thread
|
|
- `R`: resolve or unresolve the selected thread
|
|
- `r`: refresh
|
|
- `H`: open Health
|
|
- `A`: open the experimental local AI menu
|
|
- `?`: show all bindings for the current screen
|
|
- `q`: quit
|
|
|
|
Compact footers show only the first configured key for each action. The
|
|
contextual help popup shows all alternatives and is the authoritative in-app
|
|
reference.
|
|
|
|
Set `mouse = true` to enable mouse-wheel scrolling. Each wheel event moves the
|
|
focused pane by three items or rendered lines. Mouse reporting remains disabled
|
|
by default so normal terminal text selection is unchanged; with mouse reporting
|
|
enabled, terminals commonly require holding Shift while selecting text.
|
|
|
|
Editable text fields default to Vim-style modal editing, including PR metadata,
|
|
reply, and local-AI discussion fields. They support Normal, Insert, and Visual
|
|
modes, word/find motions, deletion, system clipboard yank/paste, and
|
|
soft-wrap-aware movement. The active mode and input are shown in a Neovim-style
|
|
footer bar. Set `editing.mode = "standard"` for non-modal inputs with arrow-key
|
|
cursor movement, including movement across wrapped lines. Search remains a
|
|
dedicated insert-only filter. Target-branch, reviewer, and assignee completion use
|
|
`ctrl+n` and `ctrl+p`; `enter` accepts the selected completion, while `tab`
|
|
moves to the next metadata field. Reviewer and assignee fields accept
|
|
comma-separated GitHub usernames. Pending individual review requests and assignees are
|
|
prefilled and marked in completion results. Reviewers who already submitted a
|
|
review, and requested teams, appear first as protected subdued tokens in the
|
|
reviewer field. Their handles retain a darker version of their deterministic
|
|
user color, while their brackets and review state use the theme's dim color.
|
|
GitHub only permits changing pending review requests.
|
|
Protected reviewers cannot receive cursor focus or be deleted, and are excluded
|
|
from reviewer completion. Newly entered names gain a visual `@` prefix and
|
|
their deterministic user color as soon as they exactly match an eligible
|
|
reviewer. At that point the suggestions reset to the remaining eligible users;
|
|
pressing Space commits the current reviewer and starts the next entry. Reviewers
|
|
already present in the field are excluded from those suggestions. Reviewer
|
|
suggestions prioritize recent contributors using the latest 100 commits on the
|
|
repository's default branch; this bounded window is also shown in the editor.
|
|
Every change is shown in the existing confirmation screen before GitHub is
|
|
updated.
|
|
|
|
## Configuration
|
|
|
|
Configuration is optional TOML. diple checks:
|
|
|
|
1. `--config FILE`;
|
|
2. `DIPLE_CONFIG`;
|
|
3. `$XDG_CONFIG_HOME/diple/config.toml`; and
|
|
4. the operating-system configuration directory.
|
|
|
|
Common default paths:
|
|
|
|
- Linux: `~/.config/diple/config.toml`
|
|
- macOS: `~/Library/Application Support/diple/config.toml`
|
|
- macOS fallback: `~/.config/diple/config.toml`
|
|
|
|
Unknown settings and invalid values are rejected at startup instead of being
|
|
silently ignored.
|
|
|
|
### Example configuration
|
|
|
|
All settings below show their normal defaults unless noted otherwise:
|
|
|
|
```toml
|
|
theme = "dark"
|
|
refresh_interval = "10s" # minimum 2s
|
|
repository = "" # optional "owner/repository"
|
|
show_all = false # requires repository
|
|
limit = 50 # 1-1000
|
|
endpoint = "https://api.github.com/graphql"
|
|
mouse = false # opt in to accelerated mouse-wheel scrolling
|
|
mascot = false # show the optional Difflet terminal mascot
|
|
mascot_expressive = false # allow emotional Difflet expressions
|
|
mascot_animated = false # allow brief state-driven motion
|
|
|
|
[display]
|
|
fold_resolved = true
|
|
thread_list_width_percent = 33 # 20-60
|
|
dashboard_mode = "hotkey" # "hotkey" or "intermediate"
|
|
compact_reviews = true
|
|
viewer_label = "login" # "login" or "you"
|
|
|
|
[paths]
|
|
scroll = false
|
|
scroll_interval = "350ms" # minimum 50ms
|
|
|
|
[threads]
|
|
# Each category must occur exactly once. Resolved wins over outdated.
|
|
status_order = ["unresolved", "outdated", "resolved"]
|
|
within_status = "file" # "file" or "timestamp"
|
|
|
|
[cache]
|
|
enabled = true
|
|
max_age = "168h" # 7 days; 0 disables offline expiry
|
|
directory = "" # empty uses the OS cache directory
|
|
max_entries = 200 # 10-10000
|
|
|
|
[editing]
|
|
mode = "vim" # "vim" or "standard"
|
|
|
|
[ai]
|
|
enabled = false
|
|
provider = "codex-cli" # currently the only implemented provider
|
|
model = "" # empty selects the provider default
|
|
command = "codex"
|
|
timeout = "3m"
|
|
max_calls = 8
|
|
max_request_bytes = 180000
|
|
max_run_bytes = 900000
|
|
max_file_bytes = 150000
|
|
max_context_rounds = 2 # automatic file-request rounds for a thread
|
|
max_context_files = 8 # additional files per thread discussion
|
|
store_directory = ""
|
|
exclude = [
|
|
"*.lock", "go.sum", "package-lock.json", "vendor/", "node_modules/",
|
|
"dist/", "build/", "generated/", "coverage/", "*.generated.*",
|
|
"*_generated.*", "*.min.js", "*.map",
|
|
]
|
|
sensitive_paths = [
|
|
".env", ".env.*", "*.pem", "*.key", "*.p12", "*.pfx",
|
|
"*credentials*",
|
|
]
|
|
```
|
|
|
|
As with other TOML arrays, setting `exclude` or `sensitive_paths` replaces its
|
|
default list. Copy the defaults you still want before adding project-specific
|
|
patterns.
|
|
|
|
`dashboard_mode = "hotkey"` opens threads directly from the picker and leaves
|
|
the dashboard on `d`. `"intermediate"` places the dashboard between the picker
|
|
and thread viewer.
|
|
|
|
`compact_reviews = true` summarizes the submitted-review history instead of
|
|
showing every repeated `COMMENTED` event.
|
|
|
|
`viewer_label = "login"` shows your GitHub username like every other author.
|
|
Set it to `"you"` to replace your username with `@you` throughout the UI.
|
|
|
|
Difflet is disabled by default. Set `mascot = true` to show it on the pull
|
|
request picker, dashboard, and thread screens. On the dashboard it is centered
|
|
beside the first metadata rows so it does not add whitespace below the pull
|
|
request title. Editor and popup views hide it to preserve their full usable
|
|
height. On other supported screens Difflet sits to the right of the naturally
|
|
sized header. Header information wraps when the combined header and mascot do
|
|
not fit.
|
|
`mascot_animated` controls brief loading, blink, success, and error motion
|
|
independently from `mascot_expressive`, which permits stronger emotional
|
|
faces. Disabling animation leaves the appropriate final state visible.
|
|
Disabling the mascot preserves the normal header layout.
|
|
|
|
Thread categories are:
|
|
|
|
- `unresolved`: current unresolved threads;
|
|
- `outdated`: unresolved threads attached to outdated code; and
|
|
- `resolved`: all resolved threads, including resolved-and-outdated threads.
|
|
|
|
New threads retain a `NEW THREAD` marker. When an existing thread receives new
|
|
comments, diple places a `NEW MESSAGES` divider before the first unread comment
|
|
and emphasizes the unread comment rail. Moving the thread-list cursor does not
|
|
clear this state. It is cleared when the thread detail pane receives focus, when
|
|
the thread is resolved, after the last unread comment becomes visible while
|
|
scrolling the focused detail pane, or manually with
|
|
`keybindings.threads.mark_read` (`m` by default).
|
|
|
|
Within a category, `"file"` keeps paths together and `"timestamp"` sorts by
|
|
the time the thread was opened.
|
|
|
|
### Themes
|
|
|
|
Built-in themes:
|
|
|
|
- `dark`
|
|
- `light`
|
|
- `catppuccin` / `catppuccin-mocha`
|
|
- `catppuccin-latte`
|
|
- `gruvbox` / `gruvbox-dark`
|
|
- `gruvbox-light`
|
|
- `one-dark-pro`
|
|
- `github` / `github-dark`
|
|
- `github-light`
|
|
- `high-contrast`
|
|
- `no-color`
|
|
|
|
The selected palette also controls Markdown and source-code syntax
|
|
highlighting.
|
|
|
|
For a custom theme, set `theme = "custom"` and override any subset of a
|
|
built-in base:
|
|
|
|
```toml
|
|
theme = "custom"
|
|
|
|
[custom_theme]
|
|
base = "catppuccin"
|
|
mode = "dark"
|
|
title = "#f5c2e7"
|
|
dim = "#7f849c"
|
|
text = "#cdd6f4"
|
|
active_foreground = "#11111b"
|
|
active_background = "#89b4fa"
|
|
success = "#a6e3a1"
|
|
warning = "#f9e2af"
|
|
error = "#f38ba8"
|
|
editor_foreground = "#cdd6f4"
|
|
editor_background = "#313244"
|
|
pane_inactive = "#585b70"
|
|
pane_active = "#89b4fa"
|
|
quote = "#94e2d5"
|
|
selection_background = "#45475a"
|
|
suggestion_remove_background = "#3b1f2b"
|
|
suggestion_add_background = "#193b2a"
|
|
changed_remove_background = "#4b1f2b"
|
|
changed_add_background = "#1d4b32"
|
|
author_palette = ["#89b4fa", "#cba6f7", "#94e2d5", "#f9e2af"]
|
|
syntax_theme = "catppuccin-mocha"
|
|
```
|
|
|
|
Colors must use `#RRGGBB`. `mode` is `dark` or `light`; `syntax_theme` must be
|
|
an installed Chroma style. Omitted custom values inherit from `base`.
|
|
|
|
### Keybindings
|
|
|
|
Each action accepts one or more Bubble Tea key names. Defining an action
|
|
replaces its default list; omitted actions retain their defaults. Configuration
|
|
validation rejects conflicting assignments within the same active context.
|
|
|
|
```toml
|
|
[keybindings.general]
|
|
quit = ["q", "ctrl+c"]
|
|
help = ["?", "f1"]
|
|
refresh = ["r"]
|
|
back = ["b", "esc"]
|
|
confirm = ["y"]
|
|
reject = ["n", "esc"]
|
|
|
|
[keybindings.navigation]
|
|
down = ["j", "down"]
|
|
up = ["k", "up"]
|
|
left = ["h", "left"]
|
|
right = ["l", "right"]
|
|
first = ["g"]
|
|
last = ["G"]
|
|
page_down = ["ctrl+d", "pgdown"]
|
|
page_up = ["ctrl+u", "pgup"]
|
|
|
|
[keybindings.views]
|
|
open = ["enter", "l"]
|
|
dashboard = ["d"]
|
|
health = ["H"]
|
|
edit = ["e"]
|
|
auto_merge = ["a"]
|
|
merge_now = ["M"]
|
|
toggle_list = ["tab"]
|
|
ai = ["A"]
|
|
|
|
[keybindings.threads]
|
|
search = ["/"]
|
|
clear_filter = ["F"]
|
|
next_unread = ["n"]
|
|
previous_unread = ["N"]
|
|
mark_read = ["m"]
|
|
reply = ["c"]
|
|
resolve = ["R"]
|
|
toggle = ["enter"]
|
|
fold_prefix = ["z"]
|
|
fold_toggle = ["a"]
|
|
|
|
[keybindings.input]
|
|
cancel = ["esc"]
|
|
submit = ["ctrl+s"]
|
|
newline = ["enter"]
|
|
delete_backward = ["backspace"]
|
|
delete_forward = ["delete"]
|
|
clear = ["ctrl+u"]
|
|
next_field = ["tab"]
|
|
previous_field = ["shift+tab"]
|
|
next_completion = ["ctrl+n"]
|
|
previous_completion = ["ctrl+p"]
|
|
line_start = ["home", "ctrl+a"]
|
|
line_end = ["end", "ctrl+e"]
|
|
|
|
[keybindings.vim]
|
|
insert = ["i"]
|
|
append = ["a"]
|
|
insert_line_start = ["I"]
|
|
append_line_end = ["A"]
|
|
open_below = ["o"]
|
|
open_above = ["O"]
|
|
replace_character = ["s"]
|
|
visual = ["v"]
|
|
visual_line = ["V"]
|
|
selection_other_end = ["o"]
|
|
yank = ["y"]
|
|
delete = ["d", "x", "delete"]
|
|
delete_before = ["X", "backspace"]
|
|
paste = ["p"]
|
|
line_start = ["0", "home"]
|
|
first_non_blank = ["^"]
|
|
line_end = ["$", "end"]
|
|
word_forward = ["w"]
|
|
big_word_forward = ["W"]
|
|
word_backward = ["b"]
|
|
big_word_backward = ["B"]
|
|
word_end = ["e"]
|
|
big_word_end = ["E"]
|
|
go_prefix = ["g"]
|
|
find_forward = ["f"]
|
|
find_backward = ["F"]
|
|
till_forward = ["t"]
|
|
till_backward = ["T"]
|
|
repeat_find = [";"]
|
|
repeat_find_reverse = [","]
|
|
```
|
|
|
|
Printable bindings do not steal ordinary text while an input field, search, or
|
|
Insert mode owns that key.
|
|
|
|
## Cache and local data
|
|
|
|
The read cache is designed for fast startup and offline fallback:
|
|
|
|
- core picker and PR snapshots are stored separately;
|
|
- unchanged content is not rewritten on every refresh;
|
|
- changed files are replaced atomically;
|
|
- old entries are pruned at `cache.max_entries`; and
|
|
- live data automatically replaces the visible cached snapshot.
|
|
|
|
Cached data is labelled when first shown. A normal refresh does not repeatedly
|
|
reintroduce the cached header.
|
|
|
|
Read state and recoverable drafts live beside the configuration file as
|
|
`state.json` and `drafts.json`. Confirmed reversible GitHub writes are kept in
|
|
`mutation-queue.json` until GitHub confirms them. Experimental AI data defaults
|
|
to the `ai` directory beside the configuration. These files are versioned and
|
|
written atomically; sensitive user-authored state uses restrictive permissions.
|
|
|
|
Cached permission gates are treated as the last known truth while offline:
|
|
actions granted by the snapshot can be queued, while actions denied by it stay
|
|
disabled. Pending replies and projected PR or thread changes are labelled in
|
|
the UI without being written into the read cache. Replay preserves global
|
|
enqueue order, including across repositories.
|
|
|
|
If GitHub permissions or the target changed, replay pauses before the first
|
|
unsafe operation and presents choices to keep it queued, discard that item and
|
|
continue, or discard the remaining queued changes for that PR. A lost reply
|
|
response is checked against fresh GitHub thread data first; only when delivery
|
|
cannot be determined does diple ask whether to retry or treat it as applied.
|
|
|
|
## Experimental local AI review
|
|
|
|
Enable the feature explicitly:
|
|
|
|
```toml
|
|
[ai]
|
|
enabled = true
|
|
provider = "codex-cli"
|
|
command = "codex"
|
|
```
|
|
|
|
Authenticate Codex separately before opening diple:
|
|
|
|
```sh
|
|
codex login
|
|
```
|
|
|
|
The `A` menu can:
|
|
|
|
- review the current PR and create local-only review threads;
|
|
- discuss an existing local AI thread with the same selected model;
|
|
- add local-only context to existing unresolved GitHub threads;
|
|
- let a focused thread discussion request bounded, exact-head repository files;
|
|
- produce small GitHub-style suggestion blocks for contained changes;
|
|
- refresh provider status without making an inference call; and
|
|
- run one explicitly confirmed, minimal provider test that consumes quota but
|
|
sends no PR contents.
|
|
|
|
Before a review, diple shows the exact head commit, selected model, initial
|
|
included and excluded files, byte count, maximum model-call count, and
|
|
redaction count. Every run requires confirmation. A focused thread confirmation
|
|
also shows its repository-tree summary and the configured automatic
|
|
file-request limits.
|
|
|
|
Full reviews use the authenticated GitHub PR diff. Focused discussions instead
|
|
send only the selected thread, its hunk, the complete target file when allowed,
|
|
minimal PR identifiers, and a bounded tree for the exact PR head. The model can
|
|
request additional paths from that tree, but diple validates and retrieves
|
|
their committed blobs through GitHub; the provider never receives local
|
|
checkout access.
|
|
|
|
`sensitive_paths` are absent from the model-visible tree and can never be
|
|
requested. `exclude` paths may appear as unavailable tree entries but their
|
|
contents are not sent. Binary, submodule, oversized, generated, vendored, and
|
|
lock-file content remains unavailable. All supplied content is bounded,
|
|
control-sanitized, and checked for secret-like values. Full-review findings
|
|
remain restricted to visibly changed lines in the prepared head.
|
|
|
|
The Codex process runs ephemerally in an empty temporary directory with:
|
|
|
|
- repository instructions ignored;
|
|
- a read-only sandbox;
|
|
- approvals disabled;
|
|
- a restricted environment;
|
|
- tools, commands, browser, network, plugins, memories, and multi-agent
|
|
features disabled; and
|
|
- a strict structured-output schema.
|
|
|
|
Attempted tool or file-change events fail the run. Provider output is bounded
|
|
and sanitized. Progress may display a provider-exposed reasoning summary, but
|
|
diple neither requests nor displays hidden chain-of-thought. Progress and
|
|
Health report GitHub, filtering, and provider timing without storing prompts or
|
|
repository contents.
|
|
|
|
AI findings are stored locally, deduplicated deterministically, and marked
|
|
outdated when the PR head changes. Resolving a local AI thread remains local.
|
|
diple never publishes an AI finding or discussion to GitHub automatically.
|
|
|
|
Only the Codex CLI provider is currently implemented. The interface permits
|
|
future providers, but their privacy and retention behavior must be defined
|
|
before they are added.
|
|
|
|
## Shell completion
|
|
|
|
Generate completion without contacting GitHub or loading configuration:
|
|
|
|
```sh
|
|
# Bash, current session
|
|
source <(diple completion bash)
|
|
|
|
# Zsh, current session
|
|
source <(diple completion zsh)
|
|
|
|
# Fish, persistent user installation
|
|
diple completion fish > ~/.config/fish/completions/diple.fish
|
|
```
|
|
|
|
For persistent Zsh completion, save the output as `_diple` in a directory on
|
|
`$fpath` and ensure `compinit` runs. The generated Zsh script also initializes
|
|
completion when sourced directly:
|
|
|
|
```sh
|
|
mkdir -p ~/.zfunc
|
|
diple completion zsh > ~/.zfunc/_diple
|
|
fpath=(~/.zfunc $fpath)
|
|
autoload -Uz compinit
|
|
compinit
|
|
```
|
|
|
|
Run `diple completion --help` for the supported shells.
|
|
|
|
## Development
|
|
|
|
The module path is `git.pablu.de/Pablu/diple`. The repository is a single Go
|
|
`package main` built around Bubble Tea, Lip Gloss, Chroma, and Glamour.
|
|
|
|
```sh
|
|
gofmt -w path/to/changed.go
|
|
go test ./...
|
|
go test -race ./...
|
|
go vet ./...
|
|
go build ./...
|
|
```
|
|
|
|
Repository architecture, safety invariants, and contributor guidance are
|
|
documented in [AGENTS.md](AGENTS.md). Planned work is tracked in
|
|
[TODO.md](TODO.md).
|