@swmansion/argent 0.15.1-next.6 → 0.15.1-next.7
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
CHANGED
|
@@ -6324,6 +6324,7 @@ var FAILURE_CODES = {
|
|
|
6324
6324
|
CHROMIUM_ELECTRON_EXITED_BEFORE_READY: "CHROMIUM_ELECTRON_EXITED_BEFORE_READY",
|
|
6325
6325
|
KEYBOARD_KEY_UNSUPPORTED: "KEYBOARD_KEY_UNSUPPORTED",
|
|
6326
6326
|
KEYBOARD_CHARACTER_UNSUPPORTED: "KEYBOARD_CHARACTER_UNSUPPORTED",
|
|
6327
|
+
SECRET_PLACEHOLDER_UNKNOWN: "SECRET_PLACEHOLDER_UNKNOWN",
|
|
6327
6328
|
SCREENSHOT_DIFF_INPUT_INVALID: "SCREENSHOT_DIFF_INPUT_INVALID",
|
|
6328
6329
|
BOOT_DEVICE_TARGET_SELECTION_INVALID: "BOOT_DEVICE_TARGET_SELECTION_INVALID",
|
|
6329
6330
|
BOOT_IOS_UNSUPPORTED_HOST: "BOOT_IOS_UNSUPPORTED_HOST",
|
package/dist/installer.mjs
CHANGED
|
@@ -16231,6 +16231,7 @@ var FAILURE_CODES = {
|
|
|
16231
16231
|
CHROMIUM_ELECTRON_EXITED_BEFORE_READY: "CHROMIUM_ELECTRON_EXITED_BEFORE_READY",
|
|
16232
16232
|
KEYBOARD_KEY_UNSUPPORTED: "KEYBOARD_KEY_UNSUPPORTED",
|
|
16233
16233
|
KEYBOARD_CHARACTER_UNSUPPORTED: "KEYBOARD_CHARACTER_UNSUPPORTED",
|
|
16234
|
+
SECRET_PLACEHOLDER_UNKNOWN: "SECRET_PLACEHOLDER_UNKNOWN",
|
|
16234
16235
|
SCREENSHOT_DIFF_INPUT_INVALID: "SCREENSHOT_DIFF_INPUT_INVALID",
|
|
16235
16236
|
BOOT_DEVICE_TARGET_SELECTION_INVALID: "BOOT_DEVICE_TARGET_SELECTION_INVALID",
|
|
16236
16237
|
BOOT_IOS_UNSUPPORTED_HOST: "BOOT_IOS_UNSUPPORTED_HOST",
|
package/dist/mcp-server.mjs
CHANGED
|
@@ -17750,6 +17750,7 @@ var FAILURE_CODES = {
|
|
|
17750
17750
|
CHROMIUM_ELECTRON_EXITED_BEFORE_READY: "CHROMIUM_ELECTRON_EXITED_BEFORE_READY",
|
|
17751
17751
|
KEYBOARD_KEY_UNSUPPORTED: "KEYBOARD_KEY_UNSUPPORTED",
|
|
17752
17752
|
KEYBOARD_CHARACTER_UNSUPPORTED: "KEYBOARD_CHARACTER_UNSUPPORTED",
|
|
17753
|
+
SECRET_PLACEHOLDER_UNKNOWN: "SECRET_PLACEHOLDER_UNKNOWN",
|
|
17753
17754
|
SCREENSHOT_DIFF_INPUT_INVALID: "SCREENSHOT_DIFF_INPUT_INVALID",
|
|
17754
17755
|
BOOT_DEVICE_TARGET_SELECTION_INVALID: "BOOT_DEVICE_TARGET_SELECTION_INVALID",
|
|
17755
17756
|
BOOT_IOS_UNSUPPORTED_HOST: "BOOT_IOS_UNSUPPORTED_HOST",
|
|
@@ -18981,6 +18982,14 @@ var DEFAULT_DELAY_MS = 1400;
|
|
|
18981
18982
|
function autoScreenshotEnabled(options) {
|
|
18982
18983
|
return !isFlagEnabled("disable-auto-screenshot", options);
|
|
18983
18984
|
}
|
|
18985
|
+
var SECRET_PLACEHOLDER_MARKER = "{{secret:";
|
|
18986
|
+
function containsSecretPlaceholder(args) {
|
|
18987
|
+
try {
|
|
18988
|
+
return JSON.stringify(args)?.includes(SECRET_PLACEHOLDER_MARKER) ?? false;
|
|
18989
|
+
} catch {
|
|
18990
|
+
return true;
|
|
18991
|
+
}
|
|
18992
|
+
}
|
|
18984
18993
|
function getUdidFromArgs(args) {
|
|
18985
18994
|
if (args && typeof args === "object" && "udid" in args && typeof args.udid === "string") {
|
|
18986
18995
|
return args.udid;
|
|
@@ -19209,7 +19218,15 @@ async function startMcpServer(options) {
|
|
|
19209
19218
|
content = await toMcpContent(result, outputHint, ctx, params.arguments);
|
|
19210
19219
|
}
|
|
19211
19220
|
const udid = getUdidFromArgs(params.arguments);
|
|
19212
|
-
if (autoScreenshotOn && udid && shouldAutoScreenshot(params.name)) {
|
|
19221
|
+
if (autoScreenshotOn && udid && shouldAutoScreenshot(params.name) && containsSecretPlaceholder(params.arguments)) {
|
|
19222
|
+
content = [
|
|
19223
|
+
...content,
|
|
19224
|
+
{
|
|
19225
|
+
type: "text",
|
|
19226
|
+
text: "Auto-screenshot skipped: the input contains a {{secret:\u2026}} placeholder, and a screenshot of this screen could reveal the typed secret. Submit or navigate away first, then verify the resulting screen as usual."
|
|
19227
|
+
}
|
|
19228
|
+
];
|
|
19229
|
+
} else if (autoScreenshotOn && udid && shouldAutoScreenshot(params.name)) {
|
|
19213
19230
|
const maxWaitMs = getAutoScreenshotDelayMs(params.name);
|
|
19214
19231
|
if (maxWaitMs > 0) {
|
|
19215
19232
|
try {
|
package/dist/tool-server.cjs
CHANGED
|
@@ -404,6 +404,7 @@ var init_failure_codes = __esm({
|
|
|
404
404
|
CHROMIUM_ELECTRON_EXITED_BEFORE_READY: "CHROMIUM_ELECTRON_EXITED_BEFORE_READY",
|
|
405
405
|
KEYBOARD_KEY_UNSUPPORTED: "KEYBOARD_KEY_UNSUPPORTED",
|
|
406
406
|
KEYBOARD_CHARACTER_UNSUPPORTED: "KEYBOARD_CHARACTER_UNSUPPORTED",
|
|
407
|
+
SECRET_PLACEHOLDER_UNKNOWN: "SECRET_PLACEHOLDER_UNKNOWN",
|
|
407
408
|
SCREENSHOT_DIFF_INPUT_INVALID: "SCREENSHOT_DIFF_INPUT_INVALID",
|
|
408
409
|
BOOT_DEVICE_TARGET_SELECTION_INVALID: "BOOT_DEVICE_TARGET_SELECTION_INVALID",
|
|
409
410
|
BOOT_IOS_UNSUPPORTED_HOST: "BOOT_IOS_UNSUPPORTED_HOST",
|
|
@@ -126687,6 +126688,54 @@ Fails if the device backend is not reachable \u2014 the simulator-server for iOS
|
|
|
126687
126688
|
// ../tool-server/src/tools/keyboard/index.ts
|
|
126688
126689
|
init_zod();
|
|
126689
126690
|
|
|
126691
|
+
// ../tool-server/src/utils/secrets.ts
|
|
126692
|
+
init_src();
|
|
126693
|
+
var SECRET_ENV_PREFIX = "ARGENT_SECRET_";
|
|
126694
|
+
var SECRET_PLACEHOLDER_MARKER = "{{secret:";
|
|
126695
|
+
var PLACEHOLDER_RE = /\{\{secret:([A-Za-z_][A-Za-z0-9_]*)\}\}/g;
|
|
126696
|
+
function availableSecretNames(env = process.env) {
|
|
126697
|
+
return Object.keys(env).filter((k) => k.startsWith(SECRET_ENV_PREFIX) && env[k] !== void 0).map((k) => k.slice(SECRET_ENV_PREFIX.length)).sort();
|
|
126698
|
+
}
|
|
126699
|
+
var REDUNDANT_PREFIX_RE = /^argent_secret_/i;
|
|
126700
|
+
function resolveSecretPlaceholders(text, env = process.env) {
|
|
126701
|
+
const secrets = [];
|
|
126702
|
+
const resolved = text.replace(PLACEHOLDER_RE, (placeholder, rawName) => {
|
|
126703
|
+
let name = rawName;
|
|
126704
|
+
let value = env[SECRET_ENV_PREFIX + name];
|
|
126705
|
+
if (value === void 0 && REDUNDANT_PREFIX_RE.test(name)) {
|
|
126706
|
+
name = name.replace(REDUNDANT_PREFIX_RE, "");
|
|
126707
|
+
value = env[SECRET_ENV_PREFIX + name];
|
|
126708
|
+
}
|
|
126709
|
+
if (value === void 0) {
|
|
126710
|
+
const names = availableSecretNames(env);
|
|
126711
|
+
throw new InvalidToolInputError(
|
|
126712
|
+
`Unknown secret "${rawName}" \u2014 no ${SECRET_ENV_PREFIX}${name} environment variable is set on the machine running the tool-server. Available secrets: ${names.length ? names.join(", ") : "(none)"}. To make it available, ask the user to export ${SECRET_ENV_PREFIX}${name} in the tool-server's environment \u2014 never ask the user for the secret value itself.`,
|
|
126713
|
+
{
|
|
126714
|
+
error_code: FAILURE_CODES.SECRET_PLACEHOLDER_UNKNOWN,
|
|
126715
|
+
failure_stage: "secret_placeholder_resolution",
|
|
126716
|
+
error_kind: "validation"
|
|
126717
|
+
}
|
|
126718
|
+
);
|
|
126719
|
+
}
|
|
126720
|
+
if (!secrets.some((s) => s.name === name)) secrets.push({ name, value });
|
|
126721
|
+
return value;
|
|
126722
|
+
});
|
|
126723
|
+
return { text: resolved, secrets };
|
|
126724
|
+
}
|
|
126725
|
+
function redactSecretsFromError(err, secrets) {
|
|
126726
|
+
const scrub = (s) => secrets.reduce(
|
|
126727
|
+
(acc, { name, value }) => value ? acc.split(value).join(`${SECRET_PLACEHOLDER_MARKER}${name}}}`) : acc,
|
|
126728
|
+
s
|
|
126729
|
+
);
|
|
126730
|
+
if (err instanceof Error) {
|
|
126731
|
+
err.message = scrub(err.message);
|
|
126732
|
+
if (err.stack) err.stack = scrub(err.stack);
|
|
126733
|
+
return err;
|
|
126734
|
+
}
|
|
126735
|
+
if (typeof err === "string") return scrub(err);
|
|
126736
|
+
return err;
|
|
126737
|
+
}
|
|
126738
|
+
|
|
126690
126739
|
// ../tool-server/src/tools/keyboard/simulator-server-keys.ts
|
|
126691
126740
|
init_src();
|
|
126692
126741
|
|
|
@@ -127165,7 +127214,9 @@ var zodSchema24 = external_exports.object({
|
|
|
127165
127214
|
udid: external_exports.string().describe(
|
|
127166
127215
|
"Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id)."
|
|
127167
127216
|
),
|
|
127168
|
-
text: external_exports.string().optional().describe(
|
|
127217
|
+
text: external_exports.string().optional().describe(
|
|
127218
|
+
'Text to type character by character. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` types the value of the `ARGENT_SECRET_<NAME>` environment variable set on the machine running the tool-server \u2014 e.g. text: "{{secret:APP_PASSWORD}}" types the value of `ARGENT_SECRET_APP_PASSWORD`. Only env vars with the `ARGENT_SECRET_` prefix are resolvable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, ask the user to export it as `ARGENT_SECRET_<NAME>` and restart the session \u2014 NEVER ask the user to paste the secret value into the conversation.'
|
|
127219
|
+
),
|
|
127169
127220
|
key: external_exports.string().optional().describe(
|
|
127170
127221
|
"Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1\u2013f12. When combined with `text`, the key is pressed AFTER the text is typed (so text + enter types and submits). Not supported on TV targets \u2014 move focus with `tv-remote` (up/down/left/right) instead."
|
|
127171
127222
|
),
|
|
@@ -127181,12 +127232,21 @@ var capability16 = {
|
|
|
127181
127232
|
vega: { vvd: true }
|
|
127182
127233
|
};
|
|
127183
127234
|
function createKeyboardTool(registry2) {
|
|
127235
|
+
const dispatch = dispatchByPlatform({
|
|
127236
|
+
toolId: "keyboard",
|
|
127237
|
+
capability: capability16,
|
|
127238
|
+
ios: makeIosImpl3(registry2),
|
|
127239
|
+
iosRemote: makeIosRemoteImpl(registry2),
|
|
127240
|
+
android: makeAndroidImpl(registry2),
|
|
127241
|
+
chromium: makeChromiumImpl(registry2),
|
|
127242
|
+
vega: vegaImpl4
|
|
127243
|
+
});
|
|
127184
127244
|
return {
|
|
127185
127245
|
id: "keyboard",
|
|
127186
127246
|
description: `Type text or press special keys on the device (iOS simulator, Android emulator or device, Chromium app, Vega Virtual Device, or Apple TV / Android TV) using keyboard events.
|
|
127187
127247
|
Use when you need to enter text or trigger a named key such as enter, escape, or arrow keys. On Vega and Apple TV / Android TV, prefer the remote tools for D-pad navigation; use keyboard to type into a focused text field (e.g. a search or login box).
|
|
127188
127248
|
Returns { typed: string, keys: number }. Fails if an unsupported key name is provided or the device's input backend is not reachable.
|
|
127189
|
-
- text: types a string (supports uppercase, digits, common punctuation)
|
|
127249
|
+
- text: types a string (supports uppercase, digits, common punctuation). To type a credential, use \`{{secret:<NAME>}}\` \u2014 resolved server-side from the \`ARGENT_SECRET_<NAME>\` env var (prefix mandatory; \`{{secret:APP_PASSWORD}}\` \u2194 \`ARGENT_SECRET_APP_PASSWORD\`), so the plaintext never enters agent context; the result echoes the placeholder, not the value, and the after-typing auto-screenshot is skipped.
|
|
127190
127250
|
- key: presses a single named key (enter, escape, backspace, tab, arrow-up/down/left/right, f1\u2013f12) \u2014 NOT supported on TV targets; move focus with \`tv-remote\` instead.
|
|
127191
127251
|
On a TV target (runtimeKind 'tv') only \`text\` applies \u2014 focus a text field first (with \`tv-remote\`), then type into it (injected HID keyboard on Apple TV, \`adb input text\` on Android TV).
|
|
127192
127252
|
Provide text, key, or both \u2014 when both are given, the text is typed first and the key is pressed after it (text + key:"enter" types and submits).`,
|
|
@@ -127197,15 +127257,17 @@ Provide text, key, or both \u2014 when both are given, the text is typed first a
|
|
|
127197
127257
|
// simulator-server, CDP, or Vega adb), since distinguishing a TV target is
|
|
127198
127258
|
// async and a tvOS udid must never resolve simulator-server.
|
|
127199
127259
|
services: () => ({}),
|
|
127200
|
-
execute:
|
|
127201
|
-
|
|
127202
|
-
|
|
127203
|
-
|
|
127204
|
-
|
|
127205
|
-
|
|
127206
|
-
|
|
127207
|
-
|
|
127208
|
-
|
|
127260
|
+
execute: async (services, params, options) => {
|
|
127261
|
+
if (params.text === void 0) return dispatch(services, params, options);
|
|
127262
|
+
const { text, secrets } = resolveSecretPlaceholders(params.text);
|
|
127263
|
+
if (secrets.length === 0) return dispatch(services, params, options);
|
|
127264
|
+
try {
|
|
127265
|
+
const result = await dispatch(services, { ...params, text }, options);
|
|
127266
|
+
return { ...result, typed: params.text };
|
|
127267
|
+
} catch (err) {
|
|
127268
|
+
throw redactSecretsFromError(err, secrets);
|
|
127269
|
+
}
|
|
127270
|
+
}
|
|
127209
127271
|
};
|
|
127210
127272
|
}
|
|
127211
127273
|
|
|
@@ -133622,6 +133684,7 @@ Allowed tools and their args (udid is auto-injected, do NOT include it in args):
|
|
|
133622
133684
|
gesture-rotate: { centerX: number, centerY: number, radius: number, startAngle: number, endAngle: number, durationMs?: number } [ios only]
|
|
133623
133685
|
button: { button: "home"|"back"|"power"|"volumeUp"|"volumeDown"|"appSwitch"|"actionButton" } [ios/android]
|
|
133624
133686
|
keyboard: { text?: string, key?: string, delayMs?: number } (key pressed after text; TV: text only) [ios/android/chromium/vega/tv]
|
|
133687
|
+
text supports {{secret:<NAME>}} placeholders, resolved server-side from ARGENT_SECRET_<NAME> env vars (prefix mandatory) \u2014 credentials never enter agent context
|
|
133625
133688
|
rotate: { orientation: "Portrait"|"LandscapeLeft"|"LandscapeRight"|"PortraitUpsideDown" } [ios/android]
|
|
133626
133689
|
tv-remote: { button: <remote button | array of them>, repeat?: number } [apple tv/android tv/vega]
|
|
133627
133690
|
buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute \u2014 work on Android TV and Vega; rejected on the Apple TV simulator)
|
package/package.json
CHANGED
|
@@ -60,6 +60,8 @@ For a custom poll interval or bundleId, drop to an explicit `- tool: await-ui-el
|
|
|
60
60
|
|
|
61
61
|
`type` presses Enter after typing to commit the value and dismiss the keyboard, so it can't cover later targets. For a chained form whose fields feed one explicit submit — e.g. email then password then a `tap: "Log in"` — set `submit: false` on the intermediate fields so a premature Enter doesn't fire the form early: `type: { into: password, text: "hunter2", submit: false }`.
|
|
62
62
|
|
|
63
|
+
Never record a real credential into a flow — the YAML is committed to the repo. Use a secret placeholder instead: `type: { into: password, text: "{{secret:APP_PASSWORD}}" }`. The placeholder is stored verbatim (the YAML stays secret-free) and is resolved at run time by the tool-server from the `ARGENT_SECRET_APP_PASSWORD` environment variable — including agent-less `argent flow run` in CI, where the variable comes from the job's secrets.
|
|
64
|
+
|
|
63
65
|
`scroll-to` takes an optional `direction` (`up` | `down` | `left` | `right`, default `down` — so the common case is just `- scroll-to: <selector>`) and optionally a `within: <selector>` that anchors the scroll inside a specific container — required to drive a **nested** scroller (e.g. a horizontal carousel inside a vertical list), since the device can't be asked which container to scroll. It scrolls in bounded momentum-free increments, re-checks after each, and stops if a scroll reveals nothing new (end of the container). `tap`/`type` do **not** scroll — add a `scroll-to` before any target that may be off-screen. It's a no-op when the target is already visible, so a defensive `scroll-to` costs nothing on replay and keeps the flow working on smaller screens.
|
|
64
66
|
|
|
65
67
|
### TV targets (Vega)
|
|
@@ -171,6 +171,18 @@ Values: `home`, `back`, `power`, `volumeUp`, `volumeDown`, `appSwitch`, `actionB
|
|
|
171
171
|
|
|
172
172
|
Special keys: `enter`, `escape`, `backspace`, `tab`, `space`, `arrow-up`, `arrow-down`, `arrow-left`, `arrow-right`, `f1`–`f12`. Optional: `"delayMs": 100` between keystrokes (default 50ms) — applies to the iOS simulator and Chromium; it is ignored on Android phones/tablets (typed via `adb input text`, no per-key cadence), on Vega, and on TV targets.
|
|
173
173
|
|
|
174
|
+
**Typing secrets.** To enter a credential without its plaintext ever entering your context, transcript, or logs, use a secret placeholder in `text` (works in `keyboard`, `paste`, `run-sequence` keyboard steps, and flow `type` steps):
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{ "udid": "<UDID>", "text": "{{secret:APP_PASSWORD}}", "key": "enter" }
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The placeholder is resolved on the machine running the tool-server from the `ARGENT_SECRET_<NAME>` environment variable (here `ARGENT_SECRET_APP_PASSWORD`) — the CI-native pattern: expose the secret under that prefix in the environment that starts the tool-server. Rules:
|
|
181
|
+
|
|
182
|
+
- The result echoes the placeholder, never the value. An unknown name fails with the list of available secret _names_.
|
|
183
|
+
- The auto-screenshot after the call is skipped so the typed value cannot re-enter your context as pixels. Do **not** `describe` or `screenshot` a non-secure field you just filled with a secret — submit or navigate away first, then verify the resulting screen.
|
|
184
|
+
- Only `ARGENT_SECRET_*` variables are resolvable; never ask the user to paste a secret value into the conversation — ask them to export the env var instead.
|
|
185
|
+
|
|
174
186
|
### rotate — Change orientation
|
|
175
187
|
|
|
176
188
|
```json
|