Skip to content

cockpit-dev/cockpit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

407 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cockpit logo

Cockpit 2.0

E2E License

简体中文

Cockpit is a production E2E automation and verification stack for AI, CI, and local development. Cockpit 2.0 controls installed Android and iOS applications as black boxes, drives Flutter applications through their richer semantic bridge, and exposes the same typed resources to CLI, MCP, and future independent clients.

It provides:

  • standalone YAML or JSON cases and suites;
  • semantic, native accessibility, system, visual, and coordinate planes;
  • target discovery, registration, launch, inspection, and capability truth;
  • dependency DAGs, fixtures, matrices, retries, bounded concurrency, and fail-fast suites;
  • durable run events, restart-safe suite checkpoints, exact session affinity, cancellation, artifacts, and JSON/JUnit/HTML/AI reports;
  • a per-user authenticated Supervisor with isolated per-workspace workers;
  • resource-oriented CLI, HTTP/SSE API, and MCP clients without a bundled GUI.

Packages

  • cockpit_protocol owns platform-neutral DTOs, the test DSL, JSON Schema, and OpenAPI contract.
  • cockpit owns the Supervisor, workspace workers, drivers, CLI, MCP server, reports, and artifacts.
  • flutter_cockpit is the optional in-app Flutter semantic, observation, capture, and recording bridge.

Minimum versions are Dart 3.8.0 and Flutter 3.32.0. Add only what the project uses:

dev_dependencies:
  cockpit: ^2.0.0
  flutter_cockpit: ^2.0.0 # Optional Flutter semantic bridge.

Keep Cockpit development-only. Native black-box testing does not require an application source dependency or a Flutter integration. Do not add flutter_cockpit imports to production lib/ code.

Runtime Model

cockpit commands discover or start one daemon under COCKPIT_HOME. The daemon owns authentication, workspace identity, authorization, admissions, leases, ports, run projections, and artifacts. It starts an isolated worker for each active workspace and engine version. No command relies on a global "latest" project or session.

CLI / MCP / third-party client
          |
    authenticated HTTP/SSE
          |
    per-user Supervisor
          |
  workspace-scoped worker
          |
 Flutter bridge / Android ADB / iOS WDA / host driver

Register multiple projects once, then address them explicitly or run a command from inside exactly one registered workspace:

dart run cockpit daemon start
dart run cockpit root add --path /work/projects --label projects
dart run cockpit workspace register --root-id <rootId> --path /work/projects/app-a
dart run cockpit workspace register --root-id <rootId> --path /work/projects/app-b
dart run cockpit workspace list

CLI Output

The default auto format is compact semantic text designed for agent terminal loops. Use --detail minimal|standard|full to control projection size, --stdout-format json for an exact protocol envelope, and jsonl for live run events. --output <file> atomically writes the complete JSON response and prints only a path, byte count, and SHA-256 receipt. Artifact bytes are always downloaded to --output; Cockpit never emits them as Base64.

Authorization

Dangerous operations and test safety effects are denied unless explicitly authorized. Persist policy under COCKPIT_HOME/authorization.json; validate and apply it through the CLI. A running daemon must be restarted so one process cannot change authority mid-run.

{
  "schemaVersion": "cockpit.supervisor.authorization/v2",
  "allowedDangerousOperations": [
    "app.launch",
    "app.restart",
    "app.stop",
    "command.batch",
    "command.run",
    "evidence.screenshot.capture",
    "lease.recover",
    "recording.start",
    "recording.stop",
    "system.action",
    "target.launch"
  ],
  "allowedOperationSafetyEffects": [
    "capture",
    "externalSideEffect",
    "permission",
    "recording",
    "reset",
    "system"
  ],
  "allowedTargetEnvironments": [
    "development",
    "test",
    "staging",
    "production"
  ],
  "allowedSafetyEffects": [
    "communication",
    "credentialSensitive",
    "destructive",
    "externalNavigation",
    "financial",
    "permissionChange"
  ],
  "allowedEnvironmentSecretNames": ["E2E_PASSWORD"]
}
dart run cockpit daemon policy validate --file authorization.json
dart run cockpit daemon policy apply --file authorization.json --restart
dart run cockpit daemon policy show

Only named environment secrets are copied into workspace workers. A policy may explicitly authorize production or unknown; the default policy does not. Quarantined leases remain blocked until verified cleanup succeeds. The Supervisor advertises lease.list and the reset-authorized lease.recover operation for exact lease/workspace/resource/holder identities. An explicit forceRelease: true may release an unverified logical resource; forwarded ports always require verified cleanup and can never be force released.

Black-Box Targets

Register an installed application without changing its source:

dart run cockpit target register \
  --workspace-id <workspaceId> \
  --platform android \
  --device-id emulator-5554 \
  --target-kind nativeApp \
  --app-id com.example.app \
  --environment test \
  --mode automation \
  --idempotency-key android-target-001

dart run cockpit target launch --workspace-id <workspaceId> --target-id <targetId> \
  --idempotency-key android-launch-001
dart run cockpit target inspect --workspace-id <workspaceId> --target-id <targetId>

Android uses ADB and native accessibility. iOS Simulator uses simctl; native iOS UI interaction uses a reachable WebDriverAgent endpoint. Physical iOS installation and lifecycle use devicectl where available. Cockpit reports unsupported or unavailable capabilities instead of claiming control it cannot prove.

Flutter targets accept a structured launch configuration across CLI, MCP, and operation run. Cockpit owns the entrypoint, device, mode, flavor, and remote control flags; callers can supply repeatable dart defines, define files, additional safe Flutter arguments, process environment values, and a launch budget up to 30 minutes:

dart run cockpit target launch \
  --workspace-id <workspaceId> \
  --target-id <flutterTargetId> \
  --dart-define API_URL=https://api.example.test \
  --dart-define-from-file config/staging.json \
  --env LOG_LEVEL=debug \
  --flutter-arg=--track-widget-creation \
  --launch-timeout-ms 1800000 \
  --idempotency-key flutter-launch-001

The equivalent operation input uses a launchConfiguration object with dartDefines, dartDefineFromFiles, flutterArgs, and environment. Launch configuration values are not returned in operation output. Do not pass Flutter launch fields to installed black-box targets.

Every advertised operation includes executionMode, defaultTimeoutMs, and maximumTimeoutMs. Synchronous operations block until their result and accept operation run --timeout-ms <value> or an absolute --deadline (not both). Case and suite runs are durable jobs: submission returns a runId immediately, then clients consume events and the terminal report. case run --timeout-ms defaults to 30 minutes and allows up to 6 hours; suite run --timeout-ms defaults to 2 hours and allows up to 24 hours. Step and cleanup timeouts remain independent inner budgets.

Cases And Suites

Cases and suites use schemaVersion: cockpit.test/v2. Validate documents before submitting them, and use stable idempotency keys for replay:

dart run cockpit case validate --workspace-id <workspaceId> --file cases/login.yaml
dart run cockpit case run --workspace-id <workspaceId> \
  --document-id <documentId> --case-id login \
  --idempotency-key login-2026-07-24 --inputs-json '{}' \
  --timeout-ms 1800000

dart run cockpit suite validate --workspace-id <workspaceId> --file suites/regression.yaml
dart run cockpit suite run --workspace-id <workspaceId> \
  --document-id <documentId> --suite-id regression \
  --idempotency-key regression-2026-07-24
dart run cockpit suite report --run-id <runId>

After worker termination, completed nodes stay complete, an active attempt becomes interrupted, and the suite continues only when its retry policy allows it. Persisted fixture and row bindings must resolve to the same healthy session; Cockpit fails explicitly when that session can no longer be proven.

MCP And Clients

Start the MCP stdio client with either command:

dart run cockpit serve-mcp
dart run cockpit_mcp

MCP is a thin authenticated Supervisor client. It does not construct drivers or application services in-process. It exposes bounded roots, workspaces, operations, targets, documents, cases, suites, runs, and artifacts. Official and third-party GUI clients should use /api/v2, authenticated SSE run events, public foundation DTOs, and digest-checked artifact downloads. Cockpit 2.0 intentionally ships no Flutter GUI and no embedded HTML dashboard; generated HTML reports are portable run artifacts.

Agent host setup, including the OpenCode/OMP skill, is documented in the agent integration guide.

Foreground CI

Foreground mode owns an isolated daemon, registers one checkout, submits a CockpitRunSubmission, waits for terminal truth, and exits from the run outcome:

dart run cockpitd \
  --home=/tmp/cockpit-ci \
  --foreground-workspace=/workspace/app \
  --foreground-submission=/workspace/run-submission.json

Release Gate

.github/workflows/example-e2e.yml is the required Cockpit 2.0 publication gate. Its quality job verifies formatting, static analysis, repository contracts, every package and example test suite, and dry-run publication for all three public packages. Only then does it run real Android, iOS, macOS, Linux, web, and Windows regression jobs. A release is eligible only when the quality job and every platform job complete successfully with terminal reports and verified artifacts. Wait for the whole matrix before diagnosing failures; use the uploaded report, event stream, artifacts, and daemon log as authority.

Documentation

Detailed package and protocol documentation:

About

In-app runtime primitives for AI-driven Flutter development workflows.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages