@openqa/cli 1.0.6 → 1.0.8
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/agent/index.js +161 -109
- package/dist/agent/index.js.map +1 -1
- package/dist/cli/index.js +163 -111
- package/dist/database/index.js +156 -108
- package/dist/database/index.js.map +1 -1
- package/package.json +2 -3
package/dist/agent/index.js
CHANGED
|
@@ -7,123 +7,171 @@ import { Tracer } from "@orka-js/observability";
|
|
|
7
7
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
8
8
|
|
|
9
9
|
// database/index.ts
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
10
|
+
import { Low } from "lowdb";
|
|
11
|
+
import { JSONFile } from "lowdb/node";
|
|
12
|
+
import { dirname } from "path";
|
|
13
13
|
import { fileURLToPath } from "url";
|
|
14
14
|
import { mkdirSync } from "fs";
|
|
15
15
|
var __filename = fileURLToPath(import.meta.url);
|
|
16
16
|
var __dirname = dirname(__filename);
|
|
17
17
|
var OpenQADatabase = class {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const dir = dirname(dbPath);
|
|
21
|
-
mkdirSync(dir, { recursive: true });
|
|
22
|
-
this.db = new Database(dbPath);
|
|
18
|
+
constructor(dbPath = "./data/openqa.json") {
|
|
19
|
+
this.dbPath = dbPath;
|
|
23
20
|
this.initialize();
|
|
24
21
|
}
|
|
22
|
+
db = null;
|
|
25
23
|
initialize() {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
getSession(id) {
|
|
49
|
-
return this.db.prepare("SELECT * FROM test_sessions WHERE id = ?").get(id);
|
|
24
|
+
const dir = dirname(this.dbPath);
|
|
25
|
+
mkdirSync(dir, { recursive: true });
|
|
26
|
+
const adapter = new JSONFile(this.dbPath);
|
|
27
|
+
this.db = new Low(adapter, {
|
|
28
|
+
config: {},
|
|
29
|
+
test_sessions: [],
|
|
30
|
+
actions: [],
|
|
31
|
+
bugs: [],
|
|
32
|
+
kanban_tickets: []
|
|
33
|
+
});
|
|
34
|
+
this.db.read();
|
|
35
|
+
if (!this.db.data) {
|
|
36
|
+
this.db.data = {
|
|
37
|
+
config: {},
|
|
38
|
+
test_sessions: [],
|
|
39
|
+
actions: [],
|
|
40
|
+
bugs: [],
|
|
41
|
+
kanban_tickets: []
|
|
42
|
+
};
|
|
43
|
+
this.db.write();
|
|
44
|
+
}
|
|
50
45
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
async ensureInitialized() {
|
|
47
|
+
if (!this.db) {
|
|
48
|
+
this.initialize();
|
|
49
|
+
}
|
|
50
|
+
await this.db.read();
|
|
55
51
|
}
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
async getConfig(key) {
|
|
53
|
+
await this.ensureInitialized();
|
|
54
|
+
return this.db.data.config[key] || null;
|
|
58
55
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this.db.
|
|
62
|
-
|
|
63
|
-
action.session_id,
|
|
64
|
-
action.type,
|
|
65
|
-
action.description,
|
|
66
|
-
action.input || null,
|
|
67
|
-
action.output || null,
|
|
68
|
-
action.screenshot_path || null
|
|
69
|
-
);
|
|
70
|
-
return this.db.prepare("SELECT * FROM actions WHERE id = ?").get(id);
|
|
56
|
+
async setConfig(key, value) {
|
|
57
|
+
await this.ensureInitialized();
|
|
58
|
+
this.db.data.config[key] = value;
|
|
59
|
+
await this.db.write();
|
|
71
60
|
}
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
async getAllConfig() {
|
|
62
|
+
await this.ensureInitialized();
|
|
63
|
+
return this.db.data.config;
|
|
74
64
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
async createSession(id, metadata) {
|
|
66
|
+
await this.ensureInitialized();
|
|
67
|
+
const session = {
|
|
78
68
|
id,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
);
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
69
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
70
|
+
status: "running",
|
|
71
|
+
total_actions: 0,
|
|
72
|
+
bugs_found: 0,
|
|
73
|
+
metadata: metadata ? JSON.stringify(metadata) : void 0
|
|
74
|
+
};
|
|
75
|
+
this.db.data.test_sessions.push(session);
|
|
76
|
+
await this.db.write();
|
|
77
|
+
return session;
|
|
78
|
+
}
|
|
79
|
+
async getSession(id) {
|
|
80
|
+
await this.ensureInitialized();
|
|
81
|
+
return this.db.data.test_sessions.find((s) => s.id === id) || null;
|
|
82
|
+
}
|
|
83
|
+
async updateSession(id, updates) {
|
|
84
|
+
await this.ensureInitialized();
|
|
85
|
+
const index = this.db.data.test_sessions.findIndex((s) => s.id === id);
|
|
86
|
+
if (index !== -1) {
|
|
87
|
+
this.db.data.test_sessions[index] = { ...this.db.data.test_sessions[index], ...updates };
|
|
88
|
+
await this.db.write();
|
|
89
|
+
}
|
|
96
90
|
}
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
async getRecentSessions(limit = 10) {
|
|
92
|
+
await this.ensureInitialized();
|
|
93
|
+
return this.db.data.test_sessions.sort((a, b) => new Date(b.started_at).getTime() - new Date(a.started_at).getTime()).slice(0, limit);
|
|
99
94
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
id,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
95
|
+
async createAction(action) {
|
|
96
|
+
await this.ensureInitialized();
|
|
97
|
+
const newAction = {
|
|
98
|
+
id: `action_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
99
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
100
|
+
...action
|
|
101
|
+
};
|
|
102
|
+
this.db.data.actions.push(newAction);
|
|
103
|
+
await this.db.write();
|
|
104
|
+
return newAction;
|
|
105
|
+
}
|
|
106
|
+
async getSessionActions(sessionId) {
|
|
107
|
+
await this.ensureInitialized();
|
|
108
|
+
return this.db.data.actions.filter((a) => a.session_id === sessionId).sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
109
|
+
}
|
|
110
|
+
async createBug(bug) {
|
|
111
|
+
await this.ensureInitialized();
|
|
112
|
+
const newBug = {
|
|
113
|
+
id: `bug_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
114
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
115
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
116
|
+
...bug
|
|
117
|
+
};
|
|
118
|
+
this.db.data.bugs.push(newBug);
|
|
119
|
+
await this.db.write();
|
|
120
|
+
return newBug;
|
|
121
|
+
}
|
|
122
|
+
async updateBug(id, updates) {
|
|
123
|
+
await this.ensureInitialized();
|
|
124
|
+
const index = this.db.data.bugs.findIndex((b) => b.id === id);
|
|
125
|
+
if (index !== -1) {
|
|
126
|
+
this.db.data.bugs[index] = {
|
|
127
|
+
...this.db.data.bugs[index],
|
|
128
|
+
...updates,
|
|
129
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
130
|
+
};
|
|
131
|
+
await this.db.write();
|
|
132
|
+
}
|
|
113
133
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
134
|
+
async getAllBugs() {
|
|
135
|
+
await this.ensureInitialized();
|
|
136
|
+
return this.db.data.bugs.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
137
|
+
}
|
|
138
|
+
async getBugsByStatus(status) {
|
|
139
|
+
await this.ensureInitialized();
|
|
140
|
+
return this.db.data.bugs.filter((b) => b.status === status).sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
141
|
+
}
|
|
142
|
+
async createKanbanTicket(ticket) {
|
|
143
|
+
await this.ensureInitialized();
|
|
144
|
+
const newTicket = {
|
|
145
|
+
id: `ticket_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
146
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
147
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
148
|
+
...ticket
|
|
149
|
+
};
|
|
150
|
+
this.db.data.kanban_tickets.push(newTicket);
|
|
151
|
+
await this.db.write();
|
|
152
|
+
return newTicket;
|
|
153
|
+
}
|
|
154
|
+
async updateKanbanTicket(id, updates) {
|
|
155
|
+
await this.ensureInitialized();
|
|
156
|
+
const index = this.db.data.kanban_tickets.findIndex((t) => t.id === id);
|
|
157
|
+
if (index !== -1) {
|
|
158
|
+
this.db.data.kanban_tickets[index] = {
|
|
159
|
+
...this.db.data.kanban_tickets[index],
|
|
160
|
+
...updates,
|
|
161
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
162
|
+
};
|
|
163
|
+
await this.db.write();
|
|
164
|
+
}
|
|
118
165
|
}
|
|
119
|
-
getKanbanTickets() {
|
|
120
|
-
|
|
166
|
+
async getKanbanTickets() {
|
|
167
|
+
await this.ensureInitialized();
|
|
168
|
+
return this.db.data.kanban_tickets.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
121
169
|
}
|
|
122
|
-
getKanbanTicketsByColumn(column) {
|
|
123
|
-
|
|
170
|
+
async getKanbanTicketsByColumn(column) {
|
|
171
|
+
await this.ensureInitialized();
|
|
172
|
+
return this.db.data.kanban_tickets.filter((t) => t.column === column).sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
|
|
124
173
|
}
|
|
125
|
-
close() {
|
|
126
|
-
this.db.close();
|
|
174
|
+
async close() {
|
|
127
175
|
}
|
|
128
176
|
};
|
|
129
177
|
|
|
@@ -174,8 +222,8 @@ var ConfigManager = class {
|
|
|
174
222
|
}
|
|
175
223
|
};
|
|
176
224
|
}
|
|
177
|
-
get(key) {
|
|
178
|
-
const dbValue = this.db.getConfig(key);
|
|
225
|
+
async get(key) {
|
|
226
|
+
const dbValue = await this.db.getConfig(key);
|
|
179
227
|
if (dbValue) return dbValue;
|
|
180
228
|
const keys = key.split(".");
|
|
181
229
|
let value = this.envConfig;
|
|
@@ -184,11 +232,11 @@ var ConfigManager = class {
|
|
|
184
232
|
}
|
|
185
233
|
return value?.toString() || null;
|
|
186
234
|
}
|
|
187
|
-
set(key, value) {
|
|
188
|
-
this.db.setConfig(key, value);
|
|
235
|
+
async set(key, value) {
|
|
236
|
+
await this.db.setConfig(key, value);
|
|
189
237
|
}
|
|
190
|
-
getAll() {
|
|
191
|
-
const dbConfig = this.db.getAllConfig();
|
|
238
|
+
async getAll() {
|
|
239
|
+
const dbConfig = await this.db.getAllConfig();
|
|
192
240
|
const merged = { ...this.envConfig };
|
|
193
241
|
for (const [key, value] of Object.entries(dbConfig)) {
|
|
194
242
|
const keys = key.split(".");
|
|
@@ -201,8 +249,12 @@ var ConfigManager = class {
|
|
|
201
249
|
}
|
|
202
250
|
return merged;
|
|
203
251
|
}
|
|
204
|
-
getConfig() {
|
|
205
|
-
return this.getAll();
|
|
252
|
+
async getConfig() {
|
|
253
|
+
return await this.getAll();
|
|
254
|
+
}
|
|
255
|
+
// Synchronous version that only uses env vars (no DB)
|
|
256
|
+
getConfigSync() {
|
|
257
|
+
return this.envConfig;
|
|
206
258
|
}
|
|
207
259
|
};
|
|
208
260
|
|
|
@@ -1320,11 +1372,11 @@ var OpenQAAgent = class extends EventEmitter3 {
|
|
|
1320
1372
|
constructor(configPath) {
|
|
1321
1373
|
super();
|
|
1322
1374
|
this.config = new ConfigManager(configPath);
|
|
1323
|
-
this.db = new OpenQADatabase(
|
|
1375
|
+
this.db = new OpenQADatabase("./data/openqa.json");
|
|
1324
1376
|
this.skillManager = new SkillManager(this.db);
|
|
1325
1377
|
}
|
|
1326
1378
|
createLLMAdapter() {
|
|
1327
|
-
const cfg = this.config.
|
|
1379
|
+
const cfg = this.config.getConfigSync();
|
|
1328
1380
|
switch (cfg.llm.provider) {
|
|
1329
1381
|
case "anthropic":
|
|
1330
1382
|
return new AnthropicAdapter2({
|
|
@@ -1340,9 +1392,9 @@ var OpenQAAgent = class extends EventEmitter3 {
|
|
|
1340
1392
|
}
|
|
1341
1393
|
}
|
|
1342
1394
|
async initialize(triggerType = "manual", triggerData) {
|
|
1343
|
-
const cfg = this.config.
|
|
1395
|
+
const cfg = this.config.getConfigSync();
|
|
1344
1396
|
this.sessionId = `session_${Date.now()}`;
|
|
1345
|
-
this.db.createSession(this.sessionId, {
|
|
1397
|
+
await this.db.createSession(this.sessionId, {
|
|
1346
1398
|
config: cfg,
|
|
1347
1399
|
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1348
1400
|
trigger_type: triggerType,
|