{"_id":"@brechtknecht/turbolog","name":"@brechtknecht/turbolog","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@brechtknecht/turbolog","version":"0.1.0","description":"Developer-first runtime observability toolkit with a Turbo-inspired TUI and local MCP server. Everything in the runtime is a stream.","type":"module","license":"MIT","author":{"name":"Felix Tesche","email":"felix.tesche@gmail.com"},"homepage":"https://github.com/brechtknecht/turbolog#readme","repository":{"type":"git","url":"git+https://github.com/brechtknecht/turbolog.git"},"bugs":{"url":"https://github.com/brechtknecht/turbolog/issues"},"keywords":["logging","logger","observability","tui","terminal-ui","mcp","model-context-protocol","streams","devtools","debugging"],"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./mcp":{"types":"./dist/mcp/server.d.ts","import":"./dist/mcp/server.js","require":"./dist/mcp/server.cjs"}},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","bin":{"turbolog":"dist/tui/cli.js","turbolog-mcp":"dist/mcp/cli.js"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","tui":"node dist/tui/cli.js","mcp":"node dist/mcp/cli.js","demo":"node examples/demo-app.mjs","prepublishOnly":"npm run typecheck && npm run build"},"publishConfig":{"access":"public"},"sideEffects":false,"dependencies":{"@modelcontextprotocol/sdk":"^1.12.0","zod":"^3.24.1"},"devDependencies":{"@types/node":"^22.10.0","tsup":"^8.3.5","typescript":"^5.7.2"},"engines":{"node":">=18"},"_id":"@brechtknecht/turbolog@0.1.0","gitHead":"95a62eab278bbc12e732e81901a8a7d7400c9348","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-TB3A27LypZQw+nddihbCPfTwgJNI0P55DFBReN7Qae01NHCYd3HxsIH2XCNijaXssaBjLr8MroLLZo61yzMWig==","shasum":"167e3c759ce2164a460e1d5ddec424978782eeba","tarball":"https://registry.npmjs.org/@brechtknecht/turbolog/-/turbolog-0.1.0.tgz","fileCount":23,"unpackedSize":486898,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEe2uoOU1NmJWhUh1IOVkz9RSMK9z3h8R7/+sJA1GqX4AiEA4CjquZW0JGYgwFjxrPuoOizU9sf7Jv+BWkiaW9ZjTME="}]},"_npmUser":{"name":"brechtknecht","email":"felix.tesche@gmail.com"},"directories":{},"maintainers":[{"name":"brechtknecht","email":"felix.tesche@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/turbolog_0.1.0_1783084172371_0.9602450136588663"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-03T13:09:32.244Z","0.1.0":"2026-07-03T13:09:32.509Z","modified":"2026-07-03T13:09:32.787Z"},"maintainers":[{"name":"brechtknecht","email":"felix.tesche@gmail.com"}],"description":"Developer-first runtime observability toolkit with a Turbo-inspired TUI and local MCP server. Everything in the runtime is a stream.","homepage":"https://github.com/brechtknecht/turbolog#readme","keywords":["logging","logger","observability","tui","terminal-ui","mcp","model-context-protocol","streams","devtools","debugging"],"repository":{"type":"git","url":"git+https://github.com/brechtknecht/turbolog.git"},"author":{"name":"Felix Tesche","email":"felix.tesche@gmail.com"},"bugs":{"url":"https://github.com/brechtknecht/turbolog/issues"},"license":"MIT","readme":"# turbolog\n\n> Developer-first runtime observability with a Turbo-inspired TUI and a local MCP server.\n> Everything in your runtime — logs, HTTP, SQL, jobs, cache, events — is a **stream** you can view, filter, search, inspect and control in real time.\n\nturbolog embeds into your app as a tiny SDK. It records events into an in-memory\nstore and serves them over a **local socket**. Two clients attach to that socket:\n\n- **the TUI** (`npx turbolog`) — a live terminal UI\n- **the MCP server** (`turbolog-mcp`) — exposes the runtime to AI agents/editors\n\n```\n   your app ──createLogger()──▶ turbolog runtime ──local socket──┬──▶ TUI\n                                                                 └──▶ MCP server ──▶ Claude / Cursor / VS Code\n```\n\nLocal-first. Zero-config. Development-only by default (off when `NODE_ENV=production` unless `TURBOLOG=1`).\n\n---\n\n## Install\n\n```bash\nnpm install @brechtknecht/turbolog       # in your project\n```\n\nThe package is scoped, but the CLI commands stay `turbolog` (TUI) and\n`turbolog-mcp` (MCP server). (For local development of turbolog itself:\n`npm install && npm run build`.)\n\n## 1. Embed it in your app\n\n```ts\nimport { createLogger } from \"@brechtknecht/turbolog\";\n\nconst log = createLogger();          // also starts a local socket server\n\nlog.info(\"Application started\", { pid: process.pid });\n\nconst db = log.channel(\"db\");        // channels appear as their own streams\ndb.info(\"Connected\");\ndb.warn(\"Slow query\", { duration: 320, table: \"users\" });\n\nlog.channel(\"auth\").warn(\"Invalid password\", { user: \"alice\" });\n```\n\nStructured/typed streams (used by framework integrations) go through `emit`:\n\n```ts\nlog.emit({\n  stream: \"http\",\n  message: \"GET /users 200\",\n  meta: { method: \"GET\", route: \"/users\", status: 200, tenant: \"acme\" },\n  duration: 42,\n  requestId: \"req-91\",\n  traceId: \"trace-abc\",\n});\n```\n\n`log.error(new Error(\"boom\"))` captures the stack automatically.\n\n## 2. Attach the TUI\n\nFrom the **same project directory** (so it discovers the socket):\n\n```bash\nnpx turbolog\n```\n\n```\n turbolog                                              ● connected\n┌ STREAMS ────┬ OUTPUT · http  /level:error ───────────────────────┐\n│▸≡ All    153│ 12:41:02 ERROR [http] GET /health 500        412ms  │\n│  ⛁ db      7│ 12:41:02 WARN  [sql]  SELECT * FROM users     118ms │\n│  ↔ http   49│ 12:41:03 INFO  [http] GET /orders 200   route=/ord… │\n│  ⛁ sql    49│ ...                                                 │\n└─────────────┴────────────────────────────────────────────────────┘\n ↑↓ move · → output · e toggle · c clear · / search · r rec · ? help · q quit\n```\n\n**Keys:** `↑↓`/`jk` move · `tab` switch pane · `→`/`enter` output / inspect ·\n`/` search · `e` enable/disable stream · `c` clear · `r` record · `x` export ·\n`i` inspect · `?` help · `q` quit.\n\n## 3. Attach the MCP server\n\nPoint any MCP client (Claude Desktop, Cursor, VS Code) at `turbolog-mcp`, with\n`cwd` set to your project (so it finds the same socket). See\n[`examples/mcp.json`](examples/mcp.json):\n\n```json\n{\n  \"mcpServers\": {\n    \"turbolog\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"turbolog-mcp\"],\n      \"cwd\": \"/absolute/path/to/your/project\"\n    }\n  }\n}\n```\n\nYour app must be running. Then ask things like *\"Summarize the last 100 errors\"*,\n*\"Show all failed HTTP requests\"*, *\"Find slow SQL queries\"*.\n\n**Tools:** `list_streams`, `read_stream`, `tail_stream`, `enable_stream`,\n`disable_stream`, `clear_stream`, `search_logs`, `inspect_event`,\n`list_requests`, `inspect_request`, `list_errors`, `record_session`,\n`stop_recording`, `export_session`, `execute_command`.\n\n**Resources:** `turbolog://streams`, `turbolog://errors`, `turbolog://history`.\n\n---\n\n## Search query language\n\nUsed by both the TUI `/` search and the `search_logs` MCP tool. Space-separated\ntokens are ANDed together.\n\n| Example | Matches |\n|---|---|\n| `payment` | free text in message or metadata |\n| `level:error` | exact level |\n| `level:>=warn` | level at or above warn |\n| `channel=db` | events on channel `db` |\n| `stream=http` | events on stream `http` |\n| `duration>100` | numeric compare (`> < >= <= =`), unit suffixes ok (`100ms`) |\n| `tenant=foo table=users` | metadata equality |\n| `trace=abc123` / `request=42` | correlation ids |\n\n## Runtime controls (no restart)\n\nEnable · Disable / Pause · Resume · Mute · Clear · Record · Search — per stream,\nlive, from the TUI or via MCP.\n\n## Session recording\n\n`r` in the TUI (or `record_session` / `stop_recording` via MCP) captures events;\n`x` / `export_session` writes `.turbolog/session-<ts>.json` for bug reports and replay.\n\n---\n\n## Try the demo\n\n```bash\nnpm run build\nnode examples/demo-app.mjs      # generates logs/http/sql/cache/queue streams\nnpx turbolog                    # in another terminal, same directory\n```\n\n## Configuration\n\n| Env | Effect |\n|---|---|\n| `TURBOLOG=1` / `TURBOLOG=0` | force on / off (overrides `NODE_ENV`) |\n| `TURBOLOG_SOCKET=<path>` | explicit socket path (client + server must agree) |\n| `TURBOLOG_DEBUG=1` | log server startup errors |\n\nSocket path resolution: explicit option → `TURBOLOG_SOCKET` → `.turbolog/socket`\ndiscovery file → deterministic default derived from the project directory. This\nis why the app, TUI and MCP server agree with zero configuration when run from\nthe same directory.\n\n## API\n\n```ts\nconst log = createLogger({ enabled?, serve?, socketPath?, cwd? });\nlog.info/warn/error/debug/trace(message, meta?)\nlog.channel(name)         // → scoped logger, shows as its own stream\nlog.emit({ stream, message, meta, level?, duration?, traceId?, requestId? })\nlog.store                 // underlying Store (read/subscribe in-process)\nawait log.serve()         // start socket server (idempotent) → socket path\nlog.close()               // stop serving\n```\n\nProgrammatic clients: `TurbologClient` (socket client used by TUI + MCP),\n`TurbologServer`, `Store`, `search`, `compileQuery`.\n\n## Status\n\nMVP. Implemented: core SDK, streams + channels, in-memory store, socket\nserver/client, query language, TUI (sidebar, output, search, inspector,\ncontrols, recording), and a working local MCP server (tools + resources).\n\nNot yet: framework integration packages (`@turbolog/express`, `/next`,\n`/react`), plugin system, split/timeline views, OpenTelemetry bridge.\n\nMIT.\n","readmeFilename":"README.md","_rev":"1-7b4bf171e8bcb51806701eab945f6816"}