proteum 2.5.8 → 2.5.10

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.
@@ -1,399 +0,0 @@
1
- # Proteum Root Contract
2
-
3
- This is the reusable Proteum-wide contract that is safe to place at the root of a monorepo above one or more Proteum apps.
4
- Pair this file with an app-root `AGENTS.md` inside each Proteum app when local workflow or product-context instructions depend on the current directory being the app root.
5
- Role: keep only reusable Proteum workflow, architecture contracts, shared typing rules, and cross-surface verification rules here.
6
- Do not put here: app-root bootstrap steps, documentation-driven coding workflow, detailed diagnostics workflow, optimization checklists, coding-style details, or narrow area-specific instructions that belong in `DOCUMENTATION.md`, `diagnostics.md`, `optimizations.md`, `CODING_STYLE.md`, `client/AGENTS.md`, `client/pages/AGENTS.md`, `server/routes/AGENTS.md`, `server/services/AGENTS.md`, or `tests/AGENTS.md`.
7
-
8
- Documentation source of truth: root-level `DOCUMENTATION.md`.
9
- Optimization source of truth: root-level `optimizations.md`.
10
- Diagnostics source of truth: root-level `diagnostics.md`.
11
- Coding style source of truth: root-level `CODING_STYLE.md`.
12
-
13
- Managed compact root routers must use trigger -> canonical instruction file references, not copied summaries of this contract. If a trigger points here, load this full file before acting and keep the source rule here.
14
-
15
- ## Fast Triggers
16
-
17
- - If the user pastes raw errors without asking for a fix, do not implement changes yet. First run the task-safe local reproduction path: identify the likely app, route, command, or request from the error, boot or reuse the relevant dev server with the elevated-permissions workflow in `Task Lifecycle`, reproduce the failing surface locally, and inspect server output, browser console output, diagnostics, traces, or the smallest relevant command result. If the error does not identify enough context to reproduce, say what is missing and use the available local evidence before guessing. Then list likely causes and, for each one, give probability, why, and how to fix it.
18
- - If the user asks to implement a feature, first inspect the relevant existing surface and state any implementation problem, pain point, attention point, inconsistency, missing information, or question you see. If anything needs clarification or a decision, pause before editing, ask the user what decision to take, and resume only after the user answers.
19
- - If the task is ambiguous, generated, connected, or multi-repo, start with MCP `workflow_start` and then MCP `orient { projectId, query }` only if the bootstrap did not return a sufficient owner or next action; use `npx proteum orient <query>` only when MCP is unavailable or terminal evidence is required.
20
- - Treat Proteum CLI and MCP output as the workflow router. Treat instruction previews returned by MCP `workflow_start` or `instructions_resolve { projectId }` as the allowed instruction scope for read-only discovery and diagnostics. Read full file contents only before edits or git writes, when returned `fullRead`/`fullReadPolicy` requires it, or when the compact preview is insufficient. Do not read broad instruction folders or every managed instruction file up front.
21
- - When a Proteum MCP client is available, first call MCP `workflow_start` with `cwd` or a known `projectId`. If it is ambiguous or returns offline app candidates, call `project_resolve { cwd }`, select the intended app root, resolve any returned `data.readiness.state="blocked"` fresh-copy setup actions, start exactly one dev server from that app root when needed, then retry `workflow_start`. Pass the returned live `projectId` to every follow-up app-bound MCP tool. `npx proteum dev` ensures one managed machine MCP daemon is running; do not start a second managed daemon. Prefer MCP `runtime_status`, `orient`, `instructions_resolve`, `explain_summary`, `route_candidates`, `doctor`, `diagnose`, `trace_show`, `perf_request`, `logs_tail`, and `db_query` for read-only runtime/status/orientation/owner/route/trace/perf/log/database reads. Do not run CLI equivalents after a successful MCP result for the same read. Do not run broad source searches for route/page/controller ownership after MCP returns the owner. Use CLI commands when you need reproducible terminal validation, dev/build/check workflows, fallback repair, or output to share with a human.
22
- - MCP payloads are compact single-line `proteum-mcp-v1` JSON with capped and paginated detail. Do not expand MCP output for human readability.
23
- - For every non-trivial coding task, load and follow root-level `DOCUMENTATION.md` before coding.
24
- - For bug fixes, regressions, incidents, broken public routes, auth/OAuth failures, integration failures, or production behavior fixes, load and follow root-level `DOCUMENTATION.md` before coding so the relevant fix note, regression-test docs, ADR, or explicit skip reason is handled in the same change.
25
- - If the user reports an issue, or the agent encounters one during exploration, implementation, verification, or runtime reproduction, load and follow root-level `diagnostics.md`.
26
- - If the task touches client-side files, especially `client/**` and page files, load and apply root-level `optimizations.md` only after implementation for post-implementation checking and optimization. Skip it at task start and skip it for server-only, test-only, doc-only, and non-client refactor tasks unless the user explicitly asks for optimization work.
27
- - If the task needs new app or artifact boilerplate, prefer `npx proteum init ...` and `npx proteum create ...` before creating files by hand. Use `--dry-run --json` when an agent needs a machine-readable plan before writing files.
28
- - If you changed `schema.prisma`, do not start testing or validation yet. Ask the user to run the following command in the affected worktree directory, replacing the placeholders, and wait for the user to reply exactly `continue` before resuming validation or tests:
29
- ```
30
- cd <worktree path>
31
- npx prisma migrate dev --config ./prisma.config.ts --name <migration name>
32
- ```
33
- - If you encounter `runtime/provider-hook-outside-provider`, `runtime/client-only-hook-in-ssr`, `runtime/router-context-outside-router`, or `runtime/connected-boundary-mismatch`, treat it as a framework contract failure first. Fix the provider, SSR/client, router, or connected boundary before assuming a local leaf-component bug.
34
- - If the change is runtime-visible, request-time, router, SSR, browser-visible, or controller-behavior, use running-app verification.
35
- - If the change is docs-only, wording-only, type-only, test-only, generated-output cleanup, or a clearly local non-runtime refactor, use static verification only unless the user explicitly asks for runtime verification or the agent finds a real issue.
36
- - If the user replies exactly `commit`, generate one top-level short (up to 100 characters) sentence covering all changes made since the last `commit` and, if there has been no prior `commit`, since the beginning of the whole conversation, strictly using the Conventional Commits specification:
37
- ```
38
- <type>[optional scope]: <description>
39
-
40
- [optional body]
41
- ```
42
- Then treat `commit` as conversation-wide and cross-project, not task-scoped. For downstream Proteum apps, before staging or committing, run only this commit-time verification: `proteum refresh`, then the targeted lint, typecheck, and test commands that match the conversation changes in parallel. Skip this downstream app verification when the affected repository is the Proteum framework repository itself; use the framework repo `AGENTS.md` commit workflow there. Do not run coverage, full `npm run check`, repository `check:commit`, unrelated broad suites, or any other check unless the user explicitly asks for it in the same request. Report any blocker instead of committing through failed commit-time verification. Identify every affected git repository or worktree touched during that span, stage all conversation-related changed files in each affected repository or worktree with `git add` while still avoiding unrelated pre-existing user changes or incidental untracked files, and create one `git commit` per affected repository or worktree. Do not omit linked local dependencies, framework repos, connected projects, or producer apps when they were changed to make the delivered behavior actually work. Do not stop at only suggesting the message.
43
- After providing a commit message or after creating a commit, immediately follow it with this exact prompt and obey it:
44
- `Explain in short minimalistic and few bullet points what we changed in this thread, like you would do to your grandma. Start with a verb in the past.`
45
-
46
- ## Task Lifecycle
47
-
48
- ### Before Editing
49
-
50
- - Before changing any file, load root-level `CODING_STYLE.md` and any narrower area `AGENTS.md` that applies to the touched files. Do not spend response space explicitly acknowledging those reads unless the user asks.
51
-
52
- ### During Implementation
53
-
54
- - After running `npx proteum create ...`, adapt the generated code to the real feature instead of leaving placeholder logic in place.
55
- - If any inconsistency, ambiguity, conflicting source, missing information, or implementation detail needing clarification appears while coding, stop editing immediately, ask the user what decision to take, and resume only after the user answers. Do not silently choose a default or keep implementing under a guessed assumption.
56
- - When starting a long-lived dev server for an agent task, always request elevated permissions and run `npx proteum dev` outside the sandbox. Use an explicit task/thread-scoped session file such as `var/run/proteum/dev/agents/<task>.json`, inspect `npx proteum runtime status` first, then use its exact Start Dev next action so occupied router/HMR ports are avoided. Do not `curl` normal page routes to identify a port owner; use Proteum runtime status or dev-only `/__proteum/*` endpoints. After the server is ready, print the live server URL as a clickable Markdown link.
57
- - Use `--replace-existing` only when restarting the exact session file started by the current thread/task. Never replace another live session that belongs to a user, another thread, or an unknown owner.
58
- - Do not start a second `npx proteum dev` server in the same worktree, and do not start a second managed MCP daemon. If machine MCP routing fails, run `npx proteum mcp status` and `npx proteum runtime status` from the intended app root; if no live session exists, use the exact MCP offline or runtime-status next action instead of assuming the manifest default port. If the same app already responds on the configured port without live tracking, use or repair that runtime instead of starting another server. If a live session exists but runtime/MCP is unreachable, stop the listed session file first, then start dev again. Do not run diagnose, trace, or perf reads while runtime health is unreachable. Then retry MCP `workflow_start` and use the returned `projectId`.
59
- - If the current app depends on local `file:` connected projects, boot every connected producer app too, each with its own task-scoped session file and free port, and run every one of those `proteum dev` processes with elevated permissions outside the sandbox before starting or verifying the consumer app.
60
- - During `npx proteum dev`, the app exposes the read-only Proteum MCP runtime endpoint at `/__proteum/mcp`; use it for repeated agent reads instead of spawning equivalent diagnostics commands. For route/page/controller ownership, prefer MCP `workflow_start`, `route_candidates { projectId, query }`, or `explain_summary { projectId, query }` over broad `npx proteum explain --routes --controllers --full` dumps.
61
- - For browser validation, use the browser MCP against the running app. Keep Playwright inside `npx proteum e2e --port <port>` for targeted/full end-to-end suites. Bootstrap protected browser MCP state with `npx proteum session`; bootstrap protected E2E runs with `npx proteum e2e --session-email <email> --session-role <role>`.
62
- - Current CLI banner contract: only the bare `proteum build` and bare `proteum dev` commands print the welcome banner and include the active Proteum installation method. Any extra argument or option skips the welcome banner. Terminal `proteum mcp` may print a compact central MCP ready banner when it starts or reuses the managed daemon. Only `proteum dev` clears the interactive terminal before rendering, exposes `CTRL+R` reload plus `CTRL+C` shutdown hotkeys in its session UI, and reports connected app names plus successful connected `/ping` checks in the ready banner. Every `proteum dev` start ensures tracked instruction files contain the current managed `# Proteum Instructions` section and `CLAUDE.md` symlinks point to sibling `AGENTS.md` files before the dev loop begins.
63
-
64
- ### Before Finishing
65
-
66
- - Before finishing, re-check touched files against root-level `CODING_STYLE.md` and any narrower area `AGENTS.md` that applied to the edit. Re-check against root-level `optimizations.md` only for touched client-side files. Re-check against root-level `diagnostics.md` only if the task involved an issue, diagnosis, runtime reproduction, or verification failure.
67
- - Before finishing a production code change, re-check root-level `DOCUMENTATION.md` update rules. If behavior changed, a bug was fixed, a decision changed, or an important route, auth/OAuth, or integration issue was addressed, update the relevant docs before committing or explicitly explain why no docs update was needed.
68
- - For production changes, always add or update focused unit tests and run the targeted unit or integration tests that match the changed behavior. Do not run coverage after every ordinary change by default. Reserve whole-project coverage for the repository's full `npm run check` gate during push workflows or when the user explicitly requests it; downstream app commit-only workflows run `proteum refresh`, then targeted lint, typecheck, and test commands in parallel unless the user explicitly requests more, while framework-repo commits skip this downstream app verification. Document any generated files, migrations, framework shims, unreachable defensive branches, or changes that cannot reasonably be unit-tested as explicit exceptions.
69
- - Run targeted tests and checks that match the changed surface before finishing each feature or change. When the repository defines `proteum.verify.config.ts`, use `npx proteum verify changed` as the first post-change verification pass and expand only when the selected plan is insufficient. Continue running tests after changes, but do not run coverage by default. Downstream app commit workflows run only `proteum refresh`, then targeted lint, typecheck, and test commands in parallel; framework-repo commit workflows skip this downstream app verification. Reserve the full `npm run check` gate for push workflows, explicit user requests, or when project-local instructions require the full gate. After implementing a new feature or changing existing feature behavior, update the relevant end-to-end coverage and run the cheapest trustworthy Playwright or browser verification for that behavior before finishing. For docs-only, wording-only, type-only, generated-output cleanup, or clearly local non-runtime refactors, skip Playwright unless the user explicitly asks for it or verification reveals a real issue.
70
- - When you have finished your work, ask the user whether they want a commit message. After providing a commit message or after creating a commit, immediately follow it with this exact prompt and obey it:
71
- `Explain in short minimalistic and few bullet points what we changed in this thread, like you would do to your grandma. Start with a verb in the past.`
72
-
73
- ## Core Contracts
74
-
75
- - Client pages live in `client/pages/**` and default-export `definePageRoute(...)` or `defineErrorRoute(...)`.
76
- - Page URLs come from the explicit route definition `path`, not from the file path.
77
- - Callable app APIs live only in `server/controllers/**/*.ts` files that default-export `defineController(...)`.
78
- - Dev-only internal execution lives only in `commands/**/*.ts` files that extend `Commands`.
79
- - Manual HTTP endpoints live only in `server/routes/**`.
80
- - Controllers declare input on `defineAction({ input, handler })`; handlers receive parsed `input` in context.
81
- - Request-scoped state lives only on action handler context and manual-route handler context objects.
82
- - Keep one class or one React/Preact component per file.
83
- - Prefer a deep tree grouped by business concern instead of long file names.
84
- - Use the default `*.ts` or `*.tsx` file unless an `*.ssr.ts` or `*.ssr.tsx` variant is truly required.
85
- - Never edit generated files under `.proteum`.
86
- - When a task changes database structure, edit the app's `schema.prisma` only.
87
- - Never create or edit migration files manually.
88
- - Use `@generated/client/*`, `@generated/common/*`, and `@generated/server/*` for generated surfaces.
89
- - Client context is typically imported from `@/client/context`.
90
- - Normal service methods do not read request state directly.
91
- - Do not import runtime values from `@models`.
92
- - Do not use `@request` runtime globals.
93
- - Do not use `@app` on the client.
94
- - Do not import `@app` in route, page, or controller files. Runtime app/services/router access belongs in typed callback parameters.
95
- - Prefer type inference rooted in the explicit application graph in `server/index.ts`.
96
-
97
- ## Surface Contracts
98
-
99
- ### App Bootstrap And Services
100
-
101
- - `server/index.ts` default-exports `defineApplication({ services, router, models, commands })` and is the canonical type root.
102
- - Root services are declared in the explicit `services` graph and instantiated with `new ServiceClass(app, config, app)`.
103
- - Typed root-service config lives in `server/config/*.ts` via `Services.config(ServiceClass, { ... })`.
104
- - Router plugins are instantiated explicitly inside the `Router` config `plugins` object.
105
- - Router plugins can subscribe to `request` and `request.finished`; `request.profiling` exists before `request` runs and carries the finalized request/API/SQL snapshot by `request.finished`.
106
- - Root business services live in `server/services/<Feature>/index.ts`.
107
- - Root-service config lives in `server/config/*.ts` when the service needs config.
108
- - Business logic lives in classes that extend `Service` and use `this.services`, `this.models`, and `this.app`.
109
- - Keep auth, input parsing, locale, cookies, and request-derived values in controllers, then pass explicit typed arguments into services.
110
- - Split growing features into explicit subservices.
111
- - Companion client-callable entrypoints live in `server/controllers/**`.
112
- - `proteum create service ...` scaffolds the service file, a typed config export under `server/config/*.ts`, and the root registration in `server/index.ts`; review and adapt the generated names before committing.
113
-
114
- Example app root shape; replace names with the project app type and service names:
115
-
116
- ```ts
117
- import { defineApplication, type Application } from '@server/app';
118
- import Router from '@server/services/router';
119
- import SchemaRouter from '@server/services/schema/router';
120
- import BillingService from '@/server/services/Billing';
121
-
122
- import * as appConfig from '@/server/config/app';
123
-
124
- type ProjectServices = {
125
- Billing: BillingService;
126
- };
127
-
128
- type ProjectRouterPlugins = {
129
- schema: SchemaRouter;
130
- };
131
-
132
- export type ProjectRouter = Router<ProjectApp, ProjectRouterPlugins>;
133
- export interface ProjectApp extends Application, ProjectServices {
134
- Router: ProjectRouter;
135
- }
136
-
137
- const createProjectRouter = (app: ProjectApp): ProjectRouter =>
138
- new Router<ProjectApp, ProjectRouterPlugins>(
139
- app,
140
- {
141
- ...appConfig.routerBaseConfig,
142
- plugins: {
143
- schema: new SchemaRouter({}, app),
144
- },
145
- },
146
- app,
147
- );
148
-
149
- const createProjectServices = (app: ProjectApp): ProjectServices => ({
150
- Billing: new BillingService(app, {}, app),
151
- });
152
-
153
- const ProjectApplication = defineApplication({
154
- services: createProjectServices,
155
- router: createProjectRouter,
156
- });
157
-
158
- export default ProjectApplication;
159
- ```
160
-
161
- ### Connected Projects
162
-
163
- - Declare connected namespaces in `proteum.config.ts` with explicit values such as `connect: { Product: { source: PRODUCT_CONNECTED_SOURCE, urlInternal: PRODUCT_URL_INTERNAL } }`.
164
- - Proteum does not infer connected env key names from the namespace. The source and internal URL must be provided explicitly in `proteum.config.ts`.
165
- - Use `npx proteum connect` to inspect configured connect values, cached contract state, and imported controllers for the current app.
166
- - Before launching a consumer app that depends on local `file:` connected sources, launch every connected producer app too, assign each one a free port, run each `proteum dev` outside the sandbox with elevated permissions, and make sure `connect.<Namespace>.urlInternal` resolves to those live producer URLs.
167
- - `file:` connected sources point at another Proteum app root and keep strong connected typings.
168
- - Non-local connected sources provide runtime helper generation but are intentionally typed loosely.
169
-
170
- ### Controllers
171
-
172
- - Files live under `server/controllers/**/*.ts` and default-export `defineController({ path, actions })`.
173
- - Actions declared with `defineAction(...)` become generated client-callable endpoints.
174
- - Route path comes from the controller `path` plus the action name.
175
- - Set `path: 'Custom/path'` on `defineController(...)` to override the base path.
176
- - Generated client calls use `POST`.
177
- - Prefer `proteum create controller ...` for new controller boilerplate, then adapt the generated method to real service calls.
178
-
179
- ```ts
180
- import { defineAction, defineController, schema } from '@generated/server/controller';
181
-
182
- export default defineController({
183
- path: 'Billing',
184
- actions: {
185
- read: defineAction({
186
- input: schema.object({ accountId: schema.string() }),
187
- handler: ({ input }) => ({ accountId: input.accountId }),
188
- }),
189
- },
190
- });
191
- ```
192
-
193
- ### Commands
194
-
195
- - Files live under `commands/**/*.ts` and default-export a class extending `Commands` from `@server/app/commands`.
196
- - Methods with bodies become generated dev commands.
197
- - Command path comes from the file path plus the method name.
198
- - `export const commandPath = 'Custom/path'` can override the base path.
199
- - Commands are for dev-only internal execution through `proteum command ...` or the profiler `Commands` tab.
200
- - Keep command logic internal; do not turn it into a normal controller unless it is a real app API.
201
- - Prefer `proteum create command ...` for new command boilerplate.
202
-
203
- ### Client Pages
204
-
205
- - Proteum scans page files for default-exported `definePageRoute(...)` and `defineErrorRoute(...)` definitions.
206
- - File path controls chunk identity and layout discovery; route path comes from the explicit definition `path` value.
207
- - The supported page shape is `definePageRoute({ path, options, data, render })`.
208
- - `options` is always required. `data` is the only nullable argument and must be `null` when the page has no SSR data loader.
209
- - `data` returns one flat object. Route-option keys such as `auth`, `layout`, `static`, and `_static` are forbidden in page data and must live in `options`.
210
- - Controller fetchers and promises returned from `data` resolve before render.
211
- - `render` consumes resolved page data and uses generated controller methods from render args or `@/client/context`.
212
- - Use `api.reload(...)` or `api.set(...)` only when intentionally mutating active page data state.
213
- - Error pages use `defineErrorRoute({ code, options, render })` in `client/pages/_messages/**`.
214
- - Prefer `proteum create page ...` for new page boilerplate, then review the explicit route path, options object, and data payload.
215
-
216
- ```tsx
217
- import { definePageRoute } from '@common/router/definitions';
218
-
219
- export default definePageRoute({
220
- path: '/billing',
221
- options: { auth: true },
222
- data: ({ BillingController }) => ({ billing: BillingController.read({ accountId: 'current' }) }),
223
- render: ({ billing }) => <BillingPage billing={billing} />,
224
- });
225
- ```
226
-
227
- ### Manual Routes
228
-
229
- - Use `server/routes/**` only for explicit HTTP behavior that should not be a generated controller action.
230
- - Good fits include redirects, sitemap or RSS output, OAuth callbacks, webhooks, and public resources with custom semantics.
231
- - Receive app services through `defineServerRoutes((app) => [...])` and use handler context for `request`, `response`, router plugins, and custom router context.
232
- - If the route is a normal app API, prefer a controller.
233
- - Prefer `proteum create route ...` for new manual-route boilerplate.
234
-
235
- ```ts
236
- import { defineServerRoute } from '@common/router/definitions';
237
-
238
- export default defineServerRoute({
239
- method: 'GET',
240
- path: '/health',
241
- options: {},
242
- handler: ({ response }) => response.json({ ok: true }),
243
- });
244
- ```
245
-
246
- ### Models And Aliases
247
-
248
- - Use Prisma typings from `@models/types`.
249
- - Use runtime models through `this.models` or `this.app.Models.client`.
250
- - Keep Prisma runtime access inside services when possible and prefer explicit `select` or narrow `include`.
251
- - Do not import runtime values from `@models` or edit generated Prisma client files.
252
- - Aliases:
253
- - `@/client/...`, `@/server/...`, `@/common/...`: app code
254
- - `@client/...`, `@server/...`, `@common/...`: Proteum core modules
255
- - `@generated/*`: generated app surfaces
256
-
257
- ## Verification Matrix
258
-
259
- Verify at the correct layer:
260
-
261
- - Default: use the cheapest trustworthy verification for the changed surface, including targeted tests for changed behavior. When `proteum.verify.config.ts` exists, start with `npx proteum verify changed`. Do not run coverage by default during ordinary change closeout.
262
- - Route additions: boot the app and hit the real URL.
263
- - Controller changes: exercise the generated client call or generated `/api/...` endpoint.
264
- - SSR changes: use the browser MCP to load the real page and inspect rendered HTML plus browser console.
265
- - Router or plugin changes: verify request context, auth, redirects, metrics, and validation on a running app.
266
- - New features or feature-behavior changes: use the cheapest trustworthy verification while iterating, use the browser MCP for browser-visible validation, then update and run the relevant end-to-end coverage. During downstream app commit workflows, run only `proteum refresh`, then targeted lint, typecheck, and test commands in parallel; skip this verification for framework-repo commits and reserve the full `npm run check` gate for push workflows unless the user or project-local instructions explicitly ask for the full gate earlier.
267
- - Generated, connected, or ownership-ambiguous changes: start with MCP `workflow_start`, then `orient { projectId, query }` and `explain_summary { projectId, query }` only when more detail is needed; use `npx proteum orient <query>` and `npx proteum verify owner <query>` when MCP is unavailable or terminal evidence is required.
268
- - Browser-visible issues: use the browser MCP after request-level verification is insufficient. Use `npx proteum e2e --port <port> ...` only when automated end-to-end coverage or a Playwright suite is required.
269
- - Raw browser execution outside end-to-end suites: use the browser MCP only. Keep Playwright in `npx proteum e2e --port <port>` for targeted/full end-to-end suites.
270
- - For trace-first reproduction, session-based auth setup, temporary logs, and post-fix surface checks, follow root-level `diagnostics.md`.
271
-
272
- ## Implementation Rules
273
-
274
- ### Dependency Selection
275
-
276
- - Before implementing a feature or change, first check whether the repo already includes a suitable dependency.
277
- - If not, search npm before building a new utility, abstraction, component primitive, parser, formatter, or integration from scratch.
278
- - Prefer the most popular, flexible, maintained packages that fit the project constraints.
279
- - When the task explicitly involves client-side optimization work, use root-level `optimizations.md` to decide whether custom infrastructure is justified over an existing package.
280
- - When you choose custom over a package, explain the reason briefly.
281
-
282
- ### Catalogs And Typing
283
-
284
- - Keep one canonical catalog or registry file and import it everywhere else.
285
- - Client-only catalogs live in `/client/catalogs/**`, server-only catalogs in `/server/catalogs/**`, and shared catalogs in `/common/catalogs/**`.
286
- - Do not create nested `catalogs/` folders under pages, components, services, tests, or other feature folders.
287
- - Keep strong TypeScript typings across the project.
288
- - Do not introduce `any` or `unknown`, including through casts, helper aliases, or fallback generic defaults.
289
- - Do not use `Reflect.get`, bracket access, broad `in` checks, or local loose reader helpers to bypass missing typings for app-owned data; fix the type contract or normalize once with a typed adapter at the boundary.
290
- - Fix typing issues only on code you wrote.
291
- - Never cast with `as any` or `as unknown`; fix the contract or add an explicit typed adapter.
292
-
293
- ### Design Rules
294
-
295
- - Prefer explicit `server/index.ts` bootstrap over hidden registration.
296
- - Prefer controller-backed app APIs over ad hoc manual `/api/...` routes.
297
- - Prefer service classes over server helpers with hidden dependencies.
298
- - Keep one canonical source of truth for catalogs, registries, and shared types.
299
- - Reuse shared Shadcn-based UI primitives when the project already provides them.
300
-
301
- ### Discouraged Patterns
302
-
303
- - request-scoped state inside normal service methods
304
- - hiding route definitions behind abstractions that remove the default-exported `definePageRoute(...)` or `defineServerRoute(...)` contract
305
- - editing `.proteum` directly
306
-
307
- ## Hard Stops
308
-
309
- - Never run schema-mutating SQL such as `ALTER TABLE`, `CREATE TABLE`, `DROP TABLE`, or `CREATE INDEX` to change database structure.
310
- - For read-only SQL diagnosis, use MCP `db_query` or `npx proteum db query "<sql>"`; only one capped `SELECT`, `SHOW`, or `EXPLAIN` statement is allowed.
311
- - Do not run `prisma *` yourself. If a schema change requires migration, ask the user to run `npx prisma migrate dev --config ./prisma.config.ts --name <migration name>` and wait for `continue`.
312
- - Do not run `git restore` or `git reset`.
313
- - Do not run write-mode git commands by default. The built-in exception is an exact `commit` reply, which allows `git add` and `git commit` in every affected repository or worktree touched during the whole conversation after the applicable commit-time verification succeeds. For downstream apps, commit-time verification is limited to `proteum refresh`, then targeted lint, typecheck, and test commands in parallel. For the Proteum framework repository itself, skip this downstream app verification and use the framework repo `AGENTS.md` commit workflow. This exception does not allow coverage, full `npm run check`, repository `check:commit`, unrelated broad suites, or other checks unless the user explicitly requests them in the same message. Any other write-mode git action requires an explicit user request.
314
-
315
- ## Appendix
316
-
317
- ### Project Shape
318
-
319
- This is a TypeScript, Node.js, Preact, Proteum monolith:
320
-
321
- - `/client`: assets, catalogs, components, hooks, pages
322
- - `/common`: shared functions, constants, types, and catalogs
323
- - `/server`: catalogs, config, services, routes, lib
324
- - `/tests`
325
-
326
- ### Source Of Truth
327
-
328
- Proteum reads:
329
-
330
- - `package.json`
331
- - `identity.config.ts` for app identity via `Application.identity({ ... })`
332
- - `proteum.config.ts` for compiler setup via `Application.setup({ transpile, connect })`
333
- - `process.env` via `PORT`, `ENV_*`, `URL`, `URL_INTERNAL`, any app-chosen connected-project values referenced by `proteum.config.ts`, `TRACE_*`, and `ENABLE_PROFILER`
334
- - `server/config/*.ts`
335
- - `server/index.ts`
336
- - `commands/**/*.ts`
337
- - `server/controllers/**/*.ts`
338
- - `server/routes/**/*.ts`
339
- - `client/pages/**/*.ts(x)`
340
- - `client/pages/**/_layout/index.tsx`
341
- - `public/**`
342
-
343
- Proteum owns:
344
-
345
- - `.proteum/manifest.json`
346
- - `.proteum/client/*`
347
- - `.proteum/common/*`
348
- - `.proteum/server/*`
349
-
350
- Project code should consume:
351
-
352
- - `@generated/client/*`
353
- - `@generated/common/*`
354
- - `@generated/server/*`
355
- - `@/client/context` as the generated client context entrypoint
356
-
357
- ### Useful Commands
358
-
359
- Prefer structured CLI surfaces over re-deriving framework facts from source:
360
-
361
- - `npx proteum connect`
362
- - `npx proteum connect --controllers --strict`
363
- - `npx proteum orient <query>`
364
- - `npx proteum runtime status`
365
- - `npx proteum mcp`
366
- - `npx proteum explain`
367
- - `npx proteum explain --manifest`
368
- - `npx proteum explain --connected --controllers`
369
- - `npx proteum explain --connected --controllers --full` only when raw connected/controller arrays are required
370
- - `npx proteum explain owner <query>`
371
- - `npx proteum doctor`
372
- - `npx proteum doctor --contracts`
373
- - `npx proteum diagnose <path> --port <port>`
374
- - `npx proteum verify owner <query>`
375
- - `npx proteum verify request <path>`
376
- - `npx proteum perf ...`
377
- - `npx proteum trace latest`
378
- - `npx proteum trace show <requestId> --events`
379
- - `npx proteum command ...`
380
- - `npx proteum session ...`
381
- - `npx proteum create ... --dry-run --json`
382
- - `npx proteum dev list --json`
383
- - `npx proteum dev stop --session-file <path>`
384
-
385
- Prefer scaffold commands before hand-writing boilerplate:
386
-
387
- - `npx proteum init <directory> --name <name>`
388
- - `npx proteum init ... --dry-run --json`
389
- - `npx proteum create page|controller|command|route|service <target>`
390
- - `npx proteum create ... --dry-run --json`
391
-
392
- ### High-Impact Files
393
-
394
- Edit these only when required, and keep changes minimal and explicit:
395
-
396
- - `tsconfig*.json`
397
- - `PORT`, `ENV_*`, `URL`, `TRACE_*`, and `ENABLE_PROFILER` env setup
398
- - Prisma-generated files
399
- - symbolic links