@zibby/skills 0.1.8 → 0.1.10
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/browser.js +2 -2
- package/dist/chat-memory.js +15 -15
- package/dist/core-tools.js +2 -2
- package/dist/function-skill.js +1 -1
- package/dist/git.js +2 -2
- package/dist/github.js +3 -3
- package/dist/index.js +646 -1
- package/dist/jira.js +6 -6
- package/dist/memory.js +4 -4
- package/dist/package.json +16 -11
- package/dist/sentry.js +2 -2
- package/dist/skill-installer.js +3 -3
- package/dist/slack.js +2 -2
- package/dist/test-runner.js +13 -13
- package/dist/workflow-builder.js +146 -82
- package/docs/analysis.md +109 -0
- package/docs/cli-reference.md +338 -0
- package/docs/cloning-repositories.md +285 -0
- package/docs/custom-workflows.md +358 -0
- package/docs/getting-started.md +108 -0
- package/docs/installation.md +127 -0
- package/docs/integrations/github.md +73 -0
- package/docs/integrations/jira.md +71 -0
- package/docs/intro.md +87 -0
- package/docs/packages/cli.md +238 -0
- package/docs/packages/core.md +256 -0
- package/docs/packages/mcp-browser.md +110 -0
- package/docs/packages/memory.md +223 -0
- package/docs/packages/skills.md +216 -0
- package/docs/reviewing-results.md +114 -0
- package/docs/running-tests.md +134 -0
- package/docs/triggering-workflows.md +552 -0
- package/docs/workflow-artifact-layout-evaluation.md +119 -0
- package/docs/workflow.md +558 -0
- package/package.json +7 -2
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 5
|
|
3
|
+
title: Running Tests
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Running Tests
|
|
7
|
+
|
|
8
|
+
Zibby runs tests locally using an AI agent that drives a real browser. It records video, captures actions, and generates reusable Playwright scripts.
|
|
9
|
+
|
|
10
|
+
## Basic Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
zibby test test-specs/login.txt --agent cursor
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## From a Test Spec File
|
|
17
|
+
|
|
18
|
+
Create a plain-text file with test steps:
|
|
19
|
+
|
|
20
|
+
```text title="test-specs/login.txt"
|
|
21
|
+
1. Navigate to the login page
|
|
22
|
+
2. Enter email: test@example.com
|
|
23
|
+
3. Enter password: TestPass123
|
|
24
|
+
4. Click the Sign In button
|
|
25
|
+
5. Verify the dashboard page loads
|
|
26
|
+
6. Verify the user's name appears in the header
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Run it:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
zibby test test-specs/login.txt
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## From Cloud Test Cases
|
|
36
|
+
|
|
37
|
+
After running analysis on a Jira ticket in the dashboard:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
zibby test --sources TC001,TC002 --execution abc-123-def --sync
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## What Happens During a Run
|
|
44
|
+
|
|
45
|
+
The default workflow executes three nodes:
|
|
46
|
+
|
|
47
|
+
1. **Preflight** — AI extracts a title and assertions from the test spec
|
|
48
|
+
2. **Execute Live** — AI drives a Playwright browser, following the test steps
|
|
49
|
+
3. **Generate Script** — AI produces a reusable `.spec.js` from recorded actions
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Test Spec → Preflight → Execute Live → Generate Script → Done
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Choosing an AI Agent
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Cursor Agent (uses Cursor IDE or CURSOR_API_KEY)
|
|
59
|
+
zibby test test-specs/login.txt --agent cursor
|
|
60
|
+
|
|
61
|
+
# Claude (uses ANTHROPIC_API_KEY)
|
|
62
|
+
zibby test test-specs/login.txt --agent claude
|
|
63
|
+
|
|
64
|
+
# Codex (uses OPENAI_API_KEY + codex CLI)
|
|
65
|
+
zibby test test-specs/login.txt --agent codex
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Headless Mode
|
|
69
|
+
|
|
70
|
+
Run without a visible browser (for CI/CD):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
zibby test test-specs/login.txt --headless
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Cloud Sync
|
|
77
|
+
|
|
78
|
+
Upload results to the [Zibby dashboard](https://zibby.app):
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Upload to dashboard
|
|
82
|
+
zibby test test-specs/login.txt --sync
|
|
83
|
+
|
|
84
|
+
# Organize into a collection
|
|
85
|
+
zibby test test-specs/login.txt --collection "Auth Tests" --sync
|
|
86
|
+
|
|
87
|
+
# With subfolder
|
|
88
|
+
zibby test test-specs/login.txt --collection "Auth Tests" --folder "Login" --sync
|
|
89
|
+
|
|
90
|
+
# Local only (no upload)
|
|
91
|
+
zibby test test-specs/login.txt --no-sync
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The `cloudSync` setting in `.zibby.config.js` sets the default. CLI flags override it.
|
|
95
|
+
|
|
96
|
+
## Running a Single Node
|
|
97
|
+
|
|
98
|
+
Re-run just one step of the workflow (useful for debugging):
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Re-execute the browser test (reusing previous session)
|
|
102
|
+
zibby test test-specs/login.txt --node execute_live --session last
|
|
103
|
+
|
|
104
|
+
# Only regenerate the Playwright script
|
|
105
|
+
zibby test test-specs/login.txt --node generate_script --session last
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Custom Workflows
|
|
109
|
+
|
|
110
|
+
If you've created a custom workflow in `.zibby/graph.js`:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
zibby test test-specs/login.txt --workflow QuickSmokeWorkflow
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Supported formats: `QuickSmokeWorkflow`, `QuickSmoke`, `quick-smoke`.
|
|
117
|
+
|
|
118
|
+
## Opening Results in Browser
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
zibby test test-specs/login.txt --sync --open
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The `--open` flag opens the dashboard results page after upload.
|
|
125
|
+
|
|
126
|
+
## Debugging
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Info-level logs
|
|
130
|
+
zibby test test-specs/login.txt --verbose
|
|
131
|
+
|
|
132
|
+
# Full debug logs
|
|
133
|
+
zibby test test-specs/login.txt --debug
|
|
134
|
+
```
|
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 6
|
|
3
|
+
title: Triggering Workflows
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Triggering Workflows
|
|
7
|
+
|
|
8
|
+
Learn how to trigger Zibby workflows using the API, CLI, webhooks, cron jobs, and third-party integrations.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Once deployed, workflows can be triggered from anywhere via HTTP API. Every trigger spawns an isolated execution in Zibby Cloud (ECS Fargate), with full logging and quota tracking.
|
|
13
|
+
|
|
14
|
+
### Execution Flow
|
|
15
|
+
|
|
16
|
+
1. Client triggers workflow via API
|
|
17
|
+
2. Backend validates quota & permissions
|
|
18
|
+
3. ECS Fargate task spawned with `zibby run-workflow`
|
|
19
|
+
4. Workflow sources fetched from S3
|
|
20
|
+
5. Graph executes in isolated container
|
|
21
|
+
6. Results uploaded to cloud
|
|
22
|
+
7. Logs streamed to CloudWatch
|
|
23
|
+
|
|
24
|
+
## Trigger Methods
|
|
25
|
+
|
|
26
|
+
### 1. CLI (Local Development)
|
|
27
|
+
|
|
28
|
+
Trigger workflows directly from your terminal using workflow UUID (project auto-discovered):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Trigger by workflow UUID (simplest - no project needed)
|
|
32
|
+
zibby trigger 562e48d7-ef67-4900-96b7-0d7b51a33405
|
|
33
|
+
|
|
34
|
+
# With input data
|
|
35
|
+
zibby trigger 562e48d7-ef67-4900-96b7-0d7b51a33405 \
|
|
36
|
+
--input '{"ticket":"JIRA-123"}'
|
|
37
|
+
|
|
38
|
+
# By workflow name (requires project ID)
|
|
39
|
+
zibby trigger custom-flow --project <id> \
|
|
40
|
+
--input '{"key":"value"}'
|
|
41
|
+
|
|
42
|
+
# With idempotency key (prevents duplicate runs)
|
|
43
|
+
zibby trigger 562e48d7-ef67-4900-96b7-0d7b51a33405 \
|
|
44
|
+
--idempotency-key "daily-scan-2026-04-27"
|
|
45
|
+
|
|
46
|
+
# Stream logs immediately after triggering
|
|
47
|
+
zibby trigger 562e48d7-ef67-4900-96b7-0d7b51a33405 && \
|
|
48
|
+
zibby logs 562e48d7-ef67-4900-96b7-0d7b51a33405 -t
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. HTTP API
|
|
52
|
+
|
|
53
|
+
#### Standard Endpoint
|
|
54
|
+
|
|
55
|
+
Always available for all workflows:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
curl -X POST https://api.zibby.app/projects/{projectId}/workflows/{type}/trigger \
|
|
59
|
+
-H "Authorization: Bearer zby_xxx" \
|
|
60
|
+
-H "Content-Type: application/json" \
|
|
61
|
+
-d '{"input": {"ticket": "JIRA-123"}}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Request Body:**
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"input": {
|
|
68
|
+
"ticket": "JIRA-123",
|
|
69
|
+
"branch": "main"
|
|
70
|
+
},
|
|
71
|
+
"idempotencyKey": "optional-unique-key-for-deduplication"
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Response (202 Accepted):**
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"jobId": "job-...",
|
|
79
|
+
"status": "accepted",
|
|
80
|
+
"workflow": "custom-flow",
|
|
81
|
+
"version": 2,
|
|
82
|
+
"projectId": "...",
|
|
83
|
+
"triggeredAt": "2026-04-24T..."
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### Custom Subdomain (Optional)
|
|
88
|
+
|
|
89
|
+
Each deployed workflow gets a unique subdomain URL for cleaner integration:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
curl -X POST https://my-security-scan.workflows.zibby.app/trigger \
|
|
93
|
+
-H "Authorization: Bearer zby_xxx" \
|
|
94
|
+
-H "Content-Type: application/json" \
|
|
95
|
+
-d '{"input": {"branch": "main"}}'
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The subdomain maps to a specific `{projectId, workflowType}` pair, ideal for:
|
|
99
|
+
- Webhooks (cleaner URLs)
|
|
100
|
+
- Public APIs
|
|
101
|
+
- Third-party integrations
|
|
102
|
+
- Branded endpoints
|
|
103
|
+
|
|
104
|
+
### 3. Scheduled Execution
|
|
105
|
+
|
|
106
|
+
#### AWS EventBridge (Serverless)
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
# CloudFormation
|
|
110
|
+
EventBridgeRule:
|
|
111
|
+
Type: AWS::Events::Rule
|
|
112
|
+
Properties:
|
|
113
|
+
ScheduleExpression: 'cron(0 9 * * ? *)' # Daily 9am
|
|
114
|
+
Targets:
|
|
115
|
+
- Arn: !GetAtt TriggerFunction.Arn
|
|
116
|
+
Input: |
|
|
117
|
+
{
|
|
118
|
+
"projectId": "6b60049d-...",
|
|
119
|
+
"workflowType": "custom-flow",
|
|
120
|
+
"input": {"source": "cron"}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### GitHub Actions
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
name: Daily Security Scan
|
|
128
|
+
on:
|
|
129
|
+
schedule:
|
|
130
|
+
- cron: '0 0 * * *' # Daily midnight
|
|
131
|
+
|
|
132
|
+
jobs:
|
|
133
|
+
trigger:
|
|
134
|
+
runs-on: ubuntu-latest
|
|
135
|
+
steps:
|
|
136
|
+
- name: Trigger Zibby Workflow
|
|
137
|
+
run: |
|
|
138
|
+
curl -X POST https://api.zibby.app/projects/$PROJECT_ID/workflows/security-scan/trigger \
|
|
139
|
+
-H "Authorization: Bearer $ZIBBY_API_KEY" \
|
|
140
|
+
-d '{"input": {"branch": "${{ github.ref }}"}}'
|
|
141
|
+
env:
|
|
142
|
+
ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
|
|
143
|
+
PROJECT_ID: ${{ vars.ZIBBY_PROJECT_ID }}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### Traditional Cron (Linux)
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# /etc/crontab or crontab -e
|
|
150
|
+
0 9 * * * zibby trigger custom-flow --project <id> >> /var/log/zibby.log 2>&1
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 4. Webhooks
|
|
154
|
+
|
|
155
|
+
#### Jira Webhook Integration
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
// AWS Lambda or Express endpoint
|
|
159
|
+
app.post('/webhooks/jira', async (req, res) => {
|
|
160
|
+
const { issue } = req.body;
|
|
161
|
+
|
|
162
|
+
if (issue.fields.status === 'Ready for Testing') {
|
|
163
|
+
await fetch('https://api.zibby.app/projects/{projectId}/workflows/test-gen/trigger', {
|
|
164
|
+
method: 'POST',
|
|
165
|
+
headers: {
|
|
166
|
+
'Authorization': `Bearer ${process.env.ZIBBY_API_KEY}`,
|
|
167
|
+
'Content-Type': 'application/json',
|
|
168
|
+
},
|
|
169
|
+
body: JSON.stringify({
|
|
170
|
+
input: {
|
|
171
|
+
ticketKey: issue.key,
|
|
172
|
+
title: issue.fields.summary,
|
|
173
|
+
description: issue.fields.description,
|
|
174
|
+
},
|
|
175
|
+
idempotencyKey: `jira-${issue.key}-${issue.updated}`,
|
|
176
|
+
}),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
res.sendStatus(200);
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### GitHub Pull Request Trigger
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
# .github/workflows/zibby-analyze.yml
|
|
188
|
+
name: Zibby Code Analysis
|
|
189
|
+
on:
|
|
190
|
+
pull_request:
|
|
191
|
+
types: [opened, synchronize]
|
|
192
|
+
|
|
193
|
+
jobs:
|
|
194
|
+
analyze:
|
|
195
|
+
runs-on: ubuntu-latest
|
|
196
|
+
steps:
|
|
197
|
+
- name: Trigger Zibby Analysis
|
|
198
|
+
run: |
|
|
199
|
+
curl -X POST https://api.zibby.app/projects/$PROJECT_ID/workflows/code-review/trigger \
|
|
200
|
+
-H "Authorization: Bearer $ZIBBY_API_KEY" \
|
|
201
|
+
-d '{
|
|
202
|
+
"input": {
|
|
203
|
+
"prNumber": "${{ github.event.pull_request.number }}",
|
|
204
|
+
"repo": "${{ github.repository }}",
|
|
205
|
+
"branch": "${{ github.head_ref }}"
|
|
206
|
+
},
|
|
207
|
+
"idempotencyKey": "pr-${{ github.event.pull_request.number }}-${{ github.sha }}"
|
|
208
|
+
}'
|
|
209
|
+
env:
|
|
210
|
+
ZIBBY_API_KEY: ${{ secrets.ZIBBY_API_KEY }}
|
|
211
|
+
PROJECT_ID: ${{ vars.ZIBBY_PROJECT_ID }}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### 5. Third-Party Integrations
|
|
215
|
+
|
|
216
|
+
#### No-Code Platforms (Zapier/Make.com)
|
|
217
|
+
|
|
218
|
+
Configure an action to POST to the Zibby API:
|
|
219
|
+
- **Trigger**: Google Sheets row added, Slack message, etc.
|
|
220
|
+
- **Action**: HTTP POST to `https://api.zibby.app/projects/{id}/workflows/{type}/trigger`
|
|
221
|
+
- **Headers**: Add `Authorization: Bearer {your-token}`
|
|
222
|
+
- **Body**: JSON with `input` field
|
|
223
|
+
|
|
224
|
+
#### AWS Step Functions
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"StartAt": "CheckCode",
|
|
229
|
+
"States": {
|
|
230
|
+
"CheckCode": {
|
|
231
|
+
"Type": "Task",
|
|
232
|
+
"Resource": "arn:aws:lambda:...:TriggerZibbyWorkflow",
|
|
233
|
+
"Parameters": {
|
|
234
|
+
"workflow": "security-scan"
|
|
235
|
+
},
|
|
236
|
+
"Next": "WaitForCompletion"
|
|
237
|
+
},
|
|
238
|
+
"WaitForCompletion": {
|
|
239
|
+
"Type": "Wait",
|
|
240
|
+
"Seconds": 300,
|
|
241
|
+
"Next": "CheckResults"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Authentication
|
|
248
|
+
|
|
249
|
+
Zibby uses two types of authentication tokens:
|
|
250
|
+
|
|
251
|
+
### Personal Access Tokens (PAT)
|
|
252
|
+
|
|
253
|
+
For programmatic access (API, CLI, webhooks, CI/CD):
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
Format: zby_pat_xxxxx
|
|
257
|
+
Scope: All projects user has access to
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Create a PAT:**
|
|
261
|
+
1. Go to Settings > API Tokens
|
|
262
|
+
2. Click "Create Token"
|
|
263
|
+
3. Name it (e.g., "Production Webhook")
|
|
264
|
+
4. Optionally set expiration
|
|
265
|
+
5. Copy token (shown only once!)
|
|
266
|
+
|
|
267
|
+
**Usage:**
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# CLI
|
|
271
|
+
export ZIBBY_API_KEY=zby_pat_xxxxx
|
|
272
|
+
zibby trigger custom-flow --project <id>
|
|
273
|
+
|
|
274
|
+
# API Request
|
|
275
|
+
curl -X POST https://api.zibby.app/projects/<id>/workflows/custom-flow/trigger \
|
|
276
|
+
-H "Authorization: Bearer zby_pat_xxxxx" \
|
|
277
|
+
-d '{"input": {"ticket": "JIRA-123"}}'
|
|
278
|
+
|
|
279
|
+
# GitHub Actions
|
|
280
|
+
env:
|
|
281
|
+
ZIBBY_API_KEY: ${{ secrets.ZIBBY_PAT }}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
**Characteristics:**
|
|
285
|
+
- User creates in UI (Settings > API Tokens)
|
|
286
|
+
- Long-lived (or custom expiration)
|
|
287
|
+
- Can be revoked individually
|
|
288
|
+
- Named tokens for tracking
|
|
289
|
+
- User's access controls apply
|
|
290
|
+
|
|
291
|
+
### JWT Tokens
|
|
292
|
+
|
|
293
|
+
For web UI sessions only (automatic):
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
Format: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
297
|
+
Scope: Full user access
|
|
298
|
+
Usage: Web UI only (automatic)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Characteristics:**
|
|
302
|
+
- Short-lived (24 hours)
|
|
303
|
+
- Created automatically via OAuth login
|
|
304
|
+
- Auto-refreshed by frontend
|
|
305
|
+
- Not for API/CLI use
|
|
306
|
+
|
|
307
|
+
## Security Best Practices
|
|
308
|
+
|
|
309
|
+
### 1. Use PAT for All Programmatic Access
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
# ✅ Correct - Use PAT
|
|
313
|
+
export ZIBBY_API_KEY=zby_pat_xxxxx
|
|
314
|
+
|
|
315
|
+
# ❌ Wrong - Don't try to extract JWT from browser
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### 2. Create Separate PATs per Use Case
|
|
319
|
+
|
|
320
|
+
In the UI, create multiple tokens:
|
|
321
|
+
- "Production Webhooks" (never expires, heavily monitored)
|
|
322
|
+
- "CI/CD Pipeline" (expires yearly)
|
|
323
|
+
- "Development Testing" (expires monthly)
|
|
324
|
+
- "Partner Integration - Acme Corp" (expires quarterly)
|
|
325
|
+
|
|
326
|
+
### 3. Token Rotation
|
|
327
|
+
|
|
328
|
+
Best practice: Rotate annually or when compromised
|
|
329
|
+
|
|
330
|
+
1. Create new PAT: "CI/CD Pipeline v2"
|
|
331
|
+
2. Update CI/CD secrets
|
|
332
|
+
3. Test with new token
|
|
333
|
+
4. Revoke old PAT after grace period
|
|
334
|
+
|
|
335
|
+
### 4. Monitor Token Usage
|
|
336
|
+
|
|
337
|
+
In UI: Settings > API Tokens
|
|
338
|
+
- View last used timestamp
|
|
339
|
+
- Track execution count
|
|
340
|
+
- Monitor for unusual activity
|
|
341
|
+
|
|
342
|
+
### 5. Webhook Signatures
|
|
343
|
+
|
|
344
|
+
Verify webhook authenticity:
|
|
345
|
+
|
|
346
|
+
```javascript
|
|
347
|
+
const crypto = require('crypto');
|
|
348
|
+
const signature = crypto
|
|
349
|
+
.createHmac('sha256', WEBHOOK_SECRET)
|
|
350
|
+
.update(JSON.stringify(req.body))
|
|
351
|
+
.digest('hex');
|
|
352
|
+
|
|
353
|
+
if (signature !== req.headers['x-zibby-signature']) {
|
|
354
|
+
return res.status(401).send('Invalid signature');
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### 6. Network Restrictions
|
|
359
|
+
|
|
360
|
+
```yaml
|
|
361
|
+
# AWS Security Group
|
|
362
|
+
Ingress:
|
|
363
|
+
- IpProtocol: tcp
|
|
364
|
+
FromPort: 443
|
|
365
|
+
ToPort: 443
|
|
366
|
+
CidrIp: 52.89.214.238/32
|
|
367
|
+
Description: GitHub Actions webhook
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Quota & Billing
|
|
371
|
+
|
|
372
|
+
### Tiers
|
|
373
|
+
|
|
374
|
+
- **Free Tier**: 100 workflow executions/month
|
|
375
|
+
- **Pro Tier**: 1,000 executions/month
|
|
376
|
+
- **Enterprise**: Unlimited
|
|
377
|
+
|
|
378
|
+
### Metering
|
|
379
|
+
|
|
380
|
+
- Each trigger = 1 execution
|
|
381
|
+
- Idempotency: Same key within 24h = no charge
|
|
382
|
+
- CloudWatch logs for audit trail
|
|
383
|
+
|
|
384
|
+
### Quota Exceeded Response
|
|
385
|
+
|
|
386
|
+
```json
|
|
387
|
+
{
|
|
388
|
+
"error": "Quota exceeded",
|
|
389
|
+
"statusCode": 429,
|
|
390
|
+
"limit": 1000,
|
|
391
|
+
"used": 1000,
|
|
392
|
+
"resetDate": "2026-05-01T00:00:00Z"
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Best Practices
|
|
397
|
+
|
|
398
|
+
### 1. Use Idempotency Keys
|
|
399
|
+
|
|
400
|
+
Prevent duplicate executions:
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
zibby trigger custom-flow \
|
|
404
|
+
--idempotency-key "daily-scan-2026-04-24"
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Same key within 24 hours = no additional charge, returns existing job ID.
|
|
408
|
+
|
|
409
|
+
### 2. Input Validation
|
|
410
|
+
|
|
411
|
+
Validate input in your workflow:
|
|
412
|
+
|
|
413
|
+
```javascript
|
|
414
|
+
// In workflow graph.mjs
|
|
415
|
+
buildGraph() {
|
|
416
|
+
const graph = new WorkflowGraph();
|
|
417
|
+
|
|
418
|
+
graph.addNode('validate_input', async (state) => {
|
|
419
|
+
const { ticketKey } = state.input;
|
|
420
|
+
if (!ticketKey) {
|
|
421
|
+
throw new Error('ticketKey required');
|
|
422
|
+
}
|
|
423
|
+
return { valid: true };
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// ...
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### 3. Error Handling & Retries
|
|
431
|
+
|
|
432
|
+
Client-side retry logic:
|
|
433
|
+
|
|
434
|
+
```javascript
|
|
435
|
+
async function triggerWithRetry(workflow, input, maxRetries = 3) {
|
|
436
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
437
|
+
try {
|
|
438
|
+
const response = await fetch(`${API_URL}/workflows/${workflow}/trigger`, {
|
|
439
|
+
method: 'POST',
|
|
440
|
+
headers: { 'Authorization': `Bearer ${API_KEY}` },
|
|
441
|
+
body: JSON.stringify({ input }),
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
if (response.status === 429) {
|
|
445
|
+
await new Promise(r => setTimeout(r, 60000 * (i + 1)));
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return await response.json();
|
|
450
|
+
} catch (err) {
|
|
451
|
+
if (i === maxRetries - 1) throw err;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Monitoring
|
|
458
|
+
|
|
459
|
+
### View Logs
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
# Fetch complete logs from latest execution (one-time)
|
|
463
|
+
zibby logs 562e48d7-ef67-4900-96b7-0d7b51a33405
|
|
464
|
+
|
|
465
|
+
# Stream logs in real-time (like "heroku logs -t")
|
|
466
|
+
zibby logs 562e48d7-ef67-4900-96b7-0d7b51a33405 -t
|
|
467
|
+
|
|
468
|
+
# By workflow name
|
|
469
|
+
zibby logs --workflow custom-flow --project <id> -t
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Log Architecture:**
|
|
473
|
+
|
|
474
|
+
- **Without `-t`**: Fetches from CloudWatch (permanent storage). Shows complete historical logs from any execution, even old ones.
|
|
475
|
+
- **With `-t`**: Streams in real-time via SSE from DynamoDB hot cache (24h TTL). Only works for active/recent executions.
|
|
476
|
+
|
|
477
|
+
```
|
|
478
|
+
CloudWatch Logs (permanent) ──────────> CLI (without -t)
|
|
479
|
+
│
|
|
480
|
+
└──> Kinesis ──> Lambda ──> DynamoDB (24h TTL) ──> SSE ──> CLI (with -t)
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### CloudWatch Dashboards
|
|
484
|
+
|
|
485
|
+
Monitor:
|
|
486
|
+
- Execution count by workflow
|
|
487
|
+
- Success/failure rates
|
|
488
|
+
- P50/P95/P99 latencies
|
|
489
|
+
- Quota utilization
|
|
490
|
+
|
|
491
|
+
### Alerts
|
|
492
|
+
|
|
493
|
+
```yaml
|
|
494
|
+
# EventBridge Rule → SNS → Email/Slack
|
|
495
|
+
Pattern:
|
|
496
|
+
source: [zibby.workflows]
|
|
497
|
+
detail-type: [WorkflowFailed]
|
|
498
|
+
detail:
|
|
499
|
+
workflow: [security-scan]
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
## Common Patterns
|
|
503
|
+
|
|
504
|
+
### Pattern 1: Daily Report Generation
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
# Cron job that triggers workflow by UUID and streams logs
|
|
508
|
+
WORKFLOW_UUID="562e48d7-ef67-4900-96b7-0d7b51a33405"
|
|
509
|
+
|
|
510
|
+
0 9 * * * zibby trigger $WORKFLOW_UUID \
|
|
511
|
+
--input '{"date":"'$(date +%Y-%m-%d)'"}' \
|
|
512
|
+
--idempotency-key "daily-report-$(date +%Y-%m-%d)" \
|
|
513
|
+
&& sleep 5 \
|
|
514
|
+
&& zibby logs $WORKFLOW_UUID | mail -s "Daily Report" team@company.com
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### Pattern 2: Event-Driven Testing
|
|
518
|
+
|
|
519
|
+
```javascript
|
|
520
|
+
// GitHub webhook → test generation → PR comment
|
|
521
|
+
app.post('/webhook/github', async (req, res) => {
|
|
522
|
+
const { pull_request } = req.body;
|
|
523
|
+
|
|
524
|
+
const { jobId } = await triggerWorkflow('test-gen', {
|
|
525
|
+
prNumber: pull_request.number,
|
|
526
|
+
repo: pull_request.base.repo.full_name,
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
await postComment(pull_request.number, `Generating tests... [Job ${jobId}]`);
|
|
530
|
+
res.sendStatus(200);
|
|
531
|
+
});
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Pattern 3: Conditional Execution
|
|
535
|
+
|
|
536
|
+
```javascript
|
|
537
|
+
// Only trigger if conditions are met
|
|
538
|
+
const shouldTrigger = await checkConditions();
|
|
539
|
+
if (shouldTrigger) {
|
|
540
|
+
await fetch('https://api.zibby.app/projects/.../workflows/deploy/trigger', {
|
|
541
|
+
method: 'POST',
|
|
542
|
+
headers: { 'Authorization': `Bearer ${PAT}` },
|
|
543
|
+
body: JSON.stringify({ input: { environment: 'production' } }),
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
## Next Steps
|
|
549
|
+
|
|
550
|
+
- [Custom Workflows](custom-workflows.md) - Build your own workflows
|
|
551
|
+
- [CLI Reference](cli-reference.md) - Full command documentation
|
|
552
|
+
- [Integrations](integrations/github.md) - Connect with GitHub, Jira, etc.
|