npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

symphony-beads

v0.1.7

Published

Symphony implementation for Beads issue tracker

Readme

symphony-beads

Autonomous coding orchestrator for Beads issues.

It polls issues, creates per-issue workspaces, runs the configured coding runner (default: pi) to implement work, opens PRs, and reacts to PR review outcomes.

Built on Beads and Bun, with pi as the default runner. Based on the Symphony spec.

Table of contents

Requirements

  • Bun >= 1.0
  • Beads (bd CLI)
  • Dolt (required by Beads)
  • pi (default runner used by symphony init)
  • A coding runner available in PATH for your configured runner.command (you can replace pi)
  • gh (for PR creation/monitoring)
  • git

Install

Global install (Bun)

bun add -g symphony-beads

From source

git clone https://github.com/ahkohd/symphony-beads.git
cd symphony-beads
bun install
bun link    # installs the `symphony` command globally

Quick start

cd your-project

# Ask your coding agent to initialize Beads in this repo

# Option A: export full clone URL
export REPO_URL="https://github.com/owner/repo.git"

# Option B: set workspace.repo in WORKFLOW.md (owner/repo)

symphony init
symphony validate --strict
symphony doctor

# Ask your coding agent to create the first ticket in Beads
symphony start
symphony status
symphony logs -f

First-run checklist

Before first start, confirm:

  1. Clone source is configured
    • REPO_URL env var, or
    • workspace.repo in WORKFLOW.md.
  2. gh auth status succeeds.
  3. workspace.root is unique for this project (not overlapping another running instance root).
  4. symphony validate --strict passes.
  5. symphony doctor is healthy.

Daily operator workflow

# Start (daemon by default)
symphony start

# Observe
symphony status
symphony instances
symphony logs -f

# Stop one instance
symphony stop --id <instance-id-or-unique-prefix>

# Stop all
symphony stop --all

Creating tickets via agents

Beads operations are agent-facing in this workflow. Humans are expected to ask their coding agent to create and update tickets.

Example requests to your agent:

  • "Create a P1 bug ticket in Beads: Fix flaky CI test suite. Description: Intermittent failure in parser tests."
  • "Create a feature ticket for Migrate auth flow and set metadata model=claude-opus-4-6."
  • "Create a ticket for docs cleanup and set it to deferred (backlog)."
  • "For issue bd-42, set metadata model=claude-opus-4-6."
  • "For issue bd-42, clear metadata model."

When model metadata is present, Symphony uses it as the highest-priority model routing signal (see model routing section below).

CLI reference

symphony <command> [flags]

Commands:
  start      Start the orchestrator (daemonizes by default)
  status     Show current issue status from beads
  validate   Validate WORKFLOW.md configuration
  init       Create a new WORKFLOW.md
  instances  List all running symphony instances
  doctor     Verify dependencies, config, and runtime state
  logs       Tail the symphony log file
  stop       Stop a running symphony instance
  kanban     Interactive kanban board

Flags:
  --json            Output as JSON
  --workflow PATH   Workflow file (default: WORKFLOW.md)
  --verbose         Verbose output
  -h, --help        Show help
  -v, --version     Show version

Start flags:
  -f, --foreground  Run in foreground

Logs flags:
  -f, --follow      Follow the log file
  -n, --lines N     Number of lines to show (default: 50)

Stop flags:
  --all             Stop all registered symphony instances
  --id ID           Stop a specific instance by ID or unique ID prefix

Validate flags:
  --strict          Treat warnings as errors

Doctor flags:
  --fix             Apply safe automatic repairs before checks
  --dry-run         Preview fixes without applying changes (requires --fix)

Kanban

Launch the TUI board:

symphony kanban

Kanban is an operator view for triage and monitoring. Ticket creation remains agent-driven (n shows guidance to ask your coding agent).

  • j/k or arrows: move selection
  • g/G: jump to top/bottom in active column
  • m/M: move status forward/backward
  • b/B: defer/promote backlog
  • r: refresh
  • q: quit

Kanban screenshot:

Kanban screenshot

Runtime isolation and instance IDs

Isolation model

  • Per project: .symphony.lock prevents duplicate local starts.
  • Global: ~/.symphony/instances/ tracks live instances.
  • Workspace collision guard: overlapping roots are blocked (exact match and parent/child overlap).

Example overlap (invalid):

  • Instance A: /tmp/symphony
  • Instance B: /tmp/symphony/project-b

Deterministic instance IDs

Instance IDs are deterministic from absolute project path.

  • start --json: top-level instance_id
  • status --json: service.instance_id
  • instances --json: instances[].id

Prefix behavior for stop --id:

  • exact ID match wins
  • otherwise unique prefix works
  • ambiguous prefix fails with instance_id_ambiguous

WORKFLOW.md configuration

WORKFLOW.md has YAML front-matter and prompt body.

Front-matter example (aligned with symphony init defaults)

---
tracker:
  kind: beads
  project_path: "."
workspace:
  root: ./workspaces
  repo: $SYMPHONY_REPO
  remote: origin
agent:
  max_concurrent: 5
  max_turns: 20
runner:
  command: pi --no-session
  turn_timeout_ms: 3600000
  stall_timeout_ms: 300000
polling:
  interval_ms: 30000
hooks:
  after_create: |
    set -e
    if [ -n "$REPO_URL" ]; then
      git clone "$REPO_URL" .
    elif [ -n "$SYMPHONY_REPO" ] && [ "$SYMPHONY_REPO" != '$SYMPHONY_REPO' ]; then
      if command -v gh >/dev/null 2>&1; then
        gh repo clone "$SYMPHONY_REPO" .
      else
        git clone "https://github.com/$SYMPHONY_REPO.git" .
      fi
    else
      echo "No repository source configured. Set REPO_URL or workspace.repo." >&2
      exit 1
    fi
    bun install 2>/dev/null || npm install 2>/dev/null || true
  before_run: |
    DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/$SYMPHONY_REMOTE/HEAD 2>/dev/null | sed "s|refs/remotes/$SYMPHONY_REMOTE/||" || echo "master")
    git fetch $SYMPHONY_REMOTE $DEFAULT_BRANCH 2>/dev/null || true
    git fetch $SYMPHONY_REMOTE issue/$SYMPHONY_ISSUE_ID 2>/dev/null || true
    if git rev-parse --verify $SYMPHONY_REMOTE/issue/$SYMPHONY_ISSUE_ID >/dev/null 2>&1; then
      git checkout -B issue/$SYMPHONY_ISSUE_ID $SYMPHONY_REMOTE/issue/$SYMPHONY_ISSUE_ID
    else
      git checkout -B issue/$SYMPHONY_ISSUE_ID $SYMPHONY_REMOTE/$DEFAULT_BRANCH
    fi
    git clean -fd 2>/dev/null || true
log:
  file: ./symphony.log
---

Hook environment variables

| Variable | Description | |---|---| | SYMPHONY_ISSUE_ID | Current issue identifier | | SYMPHONY_PROJECT_PATH | Absolute project path | | SYMPHONY_REMOTE | workspace.remote value | | SYMPHONY_REPO | workspace.repo value (owner/repo) | | REPO_URL | Optional full clone URL |

Prompt template variables

| Variable | Description | |---|---| | {{ issue.identifier }} | Issue ID | | {{ issue.title }} | Title | | {{ issue.description }} | Description | | {{ issue.priority }} | Priority | | {{ issue.labels }} | Comma-separated labels | | {{ issue.state }} | Current state | | {{ attempt }} | Retry attempt | | {{ review_feedback }} | PR review feedback on rework |

Model routing and per-ticket model selection

Symphony supports per-ticket model routing.

Resolution order (highest first):

  1. issue.metadata.model
  2. runner.models.<issue_type> (for example bug, feature, chore)
  3. runner.models.P0..P4
  4. runner.models.default

To enable dynamic model selection, ensure your runner command consumes $SYMPHONY_MODEL:

runner:
  command: pi --no-session --model $SYMPHONY_MODEL
  models:
    default: claude-sonnet-4-5-20250929
    P0: claude-opus-4-6
    bug: claude-opus-4-6
    chore: claude-haiku-4-5-20251001

Notes:

  • For non-pi runners, use an equivalent command that accepts a model argument (still via $SYMPHONY_MODEL).
  • Legacy fixed model is still supported via runner.model when runner.models is not set.

To set a per-issue model override, ask your agent to update issue metadata in Beads (for example: set model=claude-opus-4-6 on bd-42).

Issue lifecycle and backlog

open/in_progress -> review -> closed
          ^          |
          |          | changes requested
          +----------+

open <-> deferred (backlog)

| State | Orchestrator behavior | |---|---| | open, in_progress | dispatch / keep running | | review, blocked, deferred | do not dispatch; running agent is stopped | | closed, cancelled, duplicate | terminal; workspace cleaned |

Backlog helpers (via agent requests):

  • "Move bd-42 to deferred (backlog)."
  • "Move bd-42 back to open."

Kanban backlog shortcuts:

  • b: move selected issue to backlog (deferred)
  • B: promote selected issue from backlog (open)

Validate and doctor

symphony validate

  • validates known config semantics
  • warns on unknown sections/keys (typo detection)
  • warns when clone bootstrap likely has no source (workspace.repo and REPO_URL missing)
  • --strict turns warnings into non-zero exit (CI mode)

symphony doctor

Checks dependencies + runtime health, including workspace overlap risk.

When overlap is detected, doctor includes actionable hints such as:

  • symphony instances
  • symphony stop --id <instance-id>

symphony doctor --fix

Safe repairs before checks:

  • remove stale project lock
  • ensure workspace root exists
  • prune stale/invalid global registry entries

Use preview mode first:

symphony doctor --fix --dry-run

Troubleshooting

No repository source configured

No repository source configured. Set REPO_URL or workspace.repo.

Configure one of:

  • export REPO_URL=...
  • workspace.repo: owner/repo

Then run:

symphony validate --strict

Workspace overlap failure

Run:

symphony instances
symphony stop --id <conflicting-id>

Then set distinct workspace.root paths per project.

gh auth failures

gh auth login
symphony doctor

Beads DB missing

Ask your coding agent to initialize Beads, then re-run:

symphony doctor

Logs JSON

logs --json and logs --follow are mutually exclusive.

JSON output quick reference

  • start --json: includes instance_id, pid, log_file
  • status --json: includes service, issues, by_state
  • instances --json: includes instances[] with id, pid, workspace_root
  • stop --json: structured stop result; errors include typed codes (instance_not_found, instance_id_ambiguous, stop_flag_conflict)
  • validate --json: valid, errors, warnings, strict
  • doctor --json: checks[] (fix section when using --fix)

Running multiple projects

cd ~/projects/project-a && symphony start
cd ~/projects/project-b && symphony start

symphony instances
symphony stop --id <instance-id>

Use non-overlapping workspace.root values across projects.