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
55 changes: 55 additions & 0 deletions plugins/amp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Warp Notifications for Amp

Warp terminal integration for [Amp](https://ampcode.com) — the coding agent by Sourcegraph.

## Installation

Copy the plugin file to Amp's global plugins directory:

```bash
cp plugins/amp/warp-notify.ts ~/.config/amp/plugins/warp-notify.ts
```

Then run Amp with plugins enabled:

```bash
PLUGINS=all amp
```

To enable permanently, add to your shell profile:

```bash
echo 'export PLUGINS=all' >> ~/.zshrc
```

## Verify

```bash
PLUGINS=all amp plugins list
```

You should see:
```
✓ /Users/you/.config/amp/plugins/warp-notify.ts active
Events: session.start, agent.start, tool.call, tool.result, agent.end
```

## Requirements

- [Warp terminal](https://warp.dev)
- [Amp CLI](https://ampcode.com) (binary install, not npm)
- `PLUGINS=all` environment variable

## How It Works

Uses Amp's TypeScript plugin API (`amp.on(...)`) to hook into 5 lifecycle events and emit the same `warp://cli-agent` OSC 777 structured notifications as the Claude Code plugin.

| Amp Event | Warp Notification |
|---|---|
| `session.start` | `session_start` |
| `agent.start` | `prompt_submit` |
| `tool.call` | `permission_request` |
| `tool.result` | `tool_complete` |
| `agent.end` | `stop` |

> **Note**: Amp's plugin API is experimental. Expect breaking changes.
81 changes: 81 additions & 0 deletions plugins/amp/warp-notify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// @i-know-the-amp-plugin-api-is-wip-and-very-experimental-right-now
import type { PluginAPI } from '@ampcode/plugin'

function shouldUseStructured(): boolean {
const proto = process.env.WARP_CLI_AGENT_PROTOCOL_VERSION
const client = process.env.WARP_CLIENT_VERSION
if (!proto || !client) return false

const LAST_BROKEN_STABLE = 'v0.2026.03.25.08.24.stable_05'
const LAST_BROKEN_PREVIEW = 'v0.2026.03.25.08.24.preview_05'

let threshold = ''
if (client.includes('stable')) threshold = LAST_BROKEN_STABLE
else if (client.includes('preview')) threshold = LAST_BROKEN_PREVIEW

if (threshold && !(client > threshold)) return false
return true
}

function warpNotify(payload: Record<string, unknown>): void {
if (!shouldUseStructured()) return
const body = JSON.stringify(payload)
try {
const fs = require('fs')
fs.writeFileSync('/dev/tty', `\x1b]777;notify;warp://cli-agent;${body}\x07`)
} catch {}
}

function buildPayload(event: string, extra: Record<string, unknown> = {}): Record<string, unknown> {
const cwd = process.cwd()
return {
v: 1,
agent: 'amp',
event,
cwd,
project: cwd.split('/').pop() || '',
...extra,
}
}

export default function (amp: PluginAPI) {
amp.on('session.start', (event) => {
warpNotify(buildPayload('session_start', {
session_id: event.thread?.id || 'unknown',
}))
})

amp.on('agent.start', (event) => {
const query = event.message.length > 200 ? event.message.slice(0, 197) + '...' : event.message
warpNotify(buildPayload('prompt_submit', {
session_id: event.thread.id,
query,
}))
})

amp.on('tool.call', (event, ctx) => {
const summary = `Wants to run ${event.tool}`
warpNotify(buildPayload('permission_request', {
session_id: event.thread.id,
summary,
tool_name: event.tool,
tool_input: event.input,
}))
return { action: 'allow' }
})

amp.on('tool.result', (event) => {
warpNotify(buildPayload('tool_complete', {
session_id: event.thread.id,
tool_name: event.tool,
}))
})

amp.on('agent.end', (event) => {
const query = event.message.length > 200 ? event.message.slice(0, 197) + '...' : event.message
warpNotify(buildPayload('stop', {
session_id: event.thread.id,
query,
}))
})
}
42 changes: 42 additions & 0 deletions plugins/cline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Warp Notifications for Cline CLI

Warp terminal integration for [Cline CLI](https://cline.bot) — the open-source AI coding agent.

## Installation

Copy the hook scripts to Cline's hooks directory:

```bash
mkdir -p ~/Documents/Cline/Hooks
cp plugins/cline/hooks/*.sh ~/Documents/Cline/Hooks/
chmod +x ~/Documents/Cline/Hooks/*.sh
```

Cline automatically discovers hooks from `~/Documents/Cline/Hooks/`.

## Hooks

| Hook File | Warp Notification | When |
|---|---|---|
| `TaskStart.sh` | `session_start` | Cline starts a new task |
| `TaskComplete.sh` | `stop` | Cline finishes a task |
| `TaskError.sh` | `stop` (with error) | Cline encounters an error |
| `PreToolUse.sh` | `permission_request` | Before a tool runs |
| `PostToolUse.sh` | `tool_complete` | After a tool finishes |
| `UserPromptSubmit.sh` | `prompt_submit` | User sends a prompt |

## Requirements

- [Warp terminal](https://warp.dev)
- [Cline CLI](https://cline.bot) v2.15+
- `jq` for JSON parsing (`brew install jq`)

## How It Works

Each hook script is a self-contained bash script that:
1. Checks for Warp's `WARP_CLI_AGENT_PROTOCOL_VERSION` env var (exits silently if not in Warp)
2. Reads event data from stdin as JSON
3. Builds a structured notification payload
4. Emits it via OSC 777 escape sequence to `/dev/tty`

The payloads use the same `warp://cli-agent` protocol as the Claude Code plugin.
27 changes: 27 additions & 0 deletions plugins/cline/hooks/PostToolUse.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash
# Warp notification on Cline post-tool-use

[ -z "${WARP_CLI_AGENT_PROTOCOL_VERSION:-}" ] && exit 0
[ -z "${WARP_CLIENT_VERSION:-}" ] && exit 0

command -v jq &>/dev/null || exit 0

INPUT=$(cat 2>/dev/null || echo '{}')
SESSION_ID=$(echo "$INPUT" | jq -r '.conversationId // .session_id // "unknown"' 2>/dev/null)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
[ -z "$CWD" ] && CWD="$(pwd)"
PROJECT=$(basename "$CWD")

TOOL_NAME=$(echo "$INPUT" | jq -r '.tool // .tool_name // empty' 2>/dev/null)

BODY=$(jq -nc \
--argjson v 1 \
--arg agent "cline" \
--arg event "tool_complete" \
--arg session_id "$SESSION_ID" \
--arg cwd "$CWD" \
--arg project "$PROJECT" \
--arg tool_name "$TOOL_NAME" \
'{v:$v, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, tool_name:$tool_name}')

printf '\033]777;notify;%s;%s\007' "warp://cli-agent" "$BODY" > /dev/tty 2>/dev/null || true
33 changes: 33 additions & 0 deletions plugins/cline/hooks/PreToolUse.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/bash
# Warp notification on Cline pre-tool-use (permission request)

[ -z "${WARP_CLI_AGENT_PROTOCOL_VERSION:-}" ] && exit 0
[ -z "${WARP_CLIENT_VERSION:-}" ] && exit 0

command -v jq &>/dev/null || exit 0

INPUT=$(cat 2>/dev/null || echo '{}')
SESSION_ID=$(echo "$INPUT" | jq -r '.conversationId // .session_id // "unknown"' 2>/dev/null)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
[ -z "$CWD" ] && CWD="$(pwd)"
PROJECT=$(basename "$CWD")

TOOL_NAME=$(echo "$INPUT" | jq -r '.tool // .tool_name // "unknown"' 2>/dev/null)
TOOL_INPUT=$(echo "$INPUT" | jq -c '.input // .tool_input // {}' 2>/dev/null)
[ -z "$TOOL_INPUT" ] && TOOL_INPUT='{}'

SUMMARY="Wants to run $TOOL_NAME"

BODY=$(jq -nc \
--argjson v 1 \
--arg agent "cline" \
--arg event "permission_request" \
--arg session_id "$SESSION_ID" \
--arg cwd "$CWD" \
--arg project "$PROJECT" \
--arg summary "$SUMMARY" \
--arg tool_name "$TOOL_NAME" \
--argjson tool_input "$TOOL_INPUT" \
'{v:$v, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, summary:$summary, tool_name:$tool_name, tool_input:$tool_input}')

printf '\033]777;notify;%s;%s\007' "warp://cli-agent" "$BODY" > /dev/tty 2>/dev/null || true
31 changes: 31 additions & 0 deletions plugins/cline/hooks/TaskComplete.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Warp notification on Cline task complete

[ -z "${WARP_CLI_AGENT_PROTOCOL_VERSION:-}" ] && exit 0
[ -z "${WARP_CLIENT_VERSION:-}" ] && exit 0

command -v jq &>/dev/null || exit 0

INPUT=$(cat 2>/dev/null || echo '{}')
SESSION_ID=$(echo "$INPUT" | jq -r '.conversationId // .session_id // "unknown"' 2>/dev/null)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
[ -z "$CWD" ] && CWD="$(pwd)"
PROJECT=$(basename "$CWD")

QUERY=$(echo "$INPUT" | jq -r '.query // .prompt // empty' 2>/dev/null)
RESPONSE=$(echo "$INPUT" | jq -r '.response // empty' 2>/dev/null)
[ -n "$QUERY" ] && [ ${#QUERY} -gt 200 ] && QUERY="${QUERY:0:197}..."
[ -n "$RESPONSE" ] && [ ${#RESPONSE} -gt 200 ] && RESPONSE="${RESPONSE:0:197}..."

BODY=$(jq -nc \
--argjson v 1 \
--arg agent "cline" \
--arg event "stop" \
--arg session_id "$SESSION_ID" \
--arg cwd "$CWD" \
--arg project "$PROJECT" \
--arg query "$QUERY" \
--arg response "$RESPONSE" \
'{v:$v, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, query:$query, response:$response}')

printf '\033]777;notify;%s;%s\007' "warp://cli-agent" "$BODY" > /dev/tty 2>/dev/null || true
25 changes: 25 additions & 0 deletions plugins/cline/hooks/TaskError.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash
# Warp notification on Cline task error

[ -z "${WARP_CLI_AGENT_PROTOCOL_VERSION:-}" ] && exit 0
[ -z "${WARP_CLIENT_VERSION:-}" ] && exit 0

command -v jq &>/dev/null || exit 0

INPUT=$(cat 2>/dev/null || echo '{}')
SESSION_ID=$(echo "$INPUT" | jq -r '.conversationId // .session_id // "unknown"' 2>/dev/null)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
[ -z "$CWD" ] && CWD="$(pwd)"
PROJECT=$(basename "$CWD")

BODY=$(jq -nc \
--argjson v 1 \
--arg agent "cline" \
--arg event "stop" \
--arg session_id "$SESSION_ID" \
--arg cwd "$CWD" \
--arg project "$PROJECT" \
--arg summary "Task errored" \
'{v:$v, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, summary:$summary}')

printf '\033]777;notify;%s;%s\007' "warp://cli-agent" "$BODY" > /dev/tty 2>/dev/null || true
24 changes: 24 additions & 0 deletions plugins/cline/hooks/TaskStart.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
# Warp notification on Cline task start

[ -z "${WARP_CLI_AGENT_PROTOCOL_VERSION:-}" ] && exit 0
[ -z "${WARP_CLIENT_VERSION:-}" ] && exit 0

command -v jq &>/dev/null || exit 0

INPUT=$(cat 2>/dev/null || echo '{}')
SESSION_ID=$(echo "$INPUT" | jq -r '.conversationId // .session_id // "unknown"' 2>/dev/null)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
[ -z "$CWD" ] && CWD="$(pwd)"
PROJECT=$(basename "$CWD")

BODY=$(jq -nc \
--argjson v 1 \
--arg agent "cline" \
--arg event "session_start" \
--arg session_id "$SESSION_ID" \
--arg cwd "$CWD" \
--arg project "$PROJECT" \
'{v:$v, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project}')

printf '\033]777;notify;%s;%s\007' "warp://cli-agent" "$BODY" > /dev/tty 2>/dev/null || true
28 changes: 28 additions & 0 deletions plugins/cline/hooks/UserPromptSubmit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash
# Warp notification on Cline user prompt submit

[ -z "${WARP_CLI_AGENT_PROTOCOL_VERSION:-}" ] && exit 0
[ -z "${WARP_CLIENT_VERSION:-}" ] && exit 0

command -v jq &>/dev/null || exit 0

INPUT=$(cat 2>/dev/null || echo '{}')
SESSION_ID=$(echo "$INPUT" | jq -r '.conversationId // .session_id // "unknown"' 2>/dev/null)
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
[ -z "$CWD" ] && CWD="$(pwd)"
PROJECT=$(basename "$CWD")

QUERY=$(echo "$INPUT" | jq -r '.prompt // empty' 2>/dev/null)
[ -n "$QUERY" ] && [ ${#QUERY} -gt 200 ] && QUERY="${QUERY:0:197}..."

BODY=$(jq -nc \
--argjson v 1 \
--arg agent "cline" \
--arg event "prompt_submit" \
--arg session_id "$SESSION_ID" \
--arg cwd "$CWD" \
--arg project "$PROJECT" \
--arg query "$QUERY" \
'{v:$v, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, query:$query}')

printf '\033]777;notify;%s;%s\007' "warp://cli-agent" "$BODY" > /dev/tty 2>/dev/null || true