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
88 changes: 86 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,86 @@
# splat-cli-releases
Public release assets for the Splat CLI
# Splat CLI Releases

This repo hosts the public release assets for the Splat CLI.

## Purpose

The source code for the CLI and backend remains private in:

- `protastudios/splat-trading-backend`

This repo is public so installers and Homebrew can fetch release assets without needing access to the private source repository.

## Install

The installer script lives in this public repo and downloads release assets from this public repo:

```bash
curl -fsSL https://raw.githubusercontent.com/protastudios/splat-cli-releases/main/install-release.sh | bash
```

## Homebrew

The Homebrew formula in `protastudios/homebrew-tap` points at the GitHub releases published here.

Target install command:

```bash
brew install protastudios/tap/splat
```

## Agent Skills

This repo also publishes agent-facing guidance for the Splat CLI:

- Codex skill: `skills/splat-cli/SKILL.md`
- Claude Code command: `claude/commands/splat.md`
- Claude Code memory snippet: `claude/CLAUDE.md.snippet`

The Codex skill teaches agents to inspect the live CLI surface with `splat --json commands` and to use staged/explicit confirmation flows for trading, signing, bridge, reward, token, and grant operations.

Install both Codex and Claude Code guidance with npm:

```bash
npx @splat/agent-skills install
```

Install only one target:

```bash
npx @splat/agent-skills install --codex
npx @splat/agent-skills install --claude
```

After installation, restart Codex or Claude Code so the new skill or command is discovered.

The no-npm fallback is:

```bash
curl -fsSL https://raw.githubusercontent.com/protastudios/splat-cli-releases/main/install-agent-skills.sh | bash
```

Fallback install for only one target:

```bash
curl -fsSL https://raw.githubusercontent.com/protastudios/splat-cli-releases/main/install-agent-skills.sh | SPLAT_INSTALL_CLAUDE=0 bash
curl -fsSL https://raw.githubusercontent.com/protastudios/splat-cli-releases/main/install-agent-skills.sh | SPLAT_INSTALL_CODEX=0 bash
```

Publish the npm installer after logging into an npm account with access to the `@splat` scope:

```bash
npm test
npm pack --dry-run
npm publish --access public
```

## Contents

Tagged releases in this repo are expected to include:

- macOS tarballs
- Linux tarballs
- Windows zip archives
- `checksums.txt`

The backend release workflow publishes those assets here automatically when distribution secrets are configured.
150 changes: 150 additions & 0 deletions bin/install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/usr/bin/env node
"use strict";

const fs = require("fs");
const os = require("os");
const path = require("path");

const packageRoot = path.resolve(__dirname, "..");

function printHelp() {
console.log(`Usage:
splat-agent-skills install [options]
splat-agent-skills --help

Options:
--codex Install only the Codex skill
--claude Install only the Claude Code command/snippet
--codex-home <path> Override Codex home directory
--claude-home <path> Override Claude home directory
--dry-run Print planned file operations without writing

Environment:
CODEX_HOME Codex home directory, default ~/.codex
CLAUDE_HOME Claude home directory, default ~/.claude
`);
}

function parseArgs(argv) {
const options = {
command: "install",
codex: false,
claude: false,
codexHome: process.env.CODEX_HOME || path.join(os.homedir(), ".codex"),
claudeHome: process.env.CLAUDE_HOME || path.join(os.homedir(), ".claude"),
dryRun: false,
};

const args = [...argv];
if (args[0] && !args[0].startsWith("-")) {
options.command = args.shift();
}

for (let index = 0; index < args.length; index += 1) {
const arg = args[index];

if (arg === "--help" || arg === "-h") {
options.command = "help";
} else if (arg === "--codex") {
options.codex = true;
} else if (arg === "--claude") {
options.claude = true;
} else if (arg === "--dry-run") {
options.dryRun = true;
} else if (arg === "--codex-home") {
options.codexHome = readValue(args, index, arg);
index += 1;
} else if (arg === "--claude-home") {
options.claudeHome = readValue(args, index, arg);
index += 1;
} else {
throw new Error(`Unknown option: ${arg}`);
}
}

if (!options.codex && !options.claude) {
options.codex = true;
options.claude = true;
}

return options;
}

function readValue(args, index, flag) {
const value = args[index + 1];
if (!value || value.startsWith("-")) {
throw new Error(`${flag} requires a path value`);
}
return path.resolve(value);
}

function copyDirectory(source, destination, dryRun) {
if (dryRun) {
console.log(`[dry-run] copy directory ${source} -> ${destination}`);
return;
}

fs.rmSync(destination, { recursive: true, force: true });
fs.mkdirSync(path.dirname(destination), { recursive: true });
fs.cpSync(source, destination, { recursive: true });
}

function copyFile(source, destination, dryRun) {
if (dryRun) {
console.log(`[dry-run] copy file ${source} -> ${destination}`);
return;
}

fs.mkdirSync(path.dirname(destination), { recursive: true });
fs.copyFileSync(source, destination);
}

function installCodex(options) {
const source = path.join(packageRoot, "skills", "splat-cli");
const destination = path.join(options.codexHome, "skills", "splat-cli");

copyDirectory(source, destination, options.dryRun);
console.log(`Installed Codex skill to ${destination}`);
}

function installClaude(options) {
const commandSource = path.join(packageRoot, "claude", "commands", "splat.md");
const snippetSource = path.join(packageRoot, "claude", "CLAUDE.md.snippet");
const commandDestination = path.join(options.claudeHome, "commands", "splat.md");
const snippetDestination = path.join(options.claudeHome, "SPLAT_CLAUDE.md");

copyFile(commandSource, commandDestination, options.dryRun);
copyFile(snippetSource, snippetDestination, options.dryRun);
console.log(`Installed Claude command to ${commandDestination}`);
console.log(`Installed Claude memory snippet to ${snippetDestination}`);
}

function main() {
const options = parseArgs(process.argv.slice(2));

if (options.command === "help") {
printHelp();
return;
}

if (options.command !== "install") {
throw new Error(`Unknown command: ${options.command}`);
}

if (options.codex) {
installCodex(options);
}

if (options.claude) {
installClaude(options);
}

console.log("Done. Restart Codex or Claude Code if the new guidance is not discovered immediately.");
}

try {
main();
} catch (error) {
console.error(error instanceof Error ? error.message : String(error));
process.exit(1);
}
10 changes: 10 additions & 0 deletions claude/CLAUDE.md.snippet
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Splat CLI

When working with Splat CLI tasks, inspect the live command surface before giving detailed command advice:

```bash
splat --json commands
```

Use `splat doctor`, `splat auth status`, and `splat me` to verify local setup and authentication. Prefer staging or prepare/execute flows before final submit/confirm actions. Never run final trade, swap, bridge, reward-claim, token-revoke, grant-update, or signer-submit commands unless the user explicitly asks for that final action in the current task.

27 changes: 27 additions & 0 deletions claude/commands/splat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
description: Inspect and use the Splat CLI safely
argument-hint: [task]
---

Use the Splat CLI to help with this task:

`$ARGUMENTS`

Before giving detailed command advice, inspect the installed CLI when possible:

```bash
splat --json commands
```

Also check setup when the task involves auth, API reachability, trading, signing, or local environments:

```bash
splat doctor
splat auth status
```

Follow these rules:

- Do not invent flags or command names. Use the live command catalog or `splat help <group>`.
- Prefer read-only inspection before writes, signing, trading, token changes, or grant changes.
- Do not run final submit, confirm, revoke, claim, bridge, or signing commands unless the user explicitly asks for that final action.
55 changes: 55 additions & 0 deletions install-agent-skills.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail

SPLAT_SKILLS_REPO="${SPLAT_SKILLS_REPO:-protastudios/splat-cli-releases}"
SPLAT_SKILLS_BRANCH="${SPLAT_SKILLS_BRANCH:-main}"
SPLAT_INSTALL_CODEX="${SPLAT_INSTALL_CODEX:-1}"
SPLAT_INSTALL_CLAUDE="${SPLAT_INSTALL_CLAUDE:-1}"

raw_base="https://raw.githubusercontent.com/${SPLAT_SKILLS_REPO}/${SPLAT_SKILLS_BRANCH}"
tmp_dir="$(mktemp -d)"

cleanup() {
rm -rf "${tmp_dir}"
}
trap cleanup EXIT

download() {
local remote_path="$1"
local local_path="$2"
mkdir -p "$(dirname "${local_path}")"
curl -fsSL "${raw_base}/${remote_path}" -o "${local_path}"
}

if [[ "${SPLAT_INSTALL_CODEX}" == "1" ]]; then
codex_home="${CODEX_HOME:-${HOME}/.codex}"
codex_skill_dir="${codex_home}/skills/splat-cli"

download "skills/splat-cli/SKILL.md" "${tmp_dir}/codex/SKILL.md"
download "skills/splat-cli/agents/openai.yaml" "${tmp_dir}/codex/agents/openai.yaml"
download "skills/splat-cli/references/install.md" "${tmp_dir}/codex/references/install.md"
download "skills/splat-cli/references/auth.md" "${tmp_dir}/codex/references/auth.md"
download "skills/splat-cli/references/safety.md" "${tmp_dir}/codex/references/safety.md"
download "skills/splat-cli/references/commands.md" "${tmp_dir}/codex/references/commands.md"

rm -rf "${codex_skill_dir}"
mkdir -p "$(dirname "${codex_skill_dir}")"
cp -R "${tmp_dir}/codex" "${codex_skill_dir}"
echo "Installed Codex skill to ${codex_skill_dir}"
fi

if [[ "${SPLAT_INSTALL_CLAUDE}" == "1" ]]; then
claude_home="${CLAUDE_HOME:-${HOME}/.claude}"
claude_command_dir="${claude_home}/commands"

download "claude/commands/splat.md" "${tmp_dir}/claude/commands/splat.md"
download "claude/CLAUDE.md.snippet" "${tmp_dir}/claude/CLAUDE.md.snippet"

mkdir -p "${claude_command_dir}"
cp "${tmp_dir}/claude/commands/splat.md" "${claude_command_dir}/splat.md"
cp "${tmp_dir}/claude/CLAUDE.md.snippet" "${claude_home}/SPLAT_CLAUDE.md"
echo "Installed Claude command to ${claude_command_dir}/splat.md"
echo "Installed Claude memory snippet to ${claude_home}/SPLAT_CLAUDE.md"
fi

echo "Done. Restart Codex or Claude Code if the new guidance is not discovered immediately."
41 changes: 41 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@splat/agent-skills",
"version": "1.0.0",
"description": "Codex and Claude Code guidance for the Splat CLI.",
"bin": {
"splat-agent-skills": "bin/install.js"
},
"files": [
"bin",
"skills",
"claude",
"README.md"
],
"scripts": {
"test": "node --check bin/install.js && bash -n install-agent-skills.sh",
"pack:dry-run": "npm pack --dry-run"
},
"keywords": [
"splat",
"codex",
"claude",
"skills",
"cli",
"trading"
],
"homepage": "https://asksplat.com",
"repository": {
"type": "git",
"url": "git+https://github.com/protastudios/splat-cli-releases.git"
},
"bugs": {
"url": "https://github.com/protastudios/splat-cli-releases/issues"
},
"license": "UNLICENSED",
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=18"
}
}
Loading