@vostride/agent-qa-core 0.1.9 → 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/index.cjs +179 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +132 -102
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -93,14 +93,14 @@ function toObservationFrontmatter(data) {
|
|
|
93
93
|
}
|
|
94
94
|
async function ensureMemoryDirs(root) {
|
|
95
95
|
await Promise.all(
|
|
96
|
-
MEMORY_TIERS.map((tier) => (0, import_promises8.mkdir)((0,
|
|
96
|
+
MEMORY_TIERS.map((tier) => (0, import_promises8.mkdir)((0, import_node_path12.join)(root, tier), { recursive: true }))
|
|
97
97
|
);
|
|
98
98
|
}
|
|
99
99
|
async function writeObservation(root, tier, scope, data) {
|
|
100
|
-
const dir = (0,
|
|
101
|
-
const resolved = (0,
|
|
102
|
-
const boundary = (0,
|
|
103
|
-
if (!resolved.startsWith(boundary +
|
|
100
|
+
const dir = (0, import_node_path12.join)(root, tier, scope);
|
|
101
|
+
const resolved = (0, import_node_path12.resolve)(dir);
|
|
102
|
+
const boundary = (0, import_node_path12.resolve)(root);
|
|
103
|
+
if (!resolved.startsWith(boundary + import_node_path12.sep)) {
|
|
104
104
|
throw new Error(`Scope "${scope}" escapes memory root`);
|
|
105
105
|
}
|
|
106
106
|
const schema = "position" in data ? SuiteObservationWriteSchema : BaseObservationWriteSchema;
|
|
@@ -111,7 +111,7 @@ async function writeObservation(root, tier, scope, data) {
|
|
|
111
111
|
${(0, import_yaml3.stringify)({ ...frontmatter }, { lineWidth: 0 })}---
|
|
112
112
|
${validated.content}
|
|
113
113
|
`;
|
|
114
|
-
const filePath = (0,
|
|
114
|
+
const filePath = (0, import_node_path12.join)(dir, `${data.id}.md`);
|
|
115
115
|
await (0, import_promises8.writeFile)(filePath, content, "utf-8");
|
|
116
116
|
return filePath;
|
|
117
117
|
}
|
|
@@ -158,13 +158,13 @@ async function listObservations(dir) {
|
|
|
158
158
|
}
|
|
159
159
|
return entries.filter((f) => f.startsWith("obs_") && f.endsWith(".md")).sort();
|
|
160
160
|
}
|
|
161
|
-
var import_yaml3, import_promises8,
|
|
161
|
+
var import_yaml3, import_promises8, import_node_path12, MEMORY_TIERS;
|
|
162
162
|
var init_observation_io = __esm({
|
|
163
163
|
"src/memory/observation-io.ts"() {
|
|
164
164
|
"use strict";
|
|
165
165
|
import_yaml3 = require("yaml");
|
|
166
166
|
import_promises8 = require("fs/promises");
|
|
167
|
-
|
|
167
|
+
import_node_path12 = require("path");
|
|
168
168
|
init_schema();
|
|
169
169
|
MEMORY_TIERS = ["products", "suites", "tests"];
|
|
170
170
|
}
|
|
@@ -238,14 +238,14 @@ function isBetterSqlite3NodeGypSymlinkConflict(error) {
|
|
|
238
238
|
return message.includes("node_gyp_bins/python3") && message.includes("EEXIST");
|
|
239
239
|
}
|
|
240
240
|
function resolveCurrentRuntimeNpmCliPath() {
|
|
241
|
-
const nodeInstallRoot = (0,
|
|
242
|
-
const npmCliPath = (0,
|
|
243
|
-
return (0,
|
|
241
|
+
const nodeInstallRoot = (0, import_node_path19.dirname)((0, import_node_path19.dirname)(process.execPath));
|
|
242
|
+
const npmCliPath = (0, import_node_path19.join)(nodeInstallRoot, "lib", "node_modules", "npm", "bin", "npm-cli.js");
|
|
243
|
+
return (0, import_node_fs7.existsSync)(npmCliPath) ? npmCliPath : null;
|
|
244
244
|
}
|
|
245
245
|
function resolveCurrentRuntimeNodeDir() {
|
|
246
|
-
const nodeInstallRoot = (0,
|
|
247
|
-
const nodeHeaderPath = (0,
|
|
248
|
-
return (0,
|
|
246
|
+
const nodeInstallRoot = (0, import_node_path19.dirname)((0, import_node_path19.dirname)(process.execPath));
|
|
247
|
+
const nodeHeaderPath = (0, import_node_path19.join)(nodeInstallRoot, "include", "node", "node.h");
|
|
248
|
+
return (0, import_node_fs7.existsSync)(nodeHeaderPath) ? nodeInstallRoot : null;
|
|
249
249
|
}
|
|
250
250
|
function resolveBetterSqliteRebuildCommand() {
|
|
251
251
|
const npmCliPath = resolveCurrentRuntimeNpmCliPath();
|
|
@@ -266,31 +266,31 @@ function sleepSync(milliseconds) {
|
|
|
266
266
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
267
267
|
}
|
|
268
268
|
function waitForBetterSqlite3BuildOutput(installRoot, timeoutMs = 3e4) {
|
|
269
|
-
const bindingPath = (0,
|
|
269
|
+
const bindingPath = (0, import_node_path19.join)(installRoot, "build", "Release", "better_sqlite3.node");
|
|
270
270
|
const deadline = Date.now() + timeoutMs;
|
|
271
271
|
while (Date.now() < deadline) {
|
|
272
|
-
if ((0,
|
|
272
|
+
if ((0, import_node_fs7.existsSync)(bindingPath)) {
|
|
273
273
|
return true;
|
|
274
274
|
}
|
|
275
275
|
sleepSync(200);
|
|
276
276
|
}
|
|
277
|
-
return (0,
|
|
277
|
+
return (0, import_node_fs7.existsSync)(bindingPath);
|
|
278
278
|
}
|
|
279
279
|
function acquireBetterSqlite3RebuildLock(installRoot) {
|
|
280
|
-
const lockRoot = (0,
|
|
280
|
+
const lockRoot = (0, import_node_path19.join)((0, import_node_os3.tmpdir)(), "agent-qa-better-sqlite3-rebuild-locks");
|
|
281
281
|
const lockKey = (0, import_node_crypto6.createHash)("sha256").update(`${installRoot}\0${process.version}`).digest("hex");
|
|
282
|
-
const lockDir = (0,
|
|
282
|
+
const lockDir = (0, import_node_path19.join)(lockRoot, lockKey);
|
|
283
283
|
const deadline = Date.now() + 12e4;
|
|
284
|
-
(0,
|
|
284
|
+
(0, import_node_fs7.mkdirSync)(lockRoot, { recursive: true });
|
|
285
285
|
while (true) {
|
|
286
286
|
try {
|
|
287
|
-
(0,
|
|
288
|
-
(0,
|
|
287
|
+
(0, import_node_fs7.mkdirSync)(lockDir);
|
|
288
|
+
(0, import_node_fs7.writeFileSync)((0, import_node_path19.join)(lockDir, "owner"), `${process.pid}
|
|
289
289
|
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
290
290
|
${installRoot}
|
|
291
291
|
`);
|
|
292
292
|
return () => {
|
|
293
|
-
(0,
|
|
293
|
+
(0, import_node_fs7.rmSync)(lockDir, { recursive: true, force: true });
|
|
294
294
|
};
|
|
295
295
|
} catch (error) {
|
|
296
296
|
const code = error instanceof Error && "code" in error ? error.code : void 0;
|
|
@@ -298,7 +298,7 @@ ${installRoot}
|
|
|
298
298
|
throw error;
|
|
299
299
|
}
|
|
300
300
|
if (Date.now() > deadline) {
|
|
301
|
-
(0,
|
|
301
|
+
(0, import_node_fs7.rmSync)(lockDir, { recursive: true, force: true });
|
|
302
302
|
continue;
|
|
303
303
|
}
|
|
304
304
|
sleepSync(200);
|
|
@@ -314,13 +314,13 @@ function rebuildBetterSqlite3ForCurrentRuntime(originalError) {
|
|
|
314
314
|
}
|
|
315
315
|
rebuildAttempted = true;
|
|
316
316
|
const packageJsonPath = require2.resolve("better-sqlite3/package.json");
|
|
317
|
-
const installRoot = (0,
|
|
317
|
+
const installRoot = (0, import_node_path19.dirname)(packageJsonPath);
|
|
318
318
|
const rebuildCommand = resolveBetterSqliteRebuildCommand();
|
|
319
|
-
const nodeGypDevDir = (0,
|
|
320
|
-
const npmCacheDir = (0,
|
|
319
|
+
const nodeGypDevDir = (0, import_node_path19.join)((0, import_node_os3.tmpdir)(), "agent-qa-node-gyp", process.version.replace(/^v/, ""));
|
|
320
|
+
const npmCacheDir = (0, import_node_path19.join)((0, import_node_os3.tmpdir)(), "agent-qa-npm-cache");
|
|
321
321
|
const nodeDir = resolveCurrentRuntimeNodeDir();
|
|
322
|
-
const nodeGypBinsPath = (0,
|
|
323
|
-
const buildRoot = (0,
|
|
322
|
+
const nodeGypBinsPath = (0, import_node_path19.join)(installRoot, "build", "node_gyp_bins");
|
|
323
|
+
const buildRoot = (0, import_node_path19.join)(installRoot, "build");
|
|
324
324
|
const releaseLock = acquireBetterSqlite3RebuildLock(installRoot);
|
|
325
325
|
try {
|
|
326
326
|
clearBetterSqlite3Cache();
|
|
@@ -333,10 +333,10 @@ function rebuildBetterSqlite3ForCurrentRuntime(originalError) {
|
|
|
333
333
|
throw error;
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
|
-
(0,
|
|
337
|
-
(0,
|
|
338
|
-
(0,
|
|
339
|
-
(0,
|
|
336
|
+
(0, import_node_fs7.mkdirSync)(nodeGypDevDir, { recursive: true });
|
|
337
|
+
(0, import_node_fs7.mkdirSync)(npmCacheDir, { recursive: true });
|
|
338
|
+
(0, import_node_fs7.rmSync)(buildRoot, { recursive: true, force: true });
|
|
339
|
+
(0, import_node_fs7.rmSync)(nodeGypBinsPath, { recursive: true, force: true });
|
|
340
340
|
if (!process.env.VITEST) {
|
|
341
341
|
console.warn(`[agent-qa] Rebuilding better-sqlite3 for Node ${process.version} in ${installRoot}`);
|
|
342
342
|
}
|
|
@@ -390,16 +390,16 @@ function createBetterSqlite3Database(path5) {
|
|
|
390
390
|
return openBetterSqlite3Database(path5);
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
|
-
var import_node_child_process2,
|
|
393
|
+
var import_node_child_process2, import_node_fs7, import_node_crypto6, import_node_module3, import_node_os3, import_node_path19, import_meta3, require2, sqliteConstructor, rebuildAttempted, rebuildFailureMessage;
|
|
394
394
|
var init_sqlite = __esm({
|
|
395
395
|
"src/sqlite.ts"() {
|
|
396
396
|
"use strict";
|
|
397
397
|
import_node_child_process2 = require("child_process");
|
|
398
|
-
|
|
398
|
+
import_node_fs7 = require("fs");
|
|
399
399
|
import_node_crypto6 = require("crypto");
|
|
400
400
|
import_node_module3 = require("module");
|
|
401
401
|
import_node_os3 = require("os");
|
|
402
|
-
|
|
402
|
+
import_node_path19 = require("path");
|
|
403
403
|
import_meta3 = {};
|
|
404
404
|
require2 = (0, import_node_module3.createRequire)(import_meta3.url);
|
|
405
405
|
sqliteConstructor = null;
|
|
@@ -430,13 +430,13 @@ async function buildMemoryIndex(params) {
|
|
|
430
430
|
const insert = db.prepare("INSERT INTO observations(title, content, id, trust) VALUES (?, ?, ?, ?)");
|
|
431
431
|
const dirs = [];
|
|
432
432
|
if (validatePathComponent(params.product)) {
|
|
433
|
-
dirs.push({ path: (0,
|
|
433
|
+
dirs.push({ path: (0, import_node_path20.join)(params.memoryRoot, "products", params.product), isSuite: false });
|
|
434
434
|
}
|
|
435
435
|
if (params.suiteId && validatePathComponent(params.suiteId)) {
|
|
436
|
-
dirs.push({ path: (0,
|
|
436
|
+
dirs.push({ path: (0, import_node_path20.join)(params.memoryRoot, "suites", params.suiteId), isSuite: true });
|
|
437
437
|
}
|
|
438
438
|
if (validatePathComponent(params.testId)) {
|
|
439
|
-
dirs.push({ path: (0,
|
|
439
|
+
dirs.push({ path: (0, import_node_path20.join)(params.memoryRoot, "tests", params.testId), isSuite: false });
|
|
440
440
|
}
|
|
441
441
|
if (dirs.length === 0) {
|
|
442
442
|
console.warn("[memory-index] All path components failed validation", {
|
|
@@ -455,7 +455,7 @@ async function buildMemoryIndex(params) {
|
|
|
455
455
|
for (const { path: dirPath, isSuite } of dirs) {
|
|
456
456
|
const filenames = await listObservations(dirPath);
|
|
457
457
|
for (const filename of filenames) {
|
|
458
|
-
const filePath = (0,
|
|
458
|
+
const filePath = (0, import_node_path20.join)(dirPath, filename);
|
|
459
459
|
let raw;
|
|
460
460
|
try {
|
|
461
461
|
raw = await (0, import_promises14.readFile)(filePath, "utf-8");
|
|
@@ -485,12 +485,12 @@ async function buildMemoryIndex(params) {
|
|
|
485
485
|
return null;
|
|
486
486
|
}
|
|
487
487
|
}
|
|
488
|
-
var import_promises14,
|
|
488
|
+
var import_promises14, import_node_path20;
|
|
489
489
|
var init_memory_index = __esm({
|
|
490
490
|
"src/memory/memory-index.ts"() {
|
|
491
491
|
"use strict";
|
|
492
492
|
import_promises14 = require("fs/promises");
|
|
493
|
-
|
|
493
|
+
import_node_path20 = require("path");
|
|
494
494
|
init_observation_io();
|
|
495
495
|
init_security_scanner();
|
|
496
496
|
init_sqlite();
|
|
@@ -508,12 +508,12 @@ var init_xml_escape = __esm({
|
|
|
508
508
|
});
|
|
509
509
|
|
|
510
510
|
// src/memory/lock-manager.ts
|
|
511
|
-
var import_promises15,
|
|
511
|
+
var import_promises15, import_node_path21, LockManager;
|
|
512
512
|
var init_lock_manager = __esm({
|
|
513
513
|
"src/memory/lock-manager.ts"() {
|
|
514
514
|
"use strict";
|
|
515
515
|
import_promises15 = require("fs/promises");
|
|
516
|
-
|
|
516
|
+
import_node_path21 = require("path");
|
|
517
517
|
LockManager = class {
|
|
518
518
|
lockPath;
|
|
519
519
|
timeout;
|
|
@@ -522,7 +522,7 @@ var init_lock_manager = __esm({
|
|
|
522
522
|
this.timeout = timeout;
|
|
523
523
|
}
|
|
524
524
|
async acquire() {
|
|
525
|
-
await (0, import_promises15.mkdir)((0,
|
|
525
|
+
await (0, import_promises15.mkdir)((0, import_node_path21.dirname)(this.lockPath), { recursive: true });
|
|
526
526
|
const deadline = Date.now() + this.timeout;
|
|
527
527
|
while (Date.now() < deadline) {
|
|
528
528
|
try {
|
|
@@ -654,12 +654,12 @@ var local_provider_exports = {};
|
|
|
654
654
|
__export(local_provider_exports, {
|
|
655
655
|
LocalMemoryProvider: () => LocalMemoryProvider
|
|
656
656
|
});
|
|
657
|
-
var
|
|
657
|
+
var import_node_path22, import_node_fs8, import_promises16, LocalMemoryProvider;
|
|
658
658
|
var init_local_provider = __esm({
|
|
659
659
|
"src/memory/local-provider.ts"() {
|
|
660
660
|
"use strict";
|
|
661
|
-
|
|
662
|
-
|
|
661
|
+
import_node_path22 = require("path");
|
|
662
|
+
import_node_fs8 = require("fs");
|
|
663
663
|
import_promises16 = require("fs/promises");
|
|
664
664
|
init_memory_index();
|
|
665
665
|
init_xml_escape();
|
|
@@ -681,7 +681,7 @@ var init_local_provider = __esm({
|
|
|
681
681
|
this.minTrust = opts?.minTrust ?? 0.3;
|
|
682
682
|
this.maxInjections = opts?.maxInjections ?? 3;
|
|
683
683
|
this.lockManager = new LockManager(
|
|
684
|
-
(0,
|
|
684
|
+
(0, import_node_path22.join)(this.memoryRoot, ".curator.lock"),
|
|
685
685
|
opts?.curatorLockTimeout ?? 12e4
|
|
686
686
|
);
|
|
687
687
|
}
|
|
@@ -751,9 +751,9 @@ ${lines.join("\n")}
|
|
|
751
751
|
return writeObservation(this.memoryRoot, tier, scope, data);
|
|
752
752
|
}
|
|
753
753
|
async deleteObservation(tier, scope, id) {
|
|
754
|
-
const filePath = (0,
|
|
755
|
-
const resolved = (0,
|
|
756
|
-
if (!resolved.startsWith((0,
|
|
754
|
+
const filePath = (0, import_node_path22.join)(this.memoryRoot, tier, scope, `${id}.md`);
|
|
755
|
+
const resolved = (0, import_node_path22.resolve)(filePath);
|
|
756
|
+
if (!resolved.startsWith((0, import_node_path22.resolve)(this.memoryRoot) + import_node_path22.sep)) {
|
|
757
757
|
throw new Error("Path escapes memory root");
|
|
758
758
|
}
|
|
759
759
|
try {
|
|
@@ -770,25 +770,25 @@ ${lines.join("\n")}
|
|
|
770
770
|
const results = [];
|
|
771
771
|
const tiers = ["products", "suites", "tests"];
|
|
772
772
|
for (const tier of tiers) {
|
|
773
|
-
const tierDir = (0,
|
|
773
|
+
const tierDir = (0, import_node_path22.join)(this.memoryRoot, tier);
|
|
774
774
|
let scopes;
|
|
775
775
|
try {
|
|
776
|
-
scopes = (0,
|
|
776
|
+
scopes = (0, import_node_fs8.readdirSync)(tierDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
777
777
|
} catch {
|
|
778
778
|
continue;
|
|
779
779
|
}
|
|
780
780
|
for (const scope of scopes) {
|
|
781
|
-
const scopeDir = (0,
|
|
781
|
+
const scopeDir = (0, import_node_path22.join)(tierDir, scope);
|
|
782
782
|
let files;
|
|
783
783
|
try {
|
|
784
|
-
files = (0,
|
|
784
|
+
files = (0, import_node_fs8.readdirSync)(scopeDir).filter((f) => f.startsWith("obs_") && f.endsWith(".md"));
|
|
785
785
|
} catch {
|
|
786
786
|
continue;
|
|
787
787
|
}
|
|
788
788
|
for (const file of files) {
|
|
789
789
|
let raw;
|
|
790
790
|
try {
|
|
791
|
-
raw = (0,
|
|
791
|
+
raw = (0, import_node_fs8.readFileSync)((0, import_node_path22.join)(scopeDir, file), "utf-8");
|
|
792
792
|
} catch {
|
|
793
793
|
continue;
|
|
794
794
|
}
|
|
@@ -823,25 +823,25 @@ ${lines.join("\n")}
|
|
|
823
823
|
const tiers = ["products", "suites", "tests"];
|
|
824
824
|
const toInsert = [];
|
|
825
825
|
for (const tier of tiers) {
|
|
826
|
-
const tierDir = (0,
|
|
826
|
+
const tierDir = (0, import_node_path22.join)(this.memoryRoot, tier);
|
|
827
827
|
let scopes;
|
|
828
828
|
try {
|
|
829
|
-
scopes = (0,
|
|
829
|
+
scopes = (0, import_node_fs8.readdirSync)(tierDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
830
830
|
} catch {
|
|
831
831
|
continue;
|
|
832
832
|
}
|
|
833
833
|
for (const scope of scopes) {
|
|
834
|
-
const scopeDir = (0,
|
|
834
|
+
const scopeDir = (0, import_node_path22.join)(tierDir, scope);
|
|
835
835
|
let files;
|
|
836
836
|
try {
|
|
837
|
-
files = (0,
|
|
837
|
+
files = (0, import_node_fs8.readdirSync)(scopeDir).filter((f) => f.startsWith("obs_") && f.endsWith(".md"));
|
|
838
838
|
} catch {
|
|
839
839
|
continue;
|
|
840
840
|
}
|
|
841
841
|
for (const file of files) {
|
|
842
842
|
let raw;
|
|
843
843
|
try {
|
|
844
|
-
raw = (0,
|
|
844
|
+
raw = (0, import_node_fs8.readFileSync)((0, import_node_path22.join)(scopeDir, file), "utf-8");
|
|
845
845
|
} catch {
|
|
846
846
|
continue;
|
|
847
847
|
}
|
|
@@ -1068,6 +1068,7 @@ __export(index_exports, {
|
|
|
1068
1068
|
findSecretTemplates: () => findSecretTemplates,
|
|
1069
1069
|
findUnresolvedTemplates: () => findUnresolvedTemplates,
|
|
1070
1070
|
flushAnalytics: () => flushAnalytics,
|
|
1071
|
+
formatAppiumInstallGuidance: () => formatAppiumInstallGuidance,
|
|
1071
1072
|
formatDiagnostics: () => formatDiagnostics,
|
|
1072
1073
|
formatDiagnosticsPlain: () => formatDiagnosticsPlain,
|
|
1073
1074
|
formatLogEntry: () => formatLogEntry,
|
|
@@ -1102,6 +1103,7 @@ __export(index_exports, {
|
|
|
1102
1103
|
listObservations: () => listObservations,
|
|
1103
1104
|
listProviders: () => listProviders,
|
|
1104
1105
|
loadLLMAuthPlugins: () => loadLLMAuthPlugins,
|
|
1106
|
+
localAppiumBinaryNames: () => localAppiumBinaryNames,
|
|
1105
1107
|
mapMobileCapabilities: () => mapMobileCapabilities,
|
|
1106
1108
|
mapWebCapabilities: () => mapWebCapabilities,
|
|
1107
1109
|
mergeRunAttributes: () => mergeRunAttributes,
|
|
@@ -1128,6 +1130,7 @@ __export(index_exports, {
|
|
|
1128
1130
|
resolveAnalyticsAgentProduct: () => resolveAnalyticsAgentProduct,
|
|
1129
1131
|
resolveAnalyticsIdentity: () => resolveAnalyticsIdentity,
|
|
1130
1132
|
resolveAnalyticsStandardProperties: () => resolveAnalyticsStandardProperties,
|
|
1133
|
+
resolveAppiumExecutable: () => resolveAppiumExecutable,
|
|
1131
1134
|
resolveBetterSqliteRebuildCommand: () => resolveBetterSqliteRebuildCommand,
|
|
1132
1135
|
resolveFarmCredentials: () => resolveFarmCredentials,
|
|
1133
1136
|
resolveFileReferences: () => resolveFileReferences,
|
|
@@ -4974,9 +4977,9 @@ function getHookCommand(runtime, entryFile) {
|
|
|
4974
4977
|
}
|
|
4975
4978
|
}
|
|
4976
4979
|
async function checkDockerAvailable(dockerBin = DEFAULT_DOCKER_BIN) {
|
|
4977
|
-
return new Promise((
|
|
4980
|
+
return new Promise((resolve8) => {
|
|
4978
4981
|
(0, import_node_child_process.execFile)(dockerBin, ["info", "--format", "{{.ID}}"], { timeout: 5e3 }, (err) => {
|
|
4979
|
-
|
|
4982
|
+
resolve8(!err);
|
|
4980
4983
|
});
|
|
4981
4984
|
});
|
|
4982
4985
|
}
|
|
@@ -5089,22 +5092,22 @@ function filterSecretVariables(variables, secretStore) {
|
|
|
5089
5092
|
);
|
|
5090
5093
|
}
|
|
5091
5094
|
function imageExists(dockerBin, image) {
|
|
5092
|
-
return new Promise((
|
|
5095
|
+
return new Promise((resolve8) => {
|
|
5093
5096
|
(0, import_node_child_process.execFile)(dockerBin, ["image", "inspect", image], { timeout: 1e4 }, (err) => {
|
|
5094
|
-
|
|
5097
|
+
resolve8(!err);
|
|
5095
5098
|
});
|
|
5096
5099
|
});
|
|
5097
5100
|
}
|
|
5098
5101
|
function pullImage(dockerBin, image) {
|
|
5099
|
-
return new Promise((
|
|
5102
|
+
return new Promise((resolve8, reject) => {
|
|
5100
5103
|
(0, import_node_child_process.execFile)(dockerBin, ["pull", image], { timeout: 12e4 }, (err) => {
|
|
5101
5104
|
if (err) reject(new Error(`Failed to pull image ${image}: ${err.message}`));
|
|
5102
|
-
else
|
|
5105
|
+
else resolve8();
|
|
5103
5106
|
});
|
|
5104
5107
|
});
|
|
5105
5108
|
}
|
|
5106
5109
|
function execDocker(dockerBin, args, timeout) {
|
|
5107
|
-
return new Promise((
|
|
5110
|
+
return new Promise((resolve8, reject) => {
|
|
5108
5111
|
let stdout = "";
|
|
5109
5112
|
let stderr = "";
|
|
5110
5113
|
let resolved = false;
|
|
@@ -5114,11 +5117,11 @@ function execDocker(dockerBin, args, timeout) {
|
|
|
5114
5117
|
stdout = out ?? "";
|
|
5115
5118
|
stderr = errOut ?? "";
|
|
5116
5119
|
if (err && "killed" in err && err.killed) {
|
|
5117
|
-
|
|
5120
|
+
resolve8({ stdout, stderr: `Hook timed out after ${timeout}ms`, exitCode: 124 });
|
|
5118
5121
|
return;
|
|
5119
5122
|
}
|
|
5120
5123
|
const exitCode = err?.code ?? 0;
|
|
5121
|
-
|
|
5124
|
+
resolve8({ stdout, stderr, exitCode: typeof exitCode === "number" ? exitCode : 1 });
|
|
5122
5125
|
});
|
|
5123
5126
|
});
|
|
5124
5127
|
}
|
|
@@ -7194,14 +7197,41 @@ function resolveMobileRunConfig(input) {
|
|
|
7194
7197
|
};
|
|
7195
7198
|
}
|
|
7196
7199
|
|
|
7200
|
+
// src/mobile/appium-executable.ts
|
|
7201
|
+
var import_node_fs2 = require("fs");
|
|
7202
|
+
var import_node_path8 = require("path");
|
|
7203
|
+
function localAppiumBinaryNames(platform = process.platform) {
|
|
7204
|
+
return platform === "win32" ? ["appium.cmd", "appium.exe", "appium"] : ["appium"];
|
|
7205
|
+
}
|
|
7206
|
+
function resolveAppiumExecutable(opts = {}) {
|
|
7207
|
+
const exists = opts.exists ?? import_node_fs2.existsSync;
|
|
7208
|
+
const names = localAppiumBinaryNames(opts.platform ?? process.platform);
|
|
7209
|
+
let current = (0, import_node_path8.resolve)(opts.cwd ?? process.cwd());
|
|
7210
|
+
const root = (0, import_node_path8.parse)(current).root;
|
|
7211
|
+
while (true) {
|
|
7212
|
+
for (const name of names) {
|
|
7213
|
+
const candidate = (0, import_node_path8.join)(current, "node_modules", ".bin", name);
|
|
7214
|
+
if (exists(candidate)) {
|
|
7215
|
+
return { command: candidate, source: "local" };
|
|
7216
|
+
}
|
|
7217
|
+
}
|
|
7218
|
+
if (current === root) break;
|
|
7219
|
+
current = (0, import_node_path8.dirname)(current);
|
|
7220
|
+
}
|
|
7221
|
+
return { command: "appium", source: "path" };
|
|
7222
|
+
}
|
|
7223
|
+
function formatAppiumInstallGuidance() {
|
|
7224
|
+
return "Install Appium locally with `npm install -D appium` (or `pnpm add -D appium` / `yarn add -D appium`). If you prefer a machine-wide setup, use `npm install -g appium`.";
|
|
7225
|
+
}
|
|
7226
|
+
|
|
7197
7227
|
// src/auth/store.ts
|
|
7198
7228
|
var import_promises7 = require("fs/promises");
|
|
7199
|
-
var
|
|
7229
|
+
var import_node_path9 = require("path");
|
|
7200
7230
|
var import_node_os2 = require("os");
|
|
7201
7231
|
function getAuthPath() {
|
|
7202
7232
|
const xdg = process.env.XDG_DATA_HOME;
|
|
7203
|
-
if (xdg) return (0,
|
|
7204
|
-
return (0,
|
|
7233
|
+
if (xdg) return (0, import_node_path9.join)(xdg, "agent-qa", "auth.json");
|
|
7234
|
+
return (0, import_node_path9.join)((0, import_node_os2.homedir)(), ".agent-qa", "auth.json");
|
|
7205
7235
|
}
|
|
7206
7236
|
async function readAuth(path5) {
|
|
7207
7237
|
const authPath = path5 ?? getAuthPath();
|
|
@@ -7216,7 +7246,7 @@ async function writeAuth(provider, credential, path5) {
|
|
|
7216
7246
|
const authPath = path5 ?? getAuthPath();
|
|
7217
7247
|
const store = await readAuth(authPath);
|
|
7218
7248
|
store[provider] = credential;
|
|
7219
|
-
await (0, import_promises7.mkdir)((0,
|
|
7249
|
+
await (0, import_promises7.mkdir)((0, import_node_path9.dirname)(authPath), { recursive: true });
|
|
7220
7250
|
await (0, import_promises7.writeFile)(authPath, JSON.stringify(store, null, 2), { mode: 384 });
|
|
7221
7251
|
}
|
|
7222
7252
|
async function removeAuth(provider, path5) {
|
|
@@ -7394,17 +7424,17 @@ async function resolveLLMAuth(configName, llmConfig, authPath) {
|
|
|
7394
7424
|
|
|
7395
7425
|
// src/auth/plugin-loader.ts
|
|
7396
7426
|
var import_node_module = require("module");
|
|
7397
|
-
var
|
|
7398
|
-
var
|
|
7427
|
+
var import_node_fs3 = require("fs");
|
|
7428
|
+
var import_node_path10 = require("path");
|
|
7399
7429
|
var import_node_url = require("url");
|
|
7400
7430
|
var import_meta = {};
|
|
7401
7431
|
var loadedDeclarations = /* @__PURE__ */ new Set();
|
|
7402
7432
|
function findPackageJson(packageName, baseDir) {
|
|
7403
|
-
let current = (0,
|
|
7433
|
+
let current = (0, import_node_path10.resolve)(baseDir);
|
|
7404
7434
|
while (true) {
|
|
7405
|
-
const candidate = (0,
|
|
7406
|
-
if ((0,
|
|
7407
|
-
const parent = (0,
|
|
7435
|
+
const candidate = (0, import_node_path10.resolve)(current, "node_modules", ...packageName.split("/"), "package.json");
|
|
7436
|
+
if ((0, import_node_fs3.existsSync)(candidate)) return candidate;
|
|
7437
|
+
const parent = (0, import_node_path10.dirname)(current);
|
|
7408
7438
|
if (parent === current) return null;
|
|
7409
7439
|
current = parent;
|
|
7410
7440
|
}
|
|
@@ -7429,10 +7459,10 @@ function exportTargetFromPackageJson(pkg) {
|
|
|
7429
7459
|
function resolvePackageImportFromBase(packageName, baseDir) {
|
|
7430
7460
|
const packageJsonPath = findPackageJson(packageName, baseDir);
|
|
7431
7461
|
if (!packageJsonPath) return null;
|
|
7432
|
-
const pkg = JSON.parse((0,
|
|
7462
|
+
const pkg = JSON.parse((0, import_node_fs3.readFileSync)(packageJsonPath, "utf-8"));
|
|
7433
7463
|
const target = exportTargetFromPackageJson(pkg);
|
|
7434
7464
|
if (!target || !target.startsWith(".")) return null;
|
|
7435
|
-
return (0, import_node_url.pathToFileURL)((0,
|
|
7465
|
+
return (0, import_node_url.pathToFileURL)((0, import_node_path10.resolve)((0, import_node_path10.dirname)(packageJsonPath), target)).href;
|
|
7436
7466
|
}
|
|
7437
7467
|
function packageDeclarationValue(declaration) {
|
|
7438
7468
|
return "package" in declaration && typeof declaration.package === "string" ? declaration.package.trim() : "";
|
|
@@ -7443,24 +7473,24 @@ function pathDeclarationValue(declaration) {
|
|
|
7443
7473
|
function declarationKey(declaration, baseDir) {
|
|
7444
7474
|
const packageName = packageDeclarationValue(declaration);
|
|
7445
7475
|
if (packageName) return `package:${packageName}`;
|
|
7446
|
-
return `path:${(0,
|
|
7476
|
+
return `path:${(0, import_node_path10.resolve)(baseDir, pathDeclarationValue(declaration))}`;
|
|
7447
7477
|
}
|
|
7448
7478
|
function resolveModuleSpecifier(declaration, baseDir) {
|
|
7449
7479
|
const packageName = packageDeclarationValue(declaration);
|
|
7450
7480
|
if (packageName) {
|
|
7451
7481
|
const packageImport = resolvePackageImportFromBase(packageName, baseDir);
|
|
7452
7482
|
if (packageImport) return packageImport;
|
|
7453
|
-
const parentUrl = (0, import_node_url.pathToFileURL)((0,
|
|
7483
|
+
const parentUrl = (0, import_node_url.pathToFileURL)((0, import_node_path10.resolve)(baseDir, "agent-qa.config.yaml")).href;
|
|
7454
7484
|
try {
|
|
7455
7485
|
const resolveImport = import_meta.resolve;
|
|
7456
7486
|
return resolveImport(packageName, parentUrl);
|
|
7457
7487
|
} catch {
|
|
7458
|
-
const require3 = (0, import_node_module.createRequire)((0,
|
|
7488
|
+
const require3 = (0, import_node_module.createRequire)((0, import_node_path10.resolve)(baseDir, "agent-qa.config.yaml"));
|
|
7459
7489
|
return (0, import_node_url.pathToFileURL)(require3.resolve(packageName)).href;
|
|
7460
7490
|
}
|
|
7461
7491
|
}
|
|
7462
7492
|
const pluginPath = pathDeclarationValue(declaration);
|
|
7463
|
-
const absolutePath = (0,
|
|
7493
|
+
const absolutePath = (0, import_node_path10.isAbsolute)(pluginPath) ? pluginPath : (0, import_node_path10.resolve)(baseDir, pluginPath);
|
|
7464
7494
|
return (0, import_node_url.pathToFileURL)(absolutePath).href;
|
|
7465
7495
|
}
|
|
7466
7496
|
async function resolvePluginBundle(module2, source) {
|
|
@@ -7850,8 +7880,8 @@ function mapMobileCapabilities(match, platform, credentials, opts) {
|
|
|
7850
7880
|
}
|
|
7851
7881
|
|
|
7852
7882
|
// src/farm/browserstack.ts
|
|
7853
|
-
var
|
|
7854
|
-
var
|
|
7883
|
+
var import_node_fs4 = require("fs");
|
|
7884
|
+
var import_node_path11 = require("path");
|
|
7855
7885
|
function isAbsoluteAppValue(value) {
|
|
7856
7886
|
return value.startsWith("/") || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\");
|
|
7857
7887
|
}
|
|
@@ -7870,9 +7900,9 @@ async function resolveBrowserStackApp(config) {
|
|
|
7870
7900
|
});
|
|
7871
7901
|
}
|
|
7872
7902
|
const appBaseDir = config.appBaseDir ?? process.cwd();
|
|
7873
|
-
const resolvedPath = (0,
|
|
7903
|
+
const resolvedPath = (0, import_node_path11.resolve)(appBaseDir, config.app);
|
|
7874
7904
|
const mustExist = isExplicitRelativePath(config.app);
|
|
7875
|
-
if (!(0,
|
|
7905
|
+
if (!(0, import_node_fs4.existsSync)(resolvedPath)) {
|
|
7876
7906
|
if (mustExist) {
|
|
7877
7907
|
throw new MobileSetupError({
|
|
7878
7908
|
category: "app-install",
|
|
@@ -7886,7 +7916,7 @@ async function resolveBrowserStackApp(config) {
|
|
|
7886
7916
|
}
|
|
7887
7917
|
const auth = Buffer.from(`${config.credentials.username}:${config.credentials.accessKey}`).toString("base64");
|
|
7888
7918
|
const form = new FormData();
|
|
7889
|
-
form.append("file", new Blob([(0,
|
|
7919
|
+
form.append("file", new Blob([(0, import_node_fs4.readFileSync)(resolvedPath)]), (0, import_node_path11.basename)(resolvedPath));
|
|
7890
7920
|
let res;
|
|
7891
7921
|
try {
|
|
7892
7922
|
res = await fetch("https://api-cloud.browserstack.com/app-automate/upload", {
|
|
@@ -8063,7 +8093,7 @@ async function runHooks(hooks, options = {}) {
|
|
|
8063
8093
|
// src/memory/curator.ts
|
|
8064
8094
|
var import_ai7 = require("ai");
|
|
8065
8095
|
var import_zod19 = require("zod");
|
|
8066
|
-
var
|
|
8096
|
+
var import_node_path13 = require("path");
|
|
8067
8097
|
var import_promises9 = require("fs/promises");
|
|
8068
8098
|
init_observation_io();
|
|
8069
8099
|
|
|
@@ -8212,7 +8242,7 @@ function collectKnownObservationIds(injectedObservationIds, dedupMatches) {
|
|
|
8212
8242
|
async function findObservationFile(memoryRoot, id) {
|
|
8213
8243
|
const tiers = ["products", "suites", "tests"];
|
|
8214
8244
|
for (const tier of tiers) {
|
|
8215
|
-
const tierDir = (0,
|
|
8245
|
+
const tierDir = (0, import_node_path13.join)(memoryRoot, tier);
|
|
8216
8246
|
let scopes;
|
|
8217
8247
|
try {
|
|
8218
8248
|
scopes = await (0, import_promises9.readdir)(tierDir);
|
|
@@ -8220,7 +8250,7 @@ async function findObservationFile(memoryRoot, id) {
|
|
|
8220
8250
|
continue;
|
|
8221
8251
|
}
|
|
8222
8252
|
for (const scope of scopes) {
|
|
8223
|
-
const filePath = (0,
|
|
8253
|
+
const filePath = (0, import_node_path13.join)(tierDir, scope, `${id}.md`);
|
|
8224
8254
|
try {
|
|
8225
8255
|
await (0, import_promises9.access)(filePath);
|
|
8226
8256
|
return { tier, scope, filePath };
|
|
@@ -8449,11 +8479,11 @@ ${userMessage}`;
|
|
|
8449
8479
|
}
|
|
8450
8480
|
if (ctx.suiteId && ctx.suiteContext) {
|
|
8451
8481
|
try {
|
|
8452
|
-
const suiteDir = (0,
|
|
8482
|
+
const suiteDir = (0, import_node_path13.join)(ctx.memoryRoot, "suites", ctx.suiteId);
|
|
8453
8483
|
const files = await listObservations(suiteDir);
|
|
8454
8484
|
for (const file of files) {
|
|
8455
8485
|
try {
|
|
8456
|
-
const filePath = (0,
|
|
8486
|
+
const filePath = (0, import_node_path13.join)(suiteDir, file);
|
|
8457
8487
|
const raw = await (0, import_promises9.readFile)(filePath, "utf-8");
|
|
8458
8488
|
const { data } = parseObservation(raw, file);
|
|
8459
8489
|
if (!data || !("suite_snapshot" in data)) continue;
|
|
@@ -9155,14 +9185,14 @@ async function runSuite(suite, testEntries, config) {
|
|
|
9155
9185
|
|
|
9156
9186
|
// src/validation/validate.ts
|
|
9157
9187
|
var import_promises12 = require("fs/promises");
|
|
9158
|
-
var
|
|
9159
|
-
var
|
|
9188
|
+
var import_node_fs6 = require("fs");
|
|
9189
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
9160
9190
|
var import_yaml5 = require("yaml");
|
|
9161
9191
|
var import_glob2 = require("glob");
|
|
9162
9192
|
|
|
9163
9193
|
// src/hooks/parser.ts
|
|
9164
9194
|
var import_promises11 = require("fs/promises");
|
|
9165
|
-
var
|
|
9195
|
+
var import_node_path14 = require("path");
|
|
9166
9196
|
var import_yaml4 = require("yaml");
|
|
9167
9197
|
async function parseHooksFile(filePath) {
|
|
9168
9198
|
let raw;
|
|
@@ -9184,31 +9214,31 @@ async function parseHooksFile(filePath) {
|
|
|
9184
9214
|
);
|
|
9185
9215
|
return { hooks: [], errors };
|
|
9186
9216
|
}
|
|
9187
|
-
const dir = (0,
|
|
9217
|
+
const dir = (0, import_node_path14.dirname)(filePath);
|
|
9188
9218
|
const hooks = result.data.hooks.map((h) => ({
|
|
9189
9219
|
...h,
|
|
9190
|
-
file: (0,
|
|
9191
|
-
deps: h.deps.map((d) => (0,
|
|
9192
|
-
packageFile: h.packageFile ? (0,
|
|
9220
|
+
file: (0, import_node_path14.resolve)(dir, h.file),
|
|
9221
|
+
deps: h.deps.map((d) => (0, import_node_path14.resolve)(dir, d)),
|
|
9222
|
+
packageFile: h.packageFile ? (0, import_node_path14.resolve)(dir, h.packageFile) : void 0
|
|
9193
9223
|
}));
|
|
9194
9224
|
return { hooks, errors: [] };
|
|
9195
9225
|
}
|
|
9196
9226
|
|
|
9197
9227
|
// src/utils/path-validation.ts
|
|
9198
|
-
var
|
|
9228
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
9199
9229
|
function isPathInsideDir(childPath, parentDir) {
|
|
9200
9230
|
if (!childPath) return false;
|
|
9201
|
-
const resolved =
|
|
9202
|
-
const relative2 =
|
|
9203
|
-
return !!relative2 && !relative2.startsWith("..") && !
|
|
9231
|
+
const resolved = import_node_path15.default.resolve(parentDir, childPath);
|
|
9232
|
+
const relative2 = import_node_path15.default.relative(parentDir, resolved);
|
|
9233
|
+
return !!relative2 && !relative2.startsWith("..") && !import_node_path15.default.isAbsolute(relative2);
|
|
9204
9234
|
}
|
|
9205
9235
|
|
|
9206
9236
|
// src/workspace/workspace-paths.ts
|
|
9207
|
-
var
|
|
9208
|
-
var
|
|
9237
|
+
var import_node_fs5 = require("fs");
|
|
9238
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
9209
9239
|
var import_glob = require("glob");
|
|
9210
9240
|
function toForwardSlash(value) {
|
|
9211
|
-
return value.split(
|
|
9241
|
+
return value.split(import_node_path16.default.sep).join("/");
|
|
9212
9242
|
}
|
|
9213
9243
|
function trimLeadingCurrentDir(value) {
|
|
9214
9244
|
return toForwardSlash(value).replace(/^\.\//, "");
|
|
@@ -9227,16 +9257,16 @@ function assertNonEmptyString(value, key) {
|
|
|
9227
9257
|
}
|
|
9228
9258
|
function resolveWorkspaceScalar(configDir, key, configuredPath) {
|
|
9229
9259
|
const value = assertNonEmptyString(configuredPath, key);
|
|
9230
|
-
const absolutePath =
|
|
9260
|
+
const absolutePath = import_node_path16.default.isAbsolute(value) ? import_node_path16.default.resolve(value) : import_node_path16.default.resolve(configDir, value);
|
|
9231
9261
|
return {
|
|
9232
9262
|
configuredPath: value,
|
|
9233
9263
|
absolutePath,
|
|
9234
|
-
workspaceRelativePath: trimLeadingCurrentDir(
|
|
9264
|
+
workspaceRelativePath: trimLeadingCurrentDir(import_node_path16.default.relative(configDir, absolutePath))
|
|
9235
9265
|
};
|
|
9236
9266
|
}
|
|
9237
9267
|
function assertInsideWorkspace(configDir, absolutePath, filePath) {
|
|
9238
|
-
const relativePath =
|
|
9239
|
-
if (!relativePath || relativePath.startsWith("..") ||
|
|
9268
|
+
const relativePath = import_node_path16.default.relative(configDir, absolutePath);
|
|
9269
|
+
if (!relativePath || relativePath.startsWith("..") || import_node_path16.default.isAbsolute(relativePath)) {
|
|
9240
9270
|
throw new Error(`Workspace file path escapes config directory: ${filePath}`);
|
|
9241
9271
|
}
|
|
9242
9272
|
return trimLeadingCurrentDir(relativePath);
|
|
@@ -9293,8 +9323,8 @@ function isIgnored(workspace, workspaceRelativePath) {
|
|
|
9293
9323
|
return workspace.testPathIgnore.length > 0 && matchesAnyPattern(workspaceRelativePath, workspace.testPathIgnore);
|
|
9294
9324
|
}
|
|
9295
9325
|
function resolveWorkspacePaths(input) {
|
|
9296
|
-
const configPath =
|
|
9297
|
-
const configDir =
|
|
9326
|
+
const configPath = import_node_path16.default.resolve(input.configPath);
|
|
9327
|
+
const configDir = import_node_path16.default.dirname(configPath);
|
|
9298
9328
|
const workspace = input.config.workspace;
|
|
9299
9329
|
if (!workspace) {
|
|
9300
9330
|
throw new Error("Missing required workspace config key: workspace");
|
|
@@ -9317,7 +9347,7 @@ function resolveWorkspacePaths(input) {
|
|
|
9317
9347
|
["workspace.envFile", resolved.envFile],
|
|
9318
9348
|
["workspace.secretsFile", resolved.secretsFile]
|
|
9319
9349
|
]) {
|
|
9320
|
-
if (!(0,
|
|
9350
|
+
if (!(0, import_node_fs5.existsSync)(file.absolutePath)) {
|
|
9321
9351
|
throw new Error(`Configured workspace file not found: ${key} -> ${file.absolutePath}`);
|
|
9322
9352
|
}
|
|
9323
9353
|
}
|
|
@@ -9332,14 +9362,14 @@ async function discoverWorkspaceFiles(input) {
|
|
|
9332
9362
|
absolute: true,
|
|
9333
9363
|
nodir: true
|
|
9334
9364
|
});
|
|
9335
|
-
return matches.map((match) =>
|
|
9365
|
+
return matches.map((match) => import_node_path16.default.resolve(match)).map((absolutePath) => ({
|
|
9336
9366
|
kind: input.kind,
|
|
9337
9367
|
absolutePath,
|
|
9338
|
-
workspaceRelativePath: trimLeadingCurrentDir(
|
|
9368
|
+
workspaceRelativePath: trimLeadingCurrentDir(import_node_path16.default.relative(input.workspace.configDir, absolutePath))
|
|
9339
9369
|
})).sort((a, b) => a.workspaceRelativePath.localeCompare(b.workspaceRelativePath));
|
|
9340
9370
|
}
|
|
9341
9371
|
async function resolveWorkspaceFileTarget(input) {
|
|
9342
|
-
const absolutePath =
|
|
9372
|
+
const absolutePath = import_node_path16.default.isAbsolute(input.filePath) ? import_node_path16.default.resolve(input.filePath) : import_node_path16.default.resolve(input.workspace.configDir, input.filePath);
|
|
9343
9373
|
const workspaceRelativePath = assertInsideWorkspace(input.workspace.configDir, absolutePath, input.filePath);
|
|
9344
9374
|
if (!isWorkspacePathMatch({
|
|
9345
9375
|
workspace: input.workspace,
|
|
@@ -9348,7 +9378,7 @@ async function resolveWorkspaceFileTarget(input) {
|
|
|
9348
9378
|
})) {
|
|
9349
9379
|
throw new Error(`Workspace ${input.kind} file is not matched by configured workspace patterns: ${workspaceRelativePath}`);
|
|
9350
9380
|
}
|
|
9351
|
-
if (input.requireExisting && !(0,
|
|
9381
|
+
if (input.requireExisting && !(0, import_node_fs5.existsSync)(absolutePath)) {
|
|
9352
9382
|
throw new Error(`Workspace ${input.kind} file not found: ${workspaceRelativePath}`);
|
|
9353
9383
|
}
|
|
9354
9384
|
return {
|
|
@@ -9469,8 +9499,8 @@ function validateSuiteFile(filePath, content, basedir) {
|
|
|
9469
9499
|
});
|
|
9470
9500
|
continue;
|
|
9471
9501
|
}
|
|
9472
|
-
const resolved =
|
|
9473
|
-
if (!(0,
|
|
9502
|
+
const resolved = import_node_path17.default.resolve(basedir, testPath);
|
|
9503
|
+
if (!(0, import_node_fs6.existsSync)(resolved)) {
|
|
9474
9504
|
let line = 1;
|
|
9475
9505
|
let column = 1;
|
|
9476
9506
|
const seqNode = testsNode;
|
|
@@ -9491,7 +9521,7 @@ function validateSuiteFile(filePath, content, basedir) {
|
|
|
9491
9521
|
return diagnostics;
|
|
9492
9522
|
}
|
|
9493
9523
|
function validateFilename(filePath) {
|
|
9494
|
-
const basename3 =
|
|
9524
|
+
const basename3 = import_node_path17.default.basename(filePath);
|
|
9495
9525
|
if (!VALID_FILENAME_RE.test(basename3)) {
|
|
9496
9526
|
return [{
|
|
9497
9527
|
file: filePath,
|
|
@@ -9505,7 +9535,7 @@ function validateFilename(filePath) {
|
|
|
9505
9535
|
}
|
|
9506
9536
|
async function validateHooksFile(hooksFilePath, options = {}) {
|
|
9507
9537
|
const diagnostics = [];
|
|
9508
|
-
if (!(0,
|
|
9538
|
+
if (!(0, import_node_fs6.existsSync)(hooksFilePath)) {
|
|
9509
9539
|
if (options.required) {
|
|
9510
9540
|
return [buildDiagnostic(hooksFilePath, `Configured hooks file not found: ${hooksFilePath}`)];
|
|
9511
9541
|
}
|
|
@@ -9525,7 +9555,7 @@ async function validateHooksFile(hooksFilePath, options = {}) {
|
|
|
9525
9555
|
return diagnostics;
|
|
9526
9556
|
}
|
|
9527
9557
|
for (const hook of hooks) {
|
|
9528
|
-
if (!(0,
|
|
9558
|
+
if (!(0, import_node_fs6.existsSync)(hook.file)) {
|
|
9529
9559
|
diagnostics.push({
|
|
9530
9560
|
file: hooksFilePath,
|
|
9531
9561
|
line: 1,
|
|
@@ -9535,7 +9565,7 @@ async function validateHooksFile(hooksFilePath, options = {}) {
|
|
|
9535
9565
|
});
|
|
9536
9566
|
}
|
|
9537
9567
|
for (const dep of hook.deps) {
|
|
9538
|
-
if (!(0,
|
|
9568
|
+
if (!(0, import_node_fs6.existsSync)(dep)) {
|
|
9539
9569
|
diagnostics.push({
|
|
9540
9570
|
file: hooksFilePath,
|
|
9541
9571
|
line: 1,
|
|
@@ -9545,7 +9575,7 @@ async function validateHooksFile(hooksFilePath, options = {}) {
|
|
|
9545
9575
|
});
|
|
9546
9576
|
}
|
|
9547
9577
|
}
|
|
9548
|
-
if (hook.packageFile && !(0,
|
|
9578
|
+
if (hook.packageFile && !(0, import_node_fs6.existsSync)(hook.packageFile)) {
|
|
9549
9579
|
diagnostics.push({
|
|
9550
9580
|
file: hooksFilePath,
|
|
9551
9581
|
line: 1,
|
|
@@ -9660,7 +9690,7 @@ function validateRequiredWorkspaceFiles(workspace) {
|
|
|
9660
9690
|
["workspace.envFile", workspace.envFile],
|
|
9661
9691
|
["workspace.secretsFile", workspace.secretsFile]
|
|
9662
9692
|
]) {
|
|
9663
|
-
if (!(0,
|
|
9693
|
+
if (!(0, import_node_fs6.existsSync)(file.absolutePath)) {
|
|
9664
9694
|
diagnostics.push(buildDiagnostic(file.absolutePath, `Configured workspace file not found: ${key} -> ${file.absolutePath}`));
|
|
9665
9695
|
}
|
|
9666
9696
|
}
|
|
@@ -9678,7 +9708,7 @@ async function validateProject(options = {}) {
|
|
|
9678
9708
|
}
|
|
9679
9709
|
filePaths = resolvedFiles;
|
|
9680
9710
|
} else if (options.files && options.files.length > 0) {
|
|
9681
|
-
filePaths = options.files.map((f) =>
|
|
9711
|
+
filePaths = options.files.map((f) => import_node_path17.default.resolve(f));
|
|
9682
9712
|
} else if (options.workspace) {
|
|
9683
9713
|
const [testFiles, suiteFiles] = await Promise.all([
|
|
9684
9714
|
discoverWorkspaceFiles({ workspace: options.workspace, kind: "test" }),
|
|
@@ -9721,11 +9751,11 @@ async function validateProject(options = {}) {
|
|
|
9721
9751
|
if (d.severity === "error") result.errorCount++;
|
|
9722
9752
|
else result.warningCount++;
|
|
9723
9753
|
}
|
|
9724
|
-
if (hooksFilePath && hooksDiags.length === 0 && (0,
|
|
9754
|
+
if (hooksFilePath && hooksDiags.length === 0 && (0, import_node_fs6.existsSync)(hooksFilePath)) {
|
|
9725
9755
|
const { hooks } = await parseHooksFile(hooksFilePath);
|
|
9726
9756
|
const hookIds = new Set(hooks.map((h) => h.id));
|
|
9727
9757
|
for (const filePath of filePaths) {
|
|
9728
|
-
const workspaceRelativePath = options.workspace ?
|
|
9758
|
+
const workspaceRelativePath = options.workspace ? import_node_path17.default.relative(options.workspace.configDir, filePath).split(import_node_path17.default.sep).join("/") : filePath;
|
|
9729
9759
|
const isWorkspaceFile = options.workspace ? isWorkspacePathMatch({ workspace: options.workspace, kind: isSuiteFile(filePath) ? "suite" : "test", workspaceRelativePath }) : true;
|
|
9730
9760
|
if (!isWorkspaceFile) continue;
|
|
9731
9761
|
try {
|
|
@@ -9827,7 +9857,7 @@ function warnIfOutOfBounds(coords, viewport, actionType) {
|
|
|
9827
9857
|
|
|
9828
9858
|
// src/hooks/migrate-hook-refs.ts
|
|
9829
9859
|
var import_promises13 = require("fs/promises");
|
|
9830
|
-
var
|
|
9860
|
+
var import_node_path18 = require("path");
|
|
9831
9861
|
var import_yaml6 = require("yaml");
|
|
9832
9862
|
var import_zod20 = require("zod");
|
|
9833
9863
|
var import_agent_qa_ids8 = require("@vostride/agent-qa-ids");
|
|
@@ -9933,7 +9963,7 @@ function rewriteSteps(owner, filePath, hookNameToId, hookIds, errors) {
|
|
|
9933
9963
|
return changed;
|
|
9934
9964
|
}
|
|
9935
9965
|
async function resolveWorkspaceMigrationContext(workspaceDir, configPath) {
|
|
9936
|
-
const resolvedConfigPath = configPath ? (0,
|
|
9966
|
+
const resolvedConfigPath = configPath ? (0, import_node_path18.resolve)(configPath) : (0, import_node_path18.resolve)(workspaceDir, "agent-qa.config.yaml");
|
|
9937
9967
|
const rawConfig = await (0, import_promises13.readFile)(resolvedConfigPath, "utf-8");
|
|
9938
9968
|
const parsedConfig = (0, import_yaml6.parse)(rawConfig);
|
|
9939
9969
|
const configResult = AgentQaConfigSchema.safeParse(parsedConfig);
|
|
@@ -9960,7 +9990,7 @@ async function resolveWorkspaceMigrationContext(workspaceDir, configPath) {
|
|
|
9960
9990
|
};
|
|
9961
9991
|
}
|
|
9962
9992
|
async function auditWorkspaceHookReferenceMigration(options) {
|
|
9963
|
-
const workspaceDir = (0,
|
|
9993
|
+
const workspaceDir = (0, import_node_path18.resolve)(options.workspaceDir);
|
|
9964
9994
|
const errors = [];
|
|
9965
9995
|
let context;
|
|
9966
9996
|
try {
|
|
@@ -10023,12 +10053,12 @@ async function auditWorkspaceHookReferenceMigration(options) {
|
|
|
10023
10053
|
const hookIds = new Set(Object.values(hookNameToId));
|
|
10024
10054
|
if (hooksChanged) {
|
|
10025
10055
|
rewriteFiles.push({
|
|
10026
|
-
path: (0,
|
|
10056
|
+
path: (0, import_node_path18.relative)(context.configDir, context.hooksFilePath),
|
|
10027
10057
|
content: (0, import_yaml6.stringify)({ hooks: normalizedHooks })
|
|
10028
10058
|
});
|
|
10029
10059
|
}
|
|
10030
10060
|
for (const relativePath of context.targetFiles) {
|
|
10031
|
-
const absolutePath = (0,
|
|
10061
|
+
const absolutePath = (0, import_node_path18.resolve)(context.configDir, relativePath);
|
|
10032
10062
|
let parsedFile;
|
|
10033
10063
|
try {
|
|
10034
10064
|
parsedFile = (0, import_yaml6.parse)(await (0, import_promises13.readFile)(absolutePath, "utf-8"));
|
|
@@ -10069,14 +10099,14 @@ async function applyWorkspaceHookReferenceMigration(options) {
|
|
|
10069
10099
|
if (!audit.ok) {
|
|
10070
10100
|
throw new HookReferenceMigrationError(audit.errors);
|
|
10071
10101
|
}
|
|
10072
|
-
const workspaceDir = options.configPath ? (0,
|
|
10102
|
+
const workspaceDir = options.configPath ? (0, import_node_path18.dirname)((0, import_node_path18.resolve)(options.configPath)) : (0, import_node_path18.resolve)(options.workspaceDir);
|
|
10073
10103
|
for (const rewrite of audit.rewriteFiles) {
|
|
10074
|
-
const outputPath = (0,
|
|
10075
|
-
await (0, import_promises13.mkdir)((0,
|
|
10104
|
+
const outputPath = (0, import_node_path18.resolve)(workspaceDir, rewrite.path);
|
|
10105
|
+
await (0, import_promises13.mkdir)((0, import_node_path18.dirname)(outputPath), { recursive: true });
|
|
10076
10106
|
await (0, import_promises13.writeFile)(outputPath, rewrite.content, "utf-8");
|
|
10077
10107
|
}
|
|
10078
10108
|
for (const cleanupTarget of audit.cleanupTargets) {
|
|
10079
|
-
await (0, import_promises13.rm)((0,
|
|
10109
|
+
await (0, import_promises13.rm)((0, import_node_path18.resolve)(workspaceDir, cleanupTarget), { recursive: true, force: true });
|
|
10080
10110
|
}
|
|
10081
10111
|
return audit;
|
|
10082
10112
|
}
|
|
@@ -10147,12 +10177,12 @@ var RUN_ARTIFACT_SCHEMA_VERSION = 1;
|
|
|
10147
10177
|
// src/analytics/identity.ts
|
|
10148
10178
|
var import_promises17 = require("fs/promises");
|
|
10149
10179
|
var import_node_os4 = require("os");
|
|
10150
|
-
var
|
|
10180
|
+
var import_node_path23 = require("path");
|
|
10151
10181
|
var import_id_agent = require("id-agent");
|
|
10152
10182
|
var LOCAL_ANALYTICS_ID_PATTERN = /^u_([a-z]+-){9}[a-z]+$/;
|
|
10153
10183
|
function getAnalyticsIdentityPath(env = process.env, homeDir = (0, import_node_os4.homedir)()) {
|
|
10154
|
-
if (env.XDG_DATA_HOME) return (0,
|
|
10155
|
-
return (0,
|
|
10184
|
+
if (env.XDG_DATA_HOME) return (0, import_node_path23.join)(env.XDG_DATA_HOME, "agent-qa", "analytics.json");
|
|
10185
|
+
return (0, import_node_path23.join)(homeDir, ".agent-qa", "analytics.json");
|
|
10156
10186
|
}
|
|
10157
10187
|
function generateAnalyticsUserId() {
|
|
10158
10188
|
return (0, import_id_agent.idAgent)({ prefix: "u", words: 10 });
|
|
@@ -10184,7 +10214,7 @@ async function readAnalyticsIdentity(path5) {
|
|
|
10184
10214
|
}
|
|
10185
10215
|
async function writeAnalyticsIdentity(distinctId, path5, isInternal = false) {
|
|
10186
10216
|
const identityPath = path5 ?? getAnalyticsIdentityPath();
|
|
10187
|
-
await (0, import_promises17.mkdir)((0,
|
|
10217
|
+
await (0, import_promises17.mkdir)((0, import_node_path23.dirname)(identityPath), { recursive: true });
|
|
10188
10218
|
await (0, import_promises17.writeFile)(identityPath, JSON.stringify({
|
|
10189
10219
|
distinctId,
|
|
10190
10220
|
is_internal: isInternal
|
|
@@ -11295,6 +11325,7 @@ function isMacPlatform() {
|
|
|
11295
11325
|
findSecretTemplates,
|
|
11296
11326
|
findUnresolvedTemplates,
|
|
11297
11327
|
flushAnalytics,
|
|
11328
|
+
formatAppiumInstallGuidance,
|
|
11298
11329
|
formatDiagnostics,
|
|
11299
11330
|
formatDiagnosticsPlain,
|
|
11300
11331
|
formatLogEntry,
|
|
@@ -11329,6 +11360,7 @@ function isMacPlatform() {
|
|
|
11329
11360
|
listObservations,
|
|
11330
11361
|
listProviders,
|
|
11331
11362
|
loadLLMAuthPlugins,
|
|
11363
|
+
localAppiumBinaryNames,
|
|
11332
11364
|
mapMobileCapabilities,
|
|
11333
11365
|
mapWebCapabilities,
|
|
11334
11366
|
mergeRunAttributes,
|
|
@@ -11355,6 +11387,7 @@ function isMacPlatform() {
|
|
|
11355
11387
|
resolveAnalyticsAgentProduct,
|
|
11356
11388
|
resolveAnalyticsIdentity,
|
|
11357
11389
|
resolveAnalyticsStandardProperties,
|
|
11390
|
+
resolveAppiumExecutable,
|
|
11358
11391
|
resolveBetterSqliteRebuildCommand,
|
|
11359
11392
|
resolveFarmCredentials,
|
|
11360
11393
|
resolveFileReferences,
|