@qawolf/cli 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +145 -128
- package/package.json +2 -2
- package/skills/qawolf-cli/SKILL.md +1 -1
package/dist/cli.js
CHANGED
|
@@ -134044,7 +134044,7 @@ var require_snapshot_utils = __commonJS((exports, module) => {
|
|
|
134044
134044
|
// node_modules/undici/lib/mock/snapshot-recorder.js
|
|
134045
134045
|
var require_snapshot_recorder = __commonJS((exports, module) => {
|
|
134046
134046
|
var { writeFile, readFile, mkdir } = __require("node:fs/promises");
|
|
134047
|
-
var { dirname:
|
|
134047
|
+
var { dirname: dirname11, resolve: resolve9 } = __require("node:path");
|
|
134048
134048
|
var { setTimeout: setTimeout3, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
134049
134049
|
var { InvalidArgumentError: InvalidArgumentError3, UndiciError } = require_errors6();
|
|
134050
134050
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -134239,7 +134239,7 @@ var require_snapshot_recorder = __commonJS((exports, module) => {
|
|
|
134239
134239
|
throw new InvalidArgumentError3("Snapshot path is required");
|
|
134240
134240
|
}
|
|
134241
134241
|
const resolvedPath = resolve9(path4);
|
|
134242
|
-
await mkdir(
|
|
134242
|
+
await mkdir(dirname11(resolvedPath), { recursive: true });
|
|
134243
134243
|
const data2 = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
|
|
134244
134244
|
hash: hash2,
|
|
134245
134245
|
snapshot
|
|
@@ -155273,6 +155273,10 @@ var flowsMessages = {
|
|
|
155273
155273
|
title: "Flows",
|
|
155274
155274
|
remoteTitle: "Remote Flows",
|
|
155275
155275
|
flowCount: (count) => pluralize(count, "flow"),
|
|
155276
|
+
list: {
|
|
155277
|
+
remoteRequiresEnv: "--remote requires --env <env> to pick the environment to list",
|
|
155278
|
+
flagsRequireRemote: "--env and --include-drafts require --remote"
|
|
155279
|
+
},
|
|
155276
155280
|
pull: {
|
|
155277
155281
|
downloadingBundle: "Downloading flows bundle",
|
|
155278
155282
|
fetchingEnvVars: "Fetching environment variables",
|
|
@@ -170022,7 +170026,8 @@ async function validateApiKey(deps) {
|
|
|
170022
170026
|
}
|
|
170023
170027
|
// src/shell/logger.ts
|
|
170024
170028
|
var import_pino = __toESM(require_pino(), 1);
|
|
170025
|
-
import {
|
|
170029
|
+
import { mkdirSync as mkdirSync2, openSync } from "node:fs";
|
|
170030
|
+
import { dirname, join as join4 } from "node:path";
|
|
170026
170031
|
function defaultLogPath() {
|
|
170027
170032
|
return join4(envPaths("qawolf", { suffix: "" }).log, "cli.log");
|
|
170028
170033
|
}
|
|
@@ -170036,7 +170041,8 @@ function resolveStderrLevel(env2, verbose) {
|
|
|
170036
170041
|
}
|
|
170037
170042
|
function createLoggingSystem(opts) {
|
|
170038
170043
|
const { stderrLevel, logPath } = opts;
|
|
170039
|
-
|
|
170044
|
+
mkdirSync2(dirname(logPath), { recursive: true });
|
|
170045
|
+
const dest = import_pino.default.destination({ fd: openSync(logPath, "a"), sync: false });
|
|
170040
170046
|
const fileLogger = import_pino.default({ level: "debug" }, dest);
|
|
170041
170047
|
const levelNums = {
|
|
170042
170048
|
trace: 10,
|
|
@@ -171158,45 +171164,6 @@ async function getIdentity(apiKey, deps) {
|
|
|
171158
171164
|
return { ok: true, data: parsed.data };
|
|
171159
171165
|
}
|
|
171160
171166
|
|
|
171161
|
-
// src/shell/platform/getRemoteFlows.ts
|
|
171162
|
-
var remoteFlowSchema = exports_external.object({
|
|
171163
|
-
executionTarget: exports_external.union([exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown())]),
|
|
171164
|
-
id: exports_external.string(),
|
|
171165
|
-
name: exports_external.string(),
|
|
171166
|
-
path: exports_external.string(),
|
|
171167
|
-
tags: exports_external.array(exports_external.string())
|
|
171168
|
-
});
|
|
171169
|
-
var remoteFlowsResponseSchema = exports_external.object({
|
|
171170
|
-
flows: exports_external.array(remoteFlowSchema)
|
|
171171
|
-
});
|
|
171172
|
-
async function getRemoteFlows(apiKey, deps) {
|
|
171173
|
-
const url2 = `${deps.baseUrl}/api/v0/flows?includeDrafts=false`;
|
|
171174
|
-
let response;
|
|
171175
|
-
try {
|
|
171176
|
-
response = await deps.fetch(url2, {
|
|
171177
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
171178
|
-
signal: AbortSignal.timeout(15000)
|
|
171179
|
-
});
|
|
171180
|
-
} catch (error51) {
|
|
171181
|
-
return { ok: false, error: { kind: "network", cause: toError(error51) } };
|
|
171182
|
-
}
|
|
171183
|
-
if (!response.ok) {
|
|
171184
|
-
const body = await response.text().catch(() => "");
|
|
171185
|
-
return {
|
|
171186
|
-
ok: false,
|
|
171187
|
-
error: { kind: "http", status: response.status, body }
|
|
171188
|
-
};
|
|
171189
|
-
}
|
|
171190
|
-
const json2 = await response.json().catch(() => {
|
|
171191
|
-
return;
|
|
171192
|
-
});
|
|
171193
|
-
const parsed = remoteFlowsResponseSchema.safeParse(json2);
|
|
171194
|
-
if (!parsed.success) {
|
|
171195
|
-
return { ok: false, error: { kind: "parse", cause: parsed.error } };
|
|
171196
|
-
}
|
|
171197
|
-
return { ok: true, data: parsed.data };
|
|
171198
|
-
}
|
|
171199
|
-
|
|
171200
171167
|
// src/shell/platform/types.ts
|
|
171201
171168
|
var environmentListItemSchema = exports_external.object({
|
|
171202
171169
|
envId: exports_external.string(),
|
|
@@ -171250,10 +171217,10 @@ async function listTeamStorageFiles(trpc, args, deps) {
|
|
|
171250
171217
|
}
|
|
171251
171218
|
|
|
171252
171219
|
// src/shell/platform/teamStorageAssets.ts
|
|
171253
|
-
import { dirname as
|
|
171220
|
+
import { dirname as dirname3, join as join8 } from "node:path";
|
|
171254
171221
|
|
|
171255
171222
|
// src/shell/platform/teamStorageAssetManifest.ts
|
|
171256
|
-
import { dirname } from "node:path";
|
|
171223
|
+
import { dirname as dirname2 } from "node:path";
|
|
171257
171224
|
var assetManifestSchema = exports_external.object({
|
|
171258
171225
|
version: exports_external.literal(1),
|
|
171259
171226
|
files: exports_external.array(exports_external.object({
|
|
@@ -171297,7 +171264,7 @@ async function writeAssetManifest(assetsAbs, files, fs2) {
|
|
|
171297
171264
|
}))
|
|
171298
171265
|
};
|
|
171299
171266
|
const path2 = assetManifestPath(assetsAbs);
|
|
171300
|
-
await fs2.mkdir(
|
|
171267
|
+
await fs2.mkdir(dirname2(path2), { recursive: true });
|
|
171301
171268
|
await fs2.writeFile(path2, `${JSON.stringify(manifest, undefined, 2)}
|
|
171302
171269
|
`);
|
|
171303
171270
|
}
|
|
@@ -171463,7 +171430,7 @@ async function writeAssetSnapshot(args) {
|
|
|
171463
171430
|
await args.deps.fs.mkdir(args.tmpAssets, { recursive: true });
|
|
171464
171431
|
for (const { file: file2, relativePath } of args.safeFiles) {
|
|
171465
171432
|
const dest = join8(args.tmpAssets, relativePath);
|
|
171466
|
-
await args.deps.fs.mkdir(
|
|
171433
|
+
await args.deps.fs.mkdir(dirname3(dest), { recursive: true });
|
|
171467
171434
|
if (args.reusable.has(relativePath)) {
|
|
171468
171435
|
await args.deps.fs.copyFile(join8(args.assetsAbs, relativePath), dest);
|
|
171469
171436
|
continue;
|
|
@@ -171502,14 +171469,6 @@ function createPlatformClient(apiKey, deps) {
|
|
|
171502
171469
|
sleep: deps.sleep
|
|
171503
171470
|
});
|
|
171504
171471
|
},
|
|
171505
|
-
async getRemoteFlows() {
|
|
171506
|
-
return requestWithRetry({
|
|
171507
|
-
call: () => getRemoteFlows(apiKey, deps),
|
|
171508
|
-
backoffMs: requestBackoffMs2,
|
|
171509
|
-
describe: (err) => describeRequestError(err, deps.baseUrl, "flows"),
|
|
171510
|
-
sleep: deps.sleep
|
|
171511
|
-
});
|
|
171512
|
-
},
|
|
171513
171472
|
getFlowsBundleUrl: getFlowsBundleUrlImpl,
|
|
171514
171473
|
callPublicApi: makeCallPublicApiMethod(trpc, deps, requestBackoffMs2),
|
|
171515
171474
|
async getEnvVars(envId) {
|
|
@@ -173630,7 +173589,7 @@ function registerAuthCommand(program2, signals) {
|
|
|
173630
173589
|
// package.json
|
|
173631
173590
|
var package_default = {
|
|
173632
173591
|
name: "@qawolf/cli",
|
|
173633
|
-
version: "1.
|
|
173592
|
+
version: "1.3.0",
|
|
173634
173593
|
description: "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
173635
173594
|
keywords: [
|
|
173636
173595
|
"automation",
|
|
@@ -173690,7 +173649,7 @@ var package_default = {
|
|
|
173690
173649
|
"@napi-rs/keyring": "1.3.0",
|
|
173691
173650
|
"@oxc-node/core": "0.1.0",
|
|
173692
173651
|
"@playwright/test": "1.60.0",
|
|
173693
|
-
"@qawolf/api-contracts": "0.
|
|
173652
|
+
"@qawolf/api-contracts": "0.2.0",
|
|
173694
173653
|
"@qawolf/emails": "1.1.1",
|
|
173695
173654
|
"@qawolf/flow-targets": "1.0.0",
|
|
173696
173655
|
"@qawolf/flows": "0.1.1",
|
|
@@ -174217,13 +174176,13 @@ function renderResults(ui, results) {
|
|
|
174217
174176
|
}
|
|
174218
174177
|
|
|
174219
174178
|
// src/domains/flows/ensureDeps.ts
|
|
174220
|
-
import { dirname as
|
|
174179
|
+
import { dirname as dirname4, join as join10 } from "node:path";
|
|
174221
174180
|
function findEnvDir(flowPath, fs2) {
|
|
174222
|
-
let dir =
|
|
174181
|
+
let dir = dirname4(flowPath);
|
|
174223
174182
|
while (true) {
|
|
174224
174183
|
if (fs2.existsSync(join10(dir, "package.json")))
|
|
174225
174184
|
return dir;
|
|
174226
|
-
const parent =
|
|
174185
|
+
const parent = dirname4(dir);
|
|
174227
174186
|
if (parent === dir)
|
|
174228
174187
|
return;
|
|
174229
174188
|
dir = parent;
|
|
@@ -174256,7 +174215,7 @@ import { fileURLToPath } from "url";
|
|
|
174256
174215
|
|
|
174257
174216
|
// node_modules/fdir/dist/index.mjs
|
|
174258
174217
|
import { createRequire as createRequire2 } from "module";
|
|
174259
|
-
import { basename, dirname as
|
|
174218
|
+
import { basename, dirname as dirname5, normalize as normalize2, relative as relative2, resolve, sep as sep3 } from "path";
|
|
174260
174219
|
import * as nativeFs from "fs";
|
|
174261
174220
|
var __require2 = /* @__PURE__ */ createRequire2(import.meta.url);
|
|
174262
174221
|
function cleanPath(path2) {
|
|
@@ -174420,7 +174379,7 @@ function build$2(options, isSynchronous) {
|
|
|
174420
174379
|
function isRecursive(path2, resolved, state) {
|
|
174421
174380
|
if (state.options.useRealPaths)
|
|
174422
174381
|
return isRecursiveUsingRealPaths(resolved, state);
|
|
174423
|
-
let parent =
|
|
174382
|
+
let parent = dirname5(path2);
|
|
174424
174383
|
let depth = 1;
|
|
174425
174384
|
while (parent !== state.root && depth < 2) {
|
|
174426
174385
|
const resolvedPath = state.symlinks.get(parent);
|
|
@@ -174428,7 +174387,7 @@ function isRecursive(path2, resolved, state) {
|
|
|
174428
174387
|
if (isSameRoot)
|
|
174429
174388
|
depth++;
|
|
174430
174389
|
else
|
|
174431
|
-
parent =
|
|
174390
|
+
parent = dirname5(parent);
|
|
174432
174391
|
}
|
|
174433
174392
|
state.symlinks.set(path2, resolved);
|
|
174434
174393
|
return depth > 1;
|
|
@@ -174624,7 +174583,7 @@ var Walker = class {
|
|
|
174624
174583
|
} else {
|
|
174625
174584
|
resolvedPath = useRealPaths ? resolvedPath : path2;
|
|
174626
174585
|
const filename = basename(resolvedPath);
|
|
174627
|
-
const directoryPath$1 = normalizePath(
|
|
174586
|
+
const directoryPath$1 = normalizePath(dirname5(resolvedPath), this.state.options);
|
|
174628
174587
|
resolvedPath = this.joinPath(filename, directoryPath$1);
|
|
174629
174588
|
this.pushFile(resolvedPath, files, this.state.counts, filters);
|
|
174630
174589
|
}
|
|
@@ -175702,14 +175661,80 @@ function handleFlowsList(ctx, pattern) {
|
|
|
175702
175661
|
|
|
175703
175662
|
// src/domains/flows/listRemote.ts
|
|
175704
175663
|
var import_picomatch2 = __toESM(require_picomatch2(), 1);
|
|
175705
|
-
|
|
175706
|
-
|
|
175664
|
+
|
|
175665
|
+
// node_modules/@qawolf/api-contracts/dist/v1/ids.js
|
|
175666
|
+
var defaultIdSchemas = {
|
|
175667
|
+
environment: exports_external.string().min(1).describe("The id of the environment."),
|
|
175668
|
+
flow: exports_external.string().min(1).describe("The id of the flow."),
|
|
175669
|
+
run: exports_external.string().min(1).describe("The id of the run.")
|
|
175670
|
+
};
|
|
175671
|
+
|
|
175672
|
+
// node_modules/@qawolf/api-contracts/dist/v1/flow/index.js
|
|
175673
|
+
var makeListFlowsContract = (ids) => {
|
|
175674
|
+
const input = exports_external.object({
|
|
175675
|
+
environmentId: ids.environment,
|
|
175676
|
+
includeDrafts: exports_external.boolean().default(false).describe("Include draft flows in the listing.")
|
|
175677
|
+
});
|
|
175678
|
+
const executionTarget = exports_external.union([exports_external.string().min(1), exports_external.record(exports_external.string(), exports_external.unknown())]).describe("The target the flow executes against, as a preset or object.");
|
|
175679
|
+
const output = exports_external.object({
|
|
175680
|
+
flows: exports_external.array(exports_external.object({
|
|
175681
|
+
executionTarget,
|
|
175682
|
+
flowId: ids.flow,
|
|
175683
|
+
name: exports_external.string(),
|
|
175684
|
+
path: exports_external.string().describe("The flow file path, relative to the repo."),
|
|
175685
|
+
tags: exports_external.array(exports_external.string())
|
|
175686
|
+
}))
|
|
175687
|
+
});
|
|
175688
|
+
return {
|
|
175689
|
+
description: "List the flows of an environment at its latest reconciled commit.",
|
|
175690
|
+
input,
|
|
175691
|
+
kind: "read",
|
|
175692
|
+
name: "flow.list",
|
|
175693
|
+
output
|
|
175694
|
+
};
|
|
175695
|
+
};
|
|
175696
|
+
|
|
175697
|
+
// node_modules/@qawolf/api-contracts/dist/v1/run/index.js
|
|
175698
|
+
var makeCreateRunContract = (ids) => {
|
|
175699
|
+
const input = exports_external.object({
|
|
175700
|
+
environmentId: ids.environment,
|
|
175701
|
+
environmentVariables: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
175702
|
+
flowIds: exports_external.array(ids.flow).min(1),
|
|
175703
|
+
ignoreRules: exports_external.boolean().default(false)
|
|
175704
|
+
});
|
|
175705
|
+
const output = exports_external.object({ runId: ids.run });
|
|
175706
|
+
return {
|
|
175707
|
+
description: "Create a run for selected flows in an environment.",
|
|
175708
|
+
input,
|
|
175709
|
+
kind: "write",
|
|
175710
|
+
name: "run.create",
|
|
175711
|
+
output
|
|
175712
|
+
};
|
|
175713
|
+
};
|
|
175714
|
+
|
|
175715
|
+
// node_modules/@qawolf/api-contracts/dist/v1/index.js
|
|
175716
|
+
var makeContractsV1 = (ids) => ({
|
|
175717
|
+
flow: {
|
|
175718
|
+
list: makeListFlowsContract(ids)
|
|
175719
|
+
},
|
|
175720
|
+
run: {
|
|
175721
|
+
create: makeCreateRunContract(ids)
|
|
175722
|
+
}
|
|
175723
|
+
});
|
|
175724
|
+
var publicContractsV1 = makeContractsV1(defaultIdSchemas);
|
|
175725
|
+
|
|
175726
|
+
// src/domains/flows/listRemote.ts
|
|
175727
|
+
async function flowsListRemote(ctx, pattern, options) {
|
|
175728
|
+
const result = await ctx.platform.callPublicApi(publicContractsV1.flow.list, {
|
|
175729
|
+
environmentId: options.env,
|
|
175730
|
+
includeDrafts: options.includeDrafts
|
|
175731
|
+
});
|
|
175707
175732
|
if (!result.ok) {
|
|
175708
175733
|
return { error: result.error };
|
|
175709
175734
|
}
|
|
175710
175735
|
const matches = pattern ? import_picomatch2.default(pattern) : undefined;
|
|
175711
175736
|
const items = result.value.flows.filter((f2) => !matches || matches(f2.path)).map((f2) => ({
|
|
175712
|
-
|
|
175737
|
+
flowId: f2.flowId,
|
|
175713
175738
|
file: f2.path,
|
|
175714
175739
|
name: f2.name,
|
|
175715
175740
|
tags: f2.tags,
|
|
@@ -175739,7 +175764,7 @@ async function flowsListRemote(ctx, pattern) {
|
|
|
175739
175764
|
}
|
|
175740
175765
|
|
|
175741
175766
|
// src/domains/flows/pull/handler.ts
|
|
175742
|
-
import { dirname as
|
|
175767
|
+
import { dirname as dirname7, join as join23, resolve as resolve7 } from "node:path";
|
|
175743
175768
|
|
|
175744
175769
|
// src/shell/manifest/io.ts
|
|
175745
175770
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -176130,7 +176155,7 @@ async function writeEnvFile(envDir, vars, fs2 = makeDefaultFs()) {
|
|
|
176130
176155
|
}
|
|
176131
176156
|
|
|
176132
176157
|
// src/domains/flows/pull/extract.ts
|
|
176133
|
-
import { dirname as
|
|
176158
|
+
import { dirname as dirname6, resolve as resolve6 } from "node:path";
|
|
176134
176159
|
import { createGunzip } from "node:zlib";
|
|
176135
176160
|
|
|
176136
176161
|
// node_modules/tar/dist/esm/index.min.js
|
|
@@ -179394,7 +179419,7 @@ async function handleEntry(args) {
|
|
|
179394
179419
|
total: args.getTotal()
|
|
179395
179420
|
});
|
|
179396
179421
|
args.addTotal(size);
|
|
179397
|
-
args.fs.mkdirSync(
|
|
179422
|
+
args.fs.mkdirSync(dirname6(target), { recursive: true });
|
|
179398
179423
|
const chunks = [];
|
|
179399
179424
|
await new Promise((res, rej) => {
|
|
179400
179425
|
entry.on("data", (chunk) => chunks.push(chunk));
|
|
@@ -179498,7 +179523,7 @@ async function handleFlowsPull(ctx, opts, deps) {
|
|
|
179498
179523
|
return { error: validation.error };
|
|
179499
179524
|
}
|
|
179500
179525
|
const destAbs = resolve7(opts.out ?? join23(".qawolf", opts.env));
|
|
179501
|
-
const assetsAbs = join23(
|
|
179526
|
+
const assetsAbs = join23(dirname7(destAbs), "assets");
|
|
179502
179527
|
await resolvedDeps.fs.mkdir(assetsAbs, { recursive: true });
|
|
179503
179528
|
const yes = opts.yes ?? false;
|
|
179504
179529
|
let archive;
|
|
@@ -180034,7 +180059,7 @@ async function defaultRunWebFlowDeps(cwd = process.cwd(), signals) {
|
|
|
180034
180059
|
|
|
180035
180060
|
// src/domains/runtimeEnv/prepareRunDir.ts
|
|
180036
180061
|
import { createHash as createHash3 } from "node:crypto";
|
|
180037
|
-
import { basename as basename4, dirname as
|
|
180062
|
+
import { basename as basename4, dirname as dirname10, join as join28, resolve as resolve8, sep as sep4 } from "node:path";
|
|
180038
180063
|
|
|
180039
180064
|
// src/shell/copyDir.ts
|
|
180040
180065
|
import { cp, readdir as readdir2 } from "node:fs/promises";
|
|
@@ -180075,7 +180100,7 @@ async function readPackageJson(pkgPath, fs3) {
|
|
|
180075
180100
|
}
|
|
180076
180101
|
|
|
180077
180102
|
// src/domains/runtimeEnv/innerHop.ts
|
|
180078
|
-
import { dirname as
|
|
180103
|
+
import { dirname as dirname8, join as join26 } from "node:path";
|
|
180079
180104
|
|
|
180080
180105
|
// src/domains/runtimeEnv/symlinkDir.ts
|
|
180081
180106
|
import { symlink } from "node:fs/promises";
|
|
@@ -180094,7 +180119,7 @@ async function populateInnerHop(args) {
|
|
|
180094
180119
|
const segments = name.split("/");
|
|
180095
180120
|
const target = join26(innerModules, ...segments);
|
|
180096
180121
|
if (segments.length > 1) {
|
|
180097
|
-
await fs3.mkdir(
|
|
180122
|
+
await fs3.mkdir(dirname8(target), { recursive: true });
|
|
180098
180123
|
}
|
|
180099
180124
|
await createDirSymlink(join26(managedModules, ...segments), target);
|
|
180100
180125
|
}
|
|
@@ -180102,7 +180127,7 @@ async function populateInnerHop(args) {
|
|
|
180102
180127
|
|
|
180103
180128
|
// src/domains/runtimeEnv/outerHop.ts
|
|
180104
180129
|
import { lstat } from "node:fs/promises";
|
|
180105
|
-
import { dirname as
|
|
180130
|
+
import { dirname as dirname9, join as join27 } from "node:path";
|
|
180106
180131
|
var executorPackageNames = new Set(pinnedPackages.map((p3) => p3.name));
|
|
180107
180132
|
async function populateOuterHop(args) {
|
|
180108
180133
|
const { projectDir, runDir, fs: fs3 } = args;
|
|
@@ -180133,7 +180158,7 @@ async function findSatisfyingNodeModulesDir(startDir, depNames, fs3) {
|
|
|
180133
180158
|
return { satisfying: candidate, rejected };
|
|
180134
180159
|
rejected.push({ dir: candidate, missing });
|
|
180135
180160
|
}
|
|
180136
|
-
const parent =
|
|
180161
|
+
const parent = dirname9(dir);
|
|
180137
180162
|
if (parent === dir)
|
|
180138
180163
|
return { satisfying: undefined, rejected };
|
|
180139
180164
|
dir = parent;
|
|
@@ -180221,7 +180246,7 @@ async function stageFlowFiles(args) {
|
|
|
180221
180246
|
}
|
|
180222
180247
|
if (files.length > 1) {
|
|
180223
180248
|
return Promise.all(files.map(async (f3) => {
|
|
180224
|
-
const dirHash = createHash3("sha256").update(
|
|
180249
|
+
const dirHash = createHash3("sha256").update(dirname10(f3)).digest("hex").slice(0, 8);
|
|
180225
180250
|
const subDir = join28(execDir, dirHash);
|
|
180226
180251
|
await fs3.mkdir(subDir, { recursive: true });
|
|
180227
180252
|
const dest = join28(subDir, basename4(f3));
|
|
@@ -180834,12 +180859,12 @@ Install Android Studio and open Tools > SDK Manager.`);
|
|
|
180834
180859
|
}
|
|
180835
180860
|
|
|
180836
180861
|
// src/shell/manifest/lookup.ts
|
|
180837
|
-
import { basename as basename5, dirname as
|
|
180862
|
+
import { basename as basename5, dirname as dirname11, relative as relative6 } from "node:path";
|
|
180838
180863
|
async function findFlowStamp(flowAbsPath) {
|
|
180839
180864
|
let envDir;
|
|
180840
|
-
let current =
|
|
180841
|
-
while (current !==
|
|
180842
|
-
const parent2 =
|
|
180865
|
+
let current = dirname11(flowAbsPath);
|
|
180866
|
+
while (current !== dirname11(current)) {
|
|
180867
|
+
const parent2 = dirname11(current);
|
|
180843
180868
|
if (basename5(parent2) === ".qawolf") {
|
|
180844
180869
|
envDir = current;
|
|
180845
180870
|
break;
|
|
@@ -181646,7 +181671,7 @@ async function runWebFlow({
|
|
|
181646
181671
|
}
|
|
181647
181672
|
|
|
181648
181673
|
// src/shell/embeddedWorkerCli.ts
|
|
181649
|
-
import { existsSync as existsSync3, mkdirSync as
|
|
181674
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
181650
181675
|
import { basename as basename6, join as join32 } from "node:path";
|
|
181651
181676
|
var embeddedCliPathEnv = "QAWOLF_EMBEDDED_CLI_PATH";
|
|
181652
181677
|
function extractEmbeddedWorkerCli() {
|
|
@@ -181657,7 +181682,7 @@ function extractEmbeddedWorkerCli() {
|
|
|
181657
181682
|
const dest = join32(dir, basename6(assetPath));
|
|
181658
181683
|
if (existsSync3(dest))
|
|
181659
181684
|
return dest;
|
|
181660
|
-
|
|
181685
|
+
mkdirSync3(dir, { recursive: true });
|
|
181661
181686
|
writeFileSync2(dest, readFileSync2(assetPath));
|
|
181662
181687
|
return dest;
|
|
181663
181688
|
}
|
|
@@ -181807,7 +181832,7 @@ function makePooledDispatch(resolvedDir) {
|
|
|
181807
181832
|
}
|
|
181808
181833
|
|
|
181809
181834
|
// src/commands/flows/buildRunReporter.ts
|
|
181810
|
-
import { dirname as
|
|
181835
|
+
import { dirname as dirname12 } from "node:path";
|
|
181811
181836
|
|
|
181812
181837
|
// src/shell/reporter/createConsoleReporter.ts
|
|
181813
181838
|
import { styleText as styleText3 } from "node:util";
|
|
@@ -182035,7 +182060,7 @@ function buildRunReporter(flags, deps) {
|
|
|
182035
182060
|
const junit = createJUnitReporter({
|
|
182036
182061
|
outputPath: resolveJUnitOutputPath(flags.junit, flags.outputDir),
|
|
182037
182062
|
writeFile: (path9, content) => {
|
|
182038
|
-
deps.fs.mkdirSync(
|
|
182063
|
+
deps.fs.mkdirSync(dirname12(path9), { recursive: true });
|
|
182039
182064
|
deps.fs.writeFileSync(path9, content);
|
|
182040
182065
|
},
|
|
182041
182066
|
stderr
|
|
@@ -182321,8 +182346,8 @@ var listExamples = `
|
|
|
182321
182346
|
Examples:
|
|
182322
182347
|
$ qawolf flows list
|
|
182323
182348
|
$ qawolf flows list "flows/checkout/**"
|
|
182324
|
-
$ qawolf flows list --remote
|
|
182325
|
-
$ qawolf flows list "**/checkout/**" --remote`;
|
|
182349
|
+
$ qawolf flows list --remote --env staging
|
|
182350
|
+
$ qawolf flows list "**/checkout/**" --remote --env staging --include-drafts`;
|
|
182326
182351
|
var pullExamples = `
|
|
182327
182352
|
Examples:
|
|
182328
182353
|
$ qawolf flows pull --env staging
|
|
@@ -182334,9 +182359,23 @@ function registerFlowsCommand(program2, signals) {
|
|
|
182334
182359
|
registerRunWorkerCommand(flows, signals);
|
|
182335
182360
|
declareCommandKind(flows.command("list [pattern]"), "local", {
|
|
182336
182361
|
kindNote: "read with --remote"
|
|
182337
|
-
}).description("List flows matching [pattern] from the local project, or from QA Wolf with --remote").option("--remote", "List flows from the QA Wolf platform instead of the local project", false).addHelpText("after", listExamples).action((pattern, opts, command) => {
|
|
182362
|
+
}).description("List flows matching [pattern] from the local project, or from a QA Wolf environment with --remote").option("--remote", "List flows from the QA Wolf platform instead of the local project", false).option("--env <env>", "Environment to list flows from (required with --remote)").option("--include-drafts", "Include draft flows in the listing (requires --remote)", false).addHelpText("after", listExamples).action((pattern, opts, command) => {
|
|
182338
182363
|
if (opts.remote) {
|
|
182339
|
-
|
|
182364
|
+
const env3 = opts.env;
|
|
182365
|
+
if (env3 === undefined) {
|
|
182366
|
+
return withContext(signals, async () => ({
|
|
182367
|
+
error: flowsMessages.list.remoteRequiresEnv
|
|
182368
|
+
}))(opts, command);
|
|
182369
|
+
}
|
|
182370
|
+
return withAuthContext(signals, (ctx) => flowsListRemote(ctx, pattern, {
|
|
182371
|
+
env: env3,
|
|
182372
|
+
includeDrafts: opts.includeDrafts
|
|
182373
|
+
}))(opts, command);
|
|
182374
|
+
}
|
|
182375
|
+
if (opts.env !== undefined || opts.includeDrafts) {
|
|
182376
|
+
return withContext(signals, async () => ({
|
|
182377
|
+
error: flowsMessages.list.flagsRequireRemote
|
|
182378
|
+
}))(opts, command);
|
|
182340
182379
|
}
|
|
182341
182380
|
return withContext(signals, (ctx) => handleFlowsList(ctx, pattern))(opts, command);
|
|
182342
182381
|
});
|
|
@@ -182346,7 +182385,7 @@ function registerFlowsCommand(program2, signals) {
|
|
|
182346
182385
|
}
|
|
182347
182386
|
|
|
182348
182387
|
// src/domains/init/init.ts
|
|
182349
|
-
import { dirname as
|
|
182388
|
+
import { dirname as dirname13, join as join36, relative as relative7 } from "node:path";
|
|
182350
182389
|
|
|
182351
182390
|
// src/domains/init/templates.ts
|
|
182352
182391
|
var qawolfConfigTs = `export default {
|
|
@@ -182405,7 +182444,7 @@ async function writeWithPrompt(ctx, filePath, content, yes, deps) {
|
|
|
182405
182444
|
return;
|
|
182406
182445
|
}
|
|
182407
182446
|
}
|
|
182408
|
-
await deps.fs.mkdir(
|
|
182447
|
+
await deps.fs.mkdir(dirname13(filePath), { recursive: true });
|
|
182409
182448
|
await deps.fs.writeFile(filePath, content);
|
|
182410
182449
|
ctx.ui.step(initMessages.createdFile(relPath));
|
|
182411
182450
|
}
|
|
@@ -182779,39 +182818,6 @@ Examples:
|
|
|
182779
182818
|
});
|
|
182780
182819
|
}
|
|
182781
182820
|
|
|
182782
|
-
// node_modules/@qawolf/api-contracts/dist/v1/ids.js
|
|
182783
|
-
var defaultIdSchemas = {
|
|
182784
|
-
environment: exports_external.string().min(1).describe("The id of the environment."),
|
|
182785
|
-
flow: exports_external.string().min(1).describe("The id of the flow."),
|
|
182786
|
-
run: exports_external.string().min(1).describe("The id of the run.")
|
|
182787
|
-
};
|
|
182788
|
-
|
|
182789
|
-
// node_modules/@qawolf/api-contracts/dist/v1/run/index.js
|
|
182790
|
-
var makeCreateRunContract = (ids) => {
|
|
182791
|
-
const input = exports_external.object({
|
|
182792
|
-
environmentId: ids.environment,
|
|
182793
|
-
environmentVariables: exports_external.record(exports_external.string(), exports_external.string()).optional(),
|
|
182794
|
-
flowIds: exports_external.array(ids.flow).min(1),
|
|
182795
|
-
ignoreRules: exports_external.boolean().default(false)
|
|
182796
|
-
});
|
|
182797
|
-
const output = exports_external.object({ runId: ids.run });
|
|
182798
|
-
return {
|
|
182799
|
-
description: "Create a run for selected flows in an environment.",
|
|
182800
|
-
input,
|
|
182801
|
-
kind: "write",
|
|
182802
|
-
name: "run.create",
|
|
182803
|
-
output
|
|
182804
|
-
};
|
|
182805
|
-
};
|
|
182806
|
-
|
|
182807
|
-
// node_modules/@qawolf/api-contracts/dist/v1/index.js
|
|
182808
|
-
var makeContractsV1 = (ids) => ({
|
|
182809
|
-
run: {
|
|
182810
|
-
create: makeCreateRunContract(ids)
|
|
182811
|
-
}
|
|
182812
|
-
});
|
|
182813
|
-
var publicContractsV1 = makeContractsV1(defaultIdSchemas);
|
|
182814
|
-
|
|
182815
182821
|
// src/core/publicApi/flagSpecs.ts
|
|
182816
182822
|
var kebabCase = (field) => field.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
|
|
182817
182823
|
function flagKind(schema) {
|
|
@@ -182908,8 +182914,16 @@ function buildSpec(contract, path9) {
|
|
|
182908
182914
|
contract
|
|
182909
182915
|
};
|
|
182910
182916
|
}
|
|
182911
|
-
function buildCommandSpecs(tree) {
|
|
182912
|
-
const
|
|
182917
|
+
function buildCommandSpecs(tree, options = {}) {
|
|
182918
|
+
const skip = options.skipContractNames;
|
|
182919
|
+
const walk3 = (node2, path9) => Object.entries(node2).flatMap(([key, value]) => {
|
|
182920
|
+
const childPath = [...path9, key];
|
|
182921
|
+
if (!isContract(value))
|
|
182922
|
+
return walk3(value, childPath);
|
|
182923
|
+
if (skip?.has(childPath.join(".")))
|
|
182924
|
+
return [];
|
|
182925
|
+
return [buildSpec(value, childPath)];
|
|
182926
|
+
});
|
|
182913
182927
|
return walk3(tree, []);
|
|
182914
182928
|
}
|
|
182915
182929
|
|
|
@@ -182980,6 +182994,7 @@ async function handlePublicApiCommand(ctx, spec, options) {
|
|
|
182980
182994
|
var groupDescriptions = {
|
|
182981
182995
|
run: "Trigger and manage QA Wolf runs on the platform"
|
|
182982
182996
|
};
|
|
182997
|
+
var handWrittenContractNames = new Set(["flow.list"]);
|
|
182983
182998
|
function resolveGroup(parent2, segment) {
|
|
182984
182999
|
const existing = parent2.commands.find((command) => command.name() === segment);
|
|
182985
183000
|
return existing ?? parent2.command(segment).description(groupDescriptions[segment] ?? `QA Wolf public API ${segment} commands`);
|
|
@@ -183005,7 +183020,9 @@ function registerSpec(program2, signals, spec, authDeps) {
|
|
|
183005
183020
|
command.action((options, leaf) => withAuthContext(signals, (ctx) => handlePublicApiCommand(ctx, spec, options), authDeps ?? {})(options, leaf));
|
|
183006
183021
|
}
|
|
183007
183022
|
function registerPublicApiCommands(program2, signals, options = {}) {
|
|
183008
|
-
const specs = buildCommandSpecs(options.contracts ?? publicContractsV1
|
|
183023
|
+
const specs = buildCommandSpecs(options.contracts ?? publicContractsV1, {
|
|
183024
|
+
skipContractNames: handWrittenContractNames
|
|
183025
|
+
});
|
|
183009
183026
|
for (const spec of specs) {
|
|
183010
183027
|
registerSpec(program2, signals, spec, options.authDeps);
|
|
183011
183028
|
}
|
|
@@ -183046,4 +183063,4 @@ createProgram({ signals }).parseAsync().catch(() => {
|
|
|
183046
183063
|
process.exitCode = 1;
|
|
183047
183064
|
}).finally(() => flushAndExit(typeof process.exitCode === "number" ? process.exitCode : 0));
|
|
183048
183065
|
|
|
183049
|
-
//# debugId=
|
|
183066
|
+
//# debugId=64AB4032821CC8E864756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qawolf/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Run and manage QA Wolf flows from the terminal, CI, or an AI agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@napi-rs/keyring": "1.3.0",
|
|
61
61
|
"@oxc-node/core": "0.1.0",
|
|
62
62
|
"@playwright/test": "1.60.0",
|
|
63
|
-
"@qawolf/api-contracts": "0.
|
|
63
|
+
"@qawolf/api-contracts": "0.2.0",
|
|
64
64
|
"@qawolf/emails": "1.1.1",
|
|
65
65
|
"@qawolf/flow-targets": "1.0.0",
|
|
66
66
|
"@qawolf/flows": "0.1.1",
|
|
@@ -41,7 +41,7 @@ write on timeout: it may have reached the server the first time.
|
|
|
41
41
|
| `qawolf auth logout` | local | Remove stored credentials |
|
|
42
42
|
| `qawolf auth whoami` | read | Show authentication status |
|
|
43
43
|
| `qawolf doctor` | local | Diagnose problems running flows locally |
|
|
44
|
-
| `qawolf flows list` | local (read with --remote) | List flows matching [pattern] from the local project, or from QA Wolf with --remote
|
|
44
|
+
| `qawolf flows list` | local (read with --remote) | List flows matching [pattern] from the local project, or from a QA Wolf environment with --remote |
|
|
45
45
|
| `qawolf flows pull` | read | Download an environment's flows into the local .qawolf/<env>/ cache |
|
|
46
46
|
| `qawolf flows run` | local (read with --env) | Run flows matching [pattern], or every flow when omitted; with --env, pull missing flows from that QA Wolf environment |
|
|
47
47
|
| `qawolf init` | local | Scaffold a QA Wolf project in the current directory |
|