add AGENTS.md and update README.md
This commit is contained in:
657
README.md
657
README.md
@@ -1,21 +1,99 @@
|
||||
> [!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
|
||||
|
||||
A terminal UI for people receiving GitHub pull-request reviews. It
|
||||
shows open PRs and a scrollable PR dashboard with the description, branches,
|
||||
review state, merge conflicts and affected files, checks, people, labels,
|
||||
milestone, activity, change statistics, thread totals, submitted reviews, and
|
||||
the PR conversation. Review threads and comments are paginated rather than
|
||||
silently stopping at the first page. The
|
||||
thread viewer includes highlighted diff hunks, comment authors, and read-only
|
||||
reaction counts on individual comments. Resolved threads start folded. GitHub suggestion blocks are shown as
|
||||
syntax-highlighted remove/add previews. Comments and PR descriptions render
|
||||
GitHub Flavored Markdown, including quoted replies, inline and fenced code,
|
||||
lists and tasks, links, tables, emphasis, strikethrough, emoji, and GitHub
|
||||
alerts. The current PR is refreshed in the background.
|
||||
`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.
|
||||
- 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, and target branch;
|
||||
- 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.
|
||||
|
||||
Reactions are currently read-only. Assigning reviewers, assignees, 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
|
||||
|
||||
Requires Go 1.24+, Git 2.38+, and an authenticated GitHub CLI:
|
||||
From a source checkout:
|
||||
|
||||
```sh
|
||||
go install .
|
||||
@@ -23,127 +101,255 @@ gh auth login
|
||||
diple
|
||||
```
|
||||
|
||||
To run directly from a source checkout instead:
|
||||
Run without installing:
|
||||
|
||||
```sh
|
||||
go run .
|
||||
```
|
||||
|
||||
Use `go run .`, not `go run main.go`: the latter compiles only `main.go` and
|
||||
omits the other files in the package.
|
||||
Use `go run .`, not `go run main.go`. The latter omits the other Go files in
|
||||
the package.
|
||||
|
||||
For automation, `GH_TOKEN` or `GITHUB_TOKEN` can still be provided and takes
|
||||
precedence over the GitHub CLI credential. Enterprise token environment
|
||||
variables are also supported.
|
||||
By default, diple finds open PRs assigned to the authenticated user across all
|
||||
repositories:
|
||||
|
||||
By default the PR picker searches all repositories for open PRs assigned to the
|
||||
authenticated user and groups the results by repository. Use `--repo` to limit
|
||||
the picker to one repository:
|
||||
```sh
|
||||
diple
|
||||
```
|
||||
|
||||
Limit the picker to one repository:
|
||||
|
||||
```sh
|
||||
diple --repo owner/repository
|
||||
```
|
||||
|
||||
With a repository selected, pass `--all` to include every open PR in that
|
||||
repository:
|
||||
Include every open PR in that repository:
|
||||
|
||||
```sh
|
||||
diple --repo owner/repository --all --poll 15s
|
||||
diple --repo owner/repository --all
|
||||
```
|
||||
|
||||
GitHub Enterprise Server can be used after authenticating that host:
|
||||
Adjust polling or inspect all command-line options:
|
||||
|
||||
```sh
|
||||
diple --poll 15s
|
||||
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 \
|
||||
diple \
|
||||
--repo owner/repository \
|
||||
--endpoint https://github.example.com/api/graphql
|
||||
```
|
||||
|
||||
## Shell completion
|
||||
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.
|
||||
|
||||
`diple` generates completion scripts without contacting GitHub or loading the
|
||||
configuration. Choose the command for your shell:
|
||||
## Navigation
|
||||
|
||||
```sh
|
||||
# Bash: current session
|
||||
source <(diple completion bash)
|
||||
The defaults are Vim-like and every binding is configurable.
|
||||
|
||||
# Zsh: current session
|
||||
source <(diple completion zsh)
|
||||
- `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
|
||||
|
||||
# Fish: install for the current user
|
||||
diple completion fish > ~/.config/fish/completions/diple.fish
|
||||
```
|
||||
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.
|
||||
|
||||
For persistent Bash completion, write the generated output to a directory
|
||||
loaded by your distribution's `bash-completion` package. For persistent Zsh
|
||||
completion, write it to a file named `_diple` in a directory on `$fpath`, then
|
||||
run `compinit`. `diple completion --help` lists the supported shells, while
|
||||
`diple --help` shows grouped command-line options, defaults, configuration
|
||||
precedence, and authentication behavior.
|
||||
The PR description editor defaults to Vim-style modal editing, including
|
||||
Normal, Insert, and Visual modes, word/find motions, deletion, system clipboard
|
||||
yank/paste, and soft-wrap-aware movement. Set `editing.mode = "standard"` for a
|
||||
non-modal editor. Target-branch completion uses `ctrl+n` and `ctrl+p`.
|
||||
|
||||
## Configuration
|
||||
|
||||
The optional TOML configuration is loaded from
|
||||
`$DIPLE_CONFIG`, `$XDG_CONFIG_HOME/diple/config.toml`, or the operating
|
||||
system's user configuration directory at `diple/config.toml`.
|
||||
On Linux this is normally `~/.config/diple/config.toml`. On macOS,
|
||||
`~/Library/Application Support/diple/config.toml` is preferred, with
|
||||
`~/.config/diple/config.toml` automatically used as a fallback when it
|
||||
exists.
|
||||
Configuration is optional TOML. diple checks:
|
||||
|
||||
For migration, `GH_THREADS_CONFIG` and existing `gh-threads` configuration or
|
||||
cache directories remain fallback locations when their new `diple`
|
||||
counterparts do not yet exist.
|
||||
1. `--config FILE`;
|
||||
2. `DIPLE_CONFIG`;
|
||||
3. `GH_THREADS_CONFIG` as a migration fallback;
|
||||
4. `$XDG_CONFIG_HOME/diple/config.toml`;
|
||||
5. the operating-system configuration directory; and
|
||||
6. legacy `gh-threads` paths when no diple configuration exists.
|
||||
|
||||
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" # built-in name, "custom", or an accessibility mode
|
||||
refresh_interval = "10s"
|
||||
repository = "" # optional owner/repository default
|
||||
show_all = false # requires repository
|
||||
limit = 50
|
||||
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"
|
||||
|
||||
[display]
|
||||
fold_resolved = true
|
||||
thread_list_width_percent = 33 # 20-60
|
||||
dashboard_mode = "hotkey" # "hotkey" or "intermediate"
|
||||
compact_reviews = true # aggregate submitted review history
|
||||
compact_reviews = true
|
||||
|
||||
[paths]
|
||||
scroll = false
|
||||
scroll_interval = "350ms" # minimum 50ms
|
||||
|
||||
[threads]
|
||||
# Each status must occur exactly once. "outdated" means unresolved and outdated;
|
||||
# resolved threads remain in "resolved" even when they are also outdated.
|
||||
# Each category must occur exactly once. Resolved wins over outdated.
|
||||
status_order = ["unresolved", "outdated", "resolved"]
|
||||
within_status = "file" # "file" or "timestamp" (oldest first)
|
||||
within_status = "file" # "file" or "timestamp"
|
||||
|
||||
[cache]
|
||||
enabled = true # instant stale view plus offline fallback
|
||||
max_age = "168h" # 7 days; 0 means no age limit
|
||||
directory = "" # defaults to the OS user cache directory
|
||||
max_entries = 200 # bounded oldest-first pruning; 10-10000
|
||||
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"; description field only for now
|
||||
mode = "vim" # "vim" or "standard"
|
||||
|
||||
[ai]
|
||||
# Experimental and local-only. Disabled unless explicitly enabled. Each run
|
||||
# still requires confirmation after its exact scope and redactions are shown.
|
||||
enabled = false
|
||||
provider = "codex-cli" # provider abstraction; only Codex CLI is implemented
|
||||
model = "" # empty uses the provider default for the whole run
|
||||
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
|
||||
store_directory = "" # defaults beside config.toml, mode 0700/0600
|
||||
exclude = ["*.lock", "go.sum", "package-lock.json", "vendor/", "node_modules/", "dist/", "build/", "generated/", "coverage/", "*.generated.*", "*_generated.*", "*.min.js", "*.map", ".env", ".env.*", "*.pem", "*.key", "*.p12", "*.pfx", "*credentials*"]
|
||||
store_directory = ""
|
||||
exclude = [
|
||||
"*.lock", "go.sum", "package-lock.json", "vendor/", "node_modules/",
|
||||
"dist/", "build/", "generated/", "coverage/", "*.generated.*",
|
||||
"*_generated.*", "*.min.js", "*.map", ".env", ".env.*", "*.pem",
|
||||
"*.key", "*.p12", "*.pfx", "*credentials*",
|
||||
]
|
||||
```
|
||||
|
||||
`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.
|
||||
|
||||
Thread categories are:
|
||||
|
||||
- `unresolved`: current unresolved threads;
|
||||
- `outdated`: unresolved threads attached to outdated code; and
|
||||
- `resolved`: all resolved threads, including resolved-and-outdated threads.
|
||||
|
||||
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"]
|
||||
@@ -153,7 +359,6 @@ confirm = ["y"]
|
||||
reject = ["n", "esc"]
|
||||
|
||||
[keybindings.navigation]
|
||||
# Shared by the picker, dashboard, thread panes, help, and Vim Normal/Visual modes.
|
||||
down = ["j", "down"]
|
||||
up = ["k", "up"]
|
||||
left = ["h", "left"]
|
||||
@@ -231,235 +436,127 @@ repeat_find = [";"]
|
||||
repeat_find_reverse = [","]
|
||||
```
|
||||
|
||||
Themes are compiled into `diple`; they do not require a separate download.
|
||||
Available names are `dark`, `light`, `catppuccin` (`catppuccin-mocha`),
|
||||
`catppuccin-latte`, `gruvbox` (`gruvbox-dark`), `gruvbox-light`,
|
||||
`one-dark-pro`, `github` (`github-dark`), `github-light`, `high-contrast`,
|
||||
and `no-color`.
|
||||
Printable bindings do not steal ordinary text while an input field, search, or
|
||||
Insert mode owns that key.
|
||||
|
||||
Set `theme = "custom"` to inherit a built-in palette and replace only the
|
||||
roles you care about:
|
||||
## Cache and local data
|
||||
|
||||
```toml
|
||||
theme = "custom"
|
||||
The read cache is designed for fast startup and offline fallback:
|
||||
|
||||
[custom_theme]
|
||||
base = "catppuccin-mocha" # defaults to "dark"
|
||||
mode = "dark" # "dark" or "light"; controls Markdown rendering
|
||||
title = "#F5C2E7"
|
||||
active_foreground = "#1E1E2E"
|
||||
active_background = "#89B4FA"
|
||||
selection_background = "#313244"
|
||||
author_palette = ["#89B4FA", "#CBA6F7", "#94E2D5", "#F9E2AF"]
|
||||
syntax_theme = "catppuccin-mocha"
|
||||
```
|
||||
- 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.
|
||||
|
||||
Every color override uses `#RRGGBB`. The complete set of roles is `title`,
|
||||
`dim`, `text`, `active_foreground`, `active_background`, `success`, `warning`,
|
||||
`error`, `editor_foreground`, `editor_background`, `pane_inactive`,
|
||||
`pane_active`, `quote`, `selection_background`,
|
||||
`suggestion_remove_background`, `suggestion_add_background`,
|
||||
`changed_remove_background`, and `changed_add_background`.
|
||||
`author_palette` accepts one or more colors. `syntax_theme` accepts an installed
|
||||
Chroma style name; invalid colors, bases, and syntax styles are reported as
|
||||
configuration errors at startup. The `[custom_theme]` table is ignored unless
|
||||
`theme = "custom"`.
|
||||
Cached data is labelled when first shown. A normal refresh does not repeatedly
|
||||
reintroduce the cached header.
|
||||
|
||||
Every command binding accepts one or more Bubble Tea key names. Omitted
|
||||
settings retain their defaults, while an explicitly configured action replaces
|
||||
its default keys. Printable keys remain text in Insert mode, reply drafts, and
|
||||
search queries; command bindings apply in the appropriate non-text context.
|
||||
The contextual `?` popup and compact screen footers use the configured keys.
|
||||
Configuration loading also checks each active context independently. A key may
|
||||
be reused on unrelated screens, but assigning it to two different actions that
|
||||
can be active together reports the context and both conflicting actions.
|
||||
Read state and recoverable drafts live beside the configuration file as
|
||||
`state.json` and `drafts.json`. 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.
|
||||
|
||||
## Experimental local AI review
|
||||
|
||||
Set `ai.enabled = true` to expose the `A` menu on the dashboard and thread
|
||||
screens. The initial provider uses the authenticated Codex CLI, so run
|
||||
`codex login` first. A full review creates clearly labelled `LOCAL AI · LOCAL
|
||||
ONLY` threads; it may also attach local-only context to unresolved GitHub
|
||||
threads. Pressing the normal reply key on a local AI thread starts a discussion
|
||||
with the same configured model. Resolving or unresolving those threads changes
|
||||
only the permission-restricted local per-PR state file. For small,
|
||||
self-contained replacements the model can include a standard GitHub-style
|
||||
suggestion in its local comment. These use the existing syntax-aware
|
||||
remove/add preview and remain local; diple does not apply or publish them.
|
||||
Enable the feature explicitly:
|
||||
|
||||
Every model run is manually confirmed. The preview shows the head commit,
|
||||
model, files, byte budget, call count, exclusions, and redaction count. Input
|
||||
comes exclusively from GitHub's authenticated PR diff and PR metadata: diple
|
||||
does not read the local checkout for AI review. Secret-like values are
|
||||
redacted, binary/generated/vendor/lock/oversized files are excluded, and the
|
||||
provider subprocess receives a small environment allowlist. Codex is launched
|
||||
ephemerally in an empty temporary directory with project instructions ignored,
|
||||
read-only sandboxing, approvals disabled, and all supported tool surfaces
|
||||
disabled. Any attempted tool event or malformed/out-of-range structured result
|
||||
fails the run closed.
|
||||
```toml
|
||||
[ai]
|
||||
enabled = true
|
||||
provider = "codex-cli"
|
||||
command = "codex"
|
||||
```
|
||||
|
||||
The AI menu distinguishes the inference-free provider status refresh from a
|
||||
provider test that makes one deliberately small structured model call. The
|
||||
test requires its own confirmation, consumes provider quota, and sends no PR
|
||||
content or local files. Preparing and running a review displays animated,
|
||||
stable progress; multi-chunk reviews report completed model calls. When the
|
||||
provider exposes a reasoning summary, diple shows a bounded, sanitized summary
|
||||
beside the progress bar. It never requests or displays hidden chain-of-thought.
|
||||
Authenticate Codex separately before opening diple:
|
||||
|
||||
PR content is untrusted and is explicitly delimited as data in the model
|
||||
prompt. Results are validated against changed paths and lines, deduplicated,
|
||||
and retained as outdated when the PR head moves. No AI result is published to
|
||||
GitHub. Publishing proposed replies and additional providers remain future
|
||||
work; a future direct API provider must require no-training and zero-data-
|
||||
retention guarantees.
|
||||
```sh
|
||||
codex login
|
||||
```
|
||||
|
||||
When cached data exists, the picker and PR details are rendered immediately
|
||||
from that snapshot while a live GitHub refresh runs in the background. Cached
|
||||
screens are labelled with their save time and are replaced automatically when
|
||||
fresh data arrives. Core PR and review data is rendered before check
|
||||
annotations and conflict-file analysis finish. A failed subsection keeps its
|
||||
last complete value, is marked partial, and does not discard the rest of a
|
||||
successful refresh. Check annotations are fetched separately only for failed
|
||||
checks and are reused by immutable check ID.
|
||||
The `A` menu can:
|
||||
|
||||
The cache uses separate JSON files for the picker and each visited PR. Cache
|
||||
content is hashed before writing: unchanged responses do not rewrite their
|
||||
files. Their modification time is touched at most once per day (or half the
|
||||
configured maximum age, when shorter) so recently validated snapshots remain
|
||||
usable without writing on every poll. Changed files are replaced atomically,
|
||||
and oldest cache entries are pruned at the configured bound. Read state and
|
||||
recoverable reply/metadata drafts use versioned, atomic files beside the
|
||||
configuration.
|
||||
- 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;
|
||||
- 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.
|
||||
|
||||
Polling adapts to GitHub's reported rate-limit budget. It backs off as the
|
||||
remaining budget gets low, honors server retry windows, and adds jitter to
|
||||
avoid synchronized clients. Opening another PR or starting another refresh
|
||||
cancels the superseded request.
|
||||
Before a review, diple shows the exact head commit, selected model, included and
|
||||
excluded files, byte count, maximum model-call count, and redaction count.
|
||||
Every run requires confirmation.
|
||||
|
||||
GitHub's public APIs report whether a PR conflicts but do not expose its
|
||||
conflicting file paths. For conflicting PRs only, `diple` performs a
|
||||
read-only `git merge-tree` analysis in a temporary bare repository. It never
|
||||
touches or inspects the current checkout, so Git, Jujutsu (`jj`), and directories
|
||||
without a local repository behave identically. The analysis fetches the exact
|
||||
remote base branch and pull-request head ref using the existing GitHub
|
||||
credential. Results are memoized by the base and head commit, and failed scans
|
||||
are retried after one minute.
|
||||
AI input comes from the authenticated GitHub PR diff and PR metadata, not from
|
||||
the local checkout. diple excludes configured sensitive, generated, vendored,
|
||||
lock, binary, and oversized files; redacts secret-like values; chunks bounded
|
||||
requests; and validates findings against lines changed in the prepared head.
|
||||
|
||||
Command-line flags override the configuration. `GH_REPO` overrides the
|
||||
configured repository when `--repo` is not provided. The corresponding flags
|
||||
include `--config`, `--theme`, `--poll`, `--fold-resolved`,
|
||||
`--thread-list-width`, `--dashboard-mode`, `--compact-reviews`,
|
||||
`--path-scroll`, and `--path-scroll-interval`, plus `--cache`,
|
||||
`--cache-max-age`, `--cache-dir`, and `--editor-mode`.
|
||||
Boolean settings can be disabled explicitly, for
|
||||
example `--compact-reviews=false`.
|
||||
The Codex process runs ephemerally in an empty temporary directory with:
|
||||
|
||||
With the default `dashboard_mode = "hotkey"`, opening a PR goes directly to its
|
||||
review threads and `d` opens the dashboard only when requested. Set
|
||||
`dashboard_mode = "intermediate"` to follow picker → dashboard → review
|
||||
threads instead.
|
||||
- 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.
|
||||
|
||||
Compact reviews aggregate submission counts by state and author. Reviews with
|
||||
a written summary retain a compact one-line body, while timestamps and commit
|
||||
SHAs are omitted. Set `compact_reviews = false` to restore the complete review
|
||||
history and metadata.
|
||||
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.
|
||||
|
||||
## Default keys
|
||||
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.
|
||||
|
||||
| Key | Action |
|
||||
| --- | --- |
|
||||
| `h` / `l` | Focus the thread list / thread detail |
|
||||
| `j` / `k` | Move between items or scroll the dashboard/focused detail |
|
||||
| `?` | Show contextual keybinding help |
|
||||
| `H` | Open application health and diagnostics |
|
||||
| `d` | Open the current pull request dashboard |
|
||||
| `e` | Edit the current PR title, target branch, and description from its dashboard |
|
||||
| `a` | Enable or disable auto-merge from the dashboard |
|
||||
| `M` | Merge now when GitHub reports that all represented requirements are satisfied |
|
||||
| `/` | Fuzzy-search paths and filter with `status:`, `author:`, `updated:true` |
|
||||
| `F` | Clear active thread filters |
|
||||
| `n` / `N` | Next / previous thread with a new update |
|
||||
| `c` | Compose a reply to the selected thread |
|
||||
| `R` | Resolve or unresolve the selected thread |
|
||||
| `ctrl-p` / `ctrl-n` | Choose the previous / next fuzzy-search or branch-completion match |
|
||||
| `g` / `G` | First / last item |
|
||||
| `enter` / `l` | Open the selected PR dashboard or its review threads |
|
||||
| `enter` | Toggle the selected review thread |
|
||||
| `za` | Toggle the selected thread |
|
||||
| `ctrl-d` / `ctrl-u` | Scroll thread detail or page through lists |
|
||||
| `tab` | Hide or reveal the thread list |
|
||||
| `b` / `esc` | Return to the previous screen |
|
||||
| `r` | Refresh now |
|
||||
| `q` | Quit |
|
||||
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.
|
||||
|
||||
The Health modal reports the interactive loop, configuration, GitHub API,
|
||||
rate-limit budget and reset/retry time, disk cache, unread-state persistence,
|
||||
draft recovery, core PR data, and secondary enrichment. Session warnings and
|
||||
errors are retained there with their component and timestamp. Long diagnostics
|
||||
wrap to the modal width. Refresh activity occupies a stable informational row
|
||||
so polling does not reorder the report. Press `H` from the picker, dashboard,
|
||||
or thread view; `b` or `esc` closes it without changing the underlying scroll
|
||||
position.
|
||||
## Shell completion
|
||||
|
||||
The reply composer appears inline beneath the selected thread so its code and
|
||||
comments remain visible while writing. It supports multiple lines: `enter`
|
||||
inserts a newline, `ctrl-s` opens the rendered confirmation preview, and `esc`
|
||||
cancels. Replies and resolution changes require an explicit `y` confirmation.
|
||||
Write keys remain disabled for cached snapshots, during refreshes, and whenever
|
||||
GitHub does not grant the corresponding capability.
|
||||
Generate completion without contacting GitHub or loading configuration:
|
||||
|
||||
Auto-merge and immediate merge actions are available from the dashboard and
|
||||
always require confirmation. The selected method is the repository's first
|
||||
available method in `squash`, `merge`, then `rebase` preference order. Both
|
||||
mutations include the currently displayed head commit OID, so a force-push or
|
||||
new commit prevents a stale merge. “Merge now” is gated for drafts, conflicts,
|
||||
required reviews, required checks, unresolved required conversations, closed
|
||||
PRs, and branches that require a merge queue; GitHub performs the final
|
||||
permission and mergeability validation.
|
||||
```sh
|
||||
# Bash, current session
|
||||
source <(diple completion bash)
|
||||
|
||||
The dashboard editor works with raw Markdown so template checklists can be
|
||||
updated directly. The active line is highlighted without inserting a
|
||||
layout-changing block character. It opens with the description focused;
|
||||
`tab` and `shift-tab` move between the description, title, and target branch.
|
||||
When the target branch is focused, repository branches are recommended using
|
||||
the typed text, likely branch names, the current/default branch, and each
|
||||
branch's latest commit time. The list updates as you type. Use `ctrl-p` and
|
||||
`ctrl-n` to select the previous or next result, then `tab` or `enter` to complete it;
|
||||
pressing `tab` again moves to the description.
|
||||
# Zsh, current session
|
||||
source <(diple completion zsh)
|
||||
|
||||
With the default `editing.mode = "vim"`, the description starts in Normal mode.
|
||||
It supports `hjkl`, `0`, `^`, `$`, `gg`, `G`, `w`/`W`, `b`/`B`, `e`/`E`,
|
||||
`f`/`F`/`t`/`T` with `;` and `,`, `i`/`a`/`I`/`A`, `o`/`O`, `s`, and
|
||||
`x`/`X`. `s` removes the character under the cursor and enters Insert mode.
|
||||
Soft-wrapped rows behave as visual editor lines for vertical and line-local
|
||||
motions, but do not add newlines to the Markdown submitted to GitHub.
|
||||
`ctrl-d` and `ctrl-u` move the cursor and viewport down or up by half a page,
|
||||
including while extending a Visual selection.
|
||||
`v` starts character-wise Visual mode and `V` starts visual-line selection;
|
||||
`d` or `x` deletes the selection, `y` copies it to the system clipboard, and
|
||||
`p` pastes from the system clipboard. Normal mode uses a block cursor, while
|
||||
Insert mode uses the terminal's hardware bar cursor at the boundary between
|
||||
characters without hiding or shifting either character.
|
||||
The description retains its raw Markdown while headings, emphasis, inline
|
||||
code, links, quote markers, and HTML comments receive syntax highlighting.
|
||||
Highlighting consists only of zero-width terminal styling and cannot alter
|
||||
wrapping, selection, clipboard contents, cursor offsets, or submitted text.
|
||||
`esc` returns from Insert to Normal mode; a second `esc` cancels the editor.
|
||||
Set `editing.mode = "standard"` for direct insertion with arrow,
|
||||
`home`, and `end` navigation. Title and target branch remain standard inputs
|
||||
in either mode. `ctrl-s` opens an explicit confirmation. If the title,
|
||||
description, or target branch changes remotely while the editor is open,
|
||||
submission is blocked rather than overwriting the newer metadata.
|
||||
# Fish, persistent user installation
|
||||
diple completion fish > ~/.config/fish/completions/diple.fish
|
||||
```
|
||||
|
||||
## Current scope
|
||||
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:
|
||||
|
||||
The application can reply to review threads, resolve or unresolve them, update
|
||||
the PR title, target branch, and description, enable or disable auto-merge, and
|
||||
merge an eligible PR immediately. Comment reactions remain read-only. Other
|
||||
write operations remain disabled. The dashboard shows the capability gate,
|
||||
including why each action is unavailable. Read state
|
||||
persists beside the configuration, and recent PR data is cached for offline
|
||||
fallback. Check contexts and annotations are paginated. GitHub features which
|
||||
depend on server-side context, such as unfurling issue references or displaying
|
||||
uploaded images, are represented textually in the terminal. See
|
||||
[`TODO.md`](TODO.md) for remaining read-only work and write-support preparation.
|
||||
```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).
|
||||
|
||||
Reference in New Issue
Block a user