Skip to content
Merged
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
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Privacy Router provider configuration.
# shadow skill provider configuration.
#
# The vendor-neutral privacy-router skill enables providers independently.
# shadow skill enables privacy providers independently.
# Missing credentials disable only that provider; `list-providers` will still
# show the disabled reason.
#
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2026 HoudiniSkill contributors
Copyright (c) 2026 shadow skill contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
279 changes: 153 additions & 126 deletions README.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "houdiniskill",
"name": "shadow-skill",
"version": "0.1.0",
"description": "Privacy-preserving cross-chain crypto swap Agent Skill, powered by HoudiniSwap Partner API v2. Compatible with Claude Code, OpenClaw, Hermes (Nous Research), Pi (earendil-works), Cursor and any tool supporting the SKILL.md standard.",
"description": "Comprehensive privacy-preserving cross-chain crypto transfer and swap Agent Skill with provider-neutral routing. HoudiniSwap is the first bundled provider adapter. Compatible with Claude Code, OpenClaw, Hermes (Nous Research), Pi, Cursor and any tool supporting the SKILL.md standard.",
"type": "module",
"private": false,
"license": "MIT",
Expand All @@ -18,6 +18,8 @@
"pi-coding-agent",
"cursor",
"skill-md",
"shadow-skill",
"privacy-router",
"houdiniswap",
"crypto",
"defi",
Expand All @@ -29,14 +31,14 @@
"test": "node scripts/run-tests.mjs",
"test:coverage": "node scripts/run-tests.mjs --coverage",
"smoke": "node --test --test-reporter=spec skills/houdiniswap/tests/_client.test.mjs skills/houdiniswap/tests/list-chains.test.mjs skills/privacy-router/tests/registry.test.mjs skills/privacy-router/tests/router.test.mjs",
"lint:syntax": "node --check skills/houdiniswap/scripts/_client.mjs && node --check skills/privacy-router/lib/router.mjs && node --check scripts/router/list-providers.mjs"
"lint:syntax": "node --check skills/houdiniswap/scripts/_client.mjs && node --check skills/privacy-router/lib/router.mjs && node --check scripts/router/list-providers.mjs && node --check skills/shadow-skill/scripts/list-providers.mjs"
},
"repository": {
"type": "git",
"url": "git+https://github.com/REPLACE_ME/HoudiniSkill.git"
"url": "git+https://github.com/REPLACE_ME/shadow-skill.git"
},
"bugs": {
"url": "https://github.com/REPLACE_ME/HoudiniSkill/issues"
"url": "https://github.com/REPLACE_ME/shadow-skill/issues"
},
"homepage": "https://github.com/REPLACE_ME/HoudiniSkill#readme"
"homepage": "https://github.com/REPLACE_ME/shadow-skill#readme"
}
21 changes: 11 additions & 10 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<#
.SYNOPSIS
HoudiniSkill installer (Windows PowerShell).
shadow skill installer (Windows PowerShell).

.DESCRIPTION
- Verifies Node.js >= 22 is installed
- Copies .env.example to .env (preserving existing .env)
- Runs the offline smoke test suite
- Symlinks/junctions skills/houdiniswap and skills/privacy-router into the standard agent skill paths
- Symlinks/junctions skills/shadow-skill, skills/privacy-router, and skills/houdiniswap into the standard agent skill paths
(Claude Code / OpenClaw / Hermes / Pi / Cursor) when they exist on this machine
- Verifies the deployment is readable end-to-end

Expand Down Expand Up @@ -44,7 +44,7 @@ $RequiredMajor = 22
$RepoRoot = Resolve-Path (Join-Path $PSScriptRoot '..')
Set-Location $RepoRoot

$SkillNames = @('houdiniswap', 'privacy-router')
$SkillNames = @('shadow-skill', 'privacy-router', 'houdiniswap')

$AgentTargets = @(
@{ Label = 'Claude Code (global)'; Parent = (Join-Path $env:USERPROFILE '.claude\skills') },
Expand All @@ -63,7 +63,7 @@ function Write-Info($msg) { Write-Host " $msg" }
function Write-Warn($msg) { Write-Host " $msg" -ForegroundColor Yellow }
function Write-Fail($msg) { Write-Host " $msg" -ForegroundColor Red }

Write-Bold "==> HoudiniSkill installer"
Write-Bold "==> shadow skill installer"
Write-Info "Repo root: $RepoRoot"
Write-Info "Skills: $($SkillNames -join ', ')"
""
Expand Down Expand Up @@ -128,7 +128,7 @@ if (-not $LinkOnly) {
} else {
Copy-Item .env.example .env
Write-Info "Created .env from .env.example."
Write-Info "Edit .env to add HOUDINISWAP_API_KEY + HOUDINISWAP_API_SECRET (optional)."
Write-Info "Edit .env to add HOUDINISWAP_API_KEY + HOUDINISWAP_API_SECRET for the bundled HoudiniSwap provider (optional)."
}
""

Expand Down Expand Up @@ -207,8 +207,9 @@ Write-Bold "==> Project-scoped install (optional)"

cd <your-project>
New-Item -ItemType Directory -Force .claude\skills | Out-Null
New-Item -ItemType Junction -Path ".claude\skills\houdiniswap" -Target "$(Join-Path $RepoRoot 'skills\houdiniswap')"
New-Item -ItemType Junction -Path ".claude\skills\shadow-skill" -Target "$(Join-Path $RepoRoot 'skills\shadow-skill')"
New-Item -ItemType Junction -Path ".claude\skills\privacy-router" -Target "$(Join-Path $RepoRoot 'skills\privacy-router')"
New-Item -ItemType Junction -Path ".claude\skills\houdiniswap" -Target "$(Join-Path $RepoRoot 'skills\houdiniswap')"

"@ | Write-Host

Expand All @@ -234,18 +235,18 @@ if ($linkFailures -gt 0) {

What this did:

- Linked skills/houdiniswap/ and skills/privacy-router/ into every agent's global skills directory
- Linked skills/shadow-skill/, skills/privacy-router/, and skills/houdiniswap/ into every agent's global skills directory
that already exists on this machine (Claude Code / OpenClaw / Hermes /
Pi / Cursor).
- The skill auto-loads .env from the cloned repo root (via _client.mjs),
so changes to .env take effect for any agent that picks up the skill.
- The bundled HoudiniSwap provider auto-loads .env from the cloned repo root (via _client.mjs),
so changes to .env take effect for any agent that picks up shadow skill.

Next steps:

- Restart your agent (Claude Desktop / Code CLI / OpenClaw / Hermes /
Pi / Cursor) so it re-scans its skills directory.
- Try a prompt:
"Use the privacy-router skill to find a private cross-chain route for 26 USDT (eth) -> USDT (bsc)."
"Use shadow-skill to find a private cross-chain route for 26 USDT (eth) -> USDT (bsc)."

Verify connectivity to the real API (optional, no funds spent):

Expand Down
24 changes: 13 additions & 11 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env bash
# HoudiniSkill installer (POSIX)
# shadow skill installer (POSIX)
#
# - Verifies Node.js >= 22 is installed
# - Copies .env.example to .env (preserving existing .env)
# - Runs the offline smoke test suite
# - Symlinks skills/houdiniswap and skills/privacy-router into the standard agent skill paths so
# - Symlinks skills/shadow-skill, skills/privacy-router, and skills/houdiniswap into the standard agent skill paths so
# Claude Code / OpenClaw / Hermes / Pi / Cursor / Codex / etc. discover it
# - Verifies the deployment is readable end-to-end
#
Expand Down Expand Up @@ -56,7 +56,7 @@ fail() { printf '\033[31m %s\033[0m\n' "$*" >&2; }

# ---------- Source-of-truth paths ------------------------------------------

SKILL_NAMES=("houdiniswap" "privacy-router")
SKILL_NAMES=("shadow-skill" "privacy-router" "houdiniswap")

# Agent skill destinations. Format: "<label>|<dir>"
# Each entry's parent must already exist (we never auto-create $HOME/.foo
Expand All @@ -69,7 +69,7 @@ AGENT_TARGETS=(
"Cursor (global)|$HOME/.cursor/skills"
)

bold "==> HoudiniSkill installer"
bold "==> shadow skill installer"
info "Repo root: $REPO_ROOT"
info "Skills: ${SKILL_NAMES[*]}"
echo
Expand Down Expand Up @@ -134,7 +134,7 @@ EOF
else
cp .env.example .env
info "Created .env from .env.example."
info "Edit .env to add HOUDINISWAP_API_KEY + HOUDINISWAP_API_SECRET (optional)."
info "Edit .env to add HOUDINISWAP_API_KEY + HOUDINISWAP_API_SECRET for the bundled HoudiniSwap provider (optional)."
fi
echo

Expand Down Expand Up @@ -214,12 +214,14 @@ cat <<EOF

cd <your-project>
mkdir -p .claude/skills
ln -snf "$REPO_ROOT/skills/houdiniswap" .claude/skills/houdiniswap
ln -snf "$REPO_ROOT/skills/shadow-skill" .claude/skills/shadow-skill
ln -snf "$REPO_ROOT/skills/privacy-router" .claude/skills/privacy-router
ln -snf "$REPO_ROOT/skills/houdiniswap" .claude/skills/houdiniswap
# or:
mkdir -p .cursor/skills
ln -snf "$REPO_ROOT/skills/houdiniswap" .cursor/skills/houdiniswap
ln -snf "$REPO_ROOT/skills/shadow-skill" .cursor/skills/shadow-skill
ln -snf "$REPO_ROOT/skills/privacy-router" .cursor/skills/privacy-router
ln -snf "$REPO_ROOT/skills/houdiniswap" .cursor/skills/houdiniswap

EOF

Expand All @@ -246,18 +248,18 @@ cat <<'EOF'

What this did:

- Linked skills/houdiniswap/ and skills/privacy-router/ into every agent's global skills directory
- Linked skills/shadow-skill/, skills/privacy-router/, and skills/houdiniswap/ into every agent's global skills directory
that already exists on this machine (Claude Code / OpenClaw / Hermes /
Pi / Cursor).
- The skill auto-loads .env from the cloned repo root (via _client.mjs),
so changes to .env take effect for any agent that picks up the skill.
- The bundled HoudiniSwap provider auto-loads .env from the cloned repo root (via _client.mjs),
so changes to .env take effect for any agent that picks up shadow skill.

Next steps:

- Restart your agent (Claude Desktop / Code CLI / OpenClaw / Hermes /
Pi / Cursor) so it re-scans its skills directory.
- Try a prompt:
"Use the privacy-router skill to find a private cross-chain route for 26 USDT (eth) -> USDT (bsc)."
"Use shadow-skill to find a private cross-chain route for 26 USDT (eth) -> USDT (bsc)."

Verify connectivity to the real API (optional, no funds spent):

Expand Down
28 changes: 22 additions & 6 deletions scripts/verify-deployment.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#!/usr/bin/env bash
# Verify that this skill is correctly deployed for an agent.
# Verify that shadow skill is correctly deployed for an agent.
#
# Checks performed (in order):
# 1. The skill's source dir contains SKILL.md with a valid frontmatter
# 1. Each skill source dir contains SKILL.md with a valid frontmatter
# (name + description).
# 2. At least one agent skills directory contains a deployed copy/link of
# the skills at <agent-dir>/houdiniswap/SKILL.md and
# <agent-dir>/privacy-router/SKILL.md.
# the skills at <agent-dir>/shadow-skill/SKILL.md,
# <agent-dir>/privacy-router/SKILL.md, and
# <agent-dir>/houdiniswap/SKILL.md.
# 3. From the deployed location, `node` can locate the source code's .env
# via _client.mjs's loader (or via process.env). Reports the resolved
# auth mode without printing the secrets.
Expand All @@ -24,7 +25,7 @@
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SKILL_NAMES=("houdiniswap" "privacy-router")
SKILL_NAMES=("shadow-skill" "privacy-router" "houdiniswap")

QUIET=0
EXTRA_TARGETS=()
Expand Down Expand Up @@ -107,7 +108,7 @@ DEFAULT_TARGETS=(
# When --target is given we only check those; otherwise the defaults.
# Explicit targets may be either an agent skills parent directory
# (~/.claude/skills) or one concrete skill directory
# (~/.claude/skills/houdiniswap).
# (~/.claude/skills/shadow-skill).
TARGET_LABELS=()
TARGET_CHECKS=()
add_target_checks() {
Expand Down Expand Up @@ -160,6 +161,21 @@ for check in "${TARGET_CHECKS[@]}"; do
info "OK $dest_skill_md"

if [ "$skill_name" != "houdiniswap" ]; then
entrypoint_mjs="$dest/scripts/list-providers.mjs"
if [ ! -f "$entrypoint_mjs" ]; then
warn "$dest is missing scripts/list-providers.mjs (broken deployment?)"
verify_failures=$((verify_failures + 1))
continue
fi
entrypoint_out="$(
cd "$dest" && HOUDINISWAP_SKIP_DOTENV=1 node scripts/list-providers.mjs 2>&1
)" || {
fail "Entrypoint probe failed inside $dest"
fail " $entrypoint_out"
verify_failures=$((verify_failures + 1))
continue
}
info " entrypoint: OK"
continue
fi

Expand Down
9 changes: 5 additions & 4 deletions skills/houdiniswap/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ license: MIT

# HoudiniSwap Agent Skill

This skill turns natural-language swap intents into HoudiniSwap Partner API v2
calls. It is suited for privacy-conscious cross-chain swaps where the user
wants to disconnect the source wallet from the destination wallet on-chain.
This is the direct low-level HoudiniSwap provider skill for shadow skill.
Prefer `shadow-skill` when the user wants the agent to choose among providers.
Use this skill when the user explicitly needs HoudiniSwap-specific commands or
provider behavior.

## Prerequisites

Expand Down Expand Up @@ -301,7 +302,7 @@ Pure-local introspection of the chain RPC pool. Reports each registered
chain's adapter, env var name, built-in pool size, whether an override is
currently active, and the effective ordered URL list `verify-tx-onchain`
would try. No API auth needed; never makes a network call. Use it to answer
"does HoudiniSkill have a built-in RPC for chain X?" or "did my custom
"does shadow skill have a built-in RPC for chain X?" or "did my custom
override actually get picked up?". Exit `1` if the requested `--chain` isn't
registered with any adapter (the JSON output still includes a `note` hint).

Expand Down
10 changes: 6 additions & 4 deletions skills/houdiniswap/references/architecture.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Architecture

HoudiniSkill is an installable Agent Skill package for HoudiniSwap, not a
long-running service. The runtime surface is a set of small Node.js CLI scripts
that an agent can call after reading `SKILL.md`.
shadow skill is an installable Agent Skill package for privacy-preserving
transfers and cross-chain swaps, not a long-running service. HoudiniSwap is the
first bundled provider adapter. The runtime surface is a set of small Node.js
CLI scripts that an agent can call after reading `SKILL.md`.

## System Overview

Expand Down Expand Up @@ -35,6 +36,7 @@ validation, JSON output, and exit codes.
flowchart LR
subgraph Docs["Docs and agent entrypoint"]
R[README.md]
SS[skills/shadow-skill/SKILL.md]
S[skills/houdiniswap/SKILL.md]
Ref[references/*.md]
end
Expand Down Expand Up @@ -131,7 +133,7 @@ The adapter layer implements the chain-specific mechanics:
sequenceDiagram
participant User
participant Agent
participant CLI as HoudiniSkill CLI
participant CLI as shadow skill CLI
participant API as HoudiniSwap API
participant Chain as Chain RPC/REST

Expand Down
2 changes: 1 addition & 1 deletion skills/houdiniswap/references/status-codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ This applies to every script in `skills/houdiniswap/scripts/`.
| `2` | Usage / argument error | Missing required flag, bad value, malformed input |
| `3` | Network error | Timeout, connection refused, abort |
| `4` | Auth not configured | `AuthMissingError` from `_client.mjs` |
| `70` | Internal error (unexpected) | Anything not derived from `HoudiniSkillError` |
| `70` | Internal error (unexpected) | Anything not derived from `ShadowSkillError` |

## How `wait-for-order` decides when to stop

Expand Down
Loading
Loading