@swmansion/argent 0.15.1-next.3 → 0.15.1-next.4
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/tool-server.cjs +77 -3
- package/package.json +1 -1
- package/skills/argent-create-flow/SKILL.md +13 -12
package/dist/tool-server.cjs
CHANGED
|
@@ -144547,6 +144547,12 @@ function toYamlStep(step) {
|
|
|
144547
144547
|
const body = step.selector ? selectorToYaml(step.selector) : { x: step.x, y: step.y };
|
|
144548
144548
|
return { tap: body };
|
|
144549
144549
|
}
|
|
144550
|
+
case "long-press": {
|
|
144551
|
+
const sel = selectorToYaml(step.selector);
|
|
144552
|
+
return {
|
|
144553
|
+
"long-press": step.duration !== void 0 ? { on: sel, duration: step.duration } : sel
|
|
144554
|
+
};
|
|
144555
|
+
}
|
|
144550
144556
|
case "type": {
|
|
144551
144557
|
const body = {
|
|
144552
144558
|
into: selectorToYaml(step.into),
|
|
@@ -144796,6 +144802,7 @@ var STEP_DIRECTIVE_KEYS = [
|
|
|
144796
144802
|
"run",
|
|
144797
144803
|
"tool",
|
|
144798
144804
|
"tap",
|
|
144805
|
+
"long-press",
|
|
144799
144806
|
"type",
|
|
144800
144807
|
"await",
|
|
144801
144808
|
"assert",
|
|
@@ -144803,6 +144810,35 @@ var STEP_DIRECTIVE_KEYS = [
|
|
|
144803
144810
|
"scroll-to",
|
|
144804
144811
|
"snapshot"
|
|
144805
144812
|
];
|
|
144813
|
+
function parseLongPress(body, entry) {
|
|
144814
|
+
const obj = body !== null && typeof body === "object" ? body : {};
|
|
144815
|
+
if (obj.on !== void 0 || obj.duration !== void 0) {
|
|
144816
|
+
if (obj.text !== void 0 || obj.id !== void 0 || obj.identifier !== void 0 || obj.role !== void 0) {
|
|
144817
|
+
badEntry(
|
|
144818
|
+
entry,
|
|
144819
|
+
'the long-press options form takes a nested selector \u2014 e.g. long-press: { on: { text: "Row" }, duration: 1200 }'
|
|
144820
|
+
);
|
|
144821
|
+
}
|
|
144822
|
+
if (!Object.keys(obj).every((k) => k === "on" || k === "duration")) {
|
|
144823
|
+
badEntry(entry, "the long-press options form accepts only { on, duration }");
|
|
144824
|
+
}
|
|
144825
|
+
if (obj.on === void 0) {
|
|
144826
|
+
badEntry(entry, 'long-press needs a target \u2014 e.g. long-press: { on: "Row", duration: 1200 }');
|
|
144827
|
+
}
|
|
144828
|
+
const step = { kind: "long-press", selector: parseSelector(obj.on, "long-press.on") };
|
|
144829
|
+
if (obj.duration !== void 0) {
|
|
144830
|
+
if (typeof obj.duration !== "number" || !Number.isFinite(obj.duration) || obj.duration <= 0) {
|
|
144831
|
+
badEntry(
|
|
144832
|
+
entry,
|
|
144833
|
+
"long-press.duration needs a positive number of milliseconds (e.g. `duration: 1200`)"
|
|
144834
|
+
);
|
|
144835
|
+
}
|
|
144836
|
+
step.duration = obj.duration;
|
|
144837
|
+
}
|
|
144838
|
+
return step;
|
|
144839
|
+
}
|
|
144840
|
+
return { kind: "long-press", selector: parseSelector(body, "long-press") };
|
|
144841
|
+
}
|
|
144806
144842
|
function fromYamlStep(raw) {
|
|
144807
144843
|
const entry = raw;
|
|
144808
144844
|
const kinds = STEP_DIRECTIVE_KEYS.filter((k) => k in entry);
|
|
@@ -144845,6 +144881,9 @@ function fromYamlStep(raw) {
|
|
|
144845
144881
|
}
|
|
144846
144882
|
return { kind: "tap", selector: parseSelector(body, "tap") };
|
|
144847
144883
|
}
|
|
144884
|
+
if ("long-press" in raw) {
|
|
144885
|
+
return parseLongPress(raw["long-press"], raw);
|
|
144886
|
+
}
|
|
144848
144887
|
if ("type" in raw) {
|
|
144849
144888
|
const body = raw.type;
|
|
144850
144889
|
if (!body || typeof body !== "object") badEntry(raw, "type needs { into, text }");
|
|
@@ -145776,6 +145815,8 @@ You can still edit the .yaml file directly afterwards to remove or reorder steps
|
|
|
145776
145815
|
return `${n}. run: ${step.flow}`;
|
|
145777
145816
|
case "tap":
|
|
145778
145817
|
return `${n}. tap: ${step.selector ? selectorLabel(step.selector) : `(${step.x}, ${step.y})`}`;
|
|
145818
|
+
case "long-press":
|
|
145819
|
+
return `${n}. long-press: ${selectorLabel(step.selector)}`;
|
|
145779
145820
|
case "type":
|
|
145780
145821
|
return `${n}. type: ${selectorLabel(step.into)} \u2190 "${step.text}"`;
|
|
145781
145822
|
case "await":
|
|
@@ -146022,7 +146063,7 @@ function offscreenHint(sel) {
|
|
|
146022
146063
|
return `no visible element matched selector ${describeSelector(sel)} \u2014 if it is off-screen, add a scroll-to step before this one`;
|
|
146023
146064
|
}
|
|
146024
146065
|
async function runDirective(env, step) {
|
|
146025
|
-
if (env.device.platform === "vega" && (step.kind === "tap" || step.kind === "type" || step.kind === "scroll-to")) {
|
|
146066
|
+
if (env.device.platform === "vega" && (step.kind === "tap" || step.kind === "long-press" || step.kind === "type" || step.kind === "scroll-to")) {
|
|
146026
146067
|
return {
|
|
146027
146068
|
ok: false,
|
|
146028
146069
|
reason: `${step.kind} is a touch directive and Vega is remote-driven \u2014 move focus with \`tool: tv-remote\` steps (and type via \`tool: keyboard\`) instead`
|
|
@@ -146031,6 +146072,8 @@ async function runDirective(env, step) {
|
|
|
146031
146072
|
switch (step.kind) {
|
|
146032
146073
|
case "tap":
|
|
146033
146074
|
return runTap(env, step);
|
|
146075
|
+
case "long-press":
|
|
146076
|
+
return runLongPress(env, step);
|
|
146034
146077
|
case "type":
|
|
146035
146078
|
return runType(env, step);
|
|
146036
146079
|
case "await":
|
|
@@ -146061,6 +146104,33 @@ async function runTap(env, target) {
|
|
|
146061
146104
|
await invokeOnDevice(env, "gesture-tap", point);
|
|
146062
146105
|
return { ok: true };
|
|
146063
146106
|
}
|
|
146107
|
+
var DEFAULT_LONG_PRESS_MS = 800;
|
|
146108
|
+
async function runLongPress(env, step) {
|
|
146109
|
+
const frame = await waitForFrame(env, step.selector);
|
|
146110
|
+
if (frame === "aborted") return ABORTED_OUTCOME;
|
|
146111
|
+
if (!frame) {
|
|
146112
|
+
return { ok: false, reason: offscreenHint(step.selector) };
|
|
146113
|
+
}
|
|
146114
|
+
const point = getDescribeTapPoint(frame);
|
|
146115
|
+
const duration3 = step.duration ?? DEFAULT_LONG_PRESS_MS;
|
|
146116
|
+
if (env.device.platform === "chromium") {
|
|
146117
|
+
await invokeOnDevice(env, "gesture-drag", {
|
|
146118
|
+
fromX: point.x,
|
|
146119
|
+
fromY: point.y,
|
|
146120
|
+
toX: point.x,
|
|
146121
|
+
toY: point.y,
|
|
146122
|
+
durationMs: duration3
|
|
146123
|
+
});
|
|
146124
|
+
} else {
|
|
146125
|
+
await invokeOnDevice(env, "gesture-custom", {
|
|
146126
|
+
events: [
|
|
146127
|
+
{ type: "Down", x: point.x, y: point.y, delayMs: 0 },
|
|
146128
|
+
{ type: "Up", x: point.x, y: point.y, delayMs: duration3 }
|
|
146129
|
+
]
|
|
146130
|
+
});
|
|
146131
|
+
}
|
|
146132
|
+
return { ok: true };
|
|
146133
|
+
}
|
|
146064
146134
|
async function runType(env, step) {
|
|
146065
146135
|
const frame = await waitForFrame(env, step.into);
|
|
146066
146136
|
if (frame === "aborted") return ABORTED_OUTCOME;
|
|
@@ -148495,8 +148565,9 @@ function createRunFlowTool(registry2) {
|
|
|
148495
148565
|
id: "flow-execute",
|
|
148496
148566
|
description: `Run a saved flow from the .argent/flows/ directory.
|
|
148497
148567
|
Steps run in order: \`launch\` starts an app from scratch (terminate + relaunch) and waits until it is
|
|
148498
|
-
ready; \`tool\` calls dispatch through the registry; \`tap\`/\`type\` resolve a selector to an
|
|
148499
|
-
act on it
|
|
148568
|
+
ready; \`tool\` calls dispatch through the registry; \`tap\`/\`long-press\`/\`type\` resolve a selector to an
|
|
148569
|
+
element and act on it (\`long-press: { on, duration }\` presses and holds); \`scroll-to\` scrolls
|
|
148570
|
+
(momentum-free) until a target is visible; \`await\` waits for a UI
|
|
148500
148571
|
condition; \`wait\` pauses for a fixed number of milliseconds; \`assert\` checks one now; \`snapshot\`
|
|
148501
148572
|
diffs a screenshot against a stored baseline (a missing baseline fails the step \u2014 set updateBaselines
|
|
148502
148573
|
to adopt the current screen); \`echo\` annotates; \`run\` executes a referenced fragment inline.
|
|
@@ -148651,6 +148722,8 @@ function stepTarget(step) {
|
|
|
148651
148722
|
if (step.selector) return selectorLabel2(step.selector);
|
|
148652
148723
|
if (step.x !== void 0 && step.y !== void 0) return `(${step.x}, ${step.y})`;
|
|
148653
148724
|
return void 0;
|
|
148725
|
+
case "long-press":
|
|
148726
|
+
return selectorLabel2(step.selector);
|
|
148654
148727
|
case "type":
|
|
148655
148728
|
return `into ${selectorLabel2(step.into)}`;
|
|
148656
148729
|
case "await":
|
|
@@ -148746,6 +148819,7 @@ async function execLeafStep(state3, step, index, sourceFlow) {
|
|
|
148746
148819
|
return { ...base, status: r.ok ? "pass" : "error", reason: r.reason };
|
|
148747
148820
|
}
|
|
148748
148821
|
case "tap":
|
|
148822
|
+
case "long-press":
|
|
148749
148823
|
case "type":
|
|
148750
148824
|
case "await":
|
|
148751
148825
|
case "assert":
|
package/package.json
CHANGED
|
@@ -20,17 +20,18 @@ Both run via `argent flow run <name>` — a fragment simply runs against whateve
|
|
|
20
20
|
|
|
21
21
|
Beyond raw `tool:` steps and `echo:`, flows support declarative directives interpreted by the runner (they are **not** agent-callable tools). **Every directive hard-stops the flow on failure**; later steps are reported `skip`.
|
|
22
22
|
|
|
23
|
-
| Directive
|
|
24
|
-
|
|
|
25
|
-
| `launch`
|
|
26
|
-
| `tap`
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
23
|
+
| Directive | YAML | Meaning |
|
|
24
|
+
| ------------ | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
|
25
|
+
| `launch` | `- launch: com.acme.app` or `- launch: { ios: …, android: … }` | start the app from scratch (terminate + relaunch) and wait until ready |
|
|
26
|
+
| `tap` | `- tap: Login` or `- tap: { x: 0.5, y: 0.57 }` | tap an element by selector (auto-waits), or a raw normalized point |
|
|
27
|
+
| `long-press` | `- long-press: Row 3` or `- long-press: { on: <sel>, duration: 1200 }` | press and hold an element (default 800ms; Chromium: mouse press-hold) |
|
|
28
|
+
| `type` | `- type: { into: email, text: "a@b.com" }` | focus a field, type, then press Enter to submit + dismiss the keyboard |
|
|
29
|
+
| `scroll-to` | `- scroll-to: "Order #1234"` (scrolls down) or `- scroll-to: { target: …, direction: right, within: … }` | momentum-free scroll until the target is visible |
|
|
30
|
+
| `await` | `- await: { visible: Home }` | wait for a UI condition |
|
|
31
|
+
| `wait` | `- wait: 500` | pause for a fixed number of milliseconds (last resort — prefer `await`) |
|
|
32
|
+
| `assert` | `- assert: { visible: Welcome }` | check a condition, hard-fail if it never holds |
|
|
33
|
+
| `snapshot` | `- snapshot: home` or `- snapshot: { name: home, maxMismatch: 0.5 }` | diff a screenshot against a stored baseline |
|
|
34
|
+
| `run` | `- run: login` | execute a fragment's steps inline |
|
|
34
35
|
|
|
35
36
|
### Selectors
|
|
36
37
|
|
|
@@ -60,7 +61,7 @@ For a custom poll interval or bundleId, drop to an explicit `- tool: await-ui-el
|
|
|
60
61
|
|
|
61
62
|
### TV targets (Vega)
|
|
62
63
|
|
|
63
|
-
A Vega (Fire TV) device is remote-driven — there is no touch input, so the touch directives (`tap`, `type`, `scroll-to`) fail on it with guidance. Drive focus with `tool: tv-remote` steps and type with `tool: keyboard` instead; everything else (`launch`, `await`, `assert`, `wait`, `snapshot`, `echo`, `run`, selectors) works unchanged — the tree comes from the on-device automation toolkit, which attaches at app launch (the `launch` step waits for it, so a leading `launch` also guarantees selectors resolve).
|
|
64
|
+
A Vega (Fire TV) device is remote-driven — there is no touch input, so the touch directives (`tap`, `long-press`, `type`, `scroll-to`) fail on it with guidance. Drive focus with `tool: tv-remote` steps and type with `tool: keyboard` instead; everything else (`launch`, `await`, `assert`, `wait`, `snapshot`, `echo`, `run`, selectors) works unchanged — the tree comes from the on-device automation toolkit, which attaches at app launch (the `launch` step waits for it, so a leading `launch` also guarantees selectors resolve).
|
|
64
65
|
|
|
65
66
|
```yaml
|
|
66
67
|
steps:
|