@openqa/cli 1.0.3 → 1.0.4

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.
@@ -1,62 +1,34 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
- "use strict";
4
- var __create = Object.create;
5
- var __defProp = Object.defineProperty;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getProtoOf = Object.getPrototypeOf;
9
- var __hasOwnProp = Object.prototype.hasOwnProperty;
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
- // If the importer is in node compatibility mode or this is not an ESM
20
- // file that has been converted to a CommonJS file using a Babel-
21
- // compatible transform (i.e. "__esModule" has not been set), then set
22
- // "default" to the CommonJS "module.exports" for node compatibility.
23
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
- mod
25
- ));
26
-
27
- // node_modules/tsup/assets/cjs_shims.js
28
- var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
29
- var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
30
2
 
31
3
  // cli/index.ts
32
- var import_commander = require("commander");
4
+ import { Command } from "commander";
33
5
 
34
6
  // agent/index.ts
35
- var import_agent2 = require("@orka-js/agent");
36
- var import_openai2 = require("@orka-js/openai");
37
- var import_anthropic2 = require("@orka-js/anthropic");
38
- var import_memory_store = require("@orka-js/memory-store");
39
- var import_observability = require("@orka-js/observability");
40
- var import_events3 = require("events");
7
+ import { ReActAgent as ReActAgent2 } from "@orka-js/agent";
8
+ import { OpenAIAdapter as OpenAIAdapter2 } from "@orka-js/openai";
9
+ import { AnthropicAdapter as AnthropicAdapter2 } from "@orka-js/anthropic";
10
+ import { SessionMemory } from "@orka-js/memory-store";
11
+ import { Tracer } from "@orka-js/observability";
12
+ import { EventEmitter as EventEmitter3 } from "events";
41
13
 
42
14
  // database/index.ts
43
- var import_better_sqlite3 = __toESM(require("better-sqlite3"), 1);
44
- var import_fs = require("fs");
45
- var import_path = require("path");
46
- var import_url = require("url");
47
- var import_fs2 = require("fs");
48
- var __filename2 = (0, import_url.fileURLToPath)(importMetaUrl);
49
- var __dirname = (0, import_path.dirname)(__filename2);
15
+ import Database from "better-sqlite3";
16
+ import { readFileSync } from "fs";
17
+ import { join, dirname } from "path";
18
+ import { fileURLToPath } from "url";
19
+ import { mkdirSync } from "fs";
20
+ var __filename = fileURLToPath(import.meta.url);
21
+ var __dirname = dirname(__filename);
50
22
  var OpenQADatabase = class {
51
23
  db;
52
24
  constructor(dbPath = "./data/openqa.db") {
53
- const dir = (0, import_path.dirname)(dbPath);
54
- (0, import_fs2.mkdirSync)(dir, { recursive: true });
55
- this.db = new import_better_sqlite3.default(dbPath);
25
+ const dir = dirname(dbPath);
26
+ mkdirSync(dir, { recursive: true });
27
+ this.db = new Database(dbPath);
56
28
  this.initialize();
57
29
  }
58
30
  initialize() {
59
- const schema = (0, import_fs.readFileSync)((0, import_path.join)(__dirname, "schema.sql"), "utf-8");
31
+ const schema = readFileSync(join(__dirname, "schema.sql"), "utf-8");
60
32
  this.db.exec(schema);
61
33
  }
62
34
  getConfig(key) {
@@ -161,8 +133,8 @@ var OpenQADatabase = class {
161
133
  };
162
134
 
163
135
  // agent/config/index.ts
164
- var import_dotenv = require("dotenv");
165
- (0, import_dotenv.config)();
136
+ import { config as dotenvConfig } from "dotenv";
137
+ dotenvConfig();
166
138
  var ConfigManager = class {
167
139
  db;
168
140
  envConfig;
@@ -240,9 +212,9 @@ var ConfigManager = class {
240
212
  };
241
213
 
242
214
  // agent/tools/browser.ts
243
- var import_playwright = require("playwright");
244
- var import_fs3 = require("fs");
245
- var import_path2 = require("path");
215
+ import { chromium } from "playwright";
216
+ import { mkdirSync as mkdirSync2 } from "fs";
217
+ import { join as join2 } from "path";
246
218
  var BrowserTools = class {
247
219
  browser = null;
248
220
  page = null;
@@ -252,10 +224,10 @@ var BrowserTools = class {
252
224
  constructor(db, sessionId) {
253
225
  this.db = db;
254
226
  this.sessionId = sessionId;
255
- (0, import_fs3.mkdirSync)(this.screenshotDir, { recursive: true });
227
+ mkdirSync2(this.screenshotDir, { recursive: true });
256
228
  }
257
229
  async initialize() {
258
- this.browser = await import_playwright.chromium.launch({ headless: true });
230
+ this.browser = await chromium.launch({ headless: true });
259
231
  const context = await this.browser.newContext({
260
232
  viewport: { width: 1920, height: 1080 },
261
233
  userAgent: "OpenQA/1.0 (Automated Testing Agent)"
@@ -359,7 +331,7 @@ var BrowserTools = class {
359
331
  if (!this.page) return "Browser not initialized. Navigate to a page first.";
360
332
  try {
361
333
  const filename = `${Date.now()}_${name}.png`;
362
- const path = (0, import_path2.join)(this.screenshotDir, filename);
334
+ const path = join2(this.screenshotDir, filename);
363
335
  await this.page.screenshot({ path, fullPage: true });
364
336
  this.db.createAction({
365
337
  session_id: this.sessionId,
@@ -425,7 +397,7 @@ ${errors.join("\n")}`;
425
397
  };
426
398
 
427
399
  // agent/tools/github.ts
428
- var import_rest = require("@octokit/rest");
400
+ import { Octokit } from "@octokit/rest";
429
401
  var GitHubTools = class {
430
402
  octokit = null;
431
403
  db;
@@ -436,7 +408,7 @@ var GitHubTools = class {
436
408
  this.sessionId = sessionId;
437
409
  this.config = config;
438
410
  if (config.token) {
439
- this.octokit = new import_rest.Octokit({ auth: config.token });
411
+ this.octokit = new Octokit({ auth: config.token });
440
412
  }
441
413
  }
442
414
  getTools() {
@@ -621,9 +593,9 @@ Total: ${tickets.length} tickets
621
593
  };
622
594
 
623
595
  // agent/webhooks/git-listener.ts
624
- var import_events = require("events");
625
- var import_rest2 = require("@octokit/rest");
626
- var GitListener = class extends import_events.EventEmitter {
596
+ import { EventEmitter } from "events";
597
+ import { Octokit as Octokit2 } from "@octokit/rest";
598
+ var GitListener = class extends EventEmitter {
627
599
  config;
628
600
  octokit = null;
629
601
  lastCommitSha = null;
@@ -639,7 +611,7 @@ var GitListener = class extends import_events.EventEmitter {
639
611
  ...config
640
612
  };
641
613
  if (config.provider === "github" && config.token) {
642
- this.octokit = new import_rest2.Octokit({ auth: config.token });
614
+ this.octokit = new Octokit2({ auth: config.token });
643
615
  }
644
616
  }
645
617
  async start() {
@@ -908,10 +880,10 @@ var GitListener = class extends import_events.EventEmitter {
908
880
  };
909
881
 
910
882
  // agent/specialists/index.ts
911
- var import_agent = require("@orka-js/agent");
912
- var import_openai = require("@orka-js/openai");
913
- var import_anthropic = require("@orka-js/anthropic");
914
- var import_events2 = require("events");
883
+ import { ReActAgent } from "@orka-js/agent";
884
+ import { OpenAIAdapter } from "@orka-js/openai";
885
+ import { AnthropicAdapter } from "@orka-js/anthropic";
886
+ import { EventEmitter as EventEmitter2 } from "events";
915
887
  var SPECIALIST_PROMPTS = {
916
888
  "form-tester": `You are a Form Testing Specialist. Your mission:
917
889
  - Find all forms on the page (login, signup, contact, search, etc.)
@@ -1000,7 +972,7 @@ var SPECIALIST_PROMPTS = {
1000
972
  - Test pagination and infinite scroll
1001
973
  - Report navigation issues with affected URLs`
1002
974
  };
1003
- var SpecialistAgentManager = class extends import_events2.EventEmitter {
975
+ var SpecialistAgentManager = class extends EventEmitter2 {
1004
976
  agents = /* @__PURE__ */ new Map();
1005
977
  agentStatuses = /* @__PURE__ */ new Map();
1006
978
  db;
@@ -1016,12 +988,12 @@ var SpecialistAgentManager = class extends import_events2.EventEmitter {
1016
988
  }
1017
989
  createLLMAdapter() {
1018
990
  if (this.llmConfig.provider === "anthropic") {
1019
- return new import_anthropic.AnthropicAdapter({
991
+ return new AnthropicAdapter({
1020
992
  apiKey: this.llmConfig.apiKey,
1021
993
  model: this.llmConfig.model || "claude-3-5-sonnet-20241022"
1022
994
  });
1023
995
  }
1024
- return new import_openai.OpenAIAdapter({
996
+ return new OpenAIAdapter({
1025
997
  apiKey: this.llmConfig.apiKey,
1026
998
  model: this.llmConfig.model || "gpt-4"
1027
999
  });
@@ -1029,7 +1001,7 @@ var SpecialistAgentManager = class extends import_events2.EventEmitter {
1029
1001
  createSpecialist(type, customPrompt) {
1030
1002
  const agentId = `${type}_${Date.now()}`;
1031
1003
  const systemPrompt = customPrompt || SPECIALIST_PROMPTS[type];
1032
- const agent = new import_agent.ReActAgent({
1004
+ const agent = new ReActAgent({
1033
1005
  llm: this.createLLMAdapter(),
1034
1006
  tools: this.browserTools.getTools(),
1035
1007
  maxIterations: 15,
@@ -1338,7 +1310,7 @@ Remember to report findings from each skill separately.
1338
1310
  };
1339
1311
 
1340
1312
  // agent/index.ts
1341
- var OpenQAAgent = class extends import_events3.EventEmitter {
1313
+ var OpenQAAgent = class extends EventEmitter3 {
1342
1314
  agent = null;
1343
1315
  db;
1344
1316
  config;
@@ -1360,13 +1332,13 @@ var OpenQAAgent = class extends import_events3.EventEmitter {
1360
1332
  const cfg = this.config.getConfig();
1361
1333
  switch (cfg.llm.provider) {
1362
1334
  case "anthropic":
1363
- return new import_anthropic2.AnthropicAdapter({
1335
+ return new AnthropicAdapter2({
1364
1336
  apiKey: cfg.llm.apiKey || process.env.ANTHROPIC_API_KEY,
1365
1337
  model: cfg.llm.model || "claude-3-5-sonnet-20241022"
1366
1338
  });
1367
1339
  case "openai":
1368
1340
  default:
1369
- return new import_openai2.OpenAIAdapter({
1341
+ return new OpenAIAdapter2({
1370
1342
  apiKey: cfg.llm.apiKey || process.env.OPENAI_API_KEY,
1371
1343
  model: cfg.llm.model || "gpt-4"
1372
1344
  });
@@ -1390,8 +1362,8 @@ var OpenQAAgent = class extends import_events3.EventEmitter {
1390
1362
  ...kanbanTools.getTools()
1391
1363
  ];
1392
1364
  const llm = this.createLLMAdapter();
1393
- const memory = new import_memory_store.SessionMemory({ maxMessages: 50 });
1394
- const tracer = new import_observability.Tracer({ logLevel: "info" });
1365
+ const memory = new SessionMemory({ maxMessages: 50 });
1366
+ const tracer = new Tracer({ logLevel: "info" });
1395
1367
  const enabledSkills = this.skillManager.getEnabledSkills();
1396
1368
  const skillPrompt = this.skillManager.generateSkillPrompt(enabledSkills);
1397
1369
  const agentConfig = {
@@ -1430,7 +1402,7 @@ ${skillPrompt}
1430
1402
 
1431
1403
  Always provide clear, actionable information with steps to reproduce. Think step by step like a human QA expert.`
1432
1404
  };
1433
- this.agent = new import_agent2.ReActAgent(agentConfig, llm, memory);
1405
+ this.agent = new ReActAgent2(agentConfig, llm, memory);
1434
1406
  this.specialistManager = new SpecialistAgentManager(
1435
1407
  this.db,
1436
1408
  this.sessionId,
@@ -1610,84 +1582,84 @@ Always provide clear, actionable information with steps to reproduce. Think step
1610
1582
  };
1611
1583
 
1612
1584
  // cli/index.ts
1613
- var import_child_process = require("child_process");
1614
- var import_fs4 = require("fs");
1615
- var import_path3 = require("path");
1616
- var import_chalk = __toESM(require("chalk"), 1);
1617
- var import_ora = __toESM(require("ora"), 1);
1618
- var program = new import_commander.Command();
1585
+ import { spawn } from "child_process";
1586
+ import { writeFileSync, readFileSync as readFileSync2, existsSync, unlinkSync } from "fs";
1587
+ import { join as join3 } from "path";
1588
+ import chalk from "chalk";
1589
+ import ora from "ora";
1590
+ var program = new Command();
1619
1591
  var PID_FILE = "./data/openqa.pid";
1620
1592
  program.name("openqa").description("OpenQA - Autonomous QA Testing Agent powered by Orka.js").version("1.0.0");
1621
1593
  program.command("start").description("Start the OpenQA agent and web UI").option("-d, --daemon", "Run in daemon mode").action(async (options) => {
1622
- const spinner = (0, import_ora.default)("Starting OpenQA...").start();
1594
+ const spinner = ora("Starting OpenQA...").start();
1623
1595
  try {
1624
- if ((0, import_fs4.existsSync)(PID_FILE)) {
1625
- const pid = (0, import_fs4.readFileSync)(PID_FILE, "utf-8").trim();
1596
+ if (existsSync(PID_FILE)) {
1597
+ const pid = readFileSync2(PID_FILE, "utf-8").trim();
1626
1598
  try {
1627
1599
  process.kill(parseInt(pid), 0);
1628
- spinner.fail(import_chalk.default.red("OpenQA is already running"));
1629
- console.log(import_chalk.default.yellow(`PID: ${pid}`));
1630
- console.log(import_chalk.default.cyan('Run "openqa stop" to stop it first'));
1600
+ spinner.fail(chalk.red("OpenQA is already running"));
1601
+ console.log(chalk.yellow(`PID: ${pid}`));
1602
+ console.log(chalk.cyan('Run "openqa stop" to stop it first'));
1631
1603
  process.exit(1);
1632
1604
  } catch {
1633
- (0, import_fs4.unlinkSync)(PID_FILE);
1605
+ unlinkSync(PID_FILE);
1634
1606
  }
1635
1607
  }
1636
1608
  if (options.daemon) {
1637
- const child = (0, import_child_process.spawn)("node", [(0, import_path3.join)(process.cwd(), "dist/cli/daemon.js")], {
1609
+ const child = spawn("node", [join3(process.cwd(), "dist/cli/daemon.js")], {
1638
1610
  detached: true,
1639
1611
  stdio: "ignore"
1640
1612
  });
1641
1613
  child.unref();
1642
- (0, import_fs4.writeFileSync)(PID_FILE, child.pid.toString());
1643
- spinner.succeed(import_chalk.default.green("OpenQA started in daemon mode"));
1644
- console.log(import_chalk.default.cyan(`PID: ${child.pid}`));
1614
+ writeFileSync(PID_FILE, child.pid.toString());
1615
+ spinner.succeed(chalk.green("OpenQA started in daemon mode"));
1616
+ console.log(chalk.cyan(`PID: ${child.pid}`));
1645
1617
  } else {
1646
- spinner.succeed(import_chalk.default.green("OpenQA started"));
1618
+ spinner.succeed(chalk.green("OpenQA started"));
1647
1619
  const agent = new OpenQAAgent();
1648
1620
  const config = new ConfigManager();
1649
1621
  const cfg = config.getConfig();
1650
- console.log(import_chalk.default.cyan("\n\u{1F4CA} OpenQA Status:"));
1651
- console.log(import_chalk.default.white(` Agent: Running`));
1652
- console.log(import_chalk.default.white(` Target: ${cfg.saas.url || "Not configured"}`));
1653
- console.log(import_chalk.default.white(` Web UI: http://localhost:${cfg.web.port}`));
1654
- console.log(import_chalk.default.white(` DevTools: http://localhost:${cfg.web.port}`));
1655
- console.log(import_chalk.default.white(` Kanban: http://localhost:${cfg.web.port}/kanban`));
1656
- console.log(import_chalk.default.white(` Config: http://localhost:${cfg.web.port}/config`));
1657
- console.log(import_chalk.default.gray("\nPress Ctrl+C to stop\n"));
1622
+ console.log(chalk.cyan("\n\u{1F4CA} OpenQA Status:"));
1623
+ console.log(chalk.white(` Agent: Running`));
1624
+ console.log(chalk.white(` Target: ${cfg.saas.url || "Not configured"}`));
1625
+ console.log(chalk.white(` Web UI: http://localhost:${cfg.web.port}`));
1626
+ console.log(chalk.white(` DevTools: http://localhost:${cfg.web.port}`));
1627
+ console.log(chalk.white(` Kanban: http://localhost:${cfg.web.port}/kanban`));
1628
+ console.log(chalk.white(` Config: http://localhost:${cfg.web.port}/config`));
1629
+ console.log(chalk.gray("\nPress Ctrl+C to stop\n"));
1658
1630
  if (cfg.agent.autoStart) {
1659
1631
  await agent.startAutonomous();
1660
1632
  } else {
1661
- console.log(import_chalk.default.yellow("Auto-start disabled. Agent is idle."));
1662
- console.log(import_chalk.default.cyan("Set AGENT_AUTO_START=true to enable autonomous mode"));
1633
+ console.log(chalk.yellow("Auto-start disabled. Agent is idle."));
1634
+ console.log(chalk.cyan("Set AGENT_AUTO_START=true to enable autonomous mode"));
1663
1635
  }
1664
1636
  }
1665
1637
  } catch (error) {
1666
- spinner.fail(import_chalk.default.red("Failed to start OpenQA"));
1667
- console.error(import_chalk.default.red(error.message));
1638
+ spinner.fail(chalk.red("Failed to start OpenQA"));
1639
+ console.error(chalk.red(error.message));
1668
1640
  process.exit(1);
1669
1641
  }
1670
1642
  });
1671
1643
  program.command("stop").description("Stop the OpenQA agent").action(() => {
1672
- const spinner = (0, import_ora.default)("Stopping OpenQA...").start();
1644
+ const spinner = ora("Stopping OpenQA...").start();
1673
1645
  try {
1674
- if (!(0, import_fs4.existsSync)(PID_FILE)) {
1675
- spinner.fail(import_chalk.default.red("OpenQA is not running"));
1646
+ if (!existsSync(PID_FILE)) {
1647
+ spinner.fail(chalk.red("OpenQA is not running"));
1676
1648
  process.exit(1);
1677
1649
  }
1678
- const pid = (0, import_fs4.readFileSync)(PID_FILE, "utf-8").trim();
1650
+ const pid = readFileSync2(PID_FILE, "utf-8").trim();
1679
1651
  try {
1680
1652
  process.kill(parseInt(pid), "SIGTERM");
1681
- (0, import_fs4.unlinkSync)(PID_FILE);
1682
- spinner.succeed(import_chalk.default.green("OpenQA stopped"));
1653
+ unlinkSync(PID_FILE);
1654
+ spinner.succeed(chalk.green("OpenQA stopped"));
1683
1655
  } catch (error) {
1684
- spinner.fail(import_chalk.default.red("Failed to stop OpenQA"));
1685
- console.error(import_chalk.default.red("Process not found. Cleaning up PID file..."));
1686
- (0, import_fs4.unlinkSync)(PID_FILE);
1656
+ spinner.fail(chalk.red("Failed to stop OpenQA"));
1657
+ console.error(chalk.red("Process not found. Cleaning up PID file..."));
1658
+ unlinkSync(PID_FILE);
1687
1659
  }
1688
1660
  } catch (error) {
1689
- spinner.fail(import_chalk.default.red("Failed to stop OpenQA"));
1690
- console.error(import_chalk.default.red(error.message));
1661
+ spinner.fail(chalk.red("Failed to stop OpenQA"));
1662
+ console.error(chalk.red(error.message));
1691
1663
  process.exit(1);
1692
1664
  }
1693
1665
  });
@@ -1695,38 +1667,38 @@ program.command("status").description("Show OpenQA status").action(() => {
1695
1667
  const config = new ConfigManager();
1696
1668
  const cfg = config.getConfig();
1697
1669
  const db = new OpenQADatabase(cfg.database.path);
1698
- console.log(import_chalk.default.cyan.bold("\n\u{1F4CA} OpenQA Status\n"));
1699
- if ((0, import_fs4.existsSync)(PID_FILE)) {
1700
- const pid = (0, import_fs4.readFileSync)(PID_FILE, "utf-8").trim();
1670
+ console.log(chalk.cyan.bold("\n\u{1F4CA} OpenQA Status\n"));
1671
+ if (existsSync(PID_FILE)) {
1672
+ const pid = readFileSync2(PID_FILE, "utf-8").trim();
1701
1673
  try {
1702
1674
  process.kill(parseInt(pid), 0);
1703
- console.log(import_chalk.default.green("\u2713 Agent: Running"));
1704
- console.log(import_chalk.default.white(` PID: ${pid}`));
1675
+ console.log(chalk.green("\u2713 Agent: Running"));
1676
+ console.log(chalk.white(` PID: ${pid}`));
1705
1677
  } catch {
1706
- console.log(import_chalk.default.red("\u2717 Agent: Stopped (stale PID file)"));
1707
- (0, import_fs4.unlinkSync)(PID_FILE);
1678
+ console.log(chalk.red("\u2717 Agent: Stopped (stale PID file)"));
1679
+ unlinkSync(PID_FILE);
1708
1680
  }
1709
1681
  } else {
1710
- console.log(import_chalk.default.red("\u2717 Agent: Stopped"));
1711
- }
1712
- console.log(import_chalk.default.cyan("\n\u{1F310} Web Interfaces:"));
1713
- console.log(import_chalk.default.white(` DevTools: http://localhost:${cfg.web.port}`));
1714
- console.log(import_chalk.default.white(` Kanban: http://localhost:${cfg.web.port}/kanban`));
1715
- console.log(import_chalk.default.white(` Config: http://localhost:${cfg.web.port}/config`));
1716
- console.log(import_chalk.default.cyan("\n\u2699\uFE0F Configuration:"));
1717
- console.log(import_chalk.default.white(` LLM Provider: ${cfg.llm.provider}`));
1718
- console.log(import_chalk.default.white(` Target SaaS: ${cfg.saas.url || "Not configured"}`));
1719
- console.log(import_chalk.default.white(` GitHub: ${cfg.github?.token ? "Configured" : "Not configured"}`));
1720
- console.log(import_chalk.default.white(` Test Interval: ${cfg.agent.intervalMs / 1e3 / 60} minutes`));
1682
+ console.log(chalk.red("\u2717 Agent: Stopped"));
1683
+ }
1684
+ console.log(chalk.cyan("\n\u{1F310} Web Interfaces:"));
1685
+ console.log(chalk.white(` DevTools: http://localhost:${cfg.web.port}`));
1686
+ console.log(chalk.white(` Kanban: http://localhost:${cfg.web.port}/kanban`));
1687
+ console.log(chalk.white(` Config: http://localhost:${cfg.web.port}/config`));
1688
+ console.log(chalk.cyan("\n\u2699\uFE0F Configuration:"));
1689
+ console.log(chalk.white(` LLM Provider: ${cfg.llm.provider}`));
1690
+ console.log(chalk.white(` Target SaaS: ${cfg.saas.url || "Not configured"}`));
1691
+ console.log(chalk.white(` GitHub: ${cfg.github?.token ? "Configured" : "Not configured"}`));
1692
+ console.log(chalk.white(` Test Interval: ${cfg.agent.intervalMs / 1e3 / 60} minutes`));
1721
1693
  const sessions = db.getRecentSessions(5);
1722
- console.log(import_chalk.default.cyan(`
1694
+ console.log(chalk.cyan(`
1723
1695
  \u{1F4CB} Recent Sessions (${sessions.length}):`));
1724
1696
  sessions.forEach((s) => {
1725
- const status = s.status === "completed" ? import_chalk.default.green("\u2713") : s.status === "failed" ? import_chalk.default.red("\u2717") : import_chalk.default.yellow("\u27F3");
1726
- console.log(import_chalk.default.white(` ${status} ${s.id} - ${s.bugs_found} bugs found`));
1697
+ const status = s.status === "completed" ? chalk.green("\u2713") : s.status === "failed" ? chalk.red("\u2717") : chalk.yellow("\u27F3");
1698
+ console.log(chalk.white(` ${status} ${s.id} - ${s.bugs_found} bugs found`));
1727
1699
  });
1728
1700
  const bugs = db.getBugsByStatus("open");
1729
- console.log(import_chalk.default.cyan(`
1701
+ console.log(chalk.cyan(`
1730
1702
  \u{1F41B} Open Bugs: ${bugs.length}`));
1731
1703
  const tickets = db.getKanbanTickets();
1732
1704
  const byColumn = {
@@ -1735,42 +1707,42 @@ program.command("status").description("Show OpenQA status").action(() => {
1735
1707
  "in-progress": tickets.filter((t) => t.column === "in-progress").length,
1736
1708
  done: tickets.filter((t) => t.column === "done").length
1737
1709
  };
1738
- console.log(import_chalk.default.cyan("\n\u{1F4CA} Kanban Board:"));
1739
- console.log(import_chalk.default.white(` Backlog: ${byColumn.backlog}`));
1740
- console.log(import_chalk.default.white(` To Do: ${byColumn["to-do"]}`));
1741
- console.log(import_chalk.default.white(` In Progress: ${byColumn["in-progress"]}`));
1742
- console.log(import_chalk.default.white(` Done: ${byColumn.done}`));
1710
+ console.log(chalk.cyan("\n\u{1F4CA} Kanban Board:"));
1711
+ console.log(chalk.white(` Backlog: ${byColumn.backlog}`));
1712
+ console.log(chalk.white(` To Do: ${byColumn["to-do"]}`));
1713
+ console.log(chalk.white(` In Progress: ${byColumn["in-progress"]}`));
1714
+ console.log(chalk.white(` Done: ${byColumn.done}`));
1743
1715
  console.log("");
1744
1716
  });
1745
1717
  program.command("config").description("Manage configuration").argument("[action]", "Action: get, set, list").argument("[key]", "Configuration key (e.g., llm.provider)").argument("[value]", "Configuration value").action((action, key, value) => {
1746
1718
  const config = new ConfigManager();
1747
1719
  if (!action || action === "list") {
1748
1720
  const cfg = config.getConfig();
1749
- console.log(import_chalk.default.cyan.bold("\n\u2699\uFE0F OpenQA Configuration\n"));
1721
+ console.log(chalk.cyan.bold("\n\u2699\uFE0F OpenQA Configuration\n"));
1750
1722
  console.log(JSON.stringify(cfg, null, 2));
1751
1723
  console.log("");
1752
1724
  return;
1753
1725
  }
1754
1726
  if (action === "get") {
1755
1727
  if (!key) {
1756
- console.error(import_chalk.default.red('Error: key is required for "get" action'));
1728
+ console.error(chalk.red('Error: key is required for "get" action'));
1757
1729
  process.exit(1);
1758
1730
  }
1759
1731
  const val = config.get(key);
1760
- console.log(import_chalk.default.cyan(`${key}:`), import_chalk.default.white(val || "Not set"));
1732
+ console.log(chalk.cyan(`${key}:`), chalk.white(val || "Not set"));
1761
1733
  return;
1762
1734
  }
1763
1735
  if (action === "set") {
1764
1736
  if (!key || !value) {
1765
- console.error(import_chalk.default.red('Error: key and value are required for "set" action'));
1737
+ console.error(chalk.red('Error: key and value are required for "set" action'));
1766
1738
  process.exit(1);
1767
1739
  }
1768
1740
  config.set(key, value);
1769
- console.log(import_chalk.default.green(`\u2713 Set ${key} = ${value}`));
1741
+ console.log(chalk.green(`\u2713 Set ${key} = ${value}`));
1770
1742
  return;
1771
1743
  }
1772
- console.error(import_chalk.default.red(`Unknown action: ${action}`));
1773
- console.log(import_chalk.default.cyan("Available actions: get, set, list"));
1744
+ console.error(chalk.red(`Unknown action: ${action}`));
1745
+ console.log(chalk.cyan("Available actions: get, set, list"));
1774
1746
  process.exit(1);
1775
1747
  });
1776
1748
  program.command("logs").description("Show agent logs").option("-f, --follow", "Follow log output").option("-n, --lines <number>", "Number of lines to show", "50").action((options) => {
@@ -1779,25 +1751,25 @@ program.command("logs").description("Show agent logs").option("-f, --follow", "F
1779
1751
  const db = new OpenQADatabase(cfg.database.path);
1780
1752
  const sessions = db.getRecentSessions(1);
1781
1753
  if (sessions.length === 0) {
1782
- console.log(import_chalk.default.yellow("No sessions found"));
1754
+ console.log(chalk.yellow("No sessions found"));
1783
1755
  return;
1784
1756
  }
1785
1757
  const session = sessions[0];
1786
1758
  const actions = db.getSessionActions(session.id);
1787
- console.log(import_chalk.default.cyan.bold(`
1759
+ console.log(chalk.cyan.bold(`
1788
1760
  \u{1F4CB} Session Logs: ${session.id}
1789
1761
  `));
1790
- console.log(import_chalk.default.white(`Status: ${session.status}`));
1791
- console.log(import_chalk.default.white(`Started: ${session.started_at}`));
1792
- console.log(import_chalk.default.white(`Actions: ${actions.length}
1762
+ console.log(chalk.white(`Status: ${session.status}`));
1763
+ console.log(chalk.white(`Started: ${session.started_at}`));
1764
+ console.log(chalk.white(`Actions: ${actions.length}
1793
1765
  `));
1794
1766
  const limit = parseInt(options.lines);
1795
1767
  const displayActions = actions.slice(0, limit);
1796
1768
  displayActions.forEach((action) => {
1797
1769
  const icon = action.type === "navigate" ? "\u{1F310}" : action.type === "click" ? "\u{1F446}" : action.type === "fill" ? "\u2328\uFE0F" : action.type === "screenshot" ? "\u{1F4F8}" : action.type === "github_issue" ? "\u{1F41B}" : action.type === "kanban_ticket" ? "\u{1F4CB}" : "\u2022";
1798
- console.log(import_chalk.default.gray(`[${action.timestamp}]`), icon, import_chalk.default.white(action.description));
1770
+ console.log(chalk.gray(`[${action.timestamp}]`), icon, chalk.white(action.description));
1799
1771
  if (action.output) {
1800
- console.log(import_chalk.default.gray(` \u2192 ${action.output}`));
1772
+ console.log(chalk.gray(` \u2192 ${action.output}`));
1801
1773
  }
1802
1774
  });
1803
1775
  console.log("");
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@openqa/cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Autonomous QA testing agent powered by Orka.js",
5
5
  "type": "module",
6
- "main": "./dist/cli/index.cjs",
6
+ "main": "./dist/cli/index.js",
7
7
  "bin": {
8
- "openqa": "./dist/cli/index.cjs"
8
+ "openqa": "./dist/cli/index.js"
9
9
  },
10
10
  "files": [
11
11
  "dist",