initial commit
This commit is contained in:
parent
3f7ccd0f34
commit
13a2ec6581
3 changed files with 213 additions and 0 deletions
71
AGENTS.md
Normal file
71
AGENTS.md
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# AGENTS.md — pi-worktree Extension
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
.pi/extensions/pi-worktree.ts # Single-file extension (all tool + command logic)
|
||||||
|
README.md # User-facing documentation
|
||||||
|
DESIGN.md # Architecture and design decisions
|
||||||
|
DOMAIN.md # Domain concepts and terminology
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
- **Language**: TypeScript
|
||||||
|
- **Schema**: TypeBox (`@sinclair/typebox`) for tool parameter schemas
|
||||||
|
- **Runtime**: pi coding agent extension API (`ExtensionAPI`, `ExtensionContext`)
|
||||||
|
- **Git**: native via `pi.exec("git", [...])` — no external git packages
|
||||||
|
- **No npm dependencies** in v1 beyond what pi provides
|
||||||
|
|
||||||
|
## Extension Entry Point
|
||||||
|
|
||||||
|
The extension is a single default-exported function:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
||||||
|
import { Type } from "typebox";
|
||||||
|
|
||||||
|
export default function (pi: ExtensionAPI) {
|
||||||
|
// register tools and commands here
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tool Conventions
|
||||||
|
|
||||||
|
- Each tool is a `Type.Object` schema + async execute function.
|
||||||
|
- Execute signature: `(toolCallId, params, signal, onUpdate, ctx)`
|
||||||
|
- Always check `result.exitCode !== 0` for git failures — surface the message with suggested fixes.
|
||||||
|
- **Fail fast**: refuse dangerous operations (existing paths, current branch, uncommitted changes) with clear messages and suggestions. No silent auto-correction.
|
||||||
|
|
||||||
|
## Command Conventions
|
||||||
|
|
||||||
|
- Register via `pi.registerCommand("name", { description, handler })`.
|
||||||
|
- Use `ctx.ui.select()` for interactive pickers.
|
||||||
|
- Parse structured data from tool results (not raw text).
|
||||||
|
|
||||||
|
## State Management
|
||||||
|
|
||||||
|
- Tools are **stateless** — each call works independently based on current git state.
|
||||||
|
- Session memory is ephemeral (per pi process lifetime) for back-switching behavior only.
|
||||||
|
|
||||||
|
## Error Handling Pattern
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
if (result.exitCode !== 0) {
|
||||||
|
return {
|
||||||
|
content: [{ type: "text", text: `Error: ${result.stderr}. Suggestion: <fix>` }],
|
||||||
|
isError: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Always include a suggested fix in error messages.
|
||||||
|
|
||||||
|
## Validation Checklist
|
||||||
|
|
||||||
|
- [ ] Extension loads without errors when pi starts
|
||||||
|
- [ ] All four tools registered with correct signatures
|
||||||
|
- [ ] Error paths return `isError: true` with helpful messages
|
||||||
|
- [ ] `/worktree` command shows interactive picker
|
||||||
|
- [ ] Branch display updates after switching worktrees
|
||||||
|
- [ ] No external dependencies beyond TypeBox + pi SDK
|
||||||
61
DESIGN.md
Normal file
61
DESIGN.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
# DESIGN.md — Architecture & Design Decisions
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A pi extension that manages git worktrees through tool commands and an interactive `/worktree` command, with tight session integration.
|
||||||
|
|
||||||
|
## v1 Scope
|
||||||
|
|
||||||
|
- Four tools: `git_worktree_create`, `git_worktree_list`, `git_worktree_switch`, `git_worktree_remove`
|
||||||
|
- One command: `/worktree` (interactive picker)
|
||||||
|
- Session hooks: branch display update + offer new session after switch
|
||||||
|
- **Out of scope**: auto-worktree creation, smart defaults, persistent state
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
pi-worktree.ts
|
||||||
|
├── Tools
|
||||||
|
│ ├── git_worktree_create(path, branch?, create_branch?)
|
||||||
|
│ ├── git_worktree_list()
|
||||||
|
│ ├── git_worktree_switch(target)
|
||||||
|
│ └── git_worktree_remove(path)
|
||||||
|
├── Command: /worktree (interactive picker)
|
||||||
|
└── Session hooks
|
||||||
|
├── Update pi's git branch display on switch
|
||||||
|
└── Offer new session creation after switch
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Design Decisions
|
||||||
|
|
||||||
|
### Stateless Tools, Ephemeral Memory
|
||||||
|
Tools are stateless; only in-memory mapping of worktree→session during a process lifetime for back-switching. Lost on restart.
|
||||||
|
|
||||||
|
### Fail Fast, No Auto-Correction
|
||||||
|
Refuse dangerous operations (existing path, current branch, uncommitted changes) with clear messages and suggested fixes. Never silently auto-correct.
|
||||||
|
|
||||||
|
### Session Integration Depth (v1)
|
||||||
|
Update branch display + offer new session creation. No automatic worktree creation per branch — keeps complexity down and avoids assumptions about workflow.
|
||||||
|
|
||||||
|
## Tool Behaviors
|
||||||
|
|
||||||
|
| Tool | Key Behavior | Fail Conditions |
|
||||||
|
|------|-------------|-----------------|
|
||||||
|
| `create` | `git worktree add <path> [branch]`, `-b` for new branches | Path exists, branch is current |
|
||||||
|
| `list` | Parses `git worktree list` output into structured data | No git repo present |
|
||||||
|
| `switch` | Changes cwd to target worktree path | Already there, uncommitted changes in source |
|
||||||
|
| `remove` | `git worktree remove <path>` | Target is main repo, uncommitted changes |
|
||||||
|
|
||||||
|
## Edge Cases
|
||||||
|
|
||||||
|
1. **Nested worktrees**: Not supported by git — surface native error
|
||||||
|
2. **Detached HEAD**: Use path for identification instead of branch name
|
||||||
|
3. **Untracked files on removal**: Suggest removing/moving them first
|
||||||
|
4. **Same-branch worktrees**: Let git handle it, surface the error
|
||||||
|
|
||||||
|
## Rollout Phases
|
||||||
|
|
||||||
|
1. Core tools (create, list, switch, remove) with error handling
|
||||||
|
2. `/worktree` interactive command with picker + back-switching
|
||||||
|
3. Session integration hooks (branch display, new session offer)
|
||||||
|
4. Polish: edge cases, README, user testing
|
||||||
81
README.md
Normal file
81
README.md
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
# pi-worktree
|
||||||
|
|
||||||
|
A pi extension for managing git worktrees through intuitive tool commands and an interactive picker.
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
### `git_worktree_create`
|
||||||
|
|
||||||
|
Create a linked worktree for a branch in the current repo.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
{
|
||||||
|
path: string, // Path for the new worktree
|
||||||
|
branch?: string, // Branch name (new or existing). Defaults to 'main'.
|
||||||
|
create_branch?: boolean // Create a new branch? Defaults to true if branch doesn't exist.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**: `git_worktree_create({ path: "./feature-x", branch: "feature-x" })`
|
||||||
|
|
||||||
|
### `git_worktree_list`
|
||||||
|
|
||||||
|
List all linked worktrees in the current repo.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// No parameters required
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns structured data with `branch`, `path`, and `isCurrent` for each worktree.
|
||||||
|
|
||||||
|
**Example output**:
|
||||||
|
```
|
||||||
|
main — /home/user/repo (current)
|
||||||
|
feature-x — /home/user/repo/feature-x
|
||||||
|
```
|
||||||
|
|
||||||
|
### `git_worktree_switch`
|
||||||
|
|
||||||
|
Switch pi's working directory to a linked worktree.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
{
|
||||||
|
target: string // Path or branch name of the target worktree
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**: `git_worktree_switch({ target: "./feature-x" })`
|
||||||
|
|
||||||
|
After switching, you'll be offered the option to create a new session for that worktree context.
|
||||||
|
|
||||||
|
### `git_worktree_remove`
|
||||||
|
|
||||||
|
Remove a linked worktree.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
{
|
||||||
|
path: string // Path of the worktree to remove
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**: `git_worktree_remove({ path: "./feature-x" })`
|
||||||
|
|
||||||
|
## Command
|
||||||
|
|
||||||
|
### `/worktree`
|
||||||
|
|
||||||
|
Interactive picker to switch between linked worktrees.
|
||||||
|
|
||||||
|
Lists all worktrees with a branch-first display and lets you select one to switch to. Automatically updates pi's branch display after switching.
|
||||||
|
|
||||||
|
## Behavior
|
||||||
|
|
||||||
|
- **Fail fast**: Refuses dangerous operations (existing paths, current branch, uncommitted changes) with clear messages and suggested fixes.
|
||||||
|
- **Stateless tools**: Each call works independently based on current git state.
|
||||||
|
- **Session integration**: Branch display updates automatically; you're offered a new session after switching worktrees.
|
||||||
|
- **Back-switching**: When returning to the main repo, pi restores the previous session.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Git 2.x with worktree support (all modern versions)
|
||||||
|
- No external npm dependencies — uses only pi's extension API and TypeBox schemas.
|
||||||
Loading…
Add table
Reference in a new issue