@flowriki/agent 0.1.0-beta.43 → 0.1.0-beta.44
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/{chunk-ZMHE47A5.js → chunk-E24RRF2Q.js} +106 -82
- package/dist/cli.js +89 -1
- package/dist/engine.js +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ import os from "os";
|
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
import { spawnSync } from "child_process";
|
|
9
|
-
var AGENT_VERSION = "0.1.0-beta.
|
|
9
|
+
var AGENT_VERSION = "0.1.0-beta.44";
|
|
10
10
|
async function prepareBrowsers() {
|
|
11
11
|
if (browsersReady()) {
|
|
12
12
|
return { ok: true, already: true, message: "chromium is already installed" };
|
|
@@ -1009,6 +1009,7 @@ import { z as z5 } from "zod";
|
|
|
1009
1009
|
import { z as z6 } from "zod";
|
|
1010
1010
|
import { z as z7 } from "zod";
|
|
1011
1011
|
import { z as z8 } from "zod";
|
|
1012
|
+
import { z as z9 } from "zod";
|
|
1012
1013
|
var EngineSchema = z4.enum(["chromium", "firefox", "webkit"]);
|
|
1013
1014
|
var CapabilitySchema = z4.object({
|
|
1014
1015
|
id: z4.string(),
|
|
@@ -2046,6 +2047,29 @@ var ConversationSchema = z8.object({
|
|
|
2046
2047
|
createdAt: z8.string(),
|
|
2047
2048
|
updatedAt: z8.string()
|
|
2048
2049
|
}).strict();
|
|
2050
|
+
var IMPORT_DRAFT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2051
|
+
var ImportDraftCaseSchema = z9.object({
|
|
2052
|
+
name: z9.string().min(1).max(120),
|
|
2053
|
+
description: z9.string().max(4e3).default(""),
|
|
2054
|
+
businessSteps: z9.array(BusinessStepSchema).max(200),
|
|
2055
|
+
/** Its id or row in the file. */
|
|
2056
|
+
row: z9.string().max(200).default("")
|
|
2057
|
+
}).strict();
|
|
2058
|
+
var ImportDraftSchema = z9.object({
|
|
2059
|
+
id: z9.string().regex(/^imp_[A-Za-z0-9]+$/),
|
|
2060
|
+
projectId: z9.string().min(1),
|
|
2061
|
+
userId: z9.string().min(1),
|
|
2062
|
+
file: z9.string().max(300),
|
|
2063
|
+
/** Every sheet, every cell as text. */
|
|
2064
|
+
sheets: z9.array(z9.object({ name: z9.string().max(200), rows: z9.array(z9.array(z9.string())) }).strict()).max(200),
|
|
2065
|
+
status: z9.enum(["waiting", "converting", "done", "failed"]).default("waiting"),
|
|
2066
|
+
/** What the assistant made of it: features, each with its cases. */
|
|
2067
|
+
result: z9.array(z9.object({ feature: z9.string().min(1).max(120), cases: z9.array(ImportDraftCaseSchema) }).strict()).default([]),
|
|
2068
|
+
/** The assistant's word on anything it could not convert. */
|
|
2069
|
+
note: z9.string().max(4e3).default(""),
|
|
2070
|
+
createdAt: z9.string(),
|
|
2071
|
+
updatedAt: z9.string()
|
|
2072
|
+
}).strict();
|
|
2049
2073
|
|
|
2050
2074
|
// ../engine-playwright/dist/index.js
|
|
2051
2075
|
import { createHmac, randomBytes as randomBytes2 } from "crypto";
|
|
@@ -6970,8 +6994,8 @@ async function fieldNames(page) {
|
|
|
6970
6994
|
}
|
|
6971
6995
|
|
|
6972
6996
|
// ../results/dist/chunk-LYCTVHPR.js
|
|
6973
|
-
import { z as
|
|
6974
|
-
var RunStatusSchema =
|
|
6997
|
+
import { z as z10 } from "zod";
|
|
6998
|
+
var RunStatusSchema = z10.enum([
|
|
6975
6999
|
"queued",
|
|
6976
7000
|
"running",
|
|
6977
7001
|
"passed",
|
|
@@ -6979,7 +7003,7 @@ var RunStatusSchema = z9.enum([
|
|
|
6979
7003
|
"cancelled",
|
|
6980
7004
|
"errored"
|
|
6981
7005
|
]);
|
|
6982
|
-
var TaskStatusSchema =
|
|
7006
|
+
var TaskStatusSchema = z10.enum([
|
|
6983
7007
|
"queued",
|
|
6984
7008
|
"running",
|
|
6985
7009
|
"passed",
|
|
@@ -6988,7 +7012,7 @@ var TaskStatusSchema = z9.enum([
|
|
|
6988
7012
|
"cancelled",
|
|
6989
7013
|
"errored"
|
|
6990
7014
|
]);
|
|
6991
|
-
var FailureKindSchema =
|
|
7015
|
+
var FailureKindSchema = z10.enum([
|
|
6992
7016
|
"not_found",
|
|
6993
7017
|
"ambiguous",
|
|
6994
7018
|
"timeout",
|
|
@@ -6997,30 +7021,30 @@ var FailureKindSchema = z9.enum([
|
|
|
6997
7021
|
"crash",
|
|
6998
7022
|
"unknown"
|
|
6999
7023
|
]);
|
|
7000
|
-
var RunCheckSchema =
|
|
7001
|
-
id:
|
|
7002
|
-
assertionId:
|
|
7003
|
-
kind:
|
|
7004
|
-
expected:
|
|
7005
|
-
actual:
|
|
7006
|
-
ok:
|
|
7024
|
+
var RunCheckSchema = z10.object({
|
|
7025
|
+
id: z10.string(),
|
|
7026
|
+
assertionId: z10.string().nullable(),
|
|
7027
|
+
kind: z10.string(),
|
|
7028
|
+
expected: z10.string().nullable(),
|
|
7029
|
+
actual: z10.string().nullable(),
|
|
7030
|
+
ok: z10.boolean(),
|
|
7007
7031
|
/** A failed soft check is reported but does not fail its step, so a run can
|
|
7008
7032
|
* be green and still carry findings. Stored per check rather than derived,
|
|
7009
7033
|
* because the flow it came from can be edited afterwards and history has to
|
|
7010
7034
|
* keep saying what actually happened. */
|
|
7011
|
-
soft:
|
|
7012
|
-
detail:
|
|
7035
|
+
soft: z10.boolean().default(false),
|
|
7036
|
+
detail: z10.string().nullable()
|
|
7013
7037
|
});
|
|
7014
|
-
var RunStepSchema =
|
|
7015
|
-
id:
|
|
7016
|
-
ordinal:
|
|
7038
|
+
var RunStepSchema = z10.object({
|
|
7039
|
+
id: z10.string(),
|
|
7040
|
+
ordinal: z10.number().int().nonnegative(),
|
|
7017
7041
|
/** The STABLE document step id — this is what joins runs across time and
|
|
7018
7042
|
* makes flake-rate a view over existing columns rather than a migration. */
|
|
7019
|
-
stepId:
|
|
7020
|
-
action:
|
|
7021
|
-
targetRole:
|
|
7022
|
-
targetName:
|
|
7023
|
-
targetScope:
|
|
7043
|
+
stepId: z10.string(),
|
|
7044
|
+
action: z10.string(),
|
|
7045
|
+
targetRole: z10.string().nullable(),
|
|
7046
|
+
targetName: z10.string().nullable(),
|
|
7047
|
+
targetScope: z10.string().nullable(),
|
|
7024
7048
|
/** What the step typed, chose or pressed.
|
|
7025
7049
|
*
|
|
7026
7050
|
* A report that says `fill "Password"` and nothing else cannot tell you
|
|
@@ -7029,100 +7053,100 @@ var RunStepSchema = z9.object({
|
|
|
7029
7053
|
*
|
|
7030
7054
|
* NEVER set for a secret — see `secret` below. A run report is the thing
|
|
7031
7055
|
* people paste into a ticket. */
|
|
7032
|
-
value:
|
|
7056
|
+
value: z10.string().nullable().default(null),
|
|
7033
7057
|
/** The step typed a secret, so `value` is deliberately absent rather than
|
|
7034
7058
|
* merely unknown. Stored, because "no value" and "a value withheld" render
|
|
7035
7059
|
* differently and history has to keep saying which it was. */
|
|
7036
|
-
secret:
|
|
7037
|
-
status:
|
|
7060
|
+
secret: z10.boolean().default(false),
|
|
7061
|
+
status: z10.enum(["passed", "failed", "skipped"]),
|
|
7038
7062
|
failureKind: FailureKindSchema.nullable(),
|
|
7039
|
-
detail:
|
|
7063
|
+
detail: z10.string().nullable(),
|
|
7040
7064
|
/** WHICH WAY FOUND IT, when the first way did not.
|
|
7041
7065
|
*
|
|
7042
7066
|
* A step carries several routes to its element and takes the first that
|
|
7043
7067
|
* matches. Passing on a later one is not a failure, but it does mean the
|
|
7044
7068
|
* page has moved under the step — and a suite that repairs itself quietly
|
|
7045
7069
|
* drifts away from the application it tests. Null is the ordinary case. */
|
|
7046
|
-
foundBy:
|
|
7047
|
-
durationMs:
|
|
7070
|
+
foundBy: z10.string().nullable().default(null),
|
|
7071
|
+
durationMs: z10.number().int().nonnegative().nullable(),
|
|
7048
7072
|
/** Where the browser was when this step ran. Recorded on failure, and
|
|
7049
7073
|
* frequently the whole answer — the element is missing because a step
|
|
7050
7074
|
* before it navigated somewhere unexpected, not because it was renamed. */
|
|
7051
|
-
pageUrl:
|
|
7052
|
-
pageTitle:
|
|
7053
|
-
checks:
|
|
7075
|
+
pageUrl: z10.string().nullable().default(null),
|
|
7076
|
+
pageTitle: z10.string().nullable().default(null),
|
|
7077
|
+
checks: z10.array(RunCheckSchema).default([])
|
|
7054
7078
|
});
|
|
7055
|
-
var RunTaskSchema =
|
|
7056
|
-
id:
|
|
7057
|
-
ordinal:
|
|
7058
|
-
caseName:
|
|
7059
|
-
rowId:
|
|
7079
|
+
var RunTaskSchema = z10.object({
|
|
7080
|
+
id: z10.string(),
|
|
7081
|
+
ordinal: z10.number().int().nonnegative(),
|
|
7082
|
+
caseName: z10.string(),
|
|
7083
|
+
rowId: z10.string().nullable(),
|
|
7060
7084
|
capability: CapabilitySchema,
|
|
7061
|
-
provider:
|
|
7062
|
-
attempt:
|
|
7063
|
-
maxAttempts:
|
|
7085
|
+
provider: z10.string(),
|
|
7086
|
+
attempt: z10.number().int().positive().default(1),
|
|
7087
|
+
maxAttempts: z10.number().int().positive().default(1),
|
|
7064
7088
|
status: TaskStatusSchema,
|
|
7065
|
-
workerId:
|
|
7089
|
+
workerId: z10.string().nullable(),
|
|
7066
7090
|
/** Cloud provider's own session, so a failure is one click from their video. */
|
|
7067
|
-
sessionId:
|
|
7068
|
-
sessionUrl:
|
|
7069
|
-
detail:
|
|
7070
|
-
stepsRun:
|
|
7071
|
-
stepsTotal:
|
|
7072
|
-
durationMs:
|
|
7073
|
-
steps:
|
|
7091
|
+
sessionId: z10.string().nullable(),
|
|
7092
|
+
sessionUrl: z10.string().nullable(),
|
|
7093
|
+
detail: z10.string().nullable(),
|
|
7094
|
+
stepsRun: z10.number().int().nonnegative().default(0),
|
|
7095
|
+
stepsTotal: z10.number().int().nonnegative().default(0),
|
|
7096
|
+
durationMs: z10.number().int().nonnegative().nullable(),
|
|
7097
|
+
steps: z10.array(RunStepSchema).default([])
|
|
7074
7098
|
});
|
|
7075
|
-
var ArtifactKindSchema =
|
|
7076
|
-
var ArtifactSchema =
|
|
7077
|
-
id:
|
|
7078
|
-
runId:
|
|
7079
|
-
runStepId:
|
|
7099
|
+
var ArtifactKindSchema = z10.enum(["screenshot", "video", "trace", "console", "har"]);
|
|
7100
|
+
var ArtifactSchema = z10.object({
|
|
7101
|
+
id: z10.string(),
|
|
7102
|
+
runId: z10.string(),
|
|
7103
|
+
runStepId: z10.string().nullable(),
|
|
7080
7104
|
kind: ArtifactKindSchema,
|
|
7081
|
-
relPath:
|
|
7082
|
-
bytes:
|
|
7083
|
-
masked:
|
|
7084
|
-
createdAt:
|
|
7105
|
+
relPath: z10.string(),
|
|
7106
|
+
bytes: z10.number().int().nonnegative().nullable(),
|
|
7107
|
+
masked: z10.boolean().default(false),
|
|
7108
|
+
createdAt: z10.string()
|
|
7085
7109
|
});
|
|
7086
|
-
var RunSummarySchema =
|
|
7087
|
-
id:
|
|
7088
|
-
projectId:
|
|
7110
|
+
var RunSummarySchema = z10.object({
|
|
7111
|
+
id: z10.string(),
|
|
7112
|
+
projectId: z10.string(),
|
|
7089
7113
|
/** What the run was FOR.
|
|
7090
7114
|
*
|
|
7091
7115
|
* `flake` is a deliberate repetition of one flow to measure how often it
|
|
7092
7116
|
* passes. It is kept out of pass-rate statistics: a 98/100 flakiness check is
|
|
7093
7117
|
* a useful finding, not a failing suite, and counting it as one would make
|
|
7094
7118
|
* measuring reliability look like losing it. */
|
|
7095
|
-
kind:
|
|
7096
|
-
trigger:
|
|
7119
|
+
kind: z10.enum(["smoke", "test", "adhoc", "flake"]),
|
|
7120
|
+
trigger: z10.enum(["ui", "cli", "ci"]),
|
|
7097
7121
|
status: RunStatusSchema,
|
|
7098
|
-
flowId:
|
|
7099
|
-
flowName:
|
|
7100
|
-
gitSha:
|
|
7101
|
-
gitBranch:
|
|
7102
|
-
gitDirty:
|
|
7103
|
-
env:
|
|
7104
|
-
concurrency:
|
|
7105
|
-
tasksTotal:
|
|
7106
|
-
tasksPassed:
|
|
7107
|
-
tasksFailed:
|
|
7122
|
+
flowId: z10.string().nullable(),
|
|
7123
|
+
flowName: z10.string().nullable(),
|
|
7124
|
+
gitSha: z10.string().nullable(),
|
|
7125
|
+
gitBranch: z10.string().nullable(),
|
|
7126
|
+
gitDirty: z10.boolean().default(false),
|
|
7127
|
+
env: z10.string().nullable(),
|
|
7128
|
+
concurrency: z10.number().int().positive().nullable(),
|
|
7129
|
+
tasksTotal: z10.number().int().nonnegative().default(0),
|
|
7130
|
+
tasksPassed: z10.number().int().nonnegative().default(0),
|
|
7131
|
+
tasksFailed: z10.number().int().nonnegative().default(0),
|
|
7108
7132
|
/** Rolled up from the run's tasks rather than stored on the run, so they
|
|
7109
7133
|
* cannot drift from the step rows they describe. "9 of 12" in a list is
|
|
7110
7134
|
* what tells a reader where a run died; "1 of 1 tasks" tells them nothing
|
|
7111
7135
|
* until there is more than one browser in play. */
|
|
7112
|
-
stepsRun:
|
|
7113
|
-
stepsTotal:
|
|
7114
|
-
queuedAt:
|
|
7115
|
-
startedAt:
|
|
7116
|
-
finishedAt:
|
|
7117
|
-
durationMs:
|
|
7136
|
+
stepsRun: z10.number().int().nonnegative().default(0),
|
|
7137
|
+
stepsTotal: z10.number().int().nonnegative().default(0),
|
|
7138
|
+
queuedAt: z10.string(),
|
|
7139
|
+
startedAt: z10.string().nullable(),
|
|
7140
|
+
finishedAt: z10.string().nullable(),
|
|
7141
|
+
durationMs: z10.number().int().nonnegative().nullable()
|
|
7118
7142
|
});
|
|
7119
7143
|
var RunDetailSchema = RunSummarySchema.extend({
|
|
7120
|
-
errorMessage:
|
|
7121
|
-
artifactsDir:
|
|
7122
|
-
tasks:
|
|
7144
|
+
errorMessage: z10.string().nullable(),
|
|
7145
|
+
artifactsDir: z10.string().nullable(),
|
|
7146
|
+
tasks: z10.array(RunTaskSchema).default([]),
|
|
7123
7147
|
/** Screenshots and the like, addressed by `runStepId`. Kept flat rather than
|
|
7124
7148
|
* nested inside each step: an artifact can belong to the run as a whole. */
|
|
7125
|
-
artifacts:
|
|
7149
|
+
artifacts: z10.array(ArtifactSchema).default([]),
|
|
7126
7150
|
/** The document as it was executed — a flow, or a test case with the copies
|
|
7127
7151
|
* it held that day.
|
|
7128
7152
|
*
|
|
@@ -7131,7 +7155,7 @@ var RunDetailSchema = RunSummarySchema.extend({
|
|
|
7131
7155
|
* edited, and without surfacing it the promise was only half kept: the bytes
|
|
7132
7156
|
* were there and nothing could reach them. Null for runs recorded before a
|
|
7133
7157
|
* snapshot was taken. */
|
|
7134
|
-
flowSnapshot:
|
|
7158
|
+
flowSnapshot: z10.unknown().nullable().default(null)
|
|
7135
7159
|
});
|
|
7136
7160
|
|
|
7137
7161
|
// ../results/dist/chunk-IW3PJWP6.js
|
package/dist/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
runtimeValue,
|
|
24
24
|
start,
|
|
25
25
|
status
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-E24RRF2Q.js";
|
|
27
27
|
|
|
28
28
|
// src/cli.ts
|
|
29
29
|
import { parseArgs } from "util";
|
|
@@ -219,6 +219,17 @@ var ServiceClient = class {
|
|
|
219
219
|
return this.call(`/api/agent/library?${query}`);
|
|
220
220
|
}
|
|
221
221
|
/** Test cases written, edited or linked in one commit; duplicates skipped. */
|
|
222
|
+
importPart(projectId, draftId, part) {
|
|
223
|
+
return this.call(
|
|
224
|
+
`/api/agent/import-drafts/${encodeURIComponent(draftId)}?projectId=${encodeURIComponent(projectId)}&part=${part}`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
saveImportCases(projectId, draftId, body) {
|
|
228
|
+
return this.call(
|
|
229
|
+
`/api/agent/import-drafts/${encodeURIComponent(draftId)}/cases?projectId=${encodeURIComponent(projectId)}`,
|
|
230
|
+
{ method: "POST", body: JSON.stringify(body) }
|
|
231
|
+
);
|
|
232
|
+
}
|
|
222
233
|
readCases(projectId, refs) {
|
|
223
234
|
const ids = refs.filter((r) => /^tc_/.test(r.trim()));
|
|
224
235
|
const names = refs.filter((r) => !/^tc_/.test(r.trim()));
|
|
@@ -894,6 +905,16 @@ as learned. Keep what you learn with write_knowledge (features/<name>.md,
|
|
|
894
905
|
memory/decisions.md, a session summary), on Claude's branch for review \u2014
|
|
895
906
|
never a password, key or token.
|
|
896
907
|
|
|
908
|
+
CONVERTING A SPREADSHEET: when asked to convert an import (imp_\u2026), read
|
|
909
|
+
every part with read_import_file, then save_import_cases in batches. Group
|
|
910
|
+
cases into features by product area (a sheet or section usually is one). Each
|
|
911
|
+
case is one scenario: name it after what it proves. Steps: preconditions and
|
|
912
|
+
setup as Given; ONE action per When / And \u2014 split steps that do several
|
|
913
|
+
things; each expected result as Then / And, after the action it follows.
|
|
914
|
+
Keep every case and every step's meaning, and its id from the file in row;
|
|
915
|
+
never invent a step or drop one. Rows that are not test cases (titles,
|
|
916
|
+
notes, empty) are left out. Say in note what you could not convert.
|
|
917
|
+
|
|
897
918
|
HOW TO WORK:
|
|
898
919
|
1. Call project_catalog. Reuse what exists \u2014 published, and on Claude's working
|
|
899
920
|
branch \u2014 rather than writing it again.
|
|
@@ -1313,6 +1334,73 @@ ${page}`);
|
|
|
1313
1334
|
return text(out);
|
|
1314
1335
|
}
|
|
1315
1336
|
},
|
|
1337
|
+
{
|
|
1338
|
+
name: "read_import_file",
|
|
1339
|
+
title: "Read a spreadsheet waiting to be converted",
|
|
1340
|
+
description: "Read one part of a spreadsheet the person is importing (its id is imp_\u2026): every sheet's rows, each as a JSON array of its cells, numbered as the spreadsheet numbers them. Part 1 says how many parts there are; read every one.",
|
|
1341
|
+
inputSchema: {
|
|
1342
|
+
type: "object",
|
|
1343
|
+
properties: { projectId: { type: "string" }, file: { type: "string", description: "The import's id, imp_\u2026" }, part: { type: "number", description: "Which part, from 1." } },
|
|
1344
|
+
required: ["file", "part"],
|
|
1345
|
+
additionalProperties: false
|
|
1346
|
+
},
|
|
1347
|
+
annotations: { readOnlyHint: true },
|
|
1348
|
+
run: async (args) => {
|
|
1349
|
+
const projectId = await projectFor(args["projectId"]);
|
|
1350
|
+
const got = await service.importPart(projectId, str(args["file"]) ?? "", Number(args["part"] ?? 1));
|
|
1351
|
+
return text(`${got.file} \u2014 part ${got.part} of ${got.of}${got.part < got.of ? " (read the rest too)" : " (the last)"}
|
|
1352
|
+
|
|
1353
|
+
${got.text}`);
|
|
1354
|
+
}
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
name: "save_import_cases",
|
|
1358
|
+
title: "Save the test cases a spreadsheet becomes",
|
|
1359
|
+
description: "Save test cases converted from a spreadsheet being imported (its id is imp_\u2026), in batches as you go: features, each with cases \u2014 name (the scenario it proves), steps as Given / When / Then / And lines, row (its id or row in the file), description (optional). They are shown to the person to import; nothing is written to the project until they do. done: true with the last batch; note: anything you could not convert, and why. restart: true replaces what was saved before.",
|
|
1360
|
+
inputSchema: {
|
|
1361
|
+
type: "object",
|
|
1362
|
+
properties: {
|
|
1363
|
+
projectId: { type: "string" },
|
|
1364
|
+
file: { type: "string", description: "The import's id, imp_\u2026" },
|
|
1365
|
+
features: {
|
|
1366
|
+
type: "array",
|
|
1367
|
+
items: {
|
|
1368
|
+
type: "object",
|
|
1369
|
+
properties: {
|
|
1370
|
+
feature: { type: "string" },
|
|
1371
|
+
cases: {
|
|
1372
|
+
type: "array",
|
|
1373
|
+
items: {
|
|
1374
|
+
type: "object",
|
|
1375
|
+
properties: { name: { type: "string" }, description: { type: "string" }, steps: { type: "array", items: { type: "string" } }, row: { type: "string" } },
|
|
1376
|
+
required: ["name", "steps"],
|
|
1377
|
+
additionalProperties: false
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
},
|
|
1381
|
+
required: ["feature", "cases"],
|
|
1382
|
+
additionalProperties: false
|
|
1383
|
+
}
|
|
1384
|
+
},
|
|
1385
|
+
done: { type: "boolean" },
|
|
1386
|
+
note: { type: "string" },
|
|
1387
|
+
restart: { type: "boolean" }
|
|
1388
|
+
},
|
|
1389
|
+
required: ["file", "features"],
|
|
1390
|
+
additionalProperties: false
|
|
1391
|
+
},
|
|
1392
|
+
run: async (args) => {
|
|
1393
|
+
const projectId = await projectFor(args["projectId"]);
|
|
1394
|
+
const features = Array.isArray(args["features"]) ? args["features"] : [];
|
|
1395
|
+
const saved = await service.saveImportCases(projectId, str(args["file"]) ?? "", {
|
|
1396
|
+
features,
|
|
1397
|
+
...args["done"] === true ? { done: true } : {},
|
|
1398
|
+
...typeof args["note"] === "string" ? { note: args["note"] } : {},
|
|
1399
|
+
...args["restart"] === true ? { restart: true } : {}
|
|
1400
|
+
});
|
|
1401
|
+
return text(`Saved ${saved.added} more \u2014 ${saved.total} test cases so far.${saved.done ? " Done: the person can now look them over and import them." : " Keep going, and pass done: true with the last batch."}`);
|
|
1402
|
+
}
|
|
1403
|
+
},
|
|
1316
1404
|
{
|
|
1317
1405
|
name: "read_test_cases",
|
|
1318
1406
|
title: "Read test cases",
|
package/dist/engine.js
CHANGED
package/package.json
CHANGED