Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

Extract the Maestro engine as a plugin (0.22)

Aberta
#3,377 0 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
5/5
Tempo estimado
Mais de uma semana
Facilidade para iniciantes
8/100
Tipo de issue
Refatoração
Clareza
Razoavelmente clara
Status de atividade
Ativa
Stack de tecnologia
typescript
Domínio
cli, devtools

Direção de pesquisa

Start with the seam PR the issue says must land first: read packages/replay-port (the five session-replay-maestro-runtime* and -observer/-failure files plus session-test-source-discovery.ts) and src/core/platform-plugin-registry.ts. Check the grep proof that no production code imports @agent-device/maestro outside the registration site, and that cli-startup-import-closure.test.ts still passes. Done means the seam is merged and the layering and conformance checks are green.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

backlog refactor

Purpose

Extract the Maestro compatibility engine (packages/maestro, ~11.5k production LOC) into a plugin so the core daemon, CLI, and replay-port stop naming it directly, while the --maestro replay surface, the ADR 0015 performance contract, and the three-layer conformance oracle stay intact. This issue tracks the full 0.22 extraction; the paired seam PR is the non-breaking first step.

Current coupling (what must invert)

Today the daemon↔engine relationship is almost inverted — packages/replay-port is the adapter and the engine talks back only through invoke + a package-owned operation request (per #2544). Remaining direct couplings:

  1. packages/replay-port → engine imports (5 files): session-replay-maestro-runtime.ts (executeMaestroFlow, inspectMaestroFlow, createDaemonMaestroRuntimePort), -request.ts, -response.ts, -observer.ts, -failure.ts, plus session-test-source-discovery.ts (inspectMaestroFlow).
  2. src/ import sites (4): src/cli/commands/replay.ts (static, lazy-loaded; export conversion), src/commands/schema/cli-help.ts (compat-reference strings), src/commands/replay/script-source-bundle.ts (dynamic; source closure), src/daemon/replay-device-selection.ts (dynamic; advisory device binding).
  3. Backend-id vocabulary spread across layers: ReplayFormat = 'ad' | 'maestro' in packages/ad-script, the --maestro flag in packages/command-registry, CommandFlags.maestro runtime flags, and Maestro-shaped ReplayDispatchOptions keys (closeAppOnly, observationOnly, gestureViewport, gestureExecutionProfile, settingsAppBundleId).
  4. No engine-plugin seam exists. src/plugins/* is scoped to provider runtimes only (plugins.md: plugins cannot register arbitrary commands). The registration culture to follow is src/core/platform-plugin-registry.ts + register-builtins.ts: static registration, lazy implementation.

Explicitly out of scope: the maestro-direct-selector / maestro-non-hittable-fallback iOS fast paths and the flags.maestro.* daemon runtime flags. Per the comment in interaction-guarantees.ts, those are not the flow engine; they stay in shared runtimes. Decide during extraction whether that flag namespace gets renamed or documented as replay-compat vocabulary.

Required behavior

  • Seam first (in flight): an owning replay-engine port that the daemon/replay-port depend on, with maestro as the single registered implementation behind a backend id. No npm-style dynamic loading in the seam PR — one static registration site in the daemon composition, structured so the extraction PR swaps it for a dynamic lookup.
  • Behavior unchanged through the seam: same CLI surface (replay --maestro, test --suites, replay export, help maestro), same daemon dispatch keys and response shapes, same error projection and divergence suggestions.
  • Laziness preserved: the CLI startup import closure must never evaluate the engine (cli-startup-import-closure.test.ts pins this; the replay closure may evaluate it only inside flow source collection). Any registry module's eager closure stays engine-free; eager-closure budgets must not grow.
  • Performance preserved (ADR 0015): the seam must not add a round trip, a second hierarchy capture, or per-operation indirection cost between MaestroRuntimeOperations and invoke. Android stays faster than upstream Maestro.
  • Conformance preserved: pnpm maestro:conformance and the layer-3 differential keep running against the extracted engine with declared divergences only.
  • Extraction (0.22 target): move @agent-device/maestro out of the root workspace dependency, narrow its package exports to exactly what the plugin host needs, and decide whether ./daemon-runtime-port (host-side adapter glue) stays an engine export or moves to the plugin package.

Completion conditions

  • Seam PR merged: replay-port and src/ import an owning port/registry, not @agent-device/maestro; check:layering, check:di-seams, maestro:conformance, and check:affected --run green.
  • Backend-id vocabulary owned in one place; the Pick<ReplayDispatchOptions, keyof MaestroDaemonDispatchOptions> key-lock invariant survives the split.
  • Engine reachable only through the registration seam (grep proof: no production imports of @agent-device/maestro outside the registration/adapter site).
  • Plugin package extracted with its own manifest and a host contract versioned like apiVersion in src/plugins/manifest.ts.
  • Layering bookkeeping resolved at each owning type: architecture-ownership.ts, model.ts rank, daemon-modularity.ts engine prefixes, package-boundaries.test.ts export/dependency pins, .fallowrc.json, check-affected routing, conformance CI lanes.

Dependencies

  • Blocked by: the seam PR (linked below) landing first.
  • Related policy: ADR 0015 (direct engine, five responsibilities, performance contract), ADR 0013 (gesture normalization boundary must survive), docs/dependency-graph-findings.md (#2544 adapter inversion).
Linguagem predominante
TypeScript
Estrelas
5.2k
Forks
359
Merge médio
12h 54min
PRs com merge (30d)
637

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de callstack/agent-device

Todas as issues de callstack/agent-device

Issues semelhantes

Mais issues de TypeScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.