Claude Cursor Skill

mo-qa

Use Momentic's `mo` CLI to run and control Mo, Momentic's cloud autonomous QA agent. Use when starting or continuing Mo sessions, reading their output or status, stopping active work, answering Mo, transferring files, exporting reports, or finding and fixing bugs in a local codeb

LLM Mart · 0 points · 8 views 34 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download momentic-ai-skills-skills_mo-qa-8b18dd6.zip · 10 KB
Part of momentic-ai/skills — 5 skills

Install

skills CLI npx skills add https://github.com/momentic-ai/skills/tree/main/skills/mo-qa
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install momentic-ai-skills@llmmart
Git git clone https://github.com/momentic-ai/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole momentic-ai/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Run QA with Mo

Mo runs browser QA in a hosted sandbox. Its files and processes are remote.

Work while Mo runs

Keep the tested revision stable through the initial QA pass and its reproductions. Do not change anything the target serves or hot-reloads, restart the app, deploy to its URL, or mutate shared test data while Mo uses it. Other work, such as code review, is fine. For isolated bug fixes during a longer run, follow Repair loop.

Findings arrive through qa status "$session_id" --full. A kind: "bug" entry has been independently reproduced. A kind: "flag" entry is a static, single-frame mistake such as a typo, recorded without reproduction. Test-case verdicts are verified, issues_found, or blocked. When you report a finding to the user, include its name, evidence, status, and web_url.

If Mo is blocked, answer from the brief, repository, or authorized environment data when you can. Otherwise ask the user for the missing access, permission, or decision, then send the answer to root Mo. Root Mo relays context to its internal sub-agents. Never invent or reveal a secret.

Prepare the brief

Run qa version. If Mo is missing or outdated, read Installation. Read Authentication after an authentication error.

Use the target from the request. For a local or private target, read Tunneling.

The brief is Mo's specification. Include:

  1. The exact target URL, including the affected path and query.
  2. Expected behavior and pass criteria.
  3. The login method, test account label, and allowed test data.
  4. Prohibited actions and data that Mo must not change.
  5. The product areas and user flows in scope, plus explicit exclusions.
  6. Any non-default browser setup. Read Browser settings when needed.

Fill gaps from the request and repository. Ask only when missing scope, access, or permission would change the run.

Set scope and detail

The brief sets scope. --granularity sets detail within that scope:

  • low for an early smoke pass: main happy paths and important failure states.
  • medium when changed flows work: every meaningful interaction and important failure state.
  • high for release-ready coverage: every in-scope path, alternate, failure state, and operable control.

Pass the setting explicitly because the default is high. For a happy-path-only smoke test, tell Mo to skip failure states. Mo has no session-wide time or test count option. For a hard time or spend cap, narrow the brief, monitor wall time or qa cost <session-id>, run qa stop <session-id> --subagents at the cap, and report unfinished coverage.

Start the session

Pass the brief as one argument:

brief=$(cat <<'EOF'
Target: https://preview.example.com/checkout?variant=express
Goal: Keep the selected shipping method after returning from payment.
Sign in: Use the staging QA buyer account.
Test data: Create test carts and orders only.
Do not: Submit payment, send email, delete data, or change the shared catalog.
Coverage: Smoke the express-checkout happy path and standard checkout. Skip other flows and failure states.
Pass criteria:
- The shipping method stays selected.
- The total does not change.
- Standard checkout still works.
EOF
)
session_json=$(qa start --granularity low "$brief")
session_id=$(jq -r .sessionId <<<"$session_json")
web_url=$(jq -r .webUrl <<<"$session_json")
created_at=$(jq -r '.createdAt // empty' <<<"$session_json")

Starting returns before Mo finishes. Preserve these values: every later command needs session_id, the user can watch or join through web_url, and created_at records when the session began. createdAt can be absent when the server runs an earlier API version.

A Momentic environment groups a BASE_URL with reusable non-secret variables under a name such as staging. --environment NAME selects one created under Environments in the Momentic dashboard, not one from the shell or momentic.config.yaml. Mo copies its variables into the session at start.

Use repeatable --env-file or --env-var NAME options for local values and secrets; they override matching environment variables. --env-var forwards a variable that is already present in the qa start process environment; it does not accept NAME=value. Never put the secret value in the command or brief. Use --tunnel for private access. Set --max-concurrency only when the target or test account limits parallel users. It is fixed at session start. If the target overloads, run qa stop --subagents and start a new session with a lower value.

Follow the session

Run this watcher in the background. It prints one line per new finding or state change and exits when Mo needs input or the session ends:

seen=""
while :; do
  snapshot=$(qa status "$session_id" --full) ||
    { echo "status request failed"; sleep 30; continue; }
  events=$(jq -r '"displayState \(.displayState // .state)",
    (.findings.bugs[] | "\(.kind) \(.name)"),
    (.findings.verdicts[] | "verdict \(.status) \(.testCaseName // "-")")' \
    <<<"$snapshot" | sort)
  comm -13 <(printf '%s\n' "$seen") <(printf '%s\n' "$events")
  seen=$events
  case $(jq -r '.displayState // .state' <<<"$snapshot") in
    needs_you | ready | sleeping | cancelled | failed_start) break ;;
  esac
  sleep 30
done

Run the watcher in one of two ways:

  • Background command. Run it yourself with a host tool that notifies you on each output line, such as Claude Code's Monitor, and re-arm it when it expires. Without one, start it as a background session and check its output between other tasks.
  • Runner sub-agent. Give a sub-agent the session_id, the watcher, and this skill. It messages you on each event and keeps watching. Use this only when a running sub-agent can message you, such as Codex with multi_agent_v2 enabled (send_message to /root, then wait_agent in the parent). Claude Code and default Codex sub-agents report only when they finish.

In Codex without a runner sub-agent, keep the watcher in the foreground of a long-running exec_command, retain its returned session ID, and drain it with write_stdin. Do not append &, detach it, or finish the turn while it runs. Shell variables do not persist across separate commands, so interpolate the literal Mo session ID or start the watcher in the same shell that set it.

Either way, you answer blockers and send Mo the user's decisions.

status.displayState describes the whole session for display and polling. status.state is its legacy alias:

State Meaning
running Root Mo is working.
waiting_on_agents Root Mo is idle; its internal sub-agents are working.
needs_you Mo asked a question. Answer it with qa send.
ready No agent is running and results are available.
sleeping No agent is running and there is no report or final reply.
cancelled Work was stopped.
failed_start The session never started. Start a new one.

status.sessionState is the lifecycle state shared by read, status, and report: starting, working, waitingOnUser, waitingOnAgents, idle, or stopped. createdAt is the session creation time, and lastActivityAt is the last persisted update. latestTurn contains the most recent persisted assistant timing metadata: startedAt, completedAt, and durationMs. A partial timing uses null. Servers running an earlier API can omit these new fields.

Use this bounded read for Mo's questions and replies, not findings:

qa read "$session_id" --from start --timeout 45s --json

It omits messages Mo sends during a running turn until that turn ends. --from latest also misses a turn that finishes before the read begins. In a read response, prefer sessionState; use its legacy alias state when the server omits it. timedOut: true means Mo is still working.

With --json, read writes one JSON response to stdout and no progress text. Without --json, a read that waits longer than two seconds prints liveness to stderr. Returned messages stay on stdout, while timeout or stopped status text stays on stderr.

qa wait "$session_id" --json returns when root Mo's turn finishes, stops, or needs input. Exit code 2 means Mo needs input; 4 means it was stopped. Internal sub-agents can still be running, so confirm status.displayState is ready or sleeping before treating the session as done.

Never send a message to ask for progress. Use status, read, or wait. Send only to answer a blocker or deliberately steer or recheck work. Prefer to send while Mo is idle or waiting:

qa send --session-id "$session_id" --wait 45s "Use the staging account."

Sending while active stops root Mo's current turn and in-flight tool call. Do that only when the new direction should take priority. Without --wait, confirm the reply with read.

Finish or repair

Before presenting final results, read Reports. Confirm that the brief still describes the product's expected behavior.

If the user asked for fixes, read Repair loop. Otherwise, do not change app code.

Choose how to stop:

  • qa stop <session-id> interrupts root Mo only. Sub-agents keep testing, filing findings, and billing. Root Mo stays stopped until your next qa send. Use it to redirect Mo without losing in-flight tests.
  • qa stop <session-id> --subagents also stops every running sub-agent. Use it to end spending. qa send can still resume the session.
  • qa archive <session-id> cancels all work, hides the session, and rejects further qa send. Unarchive is web-only.

qa upload returns a sandbox path. Send that path to Mo because local paths do not exist in its sandbox. Create the destination directory before qa download when --output names a directory. Run qa <command> --help for syntax.

Files (skills)
  • agents
    • openai.yaml 197 B
      interface:
        display_name: "QA"
        short_description: "Run work with Momentic’s cloud QA agent"
        default_prompt: "Use $mo-qa to run and manage a QA session with Mo, Momentic’s cloud QA agent."
      
  • references
    • authentication.md 1.4 KB
      # Authentication
      
      ## Authenticate Mo
      
      ```bash
      qa login
      ```
      
      Use `qa login --no-browser` when the environment cannot open a browser. Login
      saves the API key and server URL in `~/.momentic/auth.json`.
      
      In CI, set `MOMENTIC_API_KEY`. It overrides the saved login. Preserve an
      existing value unless authentication fails or the user asks to replace it.
      
      ## Authenticate the application
      
      Pass credentials at session start with `--env-file` or `--env-var NAME`.
      `--env-var` forwards a variable already present in the `qa start` process
      environment; it does not accept `NAME=value`. Never include the value in the
      command or brief. `--environment` selects non-secret variables from a Momentic
      dashboard environment. Put variable names and a non-secret account label in the
      brief. Root Mo supplies authentication to its internal sub-agents.
      
      A browser auth-state file uses Playwright `storageState` JSON: cookies and
      `localStorage` by origin. Momentic `AUTH_SAVE` may add `sessionStorage` and a
      top-level `idb` dump. Use `AUTH_SAVE` if the app depends on either.
      
      If the user supplies an auth-state file, upload it and send root Mo the returned
      sandbox path. You cannot message Mo's internal sub-agents directly. Uploading a
      credential file does not add its values to the session environment.
      
      If Mo needs a new environment variable, ask the user and start a new session
      with the authorized value.
      
      Never expose secrets in a brief, Mo message, URL, command, or commit.
      
    • browser-settings.md 4.2 KB
      # Configure Mo's browser
      
      Put required overrides in the brief so Mo applies them before browser work.
      
      | Setting               | Purpose                                                                                                                                                                                               | Takes effect        |
      | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
      | `extraHeaders`        | HTTP headers sent to every host. An empty value removes a header.                                                                                                                                     | Open or new browser |
      | `geolocation`         | Latitude and longitude exposed to the page.                                                                                                                                                           | Open or new browser |
      | `userAgent`           | Browser user agent. `null` uses the browser's native value.                                                                                                                                           | New browser         |
      | `locale`              | Browser locale, such as `en-US`.                                                                                                                                                                      | New browser         |
      | `timezone`            | IANA timezone, such as `America/Los_Angeles`.                                                                                                                                                         | New browser         |
      | `colorScheme`         | `light` or `dark`.                                                                                                                                                                                    | New browser         |
      | `grantedPermissions`  | Permissions to grant: `clipboard-read`, `clipboard-write`, `microphone`, `camera`, or `geolocation`. Omission grants all cloud-supported permissions; `local-network-access` is ignored in hosted Mo. | New browser         |
      | `basicAuthorization`  | HTTP Basic username and password.                                                                                                                                                                     | New browser         |
      | `ignoreHttpsErrors`   | Allow invalid or self-signed HTTPS certificates.                                                                                                                                                      | New browser         |
      | `disableJavaScript`   | Disable page JavaScript.                                                                                                                                                                              | New browser         |
      | `initialLocalStorage` | Per-origin local-storage key/value pairs loaded at startup.                                                                                                                                           | New browser         |
      | `visualActions`       | Use coordinate-based actions. This can handle rich-text editors but bypasses normal actionability checks.                                                                                             | New browser         |
      | `autoExpandIframes`   | Expose iframe contents to Momentic without explicit iframe URLs. Defaults to `true`; set `false` when the scoped app does not need iframe coverage and reduced frame work matters.                    | New browser         |
      
      Only `extraHeaders` and `geolocation` can change on an open browser. Every other
      setting needs a new browser. A restart closes pages and clears cookies, so
      request one mid-session only when Mo can recreate the state. Otherwise, start a
      new session with the setting in its brief.
      
      Do not put secrets in the brief. Supply application credentials at session
      start as described in [Authentication](authentication.md). Add only required
      headers because `extraHeaders` applies to every host.
      
    • installation.md 725 B
      # Install or update Mo
      
      Read this when Mo is missing, `qa version` fails, or the installed version does
      not support `qa upgrade`.
      
      ## Update
      
      Use the built-in command to update an installed release, then verify it:
      
      ```bash
      qa upgrade
      qa version
      ```
      
      For an npm-installed copy, update with `npm install -g qa@latest` instead;
      `qa upgrade` prints that instruction itself.
      
      ## Install
      
      If Mo is missing or too old to support `qa upgrade`, run the installer:
      
      ```bash
      curl -fsSL https://cli.momentic.ai/qa | sh
      ```
      
      The installer writes `qa` to `$HOME/.local/bin`. Add that directory to `PATH`
      if needed, then verify the installation:
      
      ```bash
      qa version
      ```
      
      After a new installation, read [Authentication](authentication.md).
      
    • remediation-loop.md 2.2 KB
      # Fix bugs found by QA
      
      The request sets the findings in scope. A `triage.json` entry is a person's
      existing disposition, such as duplicate or accepted. Preserve it unless the
      user asks to revisit it.
      
      Reuse the supplied session or start a scoped one. For a supplied session, first
      recover its brief with `qa read <session-id> --from start --timeout 0 --json`.
      Keep its target and tunnel available through verification.
      
      Functional findings can appear in the transcript before independent
      reproduction finishes. You may inspect them, but do not call them confirmed or
      change the app instance Mo is testing. A `kind: "bug"` entry in `status` or
      the report has been reproduced.
      
      1. Inspect each selected finding as it arrives. Reproduce it locally only when
         that cannot hot-reload or alter Mo's target. Choose a disposition: fix,
         duplicate, accepted issue, works as intended, cannot reproduce, or blocked.
      2. When the session becomes idle, read [Reports](reports.md) and export a
         baseline with `qa report <session-id> --require-idle --output <dir>`. Do this
         before replacing the target revision, but do not delay unrelated review or
         local investigation while Mo works.
      3. Fix confirmed defects and run focused local checks.
      4. Make the patched revision available at Mo's target. Reuse its tunnel when
         present. Ask before publishing to shared staging, opening a new tunnel, or
         deploying outside existing authority.
      5. Send the exact bug name, original reproduction, target revision, and recheck
         request. Prefer to wait for idle; sending while active interrupts root Mo's
         current work. Keep the target stable during the recheck.
      6. Wait for completion and export to a different directory. Compare the verdict
         status, `updatedAt`, summary, and recording with the baseline. Call the
         fix verified only when new evidence shows the original reproduction passes.
      
      Report one disposition and its evidence for every selected bug. Include
      unresolved findings and coverage gaps. Stop for a product decision, missing
      access, or repeated infrastructure failure. Do not broaden access or deploy only
      to complete verification.
      
      A local disposition does not update `triage.json` in Momentic.
      
    • reports.md 1.9 KB
      # Read a Mo report
      
      Use `qa wait` when incremental updates are unnecessary. Then export the
      session's evidence:
      
      ```bash
      qa report <session-id> --require-idle
      ```
      
      `--require-idle` checks once. It writes nothing while Mo or an internal
      sub-agent is working. It does not wait. Every successful export downloads the
      attached bug recordings.
      
      Read `report.json` first, then inspect every finding file it names. Do not infer
      finding filenames by listing the directory.
      
      `report.json` contains the source `sessionId`, a `summary`, a map of finding
      categories to filenames, and each recording download under `artifacts`. The CLI
      always writes `summary.generatedAt`, `counts`, `verdictsByStatus`, and
      `verdictsByScope`. When the server provides them, it also writes `sessionState`,
      `createdAt`, `lastActivityAt`, and `latestTurn`. Those server-supplied fields can
      be absent when exporting from a server running an earlier API.
      
      | File             | Contents                                                       |
      | ---------------- | -------------------------------------------------------------- |
      | `bugs.json`      | Reproduced bugs and static flags, with evidence and timestamps |
      | `testCases.json` | Planned coverage, setup, steps, and pass criteria              |
      | `verdicts.json`  | Verification results and coverage gaps                         |
      | `triage.json`    | Human dispositions; no entry means the bug is open             |
      
      Pair each bug with its recording. A missing manifest artifact means no video
      was downloaded. An artifact `error` explains a failed download. The report does
      not include raw sub-agent transcripts, standalone screenshots, or browser
      traces. Inspect the transcript with `qa read`. Ask Mo only when missing evidence
      blocks the requested work.
      
      For a recheck, ask Mo to repeat the exact reproduction. Wait for completion,
      then export again. Use `--output <directory>` to preserve the baseline.
      Exporting alone does not rerun the test.
      
    • tunneling.md 951 B
      # Connect Mo to a private target
      
      Use a tunnel when Mo cannot reach the target from the public internet.
      
      Expose only the required address:
      
      ```bash
      tunnel_json=$(qa tunnel start localhost:3000)
      tunnel_id=$(jq -r .tunnelId <<<"$tunnel_json")
      ```
      
      Pass more addresses only when the tested flow needs them:
      
      ```bash
      qa tunnel start localhost:3000 api.internal:8080
      ```
      
      Keep the exact private URL in the brief. Pass the tunnel ID at start:
      
      ```bash
      session_json=$(qa start --tunnel "$tunnel_id" "$brief")
      ```
      
      In Codex, a service started with host-network escalation may be unreachable from
      a sandboxed command even when it is healthy. Run the health check, tunnel, and
      session commands in the same host context. Do not restart a healthy service to
      work around that namespace boundary.
      
      After the last session, run `qa tunnel stop "$tunnel_id"`. If setup fails, do
      not expose more addresses, deploy the app, or share credentials without user
      direction.
      
  • SKILL.md 10.3 KB
    ---
    name: mo-qa
    description: Run and control Mo QA sessions with Momentic's `qa` CLI. Use for bug bashes, status checks, report export, replies to Mo, file transfer, or repairs based on Mo findings.
    ---
    
    # Run QA with Mo
    
    Mo runs browser QA in a hosted sandbox. Its files and processes are remote.
    
    ## Work while Mo runs
    
    Keep the tested revision stable through the initial QA pass and its
    reproductions. Do not change anything the target serves or hot-reloads, restart
    the app, deploy to its URL, or mutate shared test data while Mo uses it. Other
    work, such as code review, is fine. For isolated bug fixes during a longer run,
    follow [Repair loop](references/remediation-loop.md).
    
    Findings arrive through `qa status "$session_id" --full`. A `kind: "bug"`
    entry has been independently reproduced. A `kind: "flag"` entry is a static,
    single-frame mistake such as a typo, recorded without reproduction. Test-case
    verdicts are `verified`, `issues_found`, or `blocked`. When you report a finding
    to the user, include its name, evidence, status, and `web_url`.
    
    If Mo is blocked, answer from the brief, repository, or authorized environment
    data when you can. Otherwise ask the user for the missing access, permission,
    or decision, then send the answer to root Mo. Root Mo relays context to its
    internal sub-agents. Never invent or reveal a secret.
    
    ## Prepare the brief
    
    Run `qa version`. If Mo is missing or outdated, read
    [Installation](references/installation.md). Read
    [Authentication](references/authentication.md) after an authentication error.
    
    Use the target from the request. For a local or private target, read
    [Tunneling](references/tunneling.md).
    
    The brief is Mo's specification. Include:
    
    1. The exact target URL, including the affected path and query.
    2. Expected behavior and pass criteria.
    3. The login method, test account label, and allowed test data.
    4. Prohibited actions and data that Mo must not change.
    5. The product areas and user flows in scope, plus explicit exclusions.
    6. Any non-default browser setup. Read
       [Browser settings](references/browser-settings.md) when needed.
    
    Fill gaps from the request and repository. Ask only when missing scope, access,
    or permission would change the run.
    
    ### Set scope and detail
    
    The brief sets scope. `--granularity` sets detail within that scope:
    
    - `low` for an early smoke pass: main happy paths and important failure states.
    - `medium` when changed flows work: every meaningful interaction and important
      failure state.
    - `high` for release-ready coverage: every in-scope path, alternate, failure
      state, and operable control.
    
    Pass the setting explicitly because the default is `high`. For a happy-path-only
    smoke test, tell Mo to skip failure states. Mo has no session-wide time or test
    count option. For a hard time or spend cap, narrow the brief, monitor wall time
    or `qa cost <session-id>`, run `qa stop <session-id> --subagents` at the cap,
    and report unfinished coverage.
    
    ## Start the session
    
    Pass the brief as one argument:
    
    ```bash
    brief=$(cat <<'EOF'
    Target: https://preview.example.com/checkout?variant=express
    Goal: Keep the selected shipping method after returning from payment.
    Sign in: Use the staging QA buyer account.
    Test data: Create test carts and orders only.
    Do not: Submit payment, send email, delete data, or change the shared catalog.
    Coverage: Smoke the express-checkout happy path and standard checkout. Skip other flows and failure states.
    Pass criteria:
    - The shipping method stays selected.
    - The total does not change.
    - Standard checkout still works.
    EOF
    )
    session_json=$(qa start --granularity low "$brief")
    session_id=$(jq -r .sessionId <<<"$session_json")
    web_url=$(jq -r .webUrl <<<"$session_json")
    created_at=$(jq -r '.createdAt // empty' <<<"$session_json")
    ```
    
    Starting returns before Mo finishes. Preserve these values: every later command
    needs `session_id`, the user can watch or join through `web_url`, and
    `created_at` records when the session began. `createdAt` can be absent when the
    server runs an earlier API version.
    
    A Momentic environment groups a `BASE_URL` with reusable non-secret variables
    under a name such as `staging`. `--environment NAME` selects one created under
    **Environments** in the Momentic dashboard, not one from the shell or
    `momentic.config.yaml`. Mo copies its variables into the session at start.
    
    Use repeatable `--env-file` or `--env-var NAME` options for local values and
    secrets; they override matching environment variables. `--env-var` forwards a
    variable that is already present in the `qa start` process environment; it does
    not accept `NAME=value`. Never put the secret value in the command or brief.
    Use `--tunnel` for private access. Set `--max-concurrency` only when the target
    or test account limits parallel users. It is fixed at session start. If the
    target overloads, run `qa stop --subagents` and start a new session with a lower
    value.
    
    ## Follow the session
    
    Run this watcher in the background. It prints one line per new finding or state
    change and exits when Mo needs input or the session ends:
    
    ```bash
    seen=""
    while :; do
      snapshot=$(qa status "$session_id" --full) ||
        { echo "status request failed"; sleep 30; continue; }
      events=$(jq -r '"displayState \(.displayState // .state)",
        (.findings.bugs[] | "\(.kind) \(.name)"),
        (.findings.verdicts[] | "verdict \(.status) \(.testCaseName // "-")")' \
        <<<"$snapshot" | sort)
      comm -13 <(printf '%s\n' "$seen") <(printf '%s\n' "$events")
      seen=$events
      case $(jq -r '.displayState // .state' <<<"$snapshot") in
        needs_you | ready | sleeping | cancelled | failed_start) break ;;
      esac
      sleep 30
    done
    ```
    
    Run the watcher in one of two ways:
    
    - **Background command.** Run it yourself with a host tool that notifies you on
      each output line, such as Claude Code's `Monitor`, and re-arm it when it
      expires. Without one, start it as a background session and check its output
      between other tasks.
    - **Runner sub-agent.** Give a sub-agent the `session_id`, the watcher, and this
      skill. It messages you on each event and keeps watching. Use this only when
      a running sub-agent can message you, such as Codex with `multi_agent_v2`
      enabled (`send_message` to `/root`, then `wait_agent` in the parent). Claude
      Code and default Codex sub-agents report only when they finish.
    
    In Codex without a runner sub-agent, keep the watcher in the foreground of a
    long-running `exec_command`, retain its returned session ID, and drain it with
    `write_stdin`. Do not append `&`, detach it, or finish the turn while it runs.
    Shell variables do not persist across separate commands, so interpolate the
    literal Mo session ID or start the watcher in the same shell that set it.
    
    Either way, you answer blockers and send Mo the user's decisions.
    
    `status.displayState` describes the whole session for display and polling.
    `status.state` is its legacy alias:
    
    | State               | Meaning                                                    |
    | ------------------- | ---------------------------------------------------------- |
    | `running`           | Root Mo is working.                                        |
    | `waiting_on_agents` | Root Mo is idle; its internal sub-agents are working.      |
    | `needs_you`         | Mo asked a question. Answer it with `qa send`.             |
    | `ready`             | No agent is running and results are available.             |
    | `sleeping`          | No agent is running and there is no report or final reply. |
    | `cancelled`         | Work was stopped.                                          |
    | `failed_start`      | The session never started. Start a new one.                |
    
    `status.sessionState` is the lifecycle state shared by `read`, `status`, and
    `report`: `starting`, `working`, `waitingOnUser`, `waitingOnAgents`, `idle`, or
    `stopped`. `createdAt` is the session creation time, and `lastActivityAt` is the
    last persisted update. `latestTurn` contains the most recent persisted
    assistant timing metadata: `startedAt`, `completedAt`, and `durationMs`. A
    partial timing uses `null`. Servers running an earlier API can omit these new
    fields.
    
    Use this bounded read for Mo's questions and replies, not findings:
    
    ```bash
    qa read "$session_id" --from start --timeout 45s --json
    ```
    
    It omits messages Mo sends during a running turn until that turn ends.
    `--from latest` also misses a turn that finishes before the read begins. In a
    `read` response, prefer `sessionState`; use its legacy alias `state` when the
    server omits it. `timedOut: true` means Mo is still working.
    
    With `--json`, `read` writes one JSON response to stdout and no progress text.
    Without `--json`, a read that waits longer than two seconds prints liveness to
    stderr. Returned messages stay on stdout, while timeout or stopped status text
    stays on stderr.
    
    `qa wait "$session_id" --json` returns when root Mo's turn finishes, stops, or
    needs input. Exit code `2` means Mo needs input; `4` means it was stopped.
    Internal sub-agents can still be running, so confirm `status.displayState` is
    `ready` or `sleeping` before treating the session as done.
    
    Never send a message to ask for progress. Use `status`, `read`, or `wait`.
    Send only to answer a blocker or deliberately steer or recheck work. Prefer to
    send while Mo is idle or waiting:
    
    ```bash
    qa send --session-id "$session_id" --wait 45s "Use the staging account."
    ```
    
    Sending while active stops root Mo's current turn and in-flight tool call. Do
    that only when the new direction should take priority. Without `--wait`, confirm
    the reply with `read`.
    
    ## Finish or repair
    
    Before presenting final results, read [Reports](references/reports.md). Confirm
    that the brief still describes the product's expected behavior.
    
    If the user asked for fixes, read
    [Repair loop](references/remediation-loop.md). Otherwise, do not change app code.
    
    Choose how to stop:
    
    - `qa stop <session-id>` interrupts root Mo only. Sub-agents keep testing,
      filing findings, and billing. Root Mo stays stopped until your next
      `qa send`. Use it to redirect Mo without losing in-flight tests.
    - `qa stop <session-id> --subagents` also stops every running sub-agent. Use it
      to end spending. `qa send` can still resume the session.
    - `qa archive <session-id>` cancels all work, hides the session, and rejects
      further `qa send`. Unarchive is web-only.
    
    `qa upload` returns a sandbox path. Send that path to Mo because local paths do
    not exist in its sandbox. Create the destination directory before `qa download`
    when `--output` names a directory. Run `qa <command> --help` for syntax.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related