Skip to content

Add ensemble enable command to run latest starter scripts from CLI #3

@sharjeelyunus

Description

@sharjeelyunus

Add a new CLI command:

ensemble enable

This command should allow users to enable optional Ensemble starter capabilities/modules directly from the CLI.

The CLI should not keep a copy of starter scripts inside the CLI repo. Instead, it should fetch the latest starter implementation from the Ensemble repo at runtime, cache it locally, and execute the scripts against the user’s current starter project.

The existing starter registry should remain the source of truth:

starter/src/modules_scripts.ts

Problem

Currently, starter capabilities are enabled through scripts in the starter project, for example via starter/package.json.

But users may have an older starter clone. That means:

User has old starter clone
↓
Local starter/package.json may not include latest commands
↓
Local starter/scripts may be missing or outdated
↓
User cannot enable newly added modules/capabilities

We need users to be able to run the latest starter enable scripts by updating only the CLI.

Expected behavior:

Old starter clone + latest CLI = latest enable functionality

Goal

The CLI should act as an orchestrator:

ensemble enable
↓
Fetch latest starter tooling from Ensemble repo at runtime
↓
Use starter/src/modules_scripts.ts as the module registry
↓
Cache the fetched starter tooling locally
↓
Run selected Dart scripts against the user's starter project

The CLI repo should stay clean and should not contain a cloned copy of starter/scripts.


Proposed command

Interactive mode:

ensemble enable

This should show all available options from starter/src/modules_scripts.ts.

Example:

? What do you want to enable?
  ◯ Camera
  ◯ Location
  ◯ Firebase Analytics
  ◯ Notifications
  ◯ Bluetooth
  ◯ Google Maps
  ◯ Stripe
  ◯ Remote Config
  ◯ Android Keystore

Direct mode:

ensemble enable camera
ensemble enable location
ensemble enable google_maps --googleMapsApiKey xxx
ensemble enable remote_config
ensemble enable generate_keystore

Multi-enable mode:

ensemble enable camera location google_maps --googleMapsApiKey xxx

Target project path:

ensemble enable camera --project ./my-starter-app

Source of truth

Use the existing file:

starter/src/modules_scripts.ts

This file should remain the registry for:

module name
script path
required parameters
prompt/question text
parameter types
available choices
platform-specific behavior

The CLI should fetch/use this file from the runtime-downloaded starter tooling.


Runtime fetching strategy

The CLI should fetch the latest starter tooling from the Ensemble repo at runtime.

Recommended MVP approach:

Download the GitHub ZIP/tarball for the selected ref:

EnsembleUI/ensemble main branch

Extract only the required starter files into the CLI cache, especially:

starter/src/modules_scripts.ts
starter/src/dart_runner.ts
starter/src/common-params.ts
starter/src/interfaces.ts
starter/scripts/**
starter/package.json

Cache location:

macOS/Linux:
~/.ensemble/cache/starter/main/

Windows:
%USERPROFILE%\.ensemble\cache\starter\main\

For pinned refs:

~/.ensemble/cache/starter/main/
~/.ensemble/cache/starter/v1.2.0/
~/.ensemble/cache/starter/8f3a9c1/

Important requirement

The CLI must not execute the user project’s local scripts.

Do not do this:

npm run hasCamera

Do not depend on:

<user-project>/starter/scripts
<user-project>/package.json scripts

Instead, the CLI should execute the fetched/cached starter tooling:

~/.ensemble/cache/starter/main/...

against the user’s project root.


Starter root detection

When --project is not provided, the CLI should detect the starter project root from the current working directory or parent directories.

Possible indicators:

pubspec.yaml with ensemble package
ensemble/ensemble.properties
lib/generated/ensemble_modules.dart

If no starter project is found, show:

Could not find an Ensemble starter project.

Run this command from your starter project root, or pass:

  ensemble enable camera --project ./path-to-starter

Script execution

Scripts should be executed from the cached starter tooling, but all file changes should target the user’s project.

The runner/scripts should support a project root argument:

--project-root /path/to/user/starter

Example:

dart run ~/.ensemble/cache/starter/main/scripts/modules/enable_camera.dart

Or, preferably, reuse the existing runner flow from the cached starter:

ts-node ~/.ensemble/cache/starter/main/src/dart_runner.ts camera

The implementation can choose the cleaner path, but the user project must only be the target, not the source of scripts.


Offline behavior

If the CLI cannot fetch the latest starter tooling:

If cache exists:

Could not fetch latest starter tooling.
Using cached starter tooling from main.

If no cache exists:

Could not fetch starter tooling and no cached version was found.

Please connect to the internet and retry:
  ensemble enable

UX requirements

After successful execution, show a clear summary:

Enabled:
  - Camera
  - Location
  - Google Maps

Scripts:
  Source: EnsembleUI/ensemble
  Ref: main
  Registry: starter/src/modules_scripts.ts

Modified:
  - pubspec.yaml
  - lib/generated/ensemble_modules.dart
  - android/app/src/main/AndroidManifest.xml
  - ios/Runner/Info.plist

Required argument behavior

For interactive mode:

ensemble enable

The CLI should prompt for missing required parameters based on modules_scripts.ts.

For direct mode:

ensemble enable google_maps

If required arguments are missing, fail clearly:

google_maps requires --googleMapsApiKey.

Example:
  ensemble enable google_maps --googleMapsApiKey YOUR_KEY

Error handling

If the project is not valid:

This does not look like an Ensemble starter project.

Expected:
  - pubspec.yaml
  - ensemble/ensemble.properties
  - lib/generated/ensemble_modules.dart

If runtime fetch fails and cache is unavailable, the command should stop safely without modifying the user project.


Acceptance criteria

  • ensemble enable opens an interactive selection prompt.
  • Options are loaded from starter/src/modules_scripts.ts.
  • No new manifest.json is introduced.
  • CLI does not contain cloned starter scripts in its repo.
  • CLI fetches starter tooling from the Ensemble repo at runtime.
  • CLI caches fetched starter tooling under ~/.ensemble/cache.
  • CLI can use cached tooling when offline.
  • CLI supports --scripts-ref.
  • CLI supports --project.
  • CLI detects the starter root automatically.
  • CLI does not call the user project’s local package.json scripts.
  • CLI does not rely on the user project’s local starter/scripts.
  • ensemble enable camera works for old starter clones.
  • ensemble enable google_maps --googleMapsApiKey xxx works without prompting.
  • CLI shows enabled modules, source ref, and modified files.
  • CLI tells the user to run flutter pub get when dependencies are changed.

Suggested MVP scope

Support these first, based on the current starter module scripts:

camera
location
firebase_analytics
notification
bluetooth
google_maps
stripe
remote_config
generate_keystore

MVP command support:

ensemble enable
ensemble enable camera
ensemble enable location
ensemble enable google_maps --googleMapsApiKey xxx
ensemble enable remote_config
ensemble enable generate_keystore
ensemble enable camera --project ./my-app

Final design decision

Do not do this:

CLI repo contains copied starter scripts

Do this:

CLI fetches starter tooling from Ensemble repo at runtime
CLI uses starter/src/modules_scripts.ts as registry
CLI caches tooling locally
CLI runs cached scripts against the user's starter project

This keeps the CLI repo clean and keeps the Ensemble starter repo as the single source of truth.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions