@hasna/testers 0.0.52 → 0.0.54
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/README.md +21 -0
- package/dist/cli/index.js +155 -3
- package/dist/lib/next-route-inventory.d.ts +6 -0
- package/dist/lib/next-route-inventory.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,6 +43,27 @@ testers workflow fanout wf_abc,wf_def wf_xyz --workers 12 --url https://preview.
|
|
|
43
43
|
|
|
44
44
|
`--workers` is bounded to 1-12 concurrent sandboxes. Fanout preflights provider credentials, required sandbox environment references, `rsync`, and app source directories before launching workers. Use `--dry-run` to inspect the remote commands, upload plans, and preflight checks without spawning sandboxes.
|
|
45
45
|
|
|
46
|
+
### Next.js Route and Action Inventory
|
|
47
|
+
|
|
48
|
+
For large apps, generate source-derived route coverage from the Next.js app directory. The importer can create route-level scenarios and one scenario per discovered link, button, form, input, or API method, then group those action scenarios into sandbox workflows for fanout.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
testers inventory next /path/to/app \
|
|
52
|
+
--project alumia \
|
|
53
|
+
--create-scenarios \
|
|
54
|
+
--create-action-scenarios \
|
|
55
|
+
--create-workflows \
|
|
56
|
+
--create-action-workflows \
|
|
57
|
+
--action-workflow-grouping route \
|
|
58
|
+
--sandbox-provider e2b \
|
|
59
|
+
--sandbox-sync rsync \
|
|
60
|
+
--sandbox-env-optional OPENAI_API_KEY
|
|
61
|
+
|
|
62
|
+
testers workflow fanout --project alumia --tag next-action --workers 6 --url https://preview.example.com --dry-run
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use `--action-workflow-grouping route` for route-specific workflows or `--action-workflow-grouping area-kind` for broader workflows such as commerce buttons or admin API methods.
|
|
66
|
+
|
|
46
67
|
### Common Flags
|
|
47
68
|
|
|
48
69
|
- `--json --output results.json` — write structured results to a file for downstream tooling.
|
package/dist/cli/index.js
CHANGED
|
@@ -59331,6 +59331,7 @@ var init_openapi_import = __esm(() => {
|
|
|
59331
59331
|
// src/lib/next-route-inventory.ts
|
|
59332
59332
|
var exports_next_route_inventory = {};
|
|
59333
59333
|
__export(exports_next_route_inventory, {
|
|
59334
|
+
scenarioInputsForNextRouteActions: () => scenarioInputsForNextRouteActions,
|
|
59334
59335
|
scenarioInputForNextRoute: () => scenarioInputForNextRoute,
|
|
59335
59336
|
importNextRouteInventory: () => importNextRouteInventory,
|
|
59336
59337
|
discoverNextRouteInventory: () => discoverNextRouteInventory
|
|
@@ -59355,6 +59356,7 @@ function discoverNextRouteInventory(options) {
|
|
|
59355
59356
|
pages: items.filter((item) => item.kind === "page").length,
|
|
59356
59357
|
apiRoutes: items.filter((item) => item.kind === "api").length,
|
|
59357
59358
|
dynamic: items.filter((item) => item.dynamic).length,
|
|
59359
|
+
actions: items.reduce((sum, item) => sum + item.actions.length, 0),
|
|
59358
59360
|
categories,
|
|
59359
59361
|
items
|
|
59360
59362
|
};
|
|
@@ -59410,12 +59412,69 @@ function scenarioInputForNextRoute(item, projectId) {
|
|
|
59410
59412
|
projectId
|
|
59411
59413
|
};
|
|
59412
59414
|
}
|
|
59415
|
+
function scenarioInputsForNextRouteActions(item, projectId) {
|
|
59416
|
+
return item.actions.map((action, index) => scenarioInputForNextRouteAction(item, action, index, projectId));
|
|
59417
|
+
}
|
|
59418
|
+
function scenarioInputForNextRouteAction(item, action, index, projectId) {
|
|
59419
|
+
const label = item.kind === "page" ? "page action" : "API action";
|
|
59420
|
+
const fixtureStep = item.fixtureParams.length > 0 ? `Bind dynamic fixture values for ${item.fixtureParams.map((name) => `:${name}`).join(", ")} before exercising this action.` : undefined;
|
|
59421
|
+
const dynamicStep = item.dynamic ? "Substitute dynamic path parameters with valid fixture values from the target org before opening or calling the route." : undefined;
|
|
59422
|
+
const destructiveGuard = action.destructive ? "If the action reaches a destructive confirmation or mutating final step, verify the warning/cancel path and stop before confirming." : undefined;
|
|
59423
|
+
const pageSteps = [
|
|
59424
|
+
fixtureStep,
|
|
59425
|
+
dynamicStep,
|
|
59426
|
+
`Open the Next.js page ${item.routePath}.`,
|
|
59427
|
+
"Wait for the route to finish loading and verify it does not show a blank shell, framework error page, or unexpected auth loop.",
|
|
59428
|
+
`Locate source-discovered ${action.kind} "${action.label}" from ${action.sourceFile}.`,
|
|
59429
|
+
formatActionStep(action),
|
|
59430
|
+
destructiveGuard,
|
|
59431
|
+
action.kind === "input" ? "Fill the input with safe test data and verify the UI accepts, validates, or rejects it predictably." : "Verify the action produces the expected navigation, modal, toast, table change, validation state, or disabled state.",
|
|
59432
|
+
"Verify the route stays within the expected org/workspace context and does not emit console errors."
|
|
59433
|
+
].filter(Boolean);
|
|
59434
|
+
const apiSteps = [
|
|
59435
|
+
fixtureStep,
|
|
59436
|
+
dynamicStep,
|
|
59437
|
+
`Call ${action.label} ${item.routePath} using safe fixture data.`,
|
|
59438
|
+
action.destructive ? "Use a harmless dry-run/no-op fixture when available; otherwise verify authentication, authorization, validation, or confirmation blocks without creating destructive side effects." : "Verify the method accepts valid safe input and rejects invalid input with a stable response shape.",
|
|
59439
|
+
"Verify expected authentication, authorization, validation, and tenant isolation behavior.",
|
|
59440
|
+
"Verify response status, JSON shape, and error messages are stable and regression-safe."
|
|
59441
|
+
].filter(Boolean);
|
|
59442
|
+
return {
|
|
59443
|
+
name: `Next ${label}: ${item.routePath} :: ${action.kind} ${action.label} #${index + 1}`,
|
|
59444
|
+
description: `Source-discovered ${label} ${index + 1} from ${action.sourceFile}. Verify ${action.kind} "${action.label}" on ${item.routePath}.`,
|
|
59445
|
+
steps: item.kind === "page" ? pageSteps : apiSteps,
|
|
59446
|
+
tags: actionTagsForRoute(item, action),
|
|
59447
|
+
priority: action.destructive ? "critical" : item.priority,
|
|
59448
|
+
targetPath: item.routePath,
|
|
59449
|
+
requiresAuth: item.requiresAuth,
|
|
59450
|
+
assertions: item.kind === "page" ? SAFE_PAGE_ASSERTIONS : [],
|
|
59451
|
+
metadata: {
|
|
59452
|
+
source: "next-route-action-inventory",
|
|
59453
|
+
routeFile: item.file,
|
|
59454
|
+
routeKind: item.kind,
|
|
59455
|
+
routePath: item.routePath,
|
|
59456
|
+
category: item.category,
|
|
59457
|
+
methods: item.methods,
|
|
59458
|
+
dynamic: item.dynamic,
|
|
59459
|
+
fixtureParams: item.fixtureParams,
|
|
59460
|
+
actionIndex: index,
|
|
59461
|
+
action,
|
|
59462
|
+
groups: item.groups
|
|
59463
|
+
},
|
|
59464
|
+
parameters: item.fixtureParams.length > 0 ? {
|
|
59465
|
+
routeFixtures: defaultRouteFixturesForParams(item.fixtureParams),
|
|
59466
|
+
routeFixtureParams: item.fixtureParams
|
|
59467
|
+
} : undefined,
|
|
59468
|
+
projectId
|
|
59469
|
+
};
|
|
59470
|
+
}
|
|
59413
59471
|
function importNextRouteInventory(options) {
|
|
59414
59472
|
const inventory = discoverNextRouteInventory(options);
|
|
59415
59473
|
let created = 0;
|
|
59416
59474
|
let updated = 0;
|
|
59417
59475
|
let deduped = 0;
|
|
59418
59476
|
const scenarios = [];
|
|
59477
|
+
const actionScenarios = [];
|
|
59419
59478
|
const workflows = [];
|
|
59420
59479
|
if (options.createScenarios) {
|
|
59421
59480
|
for (const item of inventory.items) {
|
|
@@ -59429,10 +59488,28 @@ function importNextRouteInventory(options) {
|
|
|
59429
59488
|
deduped++;
|
|
59430
59489
|
}
|
|
59431
59490
|
}
|
|
59491
|
+
if (options.createActionScenarios) {
|
|
59492
|
+
for (const item of inventory.items) {
|
|
59493
|
+
for (const input of scenarioInputsForNextRouteActions(item, options.projectId)) {
|
|
59494
|
+
const result = upsertScenario(input);
|
|
59495
|
+
scenarios.push(result.scenario);
|
|
59496
|
+
actionScenarios.push(result.scenario);
|
|
59497
|
+
if (result.action === "created")
|
|
59498
|
+
created++;
|
|
59499
|
+
else if (result.action === "updated")
|
|
59500
|
+
updated++;
|
|
59501
|
+
else
|
|
59502
|
+
deduped++;
|
|
59503
|
+
}
|
|
59504
|
+
}
|
|
59505
|
+
}
|
|
59432
59506
|
if (options.createWorkflows) {
|
|
59433
59507
|
workflows.push(...upsertRouteInventoryWorkflows(inventory, options));
|
|
59434
59508
|
}
|
|
59435
|
-
|
|
59509
|
+
if (options.createActionWorkflows) {
|
|
59510
|
+
workflows.push(...upsertRouteInventoryActionWorkflows(inventory, options));
|
|
59511
|
+
}
|
|
59512
|
+
return { inventory, created, updated, deduped, scenarios, actionScenarios, workflows };
|
|
59436
59513
|
}
|
|
59437
59514
|
function upsertRouteInventoryWorkflows(inventory, options) {
|
|
59438
59515
|
const workflows = [];
|
|
@@ -59462,6 +59539,57 @@ function upsertRouteInventoryWorkflows(inventory, options) {
|
|
|
59462
59539
|
}
|
|
59463
59540
|
return workflows;
|
|
59464
59541
|
}
|
|
59542
|
+
function upsertRouteInventoryActionWorkflows(inventory, options) {
|
|
59543
|
+
const workflows = [];
|
|
59544
|
+
const grouping = options.actionWorkflowGrouping ?? "route";
|
|
59545
|
+
const existingWorkflows = listTestingWorkflows({ projectId: options.projectId, enabled: undefined });
|
|
59546
|
+
if (grouping === "area-kind") {
|
|
59547
|
+
const keys = new Set;
|
|
59548
|
+
for (const item of inventory.items) {
|
|
59549
|
+
for (const action of item.actions) {
|
|
59550
|
+
keys.add(`${item.category}|${action.kind}`);
|
|
59551
|
+
}
|
|
59552
|
+
}
|
|
59553
|
+
for (const key of [...keys].sort()) {
|
|
59554
|
+
const [category, actionKind] = key.split("|");
|
|
59555
|
+
const name = `Next action inventory ${category} ${actionKind}`;
|
|
59556
|
+
const scenarioTags = ["next-action", `area:${category}`, `action:${actionKind}`];
|
|
59557
|
+
workflows.push(upsertTestingWorkflow(existingWorkflows, name, {
|
|
59558
|
+
name,
|
|
59559
|
+
description: `Source-discovered ${actionKind} action coverage for ${category} routes.`,
|
|
59560
|
+
projectId: options.projectId,
|
|
59561
|
+
scenarioFilter: { tags: scenarioTags },
|
|
59562
|
+
execution: workflowExecutionFromOptions(options)
|
|
59563
|
+
}));
|
|
59564
|
+
}
|
|
59565
|
+
return workflows;
|
|
59566
|
+
}
|
|
59567
|
+
for (const item of inventory.items.filter((route) => route.actions.length > 0)) {
|
|
59568
|
+
const name = `Next action inventory ${item.kind} ${item.routePath}`;
|
|
59569
|
+
const scenarioTags = ["next-action", `route:${item.kind}`, `route-path:${item.routePath}`];
|
|
59570
|
+
workflows.push(upsertTestingWorkflow(existingWorkflows, name, {
|
|
59571
|
+
name,
|
|
59572
|
+
description: `Source-discovered action coverage for ${item.kind} route ${item.routePath}.`,
|
|
59573
|
+
projectId: options.projectId,
|
|
59574
|
+
scenarioFilter: { tags: scenarioTags },
|
|
59575
|
+
execution: workflowExecutionFromOptions(options)
|
|
59576
|
+
}));
|
|
59577
|
+
}
|
|
59578
|
+
return workflows;
|
|
59579
|
+
}
|
|
59580
|
+
function workflowExecutionFromOptions(options) {
|
|
59581
|
+
return {
|
|
59582
|
+
target: options.workflowTarget ?? "sandbox",
|
|
59583
|
+
provider: options.workflowProvider,
|
|
59584
|
+
sandboxCleanup: "delete",
|
|
59585
|
+
sandboxSyncStrategy: "rsync",
|
|
59586
|
+
...options.workflowExecution
|
|
59587
|
+
};
|
|
59588
|
+
}
|
|
59589
|
+
function upsertTestingWorkflow(existingWorkflows, name, input) {
|
|
59590
|
+
const existing = existingWorkflows.find((workflow) => workflow.name === name);
|
|
59591
|
+
return existing ? updateTestingWorkflow(existing.id, input) : createTestingWorkflow(input);
|
|
59592
|
+
}
|
|
59465
59593
|
function resolveAppDir(rootDir, appDir) {
|
|
59466
59594
|
const candidates = appDir ? [resolve3(rootDir, appDir)] : [
|
|
59467
59595
|
join20(rootDir, "packages", "web", "app"),
|
|
@@ -59792,6 +59920,19 @@ function tagsForRoute(input) {
|
|
|
59792
59920
|
tags.add("api");
|
|
59793
59921
|
return [...tags];
|
|
59794
59922
|
}
|
|
59923
|
+
function actionTagsForRoute(item, action) {
|
|
59924
|
+
const tags = new Set([
|
|
59925
|
+
...item.tags,
|
|
59926
|
+
"next-action",
|
|
59927
|
+
`action:${action.kind}`,
|
|
59928
|
+
`route-path:${item.routePath}`
|
|
59929
|
+
]);
|
|
59930
|
+
if (action.destructive)
|
|
59931
|
+
tags.add("destructive-action");
|
|
59932
|
+
if (action.requiresFixture)
|
|
59933
|
+
tags.add("fixture-required");
|
|
59934
|
+
return [...tags];
|
|
59935
|
+
}
|
|
59795
59936
|
function priorityForRoute(routePath, category, kind) {
|
|
59796
59937
|
if (category === "auth")
|
|
59797
59938
|
return "critical";
|
|
@@ -95410,7 +95551,7 @@ import chalk6 from "chalk";
|
|
|
95410
95551
|
// package.json
|
|
95411
95552
|
var package_default = {
|
|
95412
95553
|
name: "@hasna/testers",
|
|
95413
|
-
version: "0.0.
|
|
95554
|
+
version: "0.0.54",
|
|
95414
95555
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
95415
95556
|
type: "module",
|
|
95416
95557
|
main: "dist/index.js",
|
|
@@ -101035,7 +101176,7 @@ Imported ${imported} scenarios from API spec:`));
|
|
|
101035
101176
|
}
|
|
101036
101177
|
});
|
|
101037
101178
|
var inventoryCmd = program2.command("inventory").description("Discover source-derived app route/action inventories");
|
|
101038
|
-
inventoryCmd.command("next [root]").description("Discover Next.js app routes and optionally import route coverage scenarios").option("--app-dir <path>", "Next.js app directory relative to root (default: packages/web/app or app)").option("--project <id>", "Project ID").option("--no-pages", "Do not include page.tsx/page.ts routes").option("--no-api", "Do not include route.ts/route.js API routes").option("--limit <n>", "Limit discovered routes").option("--create-scenarios", "Upsert source-derived route coverage scenarios", false).option("--create-workflows", "Upsert grouped workflows by area and route kind", false).option("--workflow-target <target>", "Workflow execution target: local or sandbox", "sandbox").option("--sandbox-provider <provider>", "Sandbox provider for created workflows", "e2b").option("--sandbox-cleanup <mode>", "Sandbox cleanup mode: delete, stop, or keep", "delete").option("--sandbox-sync <strategy>", "Sandbox upload sync strategy: rsync or archive", "rsync").option("--sandbox-env-optional <name>", "Optional sandbox env var; forwards host NAME only when set (repeatable)", (val, acc) => {
|
|
101179
|
+
inventoryCmd.command("next [root]").description("Discover Next.js app routes and optionally import route coverage scenarios").option("--app-dir <path>", "Next.js app directory relative to root (default: packages/web/app or app)").option("--project <id>", "Project ID").option("--no-pages", "Do not include page.tsx/page.ts routes").option("--no-api", "Do not include route.ts/route.js API routes").option("--limit <n>", "Limit discovered routes").option("--create-scenarios", "Upsert source-derived route coverage scenarios", false).option("--create-action-scenarios", "Upsert one source-derived scenario per discovered page/API action", false).option("--create-workflows", "Upsert grouped workflows by area and route kind", false).option("--create-action-workflows", "Upsert action-focused workflows for discovered action scenarios", false).option("--action-workflow-grouping <mode>", "Action workflow grouping: route or area-kind", "route").option("--workflow-target <target>", "Workflow execution target: local or sandbox", "sandbox").option("--sandbox-provider <provider>", "Sandbox provider for created workflows", "e2b").option("--sandbox-cleanup <mode>", "Sandbox cleanup mode: delete, stop, or keep", "delete").option("--sandbox-sync <strategy>", "Sandbox upload sync strategy: rsync or archive", "rsync").option("--sandbox-env-optional <name>", "Optional sandbox env var; forwards host NAME only when set (repeatable)", (val, acc) => {
|
|
101039
101180
|
acc.push(val);
|
|
101040
101181
|
return acc;
|
|
101041
101182
|
}, []).option("--timeout <ms>", "Workflow timeout in milliseconds").option("--json", "Output as JSON", false).action(async (root, opts) => {
|
|
@@ -101043,6 +101184,9 @@ inventoryCmd.command("next [root]").description("Discover Next.js app routes and
|
|
|
101043
101184
|
const { importNextRouteInventory: importNextRouteInventory2 } = await Promise.resolve().then(() => (init_next_route_inventory(), exports_next_route_inventory));
|
|
101044
101185
|
const projectId = resolveProject2(opts.project) ?? undefined;
|
|
101045
101186
|
const env = parseSandboxEnv(undefined, opts.sandboxEnvOptional);
|
|
101187
|
+
if (!["route", "area-kind"].includes(opts.actionWorkflowGrouping)) {
|
|
101188
|
+
throw new Error("--action-workflow-grouping must be route or area-kind");
|
|
101189
|
+
}
|
|
101046
101190
|
const result = importNextRouteInventory2({
|
|
101047
101191
|
rootDir: root ?? process.cwd(),
|
|
101048
101192
|
appDir: opts.appDir,
|
|
@@ -101051,7 +101195,10 @@ inventoryCmd.command("next [root]").description("Discover Next.js app routes and
|
|
|
101051
101195
|
includeApi: opts.api !== false,
|
|
101052
101196
|
limit: opts.limit ? parseInt(opts.limit, 10) : undefined,
|
|
101053
101197
|
createScenarios: opts.createScenarios,
|
|
101198
|
+
createActionScenarios: opts.createActionScenarios,
|
|
101054
101199
|
createWorkflows: opts.createWorkflows,
|
|
101200
|
+
createActionWorkflows: opts.createActionWorkflows,
|
|
101201
|
+
actionWorkflowGrouping: opts.actionWorkflowGrouping,
|
|
101055
101202
|
workflowTarget: opts.workflowTarget,
|
|
101056
101203
|
workflowProvider: opts.workflowTarget === "sandbox" ? opts.sandboxProvider : undefined,
|
|
101057
101204
|
workflowExecution: {
|
|
@@ -101073,6 +101220,7 @@ inventoryCmd.command("next [root]").description("Discover Next.js app routes and
|
|
|
101073
101220
|
log(chalk6.dim(` App: ${result.inventory.appDir}`));
|
|
101074
101221
|
log("");
|
|
101075
101222
|
log(` Routes: ${chalk6.cyan(String(result.inventory.total))} (${result.inventory.pages} pages, ${result.inventory.apiRoutes} API, ${result.inventory.dynamic} dynamic)`);
|
|
101223
|
+
log(` Actions: ${chalk6.cyan(String(result.inventory.actions))}`);
|
|
101076
101224
|
log(` Scenarios: ${chalk6.green(String(result.created))} created, ${chalk6.yellow(String(result.updated))} updated, ${chalk6.dim(String(result.deduped))} deduped`);
|
|
101077
101225
|
log(` Workflows: ${result.workflows.length}`);
|
|
101078
101226
|
log("");
|
|
@@ -101082,8 +101230,12 @@ inventoryCmd.command("next [root]").description("Discover Next.js app routes and
|
|
|
101082
101230
|
log("");
|
|
101083
101231
|
if (!opts.createScenarios)
|
|
101084
101232
|
log(chalk6.dim(" Add --create-scenarios to upsert route scenarios."));
|
|
101233
|
+
if (!opts.createActionScenarios)
|
|
101234
|
+
log(chalk6.dim(" Add --create-action-scenarios to upsert one scenario per discovered action."));
|
|
101085
101235
|
if (!opts.createWorkflows)
|
|
101086
101236
|
log(chalk6.dim(" Add --create-workflows to upsert grouped workflows."));
|
|
101237
|
+
if (!opts.createActionWorkflows)
|
|
101238
|
+
log(chalk6.dim(" Add --create-action-workflows to upsert action-focused workflows."));
|
|
101087
101239
|
log("");
|
|
101088
101240
|
} catch (error40) {
|
|
101089
101241
|
logError(chalk6.red(`Error: ${error40 instanceof Error ? error40.message : String(error40)}`));
|
|
@@ -30,6 +30,7 @@ export interface NextRouteInventory {
|
|
|
30
30
|
pages: number;
|
|
31
31
|
apiRoutes: number;
|
|
32
32
|
dynamic: number;
|
|
33
|
+
actions: number;
|
|
33
34
|
categories: Record<string, number>;
|
|
34
35
|
items: NextRouteInventoryItem[];
|
|
35
36
|
}
|
|
@@ -41,7 +42,10 @@ export interface ImportNextRouteInventoryOptions {
|
|
|
41
42
|
includeApi?: boolean;
|
|
42
43
|
limit?: number;
|
|
43
44
|
createScenarios?: boolean;
|
|
45
|
+
createActionScenarios?: boolean;
|
|
44
46
|
createWorkflows?: boolean;
|
|
47
|
+
createActionWorkflows?: boolean;
|
|
48
|
+
actionWorkflowGrouping?: "route" | "area-kind";
|
|
45
49
|
workflowTarget?: "local" | "sandbox";
|
|
46
50
|
workflowProvider?: string;
|
|
47
51
|
workflowExecution?: Partial<WorkflowExecutionInput>;
|
|
@@ -52,6 +56,7 @@ export interface ImportNextRouteInventoryResult {
|
|
|
52
56
|
updated: number;
|
|
53
57
|
deduped: number;
|
|
54
58
|
scenarios: Scenario[];
|
|
59
|
+
actionScenarios: Scenario[];
|
|
55
60
|
workflows: TestingWorkflow[];
|
|
56
61
|
}
|
|
57
62
|
export declare function discoverNextRouteInventory(options: {
|
|
@@ -62,5 +67,6 @@ export declare function discoverNextRouteInventory(options: {
|
|
|
62
67
|
limit?: number;
|
|
63
68
|
}): NextRouteInventory;
|
|
64
69
|
export declare function scenarioInputForNextRoute(item: NextRouteInventoryItem, projectId?: string): CreateScenarioInput;
|
|
70
|
+
export declare function scenarioInputsForNextRouteActions(item: NextRouteInventoryItem, projectId?: string): CreateScenarioInput[];
|
|
65
71
|
export declare function importNextRouteInventory(options: ImportNextRouteInventoryOptions): ImportNextRouteInventoryResult;
|
|
66
72
|
//# sourceMappingURL=next-route-inventory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next-route-inventory.d.ts","sourceRoot":"","sources":["../../src/lib/next-route-inventory.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,mBAAmB,EACnB,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,KAAK,CAAC;AAC3C,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,CAAC;AAEtF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,kBAAkB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AAkCD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"next-route-inventory.d.ts","sourceRoot":"","sources":["../../src/lib/next-route-inventory.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "@hasna/testers",
|
|
55
|
-
version: "0.0.
|
|
55
|
+
version: "0.0.54",
|
|
56
56
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
57
57
|
type: "module",
|
|
58
58
|
main: "dist/index.js",
|
package/dist/server/index.js
CHANGED
|
@@ -47090,7 +47090,7 @@ import { join as join14 } from "path";
|
|
|
47090
47090
|
// package.json
|
|
47091
47091
|
var package_default = {
|
|
47092
47092
|
name: "@hasna/testers",
|
|
47093
|
-
version: "0.0.
|
|
47093
|
+
version: "0.0.54",
|
|
47094
47094
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
47095
47095
|
type: "module",
|
|
47096
47096
|
main: "dist/index.js",
|