Shiki's default bundle has no `ad` grammar, so rspress build failed on
three code fences in replay-e2e.md. Aligns them with the rest of the
file, which already uses ```sh for .ad script content.
* feat: parametrise .ad replay scripts
Support ${VAR} substitution with env header directives and CLI -e
overrides so flows can be reused across app variants, environments,
and devices without duplicating the script.
Precedence (high->low): CLI -e > AD_* shell env > file-local env >
built-ins (AD_PLATFORM, AD_SESSION, AD_FILENAME, AD_DEVICE,
AD_ARTIFACTS). Supports ${VAR:-default} fallback, \${ escape, and
fails with file:line on unresolved vars.
* refactor: harden .ad replay parametrisation
Tighten the parametrisation surface introduced in the feat commit after
an internal review pass:
- Reserve the AD_* namespace for built-ins. User env (file env, CLI -e,
shell AD_VAR_*) can no longer define AD_* keys, which closes a built-in
shadowing vector (e.g. AD_VAR_AD_SESSION).
- Change the shell-env prefix from AD_* to AD_VAR_* so unrelated CI
secrets that happen to start with AD_ (AD_TOKEN, AD_SECRET_KEY) are
not auto-imported into replay scripts.
- Extend the replay -u guard to also reject scripts with \${VAR}
substitutions in any action, not just those with env directives, so
the writer never silently drops substitutions on heal-rewrite.
- Reword DX-unfriendly regex errors ("must match /^[A-Z_]...$/" ->
"must be uppercase letters, digits, and underscores, e.g. APP_ID").
- Docs rewrite with precedence table, three recipes, fallback/escape
examples, and a Notes block covering replay -u limitation, remote
daemon caveat, no nested fallback, and loud typo behaviour.
- Additional unit tests: namespace reservation on every path, shell
prefix migration, \${VAR} round-trip preservation through
writeReplayScript, green-path integration test with a fake invoke.
* fix: collect .ad replay shell env on the CLI, not the daemon
Review feedback (https://github.com/callstackincubator/agent-device/pull/433#discussion_r3130695225):
the daemon was reading AD_VAR_* from its own process.env, which meant
"AD_VAR_K=V agent-device replay" only worked if V was set when the
daemon started, and never worked for remote daemons.
The client now filters process.env for AD_VAR_* at request time and
ships the result as replayShellEnv on the DaemonRequest flags. The
daemon prefers the request value when present and falls back to its
own process.env for direct-daemon callers (internal tests).
Adds two integration tests pinning both paths and updates the docs
Notes block to reflect the new behaviour.
* fix: thread per-attempt artifacts dir into AD_ARTIFACTS under test
Review feedback (https://github.com/callstackincubator/agent-device/pull/433#discussion_r3130695235):
AD_ARTIFACTS is documented as available under "agent-device test", but
buildReplayBuiltinVars was only reading the raw flags.artifactsDir.
Under the default artifacts layout the flag is unset and \${AD_ARTIFACTS}
failed; when set with --artifacts-dir it pointed at the suite root, not
the resolved per-attempt directory the test runner actually writes to.
Plumb the attempt-level artifacts dir from session-test.ts through the
runReplay callback (via runReplayTestAttempt) down into the nested
replay request's flags.artifactsDir. The daemon side is unchanged -
buildReplayBuiltinVars just now sees the right value.
Extracts the nested-request flag merge into a testable helper
(buildNestedReplayFlags) to close the coverage gap between the test
harness and the replay runtime.
* refactor: DRY .ad replay parametrisation internals
- Share VAR_KEY_RE between session-replay-vars and session-replay-script
instead of re-declaring the same /^[A-Z_][A-Z0-9_]*$/ in each.
- Fold resolveReplayFlags + resolveReplayRuntime into a single generic
resolveStringProps<T>; the two were near-identical object-walkers.
- Un-export parseReplayEnvLine (was only used inside its own module).
- Table-drive the four "reject AD_* namespace" tests with test.each
instead of four near-duplicate test blocks.
- Extract runReplayFixture helper for runReplayScriptFile integration
tests; each test is now ~10 lines instead of ~30.
No behaviour change. 812 tests still green.
* docs: clarify replay built-in variables
* test: cover replay env serialization
---------
Co-authored-by: Michał Pierzchała <thymikee@gmail.com>