initial commit

This commit is contained in:
David Kong 2026-07-24 12:36:57 +10:00
parent 3f7ccd0f34
commit 13a2ec6581
3 changed files with 213 additions and 0 deletions

71
AGENTS.md Normal file
View 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
View 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
View 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.