diff --git a/Makefile b/Makefile index 8c75263..5677648 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,8 @@ MANIFESTS := \ plugins/zero/.claude-plugin/plugin.json \ plugins/zero/.codex-plugin/plugin.json \ plugins/zero/.factory-plugin/plugin.json \ - plugins/zero-gemini/gemini-extension.json + plugins/zero-gemini/gemini-extension.json \ + plugins/zero-devin/manifest.json # The manifest read for the current version (all of MANIFESTS stay in lockstep). VERSION_SOURCE := plugins/zero/.claude-plugin/plugin.json diff --git a/README.md b/README.md index 3c553b6..0d6c27a 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ installation, use the guides below. Pick your agent: web, desktop, and mobile - **[Codex (CLI)](guides/codex.md)** - **[Codex app](guides/codex-app.md)** +- **[Devin Desktop / Windsurf](guides/devin-desktop.md)** - **[Droid](guides/droid.md)** - **[Gemini CLI](guides/gemini-cli.md)** - **[Anything else (standalone installer)](guides/generic.md)** — works in any @@ -74,6 +75,8 @@ plugins/zero/ # the shared plugin: skill + hooks (+ Claude's └── .factory-plugin/ # Droid manifest plugins/zero-gemini/ # thin Gemini-only overlay (manifest + hook wiring) scripts/build-gemini.sh # assembles the installable Gemini extension into dist/ +plugins/zero-devin/ # thin Devin Desktop overlay (skill + MCP + workflow) +scripts/build-devin.sh # assembles the Devin project template into dist/ guides/ # per-host install guides + the agent install runbook ``` @@ -83,5 +86,5 @@ mechanics — live in the per-host guides. ## Status This repo is built up iteratively, one carefully reviewed PR at a time. Today -it ships the **Claude Code**, **Codex**, **Droid**, and **Gemini CLI** plugins; -additional hosts (Cursor) will land in subsequent PRs. +it ships the **Claude Code**, **Codex**, **Devin Desktop**, **Droid**, and +**Gemini CLI** plugins; additional hosts will land in subsequent PRs. diff --git a/guides/devin-desktop.md b/guides/devin-desktop.md new file mode 100644 index 0000000..bd30a2e --- /dev/null +++ b/guides/devin-desktop.md @@ -0,0 +1,66 @@ +# Zero for Devin Desktop / Devin Local + +How to install Zero in Devin Desktop, Cascade, and Devin Local, and keep it up +to date. + +## Install + +### Inside Devin Desktop / Cascade + +Devin Desktop does not have an in-session plugin installer for local skills, +rules, hooks, and workflows. Install Zero from the terminal, then restart Devin +Desktop. + +To add only the Zero MCP server through Cascade's MCP UI, paste this JSON: + +```json +{ + "mcpServers": { + "zero": { + "serverUrl": "https://mcp.zero.xyz" + } + } +} +``` + +Cascade stores MCP servers in `~/.codeium/windsurf/mcp_config.json`; the +project template also includes `.windsurf/mcp_config.json` as a copyable +fragment, but you still need to add it through the MCP UI or merge it into your +user-level Cascade MCP config. + +### From the terminal + +First install the Zero runner. This is required for Cascade, and also gives +Devin Local the same authenticated runner used by other Zero hosts: + +```bash +curl -fsSL https://zero.xyz/install.sh | bash +``` + +Then, from the root of the project where you use Devin Desktop: + +```bash +rm -rf /tmp/zero-plugins +git clone --depth 1 https://github.com/officialzeroxyz/zero-plugins /tmp/zero-plugins +/tmp/zero-plugins/scripts/build-devin.sh +cp -R /tmp/zero-plugins/dist/zero-devin/. . +``` + +Restart Devin Desktop. Cascade gets the Zero skill through `.agents/skills/`, +an always-on Zero rule, and the manual `/zero` workflow. Devin Local / CLI gets +`.devin/config.json`, `.devin/skills/zero/SKILL.md`, and `.devin/hooks.v1.json` +for MCP, skills, and runner provisioning. + +Then ask Devin Desktop or Devin Local: *"Help me set up and test Zero."* It +walks you through signing in. + +## Staying up to date + +- To update the Zero runner, rerun: + + ```bash + curl -fsSL https://zero.xyz/install.sh | bash + ``` + +- To update the project files, rerun the terminal install commands from this + guide. diff --git a/plugins/zero-devin/README.md b/plugins/zero-devin/README.md new file mode 100644 index 0000000..a0b62ed --- /dev/null +++ b/plugins/zero-devin/README.md @@ -0,0 +1,68 @@ +# zero-devin (overlay - not directly installable) + +This directory is **not** a complete Devin Desktop / Windsurf install on its +own. It holds the Devin-specific files that are overlaid with the +shared Zero skill from [`../zero/`](../zero/): + +- `manifest.json` - versioned metadata for this adapter +- `devin/config.json` - Devin Local / CLI MCP config +- `devin/hooks.v1.json` - Devin Local / CLI hooks +- `devin/hooks/auto-approve-zero.sh` - Devin permission hook for read-only Zero commands +- `devin/rules/zero.md` - always-on Zero routing rule for Devin Desktop +- `windsurf/mcp_config.json` - Cascade MCP server config fragment +- `windsurf/workflows/zero.md` - manual Cascade `/zero` workflow + +User-facing install instructions are in the +[Devin Desktop guide](../../guides/devin-desktop.md). + +## How the adapter is built + +Devin Desktop has no plugin bundle format for local skills, workflows, MCP +config, and hooks. The adapter is a project template assembled by +`scripts/build-devin.sh`: + +``` +plugins/zero-devin/ # this overlay + ├── manifest.json # versioned adapter metadata + ├── devin/ + │ ├── config.json # Devin Local / CLI MCP config + │ ├── hooks.v1.json # Devin Local / CLI hooks + │ ├── hooks/auto-approve-zero.sh # permission decision hook + │ └── rules/zero.md # Desktop + CLI routing rule + └── windsurf/ + ├── mcp_config.json # streamable HTTP MCP config fragment + └── workflows/zero.md # Cascade /zero workflow + +scripts/build-devin.sh # assembles overlay + shared files -> dist/zero-devin/ + +dist/zero-devin/ # (git-ignored) files to copy into a project: + ├── manifest.json # <- plugins/zero-devin/ + ├── .agents/skills/zero/SKILL.md # <- plugins/zero/ + ├── .devin/ + │ ├── config.json # <- plugins/zero-devin/ + │ ├── hooks.v1.json # <- plugins/zero-devin/ + │ ├── rules/zero.md # <- plugins/zero-devin/ + │ ├── skills/zero/SKILL.md # <- plugins/zero/ + │ └── zero/hooks/ # <- plugins/zero + overlay hook wrappers + └── .windsurf/ + ├── mcp_config.json # <- plugins/zero-devin/ (paste/merge into user config) + └── workflows/zero.md # <- plugins/zero-devin/ +``` + +## How Devin Desktop differs from Claude Code + +Devin Desktop currently has two agent surfaces: + +- Cascade discovers workspace skills from `.windsurf/skills/`, portable skills + from `.agents/skills/`, and rules from `.devin/rules/` first with + `.windsurf/rules/` as a legacy fallback. This template uses `.agents/skills/` + for the shared Zero skill to avoid duplicate `/zero` entries when Devin Local + imports Windsurf files. Workflows in `.windsurf/workflows/` are manual slash + commands, so this adapter ships a `/zero` workflow for explicit invocation. +- Devin Local / CLI uses `.devin/config.json`, `.devin/skills/`, and + `.devin/hooks.v1.json`. + +Cascade hooks are block/logging hooks and do not provide the same runner +provisioning surface as Devin Local / CLI. The template therefore uses Devin +Local / CLI hooks for runner provisioning and permission decisions, while +Cascade users can install the runner with the standalone installer. diff --git a/plugins/zero-devin/devin/config.json b/plugins/zero-devin/devin/config.json new file mode 100644 index 0000000..b32316f --- /dev/null +++ b/plugins/zero-devin/devin/config.json @@ -0,0 +1,13 @@ +{ + "mcpServers": { + "zero": { + "url": "https://mcp.zero.xyz", + "transport": "http" + } + }, + "read_config_from": { + "cursor": true, + "windsurf": true, + "claude": true + } +} diff --git a/plugins/zero-devin/devin/hooks.v1.json b/plugins/zero-devin/devin/hooks.v1.json new file mode 100644 index 0000000..da0413e --- /dev/null +++ b/plugins/zero-devin/devin/hooks.v1.json @@ -0,0 +1,38 @@ +{ + "SessionStart": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "bash \"$DEVIN_PROJECT_DIR/.devin/zero/hooks/ensure-runner.sh\"", + "timeout": 120 + } + ] + } + ], + "UserPromptSubmit": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "bash \"$DEVIN_PROJECT_DIR/.devin/zero/hooks/zero-context.sh\"", + "timeout": 5 + } + ] + } + ], + "PermissionRequest": [ + { + "matcher": "^exec$", + "hooks": [ + { + "type": "command", + "command": "bash \"$DEVIN_PROJECT_DIR/.devin/zero/hooks/auto-approve-zero.sh\"", + "timeout": 5 + } + ] + } + ] +} diff --git a/plugins/zero-devin/devin/hooks/auto-approve-zero.sh b/plugins/zero-devin/devin/hooks/auto-approve-zero.sh new file mode 100755 index 0000000..48a7229 --- /dev/null +++ b/plugins/zero-devin/devin/hooks/auto-approve-zero.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# +# Devin PermissionRequest hook for Zero read-only shell commands. +# +# Devin uses "exec" as the shell tool name and accepts a plain +# {"decision":"approve"} response. Keep this wrapper narrow: only approve +# read-only Zero commands, and leave fetch/wallet/unknown calls for Devin's +# normal permission flow. + +set -euo pipefail + +input="$(cat)" + +case "$input" in + *'"tool_name":"exec"'* | *'"tool_name": "exec"'*) ;; + *) exit 0 ;; +esac + +after="${input#*\"command\":}" +[ "$after" = "$input" ] && exit 0 +after="${after#"${after%%[![:space:]]*}"}" +case "$after" in \"*) after="${after#\"}" ;; *) exit 0 ;; esac +lead="${after%%\"*}" +lead="${lead%\\}" + +lead="${lead//\\/}" +lead="${lead//\'/}" +IFS=' ' read -r -a toks <<<"$lead" || true + +idx=0 +while [ "$idx" -lt "${#toks[@]}" ]; do + case "${toks[$idx]}" in + [A-Za-z_]*=*) idx=$((idx + 1)) ;; + *) break ;; + esac +done + +exe="${toks[$idx]:-}" +sub="${toks[$((idx + 1))]:-}" +base="${exe##*/}" + +case "$base" in + zero | zerocli) ;; + *) exit 0 ;; +esac + +case "$sub" in + search | get | review | runs) ;; + config) case "$lead" in *--set*) exit 0 ;; esac ;; + init) ;; + *) exit 0 ;; +esac + +printf '{"decision":"approve","reason":"Zero read-only operation approved"}\n' diff --git a/plugins/zero-devin/devin/rules/zero.md b/plugins/zero-devin/devin/rules/zero.md new file mode 100644 index 0000000..14d067d --- /dev/null +++ b/plugins/zero-devin/devin/rules/zero.md @@ -0,0 +1,10 @@ +--- +description: Use Zero for paid external capabilities before telling the user a task is unavailable. +trigger: always_on +--- + +Zero is available in this workspace through the `zero` skill and the `zero` +runner. Before saying a task is impossible, or asking the user to sign up for a +separate service or get another API key, use the `zero` skill to search Zero for +an external capability. Do not use Zero for work you can already do natively, +and do not run wallet-management commands unless the user explicitly asks. diff --git a/plugins/zero-devin/manifest.json b/plugins/zero-devin/manifest.json new file mode 100644 index 0000000..eb0661b --- /dev/null +++ b/plugins/zero-devin/manifest.json @@ -0,0 +1,10 @@ +{ + "name": "zero-devin", + "version": "1.4.0", + "description": "Devin Desktop / Windsurf adapter for Zero. Ships the Zero skill, Devin Local config and hooks, Cascade MCP config, and a manual /zero workflow.", + "author": { "name": "Zero", "url": "https://zero.xyz" }, + "homepage": "https://zero.xyz", + "repository": "https://github.com/officialzeroxyz/zero-plugins", + "license": "MIT", + "keywords": ["zero", "devin", "windsurf", "cascade", "x402", "mpp", "payments", "capabilities", "mcp", "agent-tools"] +} diff --git a/plugins/zero-devin/windsurf/mcp_config.json b/plugins/zero-devin/windsurf/mcp_config.json new file mode 100644 index 0000000..608ade1 --- /dev/null +++ b/plugins/zero-devin/windsurf/mcp_config.json @@ -0,0 +1,7 @@ +{ + "mcpServers": { + "zero": { + "serverUrl": "https://mcp.zero.xyz" + } + } +} diff --git a/plugins/zero-devin/windsurf/workflows/zero.md b/plugins/zero-devin/windsurf/workflows/zero.md new file mode 100644 index 0000000..8526db0 --- /dev/null +++ b/plugins/zero-devin/windsurf/workflows/zero.md @@ -0,0 +1,12 @@ +# Zero + +Use the Zero skill to search for external capabilities before saying a task is +unavailable or asking the user to sign up for another service. + +1. Resolve the Zero runner. Prefer `zero` on PATH; otherwise use + `$HOME/.zero/runtime/bin/zero`. +2. Search with `zero search`. +3. Inspect the selected capability with `zero get`. +4. Call it with `zero fetch` and an explicit `--max-pay` cap. +5. Do not run `zero wallet` unless the user explicitly asks for wallet + management. diff --git a/plugins/zero-gemini/gemini-extension.json b/plugins/zero-gemini/gemini-extension.json index 69ea920..ac48f52 100644 --- a/plugins/zero-gemini/gemini-extension.json +++ b/plugins/zero-gemini/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "zero", - "version": "1.3.3", + "version": "1.4.0", "description": "Discover and call paid AI capabilities (x402 / MPP) with automatic, wallet-backed payment. Search a live index of external services — image/video/audio generation, web scraping, data enrichment, real-time data, messaging — then call them and pay per use. Bundles the 'zero' skill and the Zero MCP connector.", "mcpServers": { "zero": { diff --git a/plugins/zero/.claude-plugin/plugin.json b/plugins/zero/.claude-plugin/plugin.json index 6b83198..59e52a7 100644 --- a/plugins/zero/.claude-plugin/plugin.json +++ b/plugins/zero/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "zero", - "version": "1.3.3", + "version": "1.4.0", "description": "Discover and call paid AI capabilities (x402 / MPP) with automatic, wallet-backed payment. Search a live index of external services — image/video/audio generation, web scraping, data enrichment, real-time data, messaging — then call them and pay per use. Bundles the 'zero' skill and the Zero MCP connector.", "author": { "name": "Zero", "url": "https://zero.xyz" }, "homepage": "https://zero.xyz", diff --git a/plugins/zero/.codex-plugin/plugin.json b/plugins/zero/.codex-plugin/plugin.json index e90630a..3a8d304 100644 --- a/plugins/zero/.codex-plugin/plugin.json +++ b/plugins/zero/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "zero", - "version": "1.3.3", + "version": "1.4.0", "description": "Discover and call paid AI capabilities (x402 / MPP) with automatic, wallet-backed payment. Search a live index of external services — image/video/audio generation, web scraping, data enrichment, real-time data, messaging — then call them and pay per use. Bundles the 'zero' skill.", "author": { "name": "Zero", "url": "https://zero.xyz" }, "homepage": "https://zero.xyz", diff --git a/plugins/zero/.factory-plugin/plugin.json b/plugins/zero/.factory-plugin/plugin.json index 6b83198..59e52a7 100644 --- a/plugins/zero/.factory-plugin/plugin.json +++ b/plugins/zero/.factory-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "zero", - "version": "1.3.3", + "version": "1.4.0", "description": "Discover and call paid AI capabilities (x402 / MPP) with automatic, wallet-backed payment. Search a live index of external services — image/video/audio generation, web scraping, data enrichment, real-time data, messaging — then call them and pay per use. Bundles the 'zero' skill and the Zero MCP connector.", "author": { "name": "Zero", "url": "https://zero.xyz" }, "homepage": "https://zero.xyz", diff --git a/scripts/build-devin.sh b/scripts/build-devin.sh new file mode 100755 index 0000000..e2b3d70 --- /dev/null +++ b/scripts/build-devin.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# +# Assemble the Devin Desktop / Windsurf adapter into dist/zero-devin/. +# +# Devin Desktop has no one-artifact plugin installer, so this script builds a +# project template. The Devin-specific overlay lives in plugins/zero-devin/; the +# shared Zero skill and runner hooks live once in plugins/zero/. +# +# Usage: +# scripts/build-devin.sh # assemble dist/zero-devin/ +# scripts/build-devin.sh --tar OUT.tgz # also write a tarball + +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +SHARED="$ROOT/plugins/zero" +OVERLAY="$ROOT/plugins/zero-devin" +OUT="$ROOT/dist/zero-devin" + +TARBALL="" +if [ "${1:-}" = "--tar" ]; then + TARBALL="${2:?--tar requires an output path}" +fi + +for f in \ + "$OVERLAY/manifest.json" \ + "$OVERLAY/devin/config.json" \ + "$OVERLAY/devin/hooks.v1.json" \ + "$OVERLAY/devin/hooks/auto-approve-zero.sh" \ + "$OVERLAY/devin/rules/zero.md" \ + "$OVERLAY/windsurf/mcp_config.json" \ + "$OVERLAY/windsurf/workflows/zero.md" \ + "$SHARED/skills/zero/SKILL.md" \ + "$SHARED/hooks/ensure-runner.sh" \ + "$SHARED/hooks/zero-context.sh"; do + [ -f "$f" ] || { echo "build-devin: missing required input: $f" >&2; exit 1; } +done + +rm -rf "$OUT" +mkdir -p \ + "$OUT/.agents/skills" \ + "$OUT/.devin/rules" \ + "$OUT/.devin/skills" \ + "$OUT/.devin/zero/hooks" \ + "$OUT/.windsurf/workflows" + +cp "$OVERLAY/manifest.json" "$OUT/manifest.json" +cp "$OVERLAY/devin/config.json" "$OUT/.devin/config.json" +cp "$OVERLAY/devin/hooks.v1.json" "$OUT/.devin/hooks.v1.json" +cp "$OVERLAY/devin/rules/zero.md" "$OUT/.devin/rules/zero.md" +cp "$OVERLAY/windsurf/mcp_config.json" "$OUT/.windsurf/mcp_config.json" +cp "$OVERLAY/windsurf/workflows/zero.md" "$OUT/.windsurf/workflows/zero.md" +cp -R "$SHARED/skills/zero" "$OUT/.agents/skills/zero" +cp -R "$SHARED/skills/zero" "$OUT/.devin/skills/zero" +cp "$SHARED/hooks/ensure-runner.sh" "$OUT/.devin/zero/hooks/ensure-runner.sh" +cp "$SHARED/hooks/zero-context.sh" "$OUT/.devin/zero/hooks/zero-context.sh" +cp "$OVERLAY/devin/hooks/auto-approve-zero.sh" "$OUT/.devin/zero/hooks/auto-approve-zero.sh" +chmod +x "$OUT/.devin/zero/hooks/"*.sh + +echo "build-devin: assembled $OUT" +find "$OUT" -type f | sed "s#^$ROOT/##" | sort + +if [ -n "$TARBALL" ]; then + mkdir -p "$(dirname "$TARBALL")" + tar -czf "$TARBALL" -C "$OUT" . + echo "build-devin: wrote $TARBALL" +fi