@expressots/studio-agent 4.0.0-preview.1 → 4.0.0-preview.3
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/README.md +143 -143
- package/dist/agent.d.ts +75 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +443 -14
- package/dist/agent.js.map +1 -1
- package/dist/discovery/route-scanner.d.ts +62 -1
- package/dist/discovery/route-scanner.d.ts.map +1 -1
- package/dist/discovery/route-scanner.js +923 -101
- package/dist/discovery/route-scanner.js.map +1 -1
- package/dist/identity/index.d.ts +2 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +2 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/install-id.d.ts +22 -0
- package/dist/identity/install-id.d.ts.map +1 -0
- package/dist/identity/install-id.js +73 -0
- package/dist/identity/install-id.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/instrumentation/tracer.d.ts.map +1 -1
- package/dist/instrumentation/tracer.js +40 -4
- package/dist/instrumentation/tracer.js.map +1 -1
- package/dist/introspection/database-introspector.d.ts +58 -0
- package/dist/introspection/database-introspector.d.ts.map +1 -0
- package/dist/introspection/database-introspector.js +351 -0
- package/dist/introspection/database-introspector.js.map +1 -0
- package/dist/logging/log-capture.d.ts.map +1 -1
- package/dist/logging/log-capture.js +23 -1
- package/dist/logging/log-capture.js.map +1 -1
- package/dist/recording/request-recorder.js +73 -73
- package/dist/security/posture-analyzer.d.ts.map +1 -1
- package/dist/security/posture-analyzer.js +1 -1
- package/dist/security/posture-analyzer.js.map +1 -1
- package/dist/types/index.d.ts +261 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/package.json +18 -15
package/README.md
CHANGED
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
# @expressots/studio-agent
|
|
2
|
-
|
|
3
|
-
Instrumentation agent for ExpressoTS Studio - provides route discovery, OpenTelemetry tracing, and request recording.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Route Discovery**: Automatically scans your ExpressoTS application to discover all routes, controllers, and services
|
|
8
|
-
- **OpenTelemetry Tracing**: Full distributed tracing with automatic instrumentation
|
|
9
|
-
- **Request Recording**: Record and replay HTTP requests for debugging
|
|
10
|
-
- **WebSocket Communication**: Real-time updates to Studio UI
|
|
11
|
-
- **Metrics Collection**: P50/P95/P99 latency, error rates, and more
|
|
12
|
-
|
|
13
|
-
## Installation
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
npm install @expressots/studio-agent
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Quick Start
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
import { StudioAgent } from '@expressots/studio-agent';
|
|
23
|
-
|
|
24
|
-
const agent = new StudioAgent({
|
|
25
|
-
port: 3334,
|
|
26
|
-
serviceName: 'my-app',
|
|
27
|
-
enableRecording: true,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// Start the agent
|
|
31
|
-
await agent.start();
|
|
32
|
-
|
|
33
|
-
// Use the middleware (optional, for request recording)
|
|
34
|
-
app.use(agent.createMiddleware());
|
|
35
|
-
|
|
36
|
-
// Get discovered routes
|
|
37
|
-
const routes = agent.getRoutes();
|
|
38
|
-
|
|
39
|
-
// Stop when done
|
|
40
|
-
await agent.stop();
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## Configuration
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
interface AgentConfig {
|
|
47
|
-
/** Port for the agent WebSocket server (default: 3334) */
|
|
48
|
-
port: number;
|
|
49
|
-
|
|
50
|
-
/** Path to store SQLite database (default: '.studio/studio.db') */
|
|
51
|
-
dbPath: string;
|
|
52
|
-
|
|
53
|
-
/** Enable request/response recording (default: true) */
|
|
54
|
-
enableRecording: boolean;
|
|
55
|
-
|
|
56
|
-
/** Maximum number of recorded exchanges to keep (default: 1000) */
|
|
57
|
-
maxRecordedExchanges: number;
|
|
58
|
-
|
|
59
|
-
/** Enable performance profiling (default: true) */
|
|
60
|
-
enableProfiling: boolean;
|
|
61
|
-
|
|
62
|
-
/** Sample rate for tracing 0-1 (default: 1.0) */
|
|
63
|
-
traceSampleRate: number;
|
|
64
|
-
|
|
65
|
-
/** Custom service name (default: 'expressots-app') */
|
|
66
|
-
serviceName: string;
|
|
67
|
-
|
|
68
|
-
/** Express app instance for runtime route scanning */
|
|
69
|
-
expressApp?: any;
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Components
|
|
74
|
-
|
|
75
|
-
### StudioAgent
|
|
76
|
-
|
|
77
|
-
Main orchestrator that coordinates all functionality.
|
|
78
|
-
|
|
79
|
-
### RouteScanner
|
|
80
|
-
|
|
81
|
-
Scans TypeScript source files to discover routes and their metadata:
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
import { RouteScanner } from '@expressots/studio-agent';
|
|
85
|
-
|
|
86
|
-
const scanner = new RouteScanner('./src');
|
|
87
|
-
const structure = await scanner.scan();
|
|
88
|
-
|
|
89
|
-
console.log(structure.controllers);
|
|
90
|
-
console.log(structure.services);
|
|
91
|
-
console.log(structure.dependencies);
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### RequestRecorder
|
|
95
|
-
|
|
96
|
-
Records HTTP requests/responses for later replay:
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
import { RequestRecorder } from '@expressots/studio-agent';
|
|
100
|
-
|
|
101
|
-
const recorder = new RequestRecorder('.studio/studio.db');
|
|
102
|
-
await recorder.initialize();
|
|
103
|
-
|
|
104
|
-
// Get recent exchanges
|
|
105
|
-
const exchanges = recorder.getRecentExchanges(100);
|
|
106
|
-
|
|
107
|
-
// Search by path
|
|
108
|
-
const results = recorder.searchExchanges('/api/users', 'GET');
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### StudioTracer
|
|
112
|
-
|
|
113
|
-
OpenTelemetry tracer with custom span processing:
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
import { StudioTracer } from '@expressots/studio-agent';
|
|
117
|
-
|
|
118
|
-
const tracer = new StudioTracer('my-service');
|
|
119
|
-
await tracer.start((trace) => {
|
|
120
|
-
console.log('Trace completed:', trace.traceId);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Create custom spans
|
|
124
|
-
await tracer.createSpan('my-operation', async () => {
|
|
125
|
-
// Your code here
|
|
126
|
-
}, { attribute: 'value' });
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## WebSocket Events
|
|
130
|
-
|
|
131
|
-
The agent emits real-time events to connected clients:
|
|
132
|
-
|
|
133
|
-
| Event | Description |
|
|
134
|
-
|-------|-------------|
|
|
135
|
-
| `routes` | Discovered routes |
|
|
136
|
-
| `trace` | Completed trace |
|
|
137
|
-
| `request` | New request recorded |
|
|
138
|
-
| `metrics` | Updated metrics |
|
|
139
|
-
| `structure` | Application structure |
|
|
140
|
-
|
|
141
|
-
## License
|
|
142
|
-
|
|
143
|
-
MIT © ExpressoTS
|
|
1
|
+
# @expressots/studio-agent
|
|
2
|
+
|
|
3
|
+
Instrumentation agent for ExpressoTS Studio - provides route discovery, OpenTelemetry tracing, and request recording.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Route Discovery**: Automatically scans your ExpressoTS application to discover all routes, controllers, and services
|
|
8
|
+
- **OpenTelemetry Tracing**: Full distributed tracing with automatic instrumentation
|
|
9
|
+
- **Request Recording**: Record and replay HTTP requests for debugging
|
|
10
|
+
- **WebSocket Communication**: Real-time updates to Studio UI
|
|
11
|
+
- **Metrics Collection**: P50/P95/P99 latency, error rates, and more
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @expressots/studio-agent
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { StudioAgent } from '@expressots/studio-agent';
|
|
23
|
+
|
|
24
|
+
const agent = new StudioAgent({
|
|
25
|
+
port: 3334,
|
|
26
|
+
serviceName: 'my-app',
|
|
27
|
+
enableRecording: true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Start the agent
|
|
31
|
+
await agent.start();
|
|
32
|
+
|
|
33
|
+
// Use the middleware (optional, for request recording)
|
|
34
|
+
app.use(agent.createMiddleware());
|
|
35
|
+
|
|
36
|
+
// Get discovered routes
|
|
37
|
+
const routes = agent.getRoutes();
|
|
38
|
+
|
|
39
|
+
// Stop when done
|
|
40
|
+
await agent.stop();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface AgentConfig {
|
|
47
|
+
/** Port for the agent WebSocket server (default: 3334) */
|
|
48
|
+
port: number;
|
|
49
|
+
|
|
50
|
+
/** Path to store SQLite database (default: '.studio/studio.db') */
|
|
51
|
+
dbPath: string;
|
|
52
|
+
|
|
53
|
+
/** Enable request/response recording (default: true) */
|
|
54
|
+
enableRecording: boolean;
|
|
55
|
+
|
|
56
|
+
/** Maximum number of recorded exchanges to keep (default: 1000) */
|
|
57
|
+
maxRecordedExchanges: number;
|
|
58
|
+
|
|
59
|
+
/** Enable performance profiling (default: true) */
|
|
60
|
+
enableProfiling: boolean;
|
|
61
|
+
|
|
62
|
+
/** Sample rate for tracing 0-1 (default: 1.0) */
|
|
63
|
+
traceSampleRate: number;
|
|
64
|
+
|
|
65
|
+
/** Custom service name (default: 'expressots-app') */
|
|
66
|
+
serviceName: string;
|
|
67
|
+
|
|
68
|
+
/** Express app instance for runtime route scanning */
|
|
69
|
+
expressApp?: any;
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Components
|
|
74
|
+
|
|
75
|
+
### StudioAgent
|
|
76
|
+
|
|
77
|
+
Main orchestrator that coordinates all functionality.
|
|
78
|
+
|
|
79
|
+
### RouteScanner
|
|
80
|
+
|
|
81
|
+
Scans TypeScript source files to discover routes and their metadata:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { RouteScanner } from '@expressots/studio-agent';
|
|
85
|
+
|
|
86
|
+
const scanner = new RouteScanner('./src');
|
|
87
|
+
const structure = await scanner.scan();
|
|
88
|
+
|
|
89
|
+
console.log(structure.controllers);
|
|
90
|
+
console.log(structure.services);
|
|
91
|
+
console.log(structure.dependencies);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### RequestRecorder
|
|
95
|
+
|
|
96
|
+
Records HTTP requests/responses for later replay:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { RequestRecorder } from '@expressots/studio-agent';
|
|
100
|
+
|
|
101
|
+
const recorder = new RequestRecorder('.studio/studio.db');
|
|
102
|
+
await recorder.initialize();
|
|
103
|
+
|
|
104
|
+
// Get recent exchanges
|
|
105
|
+
const exchanges = recorder.getRecentExchanges(100);
|
|
106
|
+
|
|
107
|
+
// Search by path
|
|
108
|
+
const results = recorder.searchExchanges('/api/users', 'GET');
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### StudioTracer
|
|
112
|
+
|
|
113
|
+
OpenTelemetry tracer with custom span processing:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { StudioTracer } from '@expressots/studio-agent';
|
|
117
|
+
|
|
118
|
+
const tracer = new StudioTracer('my-service');
|
|
119
|
+
await tracer.start((trace) => {
|
|
120
|
+
console.log('Trace completed:', trace.traceId);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Create custom spans
|
|
124
|
+
await tracer.createSpan('my-operation', async () => {
|
|
125
|
+
// Your code here
|
|
126
|
+
}, { attribute: 'value' });
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## WebSocket Events
|
|
130
|
+
|
|
131
|
+
The agent emits real-time events to connected clients:
|
|
132
|
+
|
|
133
|
+
| Event | Description |
|
|
134
|
+
|-------|-------------|
|
|
135
|
+
| `routes` | Discovered routes |
|
|
136
|
+
| `trace` | Completed trace |
|
|
137
|
+
| `request` | New request recorded |
|
|
138
|
+
| `metrics` | Updated metrics |
|
|
139
|
+
| `structure` | Application structure |
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT © ExpressoTS
|
package/dist/agent.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare class StudioAgent {
|
|
|
17
17
|
private recorder;
|
|
18
18
|
private introspector;
|
|
19
19
|
private containerSnapshot;
|
|
20
|
+
private databaseIntrospector;
|
|
20
21
|
private logCapture;
|
|
21
22
|
private securityEngine;
|
|
22
23
|
private io;
|
|
@@ -28,9 +29,24 @@ export declare class StudioAgent {
|
|
|
28
29
|
private responseTimes;
|
|
29
30
|
private startTime;
|
|
30
31
|
private isRunning;
|
|
32
|
+
private srcWatcher;
|
|
33
|
+
private rescanTimer;
|
|
34
|
+
/**
|
|
35
|
+
* Periodic metrics-broadcast timer. Captured so `stop()` can clear it
|
|
36
|
+
* cleanly; `.unref()`'d so it never keeps the Node event loop alive in
|
|
37
|
+
* tests / serverless environments.
|
|
38
|
+
*/
|
|
39
|
+
private metricsTimer;
|
|
31
40
|
constructor(config?: Partial<AgentConfig>);
|
|
32
41
|
/** Start the Studio Agent */
|
|
33
42
|
start(): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Start a debounced filesystem watcher over `./src` (relative to the
|
|
45
|
+
* host's CWD) that triggers a route + structure rescan whenever a
|
|
46
|
+
* `*.ts` / `*.js` file changes. Uses `fs.watch({ recursive: true })`
|
|
47
|
+
* to avoid taking a chokidar dependency. Failures are non-fatal.
|
|
48
|
+
*/
|
|
49
|
+
private startSrcWatcher;
|
|
34
50
|
/**
|
|
35
51
|
* Stand up the SecurityEngine and kick off the first scan. The
|
|
36
52
|
* engine reuses the existing Socket.IO server — every transition in
|
|
@@ -40,6 +56,12 @@ export declare class StudioAgent {
|
|
|
40
56
|
private startSecurityEngine;
|
|
41
57
|
/** Get the captured container snapshot (or null if unavailable). */
|
|
42
58
|
getContainerSnapshot(): ContainerSnapshot | null;
|
|
59
|
+
/**
|
|
60
|
+
* Capture a fresh in-memory database snapshot. Returns an "unavailable"
|
|
61
|
+
* snapshot when no `InMemoryDBProvider` is registered or no container was
|
|
62
|
+
* provided to the agent.
|
|
63
|
+
*/
|
|
64
|
+
private captureDatabaseSnapshot;
|
|
43
65
|
/** Stop the Studio Agent */
|
|
44
66
|
stop(): Promise<void>;
|
|
45
67
|
/**
|
|
@@ -56,6 +78,25 @@ export declare class StudioAgent {
|
|
|
56
78
|
scanRoutes(): Promise<void>;
|
|
57
79
|
/** Get discovered routes */
|
|
58
80
|
getRoutes(): RouteInfo[];
|
|
81
|
+
/**
|
|
82
|
+
* Normalise the host-supplied global URL prefix into the form we
|
|
83
|
+
* actually want to splice into route paths.
|
|
84
|
+
*
|
|
85
|
+
* - Returns `''` for "no prefix" (so callers can fall through with a
|
|
86
|
+
* simple truthy check).
|
|
87
|
+
* - Strips trailing slashes (`/api/` → `/api`) so the join helper
|
|
88
|
+
* never produces `/api//foo`.
|
|
89
|
+
* - Defends against the host passing through a legitimate but
|
|
90
|
+
* no-op `'/'` prefix.
|
|
91
|
+
*/
|
|
92
|
+
private normaliseGlobalPrefix;
|
|
93
|
+
/**
|
|
94
|
+
* Splice a normalised global prefix onto a controller-relative route
|
|
95
|
+
* path while preserving the leading slash and avoiding doubled
|
|
96
|
+
* separators. `/api` + `/` → `/api/`, `/api` + `users` → `/api/users`,
|
|
97
|
+
* `/api` + `/users` → `/api/users`.
|
|
98
|
+
*/
|
|
99
|
+
private joinPrefixWithRoute;
|
|
59
100
|
/** Get application structure */
|
|
60
101
|
getAppStructure(): AppStructure | null;
|
|
61
102
|
/** Get current metrics */
|
|
@@ -79,7 +120,41 @@ export declare class StudioAgent {
|
|
|
79
120
|
providerCount?: number;
|
|
80
121
|
middlewareCount?: number;
|
|
81
122
|
runtimeItems?: import('./types/index.js').RuntimeItems;
|
|
123
|
+
middlewarePreset?: import('./types/index.js').MiddlewarePresetInfo;
|
|
82
124
|
}): void;
|
|
125
|
+
/**
|
|
126
|
+
* Recompute every route's `path` from its captured `originalPath` plus
|
|
127
|
+
* the current `config.globalPrefix`. Idempotent and prefix-change-safe
|
|
128
|
+
* — calling it twice with different prefixes never produces the
|
|
129
|
+
* `/api/api/health` doubling we'd see if we appended in place.
|
|
130
|
+
*
|
|
131
|
+
* Routes pushed by older code paths that don't carry an `originalPath`
|
|
132
|
+
* (defensive — hot-reload scans always set it now) are left alone, so
|
|
133
|
+
* we never silently strip a prefix the source of truth set
|
|
134
|
+
* intentionally.
|
|
135
|
+
*/
|
|
136
|
+
private applyGlobalPrefixToRoutes;
|
|
137
|
+
/**
|
|
138
|
+
* Merge global pipeline middleware and runtime middleware bindings
|
|
139
|
+
* into the static `appStructure` so the architecture map sees a
|
|
140
|
+
* single source of truth. Returns `true` when the structure changed.
|
|
141
|
+
*
|
|
142
|
+
* Rules:
|
|
143
|
+
* - Each `runtimeItems.middleware` entry whose `type === 'custom'`
|
|
144
|
+
* gets a `MiddlewareInfo` node with `scope: 'global'` (built-in
|
|
145
|
+
* pipeline entries like `helmet` / `jsonParser` aren't worth
|
|
146
|
+
* plotting — they would clutter every architecture map without
|
|
147
|
+
* adding signal). Names are deduplicated against the existing
|
|
148
|
+
* middleware list.
|
|
149
|
+
* - Each `runtimeItems.middlewareBindings` entry contributes a
|
|
150
|
+
* `middleware → controller` edge (deduplicated with the static
|
|
151
|
+
* bindings produced by `RouteScanner`). The middleware node's
|
|
152
|
+
* scope is upgraded to `controller` or `route`.
|
|
153
|
+
* - Global middleware also gets synthetic edges to every
|
|
154
|
+
* controller in the structure so the map shows the pipeline
|
|
155
|
+
* fanning out across the app.
|
|
156
|
+
*/
|
|
157
|
+
private mergeRuntimeMiddlewareIntoStructure;
|
|
83
158
|
/**
|
|
84
159
|
* Build a snapshot of runtime information for the Status dashboard.
|
|
85
160
|
*
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|