Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ To install the latest release (or test against a specific version):
curl -fsSL https://raw.githubusercontent.com/jongio/grut/main/install.sh | sh

# Specific version — Linux / macOS
curl -fsSL https://raw.githubusercontent.com/jongio/grut/main/install.sh | sh -s -- v0.1.0
curl -fsSL https://raw.githubusercontent.com/jongio/grut/main/install.sh | sh -s -- v0.8.0

# Latest — Windows (PowerShell)
irm https://raw.githubusercontent.com/jongio/grut/main/install.ps1 | iex

# Specific version — Windows (PowerShell)
$v="v0.1.0"; irm https://raw.githubusercontent.com/jongio/grut/main/install.ps1 | iex
$v="v0.8.0"; irm https://raw.githubusercontent.com/jongio/grut/main/install.ps1 | iex
```

## Development Workflow
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ curl -fsSL https://raw.githubusercontent.com/jongio/grut/main/install.sh | sh
To install a specific version:

```bash
curl -fsSL https://raw.githubusercontent.com/jongio/grut/main/install.sh | sh -s -- v0.1.0
curl -fsSL https://raw.githubusercontent.com/jongio/grut/main/install.sh | sh -s -- v0.8.0
```

### PowerShell script (Windows)
Expand All @@ -130,7 +130,7 @@ irm https://raw.githubusercontent.com/jongio/grut/main/install.ps1 | iex
To install a specific version:

```powershell
$v="v0.1.0"; irm https://raw.githubusercontent.com/jongio/grut/main/install.ps1 | iex
$v="v0.8.0"; irm https://raw.githubusercontent.com/jongio/grut/main/install.ps1 | iex
```

### Go Install
Expand Down Expand Up @@ -243,6 +243,12 @@ Config file: `~/.config/grut/config.toml` (Linux/macOS) or `%APPDATA%\grut\confi

See [docs/configuration.md](docs/configuration.md) for all options.

## Stability

grut is pre-1.0, so pin a version if you depend on it in automation. See
[docs/stability.md](docs/stability.md) for what 1.0 will guarantee and what
still has to be documented before it is tagged.

## Building from Source

```bash
Expand Down
2 changes: 2 additions & 0 deletions docs/specs/ai-git-ops/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Enhance `internal/panels/branches/`: when AI enabled, stale/merged/abandoned bra

The analysis engine already exists in `internal/ai/ops/branch.go` (task 12); only the panel wiring is outstanding. `ops.Branch` is currently referenced from no non-test panel code.

**Blocked on #418.** The wiring is not panel-local. `AnalyzeBranches` lives on the concrete `*middleware.AIGitClient` rather than the `git.GitClient` interface, panels are registered with the plain client before the AI client is built (`cmd/root.go:232` vs `:283`), and the layer that converts op results into panel messages does not exist yet. The same gap blocks six other shipped ops, so the access pattern should be decided once in #418 rather than invented here.

## IN PROGRESS

(none)
Expand Down
86 changes: 86 additions & 0 deletions docs/stability.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Stability and Versioning

grut is pre-1.0. This document says what that means today, what will be
guaranteed at 1.0, and what has to be true before 1.0 is worth tagging.

## Today (0.x)

Anything can change in a minor release. In practice the CLI surface has been
additive for several releases, but nothing here is promised yet, so pin a
version if you depend on grut in automation:

```bash
curl -fsSL https://raw.githubusercontent.com/jongio/grut/main/install.sh | sh -s -- v0.8.0
```

## What 1.0 will cover

At 1.0 the following become part of the compatibility surface. Breaking any of
them requires a major version bump.

### Command and flag names
The subcommands (`clean`, `completion`, `config`, `doctor`, `ext`, `keys`,
`mcp`, `report`, `run`, `status`, `theme`, `update`, `version`) and their
flags. Flags may be added; existing ones keep their meaning.

### Machine-readable output
Ten commands emit structured output behind `--json`, fourteen flags in total
once subcommands are counted. Once 1.0 lands, the shape of that output is a
contract: fields may be added, but existing fields will not be removed,
renamed, or change type.

### Exit codes
`--check` on `clean`, `doctor`, and `status` is an exit-code gate intended for
CI. Zero means the checked condition holds, non-zero means it does not. Scripts
depending on that distinction will keep working.

### Configuration keys
The TOML keys documented in [configuration.md](configuration.md). Keys may be
added. Removing or repurposing one is breaking.

Unknown keys are ignored rather than rejected, so a config written for a newer
grut still loads on an older one, minus the unrecognized settings.

### Extension API
The `extension.toml` manifest schema, the permission model, and the Lua and
WASM host functions in [extensions.md](extensions.md). Third-party extensions
are the surface most expensive to break, since the author is not us.

### Default keybindings
Default bindings will not be reassigned to different actions in a minor
release. Adding a binding to a previously unbound key is not breaking.

## What 1.0 will not cover

- **Go packages under `internal/`.** Go forbids importing these from outside
the module, so they are not an API. They can be restructured at any time.
- **TUI rendering.** Panel layout, colours, spacing, and glyphs are
presentation, not contract. Themes exist for callers who care.
- **Log and audit line formats**, unless a specific format is documented as
machine-readable.
- **Prerelease and dev builds.**

## Before tagging 1.0

Freezing a surface is only meaningful if the surface is written down. Current
gaps:

- [ ] **Document every `--json` shape.** Two of the ten commands are documented
today ([report-json.md](report-json.md),
[version-json.md](version-json.md)). The rest are contracts by accident
rather than by description.
- [ ] **Document the `--check` exit codes**, including what non-zero means for
each command.
- [ ] **Audit config keys for dead settings.** A key that is declared but
unread becomes a permanent obligation at 1.0. `socket_auth` was one of
these and has been removed; the rest of the schema deserves the same
pass.
- [ ] **Version the extension manifest.** Third-party extensions need a way to
declare which schema they target.
- [ ] **State the supported platform and Go version floor.**

## Deprecation

After 1.0, anything on the covered surface that is going away gets deprecated
before removal: it keeps working for at least one minor release, warns when
used, and the release notes name the replacement.
35 changes: 29 additions & 6 deletions internal/git/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,33 @@
// OpQueue to prevent concurrent writes from corrupting repository state.
// Read operations run concurrently against the same queue.
//
// TODO(arch): This package has grown to 27+ files spanning 15+ distinct
// domains (blame, bisect, branch, diff, difftree, log, merge, queue, reflog,
// remote, reset, revert, stage_patch, stash, tag, undo, url, worktree).
// A future refactor should split it into sub-packages (e.g. git/branch,
// git/stash, git/log) to restore single-responsibility at the package level.
// See https://github.com/jongio/grut/issues/167 for context.
// On the file count: this package spans many domains (blame, bisect, branch,
// diff, difftree, log, merge, queue, reflog, remote, reset, revert,
// stage_patch, stash, tag, undo, url, worktree), and an automated review
// (issue #167) flagged that as a god package to be split into sub-packages.
// It is deliberately not split, for three reasons.
//
// First, Go does not permit it directly. Every domain file holds methods on
// *Client, and methods cannot be declared on a type owned by another package.
// Splitting would mean either fragmenting Client into per-domain clients,
// which destroys the single GitClient interface that the AI middleware
// implements and every panel consumes, or demoting the methods to free
// functions, which changes every call site and leaves the sub-packages
// importing git for the Client type anyway.
//
// Second, the shared state is the point. Client carries one OpQueue and one
// Cache. Serialisation and caching are correctness properties that hold
// across domains: a branch operation and a stash operation must not race.
// Per-domain packages would each need a reference back to that shared state,
// so the coupling would move rather than disappear.
//
// Third, the cost is not being paid. The package is roughly 4,000 lines
// across 30 files, averaging under 140 lines each, already separated by
// domain and named for it. Navigation happens by file, and the file layout is
// exactly the split the review asked for.
//
// The signal worth watching is file size rather than file count. If a single
// domain file outgrows ~500 lines, split that file. If a domain grows genuine
// state of its own, independent of the queue and cache, that is the point to
// reconsider a sub-package for it.
package git
Loading