Quester Studio

Workspace files

Layout and formats for quester.json, flows, environments, and collections

A workspace is a folder with a quester.json manifest. Everything Quester loads — flows, environments, secrets, collections, and forms — lives under that root.

For how nodes connect and how {{input.*}} differs from the input node, see How flows work.

Layout

my-workspace/
  quester.json
  flows/
    demo-main-nodes.flow.json
    login-and-profile.flow.json
    search-pick-cart.flow.json
    forms-showcase.flow.json
    echo-subflow.flow.json
    kitchen-sink.flow.json
  forms/
    search-products.form.json
    pick-product.form.json
    product-detail.form.json
  environments/
    local.json
    local.secrets.json # gitignored
    local.secrets.json.example # committed template
  collections/suites/
    smoke.suite.json
  runs/ # gitignored when enabled

quester.json

Manifest that names the workspace and optional directory overrides.

FieldTypeDefaultDescription
namestringrequiredWorkspace display name
version"v1"requiredManifest version
descriptionstringoptionalHuman-readable notes
flowsDirstring"flows"Relative path to flow files
environmentsDirstring"environments"Relative path to env / secrets
collectionsDirstring"collections"Relative path to request collections
formsDirstring"forms"Relative path to form definitions
runs.enabledbooleanfalseWrite per-step run logs under runs.dir
runs.dirstring"runs"Relative path for on-disk run folders
settings.http.defaultHeadersobject{}Headers merged into every HTTP node (node keys win)
settings.http.timeoutMsnumberomittedRequest timeout in ms; 0 = none
settings.http.maxResponseBytesnumberomittedMax response body size; 0 = unlimited
settings.http.proxyUrlstringomittedHTTP(S) proxy URL; "" clears an outer proxy
settings.http.caFilestringomittedWorkspace-relative PEM CA path; "" clears
settings.http.verifyTlsbooleanomittedVerify TLS (inherits → app preference / env)
settings.http.cookieJarbooleanomittedIn-run cookie jar; default on when unset

Example

{
  "name": "sample-workspace",
  "version": "v1",
  "description": "Sample flows for local development",
  "flowsDir": "flows",
  "environmentsDir": "environments",
  "collectionsDir": "collections",
  "formsDir": "forms",
  "settings": {
    "http": {
      "defaultHeaders": { "Accept": "application/json" },
      "timeoutMs": 30000
    }
  }
}

Flows (*.flow.json)

Each flow is a graph of nodes and edges.

FieldTypeDescription
idstringStable flow id
version"v1"Flow format version
namestringOptional display name
descriptionstringOptional description
settings.httpobjectOptional HTTP defaults (same shape as workspace; overrides workspace)
nodesarrayAt least one node; must include exactly one start
edgesarrayConnections between nodes

Graph rules: exactly one start (no incoming edges, ≤1 outgoing); no cycles; every node reachable from start.

Node shape

{
  "id": "login",
  "type": "http",
  "data": { "method": "POST", "url": "{{env.API_BASE}}/users" },
  "position": { "x": 250, "y": 0 }
}
FieldDescription
idUnique within the flow; used in {{nodes.id}}
typeBuiltin type (input, http, …) or custom
dataType-specific config (see Nodes)
positionOptional canvas coordinates

Edge shape

{
  "id": "e1",
  "source": "in",
  "target": "login",
  "sourceHandle": null
}

source / target here are node ids (not extract’s removed data field). For if nodes, set sourceHandle to "true" or "false" to pick a branch.

Forms (*.form.json)

Forms live under formsDir (default forms/) as {id}.form.json. A flow can include multiple form nodes; each pauses until values are submitted, then continues with that node’s output ({{nodes.<formNodeId>.*}}).

This is different from the input node, which exposes the run’s initial --input / flow input payload once at the start.

FieldTypeDescription
version"v1"Form format version
idstringStable form id (file stem)
namestringDisplay name
descriptionstringOptional
fieldsarrayField definitions

Field types: string, number, boolean, json, select.

  • default may be a template (e.g. {{nodes.getProfile.body.email}}) resolved when the form pauses.
  • readonly: true shows a value but keeps it fixed on submit (useful for product detail review).
  • select needs static options or dynamic optionsFrom (items template → array, plus value / label property names).

Desktop: when a form node runs, the app shows the resolved fields; Submit resumes the run.

CLI: pass pre-filled answers keyed by form node id (not form file id):

quester run search-pick-cart --workspace examples/sample-workspace --env local \
  --forms examples/sample-workspace/forms/search-pick-cart.forms.json

Omit fields that should keep resolved defaults; required fields and select membership are still validated. There are no interactive TTY prompts in v1.

Sample flows:

  • flows/search-pick-cart.flow.json — search → pick from results → detail → add to cart
  • flows/forms-showcase.flow.json — full forms tour (string/number/boolean/json, static + dynamic select, readonly prefills, multi-step await)
quester run forms-showcase --workspace examples/sample-workspace --env local \
  --forms examples/sample-workspace/forms/forms-showcase.forms.json

Minimal flow

{
  "id": "hello",
  "version": "v1",
  "name": "Hello",
  "nodes": [
    { "id": "start", "type": "start", "data": {} },
    {
      "id": "out",
      "type": "output",
      "data": {
        "map": { "message": "Hello {{input.name}}" }
      }
    }
  ],
  "edges": [{ "id": "e1", "source": "start", "target": "out" }]
}