brakit 0.8.6 → 9.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/README.md +22 -4
- package/dist/api.d.ts +70 -48
- package/dist/api.js +773 -753
- package/dist/bin/brakit.js +316 -419
- package/dist/dashboard-client.global.js +826 -0
- package/dist/dashboard.html +1064 -2179
- package/dist/mcp/server.js +7 -15
- package/dist/runtime/index.js +2561 -5003
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<b>AI writes your code. Brakit watches what it does.</b> <br />
|
|
5
|
-
Every request, query, and
|
|
5
|
+
Every request, query, and API call mapped to the action that triggered it. See your entire backend at a glance. <br />
|
|
6
6
|
<b>Open source · Local first · Zero config · AI-native via MCP</b>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
@@ -32,6 +32,12 @@
|
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img width="700" src="docs/images/actions.png" alt="Brakit Actions — endpoints grouped by user action" />
|
|
37
|
+
<br />
|
|
38
|
+
<sub>Every endpoint grouped by the action that triggered it — see "Sign Up" and "Load Dashboard", not 47 raw requests</sub>
|
|
39
|
+
</p>
|
|
40
|
+
|
|
35
41
|
<p align="center">
|
|
36
42
|
<img width="700" src="docs/images/dashboard.png" alt="Brakit Dashboard — issues surfaced automatically" />
|
|
37
43
|
<br />
|
|
@@ -46,19 +52,31 @@
|
|
|
46
52
|
|
|
47
53
|
## Quick Start
|
|
48
54
|
|
|
55
|
+
### Node.js
|
|
56
|
+
|
|
49
57
|
```bash
|
|
50
58
|
npx brakit install
|
|
59
|
+
npm run dev
|
|
51
60
|
```
|
|
52
61
|
|
|
53
|
-
|
|
62
|
+
### Python (FastAPI / Flask)
|
|
54
63
|
|
|
55
64
|
```bash
|
|
56
|
-
|
|
65
|
+
pip install brakit
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
import brakit # must be before framework import
|
|
70
|
+
from fastapi import FastAPI
|
|
71
|
+
|
|
72
|
+
app = FastAPI()
|
|
57
73
|
```
|
|
58
74
|
|
|
59
75
|
Dashboard at `http://localhost:<port>/__brakit`. Issues in the terminal.
|
|
60
76
|
|
|
61
|
-
> **
|
|
77
|
+
> **Full setup guide:** [brakit.ai/docs/introduction](https://brakit.ai/docs/introduction)
|
|
78
|
+
|
|
79
|
+
> **Requirements:** Node.js >= 18. Python SDK requires Python >= 3.9.
|
|
62
80
|
|
|
63
81
|
---
|
|
64
82
|
|
package/dist/api.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ interface TracedRequest {
|
|
|
16
16
|
durationMs: number;
|
|
17
17
|
responseSize: number;
|
|
18
18
|
isStatic: boolean;
|
|
19
|
+
isHealthCheck: boolean;
|
|
19
20
|
}
|
|
20
21
|
type RequestListener = (req: TracedRequest) => void;
|
|
21
22
|
|
|
@@ -35,7 +36,7 @@ interface BrakitConfig {
|
|
|
35
36
|
customCommand?: string;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
type RequestCategory = "auth-handshake" | "auth-check" | "middleware" | "server-action" | "api-call" | "data-fetch" | "page-load" | "navigation" | "polling" | "static" | "unknown";
|
|
39
|
+
type RequestCategory = "auth-handshake" | "auth-check" | "health-check" | "middleware" | "server-action" | "api-call" | "data-fetch" | "page-load" | "navigation" | "polling" | "static" | "unknown";
|
|
39
40
|
interface LabeledRequest extends TracedRequest {
|
|
40
41
|
label: string;
|
|
41
42
|
category: RequestCategory;
|
|
@@ -63,6 +64,7 @@ interface TelemetryEntry {
|
|
|
63
64
|
timestamp: number;
|
|
64
65
|
}
|
|
65
66
|
interface TracedFetch extends TelemetryEntry {
|
|
67
|
+
fetchId?: string;
|
|
66
68
|
url: string;
|
|
67
69
|
method: string;
|
|
68
70
|
statusCode: number;
|
|
@@ -75,11 +77,11 @@ interface TracedLog extends TelemetryEntry {
|
|
|
75
77
|
interface TracedError extends TelemetryEntry {
|
|
76
78
|
name: string;
|
|
77
79
|
message: string;
|
|
78
|
-
stack
|
|
80
|
+
stack?: string;
|
|
79
81
|
}
|
|
80
82
|
type NormalizedOp = "SELECT" | "INSERT" | "UPDATE" | "DELETE" | "OTHER";
|
|
81
83
|
interface TracedQuery extends TelemetryEntry {
|
|
82
|
-
driver: "pg" | "mysql2" | "prisma" | "sdk";
|
|
84
|
+
driver: "pg" | "mysql2" | "prisma" | "asyncpg" | "sqlalchemy" | "sdk";
|
|
83
85
|
sql?: string;
|
|
84
86
|
model?: string;
|
|
85
87
|
operation?: string;
|
|
@@ -88,6 +90,7 @@ interface TracedQuery extends TelemetryEntry {
|
|
|
88
90
|
normalizedOp?: NormalizedOp;
|
|
89
91
|
table?: string;
|
|
90
92
|
source?: string;
|
|
93
|
+
parentFetchId?: string;
|
|
91
94
|
}
|
|
92
95
|
type TelemetryEvent = {
|
|
93
96
|
type: "fetch";
|
|
@@ -119,6 +122,10 @@ interface EndpointMetrics {
|
|
|
119
122
|
sessions: SessionMetric[];
|
|
120
123
|
dataPoints?: LiveRequestPoint[];
|
|
121
124
|
}
|
|
125
|
+
interface MetricsData {
|
|
126
|
+
version: 1;
|
|
127
|
+
endpoints: EndpointMetrics[];
|
|
128
|
+
}
|
|
122
129
|
interface LiveRequestPoint {
|
|
123
130
|
timestamp: number;
|
|
124
131
|
durationMs: number;
|
|
@@ -380,74 +387,89 @@ interface CaptureInput {
|
|
|
380
387
|
endTime?: number;
|
|
381
388
|
config: Pick<BrakitConfig, "maxBodyCapture">;
|
|
382
389
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
390
|
+
declare class RequestStore {
|
|
391
|
+
private maxEntries;
|
|
392
|
+
private requests;
|
|
393
|
+
private listeners;
|
|
394
|
+
constructor(maxEntries?: number);
|
|
395
|
+
capture(input: CaptureInput): TracedRequest;
|
|
396
|
+
add(entry: TracedRequest): void;
|
|
397
|
+
getAll(): readonly TracedRequest[];
|
|
398
|
+
clear(): void;
|
|
399
|
+
onRequest(fn: RequestListener): void;
|
|
400
|
+
offRequest(fn: RequestListener): void;
|
|
387
401
|
}
|
|
388
|
-
|
|
402
|
+
|
|
403
|
+
type TelemetryListener<T> = (entry: T) => void;
|
|
404
|
+
/** Read-only view of a TelemetryStore — used by API handlers that only query data. */
|
|
405
|
+
interface ReadonlyTelemetryStore {
|
|
406
|
+
getAll(): readonly TelemetryEntry[];
|
|
407
|
+
getByRequest(requestId: string): TelemetryEntry[];
|
|
408
|
+
}
|
|
409
|
+
declare class TelemetryStore<T extends TelemetryEntry> implements ReadonlyTelemetryStore {
|
|
410
|
+
private maxEntries;
|
|
411
|
+
private entries;
|
|
412
|
+
private listeners;
|
|
413
|
+
constructor(maxEntries?: number);
|
|
389
414
|
add(data: Omit<T, "id">): T;
|
|
390
415
|
getAll(): readonly T[];
|
|
391
416
|
getByRequest(requestId: string): T[];
|
|
392
417
|
clear(): void;
|
|
418
|
+
onEntry(fn: TelemetryListener<T>): void;
|
|
419
|
+
offEntry(fn: TelemetryListener<T>): void;
|
|
393
420
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
421
|
+
|
|
422
|
+
interface MetricsPersistence {
|
|
423
|
+
load(): MetricsData;
|
|
424
|
+
loadAsync(): Promise<MetricsData>;
|
|
425
|
+
save(data: MetricsData): void;
|
|
426
|
+
saveSync(data: MetricsData): void;
|
|
427
|
+
remove(): void;
|
|
399
428
|
}
|
|
400
|
-
|
|
429
|
+
|
|
430
|
+
declare class MetricsStore {
|
|
431
|
+
private persistence;
|
|
432
|
+
private data;
|
|
433
|
+
private endpointIndex;
|
|
434
|
+
private sessionId;
|
|
435
|
+
private sessionStart;
|
|
436
|
+
private flushTimer;
|
|
437
|
+
private dirty;
|
|
438
|
+
private accumulators;
|
|
439
|
+
private pendingPoints;
|
|
440
|
+
constructor(persistence: MetricsPersistence);
|
|
441
|
+
start(): void;
|
|
442
|
+
stop(): void;
|
|
401
443
|
recordRequest(req: TracedRequest, metrics: RequestMetrics): void;
|
|
402
444
|
getAll(): readonly EndpointMetrics[];
|
|
403
445
|
getEndpoint(endpoint: string): EndpointMetrics | undefined;
|
|
404
446
|
getLiveEndpoints(): LiveEndpointData[];
|
|
405
447
|
reset(): void;
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
upsert(issue: Issue, source: IssueSource): StatefulIssue;
|
|
409
|
-
transition(issueId: string, state: IssueState): boolean;
|
|
410
|
-
reportFix(issueId: string, status: AiFixStatus, notes: string): boolean;
|
|
411
|
-
reconcile(currentIssueIds: Set<string>, activeEndpoints: Set<string>): void;
|
|
412
|
-
getAll(): readonly StatefulIssue[];
|
|
413
|
-
getByState(state: IssueState): readonly StatefulIssue[];
|
|
414
|
-
getByCategory(category: IssueCategory): readonly StatefulIssue[];
|
|
415
|
-
get(issueId: string): StatefulIssue | undefined;
|
|
416
|
-
clear(): void;
|
|
417
|
-
}
|
|
418
|
-
interface AnalysisEngineInterface extends Lifecycle {
|
|
419
|
-
recompute(): void;
|
|
420
|
-
getInsights(): readonly Insight[];
|
|
421
|
-
getFindings(): readonly SecurityFinding[];
|
|
448
|
+
flush(sync?: boolean): void;
|
|
449
|
+
private getOrCreateEndpoint;
|
|
422
450
|
}
|
|
423
451
|
|
|
424
|
-
interface
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
declare class ServiceRegistry {
|
|
436
|
-
private services;
|
|
437
|
-
register<K extends keyof ServiceMap>(name: K, service: ServiceMap[K]): void;
|
|
438
|
-
get<K extends keyof ServiceMap>(name: K): ServiceMap[K];
|
|
439
|
-
has<K extends keyof ServiceMap>(name: K): boolean;
|
|
452
|
+
interface Services {
|
|
453
|
+
bus: EventBus;
|
|
454
|
+
requestStore: RequestStore;
|
|
455
|
+
queryStore: TelemetryStore<TracedQuery>;
|
|
456
|
+
fetchStore: TelemetryStore<TracedFetch>;
|
|
457
|
+
logStore: TelemetryStore<TracedLog>;
|
|
458
|
+
errorStore: TelemetryStore<TracedError>;
|
|
459
|
+
metricsStore: MetricsStore;
|
|
460
|
+
issueStore: IssueStore;
|
|
461
|
+
analysisEngine: AnalysisEngine;
|
|
440
462
|
}
|
|
441
463
|
|
|
442
464
|
declare class AnalysisEngine {
|
|
443
|
-
private
|
|
465
|
+
private services;
|
|
444
466
|
private debounceMs;
|
|
445
467
|
private scanner;
|
|
446
468
|
private cachedInsights;
|
|
447
469
|
private cachedFindings;
|
|
448
470
|
private debounceTimer;
|
|
449
471
|
private subs;
|
|
450
|
-
constructor(
|
|
472
|
+
constructor(services: Services, debounceMs?: number);
|
|
451
473
|
start(): void;
|
|
452
474
|
stop(): void;
|
|
453
475
|
getInsights(): readonly Insight[];
|