Wrap a new backend endpoint in the TypeScript SDK (packages/sdk), or record it as skipped. Use when `just coverage` fails, or after adding an endpoint to a Rust service.
日本語の概要は準備中です。原文の説明を表示しています。
Debug the running local stack with traces, logs, and a shared headless browser. Use when investigating a bug in a running service, tracing a request across services, reading service logs, reproducing a frontend issue, or writing/reviewing tracing instrumentation.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
just run_local and just stack up start the LGTM collector by default and
the agent browser with --with-chrome (both global: one per machine, shared
across instances, left running):
| Endpoint | What |
|---|---|
| http://localhost:3001 | Grafana (anonymous admin) — traces + logs UI |
| http://localhost:3200 | Tempo API — traces |
| http://localhost:3100 | Loki API — service logs |
| http://localhost:9090 | Prometheus API — metrics |
| localhost:4317 / 4318 | OTLP intake (gRPC / HTTP), alias otel-collector |
| http://localhost:9222 | Headless Chrome (CDP) |
--traces off disables the collector; --traces jaeger|datadog swaps it.
All collectors bind 4317/4318 — exactly one runs at a time.
Every Rust service exports spans AND its tracing events (as correlated log
records) over OTLP. The frontend exports browser spans through the proxy and
propagates traceparent, so one trace covers browser → proxy → services.
Wiring happens at stack start: if you start a collector by hand, restart the
stack to pick it up.
The grafana MCP server (.mcp.json / opencode.json / .cursor/mcp.json,
Docker mcp/grafana on the host network) is pointed at this Grafana. Prefer its tools:
query_loki_logs, list_loki_label_values, find_error_pattern_logstempo_traceql-search, tempo_get-trace,
tempo_get-attribute-values, tempo_docs-traceql (proxied from Tempo's
own MCP server; every tempo_* call needs datasourceUid: "tempo")query_prometheus; plus search_dashboards, generate_deeplinkDatasource UIDs are stable: loki, prometheus, tempo, pyroscope.
Typical calls — service names are the binary names (email_service,
document-storage-service); match on route, duration, or any span attribute:
tempo_traceql-search {datasourceUid: "tempo", query: '{resource.service.name="email_service" && status=error}'}
(also '{span.http.route="/documents" && duration>500ms}'), then
tempo_get-trace with the returned trace ID. Searches default to the past
hour; widen with RFC3339 start/end.query_loki_logs {datasourceUid: "loki", logql: '{service_name="email_service"} |= "error"'}
— log lines carry trace_id/span_id for correlation. Discover services
with list_loki_label_values on service_name.Timing quirks: Tempo's search index flushes every ~30s — a trace you just produced is fetchable by ID immediately but may not show in search yet.
Everything above is also plain HTTP: TraceQL search at
http://localhost:3200/api/search?q=<traceql>, trace fetch at
/api/traces/<id>, LogQL at
http://localhost:3100/loki/api/v1/query_range?query=<logql> (start/end
are unix epoch nanoseconds). Use the HTTP form when there is no MCP (pi),
and for bulk retrieval you want to reduce before reading — a full trace can
be 50+ spans, so curl /api/traces/<id> | jq (filter to slow spans, compute
offsets) beats dumping tempo_get-trace output into context. docker compose -p macro logs -f <service> still works for raw stdout, but Loki is queryable
and survives restarts.
Verbosity knobs (set in the shell before just run_local, or per service in
Doppler): RUST_LOG filters console + Loki output; OTEL_TRACE_FILTER
independently filters exported spans (default info). Lowering RUST_LOG
never silences traces.
--with-chrome runs a headless Chrome in Docker with CDP on 9222 (if 9222
doesn't answer, start it: the compose command is in the headless-chrome
comment in docker/docker-compose.yml). The chrome-devtools MCP server
(.mcp.json / opencode.json / .cursor/mcp.json) is already pointed at
it — prefer its tools (navigate, snapshot, click, evaluate, console, network) for browser
work. State (cookies, login) persists across agent sessions until the
container restarts.
https://localhost:8090 (named
instances remap these ports; read the stack summary).chromium.connectOverCDP('http://localhost:9222').
For token-injection and route-interception recipes see
apps/web/docs/playwright-debugging.md.Correlate a browser repro with backend traces: note the time, then search
Tempo for that window — the browser's traceparent means the frontend action
and the Rust handler share one trace ID.
take_snapshot after every navigation or pane change; act
only on uids from the latest snapshot (uid prefixes bump on re-render).
Macro snapshots are huge — split panes duplicate the doc text — so save
big ones to a file (filePath param) and grep them.navigate_page can time out while the SPA actually loaded (cold Vite
compile); follow with wait_for on expected text instead of re-navigating.wait_for matches any text presence, including placeholders. For "AI
finished"-style conditions, poll in evaluate_script for the Stop
button's absence — the only reliable completion signal.fill works on plain inputs but NOT contenteditable: click to focus, then
type_text (Enter splits paragraphs/sends). Combobox token fields need
type → wait for the "N options available" live region → Enter to tokenize.list_console_messages +
list_network_requests (filter xhr/fetch), then get_network_request for
the failing request's body — pairing console error with failing request
localizes the fault in one step.evaluate_script (e.g. query
[contenteditable] strong to confirm an AI edit) — cheaper and more
precise than screenshots.The condensed version is below; the full field-tested guide (routes, every
surface, keyboard model, crash recovery, trace correlation from a network
request's traceparent) is docs/AGENT_GUIDE/.
/app/welcome: "Continue with email" → fill
the email input → "Continue". Locally this may log in with no code prompt;
otherwise the code is in Mailpit. First login auto-creates the user./app/md/<uuid>; a doc-scoped AI chat at
/app/md/<uuid>/chat/<chatId>; split panes give the right pane its own URL
segment (/app/md/<uuid>/channel/<channelId>).value exposes the full body
text, so snapshots double as content verification.Follow CLAUDE.md's tracing rules (err on Result-returning #[instrument],
never level = "info", tracing::error!(error=?e, "msg"), prefer
.inspect_err). Beyond those:
macro_tower_layers; add #[tracing::instrument] to queue consumers,
cross-service client calls, and multi-step business operations — the places
a trace would otherwise go dark.#[instrument(skip(payload), fields(document_id = %id))])
and record the IDs you will actually search by: entity IDs, user IDs,
counts. A span you can't find by ID is a span you can't use.tracing::Span::current().record(...) rather
than emitting a second event.tracing::warn! with fields
beats three unstructured debug!s. Fields, not format strings —
warn!(attempts, "retrying"), not warn!("retrying attempt {attempts}").まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Wrap a new backend endpoint in the TypeScript SDK (packages/sdk), or record it as skipped. Use when `just coverage` fails, or after adding an endpoint to a Rust service.
日本語の概要は準備中です。原文の説明を表示しています。
Add or change an in-app feature tour (a view's guided flyover) in the web app. Use when adding a tour to a view, adding or editing tour steps, pointing a step at a new control, or when a step's target needs something opened first.
日本語の概要は準備中です。原文の説明を表示しています。
Enforce hexagonal architecture in the Rust backend. Use before modifying crates or Rust services, especially inbound axum/tool/listener adapters, domain services/ports, outbound adapters, authorization, permissions, database access, or external clients.
日本語の概要は準備中です。原文の説明を表示しています。
Enforce hexagonal architecture in the Rust backend. Use before modifying crates/ or Rust services, especially inbound axum/tool/listener adapters, domain services/ports, outbound adapters, authorization, permissions, database access, or external clients.
日本語の概要は準備中です。原文の説明を表示しています。
Use when adding collaborative markdown, notes, or descriptions to a feature with collab surfaces. Covers parent entities, service entry points, authorization, content storage, and lifecycle.
日本語の概要は準備中です。原文の説明を表示しています。
Build a new AI tool end-to-end — Rust implementation, toolset wiring, infra, schema generation, and frontend UI.
日本語の概要は準備中です。原文の説明を表示しています。