npm package: @0xkobold/pi-patch
Description: patch-package clone for pi - fuzzy matching and agent integration
Author: 0xKobold
Latest version: 0.1.0

# Pi Patch 🩹

**A full patch-package clone for pi. Create and apply patches to node_modules packages with fuzzy matching support.**

> 🎯 **Goal**: Drop-in replacement for `patch-package` that works inside pi with agent integration.

---

## Quick Start

```bash
# 1. Edit a dependency
$EDITOR node_modules/express/index.js

# 2. Create patch (exactly like patch-package)
/patch-package express

# 3. Commit patches
git add .patches/
git commit -m "fix: patch express"
```

Patches auto-apply when pi starts.

---

## Commands

| Command | Description |
|---------|-------------|
| `/patch-package <package>` | Create patch from modified package |
| `/patch-package` | Create patches for ALL modified packages |
| `/patch` or `/patch apply` | Apply all patches |
| `/patch dry-run` | Test patches without applying |
| `/patch revert` | Revert all patches |
| `/patch status` | Show modified packages & patches |

---

## Agent Integration

The agent can use the `patch_package` tool to manage patches programmatically:

```typescript
// Create patch for a specific package
{
  "action": "create",
  "package_name": "lodash"
}

// Create patches for all modified packages
{ "action": "create_all" }

// List modified packages
{ "action": "list_modified" }

// Apply patches
{ "action": "apply" }

// Dry run
{ "action": "dry_run" }

// Status check
{ "action": "status" }
```

---

## How It Works

### 1. Modify Dependencies

```bash
# Edit files in node_modules/
ed node_modules/some-package/index.js
# Files are automatically backed up as .orig
```

### 2. Create Patches

```bash
# Single package
/patch-package some-package

# All modified
/patch-package
```

**Patch naming:** `package-name+1.2.3.patch`

### 3. Apply Patches

Patches apply automatically on pi startup, or manually:
```bash
/patch apply
```

**Fuzzy matching:** Uses `git apply` with 3-way support (like patch-package).

---

## Installation

### Global (Recommended)

```bash
mkdir -p ~/.pi/agent/extensions/pi-patch
cp extension.ts ~/.pi/agent/extensions/pi-patch/
```

### Project-local

```bash
mkdir -p .pi/extensions/pi-patch
cp extension.ts .pi/extensions/pi-patch/
```

### For Development (Symlink)

```bash
ln -s $(pwd)/extension.ts ~/.pi/agent/extensions/pi-patch/index.ts
```

---

## Comparison with patch-package

| Feature | patch-package | pi-patch |
|---------|--------------|----------|
| Patch node_modules | ✅ | ✅ |
| Fuzzy matching | ✅ (git apply) | ✅ (git apply) |
| Auto-apply | ✅ (postinstall) | ✅ (pi startup) |
| Version in filename | ✅ | ✅ |
| Scoped packages (@x/y) | ✅ | ✅ |
| Dry run | ✅ | ✅ |
| Revert patches | ✅ | ✅ |
| **Agent tool access** | ❌ | ✅ |
| **Patch pi internals** | ❌ | ✅ |

**Drop-in compatible:** Same workflow, same patch format.

---

## Configuration

Create `.patches/pi-patch.json`:

```json
{
  "autoApply": true,
  "allowFuzzy": true,
  "postinstall": false,
  "excludePackages": ["@types/node"]
}
```

| Option | Description |
|--------|-------------|
| `autoApply` | Apply patches on pi startup |
| `allowFuzzy` | Allow git fuzzy matching (recommended) |
| `excludePackages` | Skip these packages |

---

## Patch Format

Standard unified diff (same as patch-package):

```diff
diff --git a/lodash b/lodash
# Package: lodash
--- a/lib/debounce.js
+++ b/lib/debounce.js
@@ -10,3 +10,4 @@
 function debounce() {
+  if (!func) return;
   setup();
 }
```

---

## Troubleshooting

### Patch fails to apply

```bash
# Check what would happen
/patch dry-run

# See detailed output
/patch status
```

### File changed too much

If upstream changed significantly:

```bash
# 1. Revert patch
/patch revert

# 2. Update package
npm update some-package

# 3. Re-apply your changes
# 4. Create new patch
/patch-package some-package
```

### "No modified packages found"

The extension uses `.orig` files to detect modifications. Make sure:
- You actually edited files in `node_modules/`
- `.orig` backups exist (created automatically on first edit)

To force detect changes:
```bash
# Manually back up before editing
cp node_modules/pkg/file.js node_modules/pkg/file.js.orig
# Now edit the file
```

---

## Testing

```bash
bun test          # Run all tests
bun test --watch  # Watch mode
```

**54 tests** covering:
- Patch creation with git diff
- Fuzzy matching with git apply
- Package detection in node_modules
- Edge cases and error scenarios

---

## Workflow Examples

### Fix a Bug in Production

```bash
# Find the bug in node_modules/express/lib/router.js

# Back up and edit
cp node_modules/express/lib/router.js{,.orig}
$EDITOR node_modules/express/lib/router.js

# Create patch
/patch-package express

# Commit
git add .patches/
git commit -m "fix: express router bug"

# Next deploy: patches auto-apply
```

### Maintain Private Fork

```bash
# Heavy customization of a package
# Edit many files in node_modules/my-fork/

# Create patches for all modifications
/patch-package

# Result: Multiple patches committed to repo
# Patches survive npm install
```

### Agent-Driven Patching

You can ask the agent to create patches:

> "The lodash merge function has a bug. Can you patch it?"

The agent will:
1. Locate `node_modules/lodash/merge.js`
2. Create a backup as `.orig`
3. Apply the fix
4. Run `patch_package` tool to create the patch
5. Report the created patch file

---

## Why Not Just Use patch-package?

1. **Agent Integration**: pi-patch gives agents direct access to patch management
2. **Pi Internals**: Can patch pi-coding-agent itself (extensions, core files)
3. **No npm Required**: Works with bun, pnpm, or any package manager
4. **Unified Interface**: One tool for dependencies and pi customization

---

## License

MIT