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
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ Guidance for Claude Code working in the `fluttersdk_telescope` repo. Path-scoped

## Stack

Flutter SDK package (Dart 3.4+, Flutter 3.22+). Plugin of `fluttersdk_artisan ^0.0.6`: contributes
Flutter SDK package (Dart 3.4+, Flutter 3.22+). Plugin of `fluttersdk_artisan ^0.0.8`: contributes
`TelescopeArtisanProvider` with 6 CLI commands plus 9 MCP tools backed by 11 `ext.telescope.*` VM Service
extensions.

Production deps are hosted only (no `pubspec_overrides.yaml`): `fluttersdk_artisan ^0.0.6`, `logging ^1.2.0`,
Production deps are hosted only (no `pubspec_overrides.yaml`): `fluttersdk_artisan ^0.0.8`, `logging ^1.2.0`,
`meta ^1.16.0`. Dev deps: `flutter_test`, `flutter_lints ^5.0.0`. Debug-only at the consumer call site: the
consumer wraps `TelescopePlugin.install()` in `if (kDebugMode)` so release builds tree-shake the subsystem.

Expand Down
15 changes: 8 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ This project follows [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.

## [Unreleased]

### Fixed

- **`telescope:install` no longer injects the `magic_devtools` import when `lib/main.dart` has no `await Magic.init(` anchor.** Previously, the magic-side wiring block fired for any project that listed `magic_devtools` in pubspec regardless of whether the app called `Magic.init`. On a vanilla Flutter app this left an unused import that broke `dart analyze` in the consumer. The block is now gated on `hasMagicInit && _hasMagicDevtoolsDep()` so the import and `MagicTelescopeIntegration.install()` call are only injected for Magic-stack apps that actually call `Magic.init`. The existing try/catch around `injectAfterMagicInit` is retained as a defensive backstop.
## [0.0.4] - 2026-06-17

### Changed

- **`telescope:install` now injects `import 'package:magic_devtools/telescope.dart';` and gates the Magic-stack wiring on the `magic_devtools` dependency** instead of the removed `package:magic/telescope_integration.dart`. Coordinated with the `magic_devtools` extraction that moved `MagicTelescopeIntegration` out of the magic core package. The injected `MagicTelescopeIntegration.install()` call and all other wiring are unchanged.
- **`fluttersdk_artisan` constraint bumped `^0.0.6` -> `^0.0.8`.** Required for co-installability with `fluttersdk_dusk` 0.0.7, which declares `fluttersdk_artisan: ^0.0.8`. Without this bump, a downstream package listing both `fluttersdk_dusk: ^0.0.7` and `fluttersdk_telescope` would fail pub dependency resolution. No public API change; constraint only.
- **`telescope:install` now injects `import 'package:magic_devtools/telescope.dart';` and gates the Magic-stack wiring on the `magic_devtools` dependency** instead of the removed `package:magic/telescope_integration.dart`. Coordinated with the `magic_devtools` extraction that moved `MagicTelescopeIntegration` (plus the 5 Magic watchers and `MagicHttpFacadeAdapter`) out of the magic core package. The injected `MagicTelescopeIntegration.install()` call and all other wiring are unchanged.

## [0.0.4] - 2026-06-17
### Fixed

### Changed
- **`telescope:install` no longer injects the `magic_devtools` import when `lib/main.dart` has no `await Magic.init(` anchor.** Previously, the magic-side wiring block fired for any project that listed `magic_devtools` in pubspec regardless of whether the app called `Magic.init`. On a vanilla Flutter app this left an unused import that broke `dart analyze` in the consumer. The block is now gated on `hasMagicInit && _hasMagicDevtoolsDep()` so the import and `MagicTelescopeIntegration.install()` call are only injected for Magic-stack apps that actually call `Magic.init`. The existing try/catch around `injectAfterMagicInit` is retained as a defensive backstop.

- **`fluttersdk_artisan` constraint bumped `^0.0.6` -> `^0.0.8`.** Required for co-installability with `fluttersdk_dusk` 0.0.7, which declares `fluttersdk_artisan: ^0.0.8`. Without this bump, a downstream package listing both `fluttersdk_dusk: ^0.0.7` and `fluttersdk_telescope` would fail pub dependency resolution. No public API change; constraint only.
### Documentation

- Synced docs, skill files, `README.md`, and `CLAUDE.md` to the `magic_devtools` extraction and the `fluttersdk_artisan ^0.0.8` bump. The Magic-stack telescope adapter is now documented as shipping in `magic_devtools` (imported via `package:magic_devtools/telescope.dart`, added as a dev_dependency); the installation / quickstart / watchers pages, the MCP setup snippet, and the skill (`SKILL.md` + references) reflect the `magic_devtools` dependency gate and import. Dependency-version pins bumped from `^0.0.3` to `^0.0.4` across `README.md`, `doc/getting-started/installation.md`, `doc/getting-started/quickstart.md`, and `doc/mcp/setup.md`; skill version stamp bumped to 0.0.4.

## [0.0.3] - 2026-05-28

Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ Guidance for Claude Code working in the `fluttersdk_telescope` repo. Path-scoped

## Stack

Flutter SDK package (Dart 3.4+, Flutter 3.22+). Plugin of `fluttersdk_artisan ^0.0.6`: contributes
Flutter SDK package (Dart 3.4+, Flutter 3.22+). Plugin of `fluttersdk_artisan ^0.0.8`: contributes
`TelescopeArtisanProvider` with 6 CLI commands plus 9 MCP tools backed by 11 `ext.telescope.*` VM Service
extensions.

Production deps are hosted only (no `pubspec_overrides.yaml`): `fluttersdk_artisan ^0.0.6`, `logging ^1.2.0`,
Production deps are hosted only (no `pubspec_overrides.yaml`): `fluttersdk_artisan ^0.0.8`, `logging ^1.2.0`,
`meta ^1.16.0`. Dev deps: `flutter_test`, `flutter_lints ^5.0.0`. Debug-only at the consumer call site: the
consumer wraps `TelescopePlugin.install()` in `if (kDebugMode)` so release builds tree-shake the subsystem.

Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ After install, the consumer gets the artisan fast-cli at `./bin/fsa` (native AOT
| 🔌 | **Adapter Contract** | `TelescopeHttpAdapter` (abstract, 3-method shape) for plugging any HTTP client; ships `DioHttpAdapter` for vanilla Dio |
| 📋 | **9 Record Types** | Immutable: `HttpRequestRecord`, `LogRecordEntry`, `ExceptionRecord`, `MagicModelRecord`, `MagicCacheRecord`, `EventRecord`, `GateRecord`, `DumpRecord`, `QueryRecord` |
| 📡 | **VM Service Extensions** | 11 extensions: `ext.telescope.requests`, `.console`, `.exceptions`, `.events`, `.gates`, `.dumps`, `.queries`, `.caches`, `.clear`, `.pause`, `.resume` |
| ✨ | **Magic Integration** | `MagicTelescopeIntegration.install()` wires Http facade adapter + model/cache/event/gate watchers in one call |
| ✨ | **Magic Integration** | `MagicTelescopeIntegration.install()` wires Http facade adapter + model/cache/event/gate watchers in one call (ships in the `magic_devtools` dev_dependency) |
| 🔒 | **Debug-only Gate** | Consumer wraps install inside `if (kDebugMode)`; release builds tree-shake the entire telescope branch on all platforms |
| 🔄 | **Idempotent Install** | Every `registerExtension` call routes through `registerExtensionIdempotent`; hot-restart safe, no `ArgumentError` on re-registration |

Expand Down Expand Up @@ -86,7 +86,7 @@ For everyday repeat usage, the consumer's `./bin/fsa` (artisan native AOT binary
```yaml
# pubspec.yaml
dependencies:
fluttersdk_telescope: ^0.0.3
fluttersdk_telescope: ^0.0.4
```

#### 2. Install in `main.dart`
Expand All @@ -96,6 +96,7 @@ Install Telescope before `Magic.init()` (or before `runApp` for plain Flutter).
```dart
import 'package:flutter/foundation.dart';
import 'package:fluttersdk_telescope/telescope.dart';
import 'package:magic_devtools/telescope.dart'; // magic_devtools dev_dependency (Magic-stack apps only)

void main() async {
WidgetsFlutterBinding.ensureInitialized();
Expand All @@ -114,6 +115,8 @@ void main() async {
await Magic.init(configFactories: [...]);

if (kDebugMode) {
// MagicTelescopeIntegration ships in magic_devtools (not magic core).
// Add magic_devtools to dev_dependencies in pubspec.yaml.
MagicTelescopeIntegration.install();
}

Expand Down
2 changes: 1 addition & 1 deletion doc/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Out of the box after `telescope:install`, Telescope captures:
- **Exceptions**: uncaught errors via `ExceptionWatcher` (opt-in, chain-preserves Sentry/Bugsnag).
- **debugPrint output**: via `DumpWatcher` (opt-in, chain-preserves prior override).

With the Magic stack (`MagicTelescopeIntegration.install()`):
With the Magic stack (`MagicTelescopeIntegration.install()` from `magic_devtools`):

- **HTTP traffic** through the Magic `Http` facade.
- **Model lifecycle**: create, save, delete events on Magic Eloquent models.
Expand Down
23 changes: 16 additions & 7 deletions doc/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ The command performs three operations in order:
if it is missing. This is a no-op when the harness is already present.
2. Runs `plugin:install fluttersdk_telescope`, which registers `TelescopeArtisanProvider`
in `.artisan/plugins.json` and refreshes the codegen barrel.
3. Patches `lib/main.dart` to call `TelescopePlugin.install()` before `runApp`. When using
the Magic framework, the patch places the call before `Magic.init()` so the Http facade
is wired before MagicTelescopeIntegration runs. The patch is wrapped in a `kDebugMode`
guard automatically.
3. Patches `lib/main.dart` to call `TelescopePlugin.install()` before `runApp`. When the
consumer's `pubspec.yaml` lists `magic_devtools:` (as a dependency or dev_dependency) and
`lib/main.dart` contains `await Magic.init(`, the patch also injects
`import 'package:magic_devtools/telescope.dart';` plus a `MagicTelescopeIntegration.install()`
block after `Magic.init()`. All patches are wrapped in a `kDebugMode` guard automatically.

The command is idempotent. Re-running it when the files are already patched is safe.

Expand All @@ -71,11 +72,17 @@ patch cannot locate the correct anchor in `lib/main.dart`.

### 1. Add the dependency

Add `fluttersdk_telescope` to `pubspec.yaml`:
Add `fluttersdk_telescope` to `pubspec.yaml`. For Magic-stack apps, also add `magic_devtools`
to `dev_dependencies`: that package ships `MagicTelescopeIntegration` and the 5 Magic-specific
watchers (previously part of the `magic` core package).

```yaml
dependencies:
fluttersdk_telescope: ^0.0.3
fluttersdk_telescope: ^0.0.4

# Magic-stack apps only:
dev_dependencies:
magic_devtools: any
```

Then fetch dependencies:
Expand All @@ -93,6 +100,7 @@ MagicTelescopeIntegration runs:
```dart
import 'package:flutter/foundation.dart';
import 'package:fluttersdk_telescope/telescope.dart';
import 'package:magic_devtools/telescope.dart'; // magic_devtools dev_dependency (Magic-stack apps only)

void main() async {
WidgetsFlutterBinding.ensureInitialized();
Expand All @@ -112,7 +120,8 @@ void main() async {

if (kDebugMode) {
// 4. Magic-specific adapters resolve framework internals from the IoC container;
// they must run after Magic.init().
// they must run after Magic.init(). MagicTelescopeIntegration ships in
// magic_devtools; add it to dev_dependencies alongside fluttersdk_telescope.
MagicTelescopeIntegration.install();
}

Expand Down
20 changes: 13 additions & 7 deletions doc/getting-started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ looks like:
```
[plugin:install] registered TelescopeArtisanProvider
[main.dart] injected TelescopePlugin.install() before framework init
[main.dart] injected MagicTelescopeIntegration.install() after Magic.init() (when using Magic framework)
[main.dart] injected import 'package:magic_devtools/telescope.dart';
[main.dart] injected MagicTelescopeIntegration.install() after Magic.init() (when magic_devtools is in pubspec)
telescope:install done
```

When using the Magic framework, `MagicTelescopeIntegration.install()` is also injected after
`Magic.init()` so all 9 watchers activate automatically. On a vanilla Flutter app only
the core watchers (`LogWatcher`, plus any you opt into manually) are wired.
When the consumer's `pubspec.yaml` lists `magic_devtools:` and `lib/main.dart` contains
`await Magic.init(`, the install command also injects the `package:magic_devtools/telescope.dart`
import and a `MagicTelescopeIntegration.install()` block after `Magic.init()` so all 9 watchers
activate automatically. `MagicTelescopeIntegration` ships in the `magic_devtools` package (not in
the `magic` core). On a vanilla Flutter app only the core watchers (`LogWatcher`, plus any you opt
into manually) are wired.

Verify the provider registered correctly. From now on, the artisan fast-cli at `./bin/fsa`
(native AOT, ~110ms warm) is the recommended entry point for every subsequent command:
Expand Down Expand Up @@ -146,7 +150,9 @@ are needed between queries; the buffers update passively as the app runs.

---

All three steps above use only the `fluttersdk_telescope ^0.0.3` package and its
All three steps above use only the `fluttersdk_telescope ^0.0.4` package and its
`fluttersdk_artisan` dependency. No additional packages are required for the core
watcher surface. Magic-specific watchers activate automatically when the Magic stack
is present and `MagicTelescopeIntegration.install()` is called.
watcher surface. Magic-specific watchers activate automatically when `magic_devtools`
is in `dev_dependencies` and `MagicTelescopeIntegration.install()` is called after
`Magic.init()`. `MagicTelescopeIntegration` ships in `magic_devtools`, not in the
`magic` core package.
11 changes: 8 additions & 3 deletions doc/mcp/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ because `TelescopePlugin` is imported by `lib/main.dart`):
```yaml
# pubspec.yaml
dependencies:
fluttersdk_telescope: ^0.0.3
fluttersdk_telescope: ^0.0.4
```

Run `dart pub get` after editing.
Expand Down Expand Up @@ -46,14 +46,19 @@ the call before `Magic.init()` so the Http facade is wired in time:
```dart
import 'package:flutter/foundation.dart';
import 'package:fluttersdk_telescope/telescope.dart';
import 'package:magic_devtools/telescope.dart'; // magic_devtools dev_dependency (Magic-stack apps only)

Comment on lines 46 to 50
Future<void> main() async {
if (kDebugMode) {
TelescopePlugin.install();
// Optional: when using the Magic framework, register its adapters and watchers.
// Call MagicTelescopeIntegration.install() after Magic.init().
}
await Magic.init(...);
if (kDebugMode) {
// Optional: when using the Magic framework, register its adapters and watchers.
// Call MagicTelescopeIntegration.install() after Magic.init(). Ships in the
// magic_devtools dev_dependency (import 'package:magic_devtools/telescope.dart').
MagicTelescopeIntegration.install();
}
runApp(MagicApplication());
}
```
Expand Down
27 changes: 23 additions & 4 deletions doc/watchers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,12 @@ matching by call order.
`pendingCount` returns the current length of the in-flight FIFO, surfaced into
`TelescopeStore.pendingHttpCount` for Dusk's network-idle detection.

Registration (via `MagicTelescopeIntegration`, the only documented entry point):
Registration (via `MagicTelescopeIntegration`, the only documented entry point; ships in
`magic_devtools` via `import 'package:magic_devtools/telescope.dart'`):

```dart
import 'package:magic_devtools/telescope.dart';

if (kDebugMode) {
TelescopePlugin.install();
MagicTelescopeIntegration.install(); // registers MagicHttpFacadeAdapter + 5 watchers
Expand All @@ -247,16 +250,18 @@ if (kDebugMode) {

## Magic-stack watchers

These five watchers are shipped inside the `magic` package via `MagicTelescopeIntegration`. They
are not part of the `fluttersdk_telescope` core. All five are registered by a single
`MagicTelescopeIntegration.install()` call.
These five watchers are shipped inside the `magic_devtools` package via `MagicTelescopeIntegration`.
They are not part of the `fluttersdk_telescope` core and are not part of the `magic` core package.
All five are registered by a single `MagicTelescopeIntegration.install()` call. Add `magic_devtools`
to `dev_dependencies` and import `package:magic_devtools/telescope.dart` to use them.

### MagicModelWatcher

| Field | Value |
|---|---|
| Contract | `TelescopeWatcher` |
| Name | `magic_model` |
| Package | `magic_devtools` (import `package:magic_devtools/telescope.dart`) |
| Auto-install | Yes (via `MagicTelescopeIntegration.install()`) |
| Ring buffer | `TelescopeStore._models` |
| VM extension | `ext.telescope.requests` (via models key; MCP tool: `telescope_models`) |
Expand All @@ -270,6 +275,8 @@ and `attributes` (snapshot of `model.attributes` at capture time).
Registration:

```dart
import 'package:magic_devtools/telescope.dart';

if (kDebugMode) {
TelescopePlugin.install();
MagicTelescopeIntegration.install(); // MagicModelWatcher is included
Expand All @@ -287,6 +294,7 @@ clean dispatcher call `EventDispatcher.instance.clear()` in their `setUp`.
|---|---|
| Contract | `TelescopeWatcher` |
| Name | `magic_cache` |
| Package | `magic_devtools` (import `package:magic_devtools/telescope.dart`) |
| Auto-install | Yes (via `MagicTelescopeIntegration.install()`) |
| Ring buffer | `TelescopeStore._caches` |
| VM extension | `ext.telescope.caches` |
Expand All @@ -300,6 +308,8 @@ Subscribes to five cache lifecycle events emitted by Magic's `CacheManager`: `Ca
Registration:

```dart
import 'package:magic_devtools/telescope.dart';

if (kDebugMode) {
TelescopePlugin.install();
MagicTelescopeIntegration.install(); // MagicCacheWatcher is included
Expand All @@ -316,6 +326,7 @@ if (kDebugMode) {
|---|---|
| Contract | `TelescopeWatcher` |
| Name | `magic_event` |
| Package | `magic_devtools` (import `package:magic_devtools/telescope.dart`) |
| Auto-install | Yes (via `MagicTelescopeIntegration.install()`) |
| Ring buffer | `TelescopeStore._events` |
| VM extension | `ext.telescope.events` |
Expand All @@ -333,6 +344,8 @@ follow-up release while the `EventRecord` wire shape stabilises.
Registration:

```dart
import 'package:magic_devtools/telescope.dart';

if (kDebugMode) {
TelescopePlugin.install();
MagicTelescopeIntegration.install(); // MagicEventWatcher is included
Expand All @@ -349,6 +362,7 @@ if (kDebugMode) {
|---|---|
| Contract | `TelescopeWatcher` |
| Name | `magic_gate` |
| Package | `magic_devtools` (import `package:magic_devtools/telescope.dart`) |
| Auto-install | Yes (via `MagicTelescopeIntegration.install()`) |
| Ring buffer | `TelescopeStore._gates` |
| VM extension | `ext.telescope.gates` |
Expand All @@ -369,6 +383,8 @@ anything else falls back to `toString()`.
Registration:

```dart
import 'package:magic_devtools/telescope.dart';

if (kDebugMode) {
TelescopePlugin.install();
MagicTelescopeIntegration.install(); // MagicGateWatcher is included
Expand All @@ -385,6 +401,7 @@ if (kDebugMode) {
|---|---|
| Contract | `TelescopeWatcher` |
| Name | `magic_query` |
| Package | `magic_devtools` (import `package:magic_devtools/telescope.dart`) |
| Auto-install | Yes (via `MagicTelescopeIntegration.install()`) |
| Ring buffer | `TelescopeStore._queries` |
| VM extension | `ext.telescope.queries` |
Expand All @@ -400,6 +417,8 @@ Surfaced via the `telescope:queries` CLI command and the `telescope_queries` MCP
Registration:

```dart
import 'package:magic_devtools/telescope.dart';

if (kDebugMode) {
TelescopePlugin.install();
MagicTelescopeIntegration.install(); // MagicQueryWatcher is included
Expand Down
Loading