diff --git a/.github/workflows/doc-minion.yml b/.github/workflows/doc-minion.yml index 666421d..bb5238a 100644 --- a/.github/workflows/doc-minion.yml +++ b/.github/workflows/doc-minion.yml @@ -19,23 +19,20 @@ permissions: jobs: update-docs: - runs-on: ubuntu-latest + runs-on: github-runner-partio-minion-ai-01 timeout-minutes: 15 steps: - uses: actions/checkout@v4 - - name: Install Claude Code - run: npm install -g @anthropic-ai/claude-code - name: Install minions run: | - go install github.com/partio-io/minions/cmd/minions@v0.0.3 + go install github.com/partio-io/minions/cmd/minions@v0.0.5 echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - name: Run doc-update program env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} GH_TOKEN: ${{ secrets.GH_PAT }} run: | ARGS="run .minions/programs/doc-update.md" diff --git a/.github/workflows/minion.yml b/.github/workflows/minion.yml index bba9317..1eb52dd 100644 --- a/.github/workflows/minion.yml +++ b/.github/workflows/minion.yml @@ -30,7 +30,7 @@ jobs: github.event_name == 'workflow_dispatch' || (github.event_name == 'issues' && (github.event.label.name == 'minion-ready' || github.event.label.name == 'minion-approved')) || (github.event_name == 'issue_comment' && contains(github.event.comment.body, '/minion build')) - runs-on: ubuntu-latest + runs-on: github-runner-partio-minion-ai-01 timeout-minutes: 30 steps: @@ -52,17 +52,14 @@ jobs: echo "issue_num=${ISSUE_NUM}" >> "$GITHUB_OUTPUT" fi - - name: Install Claude Code - run: npm install -g @anthropic-ai/claude-code - name: Install minions run: | - go install github.com/partio-io/minions/cmd/minions@v0.0.3 + go install github.com/partio-io/minions/cmd/minions@v0.0.5 echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - name: Run program env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} GH_TOKEN: ${{ secrets.GH_PAT }} run: | ARGS="run ${{ steps.program.outputs.path }}" diff --git a/.github/workflows/plan.yml b/.github/workflows/plan.yml index ab197bd..39059e7 100644 --- a/.github/workflows/plan.yml +++ b/.github/workflows/plan.yml @@ -19,18 +19,16 @@ jobs: if: > github.event_name == 'workflow_dispatch' || (github.event_name == 'issues' && github.event.label.name == 'minion-planning') - runs-on: ubuntu-latest + runs-on: github-runner-partio-minion-ai-01 timeout-minutes: 15 steps: - uses: actions/checkout@v4 - - name: Install Claude Code - run: npm install -g @anthropic-ai/claude-code - name: Install minions run: | - go install github.com/partio-io/minions/cmd/minions@v0.0.3 + go install github.com/partio-io/minions/cmd/minions@v0.0.5 echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - name: Determine program @@ -53,6 +51,5 @@ jobs: - name: Run program with planner env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} GH_TOKEN: ${{ secrets.GH_PAT }} run: minions run ${{ steps.program.outputs.path }} --dry-run diff --git a/.github/workflows/propose.yml b/.github/workflows/propose.yml index 35c7262..a5b8d3c 100644 --- a/.github/workflows/propose.yml +++ b/.github/workflows/propose.yml @@ -17,23 +17,20 @@ permissions: jobs: propose: - runs-on: ubuntu-latest + runs-on: github-runner-partio-minion-ai-01 timeout-minutes: 15 steps: - uses: actions/checkout@v4 - - name: Install Claude Code - run: npm install -g @anthropic-ai/claude-code - name: Install minions run: | - go install github.com/partio-io/minions/cmd/minions@v0.0.3 + go install github.com/partio-io/minions/cmd/minions@v0.0.5 echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - name: Run propose program env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} GH_TOKEN: ${{ secrets.GH_PAT }} run: | ARGS="run .minions/programs/propose.md" diff --git a/.minions/programs/auto-upgrade-stale-hooks.md b/.minions/programs/auto-upgrade-stale-hooks.md new file mode 100644 index 0000000..1d3ac1e --- /dev/null +++ b/.minions/programs/auto-upgrade-stale-hooks.md @@ -0,0 +1,44 @@ +--- +id: auto-upgrade-stale-hooks +target_repos: + - cli +acceptance_criteria: + - "`partio enable` compares installed hook content against expected content and updates hooks that differ" + - "Hooks that already match expected content are left untouched (no unnecessary writes)" + - "Backup chain is preserved — existing `.partio-backup` files are not overwritten during upgrade" + - "A message is printed when hooks are upgraded (e.g., 'Updated pre-commit hook')" + - "The `.partio/` directory existence check no longer short-circuits the entire enable flow" + - "Table-driven tests cover: fresh install, stale hook upgrade, already-current hook skip, and backup preservation" +pr_labels: + - minion +--- + +# Auto-upgrade stale hooks on `partio enable` + +## Problem + +When a user upgrades the Partio CLI binary, the git hook scripts installed in their repositories become stale — they may reference old binary paths, use outdated shim logic, or miss new hooks added in later versions. Currently, `partio enable` short-circuits entirely when `.partio/` exists (`cmd/partio/enable.go:38-42`), telling the user "partio is already enabled" without checking whether the installed hooks are up to date. + +The only workaround is `partio disable && partio enable`, which users must know to do and which unnecessarily tears down and rebuilds state. + +## Desired behavior + +`partio enable` should detect stale hooks and silently upgrade them: + +1. If `.partio/` exists, skip directory/config creation but still check hooks. +2. For each expected hook (`pre-commit`, `post-commit`, `pre-push`), read the installed script from the hooks directory (`git rev-parse --git-common-dir`). +3. Compare the installed content against the expected content from `hookScript()` / `hookScriptAbsolute()` (`internal/git/hooks/hooks.go`). +4. If the content differs, overwrite the hook file (preserving the existing backup chain — do not re-backup a partio-managed hook). +5. If a hook is missing entirely (e.g., a new hook type added in a later version), install it following the normal backup logic. +6. Print a summary of what was upgraded, or "partio is already enabled and hooks are up to date" if nothing changed. + +## Context hints + +- `cmd/partio/enable.go` — the `.partio/` existence check that needs to be relaxed +- `internal/git/hooks/install.go` — `installHooks()` needs an upgrade-aware code path +- `internal/git/hooks/hooks.go` — `hookScript()` / `hookScriptAbsolute()` generate expected content +- `internal/git/hooks/uninstall.go` — backup restoration logic to preserve during upgrades + +## Source + +Inspired by entireio/cli PR #775 — OpenCode plugin hook rewrite when content differs. diff --git a/.minions/programs/checkpoint-v2-migration-command.md b/.minions/programs/checkpoint-v2-migration-command.md new file mode 100644 index 0000000..75512cb --- /dev/null +++ b/.minions/programs/checkpoint-v2-migration-command.md @@ -0,0 +1,46 @@ +--- +id: checkpoint-v2-migration-command +target_repos: + - cli +acceptance_criteria: + - "`partio migrate --checkpoints v2` converts existing v1 checkpoint data to v2 format" + - "Migration reads all commits from `partio/checkpoints/v1` and writes compact `transcript.jsonl` + metadata to the v2 ref layout" + - "Migration is idempotent — running it twice does not duplicate or corrupt data" + - "Progress output shows how many checkpoints were migrated" + - "Dry-run flag (`--dry-run`) previews what would be migrated without writing" + - "make test passes" + - "make lint passes" +pr_labels: + - minion +--- + +# Add `partio migrate` command for checkpoint format upgrades + +Add a `partio migrate --checkpoints v2` CLI command that migrates existing checkpoint data from the v1 orphan branch format to the v2 compact format. + +## Context + +Partio currently stores checkpoints on `partio/checkpoints/v1` using git plumbing commands. A v2 format with compact `transcript.jsonl` and metadata on a `/main` ref layout would reduce storage overhead and improve query performance. Before v2 can become the default, users need a migration path for existing checkpoint data. + +## What to implement + +1. A new `partio migrate` Cobra command under `cmd/partio/` +2. A `--checkpoints` flag accepting `v2` as the target format +3. A `--dry-run` flag that shows what would be migrated without writing +4. Migration logic that: + - Reads checkpoint commits from the v1 branch + - Extracts session data and transcript content + - Writes compact transcript.jsonl files and metadata to the v2 ref layout + - Preserves all existing checkpoint metadata (session IDs, attribution, timestamps) +5. Progress output showing migration status + +## Agents + +### implement + +```capabilities +max_turns: 100 +checks: true +retry_on_fail: true +retry_max_turns: 20 +``` diff --git a/.minions/programs/configurable-checkpoint-path-filter.md b/.minions/programs/configurable-checkpoint-path-filter.md new file mode 100644 index 0000000..81ef4ba --- /dev/null +++ b/.minions/programs/configurable-checkpoint-path-filter.md @@ -0,0 +1,53 @@ +--- +id: configurable-checkpoint-path-filter +target_repos: + - cli +acceptance_criteria: + - "Users can configure `checkpoint_path_filter` in `.partio/settings.json` with include and exclude glob patterns" + - "Excluded paths are omitted from checkpoint transcript and prompt data" + - "Include patterns (when specified) restrict checkpoints to only matching paths" + - "Default behavior (no filter configured) captures all paths as before" + - "Filters apply during post-commit checkpoint creation" + - "make test passes" + - "make lint passes" +pr_labels: + - minion +--- + +# Add configurable path filtering for checkpoint content + +Allow users to configure which file paths are included or excluded from checkpoint data via glob patterns in Partio settings. + +## Context + +Checkpoint data currently captures all files touched during a session. In large monorepos or repos with generated files, build artifacts, or sensitive directories, users may want to exclude certain paths from checkpoint transcripts and metadata. This is distinct from secret redaction — it controls which file paths appear in checkpoint data at all. + +## What to implement + +1. Add `checkpoint_path_filter` to the config schema with `include` and `exclude` glob arrays +2. Apply path filtering in the post-commit checkpoint creation flow when determining which files to include +3. Exclude patterns take precedence over include patterns when both match +4. Support standard glob syntax (e.g., `vendor/**`, `*.generated.go`, `build/`) +5. Add config validation in `partio doctor` to warn about invalid glob patterns + +## Example config + +```json +{ + "checkpoint_path_filter": { + "exclude": ["vendor/**", "node_modules/**", "*.generated.go"], + "include": ["src/**", "internal/**"] + } +} +``` + +## Agents + +### implement + +```capabilities +max_turns: 100 +checks: true +retry_on_fail: true +retry_max_turns: 20 +``` diff --git a/.minions/programs/deprecate-reset-in-favor-of-rewind.md b/.minions/programs/deprecate-reset-in-favor-of-rewind.md new file mode 100644 index 0000000..0bc844d --- /dev/null +++ b/.minions/programs/deprecate-reset-in-favor-of-rewind.md @@ -0,0 +1,41 @@ +--- +id: deprecate-reset-in-favor-of-rewind +target_repos: + - cli +acceptance_criteria: + - "`partio reset` prints a deprecation warning to stderr before executing: `Warning: 'partio reset' is deprecated and will be removed in a future release. Use 'partio rewind' instead.`" + - "The command still functions after the warning so existing scripts are not broken" + - "`partio reset` is hidden from the default help output (marked as deprecated in cobra)" + - "The deprecation warning is tested in `cmd/partio/reset_test.go`" +pr_labels: + - minion +--- + +# Deprecate `partio reset` in favor of `partio rewind` + +## Source + +entireio/cli changelog 0.5.3: "Deprecated `entire reset` command in favor of `entire rewind`" + +## Problem + +`partio reset` is a destructive command that deletes and recreates the entire checkpoint branch, wiping all stored checkpoint data. `partio rewind` is the safer alternative — it lists checkpoints and restores to a specific one without discarding history. Having both commands creates confusion about which to use, and `reset` is easy to run accidentally with severe consequences. + +## Proposed Change + +Mark `partio reset` as deprecated in Cobra so it: + +1. Is hidden from `partio --help` output (users discover it only if they explicitly run it or know about it) +2. Prints a deprecation warning to stderr when invoked: `Warning: 'partio reset' is deprecated and will be removed in a future release. Use 'partio rewind' instead.` +3. Still executes its current logic so existing scripts continue to work during the transition period + +The implementation touches only `cmd/partio/reset.go`. Cobra supports `Deprecated` field on commands which automatically prints the warning and hides from help. + +## Why This Matters + +Surfacing the deprecation now sets expectations before `reset` is eventually removed. Users who discover `reset` (e.g. from old blog posts or AI suggestions) get a clear redirect to `rewind`, reducing the risk of accidental checkpoint data loss. + +## Context + +- `cmd/partio/reset.go` — current reset implementation +- `cmd/partio/rewind.go` — the preferred replacement command diff --git a/.minions/programs/fix-rewind-checkpoint-not-fetched.md b/.minions/programs/fix-rewind-checkpoint-not-fetched.md new file mode 100644 index 0000000..f30ca64 --- /dev/null +++ b/.minions/programs/fix-rewind-checkpoint-not-fetched.md @@ -0,0 +1,40 @@ +--- +id: fix-rewind-checkpoint-not-fetched +target_repos: + - cli +acceptance_criteria: + - "`partio rewind --list` shows a helpful fetch suggestion when the checkpoint branch exists on the remote but is not fetched locally" + - "When neither local nor remote has the branch, the original 'no checkpoint branch found' error is shown" + - "The fetch hint includes the exact git command to run" + - "make test passes" + - "make lint passes" +pr_labels: + - minion +--- + +# Fix `partio rewind` when checkpoint branch isn't fetched locally + +`partio rewind --list` returns `"no checkpoint branch found"` when `partio/checkpoints/v1` doesn't exist locally. If the user is working in a cloned repo or on a new machine where checkpoints were pushed from elsewhere, the branch may exist on the remote but not be fetched. The current error message is confusing because it implies checkpoints don't exist at all. + +## Fix + +In `runRewindList()` (`cmd/partio/rewind.go`), when `git rev-parse --verify partio/checkpoints/v1` fails: + +1. Check if the branch exists on the remote: + ``` + git ls-remote --heads origin partio/checkpoints/v1 + ``` +2. If the remote has the branch, print a helpful message instead of the generic error: + ``` + Checkpoint branch not fetched locally. + Run: git fetch origin partio/checkpoints/v1:partio/checkpoints/v1 + ``` +3. If neither local nor remote has the branch, keep the current error. + +Also apply the same check in `runRewindTo()` for consistency. + +## Key files + +- `cmd/partio/rewind.go` — `runRewindList()` at line ~50 and `runRewindTo()` at line ~94 + +**Inspired by:** entireio/cli changelog v0.5.3 — "Resume failing when checkpoints aren't fetched locally yet" diff --git a/.minions/programs/guard-post-commit-rebase-reentry.md b/.minions/programs/guard-post-commit-rebase-reentry.md new file mode 100644 index 0000000..37baf64 --- /dev/null +++ b/.minions/programs/guard-post-commit-rebase-reentry.md @@ -0,0 +1,45 @@ +--- +id: guard-post-commit-rebase-reentry +target_repos: + - cli +acceptance_criteria: + - "Post-commit hook detects an in-progress interactive rebase (presence of `.git/rebase-merge/` or `.git/rebase-apply/`) and exits 0 immediately without creating a checkpoint" + - "A debug-level log message is emitted when the rebase guard triggers: 'skipping checkpoint creation: interactive rebase in progress'" + - "Normal commits (no rebase) are unaffected" + - "The guard does not prevent Partio from operating on commits made *after* the rebase completes" + - "Unit test covers the rebase-detection logic with a fake git dir structure" +pr_labels: + - minion +--- + +# Guard post-commit hook against spurious checkpoints during interactive rebase + +## What + +During `git rebase -i`, git replays each selected commit and fires the post-commit hook for each one. Partio's post-commit hook will attempt to create a new checkpoint for every replayed commit — even though those commits already have checkpoints and no agent session is running. + +Add a guard to `internal/hooks/post_commit.go` (or wherever the post-commit logic lives) that detects an in-progress rebase and returns early with a no-op. Detection: check for the presence of `.git/rebase-merge/` or `.git/rebase-apply/` directories (these exist for the duration of an interactive or am-style rebase). + +Note: Partio already guards against `--amend` re-entry by deleting the state file before the amend. The rebase case is separate — the state file won't be present (so that guard won't trigger), but the hook still fires. + +## Why + +Without this guard, `git rebase -i` on a branch with many commits will: +1. Attempt to create a new checkpoint for each replayed commit (most will fail gracefully since there's no state file, but it adds unnecessary overhead) +2. Potentially create a spurious checkpoint if a pre-commit state file happens to be present from a prior interrupted operation +3. Slow down rebases with checkpoint overhead + +This matches a pattern seen in `entireio/cli` PR #824 which added a guard against duplicate `session.created` events being processed. + +## Source + +Inspired by `entireio/cli` PR #824 (guard session-start hook on duplicate session.created) and the general pattern of making hooks resilient to git operations that replay commits. + +## Implementation hints + +- `internal/hooks/` — post-commit hook implementation +- `internal/git/` — add a `IsRebaseInProgress(gitDir string) bool` helper +- Check `filepath.Join(gitDir, "rebase-merge")` and `filepath.Join(gitDir, "rebase-apply")` +- Use `internal/log` for the debug-level log message +- The git dir is available via `git rev-parse --git-dir` (already used elsewhere) + diff --git a/.minions/programs/omit-zero-token-count-in-checkpoint-metadata.md b/.minions/programs/omit-zero-token-count-in-checkpoint-metadata.md new file mode 100644 index 0000000..f35a246 --- /dev/null +++ b/.minions/programs/omit-zero-token-count-in-checkpoint-metadata.md @@ -0,0 +1,51 @@ +--- +id: omit-zero-token-count-in-checkpoint-metadata +target_repos: + - cli +acceptance_criteria: + - "`SessionMetadata.TotalTokens` is changed from `int` to `*int` so zero vs unknown can be distinguished" + - "When token data is not available (nil pointer), `total_tokens` is omitted from the JSON output entirely (`omitempty`)" + - "When token data is zero but explicitly set, it serializes as `0` (e.g. a session that used 0 tokens)" + - "Existing checkpoint metadata files with `total_tokens: 0` deserialize without error (nil pointer, not a panic)" + - "The post-commit hook only sets `TotalTokens` when the parsed session actually reports token usage" + - "Unit tests in `internal/checkpoint/` or `internal/hooks/` cover the nil case" +pr_labels: + - minion +--- + +# Omit token count in checkpoint metadata when no token data exists + +## Source + +entireio/cli PR #854: "fix: omit token count when no token data exists" — tokens are only calculated during checkpoint creation or condensation. Sessions with no file changes never get token data, so showing "tokens 0" is misleading — the real count is unknown. + +## Problem + +`internal/checkpoint/metadata.go` defines `TotalTokens int`, which defaults to `0` for any session where token tracking didn't occur (e.g. the session produced no new content, or the JSONL parsing found no token usage entries). This is indistinguishable from a session that genuinely used 0 tokens, making the displayed count misleading. + +## Proposed Change + +Change `SessionMetadata.TotalTokens` from `int` to `*int` in `internal/checkpoint/metadata.go`: + +```go +type SessionMetadata struct { + Agent string `json:"agent"` + TotalTokens *int `json:"total_tokens,omitempty"` + Duration string `json:"duration"` +} +``` + +Update `internal/hooks/postcommit.go` (and any other callers that set `TotalTokens`) to only assign the field when token data is actually present from the JSONL parse result. When `internal/agent/claude/parse_jsonl.go` returns a token count of 0 because no token events were found, leave `TotalTokens` as nil instead of setting it to 0. + +Any code that reads `TotalTokens` for display (e.g. `partio rewind --list`) should treat `nil` as "unknown" and skip the token field rather than showing "0 tokens". + +## Why This Matters + +Displaying "0 tokens" implies the agent ran but consumed no tokens, which is confusing and inaccurate. Omitting the field when unknown gives users correct signal: if they see a token count it's real data, if they see nothing it means the data wasn't captured. + +## Context + +- `internal/checkpoint/metadata.go` — `SessionMetadata` struct with `TotalTokens int` +- `internal/hooks/postcommit.go` — sets `TotalTokens` during checkpoint creation +- `internal/agent/claude/parse_jsonl.go` — JSONL parsing that extracts token usage +- `cmd/partio/rewind.go` — displays checkpoint metadata to users diff --git a/.minions/programs/partio-clean-command.md b/.minions/programs/partio-clean-command.md new file mode 100644 index 0000000..c666fc6 --- /dev/null +++ b/.minions/programs/partio-clean-command.md @@ -0,0 +1,43 @@ +--- +id: partio-clean-command +target_repos: + - cli +acceptance_criteria: + - "`partio clean` removes orphaned state files from `.partio/state/` (pre-commit state left by interrupted hooks)" + - "`partio clean --all` removes all session state files, including idle sessions" + - "Command is idempotent — safe to run when nothing needs cleaning, exits 0" + - "Command prints a summary of what was removed (or 'nothing to clean' when clean)" + - "Existing active session state is preserved by default (only orphaned/ended state is removed)" +pr_labels: + - minion +--- + +# Add `partio clean` command to remove stale session state + +## What + +Add a `partio clean` command that removes orphaned and stale state files from `.partio/state/`. When git hooks are interrupted (e.g., a crash during commit, a failed amend, or aborted operations), pre-commit state files can be left behind. Over time these accumulate and can cause spurious checkpoint creation on the next commit. + +Default behavior: +- Remove pre-commit state files that have no corresponding live commit operation in progress +- Remove session state for sessions that ended but whose state files were not cleaned up + +With `--all` flag: +- Remove all session state files, regardless of session status + +## Why + +Partio saves detection state to `.partio/state/pre-commit.json` before each commit and deletes it in post-commit. If the commit is interrupted before post-commit runs, this file lingers. On the next commit, Partio may pick up the stale state and create an incorrect checkpoint linkage. A `partio clean` command lets users recover from this situation without having to run `partio disable && partio enable`. + +## Source + +Inspired by `entireio/cli` PR #846 which fixed `entire clean --all` to clean all sessions (not just orphaned ones) — changelog 0.5.3. + +## Implementation hints + +- `cmd/partio/clean.go` — new Cobra subcommand +- `internal/session/` — for listing and identifying stale session state +- State files are in `.partio/state/` relative to the git worktree root +- Use `internal/git` to get the worktree root path +- Check if `.partio/state/pre-commit.json` exists and whether a commit is in progress (presence of `.git/COMMIT_EDITMSG` being written) before removing + diff --git a/.minions/programs/partio-search-checkpoints.md b/.minions/programs/partio-search-checkpoints.md new file mode 100644 index 0000000..bd1dba3 --- /dev/null +++ b/.minions/programs/partio-search-checkpoints.md @@ -0,0 +1,49 @@ +--- +id: partio-search-checkpoints +target_repos: + - cli +acceptance_criteria: + - "`partio search ` returns checkpoints whose metadata (prompt, context, files touched, commit message) contains the query string" + - "Results show checkpoint ID, associated commit hash (short), commit date, and a matching excerpt" + - "`--since ` flag filters results to checkpoints created after the given date (ISO 8601)" + - "Returns exit code 1 with a clear message when no checkpoints are found or the repo has no checkpoint branch" + - "Matches are case-insensitive" +pr_labels: + - minion +--- + +# Add `partio search` command to query checkpoint history + +## What + +Add a `partio search ` command that searches across checkpoint metadata stored on the `partio/checkpoints/v1` branch. The command reads checkpoint trees from the orphan branch and matches against available fields: prompt, context, files touched, and associated commit messages. + +Example usage: +``` +partio search "authentication" +partio search "refactor database" --since 2026-01-01 +``` + +Output example: +``` +checkpoint abc1234 → commit def5678 (2026-03-15) + Files: internal/auth/handler.go, internal/auth/middleware.go + Prompt: Refactor the authentication middleware to use... +``` + +## Why + +As checkpoint data accumulates across many sessions, users need a way to find relevant historical AI sessions without scrolling through `git log`. Search enables knowledge retrieval: "when did we refactor the auth layer?" or "what sessions touched the checkpoint storage code?" This is the core value proposition of preserving AI session context — it should be queryable. + +## Source + +Inspired by `entireio/cli` PR #833 which scaffolds managed search subagents for querying checkpoint data. + +## Implementation hints + +- `cmd/partio/search.go` — new Cobra subcommand +- `internal/checkpoint/` — for reading checkpoint trees from the orphan branch +- Use existing git plumbing (ls-tree, cat-file) to iterate checkpoints without checkout +- Start with simple substring matching; avoid external search dependencies (keep minimal deps) +- Checkpoint metadata is stored in JSON blobs within the checkpoint trees + diff --git a/.minions/programs/session-friction-improve.md b/.minions/programs/session-friction-improve.md new file mode 100644 index 0000000..ceb9d02 --- /dev/null +++ b/.minions/programs/session-friction-improve.md @@ -0,0 +1,34 @@ +--- +id: session-friction-improve +target_repos: + - cli +acceptance_criteria: + - "partio improve analyzes recent session transcripts and identifies recurring friction patterns (repeated errors, retries, misunderstandings)" + - "partio improve generates specific suggestions for CLAUDE.md improvements with evidence excerpts from transcripts" + - "Suggestions include unified diffs showing proposed changes to context files" + - "Analysis works offline using locally stored checkpoint data on the orphan branch" + - "Command exits cleanly with a helpful message when no sessions or insufficient data exist" +pr_labels: + - minion +--- + +# Add `partio improve` command for AI-powered context file improvement suggestions + +## Description + +Add a `partio improve` command that analyzes captured session transcripts from checkpoints to identify recurring friction patterns (repeated errors, tool-call retries, misunderstandings, wasted turns) and generates actionable suggestions for improving context files like `CLAUDE.md`. + +The command should use a two-phase approach: +1. **Index phase**: Scan checkpoint session data to identify recurring friction themes (e.g., agent repeatedly hitting the same linting error, misunderstanding project conventions, retrying failed approaches). +2. **Suggest phase**: Read relevant transcript excerpts and generate specific improvement suggestions — with evidence quotes and proposed diffs — for context files that would prevent the friction in future sessions. + +This leverages Partio's unique position of having captured session transcripts to close the feedback loop: sessions reveal what the agent struggled with, and those struggles inform better prompts/context for future sessions. + +## Why + +Partio already captures the full reasoning behind code changes. This feature turns that captured data into direct value by helping users write better CLAUDE.md files and project instructions. Without this, users must manually review session logs to identify patterns — a tedious process that rarely happens. Automated friction analysis makes the captured session data actively useful rather than purely archival. + +## Source + +- **Origin:** entireio/cli#765 (PR: Agent Improvement Engine) +- **Detected from:** `entireio-cli-pulls` diff --git a/.minions/programs/show-installed-agents-in-status.md b/.minions/programs/show-installed-agents-in-status.md new file mode 100644 index 0000000..1bcccc2 --- /dev/null +++ b/.minions/programs/show-installed-agents-in-status.md @@ -0,0 +1,40 @@ +--- +id: show-installed-agents-in-status +target_repos: + - cli +acceptance_criteria: + - "`partio status` shows a line listing which agents have hooks installed when partio is enabled" + - "Detection is based on whether hook files exist and contain the partio marker, not just what is in config" + - "Line is omitted when partio is disabled or no agent hooks are detected" + - "make test passes" + - "make lint passes" +pr_labels: + - minion +--- + +# Show agents with hooks installed in `partio status` + +Currently `partio status` shows `Agent: claude-code` from the config file, but this reflects configuration intent rather than the actual installed state. Users who edit configs or run `partio enable` multiple times can end up with a mismatch between config and reality. + +Add an "Agents with hooks:" line below `Hooks:` in the status output that shows which agents actually have hooks installed on disk. Detection should read the existing hook files and check for the partio marker (already defined in `internal/git/hooks/hooks.go` as `partioMarker = "# Installed by partio"`). + +## Desired output + +``` +Status: enabled +Strategy: manual-commit +Agent: claude-code +Hooks: installed +Agents: claude-code +Checkpoints: branch exists +``` + +If no partio-owned hook files are found, omit the "Agents:" line. Partio currently only supports claude-code, so for now the line will show `claude-code` when hooks are installed and be omitted otherwise. + +## Key files + +- `cmd/partio/status.go` — `runStatus()` — add the new output line after the hooks check +- `internal/git/hooks/hooks.go` — `isPartioHook()` helper for checking hook content +- `internal/git/hooks/` — `hookNames` slice lists the expected hook names + +**Inspired by:** entireio/cli#847 (Show installed agents in status output) diff --git a/.minions/programs/unknown-agent-fallback.md b/.minions/programs/unknown-agent-fallback.md new file mode 100644 index 0000000..d9fb25f --- /dev/null +++ b/.minions/programs/unknown-agent-fallback.md @@ -0,0 +1,34 @@ +--- +id: unknown-agent-fallback +target_repos: + - cli +acceptance_criteria: + - "When agent detection returns false (agent not running), checkpoints record agent as `Unknown` not the configured agent name" + - "The configured agent name is used only as a detection hint, not as an attribution fallback" + - "make test passes" + - "make lint passes" +pr_labels: + - minion +--- + +# Use "Unknown" as fallback agent type for unidentified sessions + +When Partio's pre-commit hook runs and `Detector.IsRunning()` returns false (no agent process found), the current flow still stores the configured agent name (e.g., `claude-code`) in the session state. The post-commit hook then creates a checkpoint attributing the work to that agent, even though detection failed. + +This is misleading: if the agent wasn't detected, the attribution is a guess. The agent field should be `"Unknown"` in this case rather than the configured default. + +## Change + +In the hook flow, when `IsRunning()` returns false: +- Record the agent as `"Unknown"` in the pre-commit state file (`.partio/state/pre-commit.json`) +- Post-commit reads this and writes it into the checkpoint metadata + +The configured agent name (from `cfg.Agent`) should remain the detector selector — i.e., which agent to look for — but should not appear in checkpoint metadata when detection failed. + +## Key files + +- `internal/hooks/precommit.go` — where detection state is saved; change the agent field to `"Unknown"` when `IsRunning()` returns false +- `internal/hooks/postcommit.go` — reads pre-commit state and creates checkpoints +- `internal/session/state.go` — the state struct that carries agent information between hooks + +**Inspired by:** entireio/cli#838 (fix: use Unknown instead of Claude Code for unidentified agent fallback) diff --git a/.minions/programs/v2-aware-read-commands.md b/.minions/programs/v2-aware-read-commands.md new file mode 100644 index 0000000..4906cc6 --- /dev/null +++ b/.minions/programs/v2-aware-read-commands.md @@ -0,0 +1,30 @@ +--- +id: v2-aware-read-commands +target_repos: + - cli +acceptance_criteria: + - "`partio rewind` resolves checkpoints from v2 store first, falling back to v1 when v2 data is not available" + - "`partio status` displays checkpoint information from whichever store (v1 or v2) contains the data" + - "Listing checkpoints merges results from both v1 and v2 stores so pre-migration checkpoints remain visible" + - "When v2 compact transcript exists, read commands use it instead of the full JSONL" + - "A test verifies that a v1-only checkpoint is still accessible after v2 support is added" + - "A test verifies that a v2 checkpoint is preferred over a v1 checkpoint when both exist" +pr_labels: + - minion + - feature +--- + +# Make read commands v2-aware with v1 fallback + +Once checkpoints v2 (compact `transcript.jsonl`) is implemented for writes, all read-path commands (`partio rewind`, `partio status`, and any future checkpoint inspection commands) must be updated to resolve checkpoints from the v2 store first, falling back to v1 for older checkpoints. + +## Why + +Without this, commands that read checkpoint data will break or return empty results once checkpoints are primarily written in v2 format. Users who upgrade will lose visibility into new checkpoints through the CLI, even though the data exists. Additionally, pre-migration v1 checkpoints must remain accessible during the transition period. + +## Approach + +- Add a resolution layer in the checkpoint read path that checks v2 first, then v1 +- When listing checkpoints, merge results from both stores (deduplicating by checkpoint ID) +- When reading transcript data, prefer the compact v2 `transcript.jsonl` over the full session JSONL +- Ensure `partio rewind` works with both checkpoint formats diff --git a/.minions/programs/warn-uncommitted-shared-config.md b/.minions/programs/warn-uncommitted-shared-config.md new file mode 100644 index 0000000..d13bdbf --- /dev/null +++ b/.minions/programs/warn-uncommitted-shared-config.md @@ -0,0 +1,29 @@ +--- +id: warn-uncommitted-shared-config +target_repos: + - cli +acceptance_criteria: + - "After `partio enable` or `partio configure` modifies `.partio/settings.json`, a hint is printed reminding the user to commit the file if it contains team-shared settings" + - "The hint only appears when `.partio/settings.json` has uncommitted changes (not when it is already tracked and clean)" + - "The hint is suppressed in non-interactive contexts (e.g., CI) or when stdout is not a terminal" + - "A test verifies the hint appears after a config modification when the file is untracked" + - "A test verifies the hint does not appear when the file is already committed and unchanged" +pr_labels: + - minion + - feature +--- + +# Warn when shared config file has uncommitted changes + +After `partio enable` or `partio configure` modifies `.partio/settings.json`, print a hint reminding the user to commit the file so that team members share the same configuration. + +## Why + +When users configure team-shared settings (like checkpoint strategy or agent type), forgetting to commit `.partio/settings.json` means teammates won't pick up those settings. This is especially easy to miss because the file is created/modified by CLI commands rather than edited by hand. A simple hint at the right moment prevents configuration drift across the team. + +## Approach + +- After any command that writes to `.partio/settings.json`, check if the file has uncommitted changes using `git status --porcelain` +- If the file is untracked or modified, print a hint: `Hint: .partio/settings.json has uncommitted changes. Consider committing it so your team shares the same config.` +- Only show the hint when stdout is a terminal (skip in CI/piped contexts) +- Keep the hint non-blocking — it's informational, not an error diff --git a/.minions/sources.yaml b/.minions/sources.yaml index 7add2e8..b655fb7 100644 --- a/.minions/sources.yaml +++ b/.minions/sources.yaml @@ -2,14 +2,14 @@ sources: - name: entireio-cli url: https://github.com/entireio/cli/blob/main/CHANGELOG.md type: changelog - last_version: 0.5.1 + last_version: 0.5.3 - name: entireio-cli-issues url: https://github.com/entireio/cli/issues type: issues repo: entireio/cli - last_version: "750" + last_version: "868" - name: entireio-cli-pulls url: https://github.com/entireio/cli/pulls type: pulls repo: entireio/cli - last_version: "746" + last_version: "879"