Skip to content

Latest commit

 

History

History
360 lines (281 loc) · 13 KB

File metadata and controls

360 lines (281 loc) · 13 KB

openflow CLI

Agent-facing reference for creating and inspecting OpenFlow work from a shell. For dev setup, environment isolation, and packaging see docs/development.md; for design rationale see docs/subdocs/cli-design.md.

The CLI reads OpenFlow metadata from OPENFLOW_HOME and uses a local bridge to talk to the running app for task creation/start.

User Recipes

Task Creation Tips

Tips for creating OpenFlow work from the CLI:

  1. Discover ids and templates:
    openflow project list --json
    openflow agent list --json
    openflow platform list --json
    openflow workflow list --json
  2. If the task comes after a long planning/debugging discussion, suggest saving that conversation as a plan or reference doc in the working directory or another user-approved location. Attach or cite that doc in the task description/stage prompts so future agents can use it as context.
  3. Before creating or starting anything, show the user the proposed title, project, template, agents, stages, and stage prompts.
  4. Prefer draft task create; it opens the New Task dialog for human review. Use --direct only when the user explicitly asks for immediate creation.
  5. Use --json for structured output. If the CLI returns warnings, report them and adjust the request if needed.
  6. On failure, fix obvious CLI/schema issues locally. If user input is needed, stop and include the exact command, exit code, stderr, and invalid/missing field.

Automation

Direct create + start: capture .taskId from task create --direct --json, then pass it to task start.

Cron/CI can create direct tasks; treat start exit 4 as "queued, start later" if the app is unavailable.

Synopsis

openflow <command> [args]

Commands:
  docs              Recommended first; includes agent task-creation instructions
  task create       Create a new task
  task list         List tasks
  task start        Start a pending task
  task stop         Stop a running task
  task restart      Clone and restart a task
  task resume       Resume a paused/failed task
  task inbox        Send a message to a team task leader
  agent list        List agent prompts
  platform list     List agent platforms
  project list      List projects
  workflow list     List workflow templates

Run openflow <command> --help for command-specific help.

Agents should always run openflow docs first before create openflow task; it includes the openflow bin usage instruction.

Environment and Runtime

Variable Purpose Default
OPENFLOW_HOME Data root the CLI reads/writes ~/.openflow

The CLI does not read the GUI's stored home override. If the app uses a custom home, export the same OPENFLOW_HOME.

task create and task start require the app to be running with System settings -> Local HTTP bridge enabled. List commands read files directly and work without the app.

Exit Codes

Code Meaning
0 success
1 other failure
2 validation failure
3 not found
4 cannot connect to app bridge
5 bridge auth failed
6 task already running or not startable
7 engine not ready

Exit 4

Exit 4 means the CLI could not connect to the local app bridge required by task mutation commands (task create, task start, task stop, task restart, task resume, and task inbox). Common causes:

Cause Check Fix
App is closed No OpenFlow window/process is running Open the app
Local HTTP bridge is disabled System settings -> Local HTTP bridge is off Enable the bridge
CLI and app use different homes OPENFLOW_HOME differs from the app home shown in System settings Export the same OPENFLOW_HOME or unset it
Runtime file is stale $OPENFLOW_HOME/.runtime/cli-port.json exists, but its port is not listening Restart the app
Port is blocked or occupied Bridge log shows bind/connect errors for the configured port Free the port or change the bridge port in System settings
Shell is sandboxed The port is listening on the host, but the command cannot connect from the sandbox Run with host/localhost network access, or run from a normal terminal

task create

# Spec mode
openflow task create --spec @path/to/spec.json [--direct] [--json]
openflow task create --spec - < spec.json
openflow task create --stdin < spec.json

# Inline mode: one stage per --agent, in order
openflow task create \
  --project <name|id> \
  --title "..." \
  [--description "..."] \
  [--team-mode solo|team] \
  [--template <id>] \
  --agent <platform>:<promptId> \
  [--leader <agent-id>] \
  [--direct] \
  [--json]

Default mode opens the New Task dialog pre-filled in the app and returns a draft response. --direct validates the full schema and writes the task immediately.

Required for draft mode: project/projectId and title. Required for --direct: the full spec below.

Team-mode default depends on the path. For normal agent use, omit teamMode unless the user explicitly asks for linear/solo execution:

  • Draft path: if teamMode is omitted, the New Task dialog defaults to team.
  • Direct path: if teamMode is omitted from a full spec, the service schema defaults it to solo.

Spec Shape

{
  "project": "openflow",              // name or id; "projectId" also accepted
  "title": "Add CLI",
  "description": "optional",
  "templateId": "blank",              // audit stamp; default "blank"
  "teamMode": "team",                 // optional; omit in draft mode to use GUI default team
  "leaderAgentInstanceId": null,       // required only for direct team-mode create
  "agentInstances": [
    {
      "id": "builder",                // optional; "instanceId" alias also accepted
      "name": "builder",
      "promptTemplateId": "builder",  // ~/.openflow/agents/<id>.md
      "platform": "codex",            // ~/.openflow/platforms/<id>.yaml
      "extraArg": ""
    }
  ],
  "stages": [
    {
      "name": "build",
      "agentInstanceId": "builder",
      "extraPrompt": "",              // "prompt" alias also accepted
      "needsReview": false
    }
  ],
  "settings": {
    "maxRerunsPerStage": 3,
    "requireFinalReview": true,
    "expectedDurationSec": 300,
    "isolationMode": "worktree"       // "none" | "branch" | "worktree"
  }
}

Only the fields shown in settings are accepted. The CLI prunes unused agentInstances. stages[].agentInstanceId and leaderAgentInstanceId must reference an agent instance id.

Semantics

Field Notes
teamMode: "solo" Stages run sequentially. Previous stage output becomes next stage input. Pauses on failed/review states.
teamMode: "team" A leader agent runs alongside stages and routes via leader/commands.jsonl (dispatch, approve, rerun, complete, chat, noop).
needsReview: true Stage parks in awaiting_review after completion until approved in the GUI.
isolationMode: "none" Agents run in the project repo as-is.
isolationMode: "branch" Engine creates openflow/<slug>-<taskId> in-place; dirty trees are refused.
isolationMode: "worktree" Engine creates <repo>/.worktrees/<taskId> on a new branch.

Branches/worktrees persist after task completion for manual review/cleanup. The desktop app asks by default whether to delete a task-created branch/worktree before archive/delete; this can be disabled in System settings.

Discovering IDs

openflow project list --json     # project ids and repo paths
openflow platform list --json    # platform ids: claude, codex, gemini, ...
openflow agent list --json       # prompt ids: builder, reviewer, ...

The GUI also shows platform, prompt, workflow, project, and task ids.

task list

openflow task list [--project <name|id>] [--status <status>] [--include-archived] [--json]

--status accepts pending, running, paused, awaiting_final_review, done, failed, or cancelled. Default output is ID TITLE STATUS PROJECT CREATED; --json returns full task objects.

Example: openflow task list --project openflow --status pending --json.

project list

openflow project list [--json]

Lists configured projects from $OPENFLOW_HOME/projects; no running app required. Default output is ID NAME PATH CREATED; --json returns full project objects.

agent list

openflow agent list [--json]

Lists agent prompt templates from $OPENFLOW_HOME/agents; no running app required. Default output is ID NAME UPDATED; --json returns full agent prompt objects, including systemPromptMd.

platform list

openflow platform list [--json]

Lists agent platforms from $OPENFLOW_HOME/platforms; no running app required. Default output is ID NAME BUILTIN SPAWN; --json returns full platform objects.

workflow list

openflow workflow list [--json]

Lists templates from $OPENFLOW_HOME/workflows; no running app required. Human output includes template id/name/description, agents, platform/prompt metadata, stages, review gates, and stage prompts.

--json returns the same templates with resolved metadata:

JSON field Meaning
agentInstances[].promptTemplate { id, name } or null
agentInstances[].platformInfo { id, displayName } or null
stages[].agentInstance { id, name } or null
stages[].index 1-based stage position

Recommended agent flow: run workflow list first, ask the user to review the proposed task spec, then use draft task create unless --direct is requested.

task start

openflow task start <task-id-or-prefix> [--leader <agent-instance-id>] [--json]

<task-id-or-prefix> may be a full id or unambiguous prefix. --leader overrides the leader for team-mode starts. --json returns { status, taskId, teamMode }.

task start posts to the running app's bridge and returns after the engine accepts the request; it does not tail logs. Progress is in the GUI, task log, and $OPENFLOW_HOME/logs/main-YYYY-MM-DD.log.

Bridge result Exit Meaning
200 0 accepted
401 5 bad bearer token
404 3 no matching task
409 6 task already running/not pending
422 2 invalid request
503 7 engine not ready
connection refused 4 cannot connect to app bridge

task stop, task restart, task resume

openflow task stop <task-id-or-prefix> [--json]
openflow task restart <task-id-or-prefix> [--json]
openflow task resume <task-id-or-prefix> [--json]

All three commands require the running app bridge and resolve full task ids or unambiguous prefixes in the app-owned repo.

Command Behavior
task stop Calls the engine abort path, kills task tmux sessions, marks active stages failed, and marks the task cancelled.
task restart Aborts the old task, clones it to a fresh task id/stage ids, archives the old task, and starts the clone. JSON includes newTaskId.
task resume Re-enters the engine drive loop for a paused or failed task.

task inbox

openflow task inbox <task-id-or-prefix> --message "..." [--json]

Appends { from: "user", text, ts } to projects/{projectId}/tasks/{taskId}/leader/inbox.jsonl through the running app bridge. Use this for async user guidance to a team-mode leader; the leader reads the inbox on its next tick. Solo tasks return conflict (exit 6).

Install Notes

Repo/dev: pnpm install && pnpm cli:build && pnpm link --global. Dev mode: pnpm cli:dev task list --json.

DMG app: Open OpenFlow -> System settings -> Command line tool -> Install, or:

mkdir -p "$HOME/.local/bin"
ln -sf "/Applications/OpenFlow.app/Contents/Resources/app/bin/openflow" "$HOME/.local/bin/openflow"

Ensure ~/.local/bin is on PATH.

Bridge API

The CLI is a thin HTTP client. Runtime discovery lives at $OPENFLOW_HOME/.runtime/cli-port.json with mode 0600, shaped like { "port": 61234, "token": "...", "pid": 12345, "startedAt": "..." }. The bridge binds 127.0.0.1 only and regenerates the token every start.

Routes: GET /healthz (no auth), POST /tasks (draft create), POST /tasks?mode=direct (direct create), and POST /engine/start. Authenticated routes require Authorization: Bearer <token>.

Troubleshooting

Symptom Likely cause Fix
Openflow CLI cannot connect to the app bridge / exit 4 App closed, bridge disabled, CLI home mismatch, stale runtime file, port blocked, or sandboxed localhost access Use the Exit 4 troubleshooting table above
Exit 5 Runtime token mismatch Restart app
Exit 3 for project/task Typo or ambiguous prefix/name Use exact ids from project list --json, task list --json, or GUI
Exit 2 on create Invalid spec Read stderr paths; check required fields and dangling agent refs
task start returns 0 but task does not progress Engine accepted async then failed Check task log and $OPENFLOW_HOME/logs/main-YYYY-MM-DD.log
Cannot find package 'X' imported from out/cli-bundle/... Stale build/deps pnpm install && pnpm cli:build