spanory
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Cross-runtime observability toolkit for AI agent systems — unified tracing for Claude Code, OpenClaw & OpenCode via OpenTelemetry + Langfuse
Spanory
Cross-runtime observability toolkit for AI agent systems
English | 中文
Why Spanory?
AI coding agents like Claude Code, Codex, OpenClaw, and OpenCode generate rich session transcripts — turns, tool calls, MCP interactions, shell commands — but there is no unified way to collect, trace, and observe these events across different runtimes.
Spanory gives you a single CLI and plugin system to parse agent transcripts into a unified event model, then ship them as OpenTelemetry traces to backends like Langfuse — with zero cron, realtime hooks, and offline backfill.
Features
- One CLI, Multiple Runtimes — Unified tracing for Claude Code, Codex, OpenClaw, OpenCode
- OTel-Native Transport — OTLP HTTP export compatible with Langfuse, with extensible backend adapters
- Realtime + Offline — Hook-based live ingestion and CLI-driven session replay/backfill
- Report & Alert — Built-in aggregation views (session, MCP, tool, cache, turn-diff) and rule-based alerting with webhook + CI support
- Cross-Platform — macOS, Linux, Windows with OS-specific hook wrappers
- Pluggable Architecture — Runtime adapters and backend adapters are fully decoupled
Architecture
RuntimeAdapter → Canonical Events → BackendAdapter → OTLP Core → OTLP HTTP
Unified Event Model (SpanoryEvent):
turn · agent_command · shell_command · mcp · agent_task · tool
Packages
| Package | Description |
|---|---|
@bububuger/core |
Normalized schema, parser interfaces, mapping contracts (TypeScript) |
@bububuger/otlp-core |
OTLP compile & send transport |
@bububuger/backend-langfuse |
Langfuse backend adapter |
@bububuger/spanory-statusline-plugin |
Claude Code statusline plugin for realtime probe + HUD |
@bububuger/spanory-openclaw-plugin |
OpenClaw plugin for realtime ingestion |
@bububuger/spanory-opencode-plugin |
OpenCode plugin for realtime ingestion |
@bububuger/spanory |
Local parser, export CLI, hook handler |
@alipay/spanory |
Internal wrapper package for Alipay registry distribution |
Project Workflow (Team Style)
To keep implementation style and quality consistent across humans and agents, follow the standards workflow first:
For new feature or bug fix work, this workflow defines:
- Required design updates
- Required test updates
- Required verification gates before merge
Telemetry field governance gate:
npm run telemetry:check
Issue status巡检(自动化任务建议每轮执行):
npm run issue:status
Quick Start
Install
Option A: Download prebuilt binary from GitHub Releases
Releases page: https://github.com/Bububuger/spanory/releases
Each release includes:
spanory-<version>-darwin-arm64.tar.gz(macOS Apple Silicon)spanory-<version>-darwin-x64.tar.gz(macOS Intel)spanory-<version>-linux-x64.tar.gz(Linux x64)spanory-<version>-windows-x64.zip(Windows x64)SHA256SUMS.txt
macOS / Linux:
TAG=vX.Y.Z # replace with the target release tag
# macOS arch: arm64 => darwin-arm64, x86_64 => darwin-x64
# Linux (supported): x86_64 => linux-x64
OS_ARCH=darwin-arm64
# quick check on macOS: uname -m
curl -fL -o spanory.tar.gz \
"https://github.com/Bububuger/spanory/releases/download/${TAG}/spanory-${TAG#v}-${OS_ARCH}.tar.gz"
tar -xzf spanory.tar.gz
chmod +x spanory
sudo mv spanory /usr/local/bin/spanory
spanory --help
Windows (PowerShell):
$Tag = "vX.Y.Z" # replace with the target release tag
Invoke-WebRequest -Uri "https://github.com/Bububuger/spanory/releases/download/$Tag/spanory-$($Tag.TrimStart('v'))-windows-x64.zip" -OutFile "spanory.zip"
Expand-Archive -Path "spanory.zip" -DestinationPath ".\\spanory-bin" -Force
.\\spanory-bin\\spanory.exe --help
Optional integrity check:
curl -fL -o SHA256SUMS.txt \
"https://github.com/Bububuger/spanory/releases/download/${TAG}/SHA256SUMS.txt"
shasum -a 256 -c SHA256SUMS.txt
Option B: Install via npm / npx
# Run directly (no global install)
npx @bububuger/spanory@latest --help
# Global install
npm i -g @bububuger/spanory
spanory --help
Option C: Install from source checkout
cd spanory
npm install
npm install -g ./packages/cli
spanory --help
Configure OTLP (Langfuse)
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:3000/api/public/otel/v1/traces"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic $(printf '%s' '<PUBLIC_KEY>:<SECRET_KEY>' | base64)"
OTEL_EXPORTER_OTLP_HEADERS expects k=v pairs (comma-separated if multiple).
For Langfuse OTLP, use Authorization=Basic <base64(public_key:secret_key)>.
Local Setup (Recommended: one command for 4 runtimes)
install is idempotent and configures all supported runtimes (Codex defaults to non-proxy watch daemon mode):
spanory status
spanory install --runtimes claude-code,codex,openclaw,opencode
spanory doctor --runtimes claude-code,codex,openclaw,opencode
What install does:
- Claude Code: writes/updates
Stop+SessionEndhook command tospanory hook --last-turn-only, installs thespanory-statuslineplugin under~/.claude/plugins/spanory-statusline, syncs.claude-plugin/manifest.jsonversion, and wiressettings.json -> statusLine.command - Codex: removes legacy
~/.codex/bin/spanory-codex-notify.shandnotify = [...]from~/.codex/config.toml, then startsspanory runtime codex watch --last-turn-onlyin background (~/.spanory/codex-watch.pid,~/.spanory/logs/codex-watch.log) - OpenClaw: installs/enables Spanory plugin (when
openclawis available in PATH) - OpenCode: installs Spanory plugin loader into
~/.config/opencode/plugin
spanory uninstall --runtimes claude-code removes the Claude hook wiring, the installed statusline plugin payload, and ~/.spanory/probe.
Dry-run example:
spanory install \
--runtimes claude-code,codex,openclaw,opencode \
--dry-run
Copy To Your Agent (Self-install)
Paste this block to your coding agent in this repo, and let it finish install automatically:
Install and configure Spanory on this machine with one-command install.
Requirements:
- Keep Codex in watch daemon mode (no proxy hijack, no notify injection).
- Configure all runtimes: claude-code,codex,openclaw,opencode.
- Verify and report any failed checks.
Run:
1) npm install
2) npm install -g ./packages/cli
3) spanory status
4) spanory install --runtimes claude-code,codex,openclaw,opencode
5) spanory doctor --runtimes claude-code,codex,openclaw,opencode
Output:
- status/install/doctor JSON results
- final pass/fail summary and next-step troubleshooting for failed checks
Claude Code — Realtime Hook
Set hook command in Claude Code config for SessionEnd and/or Stop events:
spanory hook
The CLI reads the hook payload from stdin, parses the session transcript, and ships traces via OTLP automatically.
Recommended: Bind the
Stopevent in addition toSessionEnd.Stopfires on every assistant turn completion, enabling near real-time trace reporting instead of waiting for the session to end.
Claude Code — Statusline Plugin
spanory install --runtimes claude-code also installs the bundled statusline plugin into ~/.claude/plugins/spanory-statusline and points Claude Code statusLine.command at the generated launcher.
Doctor checks verify:
- Claude Code binary presence and reported version
- hook wiring for
Stop+SessionEnd - statusline command wiring in
~/.claude/settings.json - plugin payload existence and loadability from the installed directory
OpenClaw — Plugin (Zero Cron)
spanory runtime openclaw plugin install
spanory runtime openclaw plugin enable
spanory runtime openclaw plugin doctor
OpenCode — Plugin
spanory runtime opencode plugin install
spanory runtime opencode plugin doctor
The plugin auto-loads ~/.spanory/.env at runtime (only fills missing env vars), so GUI-launched OpenCode can still pick up:
OTEL_EXPORTER_OTLP_ENDPOINTOTEL_EXPORTER_OTLP_HEADERS
Trigger mode (recommended realtime by turn):
# default: flush on turn/message completion events (realtime)
export SPANORY_OPENCODE_FLUSH_MODE="turn"
# optional: only flush on session lifecycle end events
# export SPANORY_OPENCODE_FLUSH_MODE="session"
Diagnostics (when "triggered but not reported"):
# latest plugin status
cat ~/.spanory/opencode/plugin-status.json
# detailed plugin runtime logs
tail -n 120 ~/.spanory/opencode/plugin.log
# structured doctor checks (includes endpointConfigured hint)
spanory runtime opencode plugin doctor
Codex — Session Parse + Notify Hook
Codex runtime supports export/backfill/hook/watch based on ~/.codex/sessions/**/*.jsonl.
# Export one codex session
spanory runtime codex export \
--session-id <SESSION_ID> \
--endpoint "$OTEL_EXPORTER_OTLP_ENDPOINT" \
--headers "$OTEL_EXPORTER_OTLP_HEADERS"
# Batch backfill codex sessions by mtime
spanory runtime codex backfill \
--since 2026-03-01T00:00:00Z \
--limit 50 \
--endpoint "$OTEL_EXPORTER_OTLP_ENDPOINT" \
--headers "$OTEL_EXPORTER_OTLP_HEADERS"
Codex notify payload can be consumed for near realtime turn-level export:
echo '{"event":"agent-turn-complete","thread_id":"<SESSION_ID>","turn_id":"<TURN_ID>","cwd":"<PROJECT_CWD>"}' | \
spanory runtime codex hook --last-turn-only
When Codex notify is not firing (or missed intermittently), use watcher fallback for near-realtime polling export:
# long-running watcher, only handles newly updated sessions after startup
spanory runtime codex watch --last-turn-only
# one-shot scan for existing sessions (useful for quick verification)
spanory runtime codex watch --include-existing --once --settle-ms 0
Codex — Optional Proxy Hijack Capture (Full Redacted)
Use an OpenAI-compatible local proxy to capture full request/response bodies with strong redaction.
# Start proxy
spanory runtime codex proxy \
--listen 127.0.0.1:8787 \
--upstream https://api.openai.com
# Route Codex traffic to proxy
export OPENAI_BASE_URL="http://127.0.0.1:8787"
Offline Backfill
# Preview sessions to process
spanory runtime claude-code backfill \
--project-id my-project \
--since 2026-02-27T00:00:00Z \
--dry-run
# Run backfill with OTLP export
spanory runtime claude-code backfill \
--project-id my-project \
--since 2026-02-27T00:00:00Z \
--endpoint "$OTEL_EXPORTER_OTLP_ENDPOINT" \
--headers "$OTEL_EXPORTER_OTLP_HEADERS"
Report & Alert
Aggregation Reports
spanory report session --input-json /path/to/exported.json
spanory report mcp --input-json /path/to/exported-or-dir
spanory report command --input-json /path/to/exported-or-dir
spanory report agent --input-json /path/to/exported-or-dir
spanory report cache --input-json /path/to/exported-or-dir
spanory report tool --input-json /path/to/exported-or-dir
spanory report context --input-json /path/to/exported-or-dir
spanory report turn-diff --input-json /path/to/exported-or-dir
Rule-Based Alerts
spanory alert \
--input-json /path/to/exported-or-dir \
--rules /path/to/rules.json \
--fail-on-alert
Supports webhook notifications and CI integration with non-zero exit codes on alert.
Exit Codes
| Code | Meaning |
|---|---|
0 |
Command succeeded. |
1 |
Unexpected runtime error (crash / unhandled rejection). |
2 |
Command completed with failed checks or alerts (for example: spanory alert eval --fail-on-alert). |
Troubleshooting
1) ERR_MODULE_NOT_FOUND after local linking
cd /path/to/spanory
npm install
npm link -w packages/cli
spanory --help
2) Hook gets OTLP 401
- Verify env is loaded:
spanory --help >/dev/null
echo "$OTEL_EXPORTER_OTLP_ENDPOINT"
echo "$OTEL_EXPORTER_OTLP_HEADERS"
- Verify header format is Basic auth (not Bearer):
Authorization=Basic <base64(public_key:secret_key)> - Run a dry local export to inspect parsed output:
spanory runtime claude-code export \
--project-id <PROJECT_ID> \
--session-id <SESSION_ID> \
--export-json /tmp/spanory-export.json
3) Hook runs but no data
- Ensure Claude Code hook command is exactly
spanory hook --last-turn-only. - Prefer binding both
StopandSessionEnd. - Check local hook log:
tail -n 100 "$HOME/.claude/state/spanory-hook.log"
Build Binary From Source
npm run build:bin
./dist/spanory-macos-arm64 --help
# Build all platforms
bash scripts/release/build-binaries.sh all
# Package release archives locally
npm run package:release-assets -- vX.Y.Z
Development
npm install
npm run check
npm test
npm run test:bdd
CI runs the same gates via .github/workflows/ci.yml.
CI/CD
- CI:
.github/workflows/ci.yml- Runs on
push(main/codex//feat/) andpull_request - Enforces quality gates:
check+test+test:bdd - Builds Linux binary and runs smoke check (
--help)
- Runs on
- CD:
.github/workflows/release.yml- Triggered by tag push:
v*(for examplev0.2.0) - Verifies quality gates before release
- Publishes
@bububuger/spanoryto npm whenNPM_TOKENis configured in thereleaseenvironment NPM_TOKENpath:GitHub Settings > Environments > release- Builds release binaries on Linux/macOS/Windows
- macOS artifacts include both Apple Silicon (
darwin-arm64) and Intel (darwin-x64) - Packages archives (
tar.gz/zip) andSHA256SUMS.txt - Publishes GitHub Release with downloadable assets
- Triggered by tag push:
Release (Internal)
Internal package @alipay/spanory is published to registry.antgroup-inc.cn.
See docs/RELEASE.md for the authoritative release flow.
# 1. Ensure local gates pass
npm run check
npm run telemetry:check
npm test
npm run test:bdd
# 2. Create a semver tag from main
git tag v0.1.XX
# 3. Build + publish internal packages
# (runs version sync from the latest local tag, then builds and tnpm publishes)
npm run publish:internal
# 4. Push the tag
git push origin v0.1.XX
Key points:
- Do NOT manually edit version in
package.json:scripts/release/sync-version.mjsderives it from the latest git tag. npm run publish:internalpublishes in order:@alipay/spanory-{darwin-arm64,darwin-x64,linux-x64}then@alipay/spanory.- Public npm release (
@bububuger/spanory) is handled by GitHub Actions CD on tag push (v*).
Roadmap
See docs/ROADMAP.md for the full project evolution and future plans.
Contributing
See CONTRIBUTING.md for guidelines.
Security
See docs/SECURITY.md for data handling, capture redaction, and release security policy.
License
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi