Skip to content
Closed
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
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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-crush/manifest.json

# The manifest read for the current version (all of MANIFESTS stay in lockstep).
VERSION_SOURCE := plugins/zero/.claude-plugin/plugin.json
Expand Down
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)**
- **[Crush](guides/crush.md)**
- **[Droid](guides/droid.md)**
- **[Gemini CLI](guides/gemini-cli.md)**
- **[Anything else (standalone installer)](guides/generic.md)** — works in any
Expand All @@ -37,18 +38,19 @@ you in and takes it from there.

## What the plugin does

Every install ships the same three ingredients:
Every install ships the same core skill and then the host-specific integration
points that host supports:

- **The `zero` skill** — teaches the agent how to search Zero, call a
capability, and review the result.
- **Hooks** — keep the Zero CLI runner provisioned and up to date, and remind
the agent that Zero is available.
- **Hooks, when supported** — keep the Zero CLI runner provisioned and up to
date, and remind the agent that Zero is available.
- **The Zero MCP connector** — capability search and account status over MCP,
on hosts that load it.

All hosts share one login (`~/.zero/config.json`) and one runtime
(`~/.zero/runtime`) — sign in once per machine. Updates are automatic; the
per-agent guides have the details.
(`~/.zero/runtime`) — sign in once per machine. Hosts with hooks can update
automatically; the per-agent guides have the details.

## How this repo is organized

Expand All @@ -63,7 +65,8 @@ plugins/zero/ # the shared plugin: skill + hooks (+ Claude's
├── .codex-plugin/ # Codex manifest
└── .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-crush/ # thin Crush overlay (skills + config templates)
scripts/build-*.sh # assemble host-specific install bundles into dist/
guides/ # per-host install guides + the agent install runbook
```

Expand All @@ -73,5 +76,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**, **Crush**, **Droid**, and
**Gemini CLI** plugins; additional hosts will land in subsequent PRs.
46 changes: 46 additions & 0 deletions guides/crush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Zero for Crush

How to install Zero in Crush and keep it up to date.

## Install

### Inside Crush

Install the Zero runtime once:

```bash
curl -fsSL https://zero.xyz/install.sh | bash
```

Build the Crush adapter from this repository, then copy it into your project:

```bash
scripts/build-crush.sh
cp -R dist/zero-crush/. /path/to/your/project/
```

Merge `dist/zero-crush/crush/crush.zero.json` into your project `crush.json`,
then restart Crush. Use the command palette (`Ctrl+P`) and choose
`project:zero`, or ask Crush: *"Help me set up and test Zero."*

### From the terminal

```bash
curl -fsSL https://zero.xyz/install.sh | bash
scripts/build-crush.sh
cp -R dist/zero-crush/. /path/to/your/project/
```

Merge `dist/zero-crush/crush/crush.zero.json` into `crush.json` or
`~/.config/crush/crush.json`, then restart Crush.

## Staying up to date

Crush does not currently provide session-start hooks for this adapter. To
update Zero, re-run:

```bash
curl -fsSL https://zero.xyz/install.sh | bash
scripts/build-crush.sh
cp -R dist/zero-crush/. /path/to/your/project/
```
33 changes: 33 additions & 0 deletions plugins/zero-crush/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# zero-crush (overlay - not directly installable)

This directory is **not** a complete Crush install on its own. It holds the
Crush-specific files:

- `manifest.json` - versioned release marker for this adapter
- `crush/crush.zero.json` - mergeable `crush.json` fragment for Zero MCP and
the PreToolUse hook
- `crush/hooks/zero-pre-tool-use.sh` - hook script for Zero command gating

The `zero` skill is copied from [`../zero/`](../zero/) during packaging with
Crush frontmatter added (`user-invocable: true`).

## How the adapter is built

Crush reads project skills from `.crush/skills/` and `.agents/skills/`. It does
not have SessionStart or UserPromptSubmit hooks yet, but it can run
`PreToolUse` hooks from `crush.json`.

`scripts/build-crush.sh` assembles those pieces into `dist/zero-crush/`:

```
dist/zero-crush/
├── .agents/skills/zero/SKILL.md
├── .crush/hooks/zero-pre-tool-use.sh
├── .crush/skills/zero/SKILL.md
├── crush/crush.zero.json
└── manifest.json
```

The hook auto-approves read-only Zero runner commands and blocks `zero fetch`
commands that do not include an explicit `--max-pay` cap. Spending commands
with a cap still fall through to Crush's normal permission flow.
20 changes: 20 additions & 0 deletions plugins/zero-crush/crush/crush.zero.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://charm.land/crush.json",
"mcp": {
"zero": {
"type": "http",
"url": "https://mcp.zero.xyz",
"timeout": 120,
"disabled": false
}
},
"hooks": {
"PreToolUse": [
{
"name": "zero-command-policy",
"matcher": "^bash$",
"command": "./.crush/hooks/zero-pre-tool-use.sh"
}
]
}
}
65 changes: 65 additions & 0 deletions plugins/zero-crush/crush/hooks/zero-pre-tool-use.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
#
# Crush PreToolUse hook for Zero runner commands.
# - Allow read-only Zero commands.
# - Block zero fetch without an explicit --max-pay cap.
# - Leave spending commands and unknown commands to Crush's normal permission flow.

set -euo pipefail

cmd="${CRUSH_TOOL_INPUT_COMMAND:-}"

context_json='"Zero is available through the zero skill and runner. Use search, inspect, fetch with an explicit --max-pay cap, then review successful paid runs when appropriate."'

trimmed="${cmd#"${cmd%%[![:space:]]*}"}"
read -r -a toks <<<"$trimmed" || true

idx=0
while [ "$idx" -lt "${#toks[@]}" ]; do
case "${toks[$idx]}" in
[A-Za-z_][A-Za-z0-9_]*=*) idx=$((idx + 1)) ;;
*) break ;;
esac
done

exe="${toks[$idx]:-}"
sub="${toks[$((idx + 1))]:-}"
base="${exe##*/}"

case "$base" in
zero | zerocli) ;;
*)
printf '{"context":%s}\n' "$context_json"
exit 0
;;
esac

case "$sub" in
search | get | runs | review)
printf '{"decision":"allow","context":%s}\n' "$context_json"
;;
auth)
if [ "${toks[$((idx + 2))]:-}" = "whoami" ]; then
printf '{"decision":"allow","context":%s}\n' "$context_json"
else
printf '{"context":%s}\n' "$context_json"
fi
;;
config)
case "$cmd" in
*"--set"*) printf '{"context":%s}\n' "$context_json" ;;
*) printf '{"decision":"allow","context":%s}\n' "$context_json" ;;
esac
;;
fetch)
case "$cmd" in
*"--max-pay"*) printf '{"context":%s}\n' "$context_json" ;;
*)
printf '{"decision":"deny","reason":"Zero fetch commands must include an explicit --max-pay cap.","context":%s}\n' "$context_json"
;;
esac
;;
*)
printf '{"context":%s}\n' "$context_json"
;;
esac
8 changes: 8 additions & 0 deletions plugins/zero-crush/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "zero-crush",
"version": "1.4.0",
"description": "Crush adapter for Zero: project skills, MCP config fragment, and PreToolUse hook.",
"homepage": "https://zero.xyz",
"repository": "https://github.com/officialzeroxyz/zero-plugins",
"license": "MIT"
}
2 changes: 1 addition & 1 deletion plugins/zero-gemini/gemini-extension.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
2 changes: 1 addition & 1 deletion plugins/zero/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion plugins/zero/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion plugins/zero/.factory-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
66 changes: 66 additions & 0 deletions scripts/build-crush.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
#
# Assemble the Crush adapter into dist/zero-crush/.
#
# Usage:
# scripts/build-crush.sh # assemble dist/zero-crush/
# scripts/build-crush.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-crush"
OUT="$ROOT/dist/zero-crush"

TARBALL=""
if [ "${1:-}" = "--tar" ]; then
TARBALL="${2:?--tar requires an output path}"
fi

for f in \
"$OVERLAY/manifest.json" \
"$OVERLAY/crush/crush.zero.json" \
"$OVERLAY/crush/hooks/zero-pre-tool-use.sh" \
"$SHARED/skills/zero/SKILL.md"; do
[ -f "$f" ] || { echo "build-crush: missing required input: $f" >&2; exit 1; }
done

rm -rf "$OUT"
mkdir -p \
"$OUT/.crush/skills/zero" \
"$OUT/.crush/hooks" \
"$OUT/.agents/skills/zero" \
"$OUT/crush"

write_crush_skill() {
local dest="$1"
cat > "$dest" <<'HEADER'
---
name: zero
description: Use Zero for external capabilities.
user-invocable: true
---
HEADER
awk '
NR == 1 && $0 == "---" { in_frontmatter = 1; next }
in_frontmatter && $0 == "---" { in_frontmatter = 0; next }
!in_frontmatter { print }
' "$SHARED/skills/zero/SKILL.md" >> "$dest"
}

cp "$OVERLAY/manifest.json" "$OUT/manifest.json"
cp "$OVERLAY/crush/crush.zero.json" "$OUT/crush/crush.zero.json"
cp "$OVERLAY/crush/hooks/zero-pre-tool-use.sh" "$OUT/.crush/hooks/zero-pre-tool-use.sh"
write_crush_skill "$OUT/.crush/skills/zero/SKILL.md"
write_crush_skill "$OUT/.agents/skills/zero/SKILL.md"
chmod +x "$OUT/.crush/hooks/zero-pre-tool-use.sh"

echo "build-crush: 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-crush: wrote $TARBALL"
fi
Loading