Skip to content

dongguri-jun/embedctl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

172 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

embedctl embedded device control plane

embedctl

ADB-like debugging, testing, deployment, evidence, and profiling for embedded devices.

release ci runtime mcp


embedctl gives embedded-device projects one local control plane for target profiles, policy-gated shell access, plan/apply file transfer and deploys, runtime logs, bug reports, evidence artifacts, performance artifacts, release checks, and OpenCode/MCP agent workflows. It is centered on embedded Linux appliance targets first. Flutter/flutter-pi support is an implemented runtime profile, not the shape every downstream project must fit.

Overview

embedctl is built around three public, reusable surfaces:

Surface What it gives you Safety stance
embedctl Local CLI for devices, deploy plans, logs, evidence, profiling, and release checks Plan/apply boundaries, typed JSON, fail-closed evidence
embedctl-mcp Thin MCP wrapper over the same CLI JSON surface No separate mutation logic, same policy gates
Target profiles Reusable declarations for runtime, transport, capabilities, and agent policy Private access details stay outside public examples

Why teams use it:

  • declare target capabilities once in public-safe or private target profiles,
  • preview mutations as hash-verified plans before applying them,
  • collect local evidence artifacts that can feed human review, agents, and release gates,
  • let MCP-capable coding agents use the same CLI JSON contract as humans.

⚑ Quickstart

1. Install

git clone https://github.com/dongguri-jun/embedctl.git
cd embedctl
bash scripts/install-local.sh
embedctl --version

From a checkout, the installer builds from source when Dart is installed and otherwise falls back to matching GitHub Release binaries. Release binary assets are attached by releases created after this installer change.

It writes two user-facing commands by default:

$HOME/.local/bin/embedctl
$HOME/.local/bin/embedctl-mcp

Latest stable release: v0.2.3. The repository may be on the next -dev version after a release.

2. Verify the public example profiles

embedctl profile validate examples/profiles/flutter-pi-panel.json --json
embedctl devices --json --profiles-dir examples/profiles
embedctl capabilities --target flutter-pi-panel-example --json --profiles-dir examples/profiles

The examples are intentionally non-mutating and public-safe. They validate the command surface without requiring a real target.

3. Connect an MCP client

Most MCP clients can run the local stdio server directly:

{
  "mcpServers": {
    "embedctl": {
      "command": "embedctl-mcp"
    }
  }
}

For OpenCode project config, use the local MCP shape:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "embedctl": {
      "type": "local",
      "command": ["embedctl-mcp"],
      "enabled": true,
      "timeout": 30000
    }
  }
}

Private target profiles, adapter directories, workflow files, payload registries, screenshots, logs, bugreports, and real device access details should stay in downstream repositories or private overlays. Public examples in this repository are neutral fixtures for exercising the CLI behavior.

🧭 Control-plane map

Need Command group First command to try
Know what targets exist devices, capabilities, doctor embedctl devices --json --profiles-dir examples/profiles
Preview file/deploy changes push, pull, sync, deploy, apply embedctl deploy --target <id> --json --plan --bundle <bundle-path>
Observe runtime state logs, screencap, visual, bugreport embedctl logs --target <id> --json
Prove release readiness release-check, evidence inspect, evidence diff embedctl release-check --target <id> --json
Measure performance profile steady, profile run, profile frames, profile compare embedctl profile steady --target <id> --output evidence/profile-steady --json
Let agents use it embedctl-mcp embedctl-mcp

🧱 Scope and safety model

embedctl is local-first, multi-device by design, multi-OS-ready by architecture, and AI-native by default. The core model is profile-driven Linux appliance development: declare a target, preview mutations, apply explicitly, collect logs/evidence, and keep private access details outside public examples.

The current implementation includes strong flutter-pi support because it was the first runtime profile to exercise deploy, visual, bridge, and profiling paths. That runtime is optional. Projects that only need SSH, systemd, journal, file transfer, reboot/reconnect workflows, and evidence collection should not need Flutter or Dart on the target.

The core product is the CLI and its stable JSON output. MCP servers, agent skills, and wrappers must stay thin adapters over that CLI surface rather than reimplementing deployment, profiling, evidence, or bridge semantics.

embedctl is not a general-purpose OS administration tool, not a replacement for SSH/systemd/journalctl/rsync, and not a replacement for flutter-pi or flutterpi_tool. It composes those tools behind explicit profiles, plan/apply mutation boundaries, release evidence, and hardware sizing reports.

Project-specific behavior does not belong in core. App routes, product workflows, sensitive payload formats, target hosts, target paths, screenshots, logs, bugreports, and real device access details belong in adapters, target profiles, examples, or private overlays.

✨ Capabilities

  • target/device registry and capability discovery
  • policy-gated SSH shell, file transfer, deploy, run, restart, and log commands
  • screenshots, host-side visual captures, bug reports, evidence manifests, and release checks
  • app bridge planning for route/state/test flows without putting app semantics in core
  • secret-safe payload handles and redaction status for sensitive workflows
  • CPU, memory, thermal, pressure, launch, frame, and workload profiling artifacts
  • AI-safe JSON output, typed errors, audit trails, and MCP access through embedctl-mcp

πŸ“š Documentation map

  • docs/reference-adoption.md explains which external projects embedctl should borrow from, adapt, integrate, or avoid cloning.
  • docs/evidence-model.md defines the evidence bundle shape used by generated bugreport artifacts and inspection commands.
  • docs/downstream-agent-integration.md explains how downstream app projects should wire embedctl into project-local AGENTS.md, private profiles, adapter manifests, and evidence workflows.
  • docs/host-camera-capture.md explains host-side visual evidence capture through declared host camera sources.
  • docs/scanner-evidence.md defines generic scanner lifecycle, preview, decode, redaction, and resource-release evidence without product-domain payload semantics.
  • docs/workflow-evidence.md defines generic planned, executed, and observed workflow proof for downstream adapters without putting app-specific routes in core.
  • docs/performance-gates.md explains the implemented v0.2 performance evidence path for structured target sampling, app/scanner telemetry ingestion, app-telemetry frame evidence, normalized metric schemas, and explicit release-check --performance-policy gates, plus future backend expansion notes.
  • docs/plan-apply.md defines mutation safety and agent policy gates.
  • docs/provider-interface.md defines the read-only v0.3 provider skeleton and future adapter boundary.
  • docs/public-safety.md defines the public/private boundary, local-only data rules, and public repository safety checks.
  • docs/release-management.md defines VERSION, CHANGELOG, tag, and GitHub Release policy.
  • docs/supported-environments.md tracks public-safe example, tested, supported, and experimental environments plus recommended settings by runtime/profile class.
  • docs/agent-ux.md defines AI-agent command, snapshot, wrapper, and evidence expectations.
  • examples/agent-guides/ contains copyable downstream AGENTS.md, adapter manifest, and target profile starter templates for project-local AI usage rules.
  • examples/profiles/ contains public-safe target profile fixtures validated by the test suite.
  • packages/embedctl_bridge/ contains an importable, default-disabled app-side bridge package for QA adapters; the CLI still treats bridge workflows as planned output until a declared live bridge backend executes them.
  • packages/embedctl_mcp/ contains the local MCP stdio adapter. It is a thin wrapper over the CLI JSON surface and should be installed as embedctl-mcp next to the embedctl binary.

πŸ› οΈ Install details

The checkout installer compiles both native commands. Use --bin-dir or EMBEDCTL_BIN_DIR to install somewhere other than $HOME/.local/bin:

bash scripts/install-local.sh --bin-dir /tmp/embedctl-bin

For source-tree development, Dart entrypoints still work, but they are not the intended downstream install surface:

dart run packages/embedctl_cli/bin/embedctl.dart --version
dart run packages/embedctl_cli/bin/embedctl.dart devices --json --profiles-dir examples/profiles

πŸ’» CLI reference

Start with the installed embedctl command. Use --json for agent-safe structured output, --plan to preview mutations, and --apply --plan-file <path> when a saved plan is ready to execute.

Area Example
Profile validation embedctl profile validate examples/profiles/flutter-pi-panel.json --json
Device discovery embedctl devices --json --profiles-dir examples/profiles
Capability discovery embedctl capabilities --target flutter-pi-panel-example --json --profiles-dir examples/profiles
File transfer planning embedctl push --target <id> --json --plan --profiles-dir examples/profiles <local> <remote>
Deploy planning embedctl deploy --target <id> --json --plan --bundle <bundle-path> --profiles-dir examples/profiles
Runtime logs embedctl logs --target <id> --json --profiles-dir examples/profiles
Evidence inspection embedctl evidence inspect evidence-bundle --json
Performance sampling embedctl profile steady --target <id> --duration 60s --interval 1s --output evidence/profile-steady --json --profiles-dir examples/profiles
Provider skeleton embedctl provider list --json
Doctor checks embedctl doctor --target <id> --json --profiles-dir examples/profiles
Detailed command behavior

The profile validation, device listing, and capability reporting commands are read-only. They load local JSON target profiles, return typed JSON results, and perform no target mutation. devices --json emits safe target summaries and capabilities --json reports declared capability groups plus agent policy limits. Both omit remote addresses, install paths, and launch commands.

embedctl shell --json runs through the configured target transport only when the target profile explicitly allows shell in agent_policy.allowed_commands. JSON output preserves the child command exit code, stdout, and stderr separately while keeping target remote details, install paths, and launch commands out of the response. Raw shell is intentionally policy-gated because it is powerful and should not be the primary AI-agent interface.

embedctl push, pull, and sync emit hashed plan JSON with target profile hashes in --plan --json mode. --apply --plan-file verifies the saved plan hash, current target profile hash, target policy permission for the specific command plus apply, and remote paths inside the declared install root before executing. Initial file-transfer apply is conservative: it copies files/directories through the configured file transport but refuses overwrite/delete semantics.

embedctl deploy --plan emits a hashed deploy plan with runtime mode metadata, sync/restart steps, and target profile hash. embedctl apply --plan-file verifies the saved plan hash and current target profile hash, then executes supported deploy steps through the configured transport. run and restart support --plan for preview and --apply for explicit live execution; restart never performs broad process matching when no service is declared. logs reports the configured service log source as a read-only JSON descriptor in non-follow mode, and logs --follow runs bounded, policy-gated live probes for declared service logs rather than unbounded streaming.

embedctl screencap writes a local PNG artifact when the target profile declares a screenshot backend and marks visual sensitivity as unknown. embedctl visual sources reports declared visual evidence sources, and embedctl visual capture can write local host-camera artifacts through an explicit host-side source such as host-camera; JSON output uses public-safe source labels rather than leaking local device paths. embedctl release-check evaluates release-build evidence from canonical hierarchical paths such as build/, deploy/, runtime/, release/, and bridge/, with legacy flat file names kept as fallback; missing proof becomes incomplete, while fatal logs, bridge timeouts, and unknown non-empty .err files fail closed. embedctl bugreport writes a local v0.2 evidence bundle directory with metadata, generated logs, redaction status, NDJSON transcript, verdict, and SHA-256 manifest files; --evidence-dir imports collected evidence under evidence/<relativePath> without flattening same-named files. embedctl evidence inspect validates required files, manifest hashes, transcript shape, and proof sufficiency across recursive evidence/ and logs/ content. embedctl evidence diff compares target profile hash, verdict, and artifact hashes between two local evidence bundles.

embedctl bridge snapshot returns a profile-derived app bridge snapshot without attempting a hidden connection. bridge batch validates a local flow, preserves assertions/expect blocks, and returns per-step planned status so acceptance checks stay visible without being mistaken for live app-state proof. workflow replay wraps bridge batch planning; workflow record supports seed --step recording plus a safe --live prototype that either records a profile-declared snapshot flow without payload values or returns typed unavailable JSON. profile launch, profile steady, and profile frames report measurable host Linux facts or explicit source/status/confidence/unknowns/next_actions states rather than guessing target metrics. profile run executes a bounded workload through the declared target shell and writes local artifacts, while profile compare compares compatible metrics conservatively and marks mismatches as not comparable. provider list and provider doctor expose read-only prototype adapter and hook contract records without lab access, lab leases, power control, measurement collection, or OTA mutation.

embedctl doctor --json emits read-only profile-driven checks for flutter-pi architecture, KMS/DRI graphics, render-device access, display conflicts, launch flag consistency, build/runtime artifacts, and input metadata. When the target policy allows shell, doctor enriches selected checks with read-only live probes; otherwise probe-dependent checks remain unknown rather than guessed.

πŸ§ͺ Development

See CONTRIBUTING.md for development rules, including the policy to install needed tooling immediately and keep verification scripts updated.

βœ… Verification

Run the same checks locally that CI runs on GitHub. The verifier also checks that VERSION, package versions, CLI output, and release documentation stay in sync:

bash scripts/verify.sh

The verifier checks Dart formatting, static analysis, tests, CLI smoke behavior, Markdown hygiene, local links, high-signal sensitive/local-only strings, public JSON fixtures, and Git diff whitespace.

πŸ—‚οΈ Project management

  • ROADMAP.md defines the milestone-gated schedule for v0.1, v0.2, and v0.3.
  • TASKS.md tracks implementation and documentation backlog items before they are migrated to GitHub Issues.
  • VERSION, CHANGELOG.md, and docs/release-management.md track release readiness before tags or GitHub Releases exist.
  • GitHub Issues should mirror these tasks once implementation starts, with each issue carrying phase, deliverable, verification, and safety notes.

πŸ“ Status

embedctl currently ships an implemented local CLI, a default-disabled app-side bridge package, public-safe target profile fixtures, profiling/evidence commands, a thin local MCP stdio adapter, and release tracking through VERSION and CHANGELOG.md.

Mutation support is explicit only: apply, file-transfer --apply --plan-file, run --apply, restart --apply, and profile run -- <command> mutate only after a saved plan, explicit apply flag, or explicit workload command. Unsupported unsafe process matching fails closed.

Live log streaming, interactive workflow recording, real target profiling probes, and provider hardware mutation remain follow-up work.

About

ADB-like debugging, testing, deployment, and profiling for embedded Flutter/Linux apps.

Resources

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors