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

@bstrehl/tix

v0.1.0

Published

Local-first Markdown ticket CLI

Readme

tix

Local-first Markdown PRDs and tickets for coding-agent workflows.

tix stores planning state in .tix/ inside a repository. Markdown files are the canonical source of truth; there is no generated database or index to keep in sync.

Install And Run

This repository is a Node 20+ TypeScript CLI.

After publishing, install the scoped npm package:

npm install -g @bstrehl/tix

The package installs the tix binary.

For local development:

npm install
npm run build
npm test

During development, run the CLI through tsx:

npm run dev -- --help
npm run dev -- init
npm run dev -- list

After building, the package exposes the tix binary from dist/cli.js. When installed or linked, use:

tix --help
tix init

Available project scripts:

  • npm run dev -- <args> runs src/cli.ts.
  • npm run build compiles TypeScript into dist/.
  • npm test runs the Vitest suite once.
  • npm run test:watch runs Vitest in watch mode.
  • npm run typecheck runs tsc --noEmit.

Quick Start

Initialize .tix/ in a project:

tix config init # optional: create ~/.config/tix/config.md defaults
tix init

Create a PRD and a few tickets:

tix prd create -t "Search v1" --label needs-triage --body "Build local search."
tix create -t "Index files" --prd A --label needs-triage --priority high -b "Build the file index."
tix create -t "Search index" --prd A --depends-on 1

Pick the next eligible ticket, read its agent context, and update state:

tix next
tix ticket 1
tix work 1
tix comment 1 "Started implementation."
tix done 1
tix check

Run a configured headless agent:

tix run 1
tix loop A

Core Model

tix has two object types:

  • PRDs use Excel-style uppercase letter IDs: A, B, Z, AA.
  • Tickets use global positive integer IDs: 1, 2, 3.

Object IDs are intentionally simple:

  • tix A reads PRD A.
  • tix 19 reads ticket 19.
  • Mixed IDs such as A1 are invalid.

The project root is the nearest parent directory containing .tix/. Commands can be run from nested directories inside that project.

Files

tix init creates:

.tix/
  config.md
  prompts.md
  prds/
  tickets/
  tmp/
  locks/

When run inside a Git repository, tix init defaults to adding runtime paths to .gitignore:

.tix/tmp/
.tix/locks/

Use tix init --gitignore all to ignore the whole .tix/ directory for local-only planning state, or tix init --gitignore none to leave .gitignore untouched.

Canonical planning state:

  • .tix/prds/*.md stores PRDs.
  • .tix/tickets/*.md stores tickets.
  • .tix/config.md stores agent commands.
  • .tix/prompts.md stores reusable prompt sections.
  • .tix/allocation.md stores the last allocated ticket ID and PRD number.

Runtime state:

  • .tix/tmp/run-*/prompt.md is the exact prompt sent to an agent.
  • .tix/tmp/run-*/stdout.txt captures agent stdout.
  • .tix/tmp/run-*/stderr.txt captures agent stderr.
  • .tix/locks/ticket-<id>.json prevents concurrent runs for the same ticket.

Command Reference

All examples use the installed binary name, tix. In this source repo, replace tix with npm run dev -- while developing.

Help And Version

tix --help
tix help
tix <command> --help
tix --version

tix init

Initializes .tix/ in the current directory.

tix init
tix init --gitignore runtime
tix init --gitignore all
tix init --gitignore none

The command is idempotent. It creates missing paths without overwriting existing config.md or prompts.md.

Options:

  • --gitignore runtime adds .tix/tmp/ and .tix/locks/ when inside a Git repository. This is the default and keeps PRDs, tickets, config, and prompts shareable in the repo.
  • --gitignore all adds .tix/ when inside a Git repository. Use this when tix state should stay local-only.
  • --gitignore none does not create or update .gitignore.

If ~/.config/tix/config.md exists, tix init copies it into a new .tix/config.md. Existing project config is never overwritten.

tix config init

Initializes the global config template at ~/.config/tix/config.md.

tix config init

The command creates the same starter config format used by project init and is idempotent. Edit this file to configure default agents and agent commands for future projects. It seeds new projects only; tix run and tix loop read the project's .tix/config.md.

tix prd create

Creates a PRD and prints the new file path.

tix prd create -t "Title"
tix prd create --title "Title" --body "Markdown body"
tix prd create -t "Title" -F body.md
tix prd create -t "Title" -F -
tix prd create -t "Title" --label needs-triage

Options:

  • -t, --title <title> is required.
  • --body <body> uses inline Markdown body text.
  • -F, --body-file <path> reads the body from a file.
  • -F - reads the body from stdin.
  • --label <label> applies an initial label. It is repeatable and accepts comma-separated values.

Use either --body or --body-file, not both.

New PRDs start with status active.

tix prd list

Lists PRDs as tab-separated rows:

<id> <status> <title>

Commands:

tix prd list
tix prd list --status active
tix prd list --status done
tix prd list --status archived
tix prd list --label needs-triage

--status and --label are literal filters. --status does not validate against built-in PRD statuses.

tix prd <id>

Reads a PRD Markdown file.

tix prd A
tix A

If the PRD has tickets, read output includes a computed ## Ticket Summary section:

## Ticket Summary

- 1 [todo] Build index
- 2 [done] Wire search

tix create

Creates a ticket and prints the new file path.

tix create -t "Title"
tix create -t "Title" -b "Markdown body"
tix create -t "Title" -F ticket.md
tix create -t "Title" -F -
tix create -t "Title" --prd A
tix create -t "Title" --label needs-triage
tix create -t "Title" --priority urgent
tix create -t "Title" --depends-on 1,2
tix create -t "Title" --depends-on 1 --depends-on 2
tix create -t "Title" --agent codex

Options:

  • -t, --title <title> is required.
  • -b, --body <body> uses inline Markdown body text.
  • -F, --body-file <path> reads the body from a file.
  • -F - reads the body from stdin.
  • --label <label> applies an initial label. It is repeatable and accepts comma-separated values.
  • --prd <id> assigns the ticket to an existing PRD.
  • --priority <priority> sets urgent, high, normal, or low.
  • --depends-on <ids> sets dependencies. It is repeatable and accepts comma-separated values.
  • --agent <agent> sets a ticket-specific agent from .tix/config.md.

New tickets start with status todo. The default priority is normal.

The command validates PRD references, dependency ticket IDs, priority values, and agent names before allocating an ID.

tix edit <id>

Edits ticket metadata or body non-interactively and prints the ticket file path.

tix edit 1 -t "New title"
tix edit 1 -b "Replacement body"
tix edit 1 -F body.md
tix edit 1 --prd B
tix edit 1 --no-prd
tix edit 1 --priority high
tix edit 1 --depends-on 2,3
tix edit 1 --depends-on ""
tix edit 1 --status doing
tix edit 1 --agent claude

Options:

  • -t, --title <title> replaces the title.
  • -b, --body <body> replaces the body.
  • -F, --body-file <path> replaces the body from a file or stdin.
  • --prd <id> assigns the ticket to an existing PRD.
  • --no-prd removes the PRD assignment.
  • --priority <priority> sets urgent, high, normal, or low.
  • --depends-on <ids> replaces dependencies.
  • --status <status> changes status after validating built-in statuses.
  • --agent <agent> sets a ticket-specific configured agent.

--status through edit appends a status log only when the status changes.

tix status <id> <status>

Changes a ticket or PRD status and prints the file path.

tix status 1 doing
tix status 1 blocked
tix status A archived

Ticket statuses are fixed to todo, doing, blocked, review, and done. PRD statuses are fixed to active, done, and archived.

Status changes append a parseable log entry under ## Log. Reapplying the current status is a no-op and does not write another status log.

Ticket Status Aliases

Aliases only accept ticket IDs:

tix work 1
tix done 1
tix block 1 "waiting on API details"
tix review 1
tix reopen 1

Alias mapping:

  • work sets doing.
  • done sets done.
  • block sets blocked and optionally writes blocked_reason.
  • review sets review.
  • reopen sets todo.

When a blocked ticket moves to another status, blocked_reason is removed from frontmatter and preserved in the status log entry.

tix label

Adds or removes labels on a ticket or PRD.

tix label add 1 needs-triage
tix label add A needs-triage ready-for-agent
tix label remove 1 needs-triage

Labels are metadata stored in frontmatter and are separate from workflow status. Use labels for triage routing such as needs-triage, needs-info, ready-for-agent, ready-for-human, and wontfix.

tix comment <id> <text...>

Appends a comment log entry to a ticket or PRD and prints the file path.

tix comment 1 "Started the indexer."
tix comment A "Scope clarified with the team."

Logs are Markdown bullets under ## Log:

- 2026-05-15T08:30:00.000Z - comment - Started the indexer.

tix ticket <id>

Reads assembled ticket working context for an agent.

tix ticket 1
tix ticket 1 --prompt custom-section
tix 1

Output can include, in order:

  • ## Repo Prompt from .tix/prompts.md.
  • ## PRD Ticket Prompt from the ticket PRD's ## Ticket Prompt section.
  • ## Ticket Prompt from .tix/prompts.md, or a custom prompt section.
  • ## Ticket Frontmatter.
  • ## Ticket Body.
  • ## Ticket Log.

The ticket body's ## Log section is separated into ## Ticket Log so the log does not appear twice.

When --prompt <section> is passed, the named section must exist in .tix/prompts.md; missing explicit prompt sections fail instead of silently omitting the prompt.

tix run <id>

Runs a configured headless agent for one ticket.

tix run 1
tix run 1 --agent codex
tix run 1 --follow
tix run 1 --prompt custom-section

Options:

  • --agent <agent> is a fallback when the ticket has no agent frontmatter.
  • --follow streams stdout and stderr while still writing artifacts.
  • --prompt <section> uses a custom agent prompt section from .tix/prompts.md.

Agent resolution order:

  1. Ticket frontmatter agent.
  2. --agent <agent>.
  3. ## Default Agent in .tix/config.md.

run writes artifacts under .tix/tmp/run-<ticket>-<timestamp>-*/ and appends a ticket log entry:

- ... - run - agent=codex exit_code=0 artifacts=.tix/tmp/run-1-...
- ... - run - agent=codex exit_code=143 signal=SIGTERM artifacts=.tix/tmp/run-1-...

It does not change ticket status. The agent prompt tells the worker to run tix work <id> at the start and finish with tix done <id> or tix block <id> "reason".

Exit behavior:

  • A zero agent exit code exits zero.
  • A non-zero agent exit code becomes the tix run exit code.
  • In quiet mode, failures print the artifact directory and the last stderr lines.
  • SIGINT and SIGTERM are forwarded to the child process group.

Environment variables provided to agents:

  • TIX_TICKET_ID
  • TIX_PRD_ID, only when the ticket belongs to a PRD
  • TIX_AGENT
  • TIX_PROMPT_FILE

tix loop

Runs tickets sequentially through tix run.

tix loop
tix loop A
tix loop 1 2 3
tix loop --agent codex
tix loop A --agent codex
tix loop 1 2 3 --agent codex

Modes:

  • No target: repeatedly selects global tix next.
  • One PRD ID: repeatedly selects tix next <prd>.
  • One or more ticket IDs: runs that explicit ordered list.

Loop stops when:

  • there are no eligible tickets,
  • a run exits non-zero,
  • a successful run leaves the ticket in any status other than done,
  • an explicit ticket is not ready.

Explicit ticket readiness requires status todo and all dependencies done.

tix list

Lists tickets as tab-separated rows:

<id> <status> <priority> <prd-or-> <title>

Commands:

tix list
tix list --status todo
tix list --status done
tix list --prd A
tix list --no-prd
tix list --priority high
tix list --depends-on 1
tix list --depends-on 1,2
tix list --label needs-triage

By default, done tickets are hidden. Use --status done to show completed tickets.

tix next [prd]

Selects the highest-priority eligible todo ticket.

tix next
tix next A

Eligibility:

  • status must be todo,
  • all dependencies must have status done,
  • global selection includes tickets with no PRD and tickets in active PRDs,
  • PRD-scoped selection includes tickets in that PRD, even if the PRD is not active.

Priority order:

  1. urgent
  2. high
  3. normal
  4. low

Lower ticket ID breaks ties.

Exit codes:

  • 0: selected a ticket.
  • 2: no eligible tickets and no dependency-blocked tickets remain.
  • 3: no eligible tickets because dependency-blocked tickets remain.
  • 1: command error.

tix blocked

Lists blocked tickets with current reasons:

tix blocked

Rows are tab-separated:

<id> <status> <priority> <prd-or-> <title> <blocked-reason-or->

tix check

Validates local Markdown state without modifying files.

tix check

It reports:

  • malformed or missing frontmatter,
  • missing required id, type, title, or status,
  • filename/frontmatter ID mismatches,
  • duplicate PRD or ticket IDs,
  • unknown ticket or PRD statuses,
  • invalid label metadata,
  • missing PRD references,
  • missing dependency ticket references,
  • dependency cycles,
  • ticket agents not configured in .tix/config.md,
  • malformed .tix/allocation.md.

It does not check whether agent commands exist on PATH.

.tix/config.md

config.md controls headless agent commands. tix init creates:

# Tix Config

## Default Agent

codex

## Agents

- codex: codex exec -
- claude: claude -p

If ~/.config/tix/config.md exists, tix init copies that file into new projects instead of using the built-in starter config. Create the global file with tix config init, then edit it to change the default agent set used for future projects. Existing .tix/config.md files are not updated from global config.

Default Agent

## Default Agent selects the fallback agent for tix run and tix loop:

## Default Agent

codex

Leave this section empty only if every run will specify an agent through ticket frontmatter or --agent. If no agent can be resolved, run fails.

Agents

The compact syntax is:

## Agents

- codex: codex exec -
- claude: claude -p
- reviewer: codex exec -

The heading syntax is also supported:

## Agents

### codex

- command: codex exec -

### claude

- status: active
- command: claude -p
- prompt: stdin

Only command affects execution. status and prompt are accepted for legacy configs but are otherwise ignored.

Agent command behavior:

  • Commands run from the project root.
  • Commands are shell strings.
  • By default, the assembled run prompt is sent on stdin.
  • If the command contains {prompt_file}, tix writes the prompt to a file and substitutes the shell-quoted prompt file path.
  • If the command contains {prompt}, tix substitutes the shell-quoted prompt text as an argument.
  • If either placeholder is used, stdin is empty.
  • Exact legacy commands codex and claude are normalized to codex exec - and claude -p.

Examples:

## Agents

- codex: codex exec -
- claude: claude -p
- file-agent: my-agent --prompt-file {prompt_file}
- arg-agent: my-agent --prompt {prompt}

.tix/prompts.md

prompts.md stores reusable prompt sections. tix init creates:

# Tix Prompts

## repo

You are working in this repository. Inspect the code before editing and keep changes scoped to the active ticket.

## ticket

Work only on the requested ticket. Update status and logs with tix commands as you make progress.

## agent

You are a headless coding agent. Start by running `tix work <ticket>` when work begins and finish with `tix done <ticket>` or `tix block <ticket> "reason"`.

Prompt section names are normalized by trimming, lowercasing, and collapsing whitespace. ## Custom Section is selected with --prompt "custom section". When a custom section is requested explicitly, it must exist.

If any default section is missing, tix omits it instead of failing.

repo

Included in tix ticket <id> output as ## Repo Prompt.

Use it for repository-wide instructions that apply to every ticket:

## repo

Inspect the code before editing. Keep changes focused. Run relevant tests before marking a ticket done.

ticket

Included in tix ticket <id> output as ## Ticket Prompt.

Use it for instructions that apply whenever an agent reads a ticket:

## ticket

Work only on this ticket. Update progress with `tix work`, `tix comment`, `tix done`, or `tix block`.

Override it per read with:

tix ticket 1 --prompt bugfix

agent

Included in tix run <id> prompts as ## Agent Prompt.

Use it for instructions specific to headless agent execution:

## agent

Start by running `tix work <ticket>`. Commit no changes unless explicitly instructed. Finish by running `tix done <ticket>` or `tix block <ticket> "reason"`.

Override it per run with:

tix run 1 --prompt cautious-agent

Custom Sections

Add any extra ## section and select it with --prompt:

## bugfix

Reproduce the bug first, add a regression test, then implement the smallest fix.

## cautious-agent

Make no broad refactors. Stop and block the ticket if requirements conflict with existing architecture.

Custom sections can be used by:

  • tix ticket <id> --prompt <section>
  • tix run <id> --prompt <section>

PRD-Level Ticket Prompt

A PRD can define a ## Ticket Prompt section. When a ticket belongs to that PRD, tix ticket <id> includes that section as ## PRD Ticket Prompt.

Example PRD body:

The search v1 work should stay local-first.

## Ticket Prompt

For tickets in this PRD, preserve backwards compatibility and document migration steps.

Only the ## Ticket Prompt section is included in ticket read output. The rest of the PRD body is not embedded.

Markdown Formats

PRD Files

PRDs live in .tix/prds/ and use filenames such as A-search-v1.md.

---
id: "A"
type: "prd"
title: "Search v1"
status: "active"
labels: ["needs-triage"]
---

PRD body.

Ticket Files

Tickets live in .tix/tickets/ and use filenames such as 1-index-files.md.

---
id: 1
type: "ticket"
title: "Index files"
status: "todo"
prd: "A"
labels: ["needs-triage","ready-for-agent"]
priority: "high"
dependencies: [2,3]
agent: "codex"
blocked_reason: "waiting on API details"
---

Ticket body.

## Log

- 2026-05-15T08:30:00.000Z - status - todo -> doing

Required fields for valid PRDs and tickets:

  • id
  • type
  • title
  • status

PRD optional fields:

  • labels

Ticket optional fields:

  • prd
  • labels
  • priority
  • dependencies
  • agent
  • blocked_reason

Frontmatter values are serialized as JSON strings for strings and arrays.

Recommended Agent Workflow

  1. Select work with tix next or use an assigned ticket ID.
  2. Read context with tix ticket <id>.
  3. Start with tix work <id>.
  4. Leave progress notes with tix comment <id> "...".
  5. Finish with tix done <id> or tix block <id> "specific blocker".
  6. Run tix check after changing .tix state.

Current Scope

Implemented scope:

  • local Markdown PRDs and tickets,
  • command-based creation, editing, listing, reading, status changes, and logs,
  • label metadata and label filters,
  • dependency-aware next,
  • read-only check,
  • sequential run and loop orchestration,
  • configurable headless agents.

Intentionally not implemented:

  • delete commands,
  • assignees, milestones, or external project fields,
  • JSON output,
  • Git branch, commit, or PR helpers,
  • remote issue tracker sync,
  • parallel loop execution.