Skip to content

CommandOutput ​

Type, in @jr2/orchestrator/src/effect.ts. It is an export of @jr2/orchestrator, on the Authoring surface page, in Effects.

ts
type CommandOutput = (ExecOutcome & { dirty?: boolean }) | Unknown;

The output of a command Effect: what the onDone of its state gets as event.output. Every outcome is output. A failed program is output too. Route on outcome:

  • exited: the program ended. code is its exit code. A program that the container does not have is exited with code 127.
  • timeout: the command ran past its timeout, and jr2 killed it.
  • killed: a signal ended it. signal names the signal.
  • unknown: jr2 cannot tell what the command did, for example because the Harness restarted while it ran. reason tells why. jr2 does not run it again.

tail is the end of what the command wrote, at most the tail option of command in characters. dirty is true when a command that names an Effect secret ran against a commit, and the Worktree held changes that it did not see.

Forms: it is one of these objects.

  • Form 1: outcome, code, tail, dirty

    • outcome: "exited"
    • code: number
    • tail: string
    • dirty (optional): boolean
  • Form 2: outcome, tail, dirty

    • outcome: "timeout"
    • tail: string
    • dirty (optional): boolean
  • Form 3: outcome, signal, tail, dirty

    • outcome: "killed"
    • signal: string
    • tail: string
    • dirty (optional): boolean
  • Form 4: outcome, reason

    • outcome: "unknown"
    • reason: string

Example

ts
import {
  command,
  type CommandOutput,
  fail,
  jr2Setup,
  workspace,
  type Workspaced,
} from "@jr2/orchestrator";

type Input = Workspaced<{}, "app">;

const passed = (output: CommandOutput): boolean =>
  output.outcome === "exited" && output.code === 0;

const body = jr2Setup({
  types: {} as { context: Input; input: Input },
  actors: { tests: command(["npm", "test"], { timeout: "15m" }), fail: fail() },
}).createMachine({
  id: "tests",
  context: ({ input }) => input,
  on: { "workspace.lost": ".lost" },
  initial: "testing",
  states: {
    testing: {
      invoke: {
        src: "tests",
        onDone: [
          { guard: ({ event }) => passed(event.output), target: "green" },
          { target: "red" },
        ],
      },
    },
    green: { type: "final" },
    // Not a final state: a final state means `done`, and the run ends `failed` here.
    red: { invoke: { src: "fail", input: { reason: "npm test did not pass" } } },
    lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
  },
});

export const machine = workspace(body, {
  repos: { app: { url: "https://github.com/you/app.git" } },
  spec: () => ({ branch: "tests" }),
});

See also

The docs of Kit version 0.5.1. Each page is also at its .md URL.