proteum 2.0.0-1 → 2.1.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.
Files changed (94) hide show
  1. package/AGENTS.md +13 -1
  2. package/README.md +375 -0
  3. package/agents/framework/AGENTS.md +917 -0
  4. package/agents/project/AGENTS.md +138 -0
  5. package/agents/{codex → project}/CODING_STYLE.md +3 -2
  6. package/agents/project/client/AGENTS.md +108 -0
  7. package/agents/{codex → project}/client/pages/AGENTS.md +8 -8
  8. package/agents/{codex → project}/server/routes/AGENTS.md +2 -1
  9. package/agents/project/server/services/AGENTS.md +170 -0
  10. package/agents/{codex → project}/tests/AGENTS.md +1 -0
  11. package/cli/app/config.ts +3 -2
  12. package/cli/app/index.ts +6 -66
  13. package/cli/bin.js +7 -2
  14. package/cli/commands/build.ts +94 -27
  15. package/cli/commands/check.ts +15 -1
  16. package/cli/commands/dev.ts +288 -132
  17. package/cli/commands/doctor.ts +108 -0
  18. package/cli/commands/explain.ts +226 -0
  19. package/cli/commands/init.ts +76 -70
  20. package/cli/commands/lint.ts +18 -1
  21. package/cli/commands/refresh.ts +16 -6
  22. package/cli/commands/typecheck.ts +14 -1
  23. package/cli/compiler/artifacts/controllers.ts +150 -0
  24. package/cli/compiler/artifacts/discovery.ts +132 -0
  25. package/cli/compiler/artifacts/manifest.ts +267 -0
  26. package/cli/compiler/artifacts/routing.ts +315 -0
  27. package/cli/compiler/artifacts/services.ts +480 -0
  28. package/cli/compiler/artifacts/shared.ts +12 -0
  29. package/cli/compiler/client/identite.ts +2 -1
  30. package/cli/compiler/client/index.ts +13 -3
  31. package/cli/compiler/common/controllers.ts +23 -28
  32. package/cli/compiler/common/files/style.ts +3 -4
  33. package/cli/compiler/common/generatedRouteModules.ts +333 -19
  34. package/cli/compiler/common/proteumManifest.ts +133 -0
  35. package/cli/compiler/index.ts +33 -896
  36. package/cli/compiler/server/index.ts +21 -4
  37. package/cli/context.ts +71 -0
  38. package/cli/index.ts +39 -181
  39. package/cli/presentation/commands.ts +208 -0
  40. package/cli/presentation/compileReporter.ts +65 -0
  41. package/cli/presentation/devSession.ts +70 -0
  42. package/cli/presentation/help.ts +193 -0
  43. package/cli/presentation/ink.ts +69 -0
  44. package/cli/presentation/layout.ts +83 -0
  45. package/cli/runtime/argv.ts +49 -0
  46. package/cli/runtime/command.ts +25 -0
  47. package/cli/runtime/commands.ts +221 -0
  48. package/cli/runtime/importEsm.ts +7 -0
  49. package/cli/runtime/verbose.ts +15 -0
  50. package/cli/utils/agents.ts +5 -4
  51. package/cli/utils/keyboard.ts +12 -6
  52. package/client/app/index.ts +0 -6
  53. package/client/services/router/index.tsx +1 -1
  54. package/client/services/router/response/index.tsx +2 -2
  55. package/common/dev/serverHotReload.ts +12 -0
  56. package/common/router/index.ts +3 -2
  57. package/common/router/layouts.ts +1 -1
  58. package/common/router/pageSetup.ts +1 -0
  59. package/package.json +10 -8
  60. package/prettier/router-registration-plugin.cjs +52 -0
  61. package/prettier.config.cjs +1 -0
  62. package/scripts/cleanup-generated-controllers.ts +2 -2
  63. package/scripts/fix-reference-app-typing.ts +2 -2
  64. package/scripts/format-router-registrations.ts +119 -0
  65. package/scripts/migrate-explicit-controllers-and-request.ts +423 -0
  66. package/scripts/refactor-server-controllers.ts +19 -18
  67. package/scripts/refactor-server-runtime-aliases.ts +1 -1
  68. package/server/app/commands.ts +309 -25
  69. package/server/app/container/config.ts +1 -1
  70. package/server/app/container/index.ts +2 -2
  71. package/server/app/controller/index.ts +13 -4
  72. package/server/app/index.ts +53 -37
  73. package/server/app/service/container.ts +26 -28
  74. package/server/app/service/index.ts +10 -20
  75. package/server/app.tsconfig.json +9 -2
  76. package/server/index.ts +32 -1
  77. package/server/services/auth/index.ts +234 -15
  78. package/server/services/auth/router/index.ts +39 -7
  79. package/server/services/auth/router/request.ts +40 -8
  80. package/server/services/disks/index.ts +1 -1
  81. package/server/services/prisma/Facet.ts +2 -2
  82. package/server/services/prisma/index.ts +22 -5
  83. package/server/services/prisma/mariadb.ts +47 -0
  84. package/server/services/router/http/index.ts +9 -1
  85. package/server/services/router/index.ts +10 -4
  86. package/server/services/router/response/index.ts +26 -6
  87. package/types/auth-check-rules.test.ts +51 -0
  88. package/types/controller-request-context.test.ts +55 -0
  89. package/types/service-config.test.ts +39 -0
  90. package/agents/codex/AGENTS.md +0 -95
  91. package/agents/codex/client/AGENTS.md +0 -102
  92. package/agents/codex/server/services/AGENTS.md +0 -137
  93. package/server/services/models.7z +0 -0
  94. /package/agents/{codex → project}/agents.md.zip +0 -0
package/AGENTS.md CHANGED
@@ -16,11 +16,13 @@ When tradeoffs exist, prioritize framework decisions in this order:
16
16
  When working on Proteum itself, optimize for agent ergonomics first:
17
17
 
18
18
  - Prefer explicit, typed, machine-readable contracts over implicit runtime magic, hidden conventions, ambient globals, or tribal knowledge.
19
+ - Enforce strong, consistent TypeScript typings across the whole project. Do not introduce `any` or `unknown`.
19
20
  - Make routes, data loading, server actions / controllers, services, SEO metadata, sitemap generation, static generation, and environment contracts easy to discover, inspect, and explain.
20
21
  - Treat SSR and SEO as first-class framework primitives, not app-level patchwork.
21
22
  - Prefer server-first designs that avoid shipping client JavaScript unless it is required for user-facing behavior.
22
23
  - Favor small, single-purpose files and modules that reduce context load and make edits easier for agents to scope safely.
23
24
  - Generated code should improve traceability and type safety, not obscure behavior. It should be deterministic, auditable, and easy for agents to map back to source files.
25
+ - Prefer inference from the explicit application class in `server/index.ts` whenever possible. Treat `server/index.ts` as the canonical type root for application services, router services, router context, and models instead of duplicating manual type declarations.
24
26
  - Prefer exact end-to-end contracts for inputs, outputs, errors, side effects, and caching behavior.
25
27
  - Prefer framework features that make impact analysis, verification, and debugging easier for agents.
26
28
  - Prefer output that is fast to render, easy to crawl, semantically rich, and easy for LLMs to parse reliably.
@@ -54,14 +56,23 @@ When changing Proteum itself, always ground the work in the real apps that use i
54
56
 
55
57
  Future changes should preserve and extend the current explicit model instead of reintroducing runtime magic.
56
58
 
57
- - Server route entrypoints live in `*.controller.ts` files.
59
+ - Strong typings are mandatory across the whole project. Do not use `any` or `unknown`; keep types explicit, precise, and consistent.
60
+ - Prefer deriving types from the explicit application class in `server/index.ts` instead of recreating them manually in feature code, helpers, or generated output.
61
+ - Server route entrypoints live in `server/controllers/**/*.ts` files.
58
62
  - Controllers extend `Controller` and read request-scoped values from `this.request`.
59
63
  - Controllers validate request input via `this.input(schema)` inside the method body. Do not use decorators for validation metadata.
64
+ - `server/config/*.ts` should export plain typed config constants with `Services.config(ServiceClass, { ... })`, for example `export const missionsConfig = Services.config(Missions, { ... })`.
65
+ - `server/index.ts` should default-export the app `Application` subclass and instantiate root services as public fields via `new ServiceClass(this, config, this)`.
60
66
  - Normal services extend `Service` and should use `this.services`, `this.models`, and `this.app` instead of implicit globals or magic imports.
67
+ - App services should be inferred from the explicit `server/index.ts` application graph and the config passed into each constructor, not hand-maintained parallel interfaces.
68
+ - Router services and router/request context values such as `user`, `auth`, and similar request-scoped contracts should come from inferred request and app types, not ad hoc casts.
69
+ - Models should be inferred from the app/model registry rooted at `server/index.ts` and exposed through generated app types, not from duplicated hand-written model maps.
70
+ - Controllers should own auth, input parsing, and request concerns, then pass explicit typed values into services.
61
71
  - Do not reintroduce runtime server imports or globals such as `@request`, `@models`, or `@app`.
62
72
  - Client pages use `Router.page(path, render)` or `Router.page(path, setup, render)`.
63
73
  - SSR data loading belongs in the `setup` function returned object, not in `api.fetch(...)`.
64
74
  - Client-side controller access should come from the generated controller tree and client context, not from fake runtime imports.
75
+ - When referencing an app service, a router service, or a model, expose it in the current block scope first by destructuring from `this.request`, `this.app`, or `this.app.Models.client`, then call methods on that local binding. The service, router value, or model should be the first element of the callee chain.
65
76
 
66
77
  ## Solution Proposals
67
78
 
@@ -82,6 +93,7 @@ When presenting a framework solution, make it easy to judge against the real app
82
93
  - Prefer deleting client-side code, dependencies, and emitted assets when the same capability can stay on the server or be generated statically.
83
94
  - Prefer deleting obsolete branches, compatibility layers, plugins, and dependencies over keeping dead paths around.
84
95
  - Prefer compiler logic that is deterministic, auditable, and easy for another agent to trace from source to generated output.
96
+ - Prefer local destructuring that exposes typed app services, router services, router context values, and models in the current block scope before use, instead of chaining through `this.request`, `this.app`, or `this.app.Models.client` at each call site.
85
97
  - Reject changes that increase bundle size, runtime cost, or crawlability risk unless the benefit is concrete and validated in both reference apps.
86
98
  - When removing old behavior, also remove the related packages, config flags, typings, docs, and dead helper files in the same pass when safe.
87
99
  - If a core change breaks one of the reference apps, keep iterating until the framework and the affected app usage are both corrected.
package/README.md ADDED
@@ -0,0 +1,375 @@
1
+ # Proteum
2
+
3
+ Proteum is an LLM-first SSR / SEO / TypeScript framework for full-stack web applications.
4
+
5
+ It is built for teams that want explicit server contracts, server-first rendering, deterministic generated artifacts, and a codebase that an AI agent can inspect without reverse-engineering hidden runtime magic.
6
+
7
+ ## Why Proteum
8
+
9
+ Most full-stack frameworks optimize first for human convenience.
10
+
11
+ Proteum optimizes first for:
12
+
13
+ - explicit, typed, machine-readable contracts
14
+ - SSR and SEO as framework primitives
15
+ - server-first architecture with minimal client runtime
16
+ - deterministic generation instead of ambient magic
17
+ - codebases that stay explainable to humans and LLMs at the same time
18
+
19
+ Proteum combines:
20
+
21
+ - page-first SSR workflows similar to modern React meta-frameworks
22
+ - explicit controller and service layers inspired by backend frameworks
23
+ - generated manifests and contracts that make routes, services, layouts, and diagnostics easy to inspect
24
+
25
+ ## Core Principles
26
+
27
+ - **Server-first by default.** Put data loading in the page setup function and keep client code focused on UI.
28
+ - **Explicit request entrypoints.** Controllers are classes. Request access is explicit through `this.request`.
29
+ - **Local validation.** Validate handler input inside the handler with `this.input(schema)`.
30
+ - **Deterministic generation.** Proteum owns `.proteum/` and regenerates it from source.
31
+ - **Explainability matters.** `proteum explain` and `proteum doctor` expose the framework view of your app.
32
+ - **SEO is not an afterthought.** Identity, routes, layouts, and SSR data are part of the app contract.
33
+
34
+ ## What a Proteum App Looks Like
35
+
36
+ ```text
37
+ my-app/
38
+ identity.yaml
39
+ env.yaml
40
+ package.json
41
+ client/
42
+ pages/
43
+ _layout/
44
+ components/
45
+ islands/
46
+ services/
47
+ server/
48
+ config/
49
+ index.ts
50
+ controllers/
51
+ services/
52
+ common/
53
+ models/
54
+ router/
55
+ errors/
56
+ .proteum/
57
+ manifest.json
58
+ client/
59
+ common/
60
+ server/
61
+ ```
62
+
63
+ Important files:
64
+
65
+ - `identity.yaml`: app identity, naming, locale, and SEO-facing metadata defaults
66
+ - `env.yaml`: environment contract loaded by the app
67
+ - `server/config/*.ts`: plain typed config exports consumed by the explicit app bootstrap
68
+ - `server/index.ts`: default-exported `Application` subclass that instantiates root services and router plugins
69
+ - `client/pages/**`: SSR page entrypoints registered through `Router.page(...)`
70
+ - `server/controllers/**`: request handlers that extend `Controller`
71
+ - `server/services/**`: business logic that extends `Service`
72
+ - `.proteum/**`: framework-owned generated contracts and manifests
73
+
74
+ ## Example: Server Bootstrap
75
+
76
+ Proteum app services are declared explicitly through typed config exports plus a concrete `Application` subclass.
77
+
78
+ ```ts
79
+ // server/config/user.ts
80
+ import { Services, type ServiceConfig } from '@server/app';
81
+ import AppContainer from '@server/app/container';
82
+ import Router from '@server/services/router';
83
+ import Users from '@/server/services/Users';
84
+
85
+ type RouterBaseConfig = Omit<ServiceConfig<typeof Router>, 'plugins'>;
86
+
87
+ export const usersConfig = Services.config(Users, {});
88
+
89
+ export const routerBaseConfig = {
90
+ domains: AppContainer.Environment.router.domains,
91
+ http: {
92
+ domain: 'example.com',
93
+ port: AppContainer.Environment.router.port,
94
+ ssl: true,
95
+ upload: { maxSize: '10mb' },
96
+ },
97
+ context: () => ({}),
98
+ } satisfies RouterBaseConfig;
99
+ ```
100
+
101
+ ```ts
102
+ // server/index.ts
103
+ import { Application } from '@server/app';
104
+ import Router from '@server/services/router';
105
+ import SchemaRouter from '@server/services/schema/router';
106
+ import Users from '@/server/services/Users';
107
+ import * as userConfig from '@/server/config/user';
108
+
109
+ export default class MyApp extends Application {
110
+ public Users = new Users(this, userConfig.usersConfig, this);
111
+ public Router = new Router(
112
+ this,
113
+ {
114
+ ...userConfig.routerBaseConfig,
115
+ plugins: {
116
+ schema: new SchemaRouter({}, this),
117
+ },
118
+ },
119
+ this
120
+ );
121
+ }
122
+ ```
123
+
124
+ Proteum reads `server/index.ts` plus `server/services/**/service.json` to derive the installed service graph and generated type contracts.
125
+
126
+ ## Example: Page
127
+
128
+ Proteum pages are explicit SSR entrypoints.
129
+
130
+ ```tsx
131
+ import Router from '@/client/router';
132
+
133
+ Router.page(
134
+ '/',
135
+ ({ Plans, Stats }) => ({
136
+ _auth: false,
137
+ _layout: false,
138
+ plans: Plans.getPlans(),
139
+ stats: Stats.general(),
140
+ }),
141
+ ({ plans, stats }) => {
142
+ return <LandingPage plans={plans} stats={stats} />;
143
+ }
144
+ );
145
+ ```
146
+
147
+ What happens here:
148
+
149
+ - the first argument is the route path
150
+ - the optional setup function runs on the server for SSR data loading
151
+ - keys prefixed with `_` become route options such as `_auth`, `_layout`, `_static`, or `_redirectLogged`
152
+ - every other returned key becomes page data
153
+ - the renderer receives the resolved data and the generated controller/service context
154
+
155
+ ## Example: Controller
156
+
157
+ Proteum controllers are explicit request entrypoints.
158
+
159
+ ```ts
160
+ import Controller, { schema } from '@server/app/controller';
161
+
162
+ export default class AuthController extends Controller<MyApp> {
163
+ public async loginWithPassword() {
164
+ const { Auth } = this.services;
165
+ const data = this.input(
166
+ schema.object({
167
+ email: schema.string().email(),
168
+ password: schema.string().min(8),
169
+ })
170
+ );
171
+
172
+ return Auth.loginWithPassword(data, this.request);
173
+ }
174
+ }
175
+ ```
176
+
177
+ Controller rules:
178
+
179
+ - read request-scoped values from `this.request`
180
+ - validate once with `this.input(schema)`
181
+ - call business logic through `this.services`, `this.models`, or `this.app`
182
+ - return explicit values instead of relying on ambient globals
183
+
184
+ ## Example: Service
185
+
186
+ Proteum services keep business logic out of request handlers.
187
+
188
+ ```ts
189
+ import Service from '@server/app/service';
190
+
191
+ export default class StatsService extends Service<Config, {}, MyApp, MyApp> {
192
+ public async general() {
193
+ return {
194
+ totalDomains: await this.models.SQL`SELECT COUNT(*) FROM domains`.value(),
195
+ tlds: Object.keys(this.app.Domains.tlds).length,
196
+ };
197
+ }
198
+ }
199
+ ```
200
+
201
+ Service rules:
202
+
203
+ - services extend `Service`
204
+ - request context should be resolved in controllers, then passed into services as explicit values
205
+ - services can use `this.services`, `this.models`, and `this.app`
206
+
207
+ ## Framework-Owned Generated Contracts
208
+
209
+ Proteum generates a machine-readable app description in `.proteum/`.
210
+
211
+ Typical generated artifacts:
212
+
213
+ - `.proteum/manifest.json`
214
+ - `.proteum/client/routes.ts`
215
+ - `.proteum/client/controllers.ts`
216
+ - `.proteum/client/layouts.ts`
217
+ - `.proteum/common/controllers.ts`
218
+ - `.proteum/server/routes.ts`
219
+ - `.proteum/server/controllers.ts`
220
+
221
+ These files are not hand-written application code. They are deterministic outputs derived from your app source and used by the runtime, the compiler, and tooling.
222
+
223
+ This is one of Proteum's most important properties: the framework can explain what it discovered instead of asking you to guess.
224
+
225
+ ## CLI
226
+
227
+ Proteum ships with a compact CLI focused on the real app lifecycle:
228
+
229
+ | Command | Purpose |
230
+ | --- | --- |
231
+ | `proteum dev` | Start the compiler, SSR server, and hot reload loop |
232
+ | `proteum refresh` | Regenerate `.proteum` contracts and typings |
233
+ | `proteum typecheck` | Refresh generated typings, then run TypeScript |
234
+ | `proteum lint` | Run ESLint for the current app |
235
+ | `proteum check` | Refresh, typecheck, and lint in one command |
236
+ | `proteum build --prod` | Produce the production server and client bundles into `bin/` |
237
+ | `proteum doctor` | Inspect manifest diagnostics |
238
+ | `proteum explain` | Explain routes, controllers, services, layouts, conventions, and env |
239
+ | `proteum init` | Experimental project scaffolding when scaffold assets are installed |
240
+
241
+ Recommended daily workflow:
242
+
243
+ ```bash
244
+ proteum dev
245
+ proteum refresh
246
+ proteum check
247
+ proteum build --prod
248
+ ```
249
+
250
+ Useful inspection commands:
251
+
252
+ ```bash
253
+ proteum doctor
254
+ proteum doctor --json
255
+ proteum explain
256
+ proteum explain --routes --controllers
257
+ proteum explain --all --json
258
+ ```
259
+
260
+ ## LLM-Friendly By Design
261
+
262
+ Proteum is built so an agent can answer these questions quickly and reliably:
263
+
264
+ - What is this app called, and what are its SEO defaults?
265
+ - Which routes exist?
266
+ - Which controller handles a request?
267
+ - Which services are installed?
268
+ - Which layouts exist?
269
+ - Which diagnostics did the framework detect?
270
+
271
+ Proteum answers those questions with explicit artifacts:
272
+
273
+ - `identity.yaml` for app identity
274
+ - `env.yaml` for the environment surface
275
+ - `server/index.ts` for the explicit root service graph
276
+ - `.proteum/manifest.json` for machine-readable app structure
277
+ - `proteum explain --json` for structured framework introspection
278
+ - `proteum doctor --json` for structured diagnostics
279
+
280
+ If you are an LLM or automation agent, start here:
281
+
282
+ 1. Read `identity.yaml`.
283
+ 2. Read `env.yaml`.
284
+ 3. Inspect `server/index.ts` and `server/config/*.ts` for the explicit app bootstrap.
285
+ 4. Read `.proteum/manifest.json` or run `proteum explain --json`.
286
+ 5. Inspect `server/controllers/**` for request entrypoints.
287
+ 6. Inspect `server/services/**` for business logic.
288
+ 7. Inspect `client/pages/**` for SSR routes and page setup contracts.
289
+
290
+ ## What Proteum Avoids
291
+
292
+ Proteum intentionally avoids several patterns that make frameworks harder to inspect and harder to trust:
293
+
294
+ - hidden runtime globals
295
+ - implicit service registration hidden behind bootstrap helpers
296
+ - implicit request state inside business services
297
+ - controller validation defined far away from the handler
298
+ - route systems that cannot be explained without reading the compiler
299
+ - generated code that hides where it came from
300
+
301
+ ## Real-World Shape
302
+
303
+ Proteum is already used on large application surfaces with:
304
+
305
+ - many controllers and services
306
+ - SSR landing pages and authenticated app pages
307
+ - generated controller accessors injected into page context
308
+ - build, typecheck, lint, and diagnostic workflows run from the CLI
309
+
310
+ In real apps, the common `package.json` scripts look like this:
311
+
312
+ ```json
313
+ {
314
+ "scripts": {
315
+ "dev": "proteum dev",
316
+ "refresh": "proteum refresh",
317
+ "typecheck": "proteum typecheck",
318
+ "check": "proteum check",
319
+ "build": "proteum build --prod",
320
+ "start": "node ./bin/server.js"
321
+ }
322
+ }
323
+ ```
324
+
325
+ ## Installation
326
+
327
+ Proteum currently targets:
328
+
329
+ - Node.js `>=20.19.0`
330
+ - npm `>=3.10.10`
331
+
332
+ Install in an app:
333
+
334
+ ```bash
335
+ npm install proteum
336
+ ```
337
+
338
+ If the scaffold assets are available in your distribution, you can bootstrap a new app with:
339
+
340
+ ```bash
341
+ npx proteum init
342
+ ```
343
+
344
+ Then use the normal workflow:
345
+
346
+ ```bash
347
+ npx proteum dev
348
+ npx proteum check
349
+ npx proteum build --prod
350
+ ```
351
+
352
+ ## Repository Structure
353
+
354
+ This repository is organized around the same explicit framework surface it exposes:
355
+
356
+ - `cli/`: compiler, commands, diagnostics, and developer workflow
357
+ - `client/`: client runtime, page registration, islands, and router behavior
358
+ - `server/`: controller base classes, services, runtime, and SSR server behavior
359
+ - `common/`: shared router contracts, models, request/response types, and utilities
360
+ - `doc/`: focused design notes and internal documentation
361
+ - `agents/`: agent-specific conventions and scaffolding used in Proteum-based projects
362
+
363
+ ## Status
364
+
365
+ Proteum is actively hardening its explicit model.
366
+
367
+ The direction is deliberate:
368
+
369
+ - less runtime magic
370
+ - more generated and auditable contracts
371
+ - clearer controller and service boundaries
372
+ - better SSR, SEO, and explainability defaults
373
+ - better ergonomics for both humans and AI agents
374
+
375
+ If you want a framework that treats machine-readable architecture as a first-class feature, Proteum is what this repository is building.