Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project follows [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.
### Changed

- mcp:install fallback now writes dart run fluttersdk_telescope mcp:serve when bin/fsa is absent (via wrapper's --invocation pass-through to fluttersdk_artisan's mcp:install).
- **`telescope:install` no longer depends on the AOT-compiled `bin/fsa`.** The chained subprocess calls (`install` + `plugin:install fluttersdk_telescope`) now spawn `dart run fluttersdk_telescope ...` directly through the telescope CLI wrapper, mirroring the Cat C subprocess pattern landed in `fluttersdk_dusk`. Consumers on a clean checkout (where fsa has not been compiled yet) can complete the bootstrap chain without a `ProcessException: No such file or directory` failure. **Behavior delta**: even consumers with `bin/fsa` scaffolded now invoke `plugin:install` through `dart run` (≈ a few seconds slower than the fsa AOT proxy on a single `telescope:install` invocation). Requires `dart` on `PATH` (always true on a Flutter dev box). Matches dusk's unconditional `dart run` pattern for cross-plugin consistency.

### Fixed

Expand Down
30 changes: 16 additions & 14 deletions lib/src/commands/telescope_install_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import 'package:fluttersdk_artisan/artisan.dart';
///
/// Runs the canonical install sequence in the consumer project:
///
/// 1. `dart run fluttersdk_artisan install` (only when
/// 1. `dart run fluttersdk_telescope install` (only when
/// `bin/dispatcher.dart` is missing; idempotent skip otherwise). This
/// step produces `bin/dispatcher.dart`, `bin/fsa` (the AOT fast-cli),
/// `lib/app/_plugins.g.dart`, and `lib/app/commands/_index.g.dart`.
/// 2. `./bin/fsa plugin:install fluttersdk_telescope` (always; the
/// underlying plugin:install + plugins:refresh are idempotent so re-runs
/// are safe). Uses fsa rather than `dart run fluttersdk_artisan ...`
/// because the latter still looks for the legacy `bin/artisan.dart`
/// wrapper file and rejects the new `bin/dispatcher.dart` layout
/// produced by step 1.
/// 2. `dart run fluttersdk_telescope plugin:install fluttersdk_telescope`
/// (always; the underlying plugin:install + plugins:refresh are
/// idempotent so re-runs are safe). Routes through the telescope CLI
/// wrapper (`bin/fluttersdk_telescope.dart`) which preloads
/// `TelescopeArtisanProvider` and sets `delegateToConsumer: false`, so
/// no `bin/fsa` AOT scaffold dependency exists at this stage and the
/// consumer can complete the chain on a clean checkout where fsa has
/// not been compiled yet.
/// 3. Inject the runtime wiring into `lib/main.dart` via
/// [MainDartEditor]: imports plus the `kDebugMode`-gated
/// [TelescopePlugin.install] + [ExceptionWatcher] + [DumpWatcher]
Expand Down Expand Up @@ -74,7 +76,7 @@ class TelescopeInstallCommand extends ArtisanCommand {
ctx.output.info('Consumer wrapper missing; running install...');
final scaffold = await processRunner(
'dart',
['run', 'fluttersdk_artisan', 'install'],
['run', 'fluttersdk_telescope', 'install'],
);
stdout.write(scaffold.stdout);
stderr.write(scaffold.stderr);
Expand All @@ -89,14 +91,14 @@ class TelescopeInstallCommand extends ArtisanCommand {
// 2. Register fluttersdk_telescope via plugin:install. Reads the
// install.yaml manifest shipped in this package and writes the entry
// to .artisan/plugins.json + regenerates lib/app/_plugins.g.dart.
// Invoked via ./bin/fsa (the AOT fast-cli scaffolded in step 1)
// because `dart run fluttersdk_artisan plugin:install` still looks for
// the legacy `bin/artisan.dart` wrapper and rejects the artisan v3
// `bin/dispatcher.dart` layout produced by step 1's `install`.
// Invoked via `dart run fluttersdk_telescope` (the telescope CLI
// wrapper which preloads `TelescopeArtisanProvider` and sets
// `delegateToConsumer: false`) so the chain works on a clean
// checkout without depending on the AOT-compiled `bin/fsa`.
ctx.output.info('Registering fluttersdk_telescope via plugin:install...');
final install = await processRunner(
'./bin/fsa',
['plugin:install', 'fluttersdk_telescope'],
'dart',
['run', 'fluttersdk_telescope', 'plugin:install', 'fluttersdk_telescope'],
);
stdout.write(install.stdout);
stderr.write(install.stderr);
Expand Down
18 changes: 12 additions & 6 deletions test/src/commands/telescope_install_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ void main() {

test(
'skips install when bin/dispatcher.dart already exists; '
'plugin:install still runs via ./bin/fsa', () async {
'plugin:install still runs via dart run fluttersdk_telescope',
() async {
final runner = _RecordingRunner();
TelescopeInstallCommand.processRunner = runner.run;
TelescopeInstallCommand.wrapperExistsCheck = () => true;
Expand All @@ -109,7 +110,9 @@ void main() {
expect(
runner.calls.single,
equals([
'./bin/fsa',
'dart',
'run',
'fluttersdk_telescope',
'plugin:install',
'fluttersdk_telescope',
]));
Expand All @@ -120,7 +123,7 @@ void main() {
// -------------------------------------------------------------------------

test(
'runs install (via dart run) then plugin:install (via ./bin/fsa) '
'runs install then plugin:install (both via dart run fluttersdk_telescope) '
'when bin/dispatcher.dart is missing (correct ordering)', () async {
final runner = _RecordingRunner();
TelescopeInstallCommand.processRunner = runner.run;
Expand All @@ -133,17 +136,20 @@ void main() {
expect(exit, equals(0));
expect(runner.calls, hasLength(2));
expect(runner.calls[0],
equals(['dart', 'run', 'fluttersdk_artisan', 'install']),
equals(['dart', 'run', 'fluttersdk_telescope', 'install']),
reason: 'install must run first (scaffolds dispatcher.dart + fsa)');
expect(
runner.calls[1],
equals([
'./bin/fsa',
'dart',
'run',
'fluttersdk_telescope',
'plugin:install',
'fluttersdk_telescope',
]),
reason:
'plugin:install must run after scaffold via the just-built fsa');
'plugin:install must run after scaffold via the telescope CLI '
'wrapper (no bin/fsa dependency at this stage)');
});

// -------------------------------------------------------------------------
Expand Down