@aryasaatvik/motel 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +180 -0
- package/LICENSE +21 -0
- package/README.md +137 -0
- package/package.json +119 -0
- package/skills/motel-debug/SKILL.md +203 -0
- package/skills/motel-debug/references/effect.md +38 -0
- package/src/App.tsx +414 -0
- package/src/StartupGate.test.ts +80 -0
- package/src/StartupGate.tsx +263 -0
- package/src/cli.ts +205 -0
- package/src/config.ts +45 -0
- package/src/daemon.test.ts +547 -0
- package/src/daemon.ts +486 -0
- package/src/domain.test.ts +62 -0
- package/src/domain.ts +291 -0
- package/src/httpApi.ts +391 -0
- package/src/httpListPolicy.test.ts +76 -0
- package/src/httpListPolicy.ts +129 -0
- package/src/index.tsx +25 -0
- package/src/instructions.ts +72 -0
- package/src/launchAgent.test.ts +430 -0
- package/src/launchAgent.ts +462 -0
- package/src/localServer.ts +568 -0
- package/src/locator.ts +138 -0
- package/src/mcp.ts +433 -0
- package/src/motel.test.ts +176 -0
- package/src/motel.ts +88 -0
- package/src/motelClient.ts +353 -0
- package/src/opentui-jsx.d.ts +11 -0
- package/src/otlp.test.ts +65 -0
- package/src/otlp.ts +162 -0
- package/src/otlpProtobuf.ts +35 -0
- package/src/queryFilters.ts +39 -0
- package/src/registry.ts +115 -0
- package/src/runtime.ts +40 -0
- package/src/server.ts +11 -0
- package/src/services/AsyncIngest.ts +82 -0
- package/src/services/LogQueryService.ts +29 -0
- package/src/services/TelemetryQuery.ts +62 -0
- package/src/services/TelemetryStore.ts +2554 -0
- package/src/services/TraceQueryService.ts +43 -0
- package/src/services/ingestRpc.ts +39 -0
- package/src/services/queryRpc.ts +15 -0
- package/src/services/telemetryQueryWorker.ts +32 -0
- package/src/services/telemetryWorker.ts +59 -0
- package/src/startupBench.ts +19 -0
- package/src/startupLifecycle.ts +57 -0
- package/src/storybook/aiChatStory.tsx +244 -0
- package/src/storybook/fixtures/errorState.ts +44 -0
- package/src/storybook/fixtures/imagePaste.ts +34 -0
- package/src/storybook/fixtures/index.ts +62 -0
- package/src/storybook/fixtures/kitchenSink.ts +148 -0
- package/src/storybook/fixtures/rawPrompt.ts +15 -0
- package/src/storybook/fixtures/short.ts +27 -0
- package/src/storybook/fixtures/toolHeavy.ts +65 -0
- package/src/telemetry.test.ts +1053 -0
- package/src/ui/AiChatView.tsx +308 -0
- package/src/ui/AttrFilterModal.tsx +120 -0
- package/src/ui/ServiceLogs.tsx +115 -0
- package/src/ui/SpanContentView.tsx +184 -0
- package/src/ui/SpanDetail.tsx +215 -0
- package/src/ui/SpanDetailFull.tsx +224 -0
- package/src/ui/SpanDetailPane.tsx +90 -0
- package/src/ui/TraceDetailsPane.tsx +175 -0
- package/src/ui/TraceList.tsx +254 -0
- package/src/ui/Waterfall.tsx +389 -0
- package/src/ui/aiChatModel.test.ts +391 -0
- package/src/ui/aiChatModel.ts +773 -0
- package/src/ui/aiState.ts +59 -0
- package/src/ui/app/TraceListPane.tsx +39 -0
- package/src/ui/app/TraceWorkspace.tsx +452 -0
- package/src/ui/app/useAppLayout.ts +101 -0
- package/src/ui/app/useTraceScreenData.ts +590 -0
- package/src/ui/atoms.ts +131 -0
- package/src/ui/cachedLoader.test.ts +23 -0
- package/src/ui/cachedLoader.ts +60 -0
- package/src/ui/filterParser.test.ts +56 -0
- package/src/ui/filterParser.ts +45 -0
- package/src/ui/format.ts +128 -0
- package/src/ui/loaders.ts +101 -0
- package/src/ui/persistence.ts +41 -0
- package/src/ui/primitives.tsx +198 -0
- package/src/ui/state.ts +6 -0
- package/src/ui/theme.ts +160 -0
- package/src/ui/traceDetailsWidth.repro.test.ts +126 -0
- package/src/ui/traceSortNav.repro.seed.ts +62 -0
- package/src/ui/traceSortNav.repro.test.ts +231 -0
- package/src/ui/useAttrFilterPicker.ts +89 -0
- package/src/ui/useKeyboardNav.ts +1023 -0
- package/src/ui/waterfallFilter.test.ts +84 -0
- package/src/ui/waterfallFilter.ts +59 -0
- package/src/ui/waterfallModel.ts +130 -0
- package/src/ui/waterfallNav.repro.seed.ts +86 -0
- package/src/ui/waterfallNav.repro.test.ts +271 -0
- package/src/ui/waterfallNav.test.ts +453 -0
- package/src/ui/waterfallNav.ts +75 -0
- package/web/dist/assets/index-B01z9BaO.css +2 -0
- package/web/dist/assets/index-CYlBaY9O.js +22 -0
- package/web/dist/index.html +13 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Commands
|
|
4
|
+
- Install deps: `bun install`
|
|
5
|
+
- Run the TUI: `bun run dev` or `bun run start` (auto-ensures a managed
|
|
6
|
+
OTLP daemon is running in the background so traces ingest while the TUI
|
|
7
|
+
is up)
|
|
8
|
+
- Start the background daemon only: `bun run daemon` (same as `motel start`)
|
|
9
|
+
- Stop the managed daemon: `bun run stop`
|
|
10
|
+
- Daemon status JSON: `bun run status`
|
|
11
|
+
- Restart the managed daemon only: `bun run restart`
|
|
12
|
+
- Run the local server in the foreground (no daemon, no TUI): `bun run server`
|
|
13
|
+
- Run tests: `bun run test`
|
|
14
|
+
- Query services via CLI: `motel services`
|
|
15
|
+
- Query traces via CLI: `motel traces <service> [limit]`
|
|
16
|
+
- Query a span via CLI: `motel span <span-id>`
|
|
17
|
+
- Query spans for one trace: `motel trace-spans <trace-id>`
|
|
18
|
+
- Search spans via CLI: `motel search-spans [service] [operation] [parent=<operation>] [attr.key=value ...]`
|
|
19
|
+
- Search traces via CLI: `motel search-traces [service] [operation] [attr.key=value ...]`
|
|
20
|
+
- Query trace stats via CLI: `motel trace-stats <groupBy> <agg> [service] [attr.key=value ...]`
|
|
21
|
+
- Query logs via CLI: `motel logs <service>`
|
|
22
|
+
- Search logs via CLI: `motel search-logs [service] [body] [attr.key=value ...]`
|
|
23
|
+
- Query log stats via CLI: `motel log-stats <groupBy> [service] [attr.key=value ...]`
|
|
24
|
+
- Query logs for one trace: `motel trace-logs <trace-id>`
|
|
25
|
+
- Query logs for one span: `motel span-logs <span-id>`
|
|
26
|
+
- Query facets via CLI: `motel facets <traces|logs> <field>`
|
|
27
|
+
- Print Effect setup instructions: `bun run instructions`
|
|
28
|
+
- Build the web UI: `bun run web:build`
|
|
29
|
+
- Dev the web UI (with hot reload): `bun run web:dev`
|
|
30
|
+
- Typecheck: `bun run typecheck`
|
|
31
|
+
- Effect LSP diagnostics over the whole project: `bunx effect-language-service diagnostics --project tsconfig.json --format text`
|
|
32
|
+
- Effect LSP interactive setup wizard: `bunx effect-language-service setup`
|
|
33
|
+
|
|
34
|
+
## Release Strategy
|
|
35
|
+
- npm package: `@aryasaatvik/motel`
|
|
36
|
+
- Releases are run from an attended local session with Tegami; GitHub Actions only validates pull requests.
|
|
37
|
+
- Tags are versioned as `vX.Y.Z` (`git tag --sort=-version:refname` shows `v0.2.4`, `v0.2.3`, ...)
|
|
38
|
+
- Add user-facing release notes under `.tegami/` and commit them with the implementation they describe.
|
|
39
|
+
- `bun run version:packages` consumes pending entries, updates the package version and changelog, writes the publish lock, and opens or updates `tegami/version-packages` against `dev`.
|
|
40
|
+
- After the version pull request is merged, run `bun run release` from a clean, current `dev` branch with npm and GitHub CLI authentication.
|
|
41
|
+
- The release command runs typechecks, Effect diagnostics, tests, and package validation before Tegami publishes npm, pushes the matching `v<version>` tag, and creates the GitHub Release.
|
|
42
|
+
- See `docs/release.md` for the attended release and verification procedure.
|
|
43
|
+
- Publishing does not install or restart the machine-global Motel service; that cutover is a separate operation.
|
|
44
|
+
|
|
45
|
+
## Effect LSP
|
|
46
|
+
The repo is wired up with `@effect/language-service` as a `tsconfig.json` `plugins` entry. Editors that pick up the TypeScript workspace plugin (Zed, VSCode, Cursor, NVim via vtsls) will surface Effect-specific diagnostics, quick fixes, and refactors inline. In Zed this requires selecting the workspace TypeScript version — it does so automatically when `node_modules/typescript` is present.
|
|
47
|
+
|
|
48
|
+
## Verification
|
|
49
|
+
- The built-in verification step is `bun run typecheck`.
|
|
50
|
+
- For runtime verification, start the TUI or server once, then query `http://127.0.0.1:27686/api/services`, `http://127.0.0.1:27686/api/spans/<span-id>`, `http://127.0.0.1:27686/openapi.json`, and `motel logs motel-otel-tui`.
|
|
51
|
+
- For span-centric debugging, use `http://127.0.0.1:27686/api/spans/search?...`, `http://127.0.0.1:27686/api/spans/<span-id>/logs`, and `http://127.0.0.1:27686/api/traces/<trace-id>/spans`.
|
|
52
|
+
|
|
53
|
+
## API Notes
|
|
54
|
+
- List and search endpoints return a `meta` object with `limit`, `lookback`, `returned`, `truncated`, and `nextCursor`.
|
|
55
|
+
- `/api/traces` and `/api/traces/search` return summaries by default. Use `/api/traces/<trace-id>` for the full trace tree.
|
|
56
|
+
- `/api/logs` and `/api/logs/search` support `severity` (e.g. `?severity=ERROR`), case-insensitive body search, and `attrContains.<key>=<substring>` for substring search inside attribute values.
|
|
57
|
+
- `/api/spans/search` supports `traceId` to scope to one trace, `attr.<key>=<value>` for exact match, and `attrContains.<key>=<substring>` for case-insensitive substring search inside attribute values.
|
|
58
|
+
- `/api/ai/calls` searches AI SDK calls (streamText, generateText, etc.) with first-class filters for `model`, `provider`, `sessionId`, `functionId`, `operation`, `status`, `text` (cross-field search), and returns compact summaries with previews and token usage.
|
|
59
|
+
- `/api/ai/calls/<span-id>` returns the full detail of a single AI call including complete prompt messages, response text, tool calls, timing, and correlated logs.
|
|
60
|
+
- `/api/ai/stats` aggregates AI call statistics by `provider`, `model`, `functionId`, `sessionId`, or `status` with aggregations: `count`, `avg_duration`, `p95_duration`, `total_input_tokens`, `total_output_tokens`.
|
|
61
|
+
- `/api/facets?type=traces&field=attribute_keys&service=<svc>` lists span-attribute keys for a service, ranked by discriminating power (keys with many distinct values first). Pair with `field=attribute_values&key=<key>` to list values for a specific key. Used by the TUI `f` attribute filter.
|
|
62
|
+
- `/api/docs` lists available documentation; `/api/docs/debug` and `/api/docs/effect` return the full skill content.
|
|
63
|
+
|
|
64
|
+
## Architecture
|
|
65
|
+
- `src/index.tsx` creates the OpenTUI renderer and mounts the app.
|
|
66
|
+
- `src/App.tsx` composes the top-level screen: header, footer, and the
|
|
67
|
+
drill-in workspace. Heavy logic is delegated to the modules below.
|
|
68
|
+
- `src/ui/app/useTraceScreenData.ts` owns the atoms and data-loading
|
|
69
|
+
effects for traces, logs, services, and cache warming.
|
|
70
|
+
- `src/ui/app/useAppLayout.ts` is the single source for layout math
|
|
71
|
+
(pane widths, body lines, viewport rows, drill-in level).
|
|
72
|
+
- `src/ui/app/TraceWorkspace.tsx` renders the drill-in state machine:
|
|
73
|
+
L0 (trace list), L1 (waterfall), L2 (span detail), plus the service
|
|
74
|
+
logs side mode. When drilled in the list is hidden entirely and the
|
|
75
|
+
detail pane(s) expand to fill.
|
|
76
|
+
- `src/ui/app/TraceListPane.tsx` hosts the trace list: header + optional
|
|
77
|
+
filter bar + virtual-windowed body (no opentui scrollbox — that had a
|
|
78
|
+
race with Yoga layout timing).
|
|
79
|
+
- `src/ui/TraceList.tsx` exports `TraceListHeader` (the `TRACES 100 · ...`
|
|
80
|
+
strip) and `TraceListBody` (virtual-windowed rows with mouse-wheel
|
|
81
|
+
scrolling). The body owns its own scrollOffset state, preserves the
|
|
82
|
+
selected row's visual position across auto-refresh shifts, and snaps
|
|
83
|
+
the window to follow selection that moves off-screen.
|
|
84
|
+
- `src/ui/Waterfall.tsx` renders the waterfall timeline with a
|
|
85
|
+
virtualised scroll viewport; `src/ui/waterfallNav.ts` is the pure
|
|
86
|
+
collapse/expand/walk resolver (unit-tested).
|
|
87
|
+
- `src/ui/TraceDetailsPane.tsx` is the L1 body: header + waterfall.
|
|
88
|
+
- `src/ui/SpanDetailPane.tsx` is the L2 body; renders
|
|
89
|
+
`src/ui/SpanDetail.tsx` below a header that owns the span identity.
|
|
90
|
+
- `src/ui/useKeyboardNav.ts` centralises the keyboard handlers and
|
|
91
|
+
cross-pane navigation state transitions.
|
|
92
|
+
- `src/motel.ts` composes and runs the public Effect command tree; `src/cli.ts` exports typed telemetry query leaves and handlers.
|
|
93
|
+
- `src/runtime.ts` wires the Effect beta runtime and OTEL trace + log exporters.
|
|
94
|
+
- `src/localServer.ts` starts the local Bun OTLP/query server.
|
|
95
|
+
- `src/httpApi.ts` defines the typed Effect HttpApi surface and OpenAPI spec for the local server.
|
|
96
|
+
- `src/httpListPolicy.ts` owns pure HTTP list/search parameter decoding, bounds, cursors, and pagination metadata shaping.
|
|
97
|
+
- `src/server.ts` runs the local server without the TUI.
|
|
98
|
+
- `src/instructions.ts` contains the copied setup instructions for other Effect apps.
|
|
99
|
+
- `src/services/TelemetryStore.ts` persists traces and logs in SQLite and exposes indexed queries through writer and read-only service identifiers.
|
|
100
|
+
- `src/services/TelemetryQuery.ts` proxies read-only store calls to `src/services/telemetryQueryWorker.ts`, keeping synchronous Bun SQLite queries off the HTTP event loop.
|
|
101
|
+
- `src/config.ts` is the source of truth for ports and env-driven OTEL settings.
|
|
102
|
+
- `web/` is a Vite + React SPA for the browser-based UI (Tailwind CSS, `@effect/atom-react`, `AtomHttpApi`).
|
|
103
|
+
- `web/src/api.ts` creates the typed `AtomHttpApi.Service` client from `src/httpApi.ts`.
|
|
104
|
+
- `web/src/pages/` contains route pages: TracesPage, TraceDetailPage, LogsPage, AiCallsPage.
|
|
105
|
+
- `web/src/components/` contains Waterfall and SpanDetail components.
|
|
106
|
+
- The server in `src/localServer.ts` serves `web/dist/` as static files with SPA fallback for non-API routes.
|
|
107
|
+
|
|
108
|
+
## Tests
|
|
109
|
+
- `bun run test` runs the suite. Three kinds of tests live in the repo:
|
|
110
|
+
- `src/telemetry.test.ts` exercises the SQLite TelemetryStore with
|
|
111
|
+
OTLP payloads end-to-end.
|
|
112
|
+
- `src/ui/waterfallNav.test.ts` unit-tests the pure collapse/expand
|
|
113
|
+
resolver (no UI).
|
|
114
|
+
- `src/ui/*.repro.test.ts` drive the real TUI under `tuistory` to
|
|
115
|
+
reproduce regressions, using deterministic traces seeded into SQLite
|
|
116
|
+
by child processes. They become no-op passes when `tuistory` is absent.
|
|
117
|
+
|
|
118
|
+
## Effect Observability Guidance
|
|
119
|
+
- Inspect the target repo’s existing Effect runtime and observability wiring before adding anything new.
|
|
120
|
+
- Prefer the repo’s existing Effect-native observability APIs if available.
|
|
121
|
+
- If `effect/unstable/observability` is already the best fit, prefer it over adding `@effect/opentelemetry`.
|
|
122
|
+
- Only add new OpenTelemetry SDK packages when the repo already uses them or they are clearly required.
|
|
123
|
+
- Merge telemetry into the main runtime once, not per-feature.
|
|
124
|
+
- Prefer structured log annotations so fields like `sessionID`, `modelID`, `providerID`, and `tool` are queryable.
|
|
125
|
+
|
|
126
|
+
## Local OTEL Ports
|
|
127
|
+
- Local API / UI base: `http://127.0.0.1:27686`
|
|
128
|
+
- OTLP HTTP traces: `http://127.0.0.1:27686/v1/traces`
|
|
129
|
+
- OTLP HTTP logs: `http://127.0.0.1:27686/v1/logs`
|
|
130
|
+
- Health: `http://127.0.0.1:27686/api/health`
|
|
131
|
+
|
|
132
|
+
## Env Vars
|
|
133
|
+
- `MOTEL_OTEL_ENABLED`: defaults to `false` (set to `true` to emit self-traces for debugging motel itself)
|
|
134
|
+
- `MOTEL_OTEL_SERVICE_NAME`: defaults to `motel-otel-tui`
|
|
135
|
+
- `MOTEL_OTEL_BASE_URL`: defaults to `http://127.0.0.1:27686`
|
|
136
|
+
- `MOTEL_OTEL_HOST`: defaults to `127.0.0.1`
|
|
137
|
+
- `MOTEL_OTEL_PORT`: defaults to `27686`
|
|
138
|
+
- `MOTEL_OTEL_EXPORTER_URL`: defaults to `http://127.0.0.1:27686/v1/traces`
|
|
139
|
+
- `MOTEL_OTEL_LOGS_EXPORTER_URL`: defaults to `http://127.0.0.1:27686/v1/logs`
|
|
140
|
+
- `MOTEL_OTEL_QUERY_URL`: defaults to `http://127.0.0.1:27686`
|
|
141
|
+
- `MOTEL_OTEL_DB_PATH`: defaults to `${XDG_STATE_HOME:-~/.local/state}/motel/telemetry.sqlite` (one shared DB per machine; daemon log + lock + instance registry live in the same directory)
|
|
142
|
+
- `MOTEL_RUNTIME_DIR`: overrides the daemon log, lock, and instance-registry directory (primarily for isolated tests and custom managed instances)
|
|
143
|
+
- `MOTEL_OTEL_TRACE_LOOKBACK_MINUTES`: defaults to `1440` (24h)
|
|
144
|
+
- `MOTEL_OTEL_TRACE_LIMIT`: defaults to `100`
|
|
145
|
+
- `MOTEL_OTEL_LOG_LIMIT`: defaults to `80`
|
|
146
|
+
- `MOTEL_OTEL_RETENTION_HOURS`: defaults to `168` (7d)
|
|
147
|
+
- `MOTEL_OTEL_MAX_DB_SIZE_MB`: defaults to `1024` (size-based retention cap)
|
|
148
|
+
- `MOTEL_OTEL_RETENTION_TRACE_BATCH`: defaults to `100` completed traces per cleanup pass
|
|
149
|
+
- `MOTEL_OTEL_RETENTION_LOG_BATCH`: defaults to `5000` logs per cleanup pass
|
|
150
|
+
- `MOTEL_OTEL_RETENTION_INTERVAL_SECONDS`: defaults to `10`
|
|
151
|
+
|
|
152
|
+
## TUI Keys
|
|
153
|
+
- `?`: toggle shortcut help
|
|
154
|
+
- `j` / `k` or `up` / `down`: move trace or span selection
|
|
155
|
+
- `h` / `left`: collapse current span, or step to parent
|
|
156
|
+
- `l` / `right`: expand current span, or step to first child
|
|
157
|
+
- `ctrl-n` / `ctrl-p`: switch traces while staying in the details area
|
|
158
|
+
- `gg` / `home`: jump to the first trace or span
|
|
159
|
+
- `G` / `end`: jump to the last trace or span
|
|
160
|
+
- `ctrl-u` / `pageup`: page up
|
|
161
|
+
- `ctrl-d` / `pagedown`: page down
|
|
162
|
+
- `enter`: drill in one level (list → waterfall → span detail)
|
|
163
|
+
- `esc`: back out one level
|
|
164
|
+
- `tab`: toggle service logs view
|
|
165
|
+
- `[` / `]`: switch services
|
|
166
|
+
- `s`: cycle sort mode (recent → slowest → errors)
|
|
167
|
+
- `t`: cycle theme (motel-default → tokyo-night → catppuccin)
|
|
168
|
+
- `/`: enter filter mode.
|
|
169
|
+
- **In the trace list (L0)** the input matches against the root operation name. Composable modifiers:
|
|
170
|
+
- `:error` — restrict to traces with at least one failed span (client-side)
|
|
171
|
+
- `:ai <query>` — FTS5-backed search against LLM prompt/response/tool content (`AI_FTS_KEYS`) across every span in the trace. Tokens are prefix-matched and implicitly AND'd. Debounced 250ms.
|
|
172
|
+
- Modifiers compose: `/ :ai rate limit :error`
|
|
173
|
+
- **In the waterfall (L1/L2)** the input runs a client-side substring match against each span's operation name and tag values. Non-matching spans are dimmed; the filter bar shows the live match count. `enter` commits (dim persists while you navigate); `esc` clears.
|
|
174
|
+
- `f`: open attribute filter picker (browse span-attribute keys → values for the current service; `backspace` walks back to keys; `esc` in the trace list clears the active filter)
|
|
175
|
+
- `a`: pause or resume auto-refresh
|
|
176
|
+
- `r`: refresh now
|
|
177
|
+
- `c`: copy setup instructions for another Effect app
|
|
178
|
+
- `o`: open selected trace in the browser
|
|
179
|
+
- `y`: copy selected trace or span id
|
|
180
|
+
- `q`: quit
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kit Langton
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# motel
|
|
2
|
+
|
|
3
|
+
A local OpenTelemetry ingest + TUI viewer for development, backed by
|
|
4
|
+
SQLite. Point your app's OTLP/HTTP exporters at the local motel server
|
|
5
|
+
and debug with real runtime evidence — from a terminal, the built-in web
|
|
6
|
+
UI, or directly from an AI coding agent.
|
|
7
|
+
|
|
8
|
+
## For agents: install the motel-debug skill
|
|
9
|
+
|
|
10
|
+
`motel` ships a companion skill that teaches Claude Code, OpenCode,
|
|
11
|
+
Cursor, Codex, and 40+ other agents how to debug with runtime evidence
|
|
12
|
+
by querying motel's local OTLP store. Install it once and any future
|
|
13
|
+
agent session in the project will know how to use it.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Project-local (adds to .claude/skills, .agents/skills, etc.)
|
|
17
|
+
npx skills add aryasaatvik/motel --skill motel-debug
|
|
18
|
+
|
|
19
|
+
# Or globally, for every project
|
|
20
|
+
npx skills add aryasaatvik/motel --skill motel-debug -g
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
See the full skill at [`skills/motel-debug/SKILL.md`](skills/motel-debug/SKILL.md).
|
|
24
|
+
|
|
25
|
+
## For humans: install and run the TUI
|
|
26
|
+
|
|
27
|
+
motel is distributed on npm as `@aryasaatvik/motel`. The binary is a Bun
|
|
28
|
+
script, so Bun must be on your `PATH` at runtime:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# one-off (no install)
|
|
32
|
+
bunx @aryasaatvik/motel
|
|
33
|
+
|
|
34
|
+
# or install globally
|
|
35
|
+
bun add -g @aryasaatvik/motel
|
|
36
|
+
motel
|
|
37
|
+
|
|
38
|
+
# npm also works (Bun still required to run it)
|
|
39
|
+
npm install -g @aryasaatvik/motel
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Don't have Bun?
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
curl -fsSL https://bun.sh/install | bash
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`motel` starts the local OTLP ingest server on
|
|
49
|
+
`http://127.0.0.1:27686` and launches the TUI. Press `?` once inside for
|
|
50
|
+
the keyboard cheat sheet, or `c` to copy paste-ready setup instructions
|
|
51
|
+
for any Effect/OTEL app you want to trace.
|
|
52
|
+
|
|
53
|
+
Requirements: [Bun](https://bun.sh/) v1.1 or newer.
|
|
54
|
+
|
|
55
|
+
### macOS service from the maintained checkout
|
|
56
|
+
|
|
57
|
+
The per-user LaunchAgent intentionally runs
|
|
58
|
+
`~/.bun/bin/bun ~/.bun/bin/motel server`. For a maintained-checkout
|
|
59
|
+
installation, prepare and link the merged `dev` checkout before installing
|
|
60
|
+
the service:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
bun install --frozen-lockfile
|
|
64
|
+
bun run web:build
|
|
65
|
+
bun link
|
|
66
|
+
motel service install
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
This service path does not discover npm-global or arbitrary `PATH`
|
|
70
|
+
executables. `motel service install` verifies both stable Bun bin paths before
|
|
71
|
+
writing or loading the LaunchAgent. Re-running it leaves an equivalent loaded
|
|
72
|
+
service unchanged and loads an equivalent definition that is currently
|
|
73
|
+
unloaded.
|
|
74
|
+
|
|
75
|
+
## How your app connects
|
|
76
|
+
|
|
77
|
+
Once motel is running, point your app's OTLP/HTTP exporters at these
|
|
78
|
+
local endpoints:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
http://127.0.0.1:27686/v1/traces
|
|
82
|
+
http://127.0.0.1:27686/v1/logs
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Motel keeps everything in a machine-global local SQLite database at
|
|
86
|
+
`${XDG_STATE_HOME:-~/.local/state}/motel/telemetry.sqlite`. One managed
|
|
87
|
+
daemon is shared across local projects. No Docker, no cloud account.
|
|
88
|
+
|
|
89
|
+
The store retains seven days of telemetry by default and targets a 1 GB
|
|
90
|
+
active-data ceiling using bounded background batches. Recent data is preserved while
|
|
91
|
+
the oldest completed traces and logs are removed first. Configure the policy
|
|
92
|
+
with `MOTEL_OTEL_RETENTION_HOURS`, `MOTEL_OTEL_MAX_DB_SIZE_MB`,
|
|
93
|
+
`MOTEL_OTEL_RETENTION_TRACE_BATCH`, `MOTEL_OTEL_RETENTION_LOG_BATCH`, and
|
|
94
|
+
`MOTEL_OTEL_RETENTION_INTERVAL_SECONDS`. Existing databases created without
|
|
95
|
+
incremental auto-vacuum are never silently rewritten at startup; deleted pages
|
|
96
|
+
are reused, but shrinking such a historical file requires an explicit offline
|
|
97
|
+
SQLite `VACUUM` chosen by the user.
|
|
98
|
+
|
|
99
|
+
## How agents connect
|
|
100
|
+
|
|
101
|
+
Agents with the `motel-debug` skill installed will automatically use
|
|
102
|
+
motel's HTTP API. The full OpenAPI spec is at
|
|
103
|
+
`http://127.0.0.1:27686/openapi.json` — the key endpoints are:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
GET /api/health liveness check
|
|
107
|
+
GET /api/services services reporting telemetry
|
|
108
|
+
GET /api/traces?service=<service> recent traces for a service
|
|
109
|
+
GET /api/traces/<trace-id> full trace tree
|
|
110
|
+
GET /api/spans/<span-id> single span + logs
|
|
111
|
+
GET /api/logs?service=<service> recent logs
|
|
112
|
+
GET /api/traces/search?... structured trace search
|
|
113
|
+
GET /api/logs/search?... structured log search
|
|
114
|
+
GET /api/ai/calls AI SDK call inspector
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## TUI keys
|
|
118
|
+
|
|
119
|
+
- `?` — keyboard cheat sheet
|
|
120
|
+
- `j` / `k` or `↑` / `↓` — move selection
|
|
121
|
+
- `enter` / `esc` — drill in / back out (trace → waterfall → span detail)
|
|
122
|
+
- `[` / `]` — switch service
|
|
123
|
+
- `tab` — toggle service logs
|
|
124
|
+
- `/` — filter traces
|
|
125
|
+
- `s` — cycle sort (recent → slowest → errors)
|
|
126
|
+
- `t` — cycle theme
|
|
127
|
+
- `c` — copy paste-ready setup instructions for another app
|
|
128
|
+
- `o` — open selected trace in the browser
|
|
129
|
+
- `q` — quit
|
|
130
|
+
|
|
131
|
+
## Privacy note
|
|
132
|
+
|
|
133
|
+
motel is a local development tool, but your app can emit sensitive
|
|
134
|
+
telemetry. Correlated logs may include secrets, tokens, or PII if your
|
|
135
|
+
app logs them; AI call traces may include full prompt content and
|
|
136
|
+
response text. Treat the local SQLite store as sensitive development
|
|
137
|
+
data when pointing motel at real workloads.
|
package/package.json
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aryasaatvik/motel",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "A local OpenTelemetry ingest + TUI viewer for development, backed by SQLite.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Kit Langton",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/aryasaatvik/motel.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/aryasaatvik/motel#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/aryasaatvik/motel/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"opentelemetry",
|
|
18
|
+
"otel",
|
|
19
|
+
"tracing",
|
|
20
|
+
"observability",
|
|
21
|
+
"tui",
|
|
22
|
+
"sqlite",
|
|
23
|
+
"effect",
|
|
24
|
+
"opentui"
|
|
25
|
+
],
|
|
26
|
+
"workspaces": [
|
|
27
|
+
"web"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"bun": ">=1.3.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public",
|
|
34
|
+
"registry": "https://registry.npmjs.org/"
|
|
35
|
+
},
|
|
36
|
+
"overrides": {
|
|
37
|
+
"@grpc/grpc-js": "1.14.4",
|
|
38
|
+
"protobufjs": "7.6.4",
|
|
39
|
+
"shell-quote": "1.9.0",
|
|
40
|
+
"ws": "8.21.0"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"src",
|
|
44
|
+
"web/dist",
|
|
45
|
+
"skills/motel-debug/SKILL.md",
|
|
46
|
+
"skills/motel-debug/references/effect.md",
|
|
47
|
+
"LICENSE",
|
|
48
|
+
"README.md",
|
|
49
|
+
"AGENTS.md"
|
|
50
|
+
],
|
|
51
|
+
"bin": {
|
|
52
|
+
"motel": "src/motel.ts",
|
|
53
|
+
"motel-mcp": "src/mcp.ts"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"clear-motel-debug": "bun run skills/motel-debug/scripts/clear-motel-debug.ts",
|
|
57
|
+
"dev": "MOTEL_OTEL_ENABLED=true bun run src/motel.ts tui",
|
|
58
|
+
"start": "bun run src/motel.ts tui",
|
|
59
|
+
"daemon": "bun run src/motel.ts daemon",
|
|
60
|
+
"status": "bun run src/motel.ts status",
|
|
61
|
+
"stop": "bun run src/motel.ts stop",
|
|
62
|
+
"restart": "bun run src/motel.ts restart",
|
|
63
|
+
"server": "bun run src/motel.ts server",
|
|
64
|
+
"mcp": "bun run src/mcp.ts",
|
|
65
|
+
"test": "bun test",
|
|
66
|
+
"cli": "bun run src/motel.ts",
|
|
67
|
+
"instructions": "bun run src/motel.ts instructions",
|
|
68
|
+
"services": "bun run src/motel.ts services",
|
|
69
|
+
"logs": "bun run src/motel.ts logs",
|
|
70
|
+
"trace-logs": "bun run src/motel.ts trace-logs",
|
|
71
|
+
"span-logs": "bun run src/motel.ts span-logs",
|
|
72
|
+
"span": "bun run src/motel.ts span",
|
|
73
|
+
"trace-spans": "bun run src/motel.ts trace-spans",
|
|
74
|
+
"search-spans": "bun run src/motel.ts search-spans",
|
|
75
|
+
"trace-stats": "bun run src/motel.ts trace-stats",
|
|
76
|
+
"log-stats": "bun run src/motel.ts log-stats",
|
|
77
|
+
"web:dev": "bun run --cwd web dev",
|
|
78
|
+
"web:build": "bun run --cwd web build",
|
|
79
|
+
"story:chat": "bun run src/storybook/aiChatStory.tsx",
|
|
80
|
+
"bench:motel-cold-start": "bun run scripts/bench-motel-cold-start.ts",
|
|
81
|
+
"bench:ingest-logs": "bun run scripts/bench-ingest-logs.ts",
|
|
82
|
+
"bench:ingest-traces": "bun run scripts/bench-ingest-traces.ts",
|
|
83
|
+
"bench:search-spans": "bun run scripts/bench-search-spans.ts",
|
|
84
|
+
"tegami": "bun scripts/tegami.mts",
|
|
85
|
+
"version:packages": "bun run tegami version",
|
|
86
|
+
"release:check": "bun run typecheck && bun run web:typecheck && bunx effect-language-service diagnostics --project tsconfig.json --format text && bun run test && bun run release:validate",
|
|
87
|
+
"release": "bun run release:check && bun run tegami publish",
|
|
88
|
+
"release:validate": "bun run scripts/validate-release.ts",
|
|
89
|
+
"typecheck": "tsc --noEmit",
|
|
90
|
+
"web:typecheck": "tsc --noEmit -p web/tsconfig.json",
|
|
91
|
+
"prepublishOnly": "bun run web:build"
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"@effect/language-service": "0.87.1",
|
|
95
|
+
"@types/bun": "^1.3.14",
|
|
96
|
+
"@types/react": "^19.2.17",
|
|
97
|
+
"tegami": "1.2.6",
|
|
98
|
+
"typescript": "^6.0.3"
|
|
99
|
+
},
|
|
100
|
+
"dependencies": {
|
|
101
|
+
"@effect/atom-react": "4.0.0-beta.101",
|
|
102
|
+
"@effect/opentelemetry": "4.0.0-beta.101",
|
|
103
|
+
"@effect/platform-bun": "4.0.0-beta.101",
|
|
104
|
+
"@opentelemetry/api": "^1.9.0",
|
|
105
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.219.0",
|
|
106
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
|
|
107
|
+
"@opentelemetry/otlp-transformer": "0.214.0",
|
|
108
|
+
"@opentelemetry/sdk-logs": "^0.219.0",
|
|
109
|
+
"@opentelemetry/sdk-node": "^0.219.0",
|
|
110
|
+
"@opentelemetry/sdk-trace-base": "^2.8.0",
|
|
111
|
+
"@opentelemetry/sdk-trace-node": "^2.8.0",
|
|
112
|
+
"@opentui/core": "0.4.2",
|
|
113
|
+
"@opentui/react": "0.4.2",
|
|
114
|
+
"effect": "4.0.0-beta.101",
|
|
115
|
+
"protobufjs": "7.6.4",
|
|
116
|
+
"react": "^19.2.7",
|
|
117
|
+
"scheduler": "^0.27.0"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: motel-debug
|
|
3
|
+
description: Debug applications with motel, a local OpenTelemetry ingest and query server. Use when the user wants runtime-evidence debugging with traces or logs, wants temporary debug instrumentation that can be removed later, or needs a repo wired to send OTLP/HTTP telemetry to a local motel server. If the target repo uses Effect or @effect/*, also read references/effect.md.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Motel Debug
|
|
7
|
+
|
|
8
|
+
You are in **debug mode**. Debug with runtime evidence, not guesswork.
|
|
9
|
+
|
|
10
|
+
Agents guess based on code alone. You need actual runtime data. Motel is the local OpenTelemetry server that collects traces and logs — use it as your evidence loop.
|
|
11
|
+
|
|
12
|
+
Default local server details:
|
|
13
|
+
|
|
14
|
+
- Base URL: `http://127.0.0.1:27686`
|
|
15
|
+
- OTLP traces: `POST /v1/traces`
|
|
16
|
+
- OTLP logs: `POST /v1/logs`
|
|
17
|
+
- Query API: `GET /api/*`
|
|
18
|
+
- OpenAPI: `GET /openapi.json`
|
|
19
|
+
- Header: `Content-Type: application/json`
|
|
20
|
+
- Auth: none by default
|
|
21
|
+
|
|
22
|
+
If the user provides a different motel URL, use that instead of the default.
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
### 1. Verify motel is running — and start it if not
|
|
27
|
+
|
|
28
|
+
Check `GET /api/health`. If it returns 200, continue.
|
|
29
|
+
|
|
30
|
+
If it fails (connection refused, timeout, non-200), motel isn't running.
|
|
31
|
+
Start it as a background daemon — **do not** launch the TUI, which is
|
|
32
|
+
interactive and will block your shell:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
motel start
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`motel start` ensures the machine-global managed daemon is running, writes
|
|
39
|
+
runtime files under `${XDG_STATE_HOME:-~/.local/state}/motel/`, and returns a
|
|
40
|
+
JSON status blob. It is idempotent and shared across local projects. If motel isn't on `PATH`, fall
|
|
41
|
+
back to `bunx @aryasaatvik/motel start`.
|
|
42
|
+
|
|
43
|
+
After starting, re-check `GET /api/health` (may take 1–2s to become
|
|
44
|
+
ready). If it still fails, read `${XDG_STATE_HOME:-~/.local/state}/motel/daemon.log` for the error
|
|
45
|
+
and surface it to the user.
|
|
46
|
+
|
|
47
|
+
Other lifecycle commands, for reference:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
motel status # JSON status (running? pid? originating workdir?)
|
|
51
|
+
motel stop # stop the shared managed daemon for all local projects
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Discover reporting services with `GET /api/services` when needed.
|
|
55
|
+
|
|
56
|
+
### 2. Generate hypotheses
|
|
57
|
+
|
|
58
|
+
Before touching any code, generate **3-5 specific hypotheses** about why the bug occurs. Be precise — "the cache key doesn't include the user ID" is better than "something is wrong with caching."
|
|
59
|
+
|
|
60
|
+
### 3. Instrument with tagged debug blocks
|
|
61
|
+
|
|
62
|
+
Add the minimum instrumentation needed to confirm or reject **all** hypotheses in parallel. Every debug block must:
|
|
63
|
+
|
|
64
|
+
- Be wrapped in `#region motel debug` / `#endregion motel debug` markers
|
|
65
|
+
- Include a `debug.hypothesis` attribute linking it to a specific hypothesis
|
|
66
|
+
- Use whatever tracing/logging mechanism the codebase already has (spans, structured logs, annotations — not raw `fetch` calls)
|
|
67
|
+
|
|
68
|
+
Tag every piece of debug instrumentation with structured attributes so you can query it later. Reuse these keys:
|
|
69
|
+
|
|
70
|
+
| Key | Purpose |
|
|
71
|
+
|-----|---------|
|
|
72
|
+
| `debug.session` | Groups all instrumentation for this debug session |
|
|
73
|
+
| `debug.hypothesis` | Links to a specific hypothesis (e.g. `"cache-miss"`, `"A"`) |
|
|
74
|
+
| `debug.step` | Position in the flow (e.g. `"entry"`, `"before-write"`, `"after-read"`) |
|
|
75
|
+
| `debug.label` | Human-readable description of what this point captures |
|
|
76
|
+
|
|
77
|
+
Choose log placements based on your hypotheses:
|
|
78
|
+
|
|
79
|
+
- Function entry with parameters
|
|
80
|
+
- Function exit with return values
|
|
81
|
+
- Values before and after critical operations
|
|
82
|
+
- Branch execution paths (which if/else ran)
|
|
83
|
+
- State mutations and intermediate values
|
|
84
|
+
- Suspected error or edge-case values
|
|
85
|
+
|
|
86
|
+
Guidelines:
|
|
87
|
+
|
|
88
|
+
- At least 1 instrumentation point is required; never skip instrumentation
|
|
89
|
+
- Do not exceed 10 — if you think you need more, narrow your hypotheses
|
|
90
|
+
- Typical range is 2-6
|
|
91
|
+
|
|
92
|
+
### 4. Reproduce the issue
|
|
93
|
+
|
|
94
|
+
- If a failing test exists, run it directly
|
|
95
|
+
- If reproduction is straightforward (CLI command, curl, simple script), write and run it yourself
|
|
96
|
+
- Otherwise, ask the user to reproduce — provide clear numbered steps and remind them to restart if needed
|
|
97
|
+
- Once a reproduction pathway is established, reuse it for all subsequent iterations
|
|
98
|
+
|
|
99
|
+
### 5. Analyze evidence
|
|
100
|
+
|
|
101
|
+
Query motel for the debug instrumentation:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&attr.debug.hypothesis=<id>"
|
|
105
|
+
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&attr.debug.session=<session>"
|
|
106
|
+
curl "http://127.0.0.1:27686/api/traces/search?service=<service>&attr.debug.hypothesis=<id>"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
For each hypothesis, evaluate: **CONFIRMED**, **REJECTED**, or **INCONCLUSIVE** — cite specific spans, logs, or attribute values as evidence.
|
|
110
|
+
|
|
111
|
+
### 6. Fix only with evidence
|
|
112
|
+
|
|
113
|
+
Do **not** fix without runtime evidence. When you fix:
|
|
114
|
+
|
|
115
|
+
- Keep all debug instrumentation in place — do not remove it yet
|
|
116
|
+
- Make the fix as small and targeted as possible
|
|
117
|
+
- Reuse existing architecture and patterns; do not overengineer
|
|
118
|
+
|
|
119
|
+
### 7. Verify the fix
|
|
120
|
+
|
|
121
|
+
Reproduce the issue again with instrumentation still active. Compare before/after evidence:
|
|
122
|
+
|
|
123
|
+
- Cite specific log lines or span attributes that prove the fix works
|
|
124
|
+
- If the fix failed: **revert code changes from rejected hypotheses** (do not let speculative fixes accumulate), generate new hypotheses from different subsystems, add more instrumentation, and iterate
|
|
125
|
+
- Iteration is expected. Taking longer with more data yields better fixes.
|
|
126
|
+
|
|
127
|
+
### 8. Clean up
|
|
128
|
+
|
|
129
|
+
Only after the fix is verified **and** the user confirms there are no remaining issues:
|
|
130
|
+
|
|
131
|
+
- Run the cleanup script or remove blocks manually (see Cleanup section below)
|
|
132
|
+
- Run `git diff` to confirm only the intentional fix remains
|
|
133
|
+
|
|
134
|
+
## Instrumentation Rules
|
|
135
|
+
|
|
136
|
+
Wrap every temporary debug block in these exact markers:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
// #region motel debug
|
|
140
|
+
// temporary debug instrumentation
|
|
141
|
+
// #endregion motel debug
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Use whatever the codebase already provides for tracing and logging. The markers are language-comment wrappers — adapt the comment syntax for non-JS/TS files (e.g. `# #region motel debug` for Python).
|
|
145
|
+
|
|
146
|
+
**Do not:**
|
|
147
|
+
- Log secrets, tokens, passwords, or raw PII
|
|
148
|
+
- Remove instrumentation before post-fix verification succeeds
|
|
149
|
+
- Use `setTimeout`, `sleep`, or artificial delays as a "fix"
|
|
150
|
+
- Let code changes from rejected hypotheses accumulate — revert them
|
|
151
|
+
|
|
152
|
+
## Query Patterns
|
|
153
|
+
|
|
154
|
+
Two filter prefixes for attribute search:
|
|
155
|
+
|
|
156
|
+
| Prefix | Match type | Example |
|
|
157
|
+
|--------|-----------|---------|
|
|
158
|
+
| `attr.<key>=<value>` | Exact match | `attr.debug.hypothesis=cache-miss` |
|
|
159
|
+
| `attrContains.<key>=<substring>` | Case-insensitive substring | `attrContains.ai.prompt.messages=hello world` |
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
curl http://127.0.0.1:27686/api/health
|
|
163
|
+
curl http://127.0.0.1:27686/api/services
|
|
164
|
+
|
|
165
|
+
# Trace search
|
|
166
|
+
curl "http://127.0.0.1:27686/api/traces/search?service=<service>&operation=<text>&attr.debug.session=<session>"
|
|
167
|
+
|
|
168
|
+
# Span search (supports traceId to scope to one trace)
|
|
169
|
+
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&traceId=<trace-id>&attr.debug.hypothesis=<id>"
|
|
170
|
+
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&attrContains.ai.prompt.messages=<phrase>"
|
|
171
|
+
|
|
172
|
+
# Log search (supports severity filter, case-insensitive body search)
|
|
173
|
+
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&severity=ERROR&body=<text>"
|
|
174
|
+
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&attrContains.debug.label=<substring>"
|
|
175
|
+
|
|
176
|
+
# AI call search (compact summaries with previews)
|
|
177
|
+
curl "http://127.0.0.1:27686/api/ai/calls?model=gpt-5.4&sessionId=<session>"
|
|
178
|
+
curl "http://127.0.0.1:27686/api/ai/calls?text=<phrase>&status=error"
|
|
179
|
+
|
|
180
|
+
# AI call detail (full prompt/response payloads)
|
|
181
|
+
curl "http://127.0.0.1:27686/api/ai/calls/<span-id>"
|
|
182
|
+
|
|
183
|
+
# AI stats
|
|
184
|
+
curl "http://127.0.0.1:27686/api/ai/stats?groupBy=model&agg=total_input_tokens"
|
|
185
|
+
|
|
186
|
+
curl http://127.0.0.1:27686/openapi.json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
List and search responses include `meta.nextCursor` when more data is available.
|
|
190
|
+
|
|
191
|
+
Motel gives you trace-correlated data — you can see which span a debug log belongs to, the parent operation, timing, and the full trace tree. Use `GET /api/traces/<trace-id>/spans` and `GET /api/spans/<span-id>/logs` to navigate the correlation.
|
|
192
|
+
|
|
193
|
+
For AI/LLM calls, use `/api/ai/calls` for compact searchable summaries (with prompt/response previews and token usage), and `/api/ai/calls/<span-id>` for full payloads.
|
|
194
|
+
|
|
195
|
+
## Effect
|
|
196
|
+
|
|
197
|
+
If the target repo uses Effect, read `references/effect.md` before changing runtime wiring or adding instrumentation.
|
|
198
|
+
|
|
199
|
+
## Cleanup
|
|
200
|
+
|
|
201
|
+
Use the bundled script at `scripts/clear-motel-debug.ts` when you want deterministic cleanup. It removes every block between `#region motel debug` and `#endregion motel debug` in JS/TS files and fails on unmatched markers.
|
|
202
|
+
|
|
203
|
+
If you cannot run the script, delete every marked block manually and then grep for `#region motel debug` to confirm none remain.
|