proteum 2.1.1 → 2.1.2

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.
@@ -9,6 +9,7 @@ export type TProfilerUiState = 'expanded' | 'minimized' | 'pinned-handle';
9
9
  export type TProfilerPanel =
10
10
  | 'summary'
11
11
  | 'timeline'
12
+ | 'auth'
12
13
  | 'routing'
13
14
  | 'controller'
14
15
  | 'ssr'
@@ -10,6 +10,12 @@ export type TTraceCallOrigin = (typeof traceCallOrigins)[number];
10
10
  export const traceEventTypes = [
11
11
  'request.start',
12
12
  'request.user',
13
+ 'auth.decode',
14
+ 'auth.route',
15
+ 'auth.check.start',
16
+ 'auth.check.rule',
17
+ 'auth.check.result',
18
+ 'auth.session',
13
19
  'resolve.start',
14
20
  'resolve.controller-route',
15
21
  'resolve.routes-evaluated',
@@ -68,6 +68,13 @@ In `proteum dev`, the bottom profiler exposes a `Commands` tab.
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
70
 
71
+ The profiler also exposes the shared diagnostics surfaces for humans:
72
+
73
+ - `Explain` renders the same manifest-backed data as `proteum explain`
74
+ - `Doctor` renders the same manifest diagnostics as `proteum doctor`
75
+
76
+ For the shared diagnostics contract and the corresponding dev HTTP endpoints, see [diagnostics.md](diagnostics.md).
77
+
71
78
  ### HTTP Endpoints
72
79
 
73
80
  The CLI remote mode and the profiler use the same dev-only endpoints:
@@ -0,0 +1,88 @@
1
+ # Diagnostics and Explainability
2
+
3
+ Proteum exposes two manifest-backed diagnostics surfaces:
4
+
5
+ - `proteum explain`: inspect the generated app structure
6
+ - `proteum doctor`: inspect manifest diagnostics
7
+
8
+ These are not separate models for different tools. They share the same generated snapshot and the same diagnostics contract.
9
+
10
+ ## Shared Contract
11
+
12
+ The canonical snapshot lives in `./.proteum/manifest.json`.
13
+
14
+ Proteum uses that same manifest in four places:
15
+
16
+ - `proteum explain` for human-readable and `--json` output
17
+ - `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`
20
+
21
+ This means the CLI, the dev HTTP endpoints, and the profiler all describe the same manifest-backed snapshot.
22
+
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.
24
+
25
+ ## CLI
26
+
27
+ Common usage:
28
+
29
+ ```bash
30
+ proteum explain
31
+ proteum explain --routes --controllers --commands
32
+ proteum explain --all --json
33
+
34
+ proteum doctor
35
+ proteum doctor --json
36
+ proteum doctor --strict
37
+ ```
38
+
39
+ `proteum explain --json` emits the selected manifest sections as machine-readable JSON.
40
+
41
+ `proteum doctor --json` emits:
42
+
43
+ - `summary.errors`
44
+ - `summary.warnings`
45
+ - `summary.strictFailed`
46
+ - `diagnostics`
47
+
48
+ ## Dev HTTP Endpoints
49
+
50
+ In `profile: dev`, the running app exposes:
51
+
52
+ - `GET /__proteum/explain`
53
+ - `GET /__proteum/doctor`
54
+
55
+ `/__proteum/explain` supports optional section selection:
56
+
57
+ ```text
58
+ GET /__proteum/explain?sections=routes,controllers,commands
59
+ GET /__proteum/explain?section=env&section=diagnostics
60
+ ```
61
+
62
+ `/__proteum/doctor` supports optional strict mode:
63
+
64
+ ```text
65
+ GET /__proteum/doctor?strict=true
66
+ ```
67
+
68
+ These endpoints are intended for local tooling and are not available in production.
69
+
70
+ ## Profiler
71
+
72
+ During `proteum dev`, the bottom profiler is the human-facing UI over the same dev diagnostics surfaces.
73
+
74
+ - `Explain` calls `/__proteum/explain`
75
+ - `Doctor` calls `/__proteum/doctor`
76
+ - `Commands` uses the dev command endpoints
77
+ - `Auth`, `Timeline`, `Routing`, `Controller`, `SSR`, `API`, and related panels remain request-trace views
78
+
79
+ Use the profiler when a human needs to browse the same data that an agent or CLI command can already inspect directly.
80
+
81
+ ## Agent Workflow
82
+
83
+ For AI coding agents or automation:
84
+
85
+ 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.
@@ -6,6 +6,7 @@ Proteum ships with a dev-only in-memory request trace buffer so routing, control
6
6
 
7
7
  - tracing is available only when the app runs with `profile: dev`
8
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)
9
10
  - production requests are not traced by this feature
10
11
 
11
12
  ## Main Commands
@@ -41,6 +42,7 @@ Use `--url http://host:port` when the dev server is reachable on a non-standard
41
42
  Depending on capture mode, traces can include:
42
43
 
43
44
  - request start, finish, user identity, status code, and duration
45
+ - auth decode input and outcome, route auth decisions, matched auth rules, rule inputs/results, and session create or clear events
44
46
  - direct controller route matches
45
47
  - route resolution start, match, and deep-mode skip reasons
46
48
  - controller start and result shape
@@ -58,6 +60,14 @@ Depending on capture mode, traces can include:
58
60
 
59
61
  Use `deep` selectively. It is for one-off investigation, not continuous capture.
60
62
 
63
+ ## Profiler
64
+
65
+ During `proteum dev`, the bottom profiler renders the same live request traces.
66
+
67
+ - `Timeline` shows the full request event stream
68
+ - `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
69
+ - expanding an auth event shows the summarized detail payload exactly as stored in the trace
70
+
61
71
  ## Configuration
62
72
 
63
73
  Set trace behavior with env vars:
package/eslint.js CHANGED
@@ -11,8 +11,8 @@ const defaultIgnores = [
11
11
  '**/var/**',
12
12
  ];
13
13
 
14
- const createDoubleAssertionSelector = (typeKeyword) =>
15
- `TSAsExpression[expression.type='TSAsExpression'][expression.typeAnnotation.type='${typeKeyword}']`;
14
+ const createZodTypeFactorySelector = (factoryName) =>
15
+ `CallExpression[callee.type='MemberExpression'][callee.computed=false][callee.object.type='Identifier'][callee.object.name=/^(schema|z|zod)$/][callee.property.name='${factoryName}']`;
16
16
 
17
17
  const createProteumEslintConfig = ({ ignores = [] } = {}) => [
18
18
  {
@@ -42,15 +42,20 @@ const createProteumEslintConfig = ({ ignores = [] } = {}) => [
42
42
  'jsx-a11y': jsxA11yPlugin,
43
43
  },
44
44
  rules: {
45
+ '@typescript-eslint/no-explicit-any': 'error',
45
46
  'no-restricted-syntax': [
46
47
  'error',
47
48
  {
48
- selector: createDoubleAssertionSelector('TSUnknownKeyword'),
49
- message: 'Do not use double assertions through `unknown`.',
49
+ selector: 'TSUnknownKeyword',
50
+ message: 'Do not use `unknown`; define an explicit type instead.',
50
51
  },
51
52
  {
52
- selector: createDoubleAssertionSelector('TSAnyKeyword'),
53
- message: 'Do not use double assertions through `any`.',
53
+ selector: createZodTypeFactorySelector('any'),
54
+ message: 'Do not use Zod `any()` schemas; define an explicit schema instead.',
55
+ },
56
+ {
57
+ selector: createZodTypeFactorySelector('unknown'),
58
+ message: 'Do not use Zod `unknown()` schemas; define an explicit schema instead.',
54
59
  },
55
60
  ],
56
61
  },
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.1",
4
+ "version": "2.1.2",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/proteum.git",
7
7
  "license": "MIT",
@@ -23,6 +23,7 @@
23
23
  "@tailwindcss/postcss": "^4.1.17",
24
24
  "accepts": "^1.3.7",
25
25
  "ansi-to-html": "^0.7.1",
26
+ "apexcharts": "^5.10.4",
26
27
  "autoprefixer": "^10.4.21",
27
28
  "aws-sdk": "^2.1415.0",
28
29
  "bowser": "^2.11.0",
@@ -41,7 +42,6 @@
41
42
  "eslint-plugin-react": "^7.37.5",
42
43
  "eslint-plugin-react-hooks": "^7.0.1",
43
44
  "express": "^4.17.1",
44
- "express-csp-header": "^5.0.0",
45
45
  "express-fileupload": "^1.2.1",
46
46
  "fast-safe-stringify": "^2.1.1",
47
47
  "favicons": "^7.2.0",
@@ -69,6 +69,7 @@
69
69
  "preact": "^10.27.1",
70
70
  "preact-render-to-string": "^6.6.1",
71
71
  "prompts": "^2.4.2",
72
+ "react-apexcharts": "^2.1.0",
72
73
  "replace-once": "^1.0.0",
73
74
  "responsive-loader": "^3.1.2",
74
75
  "serialize-javascript": "^6.0.2",
@@ -2,6 +2,8 @@
2
2
  - DEPENDANCES
3
3
  ----------------------------------*/
4
4
 
5
+ process.env.DOTENV_CONFIG_QUIET ??= 'true';
6
+
5
7
  // Core
6
8
  import AppContainer from './container';
7
9
  import ApplicationService, { AnyService } from './service';
@@ -144,8 +146,6 @@ export abstract class Application<
144
146
  ----------------------------------*/
145
147
 
146
148
  public async start(options: TApplicationStartOptions = {}) {
147
- console.log('Build date', BUILD_DATE);
148
- console.log('Core version', CORE_VERSION);
149
149
  const startTime = Date.now();
150
150
 
151
151
  const startingServices = await this.ready(options);
package/server/index.ts CHANGED
@@ -9,7 +9,6 @@ const shutdownApplication = async (reason: string) => {
9
9
  if (!shutdownPromise) {
10
10
  shutdownPromise = (async () => {
11
11
  try {
12
- console.info(`[server] Shutting down (${reason}) ...`);
13
12
  await application.runHook('cleanup');
14
13
  } catch (error) {
15
14
  console.error('[server] Failed to run application cleanup.', error);