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

sinscribe

v1.4.1

Published

A git-centric developer-workflow assistant CLI: PR descriptions, commit messages, branch names, project context briefs, and AI agent context files.

Downloads

349

Readme

Your git workflow, written for you — from the terminal.

License Node npm Built with TypeScript

Sinscribe is a git-centric developer-workflow assistant CLI. It reads your actual git state — diffs, branch, ticket, session context — and writes the prose around it: PR/MR descriptions, commit messages, branch names, project-context briefs, documentation with mermaid diagrams, and AI agent context files (CLAUDE.md / AGENTS.md). It runs in your terminal as a one-shot command or an interactive chat agent.

[!NOTE] Stable (v1.0.0). Sinscribe is in daily use and its CLI surface — commands, flags, env vars, and config layout — is now covered by semver. Install it globally with npm install -g sinscribe, or from source for development.

Features

  • PR/MR descriptions from your local changes vs the target branch, measured from the merge base up — so it works before you commit.
  • Conventional Commit + Gitmoji messages from your staged changes.
  • Branch names and task prompts for your AI coding agent, generated from a short description or ticket.
  • Project understanding — a structured context brief, full documentation with mermaid diagrams, and CLAUDE.md / AGENTS.md scaffolding, produced by an agent that explores the repo.
  • Interactive chat over the current repository.
  • Per-branch sessions that capture business context (feature, ticket, requirements, target branch) and feed it to every generation.
  • Customizable templates — six built-in house styles plus your own, with typed placeholders filled deterministically from git or by the model.
  • Deterministic --dry-run on every command: no model call, no credentials read — useful for previewing detection and in CI.

Prerequisites

  • Node.js >= 20
  • git
  • An API key for a supported provider (OpenCode Go by default — see Configuration). The kiro-cli provider needs no key.

Install

npm install -g sinscribe
sinscribe --help

Or from source, for development:

pnpm install
pnpm build
node dist/cli.js --help       # or: pnpm sinscribe --help
# optional: pnpm link --global   → `sinscribe` on your PATH

Quick start

The first command needs no API key, which makes it a good way to check that Sinscribe reads your repository correctly before you configure anything:

cd your-repo
sinscribe pr --dry-run          # detected branch, base, ticket, diff + scaffold

Then set a key and generate for real:

export OPENCODE_API_KEY=...     # or run `sinscribe` and let it ask
sinscribe pr                    # draft a PR description from your local changes
sinscribe commit                # Conventional Commit message from staged changes
sinscribe                       # interactive menu + chat over the current repo

The first interactive run asks for your provider API key and stores it in ~/.sinscribe/.env.

Commands

| Command | What it does | | ----------------------- | ------------------------------------------------------------------------------- | | sinscribe | Interactive chat agent + menu over the current repo | | sinscribe pr | PR/MR description from local changes vs the target branch | | sinscribe commit | Conventional Commit + Gitmoji message from staged changes | | sinscribe branch | Branch-name suggestions from a description/ticket | | sinscribe prompt | Copy-ready feature/bugfix task prompt for your AI coding agent | | sinscribe context | Structured project-context brief (markdown or JSON) | | sinscribe docs | Project documentation with mermaid diagrams | | sinscribe agents | Generate/refresh CLAUDE.md + AGENTS.md from the repo | | sinscribe agent-setup | Analyze the project and write specialized agent definitions to .claude/agents | | sinscribe template | Manage the template library (list / show / add / edit / path) |

Command options

| Command | Option | Effect | | ------------- | --------------------- | ----------------------------------------------------------------------------------- | | pr | --template <name> | Template to use (default: andersoftware) | | | --base <ref> | Target branch to diff against (default: session, else detected) | | | --staged | Diff only staged changes (default: all local changes) | | | --ticket <id> | Ticket ID (default: parsed from the branch name) | | | --out <file> | Write the description to a file | | prompt | --type <type> | feature or bugfix (default: inferred from the description) | | | --out <file> | Write the prompt to a file | | | --handoff | Also write HANDOFF.md without asking | | commit | --all, -a | Use all tracked changes, not only staged | | | --scope <scope> | Force the Conventional Commit scope | | | --no-gitmoji | Skip the gitmoji prefix (it is on by default) | | branch | --type <type> | feat|fix|chore|docs|refactor|test|perf|build|ci|hotfix | | context | --out <file> | Write the brief to a file | | | --format <md\|json> | Output format (default: md) | | docs | --out <file> | Write the documentation to a file | | agents | --target <t> | claude|agents|both (default: both) | | | --update | Surgically refresh existing files | | agent-setup | — | No options; the interactive flow asks what it needs | | template | add --from <file> | Seed a new user template from an existing file |

branch takes a required ticket ID and/or description as positional arguments. prompt takes an optional description; without one it falls back to the saved session context.

Global options

Accepted by every command, and — because they are parsed in one pass over the whole command line — they may appear anywhere in it.

| Flag | Effect | | ------------------- | ------------------------------------------------------------------ | | --dry-run | Deterministic scaffold: no LLM call, no credentials read | | -p, --print | One-shot non-interactive run, result on stdout (default off a TTY) | | --model-id <id> | Model override for this run | | --provider <name> | Provider override for this run (not persisted) | | --api-key <key> | API key override for this run (not persisted) | | -v, --version | Print the version | | -h, --help | Show usage |

-p/--print is also selected automatically when stdin is not a TTY, so sinscribe behaves correctly in a pipeline or a CI job.

Examples

# Pull requests
sinscribe pr --template github --base origin/main --out PR.md
sinscribe pr --base develop --staged       # only staged changes, vs develop
sinscribe pr --dry-run                      # branch/ticket/diff detection + scaffold

# Commits & branches
sinscribe commit --scope api --no-gitmoji
sinscribe branch ABC-123 add retry logic to uploader   # → feat/ABC-123-... suggestions

# Prompts & project understanding
sinscribe prompt --type bugfix uploader crashes on empty files
sinscribe prompt --handoff -p "add retry logic"   # also writes HANDOFF.md
sinscribe context --format json --out context.json
sinscribe agents --target claude --update

# Templates
sinscribe template list
sinscribe template show andersoftware
sinscribe template path

# Chat & per-run overrides
sinscribe -p "what changed on this branch?"
sinscribe pr --provider anthropic --api-key sk-ant-...

Ticket IDs (ABC-123, #42) are auto-detected from the branch name for pr and from the input for branch. When a branch session exists, its feature/ticket/requirements are fed to the model as business context.

Session handoff (HANDOFF.md)

A prompting session normally ends with the useful part — what was decided, what is still open — only in your head. After you approve a prompt, sinscribe prompt offers to write a HANDOFF.md at the repo root: a snapshot of where the branch stands, not an accumulated log.

## Where things stand

## What was done this session

## Key decisions

## Open questions

## Next steps

## Known issues / blockers

The next sinscribe prompt on that branch reads the file back and feeds it to the model, so a second iteration starts warm instead of re-deriving settled ground. A handoff written on a different branch is still passed along, but labeled as such rather than presented as the current state.

--handoff writes the file without asking — the only route in -p/--print and other non-TTY runs, which cannot ask. The file is yours to commit or ignore; Sinscribe never adds it to .gitignore.

Configuration

On first interactive run, Sinscribe asks for your provider API key and stores it in ~/.sinscribe/.env (directory 0700, file 0600). Real environment variables always win over the file, and nothing secret is ever printed.

# ~/.sinscribe/.env (all optional; created by the CLI)
SINSCRIBE_PROVIDER="opencode-go"    # opencode-go | openrouter | baseten | fireworks | openai | openai-compatible | anthropic | kiro-cli
SINSCRIBE_MODEL_ID="kimi-k2.7-code" # default model for the provider
OPENCODE_API_KEY="..."
ANTHROPIC_API_KEY="..."             # if you switch to anthropic
                                    # (kiro-cli needs no key — see below)
SINSCRIBE_TICKET_PATTERN="(T-\d+)"  # optional custom ticket regex
SINSCRIBE_THEME="ayu-dark"          # TUI color theme (set from the menu's Theme picker)
SINSCRIBE_REDUCED_MOTION="1"        # freeze the loading animation (the timer keeps counting)

Environment variables

| Variable | Purpose | Default | | ---------------------------- | ------------------------------------------------------------------------------ | --------------------------------- | | SINSCRIBE_PROVIDER | Which provider to use | opencode-go | | SINSCRIBE_MODEL_ID | Model for all runs | the provider's first listed model | | SINSCRIBE_TICKET_PATTERN | Custom ticket regex; the first capture group is used | ABC-123, then #123 | | SINSCRIBE_THEME | Persisted TUI color scheme | shipped default | | SINSCRIBE_REDUCED_MOTION | 1 or true renders a static spinner frame; the elapsed timer keeps counting | off | | SINSCRIBE_DEBUG | 1 prints provider/model/thread lines to stderr | off | | OPENCODE_API_KEY | Key for opencode-go — note the name has no GO | — | | OPENROUTER_API_KEY | Key for openrouter | — | | BASETEN_API_KEY | Key for baseten | — | | FIREWORKS_API_KEY | Key for fireworks | — | | OPENAI_API_KEY | Key for openai | — | | ANTHROPIC_API_KEY | Key for anthropic | — | | ANTHROPIC_BASE_URL | Base-URL override for anthropic | SDK default | | OPENAI_COMPATIBLE_API_KEY | Key for openai-compatible | — | | OPENAI_COMPATIBLE_BASE_URL | Required for openai-compatible — it has no default | — | | EDITOR / VISUAL | Editor opened by template edit | vi | | NO_COLOR | Disables color and the terminal background control | color on |

Resolution order for provider, model, and key: a per-run flag (--provider / --model-id / --api-key), then the environment, then ~/.sinscribe/.env, then the built-in default. Per-run flags are never persisted.

The default provider is OpenCode Go (an OpenAI-compatible endpoint at https://opencode.ai/zen/go/v1) with Kimi K2.7 Code as the default model — set OPENCODE_API_KEY and you're done. Other models on the same plan: glm-5.2, glm-5.1, kimi-k2.6, deepseek-v4-pro, deepseek-v4-flash, mimo-v2.5, mimo-v2.5-pro.

You can switch provider/model per run with --provider / --model-id / --api-key, or persist a new choice from the TUI's AI settings item — which also has a Test connection step that calls the provider's GET /models endpoint (free, no tokens) to verify the key and model before saving.

Provider support

| Provider | Status | | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | opencode-go | Recommended — the default; supported and regularly tested | | kiro-cli | Recommended — drives AWS's official Kiro CLI; single-shot commands only | | openrouter, anthropic, openai, baseten, fireworks, openai-compatible | Selectable — not actively maintained or regularly tested |

[!WARNING] Only the recommended providers (OpenCode Go and Kiro CLI) are exercised regularly. The others ship as-is and may lag behind their vendors' API changes — verify one with Test connection before relying on it.

Every provider except kiro-cli supports the full command set. kiro-cli is limited to pr, commit, branch, and prompt; see below.

Amazon Q Developer setup (kiro-cli)

Use the Amazon Q subscription you already have, through AWS's own CLI:

  1. Install Kiro CLI — brew install kiro-cli, or see kiro.dev/docs/cli — and run kiro-cli login once (IAM Identity Center, Builder ID, Google and GitHub all work).
  2. Set SINSCRIBE_PROVIDER=kiro-cli, or pick Amazon Q Developer (Kiro CLI) in the TUI's AI settings. There is no key to enter and nothing is stored: kiro-cli owns its own sign-in.
  3. Run pr / commit / branch / prompt as usual.

Pick a model with --model-id or in the settings wizard; the labels carry each model's credit multiplier, e.g. qwen3-coder-next (0.05x) up to claude-sonnet-4.5 (1.30x). auto (the default) lets Kiro choose.

Why a subprocess and not the API? AWS restricts Q subscriptions to approved applications: a third-party client that registers itself is refused with AccessDeniedException: "Your subscription does not support this application" however correct its request is. Rather than impersonate an approved client, Sinscribe drives the official one — the approved client makes the call, as itself — which also means the wire format stays AWS's responsibility rather than something we reverse-engineer.

Tools are off, by construction. Sinscribe runs kiro-cli chat with a generated agent that declares "tools": [], so the model can write text but has no tool to touch your working tree — that is what keeps pr/commit/ branch/prompt single-shot. (The --trust-tools= flag does not do this: it only governs auto-approval, and was verified to still let the model read the filesystem.) The agent config lives under ~/.sinscribe/kiro-agent/ and never touches your own Kiro agents.

Limitation: agentic commands (context/docs/agents/agent-setup/chat) need tool calling and exit with a clear message asking you to switch providers.

Reliability

  • Every model call has a 120 s inactivity timeout (and a 10-minute overall cap for single-shot commands); a stalled connection reports a clear network error — with automatic retries on the single-shot path — instead of freezing the CLI.
  • Ctrl+C always exits, and the process force-exits after finishing its work, so a lingering SDK socket can never hang the terminal.
  • git subprocesses are capped at 30 s with GIT_TERMINAL_PROMPT=0, so a credential or GPG prompt fails fast instead of blocking forever.

Templates

Templates are Markdown files with YAML frontmatter and typed {{placeholder}} slots. There are three tiers; a later tier overrides an earlier one by name:

  1. Built-in (shipped): andersoftware (default — Conventional Commits + Gitmoji title with full review sections), github, google, kubernetes, shopify, stripe
  2. User: ~/.sinscribe/templates/*.md
  3. Project: <repo>/.sinscribe/templates/*.md
---
name: myteam
kind: pr
placeholders:
  ticket: { type: string, required: true, from: branch } # filled from git, deterministic
  summary: { type: markdown, required: true, from: llm } # produced by the model
  changes: { type: list, required: true, from: llm } # rendered as bullets
---

## [{{ticket}}] {{summary}}

from: git|branch slots are filled deterministically (also in --dry-run); from: llm slots are requested from the model as validated JSON. Manage the library with sinscribe template list | show | add | edit | path.

Sessions

The menu (bare sinscribe) is context-first: on a branch with no saved context it opens straight into the context form, and the "Create PR description", "Create branch name", and "Create feature or bugfix prompt" items ask for a context before they run. A session captures business context per branch — feature description, ticket ID, requirements, and the target branch it merges into — stored in <repo>/.sinscribe/sessions/<branch>.json.

  • pr describes your local changes vs the target branch, from the merge base up — so it works before you commit, and commits that landed on the target after you branched don't pollute the diff. By default it includes all tracked changes (staged + unstaged); --staged narrows it to the index. On the next run for the same branch it enters update mode, revising the previous description with the fresh diff instead of starting over.
  • The target branch is resolved in order: --base <ref>, then the session's saved target, then auto-detection (origin/HEAD, origin/main, origin/master, origin/develop, main, master, develop).
  • Create branch name generates suggestions from the session context and creates the branch from the target (git checkout -b <name> <target>), migrating the session so pr works there immediately. Once the branch differs from its target, the item becomes Rename branch (git branch -m).

Session files live beside the project template tier, so .sinscribe/.gitignore ignores only sessions/ — .sinscribe/templates/ and .sinscribe/rules.md stay committable.

Project rules

Free-text rules appended to every command's system prompt. Unlike templates, the two tiers are additive — both apply, each labeled by origin:

  • Personal: ~/.sinscribe/rules.md — applies in every repository
  • Project: <repo>/.sinscribe/rules.md — applies here, meant to be committed

Edit them from the menu's Project rules item. --dry-run reports which tiers are active and how large they are, without sending them anywhere.

Troubleshooting

| Message | Cause and fix | | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | Not inside a git repository. | Every command except template needs a repo. cd into one. | | Could not detect a target branch (tried origin/HEAD, origin/main, …) | No conventional default branch resolved. Pass --base <ref>, or save a target in the session context. | | No local changes vs <ref>. Nothing to describe. | The branch matches its base. Commit or edit something, or check that --base points where you think. | | No staged changes vs <ref>. | You passed --staged with an empty index. git add, or drop the flag. | | Nothing staged. Stage changes with git add, or pass --all… | commit reads the index by default. Use -a for all tracked changes. | | <KEY> is required to run sinscribe with <Provider>. | No API key for the selected provider. Set it in the environment, in ~/.sinscribe/.env, or pass --api-key. | | Credentials are required for non-interactive runs. | -p/--print and non-TTY runs cannot open the setup wizard. Set the key in the environment first. | | The <Provider> provider supports pr/commit/branch/prompt only for now… | You asked an agentic command of a provider without tool calling — today that means kiro-cli. Switch with --provider or SINSCRIBE_PROVIDER. | | Template not found: <name>. Available pr templates: … | Typo, or the template is in a tier that is not being read. Check sinscribe template path and sinscribe template list. | | Template <name> is a commit template, not a pr template. | A user or project template shadows a built-in of the same name with a different kind. Rename one of them. | | Template <name> requires a ticket ID, but none was found… | The template has a required from: branch slot. Pass --ticket <id> or rename the branch. | | Model did not produce a commit subject. / invalid JSON | The model broke format. pr and branch retry once automatically; otherwise re-run, or try another model with --model-id. | | git … timed out after 30s — a credential or GPG prompt may be blocking. | A git subprocess is waiting on hidden input. Unlock your key, or configure a non-interactive credential helper. | | Model call timed out — … | No output for 120 s, or 10 minutes total on a single-shot command. Usually a stalled connection; the single-shot path retries on its own. | | Unknown option for <cmd>: <flag> (or Unknown option: <flag>) | The flag is not accepted there. sinscribe --help lists every command's options; note there is no per-command help. |

Two tools worth reaching for first:

sinscribe <cmd> --dry-run        # what was detected, with no model call
SINSCRIBE_DEBUG=1 sinscribe <cmd>  # provider, model, and thread on stderr

How it works

  • pr / commit / branch / prompt are single-shot: the CLI computes the diff and context locally and makes one model call — the model never touches your repo. (Branch creation/rename is a plain git call the CLI makes after you pick a name; the model only suggests names.)
  • context / docs / agents / agent-setup / chat are agentic: a deepagents loop with read tools (and, for the write commands, scoped writes) rooted at the repository.
  • Sinscribe fails gracefully outside a git repository, strips every API key from the environment its agent's shell receives, and keeps secrets out of all output and logs.

Built with Ink, LangChain / LangGraph, and deepagents. See docs/ARCHITECTURE.md for the internals and DESIGN.md for design decisions.

Development

pnpm dev pr --dry-run      # run from source (tsx); note: no "--" separator
pnpm test                  # vitest
pnpm lint:check && pnpm format:check
pnpm build

CI (.github/workflows/ci.yml) runs the same checks on push and PR, on Node 20 and 22. Setup, quality gates, house conventions, and the release process live in docs/CONTRIBUTING.md.

Why I built this

I basically live in the terminal, and lately it feels like every other tool shipping in tech is a CLI. I wanted to see what it actually takes to build one today — so I made something I'd use every day: a little assistant that shaves friction off my real workflow. The Pragmatic Programmer puts it well: invest in your tools, sharpen them, and let them make you faster. This is me taking that advice literally.

Credits

Inspired by openwiki, whose agentic-CLI skeleton (provider abstraction, config/secrets layer, agent loop) gave Sinscribe its starting point. The domain — git workflows, templates, and per-branch sessions — is Sinscribe's own.