chore(deps): bump minimatch in /maestro-studio/web#7
Closed
dependabot[bot] wants to merge 1 commit into
Closed
Conversation
Bumps and [minimatch](https://github.com/isaacs/minimatch). These dependencies needed to be updated together. Updates `minimatch` from 3.1.2 to 3.1.4 - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](isaacs/minimatch@v3.1.2...v3.1.4) Updates `minimatch` from 5.1.6 to 5.1.8 - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](isaacs/minimatch@v3.1.2...v3.1.4) --- updated-dependencies: - dependency-name: minimatch dependency-version: 3.1.4 dependency-type: indirect - dependency-name: minimatch dependency-version: 5.1.8 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
Author
|
Superseded by #9. |
dependabot
Bot
deleted the
dependabot/npm_and_yarn/maestro-studio/web/multi-d89474293d
branch
March 1, 2026 13:26
cem2ran
pushed a commit
that referenced
this pull request
Jul 10, 2026
…lat per-flow bundle, device logs & crash/ANR (mobile-dev-inc#3282) * feat(orchestra): add listener-based artifact production (Phase 0) Adds Orchestra hooks so consumers can produce flow-debug artifacts through a single mechanism instead of each rolling their own callback plumbing. New public API in maestro-orchestra: - OrchestraListener interface (onFlowStart, onCommandStart, onCommandFinished, onCommandReset, onCommandMetadataUpdate, onFlowEnd) with default no-op methods - CommandOutcome sealed type (Completed / Skipped / Warned / Failed) - Orchestra ctor: artifactsDir: Path? = null, listeners: List<OrchestraListener> = emptyList() - Orchestra.debugOutput: FlowDebugOutput exposed as a property Internal in maestro-orchestra: - ArtifactsGenerator always installed, produces the canonical bundle when artifactsDir is set: artifactsDir/maestro.log via ScopedLogCapture artifactsDir/commands.json at onFlowEnd artifactsDir/screenshot-❌-<ts>.png on first failure Failure-time hierarchy capture and screenshot capture run in independent try/catch — either failing logs a warning, the other still proceeds. - ScreenshotUtils relocated from maestro-cli to maestro-orchestra; CLI keeps a thin delegate for MaestroCommandRunner backwards-compat. New in maestro-client: - ScopedLogCapture: per-flow Log4j2 FileAppender with a maestro-only filter; attaches/detaches without reconfiguring the global context. Temporarily lowers the root level to ALL while captured, restores on close. Co-existence: Orchestra still fires the existing lambda callbacks at each call-point alongside the new listener dispatch, so CLI / Studio / worker continue working unchanged. Phase 1 migrates CLI; Phase 2/3 migrate the copilot consumers. Phase 4 removes the lambda callbacks. Tests: - ArtifactsGeneratorTest: independence of hierarchy + screenshot capture, commands.json written at onFlowEnd, no-op when artifactsDir is null, MaestroException populates debugOutput.exception - ScopedLogCaptureTest: maestro-only filter, idempotent close, appender detached after close - OrchestraListenerDispatchTest: legacy lambdas and listeners both fire, debugOutput exposed on Orchestra See copilot/docs/orchestra-artifacts-refactor.md for the full plan. * feat(cli): migrate TestSuiteInteractor to Orchestra listeners (Phase 1) Switches `maestro test` to produce its on-disk debug bundle through Maestro's new internal `ArtifactsGenerator` (Phase 0 API). The 80-line inline callback block in `TestSuiteInteractor.runFlow` that previously duplicated debug-output population now collapses to a single `Orchestra(artifactsDir = tempDir, listeners = listOf(CliConsoleListener))` construction. Failure-time hierarchy capture, scoped maestro.log capture, commands.json write, and the failure screenshot are all handled inside Maestro now. Behavior is preserved: - Files in `~/.maestro/tests/<ts>/` after a flow run are byte-identical to today: `commands-(flow_name).json`, `screenshot-<emoji>-<ts>-(flow_name).png`, session-level `maestro.log` from `LogConfig.configure` (untouched). - `TestExecutionSummary` and `captureSteps` step results read `orchestra.debugOutput` instead of a local FlowDebugOutput — same data. - `onCommandFailed` still returns `ErrorResolution.FAIL`, so `orchestra.runFlow` returns false on failure exactly as before. - `onCommandGeneratedOutput` (AI defects) stays a separate Orchestra lambda — orthogonal to the listener pattern. New files: - maestro-cli/.../runner/CliConsoleListener.kt: ~30 lines, single responsibility = the "<flow> RUNNING / COMPLETED / FAILED / …" console lines users see. TestDebugReporter: - Adds `copyToFlatLayout(sourceDir, destDir, flowName, shardIndex?)` — renames Maestro's canonical files into CLI's historic flat layout. Used by TestSuiteInteractor after each flow. - Keeps `saveFlow(...)` unchanged for `TestRunner.runSingle` (single-flow + continuous modes via MaestroCommandRunner have not been migrated yet; that's a follow-up). Tests: - Existing two saveFlow filename-pinning tests stay green (saveFlow itself is unchanged). - Added three copyToFlatLayout tests: shard prefix renaming, flow-name slash sanitization, no-op when sourceDir is missing. See copilot/docs/orchestra-artifacts-refactor.md for the full plan. * chore(cli): route per-flow staging dir through TempFileHandler Phase 1 was using java.nio.file.Files.createTempDirectory directly, which skips the recursive-cleanup lifecycle TempFileHandler provides. Long-lived JVMs (e.g. the cloud worker) leak /tmp content when temp paths bypass the handler. Swap to maestro.utils.TempFileHandler so close() in the finally recursively cleans up the staging directory. Also document the convention in AGENTS.md under Conventions so future contributions don't reach for Files.createTempFile/Directory. * fix(orchestra): dispatch listener lifecycle from executeSubflowCommands Composite commands (runFlow / repeat / retry) route their nested bodies through executeSubflowCommands, which only called the legacy lambdas. The new OrchestraListener pipeline (incl. ArtifactsGenerator) therefore only saw top-level commands — commands.json was missing every nested entry and failure screenshot + hierarchy were skipped when a leaf inside a composite failed. Mirror the five dispatch sites from executeCommands: onCommandStart listener notify with sequenceNumber + startedAt bookkeeping, and dispatchFinished on Completed / Warned / Skipped / Failed branches. Adds three RunFlow / Repeat / Retry tests in OrchestraListenerDispatchTest that exercise Completed + Warned + Failed leaves inside each composite and assert the listener sees every inner leaf. These tests went RED on the regression before the fix and pass after. * test(orchestra): expand listener-dispatch coverage to top-level + nested + reset Replaces two near-vacuous empty-flow tests with three structural tests that exercise the dispatch paths the empty-list cases couldn't: - top-level leaves (no composite wrapper) - the only path #7's composite tests didn't cover; locks down `executeCommands`-side dispatch. - Repeat -> RunFlow -> leaves - asserts dispatch chains through arbitrary nesting depth, not just one level. - Repeat with times=2 - asserts onCommandReset fires for the body leaf when Orchestra resets between iterations. Each test now carries a KDoc with the YAML-shape of the flow it exercises, so the structural intent of each case is visible in source. The deleted tests ran `runFlow(emptyList())` and asserted that flowStart/ flowEnd fire and that debugOutput.commands is empty - both are tautological once any non-empty flow runs through the listener pipeline, and empty command lists don't happen in production (YAML reader rejects them upstream). * fix(orchestra): guarantee onFlowEnd dispatches once onFlowStart has fired executeDefineVariablesCommands sat between the onFlowStart dispatch and runFlow's outer try/catch. A throw inside it (most commonly: a putEnv failure when the user injects env vars via `--env` / a flow `env:` block / MAESTRO_* shell vars, which Env.withEnv lowers into a synthesized DefineVariablesCommand prepended to the flow) propagated out of runFlow without entering the catch — so the finally never ran: - listener.onFlowEnd was never dispatched, so ArtifactsGenerator never wrote commands.json and never closed its ScopedLogCapture. - jsEngine.close() was skipped, leaking the JS engine. Move executeDefineVariablesCommands and the DefineVariablesCommand-filter inside the try, so any throw they emit is caught into `exception` and re-thrown after finally (preserving caller-visible propagation) while onFlowEnd and jsEngine.close run. Adds a test that injects a JsEngine whose putEnv throws and asserts the listener sees `flowEnd` in addition to `flowStart` and the failed-command events. Test was RED on the regression and is GREEN with the fix. * fix(orchestra): key commandStartTimes by sequenceNumber, not MaestroCommand MaestroCommand is a data class — structurally identical commands are equal as map keys. Today the dispatchFinished-removes-before-next- onCommandStart-puts pattern makes this work by accident: every terminal dispatch cleans up its own entry before the next start. Any future code path that interleaves starts and finishes (concurrency, async retry, parallel sub-execution) would silently fall into the `?: finishedAt` fallback and report duration = 0. Switch the key to the monotonic commandSequenceCounter assigned at onCommandStart. Pass sequenceNumber explicitly to dispatchFinished so lookup is unambiguous. Collisions become structurally impossible. Adds a pin-down test that asserts two structurally identical EvalScriptCommand("1") commands report independent non-zero start timestamps and sequential ordering. Test was GREEN on the old code (no observable bug today) and stays GREEN on the new — documents the contract so a future regression that breaks the per-event timing would fail visibly. * fix(client): scope ScopedLogCapture level mutation to maestro loggers Previous shape saved + restored the root logger level around each capture. Overlapping captures (every sharded run, every long-lived Worker / Studio JVM) raced on that shared state: - Capture B reads ALL as its "previous" because Capture A already lowered root; on close B restores ALL, leaving the host JVM's root logger permanently corrupted to ALL. - While A is closed but B is still active, root level reverts to the host's baseline (e.g. ERROR), silently dropping INFO/DEBUG events from maestro.* loggers before they reach B's per-flow file. Replace the root mutation with a once-per-JVM lowering of the dedicated `maestro` and `MAESTRO` LoggerConfig levels to ALL. Monotonic (never restored), so concurrent / overlapping captures cannot corrupt anything. Host's root logger and every non-maestro logger are left untouched. Adds a test that interleaves two ScopedLogCaptures and asserts the host root logger level is unchanged after both close. Test was RED on the old save/restore behaviour (root stuck at ALL) and is GREEN with the fix. Documented trade-off: hosts that embed Maestro and have their own root appender now receive maestro.* events at all levels — they can opt out by adding their own `maestro` LoggerConfig at a stricter level. * chore(orchestra): centralize listener dispatch, log throwing listeners Every listener-dispatch site was the same `effectiveListeners.forEach { runCatching { ... } }` shape — silent swallow of any listener exception. A bug in a third-party listener (Studio SSE push, Worker API reporter, future analytics hook) left no trace; users saw "flow ran fine, dashboards empty" with nothing to diagnose. Extract a single `dispatch(event, block)` helper that runs each listener in isolation and logs at ERROR with the listener class name, the event name, and the cause when a listener throws. Replace all seven dispatch sites (onFlowStart / onFlowEnd / onCommandStart x2 / onCommandFinished / onCommandReset / onCommandMetadataUpdate) with calls to the helper. Behavior unchanged for non-throwing listeners. For throwing listeners: silent -> ERROR log with stack trace; flow still continues and other listeners still fire. * refactor(orchestra): return FlowResult from runFlow, drop debugOutput field Per @steviec: exposing debugOutput as a mutable field on Orchestra implied persistent state between runFlow and the post-hoc read, and conflated the live-observation channel (OrchestraListener) with the terminal record. Every caller already consumed debugOutput strictly post-runFlow. Make the lifetime explicit: runFlow now returns data class FlowResult(val success: Boolean, val debugOutput: FlowDebugOutput) and the `val debugOutput` getter on Orchestra is gone. Side benefit at the TestSuiteInteractor call site: the lateinit var orchestra pattern is gone too. Construction failures no longer risk masking the real error with an UninitializedPropertyAccessException when the post-flow code tries to read orchestra.debugOutput — a default FlowDebugOutput() now seeds the variable up front. Callers updated: - TestSuiteInteractor — destructures result.success / result.debugOutput - MaestroCommandRunner — wraps with .success at the existing return site - IntegrationTest — 4 assertion patterns updated to .success * remove: comment * docs(orchestra): trim verbose KDoc/comments across the artifacts refactor * feat(orchestra): typed ArtifactManifest + flat per-flow run-root bundle (mobile-dev-inc#3343) * feat(orchestra-models): add ArtifactManifest taxonomy * test(orchestra-models): pin both directions of manifest unknown-field tolerance * feat(orchestra): ArtifactsGenerator emits ArtifactManifest on FlowResult * refactor(orchestra): serialize manifest.json with the bundle's JSON style * feat(cli): write flat-layout manifest.json in the session dir * refactor(cli): serialize flat manifest.json with the shared bundle JSON style * test(artifact-manifest): pin shard-prefixed flat paths + manifest content; drop unused imports * refactor(orchestra): centralize canonical artifact filenames in ArtifactFiles * feat(cli): add copyBundleToFlowDir for per-flow artifact folders * feat(cli): write suite flows to per-flow folders * refactor(cli): address review - accurate comment, verbatim-manifest test, consistent mkdir * feat(cli): MaestroCommandRunner emits artifact bundle, returns FlowResult * feat(cli): single-flow runs write a per-flow folder with manifest * refactor(cli): simplify TestRunner error printing, revert needless reformat Extract the per-type debug-message handling into printFlowError (a single when over the MaestroException subtypes) so runSingle reads top-to-bottom, and restore the original multi-line formatting of aiOutput/updatedEnv that this branch had collapsed for no reason. Behavior unchanged. * test: drop redundant artifact tests without losing coverage - Remove the cli 'no clobber' test: with different flow names each lands in its own folder trivially; same-name clobber is already pinned by the numeric-suffix disambiguation test. - Merge the two null-artifactsDir ArtifactsGenerator tests into one that asserts both no files on disk and an empty manifest. * feat(client): add CapturedDeviceArtifact descriptor + device-log filenames * feat(client): add device-log/crash capture methods to Driver (default no-op) * feat(client): Maestro wrappers for device-log/crash capture Add three suspend wrapper methods to Maestro class that delegate to Driver capture methods (startDeviceLogCapture, stopAndCollectDeviceLogs, collectCrashArtifacts), following the existing runInterruptible(Dispatchers.IO) pattern. * feat(orchestra): add DeviceArtifactCapturer helper * feat(orchestra): capture device logs/crash into per-flow bundle + manifest * feat(client): port dadb crash/ANR logcat helpers * feat(client): port LogcatReader crash/ANR parser + tests * feat(client): AndroidDriver captures logcat + crash + ANR * feat(ios-driver): port iOS .ips crash parser + finder + tests * feat(ios-driver): simctl log stream start helper * feat(client): IOSDriver captures simulator log + .ips crash * fix(device-logs): scope crash/ANR to flow start, clean up iOS log stream, harden tests * feat(client): IOSDriver harvests xctest_runner.log as second DEVICE_LOG source Threads the session logs dir (where LocalXCTestInstaller writes xctest_runner_*.log) into IOSDriver via a nullable param; stopAndCollectDeviceLogs copies the newest one into the per-flow bundle as DEVICE_LOG source=xctest. Closes the last worker-parity gap. * chore(device-logs): shorten comments and drop internal doc reference * feat(orchestra): make manifest.json self-documenting via bundled JSON Schema Agents (and humans) reading a run's manifest.json had no in-band way to learn what each field or ArtifactKind means. Make the manifest self-describing: - Add a hand-written JSON Schema (manifest.schema.json) describing ArtifactManifest, with a description on every field and per-ArtifactKind docs via the oneOf/const pattern. Lifted from the model's KDoc. - ArtifactsGenerator.onFlowEnd now bundles the schema next to manifest.json in each run dir and writes a leading `$schema` pointing at it, so the manifest resolves its own schema offline. - Centralize both writes in TestOutputWriter (saveManifest injects $schema; saveManifestSchema copies the classpath resource). Drift guard: ArtifactManifestSchemaTest fails the build if any ArtifactKind/ArtifactFormat value is missing from the schema, so the hand-written doc can't silently fall out of sync with the enums. The on-disk manifest now carries `$schema`, an unknown property to the typed model. No production code deserializes the manifest; the one test that did used a strict mapper and now decodes tolerantly, matching the model's documented contract (tolerance is the reader's choice). * feat(orchestra): register screenshots/ and recordings/ folders in the manifest * feat(orchestra): write takeScreenshot/startRecording into screenshots/ and recordings/ * feat(cli): pass the bundle dir as screenshotsDir so screenshots/recordings nest under it * docs(orchestra): clarify assertScreenshot reference lookup order * refactor: single artifact root for takeScreenshot/recording; --test-output-dir holds the full run bundle * refactor: write each flow's artifacts directly to its output folder Resolve the per-flow folder upfront and pass it as Orchestra's single artifactsDir; Orchestra writes the bundle + screenshots/ + recordings/ + manifest straight there. Drops the temp staging dir, copyBundleToFlowDir, the separate screenshotsDir param, mediaRoot, and the now-vestigial testOutputDir plumbing. Continuous mode keeps no bundle (artifactsDir null -> takeScreenshot to CWD). * feat(orchestra): nest bundle under artifacts/, flag-gated step screenshots + full recording (mobile-dev-inc#3348) feat(orchestra): nest bundle under artifacts/, flag-gated step shots + full recording Restructure the per-run artifact bundle so everything core writes lives under an artifacts/ folder (zipped as one unit), while the two separately-served outputs — per-step screenshots/ and the full-run screen-recording.mp4 — sit at the run root. - Rename takeScreenshot output screenshots/ -> artifacts/takeScreenshot/ and startRecording output recordings/ -> artifacts/startRecording/ so folders match the command that writes them. - Move commands.json, maestro.log (now under logs/), and the failure screenshot under artifacts/. - Add Orchestra flags captureStepScreenshots / captureScreenRecording (default off, so the local CLI bundle is unchanged; the worker turns them on). When on, ArtifactsGenerator writes screenshots/step-<seq>.png after each non-failed command and records the whole run to screen-recording.mp4. - Manifest entries use the new relative paths and carry metadata.source to tell same-kind entries apart (failure/take_screenshot/step, start_recording/full_run). - Update assertScreenshot reference lookup and the schema prose accordingly. * feat(orchestra): point manifest $schema at the in-repo schema on main (mobile-dev-inc#3349) Replace the per-run bundled manifest.schema.json with a stable identity: each manifest.json now sets $schema to the hand-written schema served from this repo's main branch via GitHub raw — https://raw.githubusercontent.com/mobile-dev-inc/Maestro/main/maestro-orchestra-models/src/main/resources/maestro/orchestra/manifest.schema.json A fixed branch keeps the URL constant while its content tracks the latest schema, which is safe because the model tolerates unknown fields and a test blocks undocumented artifact kinds. No extra hosting infrastructure is needed, and the manifest stays self-describing even after it is moved away from its run folder. - Drop saveManifestSchema and the per-run schema-file copy; saveManifest writes the URL directly. - Set the schema's own $id to the same URL. - Keep the in-repo schema resource as the source of truth (it is the file the URL serves) and for the schema-coverage test. Offline resolution is intentionally dropped. * remove comment * fix(orchestra): write device logs + crash/ANR into the logs/ dir * refactor(orchestra): flatten run root into the bundle; version manifest schema as v1 Drop the intermediate artifacts/ folder — the run root is now itself the zippable bundle, so commands.json, logs/ (maestro.log + device logs + crash/ANR), takeScreenshot/, startRecording/, the failure screenshot, screenshots/, and screen-recording.mp4 all sit directly under it next to manifest.json. Version the hand-written schema as manifest.v1.schema.json (file, $id, the $schema URL embedded in every manifest, and the classpath resource), so a future structural change ships as manifest.vN beside it while the v1 URL keeps resolving for manifests already in the wild. * docs(orchestra): device-log comments follow the flattened logs/ path * feat(orchestra): per-command artifacts list on CommandDebugMetadata + onCommandArtifact hook * feat(orchestra): takeScreenshot/startRecording report their output via onCommandArtifact * feat(orchestra): attribute the failure screenshot to the failed command * feat(orchestra): attribute per-step screenshots to their command * docs(orchestra): mention per-command artifacts in ArtifactsGenerator KDoc * docs(orchestra): refresh schema descriptions for the flattened layout + per-command artifacts * feat(orchestra): split ArtifactKind into self-describing kinds + screen-hierarchy dir * feat(orchestra): type per-command artifacts as {type, path} via ArtifactKind * feat(orchestra): unify failure capture into screenshots/step-N.png; dedicated manifest kinds * feat(orchestra): per-step screen-hierarchy files replace inline hierarchy in commands.json * docs(orchestra): trim comments across the artifacts PR * feat(orchestra): slim serialized errors in commands.json to message + debugMessage * feat(orchestra): add ArtifactCollector that records artifacts on allocate/adopt * refactor(orchestra): build the manifest from ArtifactCollector records, not a disk scan * refactor(orchestra): consolidate capture flags into captureFullArtifacts * refactor(orchestra): privatize bundle layout out of -models The directory/filename layout constants in ArtifactFiles had no cross-module consumer — only maestro-orchestra (the producer) read them; consumers locate artifacts via each manifest entry's relativePath at runtime. Keeping them in the shared -models module made the layout look like an inter-module contract it never was. Move them into a module-internal BundleLayout in maestro-orchestra, so the bundle shape is the producer's private concern. The only genuinely shared identity — the manifest schema URL/resource (the -models schema test consumes the latter) — moves onto ArtifactManifest, where it belongs with the type it describes. ArtifactFiles is deleted; no behavior or on-disk layout changes. * docs(orchestra): note one-app crash scoping assumption * feat(orchestra): publish manifest schema to a public GCS bucket Point each manifest.json's $schema (and the schema's own $id) at https://storage.googleapis.com/maestro-schemas/artifact-manifest/v1.schema.json — HTTPS, a versioned/immutable path served straight from a public GCS object we control — replacing the github-raw URL on main. Fixes that URL's sharp edges: 404-until-merged, raw hotlink rate limits, and a mutable v1. Serving the object directly (no load balancer / DNS) keeps schema resolution decoupled from any other product's infra. Add publish-schemas.yaml: on push to main (or manual), CI mirrors the in-repo schema to gs://maestro-schemas/artifact-manifest/v1.schema.json via the existing GCP_MOBILEDEV_BUCKET_CREDENTIALS service account. The repo file stays the source of truth; the schema-coverage test is unchanged. * docs(orchestra): schema spells out hierarchy is a separate artifact, not inline in commands.json * test(orchestra): schema coverage guards entry/manifest fields, not just kinds additionalProperties:false rejects any undocumented field, so a new model field missing from the schema is now a build failure like a missing kind. * build(orchestra-models): declare kotlin-reflect for the schema-coverage test The field-coverage check reflects over the model via primaryConstructor; make kotlin-reflect a direct test dep instead of leaning on jackson-module-kotlin's transitive copy. * refactor(orchestra): address manifest review — collector owns artifact paths, one version signal - takeScreenshot/startRecording now allocate through ArtifactsGenerator/ArtifactCollector, the single owner of bundle paths; drop the onCommandArtifact listener hook and dead getFileSink so a file can't reach the bundle unrecorded - drop the schemaVersion field — version lives only in the $schema vN path - schema additionalProperties: true (root + entry) so additive fields stay forward-compatible against a cached older v1 - remove the unused USER_FILE kind * fix(orchestra): gate per-step view hierarchy behind captureFullArtifacts captureStepHierarchy() ran on every executed command, each a synchronous maestro.viewHierarchy() device round-trip (~100 for a 100-command flow). Per-step screenshots and the full-run recording are already gated behind captureFullArtifacts for this reason; hierarchy was the outlier. Capture per-step hierarchy only when captureFullArtifacts is on (worker); the failed step's hierarchy is still captured locally so failures stay debuggable. Align the test names with the same condition wording. * fix(orchestra): per-command failure-screenshot dedup, not flow-wide The dedup skipped a failure screenshot whenever any earlier screenshot in the flow was FAILED. That swallowed every failure after the first in a continue-on-failure / optional flow. Move the dedup out of ScreenshotUtils (which can't see the command sequence) and into captureFailureScreenshot: skip only a composite parent re-shooting its leaf's screen, identified by a lower sequence number than the leaf that already captured. A genuinely later failure has a higher number and keeps its own shot. In worker mode (captureFullArtifacts on) every step is recorded individually, so a failed composite parent keeps its own screenshot too — no dedup there. Adds Orchestra-driven tests confirming repeat/retry produce one screenshot per attempt and onFlowStart/onFlowComplete hooks each get their own step. * fix(ios): wait for simctl to flush device log before collecting it stopAndCollectDeviceLogs destroyed the `simctl log stream` process with an async SIGTERM and copied the log file immediately, so the buffered tail — often the lines around a crash — could be lost. Wait (bounded) for the process to exit before copying, mirroring stopScreenRecording's close()+ waitFor(). The restart and teardown destroy() sites don't copy afterward, so they stay no-wait. * fix(orchestra): route WARNED + analyze screenshots through the manifest WARNED and --analyze screenshots were captured outside the collector (flat files via persistDebugScreenshots) and only on the single-flow path, so they never reached manifest.json and single vs suite runs diverged. - ArtifactsGenerator now captures a warned step's screenshot + hierarchy into the bundle on every run, so warned shots are first-class manifest artifacts on both single and suite. - --analyze turns on captureFullArtifacts (single + suite), so the bundle holds a per-step screenshot for every command. The AI analysis already walks the debug folder and ingests every PNG, so this replaces the bespoke analyze capture entirely — no separate code path. - Delete the bespoke analyze/warned capture, persistDebugScreenshots, and the now-dead ScreenshotUtils helpers. debugOutput.screenshots had no remaining reader, so drop it and simplify takeDebugScreenshot to (maestro, destFile). * feat(orchestra): record AI-analyzed screenshots as AI_ANALYSIS in the manifest assertWithAI / assertNoDefectsWithAI produced a screenshot the AI analyzed, but it only fed the CLI's AI report and never reached the bundle/manifest. Add an onAIArtifactGenerated listener hook; ArtifactsGenerator writes that screenshot to ai-analysis/step-<seq>.png and records it as AI_ANALYSIS (with a defectCount) attributed to the running command. The CLI report path is unchanged, and the worker gets the same artifact for free. * feat(orchestra): per-execution commands.json with nesting depth (mobile-dev-inc#3378) * feat(orchestra): per-execution commands.json with nesting depth commands.json was serialized from an identity-keyed map, so retry/repeat re-runs of the same command object collapsed into one entry (last-attempt status, all attempts' screenshots piled on). The worker couldn't drive its per-attempt run_step table from it. Record one entry per command execution instead: - FlowDebugOutput gains executedSteps (one CommandDebugMetadata per onCommandStart, in order); the identity map stays for live attribution. - Artifacts attribute by sequence number (ArtifactCollector.artifactsForStep), so each attempt keeps its own screenshot/hierarchy. - OrchestraListener.onCommandStart carries depth; Orchestra tracks a subflowDepth around executeSubflowCommands. depth 0 at the top, +1 inside each runFlow/repeat/retry — the worker's subIndex. - onCommandReset no longer mutates the finished entry (it shares the object with the identity map); a reset just precedes the next execution's entry. A repeat/retry now yields one commands.json entry per iteration/attempt, each with its own screenshot and depth — mapping 1:1 onto run_step(index, subIndex). Verified locally on web for repeat and retry. * refactor(orchestra): drop dead artifactsFor and command attribution artifactsFor(command) had no caller once onFlowEnd switched to artifactsForStep(sequenceNumber). Remove it and the now write-only command field threaded through Record/allocate/allocateInCollection/adopt and their call sites. * refactor(orchestra): drop unused RRWEB artifact format Web recording is MP4 (CDP screencast -> JCodec), so RRWEB had no producer and no consumer. Removing it before v1.schema.json is published. Note added on why enum values, unlike fields, must be reserved up front rather than added additively later. * fix: adapt new main test to FlowResult API; rename dadb logcat helpers - IntegrationTest: main's new 'optional launchApp ... warned, not failed' test used runFlow's old Boolean return; this branch returns FlowResult, so assert result.success (surfaced only at test-compile after the main merge). - Rename DadbExtensions.kt -> LogcatExtensions.kt and move from the maestro.android.dadb package into maestro.android: the helpers now extend AndroidDeviceConnection (not raw Dadb), so the 'dadb' name was stale. --------- Co-authored-by: Proksh Luthra <35415752+proksh@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps and minimatch. These dependencies needed to be updated together.
Updates
minimatchfrom 3.1.2 to 3.1.4Commits
1a2e0843.1.4ae24656update lockfileb100374limit recursion for **, improve perf considerably26ffeaalockfile update9eca892lock node version to 1400c323b3.1.330486b2update CI matrix and actions9c31b2dupdate test expectations for coalesced consecutive stars46fe687coalesce consecutive non-globstar * characters5a9ccbd[meta] update publishConfig.tag to legacy-v3Updates
minimatchfrom 5.1.6 to 5.1.8Commits
1a2e0843.1.4ae24656update lockfileb100374limit recursion for **, improve perf considerably26ffeaalockfile update9eca892lock node version to 1400c323b3.1.330486b2update CI matrix and actions9c31b2dupdate test expectations for coalesced consecutive stars46fe687coalesce consecutive non-globstar * characters5a9ccbd[meta] update publishConfig.tag to legacy-v3Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)You can disable automated security fix PRs for this repo from the Security Alerts page.