@bluelibs/runner-dev 5.1.0 → 6.0.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/AI.md +80 -6
- package/README.md +216 -22
- package/dist/cli/generators/scaffold/templates/package.json.d.ts +2 -2
- package/dist/cli/generators/scaffold/templates/package.json.js +2 -2
- package/dist/cli/generators/scaffold.js +1 -135
- package/dist/cli/generators/scaffold.js.map +1 -1
- package/dist/cli/generators/templates.js +2 -1
- package/dist/cli/generators/templates.js.map +1 -1
- package/dist/generated/resolvers-types.d.ts +545 -112
- package/dist/index.d.ts +39 -39
- package/dist/resources/cli.config.resource.d.ts +1 -1
- package/dist/resources/cli.config.resource.js +2 -2
- package/dist/resources/cli.config.resource.js.map +1 -1
- package/dist/resources/coverage.resource.d.ts +2 -2
- package/dist/resources/coverage.resource.js +3 -3
- package/dist/resources/coverage.resource.js.map +1 -1
- package/dist/resources/dev.resource.d.ts +1 -1
- package/dist/resources/dev.resource.js +2 -2
- package/dist/resources/dev.resource.js.map +1 -1
- package/dist/resources/docs.generator.resource.d.ts +4 -3
- package/dist/resources/docs.generator.resource.js +2 -2
- package/dist/resources/docs.generator.resource.js.map +1 -1
- package/dist/resources/graphql-accumulator.resource.d.ts +2 -2
- package/dist/resources/graphql-accumulator.resource.js +7 -3
- package/dist/resources/graphql-accumulator.resource.js.map +1 -1
- package/dist/resources/graphql.cli.resource.d.ts +1 -1
- package/dist/resources/graphql.cli.resource.js +2 -2
- package/dist/resources/graphql.cli.resource.js.map +1 -1
- package/dist/resources/graphql.query.cli.task.d.ts +14 -16
- package/dist/resources/graphql.query.cli.task.js +3 -3
- package/dist/resources/graphql.query.cli.task.js.map +1 -1
- package/dist/resources/graphql.query.task.d.ts +18 -18
- package/dist/resources/graphql.query.task.js +4 -4
- package/dist/resources/graphql.query.task.js.map +1 -1
- package/dist/resources/http.tag.d.ts +1 -1
- package/dist/resources/http.tag.js +2 -2
- package/dist/resources/http.tag.js.map +1 -1
- package/dist/resources/introspector.cli.resource.d.ts +2 -2
- package/dist/resources/introspector.cli.resource.js +37 -3
- package/dist/resources/introspector.cli.resource.js.map +1 -1
- package/dist/resources/introspector.resource.d.ts +3 -2
- package/dist/resources/introspector.resource.js +6 -6
- package/dist/resources/introspector.resource.js.map +1 -1
- package/dist/resources/live.resource.d.ts +7 -6
- package/dist/resources/live.resource.js +64 -25
- package/dist/resources/live.resource.js.map +1 -1
- package/dist/resources/models/Introspector.d.ts +59 -15
- package/dist/resources/models/Introspector.js +467 -137
- package/dist/resources/models/Introspector.js.map +1 -1
- package/dist/resources/models/durable.runtime.d.ts +1 -1
- package/dist/resources/models/durable.runtime.js +53 -2
- package/dist/resources/models/durable.runtime.js.map +1 -1
- package/dist/resources/models/durable.tools.d.ts +1 -1
- package/dist/resources/models/durable.tools.js +6 -3
- package/dist/resources/models/durable.tools.js.map +1 -1
- package/dist/resources/models/initializeFromStore.js +126 -19
- package/dist/resources/models/initializeFromStore.js.map +1 -1
- package/dist/resources/models/initializeFromStore.utils.d.ts +12 -7
- package/dist/resources/models/initializeFromStore.utils.js +319 -23
- package/dist/resources/models/initializeFromStore.utils.js.map +1 -1
- package/dist/resources/models/introspector.tools.js +18 -6
- package/dist/resources/models/introspector.tools.js.map +1 -1
- package/dist/resources/routeHandlers/createLiveStreamHandler.d.ts +16 -0
- package/dist/resources/routeHandlers/createLiveStreamHandler.js +127 -0
- package/dist/resources/routeHandlers/createLiveStreamHandler.js.map +1 -0
- package/dist/resources/routeHandlers/getDocsData.d.ts +4 -0
- package/dist/resources/routeHandlers/getDocsData.js +28 -0
- package/dist/resources/routeHandlers/getDocsData.js.map +1 -1
- package/dist/resources/routeHandlers/registerHttpRoutes.hook.d.ts +26 -23
- package/dist/resources/routeHandlers/registerHttpRoutes.hook.js +10 -9
- package/dist/resources/routeHandlers/registerHttpRoutes.hook.js.map +1 -1
- package/dist/resources/routeHandlers/requestCorrelation.d.ts +11 -0
- package/dist/resources/routeHandlers/requestCorrelation.js +29 -0
- package/dist/resources/routeHandlers/requestCorrelation.js.map +1 -0
- package/dist/resources/server.resource.d.ts +20 -20
- package/dist/resources/server.resource.js +17 -5
- package/dist/resources/server.resource.js.map +1 -1
- package/dist/resources/swap.cli.resource.d.ts +4 -4
- package/dist/resources/swap.cli.resource.js +2 -2
- package/dist/resources/swap.cli.resource.js.map +1 -1
- package/dist/resources/swap.resource.d.ts +7 -6
- package/dist/resources/swap.resource.js +188 -38
- package/dist/resources/swap.resource.js.map +1 -1
- package/dist/resources/swap.tools.d.ts +3 -2
- package/dist/resources/swap.tools.js +27 -27
- package/dist/resources/swap.tools.js.map +1 -1
- package/dist/resources/telemetry.resource.d.ts +1 -1
- package/dist/resources/telemetry.resource.js +46 -43
- package/dist/resources/telemetry.resource.js.map +1 -1
- package/dist/runner-compat.d.ts +85 -0
- package/dist/runner-compat.js +178 -0
- package/dist/runner-compat.js.map +1 -0
- package/dist/runner-node-compat.d.ts +2 -0
- package/dist/runner-node-compat.js +28 -0
- package/dist/runner-node-compat.js.map +1 -0
- package/dist/schema/index.js +8 -8
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/model.d.ts +100 -20
- package/dist/schema/model.js.map +1 -1
- package/dist/schema/query.js +25 -1
- package/dist/schema/query.js.map +1 -1
- package/dist/schema/types/AllType.js +13 -2
- package/dist/schema/types/AllType.js.map +1 -1
- package/dist/schema/types/BaseElementCommon.js +10 -0
- package/dist/schema/types/BaseElementCommon.js.map +1 -1
- package/dist/schema/types/ErrorType.js +1 -1
- package/dist/schema/types/ErrorType.js.map +1 -1
- package/dist/schema/types/EventType.js +19 -2
- package/dist/schema/types/EventType.js.map +1 -1
- package/dist/schema/types/InterceptorOwnersType.d.ts +2 -0
- package/dist/schema/types/InterceptorOwnersType.js +63 -0
- package/dist/schema/types/InterceptorOwnersType.js.map +1 -0
- package/dist/schema/types/LaneSummaryTypes.d.ts +3 -0
- package/dist/schema/types/LaneSummaryTypes.js +19 -0
- package/dist/schema/types/LaneSummaryTypes.js.map +1 -0
- package/dist/schema/types/LiveType.js +81 -76
- package/dist/schema/types/LiveType.js.map +1 -1
- package/dist/schema/types/ResourceType.js +101 -15
- package/dist/schema/types/ResourceType.js.map +1 -1
- package/dist/schema/types/RunOptionsType.d.ts +2 -0
- package/dist/schema/types/RunOptionsType.js +107 -0
- package/dist/schema/types/RunOptionsType.js.map +1 -0
- package/dist/schema/types/TagType.js +35 -4
- package/dist/schema/types/TagType.js.map +1 -1
- package/dist/schema/types/TaskType.js +20 -0
- package/dist/schema/types/TaskType.js.map +1 -1
- package/dist/schema/types/index.d.ts +4 -2
- package/dist/schema/types/index.js +10 -7
- package/dist/schema/types/index.js.map +1 -1
- package/dist/schema/types/middleware/common.d.ts +3 -2
- package/dist/schema/types/middleware/common.js +19 -13
- package/dist/schema/types/middleware/common.js.map +1 -1
- package/dist/ui/.vite/manifest.json +2 -2
- package/dist/ui/assets/docs-Btkv97Ls.js +302 -0
- package/dist/ui/assets/docs-Btkv97Ls.js.map +1 -0
- package/dist/ui/assets/docs-CipvKUxZ.css +1 -0
- package/dist/utils/healthCollectors.d.ts +37 -0
- package/dist/utils/healthCollectors.js +147 -0
- package/dist/utils/healthCollectors.js.map +1 -0
- package/dist/utils/lane-resources.d.ts +55 -0
- package/dist/utils/lane-resources.js +143 -0
- package/dist/utils/lane-resources.js.map +1 -0
- package/dist/utils/zod.js +36 -3
- package/dist/utils/zod.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -6
- package/readmes/runner-AI.md +740 -0
- package/readmes/runner-durable-workflows.md +2247 -0
- package/readmes/runner-full-guide.md +5869 -0
- package/readmes/runner-remote-lanes.md +909 -0
- package/dist/ui/assets/docs-B_-zFz4-.css +0 -1
- package/dist/ui/assets/docs-Be-GHfZi.js +0 -353
- package/dist/ui/assets/docs-Be-GHfZi.js.map +0 -1
package/AI.md
CHANGED
|
@@ -13,6 +13,25 @@ Runner-Dev is a powerful development toolkit for applications built with the **@
|
|
|
13
13
|
- **MCP Integration**: AI-native development environment
|
|
14
14
|
- **Tags (first-class)**: Discover Tag objects and reverse usage via GraphQL (`tags`, `tag(id)`).
|
|
15
15
|
- **Documentation UI Overviews**: Sortable and searchable overview tables with a `Used By` counter column for faster cross-element inspection.
|
|
16
|
+
- **Visibility Awareness**: Every element exposes `isPrivate` (based on Runner `isolate()` boundaries), and resources expose `isolation`.
|
|
17
|
+
- **Subtree Governance Awareness**: Resources expose normalized `subtree` policy summaries (middleware and validator counts per branch).
|
|
18
|
+
- **Lifecycle Awareness**: Resources expose `cooldown` support and run options expose `lifecycleMode`, `disposeBudgetMs`, `disposeDrainBudgetMs`.
|
|
19
|
+
- **Lane Awareness**: Events expose optional `eventLane` summaries (`globals.tags.eventLane`) and both tasks and events expose optional `rpcLane` summaries (`globals.tags.rpcLane`).
|
|
20
|
+
- **Isolation Wildcard Explorer**: Wildcard isolation rules can be clicked to inspect all matching resources in a searchable modal list.
|
|
21
|
+
- **Tag Handlers**: Tag views separate direct tag usages from handler elements that depend on the tag id.
|
|
22
|
+
- **Task Interceptor Introspection**: Tasks expose `interceptorCount` and `hasInterceptors` for runtime `task.intercept(...)` registrations.
|
|
23
|
+
- **Schema Export Compatibility**: Schema fields prefer `toJSONSchema()` exporters (including matcher-normalized schemas), with `zod` conversion as compatibility fallback.
|
|
24
|
+
|
|
25
|
+
## Runner 6.0 Migration Notes
|
|
26
|
+
|
|
27
|
+
| Before | After (hard switch) |
|
|
28
|
+
| --------------------- | --------------------------------------------------------- |
|
|
29
|
+
| `Resource.exports` | `Resource.isolation { deny, only, exports, exportsMode }` |
|
|
30
|
+
| `Middleware.global` | `Middleware.autoApply { enabled, scope, hasPredicate }` |
|
|
31
|
+
| `Tag.middlewares` | `Tag.taskMiddlewares` + `Tag.resourceMiddlewares` |
|
|
32
|
+
| N/A | `Tag.errors`, `Tag.targets` |
|
|
33
|
+
| `RunOptions.initMode` | `RunOptions.lifecycleMode` (+ disposal budgets) |
|
|
34
|
+
| `Resource.tunnelInfo` | Removed (hard switch to Event Lane + RPC Lane surfaces) |
|
|
16
35
|
|
|
17
36
|
## Available GraphQL Queries
|
|
18
37
|
|
|
@@ -23,18 +42,39 @@ Runner-Dev is a powerful development toolkit for applications built with the **@
|
|
|
23
42
|
query SystemOverview {
|
|
24
43
|
all {
|
|
25
44
|
id
|
|
45
|
+
isPrivate
|
|
26
46
|
meta {
|
|
27
47
|
title
|
|
28
48
|
description
|
|
29
49
|
}
|
|
30
50
|
filePath
|
|
31
51
|
}
|
|
52
|
+
runOptions {
|
|
53
|
+
mode
|
|
54
|
+
debug
|
|
55
|
+
debugMode
|
|
56
|
+
logsEnabled
|
|
57
|
+
logsPrintThreshold
|
|
58
|
+
logsPrintStrategy
|
|
59
|
+
logsBuffer
|
|
60
|
+
errorBoundary
|
|
61
|
+
shutdownHooks
|
|
62
|
+
dryRun
|
|
63
|
+
lazy
|
|
64
|
+
lifecycleMode
|
|
65
|
+
runtimeEventCycleDetection
|
|
66
|
+
hasOnUnhandledError
|
|
67
|
+
rootId
|
|
68
|
+
}
|
|
32
69
|
}
|
|
33
70
|
|
|
34
71
|
# Get specific element types
|
|
35
72
|
query Architecture {
|
|
36
73
|
tasks {
|
|
37
74
|
id
|
|
75
|
+
isPrivate
|
|
76
|
+
interceptorCount
|
|
77
|
+
hasInterceptors
|
|
38
78
|
meta {
|
|
39
79
|
title
|
|
40
80
|
description
|
|
@@ -47,6 +87,13 @@ query Architecture {
|
|
|
47
87
|
}
|
|
48
88
|
resources {
|
|
49
89
|
id
|
|
90
|
+
isPrivate
|
|
91
|
+
isolation {
|
|
92
|
+
deny
|
|
93
|
+
only
|
|
94
|
+
exports
|
|
95
|
+
exportsMode
|
|
96
|
+
}
|
|
50
97
|
meta {
|
|
51
98
|
title
|
|
52
99
|
description
|
|
@@ -146,6 +193,28 @@ query LiveTelemetry {
|
|
|
146
193
|
}
|
|
147
194
|
```
|
|
148
195
|
|
|
196
|
+
### SSE Live Streaming
|
|
197
|
+
|
|
198
|
+
Server-Sent Events endpoint at `GET /live/stream` for near-instant push instead of polling:
|
|
199
|
+
|
|
200
|
+
- **`telemetry`** event: `{ logs, emissions, errors, runs }` pushed ~100ms after each record (debounced)
|
|
201
|
+
- **`health`** event: `{ memory, cpu, eventLoop, gc }` every 2s
|
|
202
|
+
- Heartbeat comment every 15s to keep proxies alive
|
|
203
|
+
- `Live.onRecord(callback)` fires synchronously on each `record*` call; returns an unsubscribe function
|
|
204
|
+
- The built-in Live Panel auto-uses SSE and falls back to configurable-interval polling (500ms–10s)
|
|
205
|
+
|
|
206
|
+
### Correlation ID Trace View
|
|
207
|
+
|
|
208
|
+
The Live Panel includes a built-in **Trace View** — a unified timeline showing every log, event emission, error, and task run sharing a single `correlationId`, ordered chronologically. Click any correlationId badge (shown on logs, events, errors, and runs) to open the trace modal. This provides an in-process "distributed tracing" experience (like Jaeger).
|
|
209
|
+
|
|
210
|
+
### Unified Modal System
|
|
211
|
+
|
|
212
|
+
All UI modals (CodeModal, ExecuteModal, TraceView, RecentLogs, OverviewStatsPanel) are built on a shared `BaseModal` primitive (`src/ui/src/components/Documentation/components/modals/`). It provides:
|
|
213
|
+
|
|
214
|
+
- **Stacking**: A `ModalStackContext` tracks open modals and assigns ascending z-indexes (base 10 000 + 10 per layer). Global Escape closes the topmost modal first.
|
|
215
|
+
- **Consistent UX**: Portal to `document.body`, backdrop blur, scroll lock, focus trap, slide-up animation, ARIA `role="dialog"`.
|
|
216
|
+
- **Sizes**: `sm | md | lg | xl | fullscreen` with responsive fallback to fullscreen on small viewports.
|
|
217
|
+
|
|
149
218
|
### Diagnostics & Health
|
|
150
219
|
|
|
151
220
|
```graphql
|
|
@@ -262,9 +331,11 @@ npx @bluelibs/runner-dev new <project-name>
|
|
|
262
331
|
# Example
|
|
263
332
|
npx @bluelibs/runner-dev new my-awesome-app
|
|
264
333
|
```
|
|
334
|
+
|
|
265
335
|
This command creates a new Runner project with a complete TypeScript setup, Jest for testing, and all necessary dependencies.
|
|
266
336
|
|
|
267
337
|
Key flags for `new`:
|
|
338
|
+
|
|
268
339
|
- `--install`: Install dependencies after scaffolding.
|
|
269
340
|
- `--run-tests`: Run the generated test suite after installation.
|
|
270
341
|
- `--run`: Start the dev server after installation.
|
|
@@ -274,11 +345,13 @@ Key flags for `new`:
|
|
|
274
345
|
All commands can be prefixed with environment variables like `ENDPOINT` and `HEADERS`.
|
|
275
346
|
|
|
276
347
|
**Ping the server:**
|
|
348
|
+
|
|
277
349
|
```bash
|
|
278
350
|
ENDPOINT=http://localhost:1337/graphql npx @bluelibs/runner-dev ping
|
|
279
351
|
```
|
|
280
352
|
|
|
281
353
|
**Execute a GraphQL query (Remote Mode):**
|
|
354
|
+
|
|
282
355
|
```bash
|
|
283
356
|
# Simple query
|
|
284
357
|
ENDPOINT=http://localhost:1337/graphql npx @bluelibs/runner-dev query 'query { tasks { id } }'
|
|
@@ -306,11 +379,13 @@ npx @bluelibs/runner-dev query 'query { tasks { id } }' \
|
|
|
306
379
|
```
|
|
307
380
|
|
|
308
381
|
Selection logic:
|
|
382
|
+
|
|
309
383
|
- If `--entry-file` is provided, dry-run mode is used (no server; requires ts-node).
|
|
310
384
|
- Otherwise, the CLI uses a remote endpoint via `--endpoint` or `ENDPOINT/GRAPHQL_ENDPOINT`.
|
|
311
385
|
- If neither is provided, the command errors.
|
|
312
386
|
|
|
313
387
|
**Generate a project overview:**
|
|
388
|
+
|
|
314
389
|
```bash
|
|
315
390
|
ENDPOINT=http://localhost:1337/graphql npx @bluelibs/runner-dev overview --details 10
|
|
316
391
|
```
|
|
@@ -339,7 +414,6 @@ ENDPOINT=http://localhost:1337/graphql npx @bluelibs/runner-dev schema json
|
|
|
339
414
|
|
|
340
415
|
This direct CLI access provides a powerful way for AI assistants with shell access to script complex interactions, perform detailed introspection, and validate application state without relying on MCP tools.
|
|
341
416
|
|
|
342
|
-
|
|
343
417
|
## Common Use Cases
|
|
344
418
|
|
|
345
419
|
### 1. Understanding System Architecture
|
|
@@ -479,7 +553,10 @@ Minimal workflow setup pattern:
|
|
|
479
553
|
|
|
480
554
|
```ts
|
|
481
555
|
import { r } from "@bluelibs/runner";
|
|
482
|
-
import {
|
|
556
|
+
import {
|
|
557
|
+
durableWorkflowTag,
|
|
558
|
+
memoryDurableResource,
|
|
559
|
+
} from "@bluelibs/runner/node";
|
|
483
560
|
|
|
484
561
|
const durable = memoryDurableResource.fork("app.durable");
|
|
485
562
|
const durableRegistration = durable.with({});
|
|
@@ -496,10 +573,7 @@ const workflow = r
|
|
|
496
573
|
})
|
|
497
574
|
.build();
|
|
498
575
|
|
|
499
|
-
const app = r
|
|
500
|
-
.resource("app")
|
|
501
|
-
.register([durableRegistration, workflow])
|
|
502
|
-
.build();
|
|
576
|
+
const app = r.resource("app").register([durableRegistration, workflow]).build();
|
|
503
577
|
```
|
|
504
578
|
|
|
505
579
|
## Best Practices for AI Assistants
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Runner Dev Tools provide introspection, live telemetry, and a GraphQL API to exp
|
|
|
11
11
|
|
|
12
12
|
The way it works, is that this is a resource that opens a graphql server which opens your application to introspection.
|
|
13
13
|
|
|
14
|
-
If
|
|
14
|
+
If your runner primitives expose `toJSONSchema()` (for example matcher-based normalized schemas), runner-dev uses that as first-class schema export. `zod` schemas are also supported and converted to JSON Schema.
|
|
15
15
|
|
|
16
16
|
## Install
|
|
17
17
|
|
|
@@ -40,20 +40,42 @@ const app = resource({
|
|
|
40
40
|
|
|
41
41
|
- Fully-featured UI with AI assistance to explore your app, call tasks, emit events, diagnostics, logs and more.
|
|
42
42
|
- Overview tables across UI sections now include sortable and searchable columns (`ID`, `Title`, `Description`, `Used By`) with per-element usage counters.
|
|
43
|
+
- Overview tables now include `Visibility` (`Public`/`Private`) derived from Runner resource `isolate()` boundaries.
|
|
43
44
|
- Introspector: programmatic API to inspect tasks, hooks, resources, events, middleware, and diagnostics (including file paths, contents)
|
|
45
|
+
- Task introspection includes runtime `interceptorCount` / `hasInterceptors` (registered via `taskDependency.intercept(...)` in resource init).
|
|
46
|
+
- Resource introspection includes `isolation` (`deny`, `only`, `exports`, `exportsMode`) from `.isolate(...)`.
|
|
47
|
+
- Resource introspection includes `subtree` governance summaries (middleware attachment counts and validator counts per branch).
|
|
48
|
+
- Resource introspection indicates whether a resource exposes a `cooldown()` hook for shutdown lifecycle.
|
|
49
|
+
- Isolation wildcard rules are clickable in the docs UI and open a modal showing matched resources with inline filtering when lists are large.
|
|
50
|
+
- Event introspection includes `transactional`, `parallel`, optional `eventLane { laneId, orderingKey, metadata }`, and optional `rpcLane { laneId }`.
|
|
51
|
+
- Task introspection includes optional `rpcLane { laneId }`.
|
|
52
|
+
- Tag pages distinguish between directly tagged elements and tag handlers (elements that depend on the tag id).
|
|
44
53
|
- Live: in-memory logs and event emissions
|
|
45
54
|
- Live File Previews and Saving.
|
|
46
55
|
- GraphQL server: deep graph navigation over your app’s topology and live data
|
|
47
56
|
- CLI with scaffolding, query-ing capabilities on a live endpoint or via dry-run mode.
|
|
48
57
|
- MCP server: allow your AI to do introspection for you.
|
|
49
58
|
|
|
59
|
+
## Runner 6.0 Migration Notes
|
|
60
|
+
|
|
61
|
+
| Before | After (hard switch) |
|
|
62
|
+
| --------------------- | -------------------------------------------------------------------------------------------- |
|
|
63
|
+
| `Resource.exports` | `Resource.isolation { deny, only, exports, exportsMode }` |
|
|
64
|
+
| `Middleware.global` | `Middleware.autoApply { enabled, scope, hasPredicate }` |
|
|
65
|
+
| `Tag.middlewares` | `Tag.taskMiddlewares` + `Tag.resourceMiddlewares` |
|
|
66
|
+
| N/A | `Tag.errors`, `Tag.targets` |
|
|
67
|
+
| `RunOptions.initMode` | `RunOptions.lifecycleMode` + `dispose.{ totalBudgetMs, drainingBudgetMs, cooldownWindowMs }` |
|
|
68
|
+
| N/A | `Resource.subtree`, `Resource.cooldown` |
|
|
69
|
+
| N/A | `Event.transactional`, `Event.parallel`, `Event.eventLane`, `Event.rpcLane`, `Task.rpcLane` |
|
|
70
|
+
| `Resource.tunnelInfo` | Removed (hard switch to lane surfaces) |
|
|
71
|
+
|
|
50
72
|
## Table of Contents
|
|
51
73
|
|
|
52
74
|
- [Quickstart Guide](#quickstart)
|
|
53
75
|
- [Model Context Protocol (MCP) Server](#cli-usage-mcp-server)
|
|
54
76
|
- [CLI Tooling & Scaffolding](#cli-usage-direct)
|
|
55
77
|
- [Live Telemetry & Correlation](#live-telemetry)
|
|
56
|
-
- [Hot-Swapping Debugging System](
|
|
78
|
+
- [Hot-Swapping Debugging System](#hot-swapping-debugging-system)
|
|
57
79
|
- [GraphQL API Examples](#example-queries)
|
|
58
80
|
- [API Reference](API_REFERENCE.md)
|
|
59
81
|
- [Contributing & Local Dev](CONTRIBUTING.md)
|
|
@@ -83,9 +105,10 @@ export const app = resource({
|
|
|
83
105
|
|
|
84
106
|
Once your application is running with the `dev` resource, you can access the visual DevTools UI:
|
|
85
107
|
|
|
86
|
-
|
|
108
|
+
Open [http://localhost:1337](http://localhost:1337) in your browser.
|
|
87
109
|
|
|
88
110
|
Inside the UI, you can:
|
|
111
|
+
|
|
89
112
|
- Explore the resource graph.
|
|
90
113
|
- Manually invoke tasks with custom inputs.
|
|
91
114
|
- Inspect live logs and event emissions in real-time.
|
|
@@ -318,13 +341,13 @@ Precedence:
|
|
|
318
341
|
|
|
319
342
|
### CLI Summary
|
|
320
343
|
|
|
321
|
-
| Category
|
|
322
|
-
|
|
|
323
|
-
| **New Project** | `runner-dev new <project-name>`
|
|
344
|
+
| Category | Description |
|
|
345
|
+
| --------------- | --------------------------------------------------------- |
|
|
346
|
+
| **New Project** | `runner-dev new <project-name>` |
|
|
324
347
|
| **Scaffolding** | `runner-dev new <resource\|task\|event\|tag\|middleware>` |
|
|
325
|
-
| **Queries**
|
|
326
|
-
| **Overview**
|
|
327
|
-
| **Schema**
|
|
348
|
+
| **Queries** | `runner-dev query 'query { ... }'` |
|
|
349
|
+
| **Overview** | `runner-dev overview --details 10` |
|
|
350
|
+
| **Schema** | `runner-dev schema sdl` |
|
|
328
351
|
|
|
329
352
|
---
|
|
330
353
|
|
|
@@ -547,6 +570,41 @@ Notes:
|
|
|
547
570
|
- `cpu.usage` is a ratio; `loadAverage` is 1‑minute OS load.
|
|
548
571
|
- `eventLoop.lag` may be 0 if `monitorEventLoopDelay` is unavailable.
|
|
549
572
|
|
|
573
|
+
### SSE Live Streaming
|
|
574
|
+
|
|
575
|
+
In addition to GraphQL polling, the server exposes a **Server-Sent Events** endpoint at `GET /live/stream` for near-instant telemetry delivery:
|
|
576
|
+
|
|
577
|
+
```http
|
|
578
|
+
GET /live/stream
|
|
579
|
+
Accept: text/event-stream
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
The endpoint pushes two event types:
|
|
583
|
+
|
|
584
|
+
| Event | Cadence | Payload |
|
|
585
|
+
| ----------- | -------------------------------------------- | ----------------------------------------------------------- |
|
|
586
|
+
| `telemetry` | ~100ms after each `record*` call (debounced) | `{ logs, emissions, errors, runs }` (delta since last push) |
|
|
587
|
+
| `health` | Every 2s | `{ memory, cpu, eventLoop, gc }` |
|
|
588
|
+
|
|
589
|
+
A heartbeat comment (`: heartbeat`) is sent every 15s to keep the connection alive through proxies.
|
|
590
|
+
|
|
591
|
+
**JavaScript client example:**
|
|
592
|
+
|
|
593
|
+
```js
|
|
594
|
+
const es = new EventSource("http://localhost:1337/live/stream");
|
|
595
|
+
es.addEventListener("telemetry", (e) => {
|
|
596
|
+
const { logs, emissions, errors, runs } = JSON.parse(e.data);
|
|
597
|
+
// merge into your state
|
|
598
|
+
});
|
|
599
|
+
es.addEventListener("health", (e) => {
|
|
600
|
+
const { memory, cpu, eventLoop, gc } = JSON.parse(e.data);
|
|
601
|
+
});
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
The built-in Live Panel UI automatically uses SSE when available and falls back to configurable-interval polling (500ms–10s slider) when SSE is not supported.
|
|
605
|
+
|
|
606
|
+
**Programmatic notification hook:** The `Live` interface exposes `onRecord(callback)` which fires synchronously whenever a `record*` method is called, returning an unsubscribe function. This is the mechanism the SSE endpoint uses internally.
|
|
607
|
+
|
|
550
608
|
### Correlation and call chains
|
|
551
609
|
|
|
552
610
|
- What is correlationId? An opaque UUID (via `crypto.randomUUID()`) created for the first task in a run chain.
|
|
@@ -583,6 +641,14 @@ query TraceByCorrelation($ts: Float, $cid: String!) {
|
|
|
583
641
|
}
|
|
584
642
|
```
|
|
585
643
|
|
|
644
|
+
#### Trace View (UI)
|
|
645
|
+
|
|
646
|
+
The Live Panel includes a built-in **Trace View** — click any `correlationId` badge in the Logs, Events, Errors, or Runs sub-tabs to open a unified timeline modal showing every entry that shares that ID, ordered chronologically. Each entry is color-coded by kind (log, event, error, run) with a vertical timeline gutter, relative offset labels, and expandable details. This provides an in-process "distributed tracing" experience similar to Jaeger or Zipkin, but entirely within the Dev UI.
|
|
647
|
+
|
|
648
|
+
#### Unified Modal System
|
|
649
|
+
|
|
650
|
+
All Dev UI modals (code viewer, execute, trace view, log details, stats overlay) share a common `BaseModal` primitive that provides portal rendering, backdrop blur, focus trap, scroll lock, slide-up animation, and ARIA dialog semantics. A `ModalStackContext` manages stacking so modals can open on top of other modals — each layer gets a higher z-index and the global <kbd>Esc</kbd> key always closes the topmost one first.
|
|
651
|
+
|
|
586
652
|
## Emitting Events (Runner-native)
|
|
587
653
|
|
|
588
654
|
- Define an event:
|
|
@@ -640,7 +706,7 @@ export const logSomething = task({
|
|
|
640
706
|
|
|
641
707
|
For full details on development, testing, and codegen, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
642
708
|
|
|
643
|
-
##
|
|
709
|
+
## Hot-Swapping Debugging System
|
|
644
710
|
|
|
645
711
|
**Revolutionary live debugging feature that allows AI assistants and developers to dynamically replace task run functions in live applications.**
|
|
646
712
|
|
|
@@ -683,6 +749,18 @@ export const app = resource({
|
|
|
683
749
|
|
|
684
750
|
#### Queries
|
|
685
751
|
|
|
752
|
+
**Get the effective run options (how the app was started):**
|
|
753
|
+
|
|
754
|
+
```graphql
|
|
755
|
+
query {
|
|
756
|
+
runOptions {
|
|
757
|
+
mode
|
|
758
|
+
debug
|
|
759
|
+
rootId
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
```
|
|
763
|
+
|
|
686
764
|
**Get currently swapped tasks:**
|
|
687
765
|
|
|
688
766
|
```graphql
|
|
@@ -750,7 +828,7 @@ mutation {
|
|
|
750
828
|
await deps.emitLog({
|
|
751
829
|
timestamp: new Date(),
|
|
752
830
|
level: "info",
|
|
753
|
-
message: "
|
|
831
|
+
message: "DEBUG: Creating user started",
|
|
754
832
|
data: { input }
|
|
755
833
|
});
|
|
756
834
|
}
|
|
@@ -775,7 +853,7 @@ mutation {
|
|
|
775
853
|
await deps.emitLog({
|
|
776
854
|
timestamp: new Date(),
|
|
777
855
|
level: "info",
|
|
778
|
-
message: "
|
|
856
|
+
message: "DEBUG: User created successfully",
|
|
779
857
|
data: { result }
|
|
780
858
|
});
|
|
781
859
|
}
|
|
@@ -856,7 +934,7 @@ Swapped functions can emit logs that are captured by the live telemetry system:
|
|
|
856
934
|
# After swapping with debug logging, query the logs
|
|
857
935
|
query RecentDebugLogs {
|
|
858
936
|
live {
|
|
859
|
-
logs(last: 50, filter: { messageIncludes: "
|
|
937
|
+
logs(last: 50, filter: { messageIncludes: "DEBUG" }) {
|
|
860
938
|
timestampMs
|
|
861
939
|
level
|
|
862
940
|
message
|
|
@@ -1080,7 +1158,7 @@ The system automatically handles complex JavaScript types:
|
|
|
1080
1158
|
|
|
1081
1159
|
For advanced debugging, the system provides an `eval` mutation to execute arbitrary JavaScript/TypeScript code on the server.
|
|
1082
1160
|
|
|
1083
|
-
|
|
1161
|
+
**Security Warning**: This feature is powerful and executes code with the same privileges as the application. It is intended for development environments only and is disabled by default in production. To enable it, set the environment variable `RUNNER_DEV_EVAL=1`.
|
|
1084
1162
|
|
|
1085
1163
|
#### `eval` Mutation
|
|
1086
1164
|
|
|
@@ -1123,13 +1201,129 @@ mutation {
|
|
|
1123
1201
|
|
|
1124
1202
|
### Architecture
|
|
1125
1203
|
|
|
1126
|
-
The hot-swapping system
|
|
1204
|
+
The hot-swapping system is organized into five high-level capabilities:
|
|
1205
|
+
|
|
1206
|
+
- **Execution Control**: swaps task `run` implementations at runtime and supports rollback.
|
|
1207
|
+
- **Validation Pipeline**: parses and compiles submitted code before activation.
|
|
1208
|
+
- **API Surface**: exposes swap and restore operations through GraphQL mutations.
|
|
1209
|
+
- **Observability**: integrates with live telemetry so swapped behavior can be inspected immediately.
|
|
1210
|
+
- **Safety Controls**: isolates failures to the attempted swap and preserves previous task behavior when validation fails.
|
|
1211
|
+
|
|
1212
|
+
The implementation remains fully type-safe and is covered by both unit and GraphQL integration tests.
|
|
1213
|
+
|
|
1214
|
+
---
|
|
1215
|
+
|
|
1216
|
+
## System Architecture
|
|
1217
|
+
|
|
1218
|
+
### Overview
|
|
1219
|
+
|
|
1220
|
+
Runner-Dev is built as a modular system of resources that integrate with the @bluelibs/runner framework to provide comprehensive development tools. The architecture follows a resource-based composition pattern where each component is a self-contained resource that can be registered and configured independently.
|
|
1221
|
+
|
|
1222
|
+
### Core Components
|
|
1223
|
+
|
|
1224
|
+
```mermaid
|
|
1225
|
+
graph TB
|
|
1226
|
+
subgraph "Core Framework (@bluelibs/runner)"
|
|
1227
|
+
App[Application Root]
|
|
1228
|
+
Resource[Resources]
|
|
1229
|
+
Task[Tasks]
|
|
1230
|
+
Event[Events]
|
|
1231
|
+
Middleware[Middleware]
|
|
1232
|
+
Hook[Hooks]
|
|
1233
|
+
Tag[Tags]
|
|
1234
|
+
end
|
|
1235
|
+
|
|
1236
|
+
subgraph "DevTools Layer (@bluelibs/runner-dev)"
|
|
1237
|
+
Dev[dev Resource]
|
|
1238
|
+
Introspector[Introspector]
|
|
1239
|
+
Live[Live Telemetry]
|
|
1240
|
+
Swap[Swap Manager]
|
|
1241
|
+
GraphQL[GraphQL Server]
|
|
1242
|
+
MCP[MCP Server]
|
|
1243
|
+
end
|
|
1244
|
+
|
|
1245
|
+
subgraph "Interfaces"
|
|
1246
|
+
UI[React UI]
|
|
1247
|
+
CLI[CLI Tools]
|
|
1248
|
+
AI[AI Assistants]
|
|
1249
|
+
end
|
|
1250
|
+
|
|
1251
|
+
App --> Dev
|
|
1252
|
+
Dev --> Introspector
|
|
1253
|
+
Dev --> Live
|
|
1254
|
+
Dev --> Swap
|
|
1255
|
+
Dev --> GraphQL
|
|
1256
|
+
GraphQL --> MCP
|
|
1257
|
+
|
|
1258
|
+
Introspector --> Resource
|
|
1259
|
+
Introspector --> Task
|
|
1260
|
+
Introspector --> Event
|
|
1261
|
+
Introspector --> Middleware
|
|
1262
|
+
Introspector --> Hook
|
|
1263
|
+
Introspector --> Tag
|
|
1264
|
+
|
|
1265
|
+
GraphQL --> UI
|
|
1266
|
+
GraphQL --> CLI
|
|
1267
|
+
MCP --> AI
|
|
1268
|
+
```
|
|
1269
|
+
|
|
1270
|
+
### Component Responsibilities (High-Level)
|
|
1271
|
+
|
|
1272
|
+
| Layer | Responsibility |
|
|
1273
|
+
| --------------------------- | -------------------------------------------------------------------------------- |
|
|
1274
|
+
| **Composition Layer** | Registers and wires DevTools capabilities into the Runner application lifecycle. |
|
|
1275
|
+
| **Introspection Layer** | Builds a runtime model of tasks, resources, events, middleware, hooks, and tags. |
|
|
1276
|
+
| **Observability Layer** | Captures logs, emissions, errors, runs, and health metrics for analysis. |
|
|
1277
|
+
| **Execution Control Layer** | Supports remote task invocation and controlled hot-swapping workflows. |
|
|
1278
|
+
| **Access Layer** | Exposes a GraphQL API and transports for UI, CLI, and MCP clients. |
|
|
1279
|
+
|
|
1280
|
+
### Data Flow
|
|
1281
|
+
|
|
1282
|
+
```mermaid
|
|
1283
|
+
sequenceDiagram
|
|
1284
|
+
participant App as Runner App
|
|
1285
|
+
participant Dev as dev Resource
|
|
1286
|
+
participant Intro as Introspector
|
|
1287
|
+
participant GQL as GraphQL Server
|
|
1288
|
+
participant UI as React UI
|
|
1289
|
+
|
|
1290
|
+
App->>Dev: register dev.with({port: 1337})
|
|
1291
|
+
Dev->>Intro: walk application graph
|
|
1292
|
+
Intro-->>Dev: serialized topology
|
|
1293
|
+
Dev->>GQL: start server on port 1337
|
|
1294
|
+
|
|
1295
|
+
UI->>GQL: query { tasks { id dependsOn } }
|
|
1296
|
+
GQL-->>UI: introspected data
|
|
1297
|
+
|
|
1298
|
+
UI->>GQL: mutation invokeTask(...)
|
|
1299
|
+
GQL->>App: execute task
|
|
1300
|
+
App-->>GQL: result
|
|
1301
|
+
GQL-->>UI: response
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
### Key Architectural Patterns
|
|
1305
|
+
|
|
1306
|
+
1. **Resource-Based Composition**: Everything in Runner is a resource that can be registered and composed. The dev tools themselves are resources.
|
|
1307
|
+
|
|
1308
|
+
2. **Introspection System**: The Introspector walks the application graph at runtime, extracting metadata about:
|
|
1309
|
+
|
|
1310
|
+
- Tasks (dependencies, emissions, interceptors)
|
|
1311
|
+
- Resources (isolation rules, subtree governance, cooldown hooks)
|
|
1312
|
+
- Events (listeners, transactional/parallel modes, lanes)
|
|
1313
|
+
- Middleware (auto-apply scopes, tags)
|
|
1314
|
+
- Tags (cross-cutting concerns with handlers)
|
|
1315
|
+
|
|
1316
|
+
3. **Live Telemetry**: In-memory store for recent activity with SSE streaming via `/live/stream`
|
|
1317
|
+
|
|
1318
|
+
4. **Hot-Swapping**: Modify task implementations without restart via `swapTask` mutation
|
|
1319
|
+
|
|
1320
|
+
5. **GraphQL API**: Full schema at `src/schema/` with queries for architecture and mutations for invocation/swapping
|
|
1321
|
+
|
|
1322
|
+
6. **MCP Integration**: AI assistants can connect via Model Context Protocol to introspect and interact with running apps
|
|
1127
1323
|
|
|
1128
|
-
|
|
1129
|
-
- **GraphQL Types** (`src/schema/types/SwapType.ts`): Type definitions for GraphQL API
|
|
1130
|
-
- **GraphQL Mutations** (`src/schema/mutation.ts`): Remote swap operations
|
|
1131
|
-
- **TypeScript Compiler**: Automatic code compilation and validation
|
|
1132
|
-
- **State Management**: Tracking of swapped functions and original code
|
|
1133
|
-
- **Error Handling**: Comprehensive validation and recovery mechanisms
|
|
1324
|
+
### Entry Points
|
|
1134
1325
|
|
|
1135
|
-
|
|
1326
|
+
- **Main export**: `src/index.ts` - exports `dev` resource and types
|
|
1327
|
+
- **CLI entry**: `src/cli.ts` - command-line interface
|
|
1328
|
+
- **MCP entry**: `src/mcp.ts` - Model Context Protocol server
|
|
1329
|
+
- **UI entry**: `src/ui/index.html` - React documentation UI
|
|
@@ -12,10 +12,10 @@ export declare function packageJson(projectName: string): {
|
|
|
12
12
|
readonly "schema:sdl": "runner-dev schema sdl";
|
|
13
13
|
};
|
|
14
14
|
readonly dependencies: {
|
|
15
|
-
readonly "@bluelibs/runner": "^
|
|
15
|
+
readonly "@bluelibs/runner": "^6.0.0";
|
|
16
16
|
};
|
|
17
17
|
readonly devDependencies: {
|
|
18
|
-
readonly "@bluelibs/runner-dev": "^
|
|
18
|
+
readonly "@bluelibs/runner-dev": "^6.0.0";
|
|
19
19
|
readonly typescript: "^5.6.3";
|
|
20
20
|
readonly tsx: "^4.19.2";
|
|
21
21
|
readonly jest: "^29.7.0";
|
|
@@ -16,10 +16,10 @@ function packageJson(projectName) {
|
|
|
16
16
|
"schema:sdl": "runner-dev schema sdl",
|
|
17
17
|
},
|
|
18
18
|
dependencies: {
|
|
19
|
-
"@bluelibs/runner": "^
|
|
19
|
+
"@bluelibs/runner": "^6.0.0",
|
|
20
20
|
},
|
|
21
21
|
devDependencies: {
|
|
22
|
-
"@bluelibs/runner-dev": "^
|
|
22
|
+
"@bluelibs/runner-dev": "^6.0.0",
|
|
23
23
|
typescript: "^5.6.3",
|
|
24
24
|
tsx: "^4.19.2",
|
|
25
25
|
jest: "^29.7.0",
|