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.
- package/README.md +25 -6
- package/agents/framework/AGENTS.md +14 -1
- package/agents/project/AGENTS.md +3 -0
- package/cli/commands/create.ts +5 -0
- package/cli/commands/dev.ts +2 -1
- package/cli/commands/init.ts +2 -94
- package/cli/index.ts +1 -4
- package/cli/presentation/commands.ts +45 -9
- package/cli/presentation/devSession.ts +17 -3
- package/cli/presentation/proteum_logo_400x400_square_icon.txt +400 -0
- package/cli/runtime/commands.ts +61 -3
- package/cli/scaffold/index.ts +720 -0
- package/cli/scaffold/templates.ts +344 -0
- package/cli/scaffold/types.ts +26 -0
- package/client/dev/profiler/index.tsx +1230 -230
- package/common/dev/profiler.ts +1 -0
- package/common/dev/requestTrace.ts +6 -0
- package/docs/dev-commands.md +7 -0
- package/docs/diagnostics.md +88 -0
- package/docs/request-tracing.md +10 -0
- package/eslint.js +11 -6
- package/package.json +3 -2
- package/server/app/index.ts +2 -2
- package/server/index.ts +0 -1
- package/server/services/auth/index.ts +525 -61
- package/server/services/auth/router/index.ts +106 -7
- package/server/services/router/http/index.ts +22 -6
package/common/dev/profiler.ts
CHANGED
|
@@ -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',
|
package/docs/dev-commands.md
CHANGED
|
@@ -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§ion=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.
|
package/docs/request-tracing.md
CHANGED
|
@@ -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
|
|
15
|
-
`
|
|
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:
|
|
49
|
-
message: 'Do not use
|
|
49
|
+
selector: 'TSUnknownKeyword',
|
|
50
|
+
message: 'Do not use `unknown`; define an explicit type instead.',
|
|
50
51
|
},
|
|
51
52
|
{
|
|
52
|
-
selector:
|
|
53
|
-
message: 'Do not use
|
|
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.
|
|
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",
|
package/server/app/index.ts
CHANGED
|
@@ -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);
|