@swmansion/argent 0.22.1-next.4 → 0.22.1-next.6
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-cmds.mjs +26 -10
- package/dist/installer.mjs +1 -1
- package/dist/mcp-server.mjs +7 -1
- package/dist/tool-server.cjs +257 -24
- package/package.json +1 -1
package/dist/cli-cmds.mjs
CHANGED
|
@@ -2675,11 +2675,13 @@ async function applyClientFileDirectives(result) {
|
|
|
2675
2675
|
var ToolInvocationError = class extends Error {
|
|
2676
2676
|
errorCode;
|
|
2677
2677
|
errorKind;
|
|
2678
|
+
issues;
|
|
2678
2679
|
constructor(message, signal) {
|
|
2679
2680
|
super(message);
|
|
2680
2681
|
this.name = "ToolInvocationError";
|
|
2681
2682
|
this.errorCode = signal?.errorCode;
|
|
2682
2683
|
this.errorKind = signal?.errorKind;
|
|
2684
|
+
this.issues = signal?.issues;
|
|
2683
2685
|
}
|
|
2684
2686
|
};
|
|
2685
2687
|
function authHeaders2(token) {
|
|
@@ -2727,6 +2729,10 @@ async function consumeToolStream(body, onProgress) {
|
|
|
2727
2729
|
const { result: data } = await applyClientFileDirectives(final.data);
|
|
2728
2730
|
return { data, note: final.note };
|
|
2729
2731
|
}
|
|
2732
|
+
function errorBodyMessage(body) {
|
|
2733
|
+
if (Array.isArray(body.issues) && typeof body.message === "string") return body.message;
|
|
2734
|
+
return body.error ?? body.message;
|
|
2735
|
+
}
|
|
2730
2736
|
function createToolsClient(options = {}) {
|
|
2731
2737
|
let cached2 = null;
|
|
2732
2738
|
async function baseUrl() {
|
|
@@ -2781,13 +2787,11 @@ function createToolsClient(options = {}) {
|
|
|
2781
2787
|
}
|
|
2782
2788
|
const json = await res.json().catch(() => ({}));
|
|
2783
2789
|
if (!res.ok) {
|
|
2784
|
-
throw new ToolInvocationError(
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
}
|
|
2790
|
-
);
|
|
2790
|
+
throw new ToolInvocationError(errorBodyMessage(json) ?? `${res.status} ${res.statusText}`, {
|
|
2791
|
+
errorCode: json.error_code,
|
|
2792
|
+
errorKind: json.error_kind,
|
|
2793
|
+
issues: Array.isArray(json.issues) ? json.issues : void 0
|
|
2794
|
+
});
|
|
2791
2795
|
}
|
|
2792
2796
|
const { result: data } = await applyClientFileDirectives(json.data);
|
|
2793
2797
|
return { data, note: json.note };
|
|
@@ -2823,6 +2827,10 @@ var FLAG_REGISTRY = [
|
|
|
2823
2827
|
name: "tool-server-event-log",
|
|
2824
2828
|
description: "Write structured tool-server lifecycle events to a JSONL file."
|
|
2825
2829
|
},
|
|
2830
|
+
{
|
|
2831
|
+
name: "boot-sound",
|
|
2832
|
+
description: "Default boot-device's `sound` argument to true so Android emulators boot with audio output instead of muted. Only the argument's default changes \u2014 an explicit `sound: false` on a call still boots muted."
|
|
2833
|
+
},
|
|
2826
2834
|
{
|
|
2827
2835
|
name: "microinteractions",
|
|
2828
2836
|
description: "Amplify device actions with matching animations of the host window, so what happens on the guest is also visible on the desktop. Purely cosmetic, macOS only, and never affects whether the underlying action succeeds. Off by default."
|
|
@@ -7202,7 +7210,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
7202
7210
|
var SESSION_ID2 = randomUUID5();
|
|
7203
7211
|
function readCliVersion() {
|
|
7204
7212
|
if (true) {
|
|
7205
|
-
return "0.22.1-next.
|
|
7213
|
+
return "0.22.1-next.6";
|
|
7206
7214
|
}
|
|
7207
7215
|
return "0.0.0";
|
|
7208
7216
|
}
|
|
@@ -8005,7 +8013,11 @@ function findMissingRequired(payload, schema) {
|
|
|
8005
8013
|
}
|
|
8006
8014
|
return names.filter((name) => !Object.hasOwn(payload, name));
|
|
8007
8015
|
}
|
|
8008
|
-
function
|
|
8016
|
+
function serverIssueList(err) {
|
|
8017
|
+
const carried = err?.issues;
|
|
8018
|
+
if (Array.isArray(carried)) {
|
|
8019
|
+
return carried.length > 0 && carried.every(isValidationIssue) ? carried : null;
|
|
8020
|
+
}
|
|
8009
8021
|
const message = err instanceof Error ? err.message : typeof err === "string" ? err : null;
|
|
8010
8022
|
if (message === null) return null;
|
|
8011
8023
|
let parsed;
|
|
@@ -8015,7 +8027,11 @@ function describeServerValidationFailure(err, payload, schema) {
|
|
|
8015
8027
|
return null;
|
|
8016
8028
|
}
|
|
8017
8029
|
if (!Array.isArray(parsed) || parsed.length === 0) return null;
|
|
8018
|
-
|
|
8030
|
+
return parsed.every(isValidationIssue) ? parsed : null;
|
|
8031
|
+
}
|
|
8032
|
+
function describeServerValidationFailure(err, payload, schema) {
|
|
8033
|
+
const parsed = serverIssueList(err);
|
|
8034
|
+
if (parsed === null) return null;
|
|
8019
8035
|
const properties = schema?.properties ?? {};
|
|
8020
8036
|
const addressesThisTool = (issue) => issue.path.length === 0 || typeof issue.path[0] === "string" && Object.hasOwn(properties, issue.path[0]);
|
|
8021
8037
|
if (!parsed.every(addressesThisTool)) return null;
|
package/dist/installer.mjs
CHANGED
|
@@ -16428,7 +16428,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
16428
16428
|
var SESSION_ID = randomUUID4();
|
|
16429
16429
|
function readCliVersion() {
|
|
16430
16430
|
if (true) {
|
|
16431
|
-
return "0.22.1-next.
|
|
16431
|
+
return "0.22.1-next.6";
|
|
16432
16432
|
}
|
|
16433
16433
|
return "0.0.0";
|
|
16434
16434
|
}
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -16855,6 +16855,12 @@ async function applyClientFileDirectives(result) {
|
|
|
16855
16855
|
return { result: rewritten, written };
|
|
16856
16856
|
}
|
|
16857
16857
|
|
|
16858
|
+
// ../argent-tools-client/src/tools-client.ts
|
|
16859
|
+
function errorBodyMessage(body) {
|
|
16860
|
+
if (Array.isArray(body.issues) && typeof body.message === "string") return body.message;
|
|
16861
|
+
return body.error ?? body.message;
|
|
16862
|
+
}
|
|
16863
|
+
|
|
16858
16864
|
// ../argent-tools-client/src/artifacts.ts
|
|
16859
16865
|
import { copyFile, mkdir as mkdir4, readFile as readFile4, realpath, rm as rm3, stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
16860
16866
|
import { constants as fsConstants } from "node:fs";
|
|
@@ -18685,7 +18691,7 @@ async function startMcpServer(options) {
|
|
|
18685
18691
|
fetchTimeoutMs: meta2?.longRunning ? null : FETCH_TIMEOUT_MS
|
|
18686
18692
|
});
|
|
18687
18693
|
const json = await res.json();
|
|
18688
|
-
if (!res.ok) throw new Error(json
|
|
18694
|
+
if (!res.ok) throw new Error(errorBodyMessage(json) ?? res.statusText);
|
|
18689
18695
|
const { result: data } = await applyClientFileDirectives(json.data);
|
|
18690
18696
|
return { result: data, outputHint: meta2?.outputHint, note: json.note };
|
|
18691
18697
|
}
|
package/dist/tool-server.cjs
CHANGED
|
@@ -16063,6 +16063,63 @@ function terminatingSignalCause(message) {
|
|
|
16063
16063
|
error_kind: "unknown"
|
|
16064
16064
|
});
|
|
16065
16065
|
}
|
|
16066
|
+
function valueAtPath(root, path41) {
|
|
16067
|
+
let current = root;
|
|
16068
|
+
for (const key2 of path41) {
|
|
16069
|
+
if (current === null || typeof current !== "object") return void 0;
|
|
16070
|
+
if (!Object.hasOwn(current, key2)) return void 0;
|
|
16071
|
+
current = current[key2];
|
|
16072
|
+
}
|
|
16073
|
+
return current;
|
|
16074
|
+
}
|
|
16075
|
+
function describeParamIssues(error52, params) {
|
|
16076
|
+
const allKeys = params !== null && typeof params === "object" && !Array.isArray(params) ? Object.keys(params) : [];
|
|
16077
|
+
const supplied = allKeys.slice(0, 24);
|
|
16078
|
+
const truncated = allKeys.length > supplied.length;
|
|
16079
|
+
const parts2 = error52.issues.map((issue2) => {
|
|
16080
|
+
const at = issue2.path.length > 0 ? issue2.path.join(".") : "(root)";
|
|
16081
|
+
if (issue2.code === "custom") {
|
|
16082
|
+
return issue2.path.length > 0 ? `\`${at}\`: ${issue2.message}` : issue2.message;
|
|
16083
|
+
}
|
|
16084
|
+
if (valueAtPath(params, issue2.path) === void 0) {
|
|
16085
|
+
const expected = issue2.expected;
|
|
16086
|
+
const kind = typeof expected === "string" ? ` (${expected})` : "";
|
|
16087
|
+
return `\`${at}\` is required${kind} and was not provided`;
|
|
16088
|
+
}
|
|
16089
|
+
if (issue2.code === "unrecognized_keys") {
|
|
16090
|
+
const keys = issue2.keys ?? [];
|
|
16091
|
+
const at2 = issue2.path.length > 0 ? `${issue2.path.join(".")}.` : "";
|
|
16092
|
+
return `unknown parameter${keys.length === 1 ? "" : "s"} ${keys.map((k) => `\`${at2}${k}\``).join(", ")}`;
|
|
16093
|
+
}
|
|
16094
|
+
if (issue2.code === "invalid_union") {
|
|
16095
|
+
const branches = issue2.errors ?? [];
|
|
16096
|
+
const alternatives = [];
|
|
16097
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16098
|
+
let moreAlternatives = false;
|
|
16099
|
+
for (const branch of branches) {
|
|
16100
|
+
for (const inner of branch) {
|
|
16101
|
+
const innerAt = inner.path.length > 0 ? `${at}.${inner.path.join(".")}: ` : "";
|
|
16102
|
+
const text = `${innerAt}${inner.message}`;
|
|
16103
|
+
if (seen.has(text)) continue;
|
|
16104
|
+
if (alternatives.length >= MAX_UNION_ALTERNATIVES) {
|
|
16105
|
+
moreAlternatives = true;
|
|
16106
|
+
break;
|
|
16107
|
+
}
|
|
16108
|
+
seen.add(text);
|
|
16109
|
+
alternatives.push(text);
|
|
16110
|
+
}
|
|
16111
|
+
if (moreAlternatives) break;
|
|
16112
|
+
}
|
|
16113
|
+
if (alternatives.length > 0) {
|
|
16114
|
+
return `\`${at}\`: ${alternatives.join("; or ")}${moreAlternatives ? "; or \u2026" : ""}`;
|
|
16115
|
+
}
|
|
16116
|
+
}
|
|
16117
|
+
return `\`${at}\`: ${issue2.message}`;
|
|
16118
|
+
});
|
|
16119
|
+
const sent = supplied.length > 0 ? ` You sent: ${supplied.map((k) => `\`${k}\``).join(", ")}${truncated ? ", \u2026" : ""}.` : "";
|
|
16120
|
+
const body = parts2.length > 0 ? `${parts2.map((p) => p.replace(/\.$/, "")).join("; ")}.` : "";
|
|
16121
|
+
return `${body}${sent}`.trim() || "invalid parameters";
|
|
16122
|
+
}
|
|
16066
16123
|
function formatInteractionMessage(format, fallback) {
|
|
16067
16124
|
try {
|
|
16068
16125
|
return format() ?? fallback;
|
|
@@ -16070,7 +16127,7 @@ function formatInteractionMessage(format, fallback) {
|
|
|
16070
16127
|
return fallback;
|
|
16071
16128
|
}
|
|
16072
16129
|
}
|
|
16073
|
-
var import_node_crypto2, Registry;
|
|
16130
|
+
var import_node_crypto2, Registry, MAX_UNION_ALTERNATIVES;
|
|
16074
16131
|
var init_registry = __esm({
|
|
16075
16132
|
"../registry/src/registry.ts"() {
|
|
16076
16133
|
"use strict";
|
|
@@ -16151,7 +16208,15 @@ var init_registry = __esm({
|
|
|
16151
16208
|
if (definition.zodSchema) {
|
|
16152
16209
|
const parsed = definition.zodSchema.safeParse(params ?? {});
|
|
16153
16210
|
if (!parsed.success) {
|
|
16154
|
-
throw new
|
|
16211
|
+
throw new FailureError(
|
|
16212
|
+
`Invalid params for tool "${id}": ${describeParamIssues(parsed.error, params)}`,
|
|
16213
|
+
{
|
|
16214
|
+
error_code: FAILURE_CODES.TOOL_INPUT_INVALID,
|
|
16215
|
+
failure_stage: "tool_params_parse",
|
|
16216
|
+
failure_area: "registry",
|
|
16217
|
+
error_kind: "validation"
|
|
16218
|
+
}
|
|
16219
|
+
);
|
|
16155
16220
|
}
|
|
16156
16221
|
effectiveParams = parsed.data;
|
|
16157
16222
|
}
|
|
@@ -16388,6 +16453,7 @@ var init_registry = __esm({
|
|
|
16388
16453
|
this._transition(node, cause ? "ERROR" /* ERROR */ : "IDLE" /* IDLE */, cause);
|
|
16389
16454
|
}
|
|
16390
16455
|
};
|
|
16456
|
+
MAX_UNION_ALTERNATIVES = 12;
|
|
16391
16457
|
}
|
|
16392
16458
|
});
|
|
16393
16459
|
|
|
@@ -91789,6 +91855,10 @@ var FLAG_REGISTRY = [
|
|
|
91789
91855
|
name: "tool-server-event-log",
|
|
91790
91856
|
description: "Write structured tool-server lifecycle events to a JSONL file."
|
|
91791
91857
|
},
|
|
91858
|
+
{
|
|
91859
|
+
name: "boot-sound",
|
|
91860
|
+
description: "Default boot-device's `sound` argument to true so Android emulators boot with audio output instead of muted. Only the argument's default changes \u2014 an explicit `sound: false` on a call still boots muted."
|
|
91861
|
+
},
|
|
91792
91862
|
{
|
|
91793
91863
|
name: "microinteractions",
|
|
91794
91864
|
description: "Amplify device actions with matching animations of the host window, so what happens on the guest is also visible on the desktop. Purely cosmetic, macOS only, and never affects whether the underlying action succeeds. Off by default."
|
|
@@ -95664,7 +95734,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
|
|
|
95664
95734
|
var SESSION_ID = (0, import_node_crypto3.randomUUID)();
|
|
95665
95735
|
function readCliVersion() {
|
|
95666
95736
|
if (true) {
|
|
95667
|
-
return "0.22.1-next.
|
|
95737
|
+
return "0.22.1-next.6";
|
|
95668
95738
|
}
|
|
95669
95739
|
return "0.0.0";
|
|
95670
95740
|
}
|
|
@@ -113871,14 +113941,23 @@ async function resolveFileInputs(def, body, lookupUpload) {
|
|
|
113871
113941
|
};
|
|
113872
113942
|
const specs = def.fileInputs;
|
|
113873
113943
|
if (!specs || specs.length === 0 || typeof body !== "object" || body === null) {
|
|
113874
|
-
return {
|
|
113944
|
+
return {
|
|
113945
|
+
args: body ?? {},
|
|
113946
|
+
fileInputs: void 0,
|
|
113947
|
+
derivedTargets: [],
|
|
113948
|
+
cleanup
|
|
113949
|
+
};
|
|
113875
113950
|
}
|
|
113876
113951
|
const args = { ...body };
|
|
113877
113952
|
let resolved;
|
|
113953
|
+
const derivedTargets = [];
|
|
113878
113954
|
try {
|
|
113879
113955
|
for (const spec of specs) {
|
|
113880
113956
|
const value = args[spec.target];
|
|
113881
113957
|
if (!isFileInputWire(value)) continue;
|
|
113958
|
+
if (spec.path !== `\${${spec.target}}` && !derivedTargets.includes(spec.target)) {
|
|
113959
|
+
derivedTargets.push(spec.target);
|
|
113960
|
+
}
|
|
113882
113961
|
if (spec.unwrapWhenSet !== void 0 && isParamSet(args[spec.unwrapWhenSet])) {
|
|
113883
113962
|
args[spec.target] = value.path;
|
|
113884
113963
|
continue;
|
|
@@ -113895,7 +113974,7 @@ async function resolveFileInputs(def, body, lookupUpload) {
|
|
|
113895
113974
|
await cleanup();
|
|
113896
113975
|
throw err;
|
|
113897
113976
|
}
|
|
113898
|
-
return { args, fileInputs: resolved, cleanup };
|
|
113977
|
+
return { args, fileInputs: resolved, derivedTargets, cleanup };
|
|
113899
113978
|
}
|
|
113900
113979
|
|
|
113901
113980
|
// ../tool-server/src/utils/debugger/device-alias.ts
|
|
@@ -114186,6 +114265,14 @@ function isToolExposed(def) {
|
|
|
114186
114265
|
function findDependencyMissing(err) {
|
|
114187
114266
|
return findErrorInCauseChain(err, DependencyMissingError);
|
|
114188
114267
|
}
|
|
114268
|
+
function omitKeys(args, keys) {
|
|
114269
|
+
if (keys.length === 0 || args === null || typeof args !== "object" || Array.isArray(args)) {
|
|
114270
|
+
return args;
|
|
114271
|
+
}
|
|
114272
|
+
const copy = { ...args };
|
|
114273
|
+
for (const key2 of keys) delete copy[key2];
|
|
114274
|
+
return copy;
|
|
114275
|
+
}
|
|
114189
114276
|
function errorSignalFields(err) {
|
|
114190
114277
|
const signal = getFailureSignal(err);
|
|
114191
114278
|
return signal ? { error_code: signal.error_code, error_kind: signal.error_kind } : {};
|
|
@@ -114525,6 +114612,7 @@ function createHttpApp(registry2, options) {
|
|
|
114525
114612
|
}
|
|
114526
114613
|
let bodyArgs;
|
|
114527
114614
|
let resolvedFileInputs;
|
|
114615
|
+
let derivedTargets;
|
|
114528
114616
|
try {
|
|
114529
114617
|
const resolved = await resolveFileInputs(def, req.body, (id) => {
|
|
114530
114618
|
const entry = uploads.get(id);
|
|
@@ -114533,6 +114621,7 @@ function createHttpApp(registry2, options) {
|
|
|
114533
114621
|
});
|
|
114534
114622
|
bodyArgs = resolved.args;
|
|
114535
114623
|
resolvedFileInputs = resolved.fileInputs;
|
|
114624
|
+
derivedTargets = resolved.derivedTargets;
|
|
114536
114625
|
res.once("close", () => void resolved.cleanup());
|
|
114537
114626
|
} catch (err) {
|
|
114538
114627
|
if (err instanceof FileInputError) {
|
|
@@ -114556,7 +114645,11 @@ function createHttpApp(registry2, options) {
|
|
|
114556
114645
|
req.body,
|
|
114557
114646
|
{ invalid_params: deriveInvalidParams(parseResult.error, declared) }
|
|
114558
114647
|
);
|
|
114559
|
-
res.status(400).json({
|
|
114648
|
+
res.status(400).json({
|
|
114649
|
+
error: parseResult.error.message,
|
|
114650
|
+
message: describeParamIssues(parseResult.error, omitKeys(bodyArgs, derivedTargets)),
|
|
114651
|
+
issues: parseResult.error.issues
|
|
114652
|
+
});
|
|
114560
114653
|
return;
|
|
114561
114654
|
}
|
|
114562
114655
|
parsedData = parseResult.data;
|
|
@@ -114697,6 +114790,10 @@ function createHttpApp(registry2, options) {
|
|
|
114697
114790
|
res.status(400).json({ error: invalidInputErr.message, ...errorSignalFields(err) });
|
|
114698
114791
|
return;
|
|
114699
114792
|
}
|
|
114793
|
+
if (getFailureSignal(err)?.error_code === FAILURE_CODES.TOOL_INPUT_INVALID) {
|
|
114794
|
+
res.status(400).json({ error: formatErrorForAgent(err), ...errorSignalFields(err) });
|
|
114795
|
+
return;
|
|
114796
|
+
}
|
|
114700
114797
|
const notImplementedErr = findErrorInCauseChain(err, NotImplementedOnPlatformError);
|
|
114701
114798
|
if (notImplementedErr) {
|
|
114702
114799
|
res.status(501).json({
|
|
@@ -118670,6 +118767,9 @@ var zodSchema9 = external_exports.object({
|
|
|
118670
118767
|
"Android/Vega: overall budget for the boot sequence. Default 480000 (8 min) on Android, 120000 (2 min) on Vega. Clamped to [30s, 15min]. Ignored on iOS."
|
|
118671
118768
|
),
|
|
118672
118769
|
force: external_exports.boolean().optional().describe("Shut down and re-boot the device even if already running."),
|
|
118770
|
+
sound: external_exports.boolean().optional().describe(
|
|
118771
|
+
"Android only: boot the emulator with audio output enabled. Defaults to false \u2014 argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega/Electron, which argent never mutes."
|
|
118772
|
+
),
|
|
118673
118773
|
headless: external_exports.boolean().optional().describe(
|
|
118674
118774
|
"iOS only: boot the simulator core WITHOUT opening the Simulator.app GUI window. The device still streams via simulator-server; used by Argent Lens. Set the `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) to force this host-wide without passing the flag per call (the iOS analog of `ARGENT_EMULATOR_NO_WINDOW`). Ignored on Android/Vega/Electron, which have no equivalent GUI step."
|
|
118675
118775
|
),
|
|
@@ -118687,13 +118787,15 @@ function bootTarget(params) {
|
|
|
118687
118787
|
return params.udid ?? params.avdName ?? params.vvdImage ?? params.electronAppPath ?? "device";
|
|
118688
118788
|
}
|
|
118689
118789
|
var LAUNCH_HARDENING_ARGS = [
|
|
118690
|
-
"-noaudio",
|
|
118691
118790
|
"-no-boot-anim",
|
|
118692
118791
|
"-netfast",
|
|
118693
118792
|
"-crash-report-mode",
|
|
118694
118793
|
"never",
|
|
118695
118794
|
"-no-metrics"
|
|
118696
118795
|
];
|
|
118796
|
+
function launchHardeningArgs(sound) {
|
|
118797
|
+
return sound ? [...LAUNCH_HARDENING_ARGS] : ["-noaudio", ...LAUNCH_HARDENING_ARGS];
|
|
118798
|
+
}
|
|
118697
118799
|
var STAGE_BUDGET = {
|
|
118698
118800
|
adbRegister: 6e4,
|
|
118699
118801
|
// adb devices sees the serial for this AVD
|
|
@@ -119125,6 +119227,7 @@ async function bootAndroidImpl(params) {
|
|
|
119125
119227
|
await ensureDep("emulator");
|
|
119126
119228
|
const gpuMode = selectGpuMode();
|
|
119127
119229
|
const extraEmulatorArgs = androidHeadlessFromEnv() ? ["-no-window"] : [];
|
|
119230
|
+
const hardeningArgs = launchHardeningArgs(params.sound);
|
|
119128
119231
|
for (const msg of linuxBootDiagnostics(params.avdName) ?? []) {
|
|
119129
119232
|
console.warn(`[boot-device:linux] ${msg}`);
|
|
119130
119233
|
}
|
|
@@ -119203,7 +119306,7 @@ async function bootAndroidImpl(params) {
|
|
|
119203
119306
|
} else {
|
|
119204
119307
|
const RENDERER_ARGS = ["-gpu", gpuMode, ...extraEmulatorArgs];
|
|
119205
119308
|
const probe3 = await checkSnapshotLoadable(params.avdName, "default_boot", {
|
|
119206
|
-
extraArgs: [...RENDERER_ARGS, ...
|
|
119309
|
+
extraArgs: [...RENDERER_ARGS, ...hardeningArgs]
|
|
119207
119310
|
});
|
|
119208
119311
|
if (!probe3.loadable) {
|
|
119209
119312
|
hotBootFailureReason = `-check-snapshot-loadable: ${probe3.reason ?? "unknown"}`;
|
|
@@ -119214,7 +119317,7 @@ async function bootAndroidImpl(params) {
|
|
|
119214
119317
|
"-force-snapshot-load",
|
|
119215
119318
|
"-no-snapshot-save",
|
|
119216
119319
|
...RENDERER_ARGS,
|
|
119217
|
-
...
|
|
119320
|
+
...hardeningArgs,
|
|
119218
119321
|
...crashReportArgs
|
|
119219
119322
|
];
|
|
119220
119323
|
const hotAttemptDeadline = Math.min(overallDeadline, Date.now() + HOT_BOOT_BUDGET_MS);
|
|
@@ -119258,7 +119361,7 @@ async function bootAndroidImpl(params) {
|
|
|
119258
119361
|
"-gpu",
|
|
119259
119362
|
gpuMode,
|
|
119260
119363
|
...extraEmulatorArgs,
|
|
119261
|
-
...
|
|
119364
|
+
...hardeningArgs,
|
|
119262
119365
|
...crashReportArgs
|
|
119263
119366
|
];
|
|
119264
119367
|
let coldResult;
|
|
@@ -119455,7 +119558,11 @@ Android boots take 2\u201310 minutes depending on machine and cold/warm state; t
|
|
|
119455
119558
|
return bootAndroid({
|
|
119456
119559
|
avdName: params.avdName,
|
|
119457
119560
|
bootTimeoutMs: params.bootTimeoutMs ?? 48e4,
|
|
119458
|
-
force: params.force
|
|
119561
|
+
force: params.force,
|
|
119562
|
+
// An explicit argument always wins; the `boot-sound` flag only moves
|
|
119563
|
+
// the default when the caller left `sound` unset. Read live per call
|
|
119564
|
+
// so `argent enable/disable boot-sound` applies without a restart.
|
|
119565
|
+
sound: params.sound ?? isFlagEnabled("boot-sound")
|
|
119459
119566
|
});
|
|
119460
119567
|
}
|
|
119461
119568
|
if (hasVega) {
|
|
@@ -123240,6 +123347,7 @@ init_zod();
|
|
|
123240
123347
|
|
|
123241
123348
|
// ../tool-server/src/utils/sub-invoke.ts
|
|
123242
123349
|
var import_node_crypto7 = require("node:crypto");
|
|
123350
|
+
init_src();
|
|
123243
123351
|
async function invokeSubTool(registry2, ctx, toolId, args) {
|
|
123244
123352
|
const signal = ctx?.signal;
|
|
123245
123353
|
const recordChildInvocation = ctx?.recordChildInvocation;
|
|
@@ -123258,6 +123366,14 @@ async function invokeSubTool(registry2, ctx, toolId, args) {
|
|
|
123258
123366
|
release();
|
|
123259
123367
|
}
|
|
123260
123368
|
}
|
|
123369
|
+
function describeNestedParamError(registry2, err, toolId, dispatchedArgs, authoredArgs) {
|
|
123370
|
+
if (getFailureSignal(err)?.error_code !== FAILURE_CODES.TOOL_INPUT_INVALID) return void 0;
|
|
123371
|
+
const zodSchema76 = registry2.getTool(toolId)?.zodSchema;
|
|
123372
|
+
if (!zodSchema76) return void 0;
|
|
123373
|
+
const parsed = zodSchema76.safeParse(dispatchedArgs ?? {});
|
|
123374
|
+
if (parsed.success) return void 0;
|
|
123375
|
+
return `Invalid params for tool "${toolId}": ${describeParamIssues(parsed.error, authoredArgs)}`;
|
|
123376
|
+
}
|
|
123261
123377
|
|
|
123262
123378
|
// ../tool-server/src/tools/await-ui-element/index.ts
|
|
123263
123379
|
init_zod();
|
|
@@ -129736,8 +129852,8 @@ Stops on the first error (or unmet await-ui-element condition) and returns parti
|
|
|
129736
129852
|
throw err;
|
|
129737
129853
|
}
|
|
129738
129854
|
}
|
|
129855
|
+
const toolArgs = { ...step.args, udid };
|
|
129739
129856
|
try {
|
|
129740
|
-
const toolArgs = { ...step.args, udid };
|
|
129741
129857
|
const result = await invokeSubTool(registry2, ctx, step.tool, toolArgs);
|
|
129742
129858
|
if (isUnmetUiWaitResult(step.tool, result)) {
|
|
129743
129859
|
const note = result.note;
|
|
@@ -129749,9 +129865,16 @@ Stops on the first error (or unmet await-ui-element condition) and returns parti
|
|
|
129749
129865
|
}
|
|
129750
129866
|
results.push({ tool: step.tool, result });
|
|
129751
129867
|
} catch (err) {
|
|
129868
|
+
const reframed = describeNestedParamError(
|
|
129869
|
+
registry2,
|
|
129870
|
+
err,
|
|
129871
|
+
step.tool,
|
|
129872
|
+
toolArgs,
|
|
129873
|
+
step.args ?? {}
|
|
129874
|
+
);
|
|
129752
129875
|
results.push({
|
|
129753
129876
|
tool: step.tool,
|
|
129754
|
-
error: err instanceof Error ? err.message : String(err)
|
|
129877
|
+
error: reframed ?? (err instanceof Error ? err.message : String(err))
|
|
129755
129878
|
});
|
|
129756
129879
|
break;
|
|
129757
129880
|
}
|
|
@@ -145856,7 +145979,9 @@ var zodSchema63 = external_exports.object({
|
|
|
145856
145979
|
project_root: external_exports.string().describe(
|
|
145857
145980
|
"Absolute path to the project root of the flow being recorded \u2014 the same value passed to flow-start-recording. Together with `name` it identifies which recording this step belongs to."
|
|
145858
145981
|
),
|
|
145859
|
-
command: external_exports.string().describe(
|
|
145982
|
+
command: external_exports.string().describe(
|
|
145983
|
+
'MCP tool name (e.g. "gesture-tap", "screenshot", "launch-app") \u2014 a TOOL, not a flow directive. A flow-file directive name ("tap", "launch", "run", "type", "await", "assert", "pinch", "echo", "wait", "long-press", "scroll-to", "snapshot", "when") is answered with guidance, and nothing runs or is recorded: most name the tool that records the directive, while "wait", "long-press", "scroll-to", "snapshot" and "when" have no recording tool at all and are answered with what to do instead. A recording tool (flow-add-step, flow-add-echo, flow-start-recording, flow-finish-recording) is refused the same way, each for its own reason \u2014 nesting one would erase this flow at replay, end the take, or write the step twice.'
|
|
145984
|
+
),
|
|
145860
145985
|
args: external_exports.string().optional().describe(
|
|
145861
145986
|
`Tool arguments as a JSON string, e.g. '{"udid": "ABC", "x": 0.5, "y": 0.3}'. Omit for tools with no arguments.`
|
|
145862
145987
|
),
|
|
@@ -146056,6 +146181,77 @@ async function captureTapSelector(registry2, session, udid, point) {
|
|
|
146056
146181
|
};
|
|
146057
146182
|
}
|
|
146058
146183
|
}
|
|
146184
|
+
async function activeFlowState(session) {
|
|
146185
|
+
if (session.persist === "host") {
|
|
146186
|
+
try {
|
|
146187
|
+
session.flow = parseFlow(await fs48.readFile(session.filePath, "utf8"));
|
|
146188
|
+
} catch (err) {
|
|
146189
|
+
return {
|
|
146190
|
+
stepCount: session.flow.steps.length,
|
|
146191
|
+
note: `The persisted flow could not be read and parsed (${err instanceof Error ? err.message : String(err)}); the step count is from the last valid in-memory snapshot.`
|
|
146192
|
+
};
|
|
146193
|
+
}
|
|
146194
|
+
}
|
|
146195
|
+
return { stepCount: session.flow.steps.length };
|
|
146196
|
+
}
|
|
146197
|
+
async function recordNothing(session, guidance) {
|
|
146198
|
+
const { stepCount, note } = await activeFlowState(session);
|
|
146199
|
+
return {
|
|
146200
|
+
message: `${guidance} Nothing was executed and no step was recorded.${note ? ` ${note}` : ""}`,
|
|
146201
|
+
toolResult: void 0,
|
|
146202
|
+
stepCount,
|
|
146203
|
+
savedTo: session.filePath
|
|
146204
|
+
};
|
|
146205
|
+
}
|
|
146206
|
+
var DIRECTIVE_COMMAND_HINTS = {
|
|
146207
|
+
tap: { tool: "gesture-tap", rewritten: true },
|
|
146208
|
+
launch: {
|
|
146209
|
+
tool: "restart-app",
|
|
146210
|
+
rewritten: true,
|
|
146211
|
+
rewriteCondition: "when it carries only the bundle id (a call with an extra arg, e.g. an Android `activity`, is kept as a raw `tool: restart-app` step to convert during polish)"
|
|
146212
|
+
},
|
|
146213
|
+
run: {
|
|
146214
|
+
tool: "flow-execute",
|
|
146215
|
+
rewritten: true,
|
|
146216
|
+
rewriteCondition: "when the target resolves as a sibling flow in this recording's folder \u2014 a `name` that does not is kept as a raw `tool: flow-execute` step, and so is every target in a REMOTE recording (`run:` composition is host-resolved, so the host cannot validate the client's siblings); a `flow_path` that is not a sibling is refused outright and records nothing"
|
|
146217
|
+
},
|
|
146218
|
+
type: { tool: "keyboard", rewritten: false },
|
|
146219
|
+
await: { tool: AWAIT_UI_ELEMENT_TOOL_ID, rewritten: false },
|
|
146220
|
+
assert: { tool: AWAIT_UI_ELEMENT_TOOL_ID, rewritten: false },
|
|
146221
|
+
pinch: { tool: "gesture-pinch", rewritten: false }
|
|
146222
|
+
};
|
|
146223
|
+
var NESTED_RECORDER_TOOLS = {
|
|
146224
|
+
"flow-add-echo": "`flow-add-echo` records a step itself, so it must be called DIRECTLY, not through flow-add-step \u2014 nesting it would write the echo AND a `tool: flow-add-echo` step that fails on every replay.",
|
|
146225
|
+
"flow-add-step": "flow-add-step cannot record itself. Pass the MCP tool you want to execute as `command`.",
|
|
146226
|
+
"flow-start-recording": "`flow-start-recording` truncates the flow it names. Recording it as a step would erase this flow at replay; call it directly when you want to start a recording.",
|
|
146227
|
+
"flow-finish-recording": "`flow-finish-recording` ends the recording, so it cannot also be a step in it. Call it directly when the walkthrough is complete."
|
|
146228
|
+
};
|
|
146229
|
+
function isToolNotFound(err, command) {
|
|
146230
|
+
return err instanceof ToolNotFoundError && err.toolId === command;
|
|
146231
|
+
}
|
|
146232
|
+
function directiveCommandHint(command) {
|
|
146233
|
+
if (command === "echo") {
|
|
146234
|
+
return `"echo" is a flow directive, not a tool. Call \`flow-add-echo\` DIRECTLY \u2014 not through flow-add-step, which would run it as a nested tool AND record a \`tool: flow-add-echo\` step that fails on every replay.`;
|
|
146235
|
+
}
|
|
146236
|
+
if (command === "wait") {
|
|
146237
|
+
return `"wait" is a flow directive, not a tool, and there is no tool that records one \u2014 a fixed sleep is not a readiness signal. Record the thing you are actually waiting for with \`${AWAIT_UI_ELEMENT_TOOL_ID}\` instead.`;
|
|
146238
|
+
}
|
|
146239
|
+
if (command === "long-press") {
|
|
146240
|
+
return `"long-press" is a flow directive, not a tool, and no tool records one \u2014 there is no gesture-long-press. Record the rest of the path, then add the \`long-press:\` step by hand during polish and prove it with the replay.`;
|
|
146241
|
+
}
|
|
146242
|
+
if (command === "scroll-to") {
|
|
146243
|
+
return `"scroll-to" is a flow directive, not a tool, and no tool records one \u2014 it SEARCHES, scrolling until the target is visible, which no single recorded gesture reproduces. Record the movement with \`gesture-swipe\` (\`gesture-scroll\` on chromium) if the path needs it, then add the \`scroll-to:\` step by hand during polish and prove it with the replay.`;
|
|
146244
|
+
}
|
|
146245
|
+
if (command === "snapshot") {
|
|
146246
|
+
return `"snapshot" is a flow directive, not a tool, and no tool records one \u2014 it compares the screen against a stored baseline, which \`screenshot-diff\` does not manage. Add the \`snapshot:\` step by hand during polish, then adopt its baseline with a run that sets updateBaselines, and review the PNG before committing it.`;
|
|
146247
|
+
}
|
|
146248
|
+
if (command === "when") {
|
|
146249
|
+
return `"when" is a flow directive, not a tool, and no tool records one \u2014 it GUARDS the steps nested under it, so there is no action of its own to run. Record those steps, then wrap them in the \`when:\` block by hand during polish and prove both branches with the replay.`;
|
|
146250
|
+
}
|
|
146251
|
+
const hint = Object.hasOwn(DIRECTIVE_COMMAND_HINTS, command) ? DIRECTIVE_COMMAND_HINTS[command] : void 0;
|
|
146252
|
+
if (!hint) return void 0;
|
|
146253
|
+
return `"${command}" is a flow directive, not a tool. Record it by calling \`${hint.tool}\` through flow-add-step` + (hint.rewritten ? ` \u2014 the recorder rewrites it into the \`${command}:\` step ${hint.rewriteCondition ?? "for you"}. Where the call is recorded at all, a \`delayMs\` on it opts out of the rewrite: the step is then kept in its raw \`tool: ${hint.tool}\` form (a replay delay has no directive form), so leave \`delayMs\` off if you want the \`${command}:\` step.` : `. It is stored as a raw \`tool: ${hint.tool}\` step; converting it to \`${command}:\` is part of the polish pass.`);
|
|
146254
|
+
}
|
|
146059
146255
|
var RUN_TARGET_COMMAND = "flow-execute";
|
|
146060
146256
|
async function rewriteSiblingFlowPath(session, args) {
|
|
146061
146257
|
const flowPath = args.flow_path;
|
|
@@ -146173,12 +146369,12 @@ function createFlowAddStepTool(registry2) {
|
|
|
146173
146369
|
// Name the flow: recordings are concurrent, so several of these lines can
|
|
146174
146370
|
// interleave in one log and "the recorded flow" would not say which.
|
|
146175
146371
|
startedMsg: ({ params }) => `Adding ${params.command} step to flow ${params.name}`,
|
|
146176
|
-
completedMsg: ({ params }) => `Added ${params.command} step to flow ${params.name}`,
|
|
146372
|
+
completedMsg: ({ params, result }) => result.recorded === void 0 ? `Recorded no ${params.command} step in flow ${params.name}` : `Added ${params.command} step to flow ${params.name}`,
|
|
146177
146373
|
failedMsg: ({ params, failureSignal: failureSignal2 }) => `Failed to add ${params.command} step to flow ${params.name}: ${failureSignal2.error_code}`
|
|
146178
146374
|
},
|
|
146179
146375
|
description: `Execute a tool call and record it as a step in the flow named by \`name\` + \`project_root\` (the recording must already be open \u2014 see flow-start-recording). Use when recording a flow and you want to run and capture each action. A coordinate \`gesture-tap\` is recorded as a portable \`tap: { selector }\` step when the tapped element has stable text/identifier (otherwise coordinates are kept with a warning); a \`restart-app\` is recorded as a \`launch\` step (record one FIRST to make the flow a self-contained e2e flow; restart-app has no chromium support, so a chromium flow records as a fragment \u2014 add the \`launch: { chromium: <app path> }\` line to the YAML afterward, deleting the executionPrerequisite line if one was recorded: a flow that starts with a launch must not declare it).
|
|
146180
146376
|
A recorded \`await-ui-element\` that PASSED is re-probed against the tree the RUNNER resolves \`await:\`/\`assert:\` directives against, which is NOT the tree the live call read; a wait that came back \`{ success: false }\` is not probed at all, and its warning says so; when the condition does not hold there the step is still recorded and \`message\` carries a warning to read before converting \u2014 whether the conversion actually breaks depends on WHY the two disagree, since a screen that moved on between the live wait and the re-probe reads the same way. If that tree could not be read at all, the warning says so instead: the conversion is UNKNOWN, not known-bad. The probe judges the selector exactly as recorded, so write the conversion in the strict map spelling (\`{ visible: { text: Continue } }\`, copying the step's \`selector:\`) \u2014 the bare-string spelling (\`{ visible: Continue }\`) re-parses as a loose selector that resolves identifier-first and falls back to text, which is a different check. \`message\` also warns when the live wait itself came back \`{ success: false }\` \u2014 that tool reports a failed wait by returning rather than throwing, so the step is recorded either way. That warning names the cause, because only one of them judges the condition: a genuine miss will stop the run at replay, while a wait whose tree source was unreadable, or one that was cancelled, observed nothing and leaves the condition UNKNOWN.
|
|
146181
|
-
Returns { message, toolResult, stepCount, recorded, savedTo } on success \u2014 \`message\` is \`Step added to "<name>" flow\` plus any warning about what was recorded (read it; a warning never means the step was skipped). If it fails an error is returned and nothing is recorded.
|
|
146377
|
+
Returns { message, toolResult, stepCount, recorded, savedTo } on success \u2014 \`message\` is \`Step added to "<name>" flow\` plus any warning about what was recorded (read it; a warning never means the step was skipped). If it fails an error is returned and nothing is recorded. Two calls SUCCEED while recording nothing, and omit \`recorded\` to say so: a \`command\` naming a recording tool, and one naming a flow-file directive rather than a tool. Both answer with what to do instead \u2014 usually the call to make (the tool that records that directive, or the recording tool called directly), but \`wait\`, \`long-press\`, \`scroll-to\`, \`snapshot\` and \`when\` have no recording tool, so those name no call and say what to record or add by hand in its place. Either way nothing runs at the device and the take is left untouched \u2014 read \`recorded\`, not the status, to know whether a step was appended.
|
|
146182
146378
|
If a step was recorded by mistake, remove it from the .yaml after \`flow-finish-recording\` rather than during the recording: against a remote client the in-memory copy is authoritative and every write serializes it over your edit, and in host mode a mid-recording edit renumbers the steps, which costs the finish the cross-tree verdicts anchored to them.`,
|
|
146183
146379
|
// The recorded tool RUNS here, so this call lasts as long as whatever it
|
|
146184
146380
|
// wraps, and the three it most often wraps declare this too. Without it the
|
|
@@ -146190,7 +146386,19 @@ If a step was recorded by mistake, remove it from the .yaml after \`flow-finish-
|
|
|
146190
146386
|
services: () => ({}),
|
|
146191
146387
|
async execute(_services, params, ctx) {
|
|
146192
146388
|
const session = await requireRecordingSession(params.project_root, params.name);
|
|
146193
|
-
const
|
|
146389
|
+
const nested = Object.hasOwn(NESTED_RECORDER_TOOLS, params.command) ? NESTED_RECORDER_TOOLS[params.command] : void 0;
|
|
146390
|
+
if (nested) return recordNothing(session, nested);
|
|
146391
|
+
let args;
|
|
146392
|
+
try {
|
|
146393
|
+
args = params.args ? JSON.parse(params.args) : {};
|
|
146394
|
+
} catch (err) {
|
|
146395
|
+
if (registry2.getTool(params.command) === void 0) {
|
|
146396
|
+
const hint = directiveCommandHint(params.command);
|
|
146397
|
+
if (hint) return recordNothing(session, hint);
|
|
146398
|
+
}
|
|
146399
|
+
throw err;
|
|
146400
|
+
}
|
|
146401
|
+
const authoredArgs = { ...args };
|
|
146194
146402
|
if (params.command === RUN_TARGET_COMMAND) await rewriteSiblingFlowPath(session, args);
|
|
146195
146403
|
const isTap = params.command === "gesture-tap" && params.delayMs === void 0 && typeof args.udid === "string" && typeof args.x === "number" && typeof args.y === "number";
|
|
146196
146404
|
let captured;
|
|
@@ -146200,7 +146408,27 @@ If a step was recorded by mistake, remove it from the .yaml after \`flow-finish-
|
|
|
146200
146408
|
y: args.y
|
|
146201
146409
|
});
|
|
146202
146410
|
}
|
|
146203
|
-
|
|
146411
|
+
let toolResult;
|
|
146412
|
+
try {
|
|
146413
|
+
toolResult = await invokeSubTool(registry2, ctx, params.command, args);
|
|
146414
|
+
} catch (err) {
|
|
146415
|
+
const hint = isToolNotFound(err, params.command) ? directiveCommandHint(params.command) : void 0;
|
|
146416
|
+
if (hint) return recordNothing(session, hint);
|
|
146417
|
+
const reframed = describeNestedParamError(
|
|
146418
|
+
registry2,
|
|
146419
|
+
err,
|
|
146420
|
+
params.command,
|
|
146421
|
+
args,
|
|
146422
|
+
authoredArgs
|
|
146423
|
+
);
|
|
146424
|
+
if (reframed === void 0) throw err;
|
|
146425
|
+
throw new FailureError(reframed, {
|
|
146426
|
+
error_code: FAILURE_CODES.TOOL_INPUT_INVALID,
|
|
146427
|
+
failure_stage: "flow_add_step_nested_params",
|
|
146428
|
+
failure_area: "tool_server",
|
|
146429
|
+
error_kind: "validation"
|
|
146430
|
+
});
|
|
146431
|
+
}
|
|
146204
146432
|
let waitWarning;
|
|
146205
146433
|
if (params.command === AWAIT_UI_ELEMENT_TOOL_ID) {
|
|
146206
146434
|
if (isUnmetUiWaitResult(params.command, toolResult)) {
|
|
@@ -148742,8 +148970,10 @@ var zodSchema65 = external_exports.object({
|
|
|
148742
148970
|
if (params.name === void 0 === (params.flow_path === void 0)) {
|
|
148743
148971
|
ctx.addIssue({
|
|
148744
148972
|
code: external_exports.ZodIssueCode.custom,
|
|
148745
|
-
message: "Pass exactly one flow source: name or flow_path.",
|
|
148746
|
-
|
|
148973
|
+
message: params.name !== void 0 ? "Pass exactly one flow source: name or flow_path." : "Pass exactly one flow source: name or flow_path. flow-execute needs the flow's name in `name` \u2014 it resolves <project_root>/.argent/flows/<name>.yaml.",
|
|
148974
|
+
// The ROOT, not `flow_path`: the rule spans both source fields, and a
|
|
148975
|
+
// path would prefix the message with "`flow_path`:".
|
|
148976
|
+
path: []
|
|
148747
148977
|
});
|
|
148748
148978
|
}
|
|
148749
148979
|
});
|
|
@@ -149833,7 +150063,8 @@ async function execLeafStep(state3, step, index, scope) {
|
|
|
149833
150063
|
}
|
|
149834
150064
|
return { ...base, status: "pass", tool: step.name, result, outputHint, args };
|
|
149835
150065
|
} catch (err) {
|
|
149836
|
-
|
|
150066
|
+
const reframed = describeNestedParamError(registry2, err, step.name, args, step.args ?? {});
|
|
150067
|
+
return { ...base, status: "error", tool: step.name, reason: reframed ?? errMsg3(err) };
|
|
149837
150068
|
}
|
|
149838
150069
|
}
|
|
149839
150070
|
default:
|
|
@@ -149981,8 +150212,10 @@ var zodSchema66 = external_exports.object({
|
|
|
149981
150212
|
if (params.name === void 0 === (params.flow_path === void 0)) {
|
|
149982
150213
|
ctx.addIssue({
|
|
149983
150214
|
code: external_exports.ZodIssueCode.custom,
|
|
149984
|
-
message: "Pass exactly one flow source: name or flow_path.",
|
|
149985
|
-
|
|
150215
|
+
message: params.name !== void 0 ? "Pass exactly one flow source: name or flow_path." : "Pass exactly one flow source: name or flow_path. flow-read-prerequisite needs the flow's name in `name` \u2014 it resolves <project_root>/.argent/flows/<name>.yaml.",
|
|
150216
|
+
// The ROOT, matching flow-execute: the rule spans both source fields,
|
|
150217
|
+
// so it must not be anchored on one of them.
|
|
150218
|
+
path: []
|
|
149986
150219
|
});
|
|
149987
150220
|
}
|
|
149988
150221
|
});
|
|
@@ -150014,7 +150247,7 @@ Use when you need to check what app/simulator state is required before executing
|
|
|
150014
150247
|
source (name or flow_path) you will pass to flow-execute, so the prerequisite you read is the contract of
|
|
150015
150248
|
the flow that will actually run.
|
|
150016
150249
|
Fails if the flow file does not exist.
|
|
150017
|
-
Address the flow exactly as you will address it in flow-execute: name or flow_path, one and only one; supplying both or neither is rejected.`,
|
|
150250
|
+
Address the flow exactly as you will address it in flow-execute: name or flow_path, one and only one; supplying both or neither is rejected. The name goes in \`name\`, which resolves <project_root>/.argent/flows/<name>.yaml.`,
|
|
150018
150251
|
zodSchema: zodSchema66,
|
|
150019
150252
|
fileInputs: fileInputs4,
|
|
150020
150253
|
services: () => ({}),
|
package/package.json
CHANGED