Skip to main content
Smithers exports a small JJ helper surface for applications that want to inspect or manage Jujutsu state directly. These helpers are intentionally lightweight:
  • every helper accepts an optional cwd so you can target a specific repository
  • spawn failures are normalized instead of throwing, which makes them safe to call even when jj is not installed
  • workspace helpers try a few command shapes to tolerate JJ version drift

Import

import {
  runJj,
  getJjPointer,
  revertToJjPointer,
  isJjRepo,
  workspaceAdd,
  workspaceList,
  workspaceClose,
} from "smithers-orchestrator";

runJj(args, opts?)

Run an arbitrary jj command and capture its output.
const result = await runJj(["status"], { cwd: "/path/to/repo" });
type RunJjOptions = {
  cwd?: string;
};

type RunJjResult = {
  code: number;
  stdout: string;
  stderr: string;
};
Notes:
  • returns { code: 127, stdout: "", stderr: "..." } when jj cannot be started
  • does not throw for ordinary process failures
  • useful when you need a raw escape hatch beyond the higher-level helpers below

getJjPointer(cwd?)

Return the current workspace change_id for @, or null when JJ is unavailable or the current directory is not a JJ repo.
const pointer = await getJjPointer("/path/to/repo");
function getJjPointer(cwd?: string): Promise<string | null>;
Smithers uses the same pointer model internally for revert support and cache invalidation.

revertToJjPointer(pointer, cwd?)

Restore the working copy from a previously recorded JJ pointer.
const result = await revertToJjPointer("zqkopwvn", "/path/to/repo");
type JjRevertResult =
  | { success: true }
  | { success: false; error?: string };
This helper wraps jj restore --from <pointer>.

isJjRepo(cwd?)

Detect whether a directory is a readable JJ repository.
const enabled = await isJjRepo("/path/to/repo");
function isJjRepo(cwd?: string): Promise<boolean>;
Use this before showing JJ-specific UI or attempting a revert flow.

workspaceAdd(name, path, opts?)

Create a JJ workspace with a friendly name at a target filesystem path.
const result = await workspaceAdd("feature-auth", "/tmp/wt-feature-auth", {
  cwd: "/path/to/repo",
  atRev: "@",
});
type WorkspaceAddOptions = {
  cwd?: string;
  atRev?: string;
};

type WorkspaceResult =
  | { success: true }
  | { success: false; error?: string };
Behavior notes:
  • removes an existing workspace with the same name before retrying
  • recreates the target directory if needed
  • tries multiple jj workspace add syntaxes to work across JJ versions

workspaceList(cwd?)

List known workspaces for the current JJ repo.
const workspaces = await workspaceList("/path/to/repo");
type WorkspaceInfo = {
  name: string;
  path: string | null;
  selected: boolean;
};
The current implementation prefers template output when supported, then falls back to parsing the human-readable jj workspace list output.

workspaceClose(name, opts?)

Forget a JJ workspace by name.
const result = await workspaceClose("feature-auth", {
  cwd: "/path/to/repo",
});
function workspaceClose(
  name: string,
  opts?: { cwd?: string },
): Promise<WorkspaceResult>;
This wraps jj workspace forget <name>.

When To Use These Helpers

Use these helpers when your application needs to:
  • show whether JJ-backed revert is available
  • record or inspect a pointer outside the Smithers engine
  • manage JJ workspaces directly from an app or integration layer
If you only need workflow-level revert behavior, prefer the runtime and CLI docs: