@zibby/skills 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,83 @@
1
+ ---
2
+ sidebar_position: 1
3
+ title: Graph & nodes
4
+ ---
5
+
6
+ # Graph & nodes
7
+
8
+ A **graph** is a directed graph of agent invocations. You declare it in code:
9
+
10
+ ```js
11
+ import { WorkflowGraph } from '@zibby/agent-workflow';
12
+ import { z } from '@zibby/core';
13
+
14
+ const graph = new WorkflowGraph()
15
+ .addNode('plan', { prompt: 'List 3 tasks for: {{goal}}', outputSchema: Plan, agent: 'claude' })
16
+ .addNode('execute', { prompt: 'Do task: {{task}}', outputSchema: Done, agent: 'cursor' })
17
+ .addNode('verify', { prompt: 'Verify: {{result}}', outputSchema: Status, agent: 'codex' })
18
+ .addEdge('plan', 'execute')
19
+ .addEdge('execute', 'verify')
20
+ .setEntryPoint('plan');
21
+ ```
22
+
23
+ ## Node config
24
+
25
+ Every node accepts:
26
+
27
+ | Field | Required | Description |
28
+ |---|---|---|
29
+ | `prompt` | yes | Either a string template (`{{state.X}}` interpolated) or a function `({ input, state }) => string`. |
30
+ | `outputSchema` | yes | A Zod schema. The node's output is validated against this before downstream nodes see it. Validation failure = node failure. |
31
+ | `agent` | no | Agent strategy override: `'cursor' | 'claude' | 'codex' | 'gemini' | 'assistant'`. Falls back to project default if omitted. |
32
+ | `retries` | no | Number of times to retry on failure (default: 0). |
33
+ | `skills` | no | Array of skill IDs to enable for this node — see [Skills](./skills). |
34
+ | `onComplete` | no | Async callback invoked with the node's validated output. |
35
+
36
+ ## Edges
37
+
38
+ Three forms:
39
+
40
+ ```js
41
+ // Linear: A → B
42
+ graph.addEdge('A', 'B');
43
+
44
+ // Conditional branching: state-driven routing
45
+ graph.addConditionalEdges('classify', (state) => {
46
+ if (state.classify.severity === 'critical') return 'pageOncall';
47
+ if (state.classify.severity === 'high') return 'createIncident';
48
+ return 'logAndExit';
49
+ });
50
+
51
+ // Multi-conditional with named labels (cleaner for many branches)
52
+ graph.addConditionalEdges('classify', {
53
+ routes: (state) => state.classify.severity,
54
+ labels: { critical: 'pageOncall', high: 'createIncident', _default: 'logAndExit' },
55
+ });
56
+ ```
57
+
58
+ ## Entry point
59
+
60
+ Exactly one node is the entry point:
61
+
62
+ ```js
63
+ graph.setEntryPoint('plan');
64
+ ```
65
+
66
+ This is the node that runs first when `graph.run(initialState)` is called.
67
+
68
+ ## Running
69
+
70
+ ```js
71
+ const { state } = await graph.run(agent, {
72
+ input: { goal: 'add a dark-mode toggle' },
73
+ agentType: 'cursor',
74
+ });
75
+
76
+ console.log(state.verify.status);
77
+ ```
78
+
79
+ Each node's output lands at `state[nodeName]`, so downstream prompts can reference `{{state.plan.tasks}}` or `state.plan.tasks` from a function prompt.
80
+
81
+ ## State immutability
82
+
83
+ State is append-only — every node-completion creates a new state object. Earlier values are preserved in the state's `_history` array, accessible via `state.rollback(N)` for retries that need to drop the latest N writes.
@@ -0,0 +1,70 @@
1
+ ---
2
+ sidebar_position: 5
3
+ title: Sessions & artifacts
4
+ ---
5
+
6
+ # Sessions & artifacts
7
+
8
+ Every workflow run — local or cloud — produces a **session folder** under `.zibby/output/sessions/<sessionId>/`. The folder is the canonical record of what happened.
9
+
10
+ ## What's inside
11
+
12
+ ```
13
+ .zibby/output/sessions/1777678254943_ymcw/
14
+ ├── result.json # final structured output (Zod-validated)
15
+ ├── raw_stream_output.txt # every byte the agent emitted, raw
16
+ ├── events.json # JSONL execution log: per-node start/end, validation, retries
17
+ ├── .session-info.json # session metadata (start time, agent, model, workflow type)
18
+ └── nodes/
19
+ ├── plan/
20
+ │ ├── prompt.txt # exact prompt sent to the agent
21
+ │ ├── raw_output.txt # what the agent returned, pre-validation
22
+ │ └── result.json # the validated output
23
+ ├── implement/...
24
+ └── verify/...
25
+ ```
26
+
27
+ ## Session IDs
28
+
29
+ Format: `<unix_ms>_<random>`. Generated when the graph starts running.
30
+
31
+ You can override via:
32
+
33
+ ```bash
34
+ zibby workflow run my-pipeline --session 1777678254943_ymcw
35
+ ```
36
+
37
+ Useful for replay — re-run from a saved input/state without re-paying earlier nodes.
38
+
39
+ ## Replay a session
40
+
41
+ ```bash
42
+ zibby workflow run my-pipeline \
43
+ --session 1777678254943_ymcw \
44
+ --node verify # only re-run the 'verify' node
45
+ ```
46
+
47
+ The graph reads `state.plan` and `state.implement` from the saved session and only invokes `verify` again. Cheap iteration on the last node when debugging.
48
+
49
+ ## Cloud sessions
50
+
51
+ Cloud runs land in the same `.zibby/output/sessions/` layout, just inside the ECS container's `/workspace/`. The session folder is uploaded to S3 at the end of each run; `zibby workflow logs <uuid> -t` streams CloudWatch logs in real time.
52
+
53
+ To download a finished cloud session locally:
54
+
55
+ ```bash
56
+ zibby workflow download <uuid>
57
+ ```
58
+
59
+ This pulls the workflow source (so you can edit and redeploy) plus the most recent execution's session folder.
60
+
61
+ ## Studio integration
62
+
63
+ [Zibby Studio](https://zibby.app) is a desktop UI that watches `.zibby/output/sessions/`. Anything that writes a session folder shows up in Studio automatically — pin a session, watch state evolve live, or stop a workflow from the Stop button.
64
+
65
+ The protocol is documented and stable:
66
+
67
+ - `__WORKFLOW_GRAPH_LOG__` markers in stdout signal node begin/end events
68
+ - `.zibby-studio-stop` file is the kill switch — Studio writes it, the runtime checks for it between nodes
69
+ - `ZIBBY_RUN_SOURCE=studio` env var tells the runtime "you were spawned by Studio"
70
+ - `stoppedByStudio: true` returned from `graph.run()` when the kill switch fired
@@ -0,0 +1,84 @@
1
+ ---
2
+ sidebar_position: 4
3
+ title: Skills
4
+ ---
5
+
6
+ # Skills
7
+
8
+ A **skill** is a named bundle of MCP tools (and optional prompt fragments) that a node can opt into. Skills let you compose tool access per-node without giving every node every tool.
9
+
10
+ ## Built-in skills
11
+
12
+ `@zibby/skills` ships these:
13
+
14
+ | Skill ID | What it adds |
15
+ |---|---|
16
+ | `browser` | Playwright MCP — browse, click, fill, screenshot |
17
+ | `github` | GitHub MCP — issues, PRs, file edits, branches |
18
+ | `jira` | Jira MCP — tickets, comments, transitions |
19
+ | `slack` | Slack MCP — read/write channels, threads, DMs |
20
+ | `memory` | Test memory database — version-controlled (Dolt) knowledge from prior runs |
21
+
22
+ ## Enabling on a node
23
+
24
+ ```js
25
+ import { registerSkill } from '@zibby/agent-workflow';
26
+ import { browserSkill } from '@zibby/skills';
27
+
28
+ registerSkill(browserSkill);
29
+
30
+ graph.addNode('research', {
31
+ prompt: 'Find pricing for {{input.product}}',
32
+ outputSchema: Price,
33
+ agent: 'cursor',
34
+ skills: ['browser'],
35
+ });
36
+ ```
37
+
38
+ Two effects:
39
+ 1. The agent gets the Browser MCP tools at this node only.
40
+ 2. The skill's prompt fragment (telling the agent how to use the tools) is appended to the prompt.
41
+
42
+ ## Custom skills
43
+
44
+ Implement the `Skill` shape:
45
+
46
+ ```js
47
+ import { registerSkill } from '@zibby/agent-workflow';
48
+
49
+ registerSkill({
50
+ id: 'pdf',
51
+ serverName: 'pdf-mcp',
52
+ tools: ['pdfExtract', 'pdfRender'],
53
+ promptFragment: 'When working with PDFs, use the pdfExtract tool first.',
54
+ });
55
+ ```
56
+
57
+ Now any node can opt in via `skills: ['pdf']`.
58
+
59
+ ## Why per-node, not per-graph?
60
+
61
+ Two reasons:
62
+
63
+ - **Tool scoping** — a node that's planning shouldn't have Slack write access; a node that's posting status shouldn't have file-write tools. Per-node skills give you least-privilege automatically.
64
+ - **Prompt size** — every enabled skill adds prompt fragments. Don't pay for tools you won't use.
65
+
66
+ ## Function skills (no MCP server needed)
67
+
68
+ For lightweight cases, register a function skill:
69
+
70
+ ```js
71
+ import { registerSkill } from '@zibby/agent-workflow';
72
+
73
+ registerSkill({
74
+ id: 'pricing',
75
+ type: 'function',
76
+ fn: async ({ product }) => {
77
+ const r = await fetch(`https://my.api/price?p=${product}`);
78
+ return r.json();
79
+ },
80
+ description: 'Look up product pricing.',
81
+ });
82
+ ```
83
+
84
+ The agent sees `pricing` as a callable tool, gets your function's return value back as a tool result. No MCP server to spin up.
@@ -0,0 +1,106 @@
1
+ ---
2
+ sidebar_position: 3
3
+ title: State & schema
4
+ ---
5
+
6
+ # State & schema
7
+
8
+ Every workflow run carries one **state** object that flows from node to node. State is the only handoff mechanism — there's no shared globals, no hidden context.
9
+
10
+ ## Shape
11
+
12
+ ```js
13
+ state = {
14
+ input: { /* whatever the trigger passed */ },
15
+ plan: { tasks: ['t1', 't2'] }, // ← from node 'plan'
16
+ implement: { diff: '...' }, // ← from node 'implement'
17
+ verify: { status: 'ok' }, // ← from node 'verify'
18
+ }
19
+ ```
20
+
21
+ When a node completes, its validated output lands at `state[nodeName]`.
22
+
23
+ ## Schema-validated handoff
24
+
25
+ Every node's `outputSchema` is a Zod schema. It runs *before* downstream nodes see the output:
26
+
27
+ ```js
28
+ import { z } from '@zibby/core';
29
+
30
+ const Plan = z.object({
31
+ tasks: z.array(z.string()).min(1),
32
+ priority: z.enum(['low', 'normal', 'high']),
33
+ });
34
+
35
+ graph.addNode('plan', {
36
+ prompt: 'Triage this ticket.',
37
+ outputSchema: Plan,
38
+ agent: 'claude',
39
+ });
40
+ ```
41
+
42
+ If the agent returns malformed output, the node fails. Combined with `retries: N`, you get cheap automatic recovery from one-off LLM hallucinations.
43
+
44
+ Downstream nodes can reference plan output directly:
45
+
46
+ ```js
47
+ graph.addNode('implement', {
48
+ prompt: ({ state }) => `Implement these tasks:\n${state.plan.tasks.map(t => `- ${t}`).join('\n')}`,
49
+ outputSchema: Implementation,
50
+ agent: 'cursor',
51
+ });
52
+ ```
53
+
54
+ ## Function vs. template prompts
55
+
56
+ Two prompt forms:
57
+
58
+ ```js
59
+ // String template — variables interpolated from state.
60
+ graph.addNode('plan', { prompt: 'Plan: {{input.goal}}', ... });
61
+
62
+ // Function — full programmatic control.
63
+ graph.addNode('plan', {
64
+ prompt: ({ input, state }) => {
65
+ const ctx = state.context?.summary ?? '';
66
+ return `Plan: ${input.goal}\n\nContext:\n${ctx}`;
67
+ },
68
+ ...
69
+ });
70
+ ```
71
+
72
+ Functions get `{ input, state, getAll, get }` so they can introspect state without throwing on missing keys.
73
+
74
+ ## Skill hints
75
+
76
+ If a node opts into [skills](./skills), the framework appends prompt fragments that tell the agent how to use those tools. You don't write that boilerplate — register the skill once, list it on the node:
77
+
78
+ ```js
79
+ graph.addNode('search', {
80
+ prompt: 'Find info about {{input.query}}',
81
+ outputSchema: Results,
82
+ agent: 'cursor',
83
+ skills: ['browser'], // appends Browser MCP usage instructions to the prompt
84
+ });
85
+ ```
86
+
87
+ ## Rollback
88
+
89
+ State is history-tracked. To revert the last N writes (typical use case: a node validation passes Zod but the *content* is wrong, and you want to retry with extra instructions):
90
+
91
+ ```js
92
+ const recovered = state.rollback(2);
93
+ ```
94
+
95
+ `rollback` returns a fresh state with the last 2 writes dropped. Use it inside `onComplete` callbacks or custom retry logic.
96
+
97
+ ## Reading state in templates
98
+
99
+ Inside the `prompt` string, `{{x}}` resolves first against `state.x`, then against `input.x`. Dotted paths work:
100
+
101
+ ```
102
+ {{state.plan.tasks.length}}
103
+ {{input.ticket}}
104
+ ```
105
+
106
+ Function prompts give you the same access without the templating layer.
@@ -0,0 +1,75 @@
1
+ ---
2
+ sidebar_position: 4
3
+ title: 4. Deploy to cloud
4
+ pagination_prev: get-started/run-locally
5
+ pagination_next: get-started/trigger-and-logs
6
+ ---
7
+
8
+ # Ship a workflow to Zibby Cloud
9
+
10
+ ```bash
11
+ zibby workflow deploy my-pipeline
12
+ ```
13
+
14
+ If you have multiple projects, the CLI prompts you to pick one. On success it prints a UUID:
15
+
16
+ ```
17
+ ✔ Deployed my-pipeline (v1)
18
+ ✔ Bundle ready (78s) — runtime npm install eliminated
19
+
20
+ UUID: 2b1ea07f-3ede-4bfd-a51d-431f0bab008e
21
+
22
+ Next steps:
23
+ zibby workflow run my-pipeline Run locally
24
+ zibby workflow trigger 2b1ea07f-... Run in cloud
25
+ zibby workflow list View all workflows
26
+ ```
27
+
28
+ The UUID is **canonical** — it never changes once issued. All cloud commands (`trigger`, `logs`, `download`, `delete`) take that UUID as their identifier. The CLI caches it in `.zibby/workflows/my-pipeline/.zibby-deploy.json` so you don't have to remember it. Commit that file to git; collaborators share the same canonical reference.
29
+
30
+ ## What deploy actually does
31
+
32
+ Two phases:
33
+
34
+ 1. **Source upload** — your workflow folder (sources only, no `node_modules`) is uploaded as a JSON payload to S3 via a presigned URL. The CLI also resolves your `.zibby.config.mjs` (if present at project root) and ships it inside the bundle as `zibby.config.json`, so the cloud sees the same config as your local runs.
35
+ 2. **Bundle build (Heroku-style)** — a CodeBuild job downloads the sources, runs `npm install --omit=dev`, packages the result as a tarball, and uploads it to S3. The tarball is what each cloud execution downloads at trigger time, so there's **no `npm install` at runtime** — workflows boot in seconds.
36
+
37
+ You'll see a live spinner with the active build step:
38
+
39
+ ```
40
+ ⠹ Building bundle on Zibby Cloud... [3/4] Installing dependencies — 32s
41
+ ```
42
+
43
+ Pass `--verbose` if you want to see raw CodeBuild logs.
44
+
45
+ ## Re-deploys keep the same UUID
46
+
47
+ Once a workflow has a UUID, every subsequent `deploy` increments the version but keeps the UUID stable:
48
+
49
+ ```
50
+ v1 → v2 → v3 → ... (same UUID, same trigger URL)
51
+ ```
52
+
53
+ So your `curl` calls and CI integrations don't break across deploys.
54
+
55
+ ## Naming vs. UUIDs
56
+
57
+ A clean mental model:
58
+
59
+ - **Workflow folder name** (`my-pipeline`) is *local* — used by `workflow new`, `start`, `deploy`. It's just a directory name.
60
+ - **UUID** (`2b1ea07f-...`) is *canonical* — used by `trigger`, `logs`, `download`, `delete`. Stable across deploys.
61
+
62
+ `workflow list` shows both:
63
+
64
+ ```
65
+ ┌─────────────────────────────────────┬──────────────┬──────────┬─────┐
66
+ │ UUID │ Name │ Project │ Ver │
67
+ ├─────────────────────────────────────┼──────────────┼──────────┼─────┤
68
+ │ 2b1ea07f-3ede-4bfd-a51d-431f0bab008e│ my-pipeline │ Zibby UI │ 3 │
69
+ │ - │ scratchpad │ - │ - │
70
+ └─────────────────────────────────────┴──────────────┴──────────┴─────┘
71
+ ```
72
+
73
+ `-` in the UUID column means a local-only workflow that hasn't been deployed yet.
74
+
75
+ → Next: [Trigger & tail logs](./trigger-and-logs)
@@ -0,0 +1,58 @@
1
+ ---
2
+ sidebar_position: 1
3
+ title: 1. Install
4
+ pagination_prev: intro
5
+ pagination_next: get-started/your-first-workflow
6
+ ---
7
+
8
+ # Install the CLI
9
+
10
+ ```bash
11
+ npm install -g @zibby/cli
12
+ ```
13
+
14
+ Verify:
15
+
16
+ ```bash
17
+ zibby --version
18
+ ```
19
+
20
+ You should see `zibby v0.1.x`.
21
+
22
+ ## No global install? Use npx
23
+
24
+ Every example below works with `npx @zibby/cli` instead of `zibby`:
25
+
26
+ ```bash
27
+ npx @zibby/cli workflow new my-pipeline
28
+ ```
29
+
30
+ The first call downloads the package; subsequent calls use the cached copy.
31
+
32
+ ## Log in
33
+
34
+ Cloud features (deploy, trigger, logs) need authentication:
35
+
36
+ ```bash
37
+ zibby login
38
+ ```
39
+
40
+ This opens your browser and writes a session token to `~/.zibby/config.json`. Logged in for 30 days.
41
+
42
+ For CI/CD, set `ZIBBY_API_KEY` in the environment instead — the CLI prefers that over the saved session.
43
+
44
+ ## Pick an agent runtime
45
+
46
+ Workflows hand off to external coding-agent CLIs at runtime. You'll need at least one of these installed (locally — the cloud runtime has them pre-installed):
47
+
48
+ | Agent | How to install | Auth |
49
+ |---|---|---|
50
+ | **Cursor** | Install [Cursor](https://cursor.com), or `npm i -g cursor-agent` | `cursor-agent login` (or `CURSOR_API_KEY`) |
51
+ | **Claude Code** | `npm i -g @anthropic-ai/claude-agent-sdk` | `ANTHROPIC_API_KEY` |
52
+ | **Codex** | `npm i -g @openai/codex` | `OPENAI_API_KEY` |
53
+ | **Gemini** | `npm i -g @google/gemini-cli` | `GOOGLE_API_KEY` |
54
+ | **Assistant** | None — uses OpenAI Assistants API | `OPENAI_API_KEY` |
55
+
56
+ You only need one. The cloud runtime supports all five out of the box.
57
+
58
+ → Next: [Your first workflow](./your-first-workflow)
@@ -0,0 +1,94 @@
1
+ ---
2
+ sidebar_position: 3
3
+ title: 3. Run it locally
4
+ pagination_prev: get-started/your-first-workflow
5
+ pagination_next: get-started/deploy
6
+ ---
7
+
8
+ # Run a workflow locally
9
+
10
+ ```bash
11
+ zibby workflow run my-pipeline
12
+ ```
13
+
14
+ One-shot: loads `graph.mjs`, instantiates your `WorkflowAgent` class, runs the graph against a real agent, prints results, exits. Output lands in `.zibby/output/sessions/<sessionId>/`:
15
+
16
+ - `result.json` — the final structured output (Zod-validated)
17
+ - `raw_stream_output.txt` — every byte the agent emitted
18
+ - `events.json` — JSONL execution log: which node ran when, what it received, what it returned, retries
19
+ - `.session-info.json` — session metadata
20
+
21
+ The flag surface mirrors `zibby workflow trigger` (cloud) on purpose: the call you make locally is the same call you make against the cloud, just with the verb flipped.
22
+
23
+ ## Pass input
24
+
25
+ Most workflows take input. Edit `graph.mjs` to define an input schema and reference `state.input`:
26
+
27
+ ```js
28
+ graph.addNode('plan', {
29
+ prompt: ({ input }) => `Triage this ticket: ${input.ticket}`,
30
+ outputSchema: z.object({ tasks: z.array(z.string()) }),
31
+ agent: 'claude',
32
+ });
33
+ ```
34
+
35
+ Then pass input via `--input`:
36
+
37
+ ```bash
38
+ zibby workflow run my-pipeline --input '{"ticket":"BUG-123"}'
39
+ ```
40
+
41
+ Or `--param key=value` (repeatable, dot-notation supported):
42
+
43
+ ```bash
44
+ zibby workflow run my-pipeline -p ticket=BUG-123 -p priority=high
45
+ zibby workflow run my-pipeline -p user.name=Alice -p user.role=admin
46
+ ```
47
+
48
+ Or `--input-file payload.json` for larger payloads.
49
+
50
+ Precedence: `--param` > `--input` > `--input-file`. Same as `trigger`.
51
+
52
+ ## Iterating
53
+
54
+ Each run is a fresh process — re-edit `graph.mjs` or any node file and re-run. There's no daemon to restart; tool errors and crashes don't leave a server hanging on port 3848.
55
+
56
+ If you want auto-rerun on file change, run it under `nodemon`:
57
+
58
+ ```bash
59
+ npx nodemon --ext mjs,js --exec "zibby workflow run my-pipeline -p ticket=BUG-123"
60
+ ```
61
+
62
+ Or add it to your workflow's `package.json`:
63
+
64
+ ```json
65
+ {
66
+ "scripts": {
67
+ "dev": "nodemon --ext mjs,js --exec \"zibby workflow run my-pipeline\""
68
+ }
69
+ }
70
+ ```
71
+
72
+ Then `npm run dev`.
73
+
74
+ ## Inspect a run
75
+
76
+ After a run finishes, the CLI prints the session ID. Open the session folder to inspect every step:
77
+
78
+ ```bash
79
+ ls .zibby/output/sessions/<sessionId>/
80
+ cat .zibby/output/sessions/<sessionId>/result.json | jq
81
+ ```
82
+
83
+ ## Studio (long-lived server, optional)
84
+
85
+ Studio is a desktop UI for browsing live + past runs. It connects to a local HTTP server, so when you use Studio you start that instead:
86
+
87
+ ```bash
88
+ zibby workflow start my-pipeline # long-lived server on :3848 (Studio talks to this)
89
+ zibby studio # launch the desktop app
90
+ ```
91
+
92
+ For CLI-only iteration, stick with `zibby workflow run`.
93
+
94
+ → Next: [Deploy to cloud](./deploy)
@@ -0,0 +1,90 @@
1
+ ---
2
+ sidebar_position: 5
3
+ title: 5. Trigger & tail logs
4
+ pagination_prev: get-started/deploy
5
+ ---
6
+
7
+ # Run a deployed workflow and watch logs
8
+
9
+ ## Trigger
10
+
11
+ ```bash
12
+ zibby workflow trigger 2b1ea07f-3ede-4bfd-a51d-431f0bab008e
13
+ ```
14
+
15
+ The CLI returns immediately with a job ID:
16
+
17
+ ```
18
+ ✔ Workflow triggered successfully
19
+
20
+ Job Details:
21
+ Job ID: ee333411-22e6-4733-b790-d480af3f662e
22
+ Status: running
23
+ Version: 3
24
+ Triggered: 02/05/2026, 10:23:13
25
+
26
+ Monitor execution:
27
+ zibby workflow logs 2b1ea07f-...
28
+ zibby workflow logs 2b1ea07f-... -t
29
+ ```
30
+
31
+ Pass input the same way as locally:
32
+
33
+ ```bash
34
+ zibby workflow trigger <uuid> -p ticket=BUG-123
35
+ zibby workflow trigger <uuid> --input '{"ticket":"BUG-123"}'
36
+ zibby workflow trigger <uuid> --input-file ./input.json
37
+ ```
38
+
39
+ If you omit the UUID, the CLI shows an interactive picker over your deployed workflows.
40
+
41
+ ## Tail logs (Heroku-style)
42
+
43
+ ```bash
44
+ zibby workflow logs 2b1ea07f-3ede-4bfd-a51d-431f0bab008e -t
45
+ ```
46
+
47
+ `-t` follows live. Without `-t` it dumps the last execution and exits.
48
+
49
+ ```
50
+ Streaming logs for workflow 2b1ea07f-3ede-4bfd-a51d-431f0bab008e...
51
+ Press Ctrl+C to stop.
52
+
53
+ 2026-05-02 23:30:51.345 zibby v0.1.x
54
+ ────────────────────────────────────────────────────────────
55
+ Workflow: my-pipeline
56
+ Job: ee333411-...
57
+ Project: 6b60049d-...
58
+ Agent: cursor (model: auto)
59
+ ────────────────────────────────────────────────────────────
60
+ [setup] Bundle extracted (3.2s)
61
+ [setup] Loaded MyPipelineWorkflow
62
+ [setup] Registered 5 agent strategies (...)
63
+
64
+ ┌ example
65
+ │ ◆ Model: auto | key: ***bc97
66
+ │ ...
67
+ └ done 19.4s
68
+ [done] my-pipeline completed in 19.4s
69
+ ```
70
+
71
+ The stream covers the full execution end-to-end — agent reasoning, tool calls, schema validation, completion summary.
72
+
73
+ ## Multiple executions
74
+
75
+ Workflow UUIDs follow the workflow, not a single run. After one execution finishes, `logs -t` waits for the next trigger of the same workflow and auto-switches to streaming it. Like `heroku logs --tail`.
76
+
77
+ To exit after the current run, just Ctrl+C — there's no "exit on completion" mode (yet).
78
+
79
+ ## Triggering from anywhere
80
+
81
+ The CLI is the easiest way, but workflows expose an HTTP API for programmatic triggering — see [Cloud → Triggering programmatically](../cloud/triggering).
82
+
83
+ ## You're done
84
+
85
+ You've now scaffolded, run locally, deployed, triggered, and tailed a workflow. The rest of the docs go deeper:
86
+
87
+ - [Concepts](../concepts/graph) — how the graph engine works
88
+ - [CLI Reference](../cli-reference) — every command
89
+ - [Cloud](../cloud/triggering) — HTTP triggers, log archives, bundle internals
90
+ - [Packages](../packages/agent-workflow) — package-level docs