Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/doc-minion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:

- name: Install minions
run: |
go install github.com/partio-io/minions/cmd/minions@v0.0.1
go install github.com/partio-io/minions/cmd/minions@v0.0.3
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Run doc-update program
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/minion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:

- name: Install minions
run: |
go install github.com/partio-io/minions/cmd/minions@v0.0.1
go install github.com/partio-io/minions/cmd/minions@v0.0.3
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Run program
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/plan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:

- name: Install minions
run: |
go install github.com/partio-io/minions/cmd/minions@v0.0.1
go install github.com/partio-io/minions/cmd/minions@v0.0.3
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Determine program
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/propose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:

- name: Install minions
run: |
go install github.com/partio-io/minions/cmd/minions@v0.0.1
go install github.com/partio-io/minions/cmd/minions@v0.0.3
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Run propose program
Expand Down
53 changes: 53 additions & 0 deletions .minions/programs/add-partio-configure-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
id: add-partio-configure-command
target_repos:
- cli
acceptance_criteria:
- "`partio configure` command exists and is registered in the root command"
- "`partio configure --agent <name>` updates the `agent` field in `.partio/settings.json`"
- "`partio configure --strategy <name>` updates the `strategy` field in `.partio/settings.json`"
- Running `partio configure` without flags prints the current configuration (same as `partio status` config section, or a brief config dump)
- The command returns a clear error if run outside a git repository or before `partio enable`
- Existing `enable` and `disable` commands are unchanged
- Table-driven tests cover flag parsing and settings file update
pr_labels:
- minion
---

# Add `partio configure` command

## Source

Inspired by entireio/cli#851 (`entire configure` to remove agent / manage agents).

## Problem

Once a user has run `partio enable`, changing their agent or strategy requires:
```
partio disable && partio enable
```

There is no dedicated command for updating configuration after initial setup. This is a rough experience for users who want to switch from the default `claude-code` agent or change their strategy without reinstalling hooks.

## Desired behavior

Add a `partio configure` command with flags to update individual settings in `.partio/settings.json`:

```
partio configure --agent <agent-name>
partio configure --strategy <strategy-name>
partio configure # prints current config
```

The command should:
1. Verify partio is enabled (`.partio/` directory exists)
2. Load the current repo-level config from `.partio/settings.json`
3. Apply any flag overrides
4. Write the updated config back to `.partio/settings.json`
5. Print a confirmation of what changed

## Files to create/modify

- `cmd/partio/configure.go` — new file implementing the `configure` subcommand
- `cmd/partio/main.go` — register `newConfigureCmd()` on the root command
- `internal/config/config.go` — ensure there is a `Save(path string)` method or equivalent for writing back to JSON (add if missing)
41 changes: 41 additions & 0 deletions .minions/programs/checkpoint-push-auth-env-token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
id: checkpoint-push-auth-env-token
target_repos:
- cli
acceptance_criteria:
- When `PARTIO_CHECKPOINT_TOKEN` is set and the checkpoint remote uses HTTPS, git push/fetch operations for the checkpoint branch inject the token via `GIT_CONFIG_COUNT`/`GIT_CONFIG_KEY_*`/`GIT_CONFIG_VALUE_*` env vars (not CLI args) to avoid leaking it in /proc/cmdline
- Token is encoded as Basic auth (`x-access-token:<token>` base64) matching GitHub's Git HTTP protocol requirement
- SSH remotes emit a warning that the token is ignored (SSH handles auth separately)
- A unit test verifies the correct header format is injected for HTTPS remotes
- A unit test verifies no header is injected for SSH remotes
pr_labels:
- minion
---

# Support `PARTIO_CHECKPOINT_TOKEN` for checkpoint branch push/fetch authentication

## Description

Add support for a `PARTIO_CHECKPOINT_TOKEN` environment variable that, when set, is injected into the git push/fetch operations Partio uses for the checkpoint branch. This allows users and CI environments to authenticate checkpoint operations against HTTPS remotes (e.g., a private GitHub repository used as a checkpoint store) without needing to configure git credentials globally.

The token should be passed via the `GIT_CONFIG_COUNT` / `GIT_CONFIG_KEY_*` / `GIT_CONFIG_VALUE_*` environment variable pattern rather than as CLI arguments, to avoid the token appearing in process listings (`/proc/cmdline`). For GitHub HTTPS remotes, encode the token as Basic auth with `x-access-token:<token>` base64-encoded in the `Authorization` header (GitHub's Git HTTP protocol requires Basic, not Bearer).

SSH remotes do not use this mechanism; if the remote URL is SSH and the env var is set, log a warning that the token is unused.

## Why

Users pushing checkpoints to a separate private repository (via `checkpoint_remote` config) in CI environments have no clean way to authenticate those git operations without setting up global git credential helpers. A dedicated env var with secure injection matches how CI systems manage secrets and avoids credential leakage.

## User Relevance

CI users and teams using a centralized checkpoint repository can authenticate checkpoint push/fetch with a single environment variable, without touching global git config or exposing tokens in process arguments.

## Source

Inspired by entireio/cli#818 and entireio/cli#827

## Context Hints

- `internal/git/` — git operations including push/fetch for checkpoint branch
- `internal/hooks/` — pre-push hook that triggers checkpoint push
- `internal/config/` — environment variable handling
36 changes: 36 additions & 0 deletions .minions/programs/checkpoints-v2-compact-transcript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
id: checkpoints-v2-compact-transcript
target_repos:
- cli
acceptance_criteria:
- "When checkpoints_v2 feature flag is enabled, a compact transcript.jsonl is written to a v2 ref layout alongside the full session JSONL"
- "The compact transcript contains normalized, per-turn entries (user prompt + assistant response) instead of raw JSONL events"
- "The v2 ref layout uses a stable path structure (e.g. refs/partio/checkpoints/v2/main)"
- "When checkpoints_v2 is disabled (default), no v2 refs are written — existing behavior is unchanged"
- "make test passes"
- "make lint passes"
pr_labels:
- minion
---

# Checkpoints v2: write compact transcript.jsonl alongside full session data

## Description

Partio currently stores full JSONL session data in git objects on the checkpoint branch. For large sessions this means fetching/reading the full event stream to get a summary view. A compact `transcript.jsonl` containing only normalized turn-level entries (user prompt + assistant response, stripped of internal tool calls) would make session browsing faster and reduce storage cost for downstream consumers.

This is the approach taken in entireio/cli (changelog 0.5.2, PRs #828, #788, #781).

## What to implement

1. Add a `checkpoints_v2` boolean field to the `Config` type (default: false) as a feature flag.
2. When the flag is enabled, after writing the full checkpoint blob, also write a compact `transcript.jsonl` to a v2 ref path (e.g. `refs/partio/checkpoints/v2/<repo-id>`).
3. The compact transcript format: one JSON object per turn, each with `{"role": "user"|"assistant", "ts": "...", "content": "..."}`. Strip raw tool-call events and internal events; keep only conversation-level content.
4. The v2 ref write must use the same git plumbing approach (hash-object, mktree, commit-tree, update-ref) as the existing checkpoint storage.
5. Add a unit test for the compact transcript generation from a sample JSONL session.

## Context hints

- `internal/checkpoint/` — checkpoint domain type and git plumbing storage
- `internal/agent/claude/` — JSONL parsing utilities
- `internal/config/` — Config type, layered config loading
37 changes: 37 additions & 0 deletions .minions/programs/claude-worktree-session-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
id: claude-worktree-session-path
target_repos:
- cli
pr_labels:
- minion
acceptance_criteria:
- When Claude Code is launched with `--worktree` (creating worktrees under `.claude/worktrees/<branch>/`), `partio rewind` correctly finds and restores the session
- `partio doctor` correctly identifies the Claude session directory when `--worktree` was used
- `find_session_dir.go` handles the case where the Claude project directory key is the main repo root, not the worktree path
- Existing worktree tests still pass
- A new table-driven test covers session discovery for the `--worktree` case
---

# Fix Session Discovery for Claude Code `--worktree` Sessions

## Description

Claude Code has a `--worktree` flag that creates its own git worktrees under `.claude/worktrees/<branch>/`. When this flag is used, Claude Code keys the session directory to the **main repo path** (e.g. `/home/user/myrepo`) rather than to the worktree path (`.claude/worktrees/feat-x/`). This causes Partio's session discovery to look in the wrong place, breaking `partio rewind` and the post-commit hook's session linking.

This mirrors the fix in [entireio/cli#817](https://github.com/entireio/cli/pull/817).

### Root cause

`find_session_dir.go` walks up from the worktree root to find the Claude session directory. But when Claude Code's `--worktree` creates sub-worktrees under `.claude/worktrees/`, the session is stored under a path derived from the **main repo root**, not the git worktree root. The walk-up logic doesn't account for this indirection.

### What to fix

In `internal/agent/claude/find_session_dir.go`:

1. Detect if the current working directory is inside a `.claude/worktrees/<branch>/` path (i.e. a Claude-managed worktree).
2. If so, resolve the **main repo root** (i.e. the directory above `.claude/`) and use that as the Claude project key for session directory lookup.
3. Add a table-driven test case that creates a temp directory structure mimicking `.claude/worktrees/<branch>/` and verifies `FindSessionDir` returns the correct session path.

### Why

Users who invoke Claude Code with `--worktree` (a common pattern for parallel Claude sessions on different branches) get no checkpoints because Partio can't find the session. This is a silent failure — hooks run but nothing is linked.
42 changes: 42 additions & 0 deletions .minions/programs/codex-agent-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
id: codex-agent-support
target_repos:
- cli
acceptance_criteria:
- "A new Detector implementation exists in `internal/agent/codex/` that satisfies the `agent.Detector` interface"
- "The detector identifies running Codex CLI processes via process inspection"
- "Session JSONL/transcript parsing handles the Codex transcript format"
- "Integration is registered alongside the existing Claude Code detector"
- "Unit tests cover process detection and transcript parsing"
pr_labels:
- minion
---

# Add Codex CLI agent integration

Add support for capturing sessions from OpenAI's Codex CLI agent, similar to the existing Claude Code integration.

## Source

entireio/cli#772 (changelog 0.5.2)

## Description

Partio currently only supports Claude Code as an AI agent. Codex CLI (OpenAI's coding agent) is gaining adoption and users running Codex sessions are not getting their sessions captured in checkpoints.

Implement a `Detector` for Codex CLI in `internal/agent/codex/` following the same pattern as `internal/agent/claude/`:

1. **Process detection**: Identify running Codex CLI processes by executable name and working directory.
2. **Transcript parsing**: Parse Codex session transcripts (JSONL format) to extract prompt, context, and tool call history.
3. **Session discovery**: Find the current Codex session directory for the working repository.
4. **Registration**: Wire the new detector into the agent detection chain in `internal/agent/`.

The detector should implement the `agent.Detector` interface defined in `internal/agent/detector.go`. Follow the file-per-concern convention: `detect.go`, `find_session_dir.go`, `find_latest_session.go`, `parse_jsonl.go`.

## Why

Partio's core value proposition is agent-agnostic: it captures the *why* behind AI-assisted code changes regardless of which agent is used. Supporting only Claude Code limits adoption and leaves Codex users without session capture entirely.

## User Relevance

Developers using Codex CLI can have their sessions automatically captured in checkpoints, giving them the same traceability and context preservation that Claude Code users already enjoy — without any manual intervention.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
id: detect-claude-code-nonstandard-ide-environments
target_repos:
- cli
acceptance_criteria:
- "process.go detects Claude Code when launched as a subprocess of a known IDE process (e.g. IntelliJ, VS Code) rather than only when launched directly from a terminal"
- "`partio status` correctly shows Claude Code as active when it was launched via an IDE plugin"
- "detection does not produce false positives when the IDE is running without Claude Code"
- "unit test covers the case where the claude process is a child of a non-terminal parent"
- "fallback behaviour is unchanged: if detection is ambiguous, partio still proceeds without blocking the commit"
pr_labels:
- minion
---

# Detect Claude Code sessions launched from non-standard IDE environments

## Problem

Partio's Claude Code detection (`internal/agent/claude/process.go`) finds running Claude Code processes by scanning the process list. When Claude Code is launched via an IDE plugin (e.g. Cursor plugin inside IntelliJ IDEA, VS Code extension), the process may appear with a different parent hierarchy or execution context than when launched from a terminal. This causes Partio to miss the running session and produce no checkpoint for those commits.

The user's workflow is unchanged — they are still using Claude Code to write code — but Partio silently fails to capture their session.

## What to implement

Extend `internal/agent/claude/process.go` to detect Claude Code in non-terminal launch environments:

1. When the direct process scan doesn't find a Claude Code process, walk the process tree upward from the current process to look for a Claude Code ancestor or sibling (covering IDE plugin scenarios where the agent is a child of the IDE process).

2. Alternatively, check for the presence of an active Claude Code session directory (`.claude/projects/`) as a secondary signal when process detection returns no result. If a session file was modified recently (e.g. within the last 10 minutes), treat it as a running session.

The second approach (session directory recency check) is simpler and more portable across OS/IDE combinations. It avoids complex process-tree traversal and is resilient to the specific launch mechanism.

Keep the change within `process.go` or a new `find_active_session.go` file. The `Detector` interface in `internal/agent/detector.go` does not need to change.

## Inspiration

- `entireio/cli` issue #844 — Entire CLI does not capture sessions when using IntelliJ IDEA with Cursor plugin on macOS

<!-- program: .minions/programs/detect-claude-code-nonstandard-ide-environments.md -->
41 changes: 41 additions & 0 deletions .minions/programs/diagnostic-logging-checkpoint-failures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
id: diagnostic-logging-checkpoint-failures
target_repos:
- cli
acceptance_criteria:
- "When `stagedFilesOverlapWithContent` returns false, the actual staged file paths and the session content paths are both logged at debug level"
- "When a checkpoint trailer is not added to a commit, a warning is logged that includes the commit hash and the reason"
- "When `PARTIO_LOG_LEVEL=debug` is set, users can see exactly which file paths were compared during overlap detection"
- "No new dependencies are introduced — use the existing `log` package"
- "Existing tests continue to pass"
pr_labels:
- minion
---

# Add diagnostic logging for checkpoint linking failures

When Partio hooks run successfully but no `Partio-Checkpoint` trailer appears on commits, there is currently no way to diagnose why. Add structured debug logging at the overlap detection step so users can self-diagnose path mismatch issues.

## Source

entireio/cli PR #785 (changelog 0.5.2), issue #768

## Description

The most common silent failure mode in Partio is: hooks run, no error is reported, but commits never receive a `Partio-Checkpoint` trailer. This happens when `stagedFilesOverlapWithContent` returns false — typically because file paths don't match between what git staged and what the session recorded.

Add diagnostic logging in the post-commit hook path:

1. **In `internal/hooks/` post-commit logic**: when the overlap check fails, log at `slog.LevelDebug` the full list of staged file paths and the full list of session content file paths. This lets users running `PARTIO_LOG_LEVEL=debug` immediately see the mismatch.

2. **Warn on no-trailer commit**: if the post-commit hook finishes without amending the commit with a trailer, emit a `slog.LevelWarn` message including the commit hash and the specific reason (no active session, overlap check failed, no checkpoint created, etc.).

Use the existing `internal/log` package — no new dependencies.

## Why

Issues like #768 and the entireio/cli equivalent show this is the most common support request: "hooks are installed and running, but nothing is being captured." Right now there is no way to self-diagnose without reading source code. A single debug log line would make this immediately actionable.

## User Relevance

Users can run `PARTIO_LOG_LEVEL=debug git commit -m "..."` to see exactly why a checkpoint wasn't created, dramatically reducing the time to resolve configuration or path-mismatch issues.
37 changes: 37 additions & 0 deletions .minions/programs/fail-closed-pre-commit-content-detection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
id: fail-closed-pre-commit-content-detection
target_repos:
- cli
acceptance_criteria:
- When session content detection errors in the pre-commit hook, the checkpoint trailer is NOT added to the commit
- The error is logged at warn level with enough context to diagnose the root cause
- A regression test covers the corrupt/stale session scenario in the pre-commit hook
- Existing behavior for healthy sessions is unchanged
pr_labels:
- minion
---

# Fail closed on pre-commit content detection errors

## Description

Partio's pre-commit hook currently fails open when checking whether a session has new content: if `sessionHasNewContent` (or equivalent) returns an error, the hook still marks the commit as linked to the session. This means a stale, corrupt, or unresolvable session can cause the commit to receive the checkpoint trailer even though post-commit cannot create a valid checkpoint. The user ends up with a commit that appears to be linked to a session but has no actual checkpoint data.

Fix this by making content detection fail closed: if checking a session produces an error, log a warning and skip that session instead of treating it as linked.

## Why

A fail-open error path creates ghost checkpoints — commits that look linked but contain no data. These are confusing and erode user trust. The fix makes the system conservative: only link a commit when we are confident there is real session content to attach.

## User Relevance

Users won't encounter mysteriously empty checkpoint pages after commits that happened near session corruption, network issues, or leftover state files. The hook becomes more predictable: a commit either has a valid checkpoint or it doesn't.

## Source

Inspired by entireio/cli#826 (changelog 0.5.2)

## Context Hints

- `internal/hooks/` — pre-commit hook implementation
- `internal/session/` — session state and content detection logic
Loading