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

@halyard/cli

v0.3.0

Published

CLI for setting up Halyard in Claude/Cursor/Codex and syncing coding session logs

Downloads

2,111

Readme

@halyard/cli

Command-line companion for Halyard — scaffold Halyard into your repo for Claude Code, Cursor, and Codex, and sync your coding-agent sessions back to the platform.

halyard sync discovers sessions from Claude Code (~/.claude/projects/), Codex CLI (~/.codex/sessions/), Gemini CLI (~/.gemini/tmp/*/chats/), OpenCode (via opencode export), and GitHub Copilot CLI (~/.copilot/session-store.db, Node ≥ 22.13). Each session becomes searchable knowledge plus per-person work metrics — cost (USD), turns, duration, tokens, and tool activity.

Install

npm install -g @halyard/cli
# or run without installing
bunx @halyard/cli <command>
pnpm dlx @halyard/cli <command>

Commands

halyard setup     # Scaffold Halyard into the current repo (alias: init)
halyard login     # Authenticate via your browser
halyard sync      # Upload new session logs to Halyard
halyard push      # Push a single session file
halyard whoami    # Show the authenticated user, org, and repo binding
halyard skills    # Discover local agent skills (SKILL.md folders) and sync them to Halyard
halyard knowledge # Create or update knowledge entries, including work streams

Run halyard --help for the full list of flags.

Repo binding (.halyard.json)

A committed .halyard.json at the repo root binds the repo to one organization:

{ "org": "halyard-studio" }

Create it with halyard setup --org <slug> (add --force to rebind an already-bound repo). The binding is discovered by walking up from the current directory; detached git worktrees fall back to the main checkout's binding via git rev-parse --git-common-dir.

In a bound repo:

  • halyard sync uploads only sessions whose working directory resolves to the same repository (matched by git common dir, then by normalized remote.origin.url). Sessions whose repo can't be determined are skipped and counted; halyard sync --all restores machine-wide sync.
  • halyard sync and halyard push print Syncing <scope> → <org> before uploading and hard-fail if your credentials belong to a different org than the binding — re-run halyard login inside the repo to fix that.
  • halyard login stores workspace-scoped credentials for the bound org (see below).

Without a binding, sync keeps the old machine-wide behavior and prints a notice.

Credentials

Resolution order for every command:

  1. HALYARD_TOKEN env var — an sk_halyard_... API key (or raw token) for headless/CI use. API keys are bound to one org server-side; the CLI cannot verify that org against a repo binding, so it warns instead of hard-failing.
  2. ~/.halyard/credentials/<orgId>.json — per-org OAuth chains, matched against the repo binding's org slug. Written by halyard login inside a bound repo.
  3. ~/.halyard/credentials.json — the legacy/default chain, written by halyard login outside a bound repo and used by halyard orgs switch.

Token refresh always writes back to the same file the credentials were read from. Set HALYARD_HOME to relocate the state directory (defaults to ~/.halyard).

Environment variables

| Variable | Purpose | | ----------------- | ------------------------------------------------------------- | | HALYARD_TOKEN | API key / token override for headless use (beats stored auth) | | HALYARD_API_URL | Default for --api-url (the flag still wins) | | HALYARD_HOME | State directory override (default ~/.halyard) |

Upload every session automatically

halyard setup --org <your-org-slug>

setup --org binds the repo (see above) and writes a launcher, .halyard/hook.sh, plus session-start / session-end hook config for Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode and Grok Build. Each hook runs halyard hook, which uploads the transcript that just finished at session end and sweeps this repo's earlier transcripts that never uploaded at session start. Commit the generated files and every clone gets the behaviour. Re-running setup is idempotent; --no-hooks skips this part.

halyard hook reads the client's hook payload from stdin, resolves credentials the same way sync and push do (HALYARD_TOKEN from the environment or the repo's .env, then the per-org login for the bound org, then the default login), skips instead of uploading when login credentials belong to another org than .halyard.json, never blocks the agent, and logs to ~/.halyard/hooks.log. Claude and Codex sweeps use the same repo-scoped matching as halyard sync. Run halyard hook --help for the flags.

Upload happens at session end, not on every turn: the ingest endpoint keeps the first upload it sees for a session id. See docs/agent-session-upload.md for the per-client details.

Sync your agent skills

halyard skills list              # every SKILL.md folder on this machine, with its fingerprint
halyard skills sync              # upload new or changed skills to the bound org
halyard skills sync --scope project --dry-run

skills sync scans the directories every harness reads — user-level (~/.claude/skills, ~/.agents/skills, ~/.codex/skills, ~/.cursor/skills, ~/.gemini/skills, ~/.copilot/skills, OpenCode, Amp, Windsurf, Grok, Kiro, Cline, Factory) and repo-level (.claude/skills, .agents/skills, .github/skills, …) — de-duplicates symlink aliases by real path, fingerprints each folder (sha256 over every file, not just SKILL.md), and uploads what changed. Each skill becomes a PROCESS knowledge entry, searchable by every agent connected to the org. Re-runs are free: unchanged skills are skipped from the local ledger, and the server compares the fingerprint again for anything the ledger missed. The session-start hook syncs the repo's committed skills automatically (HALYARD_SKILLS_SYNC=0 turns that off); personal skills only go up when you run the command. See docs/agent-skills-sync.md.

Headless and cloud environments

Set HALYARD_TOKEN to an API key in the environment (one key per environment; keys are bound to one organization):

halyard api-keys create --name "my-repo-ci"      # prints sk_halyard_… once
export HALYARD_TOKEN=sk_halyard_…
halyard sync --provider claude                   # or push <file>

Where to set it: Claude Code on the web → environment variables; Codex Cloud → environment variables (not secrets, which are removed before the agent phase); Cursor cloud agents → dashboard Secrets; GitHub Copilot coding agent → Agents secrets; GitHub Actions → secrets.HALYARD_TOKEN and a final if: always() step running halyard sync.

Write knowledge entries

halyard knowledge writes entries through the typed API, so it works with a halyard login session or an sk_halyard_ key in HALYARD_TOKEN (CI, scripts, cloud agents).

halyard knowledge create --type DECISION --title "Retry ingest 3x" --content-file decision.md --tags ingest
halyard knowledge update <id> --tags ingest,retries      # only the flags you pass change
halyard knowledge apply -f stream.json                  # create, or update when the spec has "id"

apply takes the same fields as the MCP upsert_knowledge tool, including a work_stream block (admins only):

{
  "title": "Session upload pipeline",
  "content": "Purpose: reliable agent-session ingest.",
  "entry_type": "WORK_STREAM",
  "work_stream": {
    "rd_classification": "core",
    "income_years": ["2026-27"],
    "scopes": [{ "rule_type": "repo", "rule_value": "acme/api" }]
  }
}

Scope rules the stream already has are skipped, so re-running the same spec in CI is safe; add the returned id to the spec to update the entry instead of creating another. Entries written with an API key land in the inbox review queue unless you pass --filed (or "filed": true); work streams are always filed. Like sync, every write prints the destination org first and refuses to write when the repo is bound to a different org.

Learn more