Commands

chamoji ws

ws.mdEdit on GitHub

List and manage workstreams. A workstream is a piece of work that takes more than one commit, such as “Keyboard support”. Its commits carry a Workstream: line, and once it ships, the changelog shows them as one Highlight.

CHANGES YOUR REPO --json FOR CI AND AGENTS

git commit stamps the Workstream: line only through chamoji’s hook, and git doesn’t clone hooks. Run chamoji hook install once in each clone, or commit with chamoji commit.

CHANGES YOUR REPOchamoji ws

What it does, in order

  1. ws start. Adds the workstream to .chamoji/workstreams.yml, stages the file, and makes the workstream active in this worktree. It says whether git commit will stamp your commits.
  2. Your commits. While it’s active, the hook and chamoji commit add Workstream: <slug> to each new commit made with -m or the composer.
  3. ws ship. Marks it shipped in the file, stages the file, stops stamping it, and saves its commits on this branch to project memory.
  4. Your next commit. Records the change to the file. From then on, the changelog’s next release folds the workstream’s commits into one Highlight. Earlier releases don’t change.

None of it touches the network or commits for you. The file is committed and shared with your team. Which workstream is active is per worktree, in .git/chamoji/active. Workstreams has what gets stamped and how squash merges keep it.

Subcommands

  • Name
    chamoji ws
    Description

    List the workstreams, with each one’s slug, status, emoji, title and its commits since the latest tag on this branch. * marks the active one. chamoji ws list is the same.

  • Name
    chamoji ws start <title> [emoji]
    Description

    Start a workstream and make it active. Quote a title of several words: chamoji ws start "Auth revamp" 🔐. The slug comes from the title, such as auth-revamp. A slug that exists already exits 1.

  • Name
    chamoji ws switch <slug>
    Description

    Make another workstream active. It must exist and still be active, or it exits 1. With --none instead of a slug, no workstream is active.

  • Name
    chamoji ws ship [slug]
    Description

    Mark a workstream shipped, the active one when you name none, and save its commits to memory.

  • Name
    chamoji ws drop [slug]
    Description

    Mark a workstream dropped, the active one when you name none, and save its commits to memory. Its commits stay loose in the changelog.

Arguments

  • Name
    title
    Type
    string · required by start
    Description

    The workstream’s name, as the changelog shows it. Quote it when it has spaces.

  • Name
    emoji
    Type
    string · optional, start
    Description

    Shown before the title in the list and the changelog, such as 🔐. A word in its place exits 2, because it usually means an unquoted title.

  • Name
    slug
    Type
    string
    Description

    The workstream’s id, as chamoji ws lists it. Required by switch, unless you pass --none. Optional for ship and drop.

Flags

  • Name
    --json
    Type
    boolean · list
    Description

    Print the workstreams as a JSON array. Each has slug, title, status, active and commits, plus emoji, description and links when the file sets them. Only for the list; the other subcommands ignore it.

  • Name
    --none
    Type
    boolean · switch
    Description

    With ws switch: clear the active workstream. Not with a slug; both exit 2.

  • Name
    --no-update-check
    Type
    boolean
    Description

    Don’t check npm for a newer chamoji. See the update notice.

Common combinations

chamoji ws start "Auth revamp" 🔐

Start a piece of work, and stamp what you commit next.

chamoji ws

What’s open, what’s active, and how many commits each has waiting.

chamoji ws ship

Mark the active one shipped, then commit the file.

chamoji ws switch --none

Commit something unrelated without a Workstream line.

chamoji ws --json

The workstreams, for a script or an agent.

Output

These are from real runs in a small repo called widgets. With none yet:

chamoji ws

No workstreams yet. Start one with: chamoji ws start <title> [emoji]

In a clone without the hook, start warns on stderr:

chamoji ws start "Keyboard support" ⌨️

Started keyboard-support. Staged .chamoji/workstreams.yml; your next commit records it.
chamoji: no hook runs chamoji here, so `git commit` won't add "Workstream: keyboard-support". Run `chamoji hook install`, or commit with `chamoji commit`.

With the hook installed:

chamoji ws start "Dark mode" 🌙

Started dark-mode. Staged .chamoji/workstreams.yml; your next commit records it.
New commits in this worktree get "Workstream: dark-mode".

A -m commit gets the line:

git log -1 --format=%B

✨ Move between days with the arrow keys

Workstream: keyboard-support

chamoji ws

  keyboard-support  active  ⌨️ Keyboard support  2 commits
* dark-mode         active  🌙 Dark mode         1 commit

chamoji ws --json

[
  {
    "slug": "keyboard-support",
    "title": "Keyboard support",
    "status": "active",
    "emoji": "⌨️",
    "active": false,
    "commits": 2
  },
  {
    "slug": "dark-mode",
    "title": "Dark mode",
    "status": "active",
    "emoji": "🌙",
    "active": true,
    "commits": 1
  }
]

Switch, ship and drop

$ chamoji ws switch keyboard-support
Switched to keyboard-support.
New commits in this worktree get "Workstream: keyboard-support".

After both changes are committed:

chamoji ws

  keyboard-support  shipped  ⌨️ Keyboard support  2 commits
  dark-mode         dropped  🌙 Dark mode         1 commit

The shipped workstream is one Highlight in the changelog. The dropped one’s commit stays loose:

chamoji changelog --from v0.2.1

# Changelog

## Unreleased

### Highlights

- ⌨️ **Keyboard support**
  - ✨ Move between days with the arrow keys (83832de)
  - 🐛 Trap focus inside the dialog (8970246)

### Changed

- 🔧 Drop dark mode for now (c7f432c)
- 🔧 Ship keyboard support (b0bf4bf)
- 💄 Add dark colours to the picker (cae8275)

Errors

$ chamoji ws start Auth revamp
chamoji: ws start takes a title and an optional emoji; quote a title of several words: chamoji ws start "Auth revamp" 🔐

Exit codes

  • Name
    0
    Description
    It worked.
  • Name
    2
    Description

    It was used wrongly: an unknown subcommand, start with no title or an unquoted one, or switch with neither a slug nor --none, or both.

  • Name
    1
    Description

    Anything else, such as a workstream that doesn’t exist or isn’t active, a slug that’s taken, ship or drop with nothing active, or outside a git repo.

Exit codes has every command’s codes.

Was this page helpful?