@zibby/workflow-templates 0.1.0

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.
Files changed (46) hide show
  1. package/README.md +59 -0
  2. package/browser-test-automation/README.md +136 -0
  3. package/browser-test-automation/chat.mjs +36 -0
  4. package/browser-test-automation/graph.mjs +80 -0
  5. package/browser-test-automation/icon.png +0 -0
  6. package/browser-test-automation/nodes/cache-replay.mjs +213 -0
  7. package/browser-test-automation/nodes/execute-live.mjs +254 -0
  8. package/browser-test-automation/nodes/generate-script.mjs +108 -0
  9. package/browser-test-automation/nodes/index.mjs +4 -0
  10. package/browser-test-automation/nodes/preflight.mjs +94 -0
  11. package/browser-test-automation/nodes/utils.mjs +297 -0
  12. package/browser-test-automation/package.json +12 -0
  13. package/browser-test-automation/pipeline-ids.js +12 -0
  14. package/browser-test-automation/result-handler.mjs +327 -0
  15. package/browser-test-automation/run-index.mjs +420 -0
  16. package/browser-test-automation/run_test.json +358 -0
  17. package/browser-test-automation/state.js +61 -0
  18. package/code-analysis/README.md +60 -0
  19. package/code-analysis/graph.js +72 -0
  20. package/code-analysis/graph.mjs +33 -0
  21. package/code-analysis/icon.png +0 -0
  22. package/code-analysis/index.js +18 -0
  23. package/code-analysis/nodes/analyze-ticket-node.js +204 -0
  24. package/code-analysis/nodes/create-pr-node.js +175 -0
  25. package/code-analysis/nodes/finalize-node.js +118 -0
  26. package/code-analysis/nodes/generate-code-node.js +425 -0
  27. package/code-analysis/nodes/generate-test-cases-node.js +376 -0
  28. package/code-analysis/nodes/services/prMetaService.js +86 -0
  29. package/code-analysis/nodes/setup-node.js +142 -0
  30. package/code-analysis/package.json +14 -0
  31. package/code-analysis/prompts/analyze-ticket.md +181 -0
  32. package/code-analysis/prompts/generate-code.md +33 -0
  33. package/code-analysis/prompts/generate-test-cases.md +110 -0
  34. package/code-analysis/state.js +48 -0
  35. package/generate-test-cases/README.md +72 -0
  36. package/generate-test-cases/graph.mjs +46 -0
  37. package/generate-test-cases/icon.png +0 -0
  38. package/generate-test-cases/nodes/generate-test-cases-node.js +381 -0
  39. package/generate-test-cases/nodes/setup-node.js +142 -0
  40. package/generate-test-cases/package.json +12 -0
  41. package/generate-test-cases/state.js +54 -0
  42. package/global-setup.js +56 -0
  43. package/index.js +240 -0
  44. package/package.json +75 -0
  45. package/register-nodes.js +24 -0
  46. package/run-index-post-cli.js +32 -0
package/index.js ADDED
@@ -0,0 +1,240 @@
1
+ import { join, dirname } from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { existsSync } from 'fs';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+
8
+ export const TEMPLATES = {
9
+ 'browser-test-automation': {
10
+ name: 'browser-test-automation',
11
+ displayName: 'Browser Test Automation (Full Workflow)',
12
+ description: 'Complete browser test automation workflow with title generation, live execution, and script generation',
13
+ path: join(__dirname, 'browser-test-automation'),
14
+ default: true,
15
+ // Suggested slug for `zibby workflow new <slug> -t <name>`. Used in
16
+ // the `template list` scaffold hint so the printed command is
17
+ // copy-paste-ready instead of `your-workflow-name`. Users can still
18
+ // pick anything they want at scaffold time.
19
+ defaultSlug: 'browser-tests',
20
+ // Runtime deps the scaffolded copy needs in addition to @zibby/core.
21
+ // graph.mjs now imports state.js which `import { z } from 'zod'`s
22
+ // directly, so the user's package.json must declare zod or the
23
+ // scaffolded workflow fails on first import.
24
+ deps: {
25
+ zod: '^3.23.0',
26
+ },
27
+ features: [
28
+ 'Preflight analysis: extract title + assertion checklist from spec',
29
+ 'Execute test live with AI + browser (Claude or Cursor)',
30
+ 'Generate Playwright script with stable IDs',
31
+ 'Real-time streaming output',
32
+ 'Video recording of browser sessions'
33
+ ],
34
+ // ── Marketplace metadata ──────────────────────────────────────────
35
+ // Consumed by `backend/scripts/marketplace-sync-from-templates.mjs`.
36
+ // Templates without a `marketplace` field are excluded from sync —
37
+ // they're still scaffoldable via `zibby workflow new` but won't
38
+ // appear in the public catalog.
39
+ marketplace: {
40
+ slug: 'browser-test-automation',
41
+ tagline: 'Drive end-to-end browser tests authored as agent workflows.',
42
+ // Bespoke per-icon prompt. Each official template ships its own
43
+ // visual identity — different style, palette, motif, vibe —
44
+ // mirroring how the OpenAI GPT marketplace looks (Scholar GPT vs
45
+ // Canva vs Mia AI are all stylistically distinct). The icon
46
+ // generator uses `iconPrompt` verbatim when set.
47
+ iconPrompt: [
48
+ 'A bold, energetic app icon for "Browser Test Automation" — a workflow that runs end-to-end browser tests like a sprinter.',
49
+ '',
50
+ 'Visual style: cartoon mascot with personality, in the style of Duolingo\'s owl or Reddit\'s Snoo or Discord\'s Wumpus.',
51
+ 'Subject: a friendly anthropomorphic cursor-arrow CHARACTER (white arrow shape with a tiny smiling face on its tail), captured mid-stride running to the right, with a small green checkmark trailing behind it like a comic-book speed line.',
52
+ 'Background: a vibrant sunset gradient from coral-pink to amber-orange (#FF6B6B → #FFA94D), filling a softly-rounded square (1024×1024).',
53
+ 'Composition: character centered, slight forward lean, dynamic motion lines. Mood: cheerful, playful, fast.',
54
+ 'NO text, NO browser UI screenshots, NO outline wireframes.',
55
+ ].join('\n'),
56
+ category: 'Testing',
57
+ tags: ['testing', 'playwright', 'e2e', 'browser'],
58
+ capabilities: [
59
+ 'Preflight LLM extracts assertions from a plain-English spec',
60
+ 'Live Playwright execution with screenshots + DOM at every step',
61
+ 'Cache-replay short-circuits expensive LLM runs on repeat flows',
62
+ 'Emits a deterministic Playwright script with stable selectors',
63
+ ],
64
+ conversationStarters: [
65
+ 'Run the checkout smoke test against staging',
66
+ 'Test that signup → first-project works on prod',
67
+ 'Generate a Playwright script from this spec',
68
+ 'Replay yesterday\'s login test against the new build',
69
+ ],
70
+ // icon: optional — './icon.png' relative to template path,
71
+ // OR an external 'https://' URL. Omitted = fallback initials in UI.
72
+ },
73
+ },
74
+ 'code-analysis': {
75
+ name: 'code-analysis',
76
+ displayName: 'Code Analysis (Ticket → Code + Tests)',
77
+ description: 'Multi-node workflow that analyzes a Jira ticket against a code repo, generates code changes, and emits test cases',
78
+ path: join(__dirname, 'code-analysis'),
79
+ defaultSlug: 'ticket-analyzer',
80
+ // Runtime deps the scaffolded copy needs in addition to @zibby/core.
81
+ // Merged into the generated package.json so `npm install` works
82
+ // without manual edits. Browser-test doesn't declare any because
83
+ // its nodes only depend on @zibby/core.
84
+ deps: {
85
+ axios: '^1.6.0',
86
+ handlebars: '^4.7.8',
87
+ zod: '^3.23.0',
88
+ },
89
+ features: [
90
+ 'Clone repos + snapshot git baseline',
91
+ 'LLM analysis of ticket against codebase (canProceed gate)',
92
+ 'Conditional routing: skip code-gen if ticket is invalid',
93
+ 'Generate scoped code changes',
94
+ 'Generate test cases covering the changes',
95
+ 'Customizable prompts in prompts/*.md'
96
+ ],
97
+ marketplace: {
98
+ slug: 'code-analysis',
99
+ tagline: 'Take a Jira ticket end-to-end: analyze, code, and emit test cases.',
100
+ iconPrompt: [
101
+ 'A premium, hi-fi app icon for "Code Analysis" — a workflow that takes a Jira ticket end-to-end into shipping code.',
102
+ '',
103
+ 'Visual style: 3D-rendered hero object floating in space, in the style of Apple Vision Pro icons, Linear\'s changelog hero illustrations, or a Stripe product render. Glossy, dimensional, with subtle reflections and a soft rim-light.',
104
+ 'Subject: a 3D-rendered angle-bracket pair `</>` made of glossy chrome / brushed silver metal, slightly rotated in three-quarter perspective, with one bracket tilted forward and the other back so they read as a balanced "code" symbol with depth.',
105
+ 'Background: a deep midnight-navy gradient (#0F172A at the top, #1E1B4B at the bottom), with a single soft violet glow behind the brackets and a few faint star-like specks scattered across the canvas. Square format, 1024×1024.',
106
+ 'Composition: brackets centered, subtle drop shadow on the canvas. Mood: high-end, technical, confident — like the cover of a developer tool launch.',
107
+ 'NO text, NO outline wireframes, NO flat sticker style — this one is DEEP and 3D-rendered.',
108
+ ].join('\n'),
109
+ category: 'Engineering',
110
+ tags: ['code-analysis', 'jira', 'github', 'test-generation'],
111
+ capabilities: [
112
+ 'Clone repos + snapshot git baseline so changes are diff-able',
113
+ 'LLM gate: skip code-gen when ticket can\'t be implemented as-is',
114
+ 'Generates scoped patches plus test cases for the same change',
115
+ 'Prompts live in prompts/*.md — overrideable per team',
116
+ ],
117
+ conversationStarters: [
118
+ 'Analyze PROJ-1234 against the backend repo',
119
+ 'Generate code + tests for the ticket I just linked',
120
+ 'Decide if SRE-882 is implementable before I assign it',
121
+ 'Show me what tests would cover the changes for this ticket',
122
+ ],
123
+ },
124
+ },
125
+ 'generate-test-cases': {
126
+ name: 'generate-test-cases',
127
+ displayName: 'Generate Test Cases (Diff → Test Specs)',
128
+ description: 'Standalone slice — takes an existing code diff and generates plain-English test specifications for it. Skips ticket-analysis and code-gen.',
129
+ path: join(__dirname, 'generate-test-cases'),
130
+ defaultSlug: 'tests-from-diff',
131
+ deps: {
132
+ zod: '^3.23.0',
133
+ },
134
+ features: [
135
+ 'Two-node graph: setup → generate_test_cases',
136
+ 'Takes a PR diff directly as state input (no upstream code-gen needed)',
137
+ 'LLM explores codebase routing/components for accurate test steps',
138
+ 'Emits 4-8 prioritized test specs (Critical/High/Medium/Low)',
139
+ 'Plain-English test steps — runnable by AI agents'
140
+ ],
141
+ marketplace: {
142
+ slug: 'generate-test-cases',
143
+ tagline: 'Hand it a PR diff; get back prioritized, AI-runnable test specs.',
144
+ iconPrompt: [
145
+ 'A hand-illustrated, slightly whimsical app icon for "Generate Test Cases" — a workflow that turns a code diff into prioritized test specs.',
146
+ '',
147
+ 'Visual style: hand-painted, slightly textured illustration with visible brush strokes, in the spirit of a Notion template cover, Mailchimp\'s mascot illustrations, or Studio Ghibli\'s soft warmth. Avoid sterile vector look.',
148
+ 'Subject: a cozy laboratory scene — a smiling, friendly cartoon beaker character (with simple dot eyes and a tiny smile) sitting on a small stack of paper test-spec cards. Around the beaker, a tiny floating clipboard with three checkmarks gently drifts. The whole composition feels like a single mascot illustration.',
149
+ 'Background: warm cream paper texture (#F5E8D3) with a few faint pencil-sketch dots, contained inside a softly-rounded square (1024×1024). NOT a flat saturated disc — this one is a painted illustration.',
150
+ 'Mood: friendly, approachable, slightly handmade. Like a children\'s book illustration applied to a developer tool.',
151
+ 'NO text, NO photo-realism, NO sleek 3D render — this one is hand-drawn and warm.',
152
+ ].join('\n'),
153
+ category: 'Testing',
154
+ tags: ['testing', 'test-generation', 'pull-request', 'review'],
155
+ capabilities: [
156
+ 'Skips ticket analysis — feed it the diff directly',
157
+ 'LLM explores the codebase to ground test steps in real components',
158
+ 'Emits 4-8 specs labelled Critical / High / Medium / Low',
159
+ 'Specs are plain English — runnable by any browser-driving agent',
160
+ ],
161
+ conversationStarters: [
162
+ 'Generate test cases for this PR diff',
163
+ 'What are the must-cover scenarios for the patch I just pasted?',
164
+ 'Prioritise tests for the auth-refactor branch',
165
+ 'Produce specs that an AI agent can execute end-to-end',
166
+ ],
167
+ },
168
+ }
169
+ };
170
+
171
+ export class TemplateFactory {
172
+ static listTemplates() {
173
+ return Object.values(TEMPLATES);
174
+ }
175
+
176
+ static getDefault() {
177
+ return Object.values(TEMPLATES).find(t => t.default) || TEMPLATES['browser-test-automation'];
178
+ }
179
+
180
+ static getTemplate(name) {
181
+ const template = TEMPLATES[name];
182
+ if (!template) {
183
+ const available = Object.keys(TEMPLATES).join(', ');
184
+ throw new Error(`Template "${name}" not found. Available: ${available}`);
185
+ }
186
+ return template;
187
+ }
188
+
189
+ static validateTemplate(templatePath) {
190
+ const requiredFiles = ['graph.mjs', 'nodes', 'README.md'];
191
+
192
+ for (const file of requiredFiles) {
193
+ const filePath = join(templatePath, file);
194
+ if (!existsSync(filePath)) {
195
+ throw new Error(`Template missing required file: ${file}`);
196
+ }
197
+ }
198
+
199
+ return true;
200
+ }
201
+
202
+ static getTemplateFiles(templateName) {
203
+ const template = this.getTemplate(templateName);
204
+ this.validateTemplate(template.path);
205
+
206
+ const resultHandlerPath = join(template.path, 'result-handler.mjs');
207
+ return {
208
+ graphPath: join(template.path, 'graph.mjs'),
209
+ nodesPath: join(template.path, 'nodes'),
210
+ readmePath: join(template.path, 'README.md'),
211
+ resultHandlerPath: existsSync(resultHandlerPath) ? resultHandlerPath : null,
212
+ template
213
+ };
214
+ }
215
+
216
+ static registerCustomTemplate(name, config) {
217
+ if (TEMPLATES[name]) {
218
+ throw new Error(`Template "${name}" already exists`);
219
+ }
220
+
221
+ if (!config.path || !config.displayName) {
222
+ throw new Error('Custom template must have "path" and "displayName"');
223
+ }
224
+
225
+ this.validateTemplate(config.path);
226
+
227
+ TEMPLATES[name] = {
228
+ name,
229
+ displayName: config.displayName,
230
+ description: config.description || '',
231
+ path: config.path,
232
+ features: config.features || [],
233
+ custom: true
234
+ };
235
+
236
+ return TEMPLATES[name];
237
+ }
238
+ }
239
+
240
+ export default TemplateFactory;
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@zibby/workflow-templates",
3
+ "version": "0.1.0",
4
+ "description": "Built-in workflow templates for Zibby — browser-test-automation, code-analysis, generate-test-cases. Carved out of @zibby/core@0.4.6 so the engine ships without scaffolding payload.",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "exports": {
8
+ ".": "./index.js",
9
+ "./register-nodes.js": "./register-nodes.js",
10
+ "./global-setup.js": "./global-setup.js",
11
+ "./run-index-post-cli.js": "./run-index-post-cli.js",
12
+ "./browser-test-automation": "./browser-test-automation/graph.mjs",
13
+ "./browser-test-automation/*": "./browser-test-automation/*",
14
+ "./code-analysis": "./code-analysis/graph.js",
15
+ "./code-analysis/*": "./code-analysis/*",
16
+ "./generate-test-cases": "./generate-test-cases/graph.mjs",
17
+ "./generate-test-cases/*": "./generate-test-cases/*",
18
+ "./package.json": "./package.json"
19
+ },
20
+ "scripts": {
21
+ "lint": "eslint .",
22
+ "lint:fix": "eslint --fix ."
23
+ },
24
+ "keywords": [
25
+ "zibby",
26
+ "workflow",
27
+ "templates",
28
+ "agent",
29
+ "automation"
30
+ ],
31
+ "author": "Zibby",
32
+ "license": "MIT",
33
+ "homepage": "https://zibby.dev",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/ZibbyHQ/workflow-templates"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/ZibbyHQ/workflow-templates/issues"
40
+ },
41
+ "files": [
42
+ "browser-test-automation/",
43
+ "code-analysis/",
44
+ "generate-test-cases/",
45
+ "index.js",
46
+ "register-nodes.js",
47
+ "global-setup.js",
48
+ "run-index-post-cli.js",
49
+ "!**/__tests__/",
50
+ "!**/*.test.js",
51
+ "!**/*.spec.js",
52
+ "README.md",
53
+ "LICENSE"
54
+ ],
55
+ "engines": {
56
+ "node": ">=18.0.0"
57
+ },
58
+ "dependencies": {
59
+ "@anthropic-ai/sdk": "^0.88.0",
60
+ "@zibby/agent-workflow": "^0.3.0",
61
+ "axios": "^1.15.0",
62
+ "handlebars": "^4.7.9",
63
+ "zod": "^3.23.0 || ^4.0.0"
64
+ },
65
+ "peerDependencies": {
66
+ "@playwright/test": ">=1.49.0",
67
+ "@zibby/core": ">=0.5.0",
68
+ "playwright": ">=1.49.0"
69
+ },
70
+ "devDependencies": {
71
+ "@eslint/js": "^10.0.1",
72
+ "eslint": "^10.0.2",
73
+ "globals": "^17.4.0"
74
+ }
75
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Template node registrations
3
+ *
4
+ * Import this module as a side-effect to register all built-in
5
+ * template nodes with the framework's node registry.
6
+ *
7
+ * Usage: import '@zibby/workflow-templates/register-nodes.js';
8
+ */
9
+
10
+ import { registerNode } from '@zibby/agent-workflow';
11
+ import { setupNode } from './code-analysis/nodes/setup-node.js';
12
+ import { analyzeTicketNode } from './code-analysis/nodes/analyze-ticket-node.js';
13
+ import { generateCodeNode, implementCodeNode } from './code-analysis/nodes/generate-code-node.js';
14
+ import { generateTestCasesNode } from './code-analysis/nodes/generate-test-cases-node.js';
15
+ import { finalizeNode } from './code-analysis/nodes/finalize-node.js';
16
+ import { createPRNode } from './code-analysis/nodes/create-pr-node.js';
17
+
18
+ registerNode('setup', setupNode);
19
+ registerNode('analyze_ticket', analyzeTicketNode);
20
+ registerNode('generate_code', generateCodeNode);
21
+ registerNode('generate_test_cases', generateTestCasesNode);
22
+ registerNode('finalize', finalizeNode);
23
+ registerNode('implement_code', implementCodeNode);
24
+ registerNode('create_pr', createPRNode);
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Post-CLI run-index hooks for the default `browser-test-automation` template.
3
+ *
4
+ * Historically this lived in `@zibby/core/src/utils/run-index-post-cli.js`
5
+ * as a "keep templates out of the engine" bridge. After the
6
+ * @zibby/core@0.5.0 carve-out, templates own this hook directly — the CLI
7
+ * imports from `@zibby/workflow-templates/run-index-post-cli.js`.
8
+ *
9
+ * - `postCliRunIndex` / `postCliInterruptedRunIndex` — JSONL +
10
+ * `zibby-run-state.json` (template implements the shapes)
11
+ * - `createCliRunIndexPipelineProgressAppender` — optional `runTest`
12
+ * pipeline hook
13
+ */
14
+ import {
15
+ tryAppendBrowserTestRunIndex,
16
+ createBrowserTestPipelineProgressAppender,
17
+ tryAppendBrowserTestInterruptedRunIndex,
18
+ } from './browser-test-automation/run-index.mjs';
19
+
20
+ export function postCliRunIndex(payload) {
21
+ tryAppendBrowserTestRunIndex(payload);
22
+ }
23
+
24
+ /** SIGINT/SIGTERM — flush terminal index rows + session-state (template implements both). */
25
+ export function postCliInterruptedRunIndex(payload) {
26
+ tryAppendBrowserTestInterruptedRunIndex(payload);
27
+ }
28
+
29
+ /** For `runTest` → `graph.run` optional `onPipelineProgress` (default browser-test template). */
30
+ export function createCliRunIndexPipelineProgressAppender(opts) {
31
+ return createBrowserTestPipelineProgressAppender(opts);
32
+ }