Skip to content

Commit a5c2f50

Browse files
authored
Merge pull request #3 from leancodepl/flutter-read-logs
flutter-read-logs: add plugin for reading run logs as context
2 parents 7eb7518 + feb7119 commit a5c2f50

7 files changed

Lines changed: 461 additions & 0 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@
121121
"skills": [
122122
"./skills/flutter-marionette-usage"
123123
]
124+
},
125+
{
126+
"name": "flutter-read-logs",
127+
"source": "./plugins/flutter-read-logs",
128+
"description": "Read the running Flutter app's latest run logs as on-demand context — inspect what a flutter run already produced (incl. build errors and crashes), no live connection or instrumentation, via /read-logs.",
129+
"skills": [
130+
"./skills/flutter-read-logs-usage",
131+
"./skills/read-logs"
132+
]
124133
}
125134
]
126135
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Most plugins are pure rules and skills with no setup. A few need one-time toolin
8282
- [`flutter-ui`](plugins/flutter-ui/) - design-system-driven UI, loading/error patterns, localized presentation text, and UI implementation checklists
8383
- [`flutter-patrol`](plugins/flutter-patrol/) - Patrol test architecture, key conventions, and Patrol MCP workflow for AI-assisted E2E work
8484
- [`flutter-marionette`](plugins/flutter-marionette/) - runtime interaction with a live debug app through Marionette MCP for exploration, smoke checks, and UI debugging
85+
- [`flutter-read-logs`](plugins/flutter-read-logs/) - read the running app's latest `flutter run` logs as on-demand context via `/read-logs`
8586

8687
### Every plugin has a `-usage` skill
8788

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3+
"name": "flutter-read-logs",
4+
"displayName": "Flutter Read Logs",
5+
"description": "Read the running Flutter app's latest run logs as on-demand context — inspect what a flutter run already produced (including build errors and crashes), no live connection or instrumentation. Surfaces the relevant slice to Claude via /read-logs.",
6+
"version": "0.1.0",
7+
"author": {
8+
"name": "LeanCode"
9+
},
10+
"homepage": "https://github.com/leancodepl/ai-plugins",
11+
"repository": "https://github.com/leancodepl/ai-plugins",
12+
"keywords": [
13+
"flutter",
14+
"logs",
15+
"debugging",
16+
"runtime",
17+
"dap"
18+
],
19+
"skills": "./skills/"
20+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Changelog
2+
3+
## 0.1.0
4+
5+
- Initial `flutter-read-logs` plugin.
6+
- `skills/read-logs/SKILL.md` — capture and read the latest `flutter run` output as context, via `/read-logs`. Auto-detects Zed `script` transcripts and VS Code/Cursor `dapLogFile` (DAP) logs, reads task-led, flags stale runs, and guides first-run capture setup.
7+
- `skills/flutter-read-logs-usage/SKILL.md` — explain what the plugin does and route to setup.
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# flutter-read-logs
2+
3+
LeanCode Flutter plugin that lets Claude read the running app's `flutter run` output as
4+
on-demand context. Instead of pasting terminal logs, you run the app, then ask:
5+
6+
```
7+
/read-logs why is the login screen stuck
8+
```
9+
10+
Claude reads the most recent run's logs and works your task against them — it's a context
11+
loader, not an auto-analyzer.
12+
13+
## Included assets
14+
15+
- `skills/read-logs/SKILL.md` — the `/read-logs` workhorse: resolves the per-project log,
16+
auto-detects format, reads task-led, flags stale runs, and guides first-run setup.
17+
- `skills/flutter-read-logs-usage/SKILL.md` — explains the plugin and routes to setup.
18+
19+
## How it works
20+
21+
Each project logs to its own file, `/tmp/flutter-<repo>.log`, where `<repo>` is derived
22+
from the shared `.git` (`git rev-parse --git-common-dir`) — so the main checkout and every
23+
git worktree resolve to the **same** file. The file is overwritten on every launch (always
24+
the latest run) and lives in `/tmp` — outside the repo, nothing to gitignore, cleared on
25+
reboot. `/read-logs` derives the path at runtime and auto-detects the format.
26+
27+
The only per-developer step is making your editor write that file — **do it once.** If you
28+
run `/read-logs` before setting it up, the skill walks you through it (and offers to apply
29+
the change). It only edits **local** config; it never commits anything.
30+
31+
## ⚠️ Security / data handling — read this first
32+
33+
**Reading a run sends its contents to the model. That *is* the leak — it's how the tool
34+
works, and it can't be prevented.** Run logs routinely contain auth/refresh/push tokens,
35+
emails, account details, and other customer data. The file stays local in `/tmp`, but the
36+
moment `/read-logs` reads it, that slice goes to the model.
37+
38+
Treat this as a **conscious decision**:
39+
40+
- **Enabling capture** (the one-time setup below) is your opt-in — the skill confirms it
41+
with you before wiring anything up.
42+
- **Each `/read-logs`** announces the file it's about to read before reading it.
43+
- **Prefer test/staging data** when you'll `/read-logs`; avoid production or real-customer
44+
runs unless you've accepted the exposure.
45+
46+
If you need to read production-shaped logs, the durable mitigation is a **redaction pass**
47+
(mask tokens/emails/keys before the model sees them) — not yet built; tracked as a possible
48+
fast-follow. Raise it if your team wants it before adopting this widely.
49+
50+
In the snippets below, replace `myapp` with your repo's folder name (it must match the path
51+
`/read-logs` derives — i.e. `/tmp/flutter-<repo>.log`).
52+
53+
## VS Code / Cursor (one-time) — keeps F5
54+
55+
Add to your `.vscode/settings.json` (gitignored in most projects, so it stays local —
56+
correct, since the path is machine-specific):
57+
58+
```json
59+
{
60+
"dart.dapLogFile": "/tmp/flutter-myapp.log",
61+
"dart.maxLogLineLength": 1000000
62+
}
63+
```
64+
65+
- Keeps your normal debug workflow — **F5** and **Ctrl+F5** ("Run Without Debugging") both
66+
capture, because both run through the debug adapter. Breakpoints intact, no terminal hacks.
67+
- `maxLogLineLength` defaults to 2000 and truncates long lines; bump it so output and stack
68+
traces aren't cut.
69+
- Reload the window after adding (`Developer: Reload Window`) so Dart-Code picks it up.
70+
- **Cursor** is a VS Code fork using the same Dart-Code extension and `.vscode/settings.json`
71+
— identical setup.
72+
- Do **not** use `dapLogFile`'s `${workspaceName}` variable — it expands to the workspace
73+
folder (differs per worktree) and won't match how `/read-logs` derives the path.
74+
75+
**Caveats:**
76+
77+
- `dapLogFile` captures **debug-adapter sessions** (F5 / Ctrl+F5). If you launch via a plain
78+
terminal Run Task instead, use the Zed/`script` approach below.
79+
- App logs only reach the debug console (and the file) on devices that forward them: **iOS
80+
simulator / Android / macOS / the `chrome` device**. A **`-d web-server`** run sends app
81+
logs to the *browser's* DevTools console, not the editor — so the file will have
82+
build/launch output but no app logs.
83+
- Historical note: the old `dart.flutterRunLogFile` was **removed** from Dart-Code with the
84+
legacy debug adapters; `dapLogFile` is its replacement.
85+
86+
## Zed / terminal run task (one-time) — clean transcript
87+
88+
Wrap your run task's command in `script` so output is teed to the file while keeping the
89+
interactive console (hot reload). **`script`'s syntax differs by OS.**
90+
91+
**macOS (BSD `script`)** — logfile, then the command as trailing args, in `.zed/tasks.json`:
92+
93+
```json
94+
{
95+
"label": "Run app",
96+
"command": "script",
97+
"args": ["-q", "/tmp/flutter-myapp.log", "flutter", "run", "-t", "lib/main.dart"],
98+
"use_new_terminal": true
99+
}
100+
```
101+
102+
**Linux (GNU `script`)** — the command goes through `-c` as a single string, logfile **last**:
103+
104+
```json
105+
{
106+
"label": "Run app",
107+
"command": "script",
108+
"args": ["-q", "-c", "flutter run -t lib/main.dart", "/tmp/flutter-myapp.log"],
109+
"use_new_terminal": true
110+
}
111+
```
112+
113+
(Wrap whatever your existing run command is — including `fvm flutter …`, flavors, and
114+
`--dart-define`s — don't replace it.) **Windows** has no `script`; use the VS Code/Cursor
115+
`dapLogFile` path above, which is cross-platform.
116+
117+
`script` runs Flutter under a pseudo-TTY, so hot reload (`r`) / hot restart (`R`) keep
118+
working — unlike a plain `… | tee` pipe, which makes Flutter drop to non-interactive mode.
119+
This produces a clean text transcript (no JSON parsing needed). Web logs are captured here
120+
too, as long as the task uses `-d chrome` (not `-d web-server`).
121+
122+
## Note on duplicated setup
123+
124+
These setup steps also appear **inline** in `skills/read-logs/SKILL.md`, on purpose: that
125+
skill applies them at runtime, when the developer is in their editor and not reading this
126+
README. This `README.md` is the canonical copy — keep the two in sync when changing setup.
127+
128+
## Example usage
129+
130+
- `/read-logs <task>` — read the latest run's logs as context for `<task>`.
131+
- `/flutter-read-logs-usage` — short explanation of what this plugin does and how to set it up.
132+
133+
## Related plugins
134+
135+
- [`flutter-marionette`](../flutter-marionette/) — the **proactive** counterpart: it drives
136+
a *live* app (taps, navigation, hot reload, query state) via MCP, needing instrumentation
137+
and a running connection. `flutter-read-logs` is **reactive** — it reads what a run
138+
*already produced*, including build failures and crashed/exited runs, with no
139+
instrumentation or live app. Rule of thumb: **marionette to *make* things happen,
140+
read-logs to *see what happened*.** They're complementary — each catches what the other
141+
can't (marionette: live state; read-logs: build/crash output before any connection).
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
name: flutter-read-logs-usage
3+
description: Explain what the `flutter-read-logs` plugin does and how to use it. Use when the user invokes `/flutter-read-logs-usage`, asks what this plugin covers, or needs help setting up run-log capture for `/read-logs`.
4+
---
5+
6+
# Read Logs Usage
7+
8+
## How to respond
9+
10+
- If the user invoked this skill without a concrete task, explain what the plugin does and when to reach for `/read-logs`.
11+
- If they need setup, point them at this plugin's `README.md` (the canonical setup home) — VS Code/Cursor `dapLogFile`, or the Zed/`script` task.
12+
- If they already have a concrete log-reading task, briefly explain the fit and then run `/read-logs`.
13+
- Do not reply with filler like "skill loaded" or "ready for the task" before explaining the plugin.
14+
15+
## What this plugin does
16+
17+
- Lets Claude read the running app's latest `flutter run` output as on-demand context, via `/read-logs <task>` — instead of pasting terminal logs.
18+
- Captures `flutter run` output per-project to `/tmp/flutter-<repo>.log` (worktree-stable via `--git-common-dir`, overwritten each launch). Two formats, auto-detected: Zed `script` transcript and VS Code/Cursor `dapLogFile` (DAP).
19+
- Reads **task-led** — reads the whole short run, or investigates a long one against your question (errors, event ordering, a feature, …) — flags stale runs, and on first use guides editor setup.
20+
21+
## When to use it
22+
23+
- "Why did the app crash / behave like this at runtime?"
24+
- "Does the auth flow actually reach the API?"
25+
- "Trace the order these events fired" (races / timing).
26+
27+
## Setup
28+
29+
One-time per developer — full instructions in this plugin's `README.md` (VS Code/Cursor
30+
`dapLogFile` keeps the F5 workflow; Zed uses a `script`-wrapped run task). `/read-logs` also
31+
walks you through setup, and offers to apply it, the first time if no log file exists yet.
32+
33+
## Heads-up
34+
35+
Run logs can contain tokens and customer data, and `/read-logs` sends what it reads to the
36+
model — see the caution in `README.md`.
37+
38+
## Related
39+
40+
- `flutter-marionette` — the **proactive** counterpart: *interact* with a live app via MCP.
41+
Reach for it to *make* things happen; reach for `/read-logs` to *inspect* what a run
42+
already logged (including crashes/build errors marionette can't see, since it needs a live
43+
connection).

0 commit comments

Comments
 (0)