proteum 2.1.2 → 2.1.6

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.
Files changed (99) hide show
  1. package/AGENTS.md +22 -14
  2. package/README.md +112 -17
  3. package/agents/project/AGENTS.md +188 -25
  4. package/agents/project/CODING_STYLE.md +1 -0
  5. package/agents/project/client/AGENTS.md +13 -8
  6. package/agents/project/client/pages/AGENTS.md +17 -9
  7. package/agents/project/diagnostics.md +52 -0
  8. package/agents/project/optimizations.md +48 -0
  9. package/agents/project/server/routes/AGENTS.md +9 -6
  10. package/agents/project/server/services/AGENTS.md +10 -6
  11. package/agents/project/tests/AGENTS.md +11 -5
  12. package/cli/app/config.ts +13 -14
  13. package/cli/app/index.ts +58 -0
  14. package/cli/commands/command.ts +8 -0
  15. package/cli/commands/connect.ts +45 -0
  16. package/cli/commands/dev.ts +26 -11
  17. package/cli/commands/diagnose.ts +286 -0
  18. package/cli/commands/doctor.ts +18 -5
  19. package/cli/commands/explain.ts +25 -0
  20. package/cli/commands/perf.ts +243 -0
  21. package/cli/commands/session.ts +254 -0
  22. package/cli/commands/sessionLocalRunner.js +188 -0
  23. package/cli/commands/trace.ts +17 -1
  24. package/cli/commands/verify.ts +281 -0
  25. package/cli/compiler/artifacts/connectedProjects.ts +453 -0
  26. package/cli/compiler/artifacts/controllers.ts +198 -49
  27. package/cli/compiler/artifacts/discovery.ts +0 -34
  28. package/cli/compiler/artifacts/manifest.ts +90 -6
  29. package/cli/compiler/artifacts/routing.ts +2 -2
  30. package/cli/compiler/artifacts/services.ts +277 -130
  31. package/cli/compiler/client/index.ts +3 -0
  32. package/cli/compiler/common/files/style.ts +52 -0
  33. package/cli/compiler/common/generatedRouteModules.ts +34 -5
  34. package/cli/compiler/common/scripts.ts +11 -5
  35. package/cli/compiler/index.ts +2 -1
  36. package/cli/compiler/server/index.ts +3 -0
  37. package/cli/presentation/commands.ts +136 -7
  38. package/cli/presentation/devSession.ts +32 -7
  39. package/cli/runtime/commands.ts +193 -6
  40. package/cli/scaffold/index.ts +14 -25
  41. package/cli/scaffold/templates.ts +41 -27
  42. package/cli/utils/agents.ts +4 -2
  43. package/cli/utils/keyboard.ts +8 -0
  44. package/client/dev/profiler/ApexChart.tsx +66 -0
  45. package/client/dev/profiler/index.tsx +2798 -417
  46. package/client/dev/profiler/runtime.noop.ts +12 -0
  47. package/client/dev/profiler/runtime.ts +195 -4
  48. package/client/services/router/request/api.ts +6 -1
  49. package/common/applicationConfig.ts +173 -0
  50. package/common/applicationConfigLoader.ts +102 -0
  51. package/common/connectedProjects.ts +113 -0
  52. package/common/dev/connect.ts +267 -0
  53. package/common/dev/console.ts +31 -0
  54. package/common/dev/contractsDoctor.ts +128 -0
  55. package/common/dev/diagnostics.ts +59 -15
  56. package/common/dev/inspection.ts +491 -0
  57. package/common/dev/performance.ts +809 -0
  58. package/common/dev/profiler.ts +3 -0
  59. package/common/dev/proteumManifest.ts +31 -6
  60. package/common/dev/requestTrace.ts +56 -1
  61. package/common/dev/session.ts +24 -0
  62. package/common/env/proteumEnv.ts +176 -50
  63. package/common/router/index.ts +1 -0
  64. package/common/router/request/api.ts +2 -0
  65. package/config.ts +5 -0
  66. package/docs/dev-commands.md +5 -1
  67. package/docs/dev-sessions.md +90 -0
  68. package/docs/diagnostics.md +74 -11
  69. package/docs/request-tracing.md +50 -3
  70. package/package.json +1 -1
  71. package/server/app/container/config.ts +16 -87
  72. package/server/app/container/console/index.ts +42 -8
  73. package/server/app/container/index.ts +3 -1
  74. package/server/app/container/trace/index.ts +153 -0
  75. package/server/app/devDiagnostics.ts +138 -0
  76. package/server/app/index.ts +18 -8
  77. package/server/app/service/container.ts +0 -12
  78. package/server/app/service/index.ts +0 -2
  79. package/server/services/prisma/index.ts +121 -4
  80. package/server/services/router/http/index.ts +352 -0
  81. package/server/services/router/index.ts +50 -47
  82. package/server/services/router/request/api.ts +160 -19
  83. package/server/services/router/request/index.ts +8 -0
  84. package/server/services/router/response/index.ts +24 -1
  85. package/server/services/router/response/page/document.tsx +5 -0
  86. package/server/services/router/response/page/index.tsx +10 -0
  87. package/agents/framework/AGENTS.md +0 -177
  88. package/server/services/auth/router/service.json +0 -6
  89. package/server/services/auth/service.json +0 -6
  90. package/server/services/cron/service.json +0 -6
  91. package/server/services/disks/drivers/local/service.json +0 -6
  92. package/server/services/disks/drivers/s3/service.json +0 -6
  93. package/server/services/disks/service.json +0 -6
  94. package/server/services/fetch/service.json +0 -7
  95. package/server/services/prisma/service.json +0 -6
  96. package/server/services/router/service.json +0 -6
  97. package/server/services/schema/router/service.json +0 -6
  98. package/server/services/schema/service.json +0 -6
  99. package/server/services/security/encrypt/aes/service.json +0 -6
@@ -67,13 +67,17 @@ In `proteum dev`, the bottom profiler exposes a `Commands` tab.
67
67
  - it shows the backing class, method, scope, and source location
68
68
  - clicking `Run now` executes the command through the running dev server
69
69
  - the last result or error stays attached to that command row in the panel
70
+ - it now adds scope, execution-duration, and status charts over the same command definitions and latest execution snapshots
70
71
 
71
72
  The profiler also exposes the shared diagnostics surfaces for humans:
72
73
 
73
74
  - `Explain` renders the same manifest-backed data as `proteum explain`
74
75
  - `Doctor` renders the same manifest diagnostics as `proteum doctor`
76
+ - `Diagnose` renders the same owner, suspect, contract, trace-summary, and buffered-log view as `proteum diagnose`
77
+ - `Perf` renders the same hot-path, request-waterfall, compare, and memory views as `proteum perf`
78
+ - the other profiler tabs now add focused visual charts over the same trace, manifest, and dev-runtime contracts instead of only row lists
75
79
 
76
- For the shared diagnostics contract and the corresponding dev HTTP endpoints, see [diagnostics.md](diagnostics.md).
80
+ For the shared diagnostics contract, trace-derived perf contract, and the corresponding dev HTTP endpoints, see [diagnostics.md](diagnostics.md) and [request-tracing.md](request-tracing.md).
77
81
 
78
82
  ### HTTP Endpoints
79
83
 
@@ -0,0 +1,90 @@
1
+ # Dev Sessions
2
+
3
+ Proteum ships a dev-only auth bootstrap command so agents, Playwright runs, and local debugging can start from an authenticated state without driving the login UI.
4
+
5
+ ## When To Use It
6
+
7
+ Use `proteum session` when:
8
+
9
+ - a protected page, controller, or manual route must be exercised in dev
10
+ - an LLM agent or browser automation needs an authenticated cookie quickly
11
+ - you want to reproduce role-gated behavior with a known user account
12
+
13
+ Do not use it when:
14
+
15
+ - the login or signup flow itself is under test
16
+ - you are validating third-party auth redirects or callback handling
17
+ - you do not know which user should be used for the scenario
18
+
19
+ ## CLI
20
+
21
+ Local mode:
22
+
23
+ ```bash
24
+ proteum session admin@example.com --role ADMIN
25
+ ```
26
+
27
+ Remote mode against an existing dev server:
28
+
29
+ ```bash
30
+ proteum session admin@example.com --role ADMIN --port 3101
31
+ proteum session god@example.com --role GOD --url http://localhost:3102 --json
32
+ ```
33
+
34
+ Behavior:
35
+
36
+ - local mode refreshes generated artifacts, builds the dev output, starts a temporary local dev server, creates the session, prints the payload, and exits
37
+ - remote mode talks to an already running `proteum dev` instance
38
+ - the command requires an explicit email and optionally asserts a role before returning the session
39
+ - the command is available only in dev mode
40
+
41
+ ## Output Contract
42
+
43
+ The JSON payload includes:
44
+
45
+ - `baseUrl`
46
+ - `user`
47
+ - `session.token`
48
+ - `session.cookieName`
49
+ - `session.issuedAt`
50
+ - `session.expiresAt`
51
+ - `browserCookie`
52
+ - `curlCookieHeader`
53
+ - `playwright.cookies`
54
+
55
+ Playwright usage:
56
+
57
+ ```ts
58
+ await browserContext.addCookies(output.playwright.cookies);
59
+ ```
60
+
61
+ HTTP usage:
62
+
63
+ ```bash
64
+ curl -H "$(jq -r '.curlCookieHeader' session.json)" http://localhost:3101/api/Auth/CurrentUser
65
+ ```
66
+
67
+ ## Agent Guidance
68
+
69
+ - Prefer `proteum session` over UI login automation when the goal is to test or debug protected application behavior.
70
+ - Use UI login automation only when the auth UX itself is the feature under test.
71
+ - Pair it with `proteum diagnose` for a fast protected-route summary, `proteum perf request` for a one-request timing breakdown, then use `proteum trace` when you need lower-level request events.
72
+
73
+ Typical flow:
74
+
75
+ ```bash
76
+ proteum trace arm --capture deep --port 3101
77
+ proteum session admin@example.com --role ADMIN --port 3101 --json > session.json
78
+ # add the returned cookie in Playwright, then load the protected page once
79
+ proteum diagnose /dashboard --port 3101
80
+ proteum perf request /dashboard --port 3101
81
+ proteum trace latest --port 3101
82
+ ```
83
+
84
+ ## Dev HTTP Endpoint
85
+
86
+ The CLI uses the same dev-only endpoint exposed by the running app:
87
+
88
+ - `POST /__proteum/session/start`
89
+
90
+ This endpoint exists only in dev mode and is not available in production.
@@ -1,26 +1,31 @@
1
1
  # Diagnostics and Explainability
2
2
 
3
- Proteum exposes two manifest-backed diagnostics surfaces:
3
+ Proteum exposes two manifest-backed diagnostics surfaces plus one composite request-diagnosis surface:
4
4
 
5
5
  - `proteum explain`: inspect the generated app structure
6
6
  - `proteum doctor`: inspect manifest diagnostics
7
+ - `proteum diagnose`: combine owner lookup, diagnostics, matching request traces, and buffered server logs for one concrete query or path
7
8
 
8
- These are not separate models for different tools. They share the same generated snapshot and the same diagnostics contract.
9
+ These are not separate models for different tools. `explain` and `doctor` share the same generated manifest snapshot, while `diagnose` layers live dev-only request data on top of that same framework view.
10
+
11
+ Performance inspection is a sibling surface, not a separate instrumentation stack: `proteum perf` and the profiler `Perf` tab aggregate the same dev-only request traces that back `proteum trace`.
9
12
 
10
13
  ## Shared Contract
11
14
 
12
15
  The canonical snapshot lives in `./.proteum/manifest.json`.
13
16
 
14
- Proteum uses that same manifest in four places:
17
+ Proteum uses that same manifest in six places:
15
18
 
16
19
  - `proteum explain` for human-readable and `--json` output
17
20
  - `proteum doctor` for human-readable and `--json` output
18
- - the dev-only `__proteum/explain` and `__proteum/doctor` HTTP endpoints
19
- - the `Explain` and `Doctor` tabs in the bottom profiler during `proteum dev`
21
+ - `proteum explain owner <query>` for ownership lookup over the manifest index
22
+ - `proteum doctor --contracts` for generated-artifact and manifest-owned source validation on disk
23
+ - the dev-only `__proteum/explain*` and `__proteum/doctor*` HTTP endpoints
24
+ - the `Explain`, `Doctor`, and `Diagnose` tabs in the bottom profiler during `proteum dev`
20
25
 
21
- This means the CLI, the dev HTTP endpoints, and the profiler all describe the same manifest-backed snapshot.
26
+ This means the CLI, the dev HTTP endpoints, and the profiler all describe the same framework-owned snapshot before any live trace or log overlays are added.
22
27
 
23
- If a command such as `proteum explain`, `proteum doctor`, or `proteum refresh` regenerates `.proteum/manifest.json`, the next CLI call, HTTP call, or profiler refresh will reflect that same updated snapshot.
28
+ If a command such as `proteum explain`, `proteum doctor`, `proteum diagnose`, or `proteum refresh` regenerates `.proteum/manifest.json`, the next CLI call, HTTP call, or profiler refresh will reflect that same updated snapshot.
24
29
 
25
30
  ## CLI
26
31
 
@@ -28,12 +33,23 @@ Common usage:
28
33
 
29
34
  ```bash
30
35
  proteum explain
36
+ proteum explain owner /api/Auth/CurrentUser
31
37
  proteum explain --routes --controllers --commands
32
38
  proteum explain --all --json
33
39
 
34
40
  proteum doctor
41
+ proteum doctor --contracts
35
42
  proteum doctor --json
36
43
  proteum doctor --strict
44
+
45
+ proteum diagnose /
46
+ proteum diagnose /dashboard --port 3101
47
+ proteum diagnose /api/Auth/CurrentUser --url http://127.0.0.1:3101
48
+
49
+ proteum perf top --since today
50
+ proteum perf request /dashboard --port 3101
51
+ proteum perf compare --baseline yesterday --target today --group-by route
52
+ proteum perf memory --since 1h --group-by controller
37
53
  ```
38
54
 
39
55
  `proteum explain --json` emits the selected manifest sections as machine-readable JSON.
@@ -45,12 +61,37 @@ proteum doctor --strict
45
61
  - `summary.strictFailed`
46
62
  - `diagnostics`
47
63
 
64
+ `proteum diagnose` emits a composite response with:
65
+
66
+ - `owner`
67
+ - `doctor`
68
+ - `contracts`
69
+ - `request`
70
+ - `attribution`
71
+ - `suspects`
72
+ - `serverLogs`
73
+
74
+ `proteum perf` emits trace-derived performance views:
75
+
76
+ - `top`: grouped hot paths with avg, p95, CPU, SQL, render, and heap deltas
77
+ - `request`: one traced request waterfall with stage timings, CPU, SQL, render, self time, and payload sizes
78
+ - `compare`: grouped baseline vs target deltas
79
+ - `memory`: grouped heap and RSS drift summaries
80
+
48
81
  ## Dev HTTP Endpoints
49
82
 
50
83
  In `profile: dev`, the running app exposes:
51
84
 
52
85
  - `GET /__proteum/explain`
86
+ - `GET /__proteum/explain/owner`
53
87
  - `GET /__proteum/doctor`
88
+ - `GET /__proteum/doctor/contracts`
89
+ - `GET /__proteum/logs`
90
+ - `GET /__proteum/diagnose`
91
+ - `GET /__proteum/perf/top`
92
+ - `GET /__proteum/perf/compare`
93
+ - `GET /__proteum/perf/memory`
94
+ - `GET /__proteum/perf/request`
54
95
 
55
96
  `/__proteum/explain` supports optional section selection:
56
97
 
@@ -59,12 +100,28 @@ GET /__proteum/explain?sections=routes,controllers,commands
59
100
  GET /__proteum/explain?section=env&section=diagnostics
60
101
  ```
61
102
 
103
+ `/__proteum/explain/owner` supports a single query:
104
+
105
+ ```text
106
+ GET /__proteum/explain/owner?query=/api/Auth/CurrentUser
107
+ ```
108
+
62
109
  `/__proteum/doctor` supports optional strict mode:
63
110
 
64
111
  ```text
65
112
  GET /__proteum/doctor?strict=true
66
113
  ```
67
114
 
115
+ `/__proteum/doctor/contracts` supports the same optional strict mode.
116
+
117
+ `/__proteum/diagnose` supports a concrete query or request target:
118
+
119
+ ```text
120
+ GET /__proteum/diagnose?query=/dashboard&path=/dashboard
121
+ GET /__proteum/diagnose?requestId=<requestId>
122
+ GET /__proteum/diagnose?query=/api/Auth/CurrentUser&logsLevel=warn&logsLimit=40
123
+ ```
124
+
68
125
  These endpoints are intended for local tooling and are not available in production.
69
126
 
70
127
  ## Profiler
@@ -73,8 +130,11 @@ During `proteum dev`, the bottom profiler is the human-facing UI over the same d
73
130
 
74
131
  - `Explain` calls `/__proteum/explain`
75
132
  - `Doctor` calls `/__proteum/doctor`
133
+ - `Diagnose` calls `/__proteum/diagnose` and renders the same owner, diagnostics, suspect, and log summary that the CLI uses
134
+ - `Perf` calls the `/__proteum/perf/*` endpoints and renders the same grouped rollups and current-request waterfall that `proteum perf` uses, plus visual charts for hot paths, time breakdowns, regression deltas, and memory drift
76
135
  - `Commands` uses the dev command endpoints
77
- - `Auth`, `Timeline`, `Routing`, `Controller`, `SSR`, `API`, and related panels remain request-trace views
136
+ - `Summary`, `Auth`, `Routing`, `Controller`, `SSR`, `API`, `SQL`, `Errors`, `Diagnose`, `Explain`, `Doctor`, `Commands`, and `Cron` now layer focused charts over the same trace and diagnostics contracts instead of only showing rows
137
+ - `Timeline` remains the primary waterfall and event-stream inspection surface
78
138
 
79
139
  Use the profiler when a human needs to browse the same data that an agent or CLI command can already inspect directly.
80
140
 
@@ -83,6 +143,9 @@ Use the profiler when a human needs to browse the same data that an agent or CLI
83
143
  For AI coding agents or automation:
84
144
 
85
145
  1. Read `./.proteum/manifest.json` or run `proteum explain --json`.
86
- 2. Run `proteum doctor --json` to inspect framework diagnostics.
87
- 3. For request-time behavior, use `proteum trace ...` because traces are live runtime data, not manifest snapshots.
88
- 4. Open the profiler only when a human-readable view helps; it should agree with the CLI after refresh.
146
+ 2. Run `proteum doctor --json` and `proteum doctor --contracts --json` to inspect framework and generated-artifact diagnostics.
147
+ 3. Run `proteum explain owner <query>` when you need to map a route, controller path, or generated artifact back to source.
148
+ 4. For concrete request-time behavior, start with `proteum diagnose <path> --port <port>`.
149
+ 5. For performance, CPU, SQL, render, or memory questions, use `proteum perf top|request|compare|memory` against the same running dev server.
150
+ 6. Use `proteum trace ...` when you need lower-level event detail than `diagnose` or `perf` provides.
151
+ 7. Open the profiler only when a human-readable view helps; it should agree with the CLI after refresh.
@@ -1,12 +1,12 @@
1
1
  # Request Tracing
2
2
 
3
- Proteum ships with a dev-only in-memory request trace buffer so routing, controller execution, SSR, and render behavior can be inspected without attaching a debugger or scattering temporary logs through the runtime.
3
+ Proteum ships with a dev-only in-memory request trace buffer so routing, controller execution, SSR, API, Prisma SQL, render behavior, and request-time performance can be inspected without attaching a debugger or scattering temporary logs through the runtime.
4
4
 
5
5
  ## Scope
6
6
 
7
7
  - tracing is available only when the app runs with `profile: dev`
8
- - traces are exposed through `proteum trace` and the dev-only `__proteum/trace` HTTP endpoints
9
- - explain/doctor are separate manifest-backed diagnostics surfaces; see [diagnostics.md](diagnostics.md)
8
+ - traces are exposed through `proteum trace`, `proteum perf`, and the dev-only `__proteum/trace` and `__proteum/perf` HTTP endpoints
9
+ - `proteum diagnose` is a separate composite surface that reads the same framework diagnostics plus one matching request trace and buffered server logs; see [diagnostics.md](diagnostics.md)
10
10
  - production requests are not traced by this feature
11
11
 
12
12
  ## Main Commands
@@ -18,6 +18,11 @@ proteum trace show <requestId>
18
18
  proteum trace arm --capture deep
19
19
  proteum trace export <requestId>
20
20
  proteum trace latest --url http://127.0.0.1:3010
21
+
22
+ proteum perf top --since today
23
+ proteum perf request /dashboard --port 3103
24
+ proteum perf compare --baseline yesterday --target today --group-by route
25
+ proteum perf memory --since 1h --group-by controller
21
26
  ```
22
27
 
23
28
  Before reproducing a bug or starting a new test pass:
@@ -37,6 +42,19 @@ proteum trace show <requestId> --port 3103
37
42
 
38
43
  Use `--url http://host:port` when the dev server is reachable on a non-standard host and `--port` is not enough.
39
44
 
45
+ If the request under test is protected and login UX is not the feature under test, mint an auth cookie with `proteum session <email> --role <role>` before reproducing the request. This keeps the trace focused on the protected behavior instead of the login flow.
46
+
47
+ If you already know the failing path and want a one-shot suspect list before reading raw events, start with `proteum diagnose <path> --port <port>` and drop into `proteum trace show <requestId>` only when the lower-level event stream is still needed.
48
+
49
+ Trace summaries include `sql=<count>`. Detailed trace output includes both a `Calls` section for API/fetcher activity and a `SQL` section for captured Prisma queries.
50
+
51
+ `proteum perf` is a grouped view over the same trace store:
52
+
53
+ - `top` ranks routes, concrete paths, or controllers by avg, p95, CPU, SQL, render, self time, and heap delta
54
+ - `request` shows one traced request waterfall with stage timings plus the hottest calls and SQL
55
+ - `compare` shows baseline-vs-target regressions between trace windows such as `yesterday` and `today`
56
+ - `memory` shows grouped heap and RSS drift trends
57
+
40
58
  ## What Gets Recorded
41
59
 
42
60
  Depending on capture mode, traces can include:
@@ -46,12 +64,29 @@ Depending on capture mode, traces can include:
46
64
  - direct controller route matches
47
65
  - route resolution start, match, and deep-mode skip reasons
48
66
  - controller start and result shape
67
+ - synchronous SSR fetcher calls, API batch fetchers, and async request traces
68
+ - Prisma SQL queries with caller method/path, optional fetcher attribution, SQL text, params, kind, operation, and timing
49
69
  - created router/context keys
50
70
  - setup output keys and page data summaries
51
71
  - SSR payload shape and serialized byte size
52
72
  - render start/end timings and document output sizes
73
+ - per-request CPU usage deltas plus heap and RSS snapshots before and after the request
53
74
  - normalized request errors
54
75
 
76
+ ## SQL Tracing
77
+
78
+ Prisma query tracing covers both ORM operations and raw queries.
79
+
80
+ - `kind` is recorded as `orm` or `raw`
81
+ - `operation` records the Prisma operation such as `findFirst`, `count`, or `$queryRawUnsafe`
82
+ - `model` is recorded when Prisma exposes one
83
+ - `callerMethod` and `callerPath` attach the query to the request that triggered it
84
+ - when the query runs inside an SSR fetcher or an API batch fetcher, the trace also records the fetcher id/label and call id
85
+ - `durationMs`, `startedAt`, and `finishedAt` come from Prisma query events
86
+ - `query`, `paramsText`, and parsed `paramsJson` are stored for inspection
87
+
88
+ This currently covers SQL issued through Proteum's Prisma service, including raw helpers that flow through the same Prisma client.
89
+
55
90
  ## Capture Modes
56
91
 
57
92
  - `summary`: smallest capture, focused on request lifecycle and high-signal events
@@ -64,8 +99,16 @@ Use `deep` selectively. It is for one-off investigation, not continuous capture.
64
99
 
65
100
  During `proteum dev`, the bottom profiler renders the same live request traces.
66
101
 
102
+ - `Summary` charts recent duration, workload, route frequency, and status trends for the captured sessions
67
103
  - `Timeline` shows the full request event stream
68
104
  - `Auth` filters the selected session down to auth-specific events so matched rules, tracking, and allow/deny outcomes can be inspected without scanning unrelated events
105
+ - `Routing`, `Controller`, and `SSR` add focused charts over resolve, controller lifecycle, render, and payload data for the selected trace
106
+ - `API` shows synchronous SSR/API fetcher calls plus async requests, with workload and status charts above the waterfall
107
+ - `SQL` shows captured Prisma queries grouped by caller, with workload, operation, and heatmap charts plus a waterfall and detail sidebar
108
+ - `Errors` adds grouped source and error-family charts over the captured failures
109
+ - `Diagnose` combines the selected request summary with explain/doctor/contracts data and buffered server logs, plus visual suspect, owner, and severity charts
110
+ - `Explain`, `Doctor`, `Commands`, and `Cron` render the same manifest and dev-runtime contracts as their CLI surfaces with matching summary charts
111
+ - `Perf` renders the same top, request, compare, and memory rollups exposed by `proteum perf`, with visual charts for hot-path latency, time composition, regressions, and memory drift
69
112
  - expanding an auth event shows the summarized detail payload exactly as stored in the trace
70
113
 
71
114
  ## Configuration
@@ -128,5 +171,9 @@ These endpoints back the CLI:
128
171
  - `GET /__proteum/trace/latest`
129
172
  - `GET /__proteum/trace/requests/:id`
130
173
  - `POST /__proteum/trace/arm`
174
+ - `GET /__proteum/perf/top`
175
+ - `GET /__proteum/perf/compare`
176
+ - `GET /__proteum/perf/memory`
177
+ - `GET /__proteum/perf/request`
131
178
 
132
179
  The CLI should be the primary interface. Use the HTTP endpoints when you need direct machine access from another local dev tool.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "proteum",
3
3
  "description": "LLM-first Opinionated Typescript Framework for web applications.",
4
- "version": "2.1.2",
4
+ "version": "2.1.6",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/proteum.git",
7
7
  "license": "MIT",
@@ -7,11 +7,9 @@
7
7
  Because it's imported by the CLI, which should be independant of the app escept for loading config
8
8
  */
9
9
 
10
- // Npm
11
- import fs from 'fs-extra';
12
- import yaml from 'yaml';
13
-
14
10
  // Types
11
+ import type { TApplicationIdentityConfig, TApplicationSetupConfig } from '../../../common/applicationConfig';
12
+ import { loadApplicationIdentityConfig, loadApplicationSetupConfig } from '../../../common/applicationConfigLoader';
15
13
  import { parseProteumEnvConfig, type TProteumLoadedEnvConfig } from '../../../common/env/proteumEnv';
16
14
 
17
15
  declare const PROTEUM_PORT_OVERRIDE: number | null;
@@ -27,6 +25,7 @@ declare global {
27
25
 
28
26
  type Env = TEnvConfig;
29
27
  type Identity = AppIdentityConfig;
28
+ type Setup = AppSetupConfig;
30
29
  interface Services {}
31
30
  }
32
31
  }
@@ -34,31 +33,10 @@ declare global {
34
33
  export type TEnvName = TEnvConfig['name'];
35
34
  export type TEnvConfig = TProteumLoadedEnvConfig;
36
35
 
37
- type AppIdentityConfig = {
38
- name: string;
39
- identifier: string;
40
- description: string;
41
- author: { name: string; url: string; email: string };
42
-
43
- social: {};
44
-
45
- locale: string;
46
- language: string;
47
- maincolor: string;
48
- iconsPack?: string;
49
-
50
- web: {
51
- title: string;
52
- titleSuffix: string;
53
- fullTitle: string;
54
- description: string;
55
- version: string;
56
- metas?: { [name: string]: string };
57
- jsonld?: { [name: string]: string };
58
- };
59
- };
36
+ type AppIdentityConfig = TApplicationIdentityConfig;
37
+ type AppSetupConfig = TApplicationSetupConfig;
60
38
 
61
- export type AppConfig = { env: Config.Env; identity: Config.Identity };
39
+ export type AppConfig = { env: Config.Env; identity: Config.Identity; setup: Config.Setup };
62
40
 
63
41
  const debug = false;
64
42
 
@@ -77,78 +55,29 @@ export default class ConfigParser {
77
55
  public envName?: string,
78
56
  ) {}
79
57
 
80
- private loadYaml(filepath: string) {
81
- debug && console.info(`Loading config ${filepath}`);
82
- const rawConfig = fs.readFileSync(filepath, 'utf-8');
83
- return yaml.parse(rawConfig);
84
- }
85
-
86
58
  public env(): TEnvConfig {
87
59
  debug && console.info('[app] Loading Proteum env vars from process.env');
60
+ const setup = this.setup();
88
61
 
89
62
  return {
90
63
  ...parseProteumEnvConfig({
91
64
  appDir: this.appDir,
65
+ connectedProjects: setup.connect,
92
66
  routerPortOverride: getRouterPortOverride(),
93
67
  }),
94
68
  version: BUILD_DATE,
95
69
  };
96
70
  }
97
71
 
98
- public identity() {
99
- const identityFile = this.appDir + '/identity.yaml';
72
+ public identity(): Config.Identity {
73
+ const identityFile = this.appDir + '/identity.config.ts';
100
74
  debug && console.info(`Loading identity ${identityFile}`);
101
- return this.loadYaml(identityFile);
75
+ return loadApplicationIdentityConfig(this.appDir);
102
76
  }
103
- }
104
-
105
- /*const walkYaml = (dir: string, configA: any, envName: string) => {
106
-
107
- const files = fs.readdirSync(dir);
108
- for (const file of files) {
109
-
110
- const fullpath = dir + '/' + file;
111
-
112
- // extension .yaml
113
- const isDir = fs.lstatSync(fullpath).isDirectory();
114
- let key = file;
115
- if (!isDir) {
116
-
117
- if (!file.endsWith('.yaml'))
118
- continue;
119
-
120
- key = key.substring(0, key.length - 5);
121
-
122
- }
123
-
124
- let fileConfig = configA;
125
-
126
- // Ciblage environnement
127
- // Before: /config/services/env.<envName>.yaml
128
- // After: /config/services
129
- if (key.startsWith('env.')) {
130
-
131
- // Excluding not mtching env name
132
- if (key.substring(4) !== envName)
133
- continue;
134
-
135
- // Créé l'entrée dans la config, sauf si le nom du fichier est default
136
- } else if (key !== 'default') {
137
-
138
- // Init config
139
- if (!(key in fileConfig))
140
- fileConfig[key] = {};
141
-
142
- fileConfig = configA[key];
143
-
144
- }
145
-
146
- // Recursion
147
- if (isDir)
148
- walk(fullpath, fileConfig, envName);
149
- // Lecture fichier
150
- else
151
- deepExtend(fileConfig, loadYaml(fullpath));
152
77
 
78
+ public setup(): Config.Setup {
79
+ const setupFile = this.appDir + '/proteum.config.ts';
80
+ debug && console.info(`Loading setup ${setupFile}`);
81
+ return loadApplicationSetupConfig(this.appDir);
153
82
  }
154
- }*/
83
+ }
@@ -16,7 +16,9 @@ import Ansi2Html from 'ansi-to-html';
16
16
  // Core libs
17
17
  import type ApplicationContainer from '..';
18
18
  import context from '@server/context';
19
+ import type { TDevConsoleLogChannel, TDevConsoleLogEntry, TDevConsoleLogLevel } from '@common/dev/console';
19
20
  import type { ServerBug, TCatchedError } from '@common/errors';
21
+ import type { TTraceCallOrigin, TTraceSqlQueryKind } from '@common/dev/requestTrace';
20
22
  import type ServerRequest from '@server/services/router/request';
21
23
 
22
24
  /*----------------------------------
@@ -36,14 +38,9 @@ export type Services = {};
36
38
  - TYPES
37
39
  ----------------------------------*/
38
40
 
39
- export type ChannelInfos = {
40
- channelType: 'cron' | 'master' | 'request' | 'socket';
41
- channelId?: string;
42
-
43
- method?: string;
44
- path?: string;
45
-
46
- user?: string;
41
+ export type ChannelInfos = TDevConsoleLogChannel & {
42
+ traceCallOrigin?: TTraceCallOrigin;
43
+ prismaOperations?: Array<{ kind: TTraceSqlQueryKind; model?: string; operation: string }>;
47
44
  };
48
45
 
49
46
  export type TGuestLogs = {
@@ -233,6 +230,43 @@ export default class Console {
233
230
  return logLevels[logLevelName];
234
231
  }
235
232
 
233
+ private serializeLogChannel(channel: ChannelInfos): TDevConsoleLogChannel {
234
+ return {
235
+ channelType: channel.channelType,
236
+ ...(typeof channel.channelId === 'string' ? { channelId: channel.channelId } : {}),
237
+ ...(typeof channel.method === 'string' ? { method: channel.method } : {}),
238
+ ...(typeof channel.path === 'string' ? { path: channel.path } : {}),
239
+ ...(typeof channel.user === 'string' ? { user: channel.user } : {}),
240
+ ...(typeof channel.traceCallId === 'string' ? { traceCallId: channel.traceCallId } : {}),
241
+ ...(typeof channel.traceCallOrigin === 'string' ? { traceCallOrigin: channel.traceCallOrigin } : {}),
242
+ ...(typeof channel.traceCallLabel === 'string' ? { traceCallLabel: channel.traceCallLabel } : {}),
243
+ ...(typeof channel.traceCallFetcherId === 'string' ? { traceCallFetcherId: channel.traceCallFetcherId } : {}),
244
+ ...(Array.isArray(channel.prismaOperations)
245
+ ? {
246
+ prismaOperations: channel.prismaOperations.map((operation) => ({
247
+ kind: operation.kind,
248
+ ...(typeof operation.model === 'string' ? { model: operation.model } : {}),
249
+ operation: operation.operation,
250
+ })),
251
+ }
252
+ : {}),
253
+ };
254
+ }
255
+
256
+ public listLogs(limit = 100, minimumLevel: TDevConsoleLogLevel = 'log'): TDevConsoleLogEntry[] {
257
+ const minimumLogLevel = logLevels[minimumLevel];
258
+
259
+ return this.logs
260
+ .filter((entry) => logLevels[entry.level] >= minimumLogLevel)
261
+ .slice(-Math.max(0, limit))
262
+ .map((entry) => ({
263
+ channel: this.serializeLogChannel(entry.channel),
264
+ level: entry.level,
265
+ text: formatWithOptions({ breakLength: 120, colors: false, depth: 3 }, ...entry.args),
266
+ time: entry.time.toISOString(),
267
+ }));
268
+ }
269
+
236
270
  private clean() {
237
271
  if (this.config.debug) {
238
272
  console.log(
@@ -29,6 +29,7 @@ export class ApplicationContainer<TServicesIndex extends StartedServicesIndex =
29
29
  public Services = Services as ServicesContainer<TServicesIndex>;
30
30
  public Environment: TEnvConfig;
31
31
  public Identity: Config.Identity;
32
+ public Setup: Config.Setup;
32
33
  public Console: Console;
33
34
  public Trace: Trace;
34
35
 
@@ -53,7 +54,8 @@ export class ApplicationContainer<TServicesIndex extends StartedServicesIndex =
53
54
  const configParser = new ConfigParser(this.path.root);
54
55
  this.Environment = configParser.env();
55
56
  this.Identity = configParser.identity();
56
- this.Console = new Console(this, defaultConsoleConfig);
57
+ this.Setup = configParser.setup();
58
+ this.Console = new Console(this, { ...defaultConsoleConfig, enable: this.Environment.profile === 'dev' });
57
59
  this.Trace = new Trace(this, this.Environment.trace);
58
60
  }
59
61