CLI Commands

The workjournal CLI provides a resource-oriented command hierarchy for managing workspaces, journals, entries, shares, and invitations from the terminal.

For AI agent commands, see Skill Commands.

Install the CLI globally or use via npx:

npx @workjournal/cli <command>

Every resource verb takes positional <workspaceSlug> and (for journal-scoped verbs) <journalSlug> arguments. Setting an active workspace + journal with workjournal workspaces select / workjournal journals select enables two shortcut forms (workjournal and workjournal journal) but does not make the positional slugs optional on other commands — scripts stay self-documenting.


Manage workspaces (workjournal workspaces)

workjournal workspaces list

List all workspaces you belong to.

workjournal workspaces get <workspaceSlug>

Print details of a specific workspace.

workjournal workspaces select <workspaceSlug>

Set a workspace as the active workspace in global-config.

Looking for a journal shared with you from another workspace? See Shared-with-me Journals — those don’t appear under workspaces list and aren’t selectable here.

Workspace creation is API-only today — every signed-in user has their personal workspace auto-provisioned. Multi-workspace creation will land with the paid-tier signup flow.


Manage journals (workjournal journals)

workjournal journals list <workspaceSlug>

List all journals in the workspace. Pass the reserved slug shared-with-me to list journals shared with you from workspaces you don’t own — see Shared-with-me Journals below.

workjournal journals get <workspaceSlug> <journalSlug>

Print details of a specific journal.

workjournal journals new <workspaceSlug> <name>

Create a new journal in the workspace. The slug is auto-generated from <name>; override with --slug <slug>.

workjournal journals delete <workspaceSlug> <journalSlug>

Delete a journal. Requires owner role.

workjournal journals select <workspaceSlug> <journalSlug>

Set a journal as the active journal in config (global + project when running inside a git repo). Works for owned and shared journals — the underlying journals_visible view permits both owners and contributors. For shared journals, use the workspace slug returned by workjournal journals list shared-with-me. The reserved slug shared-with-me is not a valid <workspaceSlug> here. See Shared-with-me Journals below.

workjournal journals rename <workspaceSlug> <journalSlug> <newName>

Change the journal’s display name. The slug is unaffected, so existing links keep working.

workjournal journals set-slug <workspaceSlug> <journalSlug> <newSlug>

Change the journal’s URL slug. The CLI prints a stderr warning before the call — old <workspaceSlug>/<journalSlug> URLs will return 404 after the change. Use rename if you only want to change the human name.


Shared-with-me Journals

A shared journal is one where you’re a contributor in someone else’s workspace. Accept the invitation in the web app first, then from the terminal:

# 1. List — two-column table: workspace slug, journal slug
workjournal journals list shared-with-me

# 2. Select — pass both slugs from the listing
workjournal journals select acme engineering

# 3. Access — all other commands work as normal against the pinned journal
workjournal entries last
workjournal entries write -t … -s … -b …

shared-with-me is recognised only by journals list. journals select and everything else take the real workspace slug from the listing (acme, not shared-with-me).


Selected journal (workjournal journal)

Operates against the workspace + journal written to project-config by workjournal journals select. Errors with a helpful message if no active journal is set.

workjournal journal

Show the selected journal’s details.


Entries (workjournal entries)

workjournal entries list <workspaceSlug> <journalSlug>

List entries (newest first).

workjournal entries write <workspaceSlug> <journalSlug> -t <title> -s <summary> [-b <body> | -b - | --body-file <path>] [--tags <a,b,c>]

Create a new entry. -t is required and capped at 80 characters; -s is the paragraph-length summary used for AI retrieval. The body comes from exactly one source: inline -b <body>, stdin -b - (e.g. cat entry.md | workjournal entries write ...), or --body-file <path>. Combining --body-file with any -b is rejected. Prefer --body-file or stdin for long bodies that would exceed ARG_MAX or contain shell-fragile characters (backticks, $, embedded quotes, newlines). --tags is an optional comma-separated list of tag names (Plus+); every tag must already be assigned to the journal — see workjournal tags assign below.

workjournal entries last <workspaceSlug> <journalSlug> [count]

Show the most recent entries (date descending). [count] defaults to 1.

workjournal entries get <workspaceSlug> <journalSlug> <entryNr>

Get a single entry by its monotonic per-journal index.

workjournal entries update <workspaceSlug> <journalSlug> <entryNr> [-t <title>] [-s <summary>] [-b <file>|-] [--tags <a,b,c>]

Update title, summary, body, and/or tags of an existing entry. At least one of -t, -s, -b, or --tags is required. -b - reads the body from stdin; -b <path> reads from a file. --tags replaces the entire tag set on the entry — pass --tags '' to clear them. created_at and index stay fixed; updated_at advances. Use this to append verification notes or fix a typo without losing the entry’s original timestamp.

workjournal entries delete <workspaceSlug> <journalSlug> <entryNr>

Delete an entry by index.

workjournal entries search <workspaceSlug> <journalSlug> <query>

Search entries by keyword (Postgres full-text search). Available on every tier.

workjournal entries semantic-search <workspaceSlug> <journalSlug> <query> [--limit N]

Semantic (RAG) search — ranks markdown-aware chunks of every entry by cosine similarity against the query embedding. Use when you remember the idea but not the exact words (e.g. "retry-with-backoff decision" rather than "retry"). Returns the matching chunks with their parent entry pointer and a similarity score — follow up with entries get for the full body. Pro+ tier; Free/Plus workspaces get a tier-rejection error verbatim. --limit defaults to 10, capped at 50 server-side.


Tags (workjournal tags)

A Plus+ feature. Tags are a workspace-level vocabulary you can attach to entries. A tag must first exist in the workspace registry (tags new) and then be assigned to a journal (tags assign) before it can be used on an entry in that journal. Editing or removing a tag cascades to every entry that referenced it across every assigned journal. Free workspaces can’t create tags, but they can clear leftover tags from entries (entries update --tags "").

workjournal tags list <workspaceSlug> [--journal <journalSlug>]

List every tag in the workspace registry. With --journal, each row is annotated with assigned: true|false for that journal.

workjournal tags get <workspaceSlug> <tagName> [--journal <journalSlug>]

Print details of a single tag. With --journal, includes the assigned flag for that journal.

workjournal tags new <workspaceSlug> <name> [-d <description>]

Create a tag in the workspace registry. <name> is kebab-case, ≤ 50 chars, unique within the workspace. -d adds an optional description (≤ 200 chars) that agents see when picking tags.

workjournal tags update <workspaceSlug> <tagName> [-n <newName>] [-d <description>]

Rename a tag and/or update its description. Renaming cascades to every entry that already carries the tag, across every assigned journal — runs in one transaction so failure rolls both back.

workjournal tags delete <workspaceSlug> <tagName>

Delete a tag from the registry. Cascade-strips it from every entry across every assigned journal. Allowed at any tier so downgraded workspaces can clean up leftover data.

workjournal tags assign <workspaceSlug> <journalSlug> <tagName>

Make a registry tag usable on entries in this journal. Returns 409 CONFLICT if the tag is already assigned. Plus+.

workjournal tags unassign <workspaceSlug> <journalSlug> <tagName>

Remove the tag from this journal. Cascade-strips the tag’s name from every entry in this journal (entries in other journals are unaffected). Returns 404 NOT_FOUND if the tag was never assigned. Allowed at any tier.


Shares — contributors (workjournal shares)

workjournal shares list <workspaceSlug> <journalSlug>

List contributors of the journal.

workjournal shares delete <workspaceSlug> <journalSlug> <email>

Remove a contributor’s access (CLI resolves email to user_id internally).


Invites (workjournal invites)

workjournal invites list <workspaceSlug> <journalSlug>

List pending invitations.

workjournal invites new <workspaceSlug> <journalSlug> <email>

Invite a collaborator by email.

workjournal invites delete <workspaceSlug> <journalSlug> <invitationId>

Revoke a pending invitation.


Export

workjournal export <workspaceSlug> <journalSlug> [-f <json|md|csv>] [-p <path>]

Export journal data. -f defaults to json. -p writes to a file instead of stdout.


Auth

workjournal auth login

Run the authentication flow. Opens a browser to app.workjournal.pro/authorize for OAuth login with PKCE. Credentials are stored in the user config directory (~/.config/workjournal/credentials.json on Linux/macOS, %APPDATA%\workjournal\credentials.json on Windows; override with WORKJOURNAL_CONFIG_DIR).

Works in local terminals, SSH sessions, dev containers, and CI — no browser is needed on the same machine. In headless environments, use the two-phase flow: workjournal auth login start prints a URL, then workjournal auth login finish <CODE> exchanges the pasted code for credentials.

workjournal auth logout

Remove stored credentials. You’ll need to run workjournal auth login again to use the CLI.

workjournal auth whoami

Show current auth status.

workjournal auth status

Show detailed auth status, including token expiry.


Config

workjournal config show

Show resolved config (project + global), including the selected workspace and journal.


Shortcuts

ShortcutResolves to
workjournalworkjournal entries list <selected-ws> <selected-j>
workjournal journalsworkjournal journal (selected journal details)

Help & feedback

Every subcommand has a structured help block — for humans (--help) and for agents (--help --json):

workjournal entries update --help
workjournal entries update --help --json
workjournal --help          # top-level
workjournal --version       # version + feedback URL

Found a bug, ergonomics gap, or surprising CLI behaviour? File it at github.com/workjournal-pro/feedback/issues. The same URL is surfaced from workjournal --help, workjournal --version, and any unhandled-error output.