@zibby/skills 0.1.11 → 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.
- package/dist/package.json +2 -2
- package/docs/cli-reference.md +120 -256
- package/docs/cloning-repositories.md +2 -2
- package/docs/cloud/bundles.md +92 -0
- package/docs/cloud/dedicated-egress.md +140 -0
- package/docs/cloud/env-vars.md +144 -0
- package/docs/cloud/limits.md +81 -0
- package/docs/cloud/logs.md +104 -0
- package/docs/cloud/triggering.md +114 -0
- package/docs/concepts/agents.md +112 -0
- package/docs/concepts/graph.md +83 -0
- package/docs/concepts/sessions.md +70 -0
- package/docs/concepts/skills.md +84 -0
- package/docs/concepts/state.md +106 -0
- package/docs/get-started/deploy.md +75 -0
- package/docs/get-started/install.md +58 -0
- package/docs/get-started/run-locally.md +94 -0
- package/docs/get-started/trigger-and-logs.md +90 -0
- package/docs/get-started/your-first-workflow.md +66 -0
- package/docs/intro.md +37 -65
- package/docs/legacy/test-automation.md +110 -0
- package/docs/packages/agent-workflow.md +88 -0
- package/docs/packages/cli.md +42 -207
- package/docs/packages/core.md +40 -224
- package/docs/recipes/index.md +62 -0
- package/docs/recipes/test.md +154 -0
- package/package.json +2 -2
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 5
|
|
3
|
+
title: Dedicated egress IP
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dedicated egress IP
|
|
7
|
+
|
|
8
|
+
By default, every Zibby workflow exits via a random AWS IP that changes every run.
|
|
9
|
+
For most customers that's fine — but if your workflow needs to talk to a service
|
|
10
|
+
behind a firewall (private GitLab, Salesforce, Oracle Cloud, internal API behind a
|
|
11
|
+
corporate VPN), the random-IP behavior makes it unusable.
|
|
12
|
+
|
|
13
|
+
The **dedicated egress IP** addon pins all your workflow's outbound traffic to a
|
|
14
|
+
single static IP that you can whitelist once on the destination service.
|
|
15
|
+
|
|
16
|
+
## Pricing
|
|
17
|
+
|
|
18
|
+
**$50/month per account.** All your projects share the same IP.
|
|
19
|
+
|
|
20
|
+
## How it works
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Your Fargate task (random IP per run)
|
|
24
|
+
│
|
|
25
|
+
│ All HTTPS traffic tunneled through:
|
|
26
|
+
▼
|
|
27
|
+
┌──────────────────────────────────┐
|
|
28
|
+
│ Zibby's egress proxy │
|
|
29
|
+
│ - Validates your auth │
|
|
30
|
+
│ - Routes via YOUR static IP │
|
|
31
|
+
└──────────────────────────────────┘
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
Internet (sees your static IP, e.g. 54.66.241.180)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Every outbound HTTPS call from your workflow exits via your dedicated IP:
|
|
38
|
+
|
|
39
|
+
| What | Whether it tunnels |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `fetch()` from workflow code | ✅ via static IP |
|
|
42
|
+
| `git clone` private repos | ✅ via static IP |
|
|
43
|
+
| `npm install` from private registries | ✅ via static IP |
|
|
44
|
+
| `curl` / `wget` in shell scripts | ✅ via static IP |
|
|
45
|
+
| AWS SDK calls (S3, DynamoDB) | ❌ direct (AWS doesn't care about source IP) |
|
|
46
|
+
|
|
47
|
+
## Enabling
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 1. Enable the addon for your account (paid)
|
|
51
|
+
zibby deploy --dedicated-ip enable
|
|
52
|
+
|
|
53
|
+
# Output:
|
|
54
|
+
# Provisioning your dedicated egress IP...
|
|
55
|
+
# Done in 8s.
|
|
56
|
+
#
|
|
57
|
+
# Your static IP: 54.66.241.180
|
|
58
|
+
#
|
|
59
|
+
# Add this to your firewall allowlist, then opt projects in:
|
|
60
|
+
# zibby deploy --dedicated-ip use --project <project-id>
|
|
61
|
+
|
|
62
|
+
# 2. Opt each project in (free)
|
|
63
|
+
zibby deploy --dedicated-ip use --project my-project
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Checking status
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
zibby deploy --dedicated-ip status
|
|
70
|
+
|
|
71
|
+
# Output:
|
|
72
|
+
# Dedicated egress IP: active
|
|
73
|
+
#
|
|
74
|
+
# Your static IP: 54.66.241.180
|
|
75
|
+
# Provisioned: 2026-05-02
|
|
76
|
+
#
|
|
77
|
+
# Projects opted in:
|
|
78
|
+
# ✓ my-project
|
|
79
|
+
# ✗ other-project (not opted in)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Whitelisting on common services
|
|
83
|
+
|
|
84
|
+
**GitLab self-hosted:**
|
|
85
|
+
```
|
|
86
|
+
Admin → Settings → Network → Outbound requests
|
|
87
|
+
→ Allowlist: 54.66.241.180
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**GitHub Enterprise:**
|
|
91
|
+
```
|
|
92
|
+
Site admin → Authentication → IP allowlist
|
|
93
|
+
→ Add: 54.66.241.180
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**AWS Security Group (e.g. for a private RDS/ECS endpoint):**
|
|
97
|
+
```
|
|
98
|
+
Inbound rule → HTTPS → Source: 54.66.241.180/32
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Salesforce:**
|
|
102
|
+
```
|
|
103
|
+
Setup → Network Access → Trusted IP ranges
|
|
104
|
+
→ Add: 54.66.241.180 to 54.66.241.180
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## What stays the same
|
|
108
|
+
|
|
109
|
+
Your IP is **stable for as long as you have the addon enabled**:
|
|
110
|
+
|
|
111
|
+
- Survives Zibby infrastructure changes (we replace proxy boxes regularly)
|
|
112
|
+
- Survives our region failovers
|
|
113
|
+
- Survives your own workflow redeploys
|
|
114
|
+
|
|
115
|
+
The only way the IP changes is if **you** disable the addon, in which case the IP
|
|
116
|
+
is released back to AWS at the end of your billing period.
|
|
117
|
+
|
|
118
|
+
## Disabling
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
zibby deploy --dedicated-ip disable
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The IP stays attached until the end of your current billing period (no immediate
|
|
125
|
+
proration). After that, the IP is released.
|
|
126
|
+
|
|
127
|
+
If you re-enable later, you'll get a **different** IP — we can't guarantee the
|
|
128
|
+
same one. Re-whitelist on your destination services if you re-enable.
|
|
129
|
+
|
|
130
|
+
## Per-project IPs
|
|
131
|
+
|
|
132
|
+
Currently every project on your account shares the same IP. If you need separate
|
|
133
|
+
IPs per project (for compliance isolation, dev/staging/prod separation, etc.),
|
|
134
|
+
contact support.
|
|
135
|
+
|
|
136
|
+
## Limitations
|
|
137
|
+
|
|
138
|
+
- Currently only available in `ap-southeast-2` (Sydney). Multi-region coming.
|
|
139
|
+
- Only IPv4. No IPv6 yet.
|
|
140
|
+
- Outbound only. We don't host inbound services on your IP.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 4
|
|
3
|
+
title: Per-workflow env vars
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Per-workflow env vars
|
|
7
|
+
|
|
8
|
+
Each deployed workflow has its own encrypted env-var bag. The cloud runtime injects those vars into the Fargate task that runs the workflow — they show up in `process.env` like any other env var.
|
|
9
|
+
|
|
10
|
+
Use this for credentials that are **specific to one workflow** — different `ANTHROPIC_API_KEY` per pipeline, a workflow-only `DATABASE_URL`, an external webhook secret. Project-wide secrets stay on the project record (set in dashboard); workflow env wins on conflict.
|
|
11
|
+
|
|
12
|
+
## The fast path: `--env` at deploy
|
|
13
|
+
|
|
14
|
+
Most users want to ship a `.env` alongside the workflow:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
zibby workflow deploy my-pipeline --env .env
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The CLI deploys the workflow as usual, then syncs the `.env` into per-workflow env vars. You'll see:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
✔ Deployed my-pipeline (v1)
|
|
24
|
+
✔ Bundle ready (78s)
|
|
25
|
+
✔ Synced 4 env vars from .env
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Multiple files merge with later wins (mirrors how dotenv libraries usually layer):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
zibby workflow deploy my-pipeline --env .env --env .env.prod
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Manage after deploy: `zibby workflow env`
|
|
35
|
+
|
|
36
|
+
Four verbs, all keyed by the workflow UUID (from `zibby workflow list` or `.zibby-deploy.json`):
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
zibby workflow env list <uuid> # show key names (no values)
|
|
40
|
+
zibby workflow env set <uuid> ANTHROPIC_API_KEY=sk-… # add or rotate one
|
|
41
|
+
zibby workflow env unset <uuid> OLD_KEY # remove one
|
|
42
|
+
zibby workflow env push <uuid> --file .env [--file .env.prod] # bulk replace
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`set` is for surgical updates — leaves every other key alone. `push` is the deploy-flow `--env` exposed as a standalone command for when you want to update env without redeploying the workflow itself.
|
|
46
|
+
|
|
47
|
+
`list` only returns key names, never values. Once you set a value, the only place it surfaces is inside the running container.
|
|
48
|
+
|
|
49
|
+
### Examples
|
|
50
|
+
|
|
51
|
+
Rotate one key:
|
|
52
|
+
```bash
|
|
53
|
+
zibby workflow env set 1a255ded-9f57-44ad-81cf-70726b13d653 ANTHROPIC_API_KEY=sk-ant-rotated
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Wipe all env on a workflow (push an empty file):
|
|
57
|
+
```bash
|
|
58
|
+
zibby workflow env push <uuid> --file /dev/null
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
CI rotation (GitHub Actions):
|
|
62
|
+
```yaml
|
|
63
|
+
- run: |
|
|
64
|
+
echo "ANTHROPIC_API_KEY=$ANTHROPIC_KEY" > .env.cd
|
|
65
|
+
npx @zibby/cli workflow env push $WORKFLOW_UUID --file .env.cd
|
|
66
|
+
env:
|
|
67
|
+
ANTHROPIC_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
68
|
+
WORKFLOW_UUID: ${{ vars.WORKFLOW_UUID }}
|
|
69
|
+
ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Resolution order at trigger time
|
|
73
|
+
|
|
74
|
+
When a Fargate task starts, env vars come from three layers (later wins):
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
built-in container vars → project secrets (DDB) → workflow env (DDB)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
So if both your project record and your workflow env define `ANTHROPIC_API_KEY`, the workflow's value is what `process.env.ANTHROPIC_API_KEY` returns inside the run.
|
|
81
|
+
|
|
82
|
+
## Validation
|
|
83
|
+
|
|
84
|
+
| Field | Rule |
|
|
85
|
+
|---|---|
|
|
86
|
+
| Key name | Must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters, digits, underscores; can't start with a digit). Bash-compatible. |
|
|
87
|
+
| Value | Any string. Empty string is allowed. |
|
|
88
|
+
| `.env` files | Standard dotenv syntax — comments, quoted values, blank lines, `KEY=value` per line. |
|
|
89
|
+
|
|
90
|
+
The CLI validates locally before the API round-trip, so `zibby workflow env set <uuid> lowercase=v` fails fast with a readable message instead of a 400.
|
|
91
|
+
|
|
92
|
+
## Use case: multi-agent workflows
|
|
93
|
+
|
|
94
|
+
Different nodes in the same workflow may want to call different model vendors:
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
// graph.mjs
|
|
98
|
+
graph
|
|
99
|
+
.addNode('plan', { prompt, outputSchema: Plan, agent: 'claude' }) // uses ANTHROPIC_API_KEY
|
|
100
|
+
.addNode('implement', { prompt, outputSchema: Diff, agent: 'cursor' }) // uses CURSOR_API_KEY
|
|
101
|
+
.addNode('verify', { prompt, outputSchema: Result, agent: 'codex' }); // uses OPENAI_API_KEY
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Drop the three keys into `.env`, deploy:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
cat > .env <<EOF
|
|
108
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
109
|
+
CURSOR_API_KEY=key_...
|
|
110
|
+
OPENAI_API_KEY=sk-...
|
|
111
|
+
EOF
|
|
112
|
+
|
|
113
|
+
zibby workflow deploy multi-agent --env .env
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Each agent reads its own env var when invoked. No prompt-stuffing keys, no per-node config.
|
|
117
|
+
|
|
118
|
+
## Security model
|
|
119
|
+
|
|
120
|
+
- **Encryption**: KMS envelope encryption with per-account keys. The plaintext never lands in CloudWatch, DDB, or Lambda logs.
|
|
121
|
+
- **Access control**: every env command needs project-level access on the workflow's project — checked on every request.
|
|
122
|
+
- **Audit**: KMS logs every decrypt operation. Cross-reference with `WORKFLOW_JOB_ID` to see exactly which run pulled which secret.
|
|
123
|
+
- **Rotation**: `zibby workflow env set` with a new value — the next triggered run picks it up. Currently in-flight runs keep using the value they decrypted at start time.
|
|
124
|
+
|
|
125
|
+
## What this is *not*
|
|
126
|
+
|
|
127
|
+
- **Not for the project's primary credentials** — those live on the project record (dashboard → Project → Secrets). Use workflow env for *workflow-specific* overrides.
|
|
128
|
+
- **Not a values-readable store** — `list` returns key names only. If you need to retrieve the value, you'll have to push it again. This is intentional.
|
|
129
|
+
- **Not 1Password / Vault** — no rotation policies, no version history. Plain CRUD.
|
|
130
|
+
|
|
131
|
+
## HTTP API (advanced / scripting)
|
|
132
|
+
|
|
133
|
+
If you can't use the CLI (e.g. inline server-side trigger, similar to `triggering.md`'s webhook section), the routes are exposed directly:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
GET /workflows/{uuid}/env
|
|
137
|
+
PUT /workflows/{uuid}/env body: {"env": {"KEY": "value", ...}}
|
|
138
|
+
PATCH /workflows/{uuid}/env/{key} body: {"value": "..."}
|
|
139
|
+
DELETE /workflows/{uuid}/env/{key}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Auth is `Bearer` (session JWT or `ZIBBY_API_KEY`). Host is `https://api-prod.zibby.app`. There is no `/v1` prefix.
|
|
143
|
+
|
|
144
|
+
For everything else, use the CLI — it's the supported public surface and handles auth + UUID resolution + error messages for you.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 4
|
|
3
|
+
title: Limits & quotas
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Limits & quotas
|
|
7
|
+
|
|
8
|
+
## Workflow runtime cap
|
|
9
|
+
|
|
10
|
+
Every workflow execution has a **30-minute hard cap**. If a workflow exceeds it, the
|
|
11
|
+
container is terminated with exit code `124` (timeout) and the execution is marked
|
|
12
|
+
`failed` with reason `TIMEOUT`.
|
|
13
|
+
|
|
14
|
+
Why this exists:
|
|
15
|
+
- Stops runaway workflows (infinite loops, hung HTTP calls, stuck npm installs)
|
|
16
|
+
from burning unbounded compute
|
|
17
|
+
- Predictable per-execution cost ceiling
|
|
18
|
+
- Industry standard — GitHub Actions defaults to 6 hours, GitLab CI defaults to
|
|
19
|
+
1 hour, Vercel functions cap at 5 minutes. We picked 30 min as the sweet spot
|
|
20
|
+
for AI-driven workflows
|
|
21
|
+
|
|
22
|
+
If your workflow needs to run longer:
|
|
23
|
+
- Split it into multiple shorter executions chained via input/output
|
|
24
|
+
- Move long-running work (large npm installs, video processing) into your bundled
|
|
25
|
+
artifact at deploy time so the workflow itself stays short
|
|
26
|
+
- Contact us about a Pro tier with a longer cap
|
|
27
|
+
|
|
28
|
+
The cap is enforced **inside** the container by a watchdog timer set on startup,
|
|
29
|
+
so it works even if the AWS-side controls fail.
|
|
30
|
+
|
|
31
|
+
## Per-execution resource budget
|
|
32
|
+
|
|
33
|
+
| Resource | Limit |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Runtime | 30 min |
|
|
36
|
+
| CPU | 1 vCPU |
|
|
37
|
+
| Memory | 2 GB |
|
|
38
|
+
| Disk | 20 GB ephemeral |
|
|
39
|
+
| Outbound bandwidth | Unmetered |
|
|
40
|
+
|
|
41
|
+
If you hit memory or CPU limits, the container is OOM-killed and the execution is
|
|
42
|
+
marked failed.
|
|
43
|
+
|
|
44
|
+
## Container freedom (what you CAN do)
|
|
45
|
+
|
|
46
|
+
Inside your container, your workflow has **full control**:
|
|
47
|
+
|
|
48
|
+
- Install any npm package (`npm install`, `pip install`, `apt install` if root)
|
|
49
|
+
- Run any shell command (`curl`, `git`, `docker`-in-docker not supported)
|
|
50
|
+
- Spawn child processes
|
|
51
|
+
- Read/write files in `/workspace`
|
|
52
|
+
- Use the full CPU/memory budget for compute
|
|
53
|
+
|
|
54
|
+
Your code runs in an isolated Fargate task — no shared state with other customers,
|
|
55
|
+
no side effects on Zibby infrastructure.
|
|
56
|
+
|
|
57
|
+
## What you CAN'T do
|
|
58
|
+
|
|
59
|
+
| Boundary | Why |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Talk to other customers' workflows | Each task is a separate isolated container |
|
|
62
|
+
| Use someone else's static IP | Only your account's IP is reachable from your task |
|
|
63
|
+
| Run beyond the 30-min cap | Watchdog kills the process |
|
|
64
|
+
| Read Zibby infra secrets | Container IAM role only sees your execution data |
|
|
65
|
+
| Persist state between runs | Containers are ephemeral — use S3 or your DB for state |
|
|
66
|
+
|
|
67
|
+
## Outbound network
|
|
68
|
+
|
|
69
|
+
By default your workflow exits via a random AWS IP that changes every run. If you
|
|
70
|
+
need a stable IP for whitelisting customer firewalls, see
|
|
71
|
+
[Dedicated egress IP](./dedicated-egress) ($50/mo addon).
|
|
72
|
+
|
|
73
|
+
## Rate limits
|
|
74
|
+
|
|
75
|
+
| Endpoint | Limit |
|
|
76
|
+
|---|---|
|
|
77
|
+
| Trigger workflow | 60/min per account |
|
|
78
|
+
| Read logs | 600/min per account |
|
|
79
|
+
| Deploy workflow | 30/hour per account |
|
|
80
|
+
|
|
81
|
+
Hitting a rate limit returns `429 Too Many Requests` with a `Retry-After` header.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 2
|
|
3
|
+
title: Logs
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Logs
|
|
7
|
+
|
|
8
|
+
Cloud workflow runs stream to CloudWatch in real time. The CLI exposes them via Server-Sent Events (SSE) — `zibby workflow logs <uuid> -t` is a thin client over that.
|
|
9
|
+
|
|
10
|
+
## Tail live
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
zibby workflow logs <uuid> -t
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
What you see:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Streaming logs for workflow 2b1ea07f-3ede-4bfd-a51d-431f0bab008e...
|
|
20
|
+
Press Ctrl+C to stop.
|
|
21
|
+
|
|
22
|
+
2026-05-02 23:30:51.345 zibby v0.1.x
|
|
23
|
+
────────────────────────────────────────────────────────────
|
|
24
|
+
Workflow: my-pipeline
|
|
25
|
+
Job: ee333411-...
|
|
26
|
+
Project: 6b60049d-...
|
|
27
|
+
Agent: cursor (model: auto)
|
|
28
|
+
────────────────────────────────────────────────────────────
|
|
29
|
+
[setup] Bundle extracted (3.2s)
|
|
30
|
+
[setup] Loaded MyPipelineWorkflow
|
|
31
|
+
[setup] Registered 5 agent strategies (...)
|
|
32
|
+
|
|
33
|
+
┌ example
|
|
34
|
+
│ ◆ Model: auto | key: ***bc97
|
|
35
|
+
│ Prompt sent to LLM:
|
|
36
|
+
│ ...
|
|
37
|
+
│ ◆ status: warn
|
|
38
|
+
└ done 19.4s
|
|
39
|
+
[done] my-pipeline completed in 19.4s
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Heroku-style follow
|
|
43
|
+
|
|
44
|
+
UUID is a *workflow* identifier, not an execution identifier. With `-t`, after one execution finishes the stream waits for the next trigger of the same workflow and auto-switches:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Waiting for next execution...
|
|
48
|
+
|
|
49
|
+
┌─ Execution: cd1f55d5...43d7 (task: 3b85ee3a)
|
|
50
|
+
└─ Streaming logs...
|
|
51
|
+
|
|
52
|
+
(streams the new execution)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Ctrl+C to exit. There's no "exit on completion" mode — if you only want logs from one specific run, dump (without `-t`):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
zibby workflow logs <uuid>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Reconnects
|
|
62
|
+
|
|
63
|
+
The SSE client reconnects automatically on transient errors. You'll see at most one `SSE Error:` + `Reconnecting...` per outage; once recovered, `Reconnected.` is printed once and the stream continues. No spam during cold-start flap.
|
|
64
|
+
|
|
65
|
+
## Past runs
|
|
66
|
+
|
|
67
|
+
CloudWatch retains logs for 30 days by default. Beyond that, the per-run session folder (uploaded to S3 at the end of each execution) is the long-term archive — accessible via `zibby workflow download <uuid>`.
|
|
68
|
+
|
|
69
|
+
## Programmatic access
|
|
70
|
+
|
|
71
|
+
The same SSE endpoint is consumable from your own code:
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
const eventSource = new EventSource(
|
|
75
|
+
`https://logs-stream.zibby.app/?jobId=${uuid}`,
|
|
76
|
+
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
eventSource.addEventListener('log', (e) => {
|
|
80
|
+
const { timestamp, message } = JSON.parse(e.data);
|
|
81
|
+
console.log(timestamp, message);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
eventSource.addEventListener('complete', () => {
|
|
85
|
+
console.log('Run finished');
|
|
86
|
+
eventSource.close();
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or use the polling endpoint for batch retrieval:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
GET /v1/workflows/<uuid>/logs?lines=1000&since=<unix-ms>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Filtering by job ID
|
|
97
|
+
|
|
98
|
+
`uuid` matches the workflow. To pin to a specific execution, pass the job ID instead:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
zibby workflow logs <jobId>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The CLI auto-detects: if it's an execution row, you stream that one. If it's a workflow row, you get follow-mode.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 1
|
|
3
|
+
title: Triggering programmatically
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Triggering programmatically
|
|
7
|
+
|
|
8
|
+
The CLI is the public surface for triggering workflows. CI runners, cron hosts, webhook handlers — all of them shell out to the same command:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
zibby workflow trigger <uuid>
|
|
12
|
+
zibby workflow trigger <uuid> -p ticket=BUG-123
|
|
13
|
+
zibby workflow trigger <uuid> --input '{"ticket":"BUG-123","priority":"high"}'
|
|
14
|
+
zibby workflow trigger <uuid> --input-file payload.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Auth: set `ZIBBY_API_KEY` in the environment, or run `zibby login` once on a workstation. Either works; the CLI picks up whichever is available.
|
|
18
|
+
|
|
19
|
+
The flag surface is identical to `zibby workflow run` (local) — same `-p / --input / --input-file`, plus `--idempotency-key` for the cloud-only dedup case below. Flip the verb and the same call shape goes from local to remote.
|
|
20
|
+
|
|
21
|
+
## CI / cron
|
|
22
|
+
|
|
23
|
+
Anywhere you can shell out, call the CLI. Don't hand-roll an HTTP client — you'll just rebuild what the CLI already does (project lookup from UUID, idempotency, quota error messages, retries).
|
|
24
|
+
|
|
25
|
+
### GitHub Actions
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
- name: Trigger Zibby workflow
|
|
29
|
+
run: |
|
|
30
|
+
npm i -g @zibby/cli
|
|
31
|
+
zibby workflow trigger $WORKFLOW_UUID -p sha=$GITHUB_SHA -p pr=$PR_NUMBER
|
|
32
|
+
env:
|
|
33
|
+
WORKFLOW_UUID: 2b1ea07f-3ede-4bfd-a51d-431f0bab008e
|
|
34
|
+
ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Cron (any provider)
|
|
38
|
+
|
|
39
|
+
GitHub Actions schedule, Vercel Cron, EventBridge with a Lambda runner, fly.io machines — all the same pattern:
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
on:
|
|
43
|
+
schedule:
|
|
44
|
+
- cron: '0 9 * * 1' # every Monday 9am UTC
|
|
45
|
+
jobs:
|
|
46
|
+
triage:
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
steps:
|
|
49
|
+
- run: npm i -g @zibby/cli
|
|
50
|
+
- run: zibby workflow trigger $UUID --input '{"weekly":true}'
|
|
51
|
+
env:
|
|
52
|
+
UUID: ${{ vars.WORKFLOW_UUID }}
|
|
53
|
+
ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Webhook handlers
|
|
57
|
+
|
|
58
|
+
Inside a Node/Python/Go server processing an inbound webhook (Stripe, GitHub, Linear), spawn the CLI from your handler. You inherit all of its behavior — auth, error handling, idempotency — and don't write any of it yourself.
|
|
59
|
+
|
|
60
|
+
```js
|
|
61
|
+
import { execFileSync } from 'node:child_process';
|
|
62
|
+
|
|
63
|
+
app.post('/webhook', (req, res) => {
|
|
64
|
+
if (!verifySignature(req)) return res.status(401).end();
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
execFileSync('zibby', [
|
|
68
|
+
'workflow', 'trigger', process.env.WORKFLOW_UUID,
|
|
69
|
+
'--input', JSON.stringify(req.body),
|
|
70
|
+
'--idempotency-key', req.headers['x-event-id'],
|
|
71
|
+
], { env: process.env, stdio: 'pipe' });
|
|
72
|
+
res.status(202).end();
|
|
73
|
+
} catch (err) {
|
|
74
|
+
res.status(502).end();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If your runtime can't spawn a Node CLI (constrained Lambda layers, edge runtimes, non-Node servers without child_process), open an issue — that's the case worth a real SDK, not a documented HTTP surface.
|
|
80
|
+
|
|
81
|
+
## Idempotency
|
|
82
|
+
|
|
83
|
+
Pass an idempotency key to deduplicate triggers within a 24-hour window:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
zibby workflow trigger <uuid> \
|
|
87
|
+
-p ticket=BUG-123 \
|
|
88
|
+
--idempotency-key webhook-2026-05-02-event-7
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Same key + same input within 24h returns the original `jobId` instead of starting a new run. Use the inbound event's ID (`X-Event-Id`, Stripe's `event.id`, GitHub's delivery ID) — that way a retry from the source automatically dedupes.
|
|
92
|
+
|
|
93
|
+
## Tailing the result
|
|
94
|
+
|
|
95
|
+
After triggering, the CLI prints the `jobId`. To watch the execution:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
zibby workflow logs <uuid> -t
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
See [`workflow logs` in the CLI Reference](../cli-reference#workflow-logs).
|
|
102
|
+
|
|
103
|
+
## Per-workflow env vars
|
|
104
|
+
|
|
105
|
+
If your workflow needs credentials or config that's specific to it (different `ANTHROPIC_API_KEY` per pipeline, a workflow-only `DATABASE_URL`, etc.), set them via the env-var API — see [Per-workflow env vars](./env-vars). They get injected into the Fargate task at trigger time and override anything set on the project record.
|
|
106
|
+
|
|
107
|
+
## Quotas
|
|
108
|
+
|
|
109
|
+
Per-project quota:
|
|
110
|
+
- Concurrent executions
|
|
111
|
+
- Total executions per day
|
|
112
|
+
- Per-execution wall-clock cap (default: 30 min)
|
|
113
|
+
|
|
114
|
+
Hit a quota and the trigger errors out with a readable message + retry hint. The CLI surfaces these directly; if you're shelling out from CI, the non-zero exit + stderr is enough to fail the job and have your retry logic kick in.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 2
|
|
3
|
+
title: Agent strategies
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Agent strategies
|
|
7
|
+
|
|
8
|
+
A **strategy** is the bridge between a node and a real coding-agent CLI. The framework ships with five built-in strategies; you can also write your own.
|
|
9
|
+
|
|
10
|
+
## Built-ins
|
|
11
|
+
|
|
12
|
+
| Strategy | Backed by | When to pick it |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `cursor` | `cursor-agent` CLI | Fast, file-aware, great default for code tasks |
|
|
15
|
+
| `claude` | `@anthropic-ai/claude-agent-sdk` | Best reasoning, deep tool-use loops, large context |
|
|
16
|
+
| `codex` | `@openai/codex` CLI | Strong general-purpose, good for verification nodes |
|
|
17
|
+
| `gemini` | `@google/gemini-cli` | When you specifically want Gemini's behavior |
|
|
18
|
+
| `assistant` | OpenAI Assistants API | Stateful conversations, retrieval, file uploads |
|
|
19
|
+
|
|
20
|
+
## Selecting per node
|
|
21
|
+
|
|
22
|
+
Two ways:
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
// 1. Per-node config — wins over everything else
|
|
26
|
+
graph.addNode('plan', { prompt, outputSchema, agent: 'claude' });
|
|
27
|
+
|
|
28
|
+
// 2. Project default — falls through if no per-node override
|
|
29
|
+
// .zibby.config.mjs
|
|
30
|
+
export default {
|
|
31
|
+
agent: { default: 'cursor' },
|
|
32
|
+
};
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The resolution order: `node.agent` → `state.agentType` → `process.env.AGENT_TYPE` → project config default.
|
|
36
|
+
|
|
37
|
+
## Models
|
|
38
|
+
|
|
39
|
+
Each agent CLI has its own model selector. Override it via:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
// Per-node model
|
|
43
|
+
graph.addNode('plan', {
|
|
44
|
+
prompt,
|
|
45
|
+
outputSchema,
|
|
46
|
+
agent: 'claude',
|
|
47
|
+
model: 'claude-opus-4-6',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Or globally per-agent in .zibby.config.mjs
|
|
51
|
+
export default {
|
|
52
|
+
agent: {
|
|
53
|
+
default: 'cursor',
|
|
54
|
+
claude: { model: 'claude-opus-4-6' },
|
|
55
|
+
cursor: { model: 'auto' },
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`auto` (the default for cursor/claude/gemini) uses the agent CLI's own current default — which tracks the latest stable model.
|
|
61
|
+
|
|
62
|
+
## Bring your own
|
|
63
|
+
|
|
64
|
+
The `AgentStrategy` base class is two methods:
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
import { AgentStrategy, registerStrategy } from '@zibby/agent-workflow';
|
|
68
|
+
|
|
69
|
+
class MyAgent extends AgentStrategy {
|
|
70
|
+
constructor() { super('mine', 'My custom agent', 100); }
|
|
71
|
+
|
|
72
|
+
canHandle(_context) {
|
|
73
|
+
return Boolean(process.env.MY_API_KEY);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async invoke(prompt, { schema, model }) {
|
|
77
|
+
const raw = await fetch('https://my.api/chat', {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
body: JSON.stringify({ prompt, model: model ?? 'default' }),
|
|
80
|
+
}).then(r => r.text());
|
|
81
|
+
|
|
82
|
+
return { raw, structured: schema.parse(JSON.parse(raw)) };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
registerStrategy(new MyAgent());
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Then a node can use it:
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
graph.addNode('plan', { prompt, outputSchema: Plan, agent: 'mine' });
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The framework ships **zero** agent strategies bundled — `@zibby/agent-workflow` is BYO. The five built-ins above live in `@zibby/core`, which is what `zibby workflow new` scaffolds and what the cloud runtime preloads.
|
|
96
|
+
|
|
97
|
+
## Authentication
|
|
98
|
+
|
|
99
|
+
| Strategy | Env var | Alternative |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| `cursor` | `CURSOR_API_KEY` | `cursor-agent login` |
|
|
102
|
+
| `claude` | `ANTHROPIC_API_KEY` | — |
|
|
103
|
+
| `codex` | `OPENAI_API_KEY` | — |
|
|
104
|
+
| `gemini` | `GOOGLE_API_KEY` | — |
|
|
105
|
+
| `assistant` | `OPENAI_API_KEY` | — |
|
|
106
|
+
|
|
107
|
+
In Zibby Cloud, you have two options:
|
|
108
|
+
|
|
109
|
+
- **Project-wide credentials**: set once on the project record (dashboard → Project → Secrets) — every workflow in the project uses them.
|
|
110
|
+
- **Per-workflow overrides**: set on a single workflow via [`PUT /workflows/<uuid>/env`](../cloud/env-vars) — useful when one pipeline needs a different `ANTHROPIC_API_KEY` from the rest of the project, or when one workflow needs to talk to multiple agent vendors with their own keys.
|
|
111
|
+
|
|
112
|
+
Workflow env wins over project secrets on conflict (last-write-wins inside the Fargate task).
|