@zibby/cli 0.1.5

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/bin/zibby.js ADDED
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Suppress dotenv promotional messages
4
+ process.env.DOTENV_CONFIG_QUIET = 'true';
5
+
6
+ import '@zibby/skills';
7
+ import { Command } from 'commander';
8
+ import { initCommand } from '../src/commands/init.js';
9
+ import { runCommand } from '../src/commands/run.js';
10
+ import { videoCommand } from '../src/commands/video.js';
11
+ import { uploadCommand } from '../src/commands/upload.js';
12
+ import { ciSetupCommand } from '../src/commands/ci-setup.js';
13
+ // implement and analyze are lazy-loaded (they pull in @aws-sdk/client-s3 which isn't needed for local commands)
14
+ import { setupPlaywrightMcpCommand, setupCiCommand, testWithVideoCommand } from '../src/commands/setup-scripts.js';
15
+ import { readFileSync } from 'fs';
16
+ import { fileURLToPath } from 'url';
17
+ import { dirname, join } from 'path';
18
+
19
+ const __filename = fileURLToPath(import.meta.url);
20
+ const __dirname = dirname(__filename);
21
+ const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
22
+
23
+ const program = new Command();
24
+
25
+ program
26
+ .name('zibby')
27
+ .description('Zibby Test Automation - AI-powered test generation')
28
+ .version(packageJson.version);
29
+
30
+ program
31
+ .command('init')
32
+ .description('Initialize a new Zibby test project (like rails new)')
33
+ .argument('[project-name]', 'Project name (optional, uses current directory if not provided)')
34
+ .option('--agent <type>', 'Agent to use (claude, cursor)')
35
+ .option('--skip-install', 'Skip npm install')
36
+ .option('-f, --force', 'Force reinitialize (overwrite existing config)')
37
+ .option('--headed', 'Run MCP browser in headed mode (visible browser)')
38
+ .option('--headless', 'Run MCP browser in headless mode (hidden browser)')
39
+ .option('--api-key <key>', 'Zibby API key for cloud sync')
40
+ .option('--cloud-sync', 'Enable cloud sync and install Zibby MCP')
41
+ .option('-m, --mem', 'Enable test memory (initializes Dolt DB, adds ZIBBY_MEMORY to .env)')
42
+ .action(initCommand);
43
+
44
+ program
45
+ .command('run')
46
+ .description('Run a test specification')
47
+ .argument('[spec-path]', 'Path to test spec file (e.g., test-specs/auth/login.txt)')
48
+ .option('--sources <ids>', 'Comma-separated test case IDs to fetch from cloud')
49
+ .option('--execution <id>', 'Execution ID containing the test cases (required with --sources)')
50
+ .option('--agent <type>', 'Agent to use (claude, cursor) - overrides config')
51
+ .option('--workflow <name>', 'Workflow to use (e.g., QuickSmokeWorkflow, quick-smoke)')
52
+ .option('--headless', 'Run browser in headless mode')
53
+ .option('--node <name>', 'Run only a specific node (e.g., execute_live, generate_script)')
54
+ .option('--session <id>', 'Use existing session (e.g., 1768974629717 or "last") - requires --node')
55
+ .option('--project <id>', 'Project ID (optional, auto-detected from ZIBBY_API_KEY)')
56
+ .option('--collection <id-or-name>', 'Collection ID or name (creates new if name doesn\'t exist)')
57
+ .option('--folder <path>', 'Folder path within collection (optional, requires --collection)')
58
+ .option('--sync', 'Force upload to cloud (overrides cloudSync: false)')
59
+ .option('--no-sync', 'Skip upload to cloud (overrides cloudSync: true)')
60
+ .option('--config <path>', 'Path to config file', '.zibby.config.js')
61
+ .option('--auto-approve', 'Auto-approve MCP tools (for CI/CD)')
62
+ .option('-o, --open', 'Open test results in browser after completion')
63
+ .option('--verbose', 'Show info level logs')
64
+ .option('--debug', 'Show debug level logs (most verbose)')
65
+ .option('-m, --mem', 'Enable test memory (Dolt-backed knowledge from previous runs)')
66
+ .action((specPath, options) => {
67
+ if (options.debug) {
68
+ process.env.ZIBBY_DEBUG = 'true';
69
+ } else if (options.verbose) {
70
+ process.env.ZIBBY_VERBOSE = 'true';
71
+ }
72
+ if (options.mem) {
73
+ process.env.ZIBBY_MEMORY = '1';
74
+ process.env.ZIBBY_EXTRA_SKILLS = process.env.ZIBBY_EXTRA_SKILLS
75
+ ? `${process.env.ZIBBY_EXTRA_SKILLS},memory`
76
+ : 'memory';
77
+ }
78
+ return runCommand(specPath, options);
79
+ });
80
+
81
+ program
82
+ .command('implement')
83
+ .description('Implement a Jira ticket using AI agent (runs in ECS container)')
84
+ .action(async (...args) => {
85
+ const { implementCommand } = await import('../src/commands/implement.js');
86
+ return implementCommand(...args);
87
+ });
88
+
89
+ program
90
+ .command('analyze')
91
+ .description('Analyze a Jira ticket against the codebase (runs in ECS container)')
92
+ .option('--workflow <path>', 'Path to a local workflow JSON file (e.g., .zibby/workflow-analysis.json)')
93
+ .action(async (...args) => {
94
+ const { analyzeCommand } = await import('../src/commands/analyze-graph.js');
95
+ return analyzeCommand(...args);
96
+ });
97
+
98
+ program
99
+ .command('video')
100
+ .description('Organize test videos next to test files')
101
+ .action(videoCommand);
102
+
103
+ program
104
+ .command('upload <spec-path>')
105
+ .description('Upload existing test artifacts to Zibby Cloud')
106
+ .option('--project <id>', 'Project ID (REQUIRED - use flag or ZIBBY_PROJECT_ID env)')
107
+ .option('--collection <id-or-name>', 'Collection ID or name (creates new if name doesn\'t exist)')
108
+ .option('--folder <path>', 'Folder path within collection (optional)')
109
+ .option('--agent <type>', 'Agent used (for metadata)')
110
+ .action(uploadCommand);
111
+
112
+ program
113
+ .command('login')
114
+ .description('Log in to Zibby (opens browser for authentication)')
115
+ .action(async () => {
116
+ const { loginCli } = await import('../src/auth/cli-login.js');
117
+ await loginCli();
118
+ process.exit(0);
119
+ });
120
+
121
+ program
122
+ .command('logout')
123
+ .description('Log out from Zibby (clears saved session)')
124
+ .action(async () => {
125
+ const { logoutCli } = await import('../src/auth/cli-login.js');
126
+ logoutCli();
127
+ process.exit(0);
128
+ });
129
+
130
+ program
131
+ .command('status')
132
+ .description('Show current authentication status and token details')
133
+ .option('--json', 'Output in JSON format (for scripts)')
134
+ .action(async (options) => {
135
+ const { showLoginStatus } = await import('../src/auth/cli-login.js');
136
+ await showLoginStatus(options);
137
+ process.exit(0);
138
+ });
139
+
140
+ program
141
+ .command('list')
142
+ .description('List your projects and API tokens')
143
+ .action(async () => {
144
+ const { listProjectsCommand } = await import('../src/commands/list-projects.js');
145
+ await listProjectsCommand();
146
+ });
147
+
148
+ program
149
+ .command('ci-setup')
150
+ .description('Setup Cursor Agent for CI/CD (patch and configure)')
151
+ .option('--get-keys', 'Get MCP approval keys')
152
+ .option('--save', 'Save approval keys to project')
153
+ .action(ciSetupCommand);
154
+
155
+ program
156
+ .command('setup-playwright')
157
+ .description('Setup official Playwright MCP (from cursor-agent-package)')
158
+ .option('--headed', 'Configure MCP in headed mode (visible browser)')
159
+ .option('--viewport-width <width>', 'Viewport width (default: 1280)', '1280')
160
+ .option('--viewport-height <height>', 'Viewport height (default: 720)', '720')
161
+ .action((options) => {
162
+ const viewport = {
163
+ width: parseInt(options.viewportWidth, 10) || 1280,
164
+ height: parseInt(options.viewportHeight, 10) || 720
165
+ };
166
+ return setupPlaywrightMcpCommand({ ...options, viewport });
167
+ });
168
+
169
+ program
170
+ .command('setup-ci-full')
171
+ .description('Complete CI/CD setup from scratch')
172
+ .action(setupCiCommand);
173
+
174
+ program
175
+ .command('test-video')
176
+ .description('Run Playwright tests with video recording')
177
+ .argument('[test-file]', 'Test file to run (default: tests/)')
178
+ .option('--headed', 'Run in headed mode (visible browser)')
179
+ .action(testWithVideoCommand);
180
+
181
+ // ============================================
182
+ // MEMORY COMMANDS (test knowledge database)
183
+ // ============================================
184
+ const memory = program
185
+ .command('memory')
186
+ .description('Test memory database — version-controlled knowledge from runs');
187
+
188
+ memory
189
+ .command('stats')
190
+ .description('Show memory database statistics')
191
+ .action(async () => {
192
+ const { memoryStatsCommand } = await import('../src/commands/memory.js');
193
+ return memoryStatsCommand();
194
+ });
195
+
196
+ memory
197
+ .command('init')
198
+ .description('Initialize the memory database (Dolt)')
199
+ .action(async () => {
200
+ const { memoryInitCommand } = await import('../src/commands/memory.js');
201
+ return memoryInitCommand();
202
+ });
203
+
204
+ memory
205
+ .command('compact')
206
+ .description('Prune old data and run Dolt GC to reclaim storage')
207
+ .option('--max-runs <n>', 'Keep last N runs per spec (default: 50)', parseInt)
208
+ .option('--max-age <days>', 'Remove data older than N days (default: 90)', parseInt)
209
+ .action(async (options) => {
210
+ const { memoryCompactCommand } = await import('../src/commands/memory.js');
211
+ return memoryCompactCommand(options);
212
+ });
213
+
214
+ memory
215
+ .command('reset')
216
+ .description('Wipe the memory database')
217
+ .option('-f, --force', 'Confirm reset')
218
+ .action(async (options) => {
219
+ const { memoryResetCommand } = await import('../src/commands/memory.js');
220
+ return memoryResetCommand(options);
221
+ });
222
+
223
+ // ============================================
224
+ // WORKFLOW COMMANDS (download / upload / list)
225
+ // ============================================
226
+ const workflow = program
227
+ .command('workflow')
228
+ .description('Manage workflow graphs (download, upload, list)');
229
+
230
+ workflow
231
+ .command('download')
232
+ .description('Download a workflow graph from Zibby Cloud to .zibby/')
233
+ .option('--project <id>', 'Project ID (or ZIBBY_PROJECT_ID env)')
234
+ .option('--type <type>', 'Workflow type: analysis, implementation, run_test')
235
+ .option('--api-key <key>', 'API key (or ZIBBY_API_KEY env)')
236
+ .option('--output <dir>', 'Output directory (default: .zibby/)')
237
+ .option('--include-default', 'Download the built-in default graph if no custom one exists')
238
+ .action(async (options) => {
239
+ const { workflowDownloadCommand } = await import('../src/commands/workflow.js');
240
+ return workflowDownloadCommand(options);
241
+ });
242
+
243
+ workflow
244
+ .command('upload')
245
+ .description('Upload a local workflow graph to Zibby Cloud (validates before upload)')
246
+ .option('--project <id>', 'Project ID (or ZIBBY_PROJECT_ID env)')
247
+ .option('--type <type>', 'Workflow type: analysis, implementation, run_test')
248
+ .option('--api-key <key>', 'API key (or ZIBBY_API_KEY env)')
249
+ .option('--file <path>', 'Path to workflow JSON (default: .zibby/workflow-<type>.json)')
250
+ .action(async (options) => {
251
+ const { workflowUploadCommand } = await import('../src/commands/workflow.js');
252
+ return workflowUploadCommand(options);
253
+ });
254
+
255
+ workflow
256
+ .command('list')
257
+ .description('List all workflows for a project')
258
+ .option('--project <id>', 'Project ID (or ZIBBY_PROJECT_ID env)')
259
+ .option('--api-key <key>', 'API key (or ZIBBY_API_KEY env)')
260
+ .action(async (options) => {
261
+ const { workflowListCommand } = await import('../src/commands/workflow.js');
262
+ return workflowListCommand(options);
263
+ });
264
+
265
+ program.parse();
266
+
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@zibby/cli",
3
+ "version": "0.1.5",
4
+ "description": "Zibby CLI - Test automation generator and runner",
5
+ "type": "module",
6
+ "bin": {
7
+ "zibby": "./bin/zibby.js"
8
+ },
9
+ "scripts": {
10
+ "test": "vitest run test/auth*.test.js test/two-layer-auth.test.js",
11
+ "test:unit": "vitest run src/",
12
+ "test:auth": "vitest run test/auth*.test.js test/two-layer-auth.test.js",
13
+ "lint": "eslint .",
14
+ "lint:fix": "eslint --fix ."
15
+ },
16
+ "keywords": [
17
+ "testing",
18
+ "automation",
19
+ "e2e",
20
+ "playwright",
21
+ "ai"
22
+ ],
23
+ "author": "Zibby",
24
+ "license": "MIT",
25
+ "homepage": "https://zibby.app",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/ZibbyHQ/zibby-agent"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/ZibbyHQ/zibby-agent/issues"
32
+ },
33
+ "dependencies": {
34
+ "@aws-sdk/client-sqs": "^3.1000.0",
35
+ "@zibby/skills": "*",
36
+ "@zibby/core": "^0.1.1",
37
+ "chalk": "^5.3.0",
38
+ "commander": "^12.0.0",
39
+ "dotenv": "^17.2.3",
40
+ "glob": "^10.3.10",
41
+ "handlebars": "^4.7.8",
42
+ "inquirer": "^13.3.0",
43
+ "node-fetch": "^3.3.2",
44
+ "open": "^10.2.0",
45
+ "ora": "^8.0.1"
46
+ },
47
+ "files": [
48
+ "bin/",
49
+ "src/",
50
+ "!src/**/__tests__/",
51
+ "!src/**/*.test.js",
52
+ "!src/**/*.spec.js",
53
+ "README.md",
54
+ "LICENSE"
55
+ ],
56
+ "engines": {
57
+ "node": ">=18.0.0"
58
+ },
59
+ "optionalDependencies": {
60
+ "@zibby/memory": "*"
61
+ },
62
+ "devDependencies": {
63
+ "vitest": "^4.0.18"
64
+ }
65
+ }