create-prisma-php-app 5.0.0-alpha.8 → 5.0.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 (60) hide show
  1. package/README.md +23 -2
  2. package/dist/.github/copilot-instructions.md +191 -0
  3. package/dist/AGENTS.md +588 -193
  4. package/dist/bootstrap.php +426 -213
  5. package/dist/index.js +2 -2
  6. package/dist/phpunit.xml +25 -0
  7. package/dist/postcss.config.js +4 -2
  8. package/dist/prisma-php.js +2 -2
  9. package/dist/public/.htaccess +1 -1
  10. package/dist/public/js/main.js +13 -1
  11. package/dist/public/js/pp-reactive-v2.min.js +1 -0
  12. package/dist/settings/auto-swagger-docs.ts +10 -10
  13. package/dist/settings/bs-config.ts +47 -27
  14. package/dist/settings/build.ts +2 -32
  15. package/dist/settings/component-map.ts +476 -0
  16. package/dist/settings/files-list.ts +2 -2
  17. package/dist/settings/project-name.ts +3 -6
  18. package/dist/settings/restart-mcp.ts +2 -2
  19. package/dist/settings/restart-websocket.ts +2 -2
  20. package/dist/settings/run-postcss.ts +205 -0
  21. package/dist/settings/run-tests.ts +35 -0
  22. package/dist/settings/swagger-config.ts +3 -3
  23. package/dist/settings/utils.ts +3 -3
  24. package/dist/src/Lib/Auth/Auth.php +62 -34
  25. package/dist/src/Lib/MCP/mcp-server.php +2 -3
  26. package/dist/src/Lib/Middleware/CorsMiddleware.php +72 -0
  27. package/dist/src/Lib/Websocket/ConnectionManager.php +460 -7
  28. package/dist/src/Lib/Websocket/Socket.php +170 -0
  29. package/dist/src/Lib/Websocket/SocketPool.php +50 -0
  30. package/dist/src/Lib/Websocket/SocketRegistry.php +88 -0
  31. package/dist/src/Lib/Websocket/sockets.php +50 -0
  32. package/dist/src/Lib/Websocket/websocket-server.php +10 -3
  33. package/dist/src/app/globals.css +3 -1
  34. package/dist/src/app/layout.php +1 -1
  35. package/dist/tests/AuthTest.php +59 -0
  36. package/dist/tests/ConnectionManagerTest.php +277 -0
  37. package/dist/tests/CsrfTest.php +119 -0
  38. package/dist/tests/DeferComponentRootsTest.php +147 -0
  39. package/dist/tests/FeaturesTest.php +41 -0
  40. package/dist/tests/README.md +119 -0
  41. package/dist/tests/RpcWireContractTest.php +101 -0
  42. package/dist/tests/SocketPoolTest.php +69 -0
  43. package/dist/tests/SocketRegistryTest.php +77 -0
  44. package/dist/tests/SocketTest.php +124 -0
  45. package/dist/tests/SocketsRegistrationTest.php +40 -0
  46. package/dist/tests/Support/FakeConnection.php +62 -0
  47. package/dist/tests/Support/Features.php +38 -0
  48. package/dist/tests/Support/RequiresFeature.php +26 -0
  49. package/dist/tests/bootstrap.php +44 -0
  50. package/dist/ts/main.ts +21 -3
  51. package/dist/ts/tailwind-merge.ts +13 -0
  52. package/package.json +4 -4
  53. package/dist/README.md +0 -213
  54. package/dist/public/js/pp-reactive-v2.js +0 -1
  55. package/dist/settings/bs-config.json +0 -6
  56. package/dist/settings/class-imports.ts +0 -165
  57. package/dist/settings/class-log.ts +0 -244
  58. package/dist/settings/component-import-checker.ts +0 -90
  59. package/dist/settings/files-list.json +0 -1
  60. package/dist/settings/prisma-schema-config.json +0 -16
package/dist/AGENTS.md CHANGED
@@ -2,89 +2,116 @@
2
2
 
3
3
  # Prisma PHP AI Agent Rules
4
4
 
5
- Before generating, editing, or reviewing Prisma PHP code, read the installed Prisma PHP docs for the current project version, read the project manifest, and only inspect framework internals when the docs do not answer the task.
5
+ This AGENTS.md belongs in the root of a Prisma PHP application.
6
6
 
7
- Do not guess framework behavior from Laravel, Next.js, React, Vue, Livewire, Alpine, or generic PHP habits. The installed Prisma PHP docs and the local project configuration are the source of truth.
7
+ Treat `./node_modules/prisma-php/dist/docs/index.md` as the entry point for Prisma PHP guidance, then read the matching document in `./node_modules/prisma-php/dist/docs` before generating, editing, reviewing, or documenting framework-specific behavior.
8
8
 
9
- ## Source of truth priority
9
+ Treat the installed docs as framework knowledge. They explain what Prisma PHP can do and how to do it. Do not treat the presence of a page in `./node_modules/prisma-php/dist/docs` as proof that the current app has that feature enabled.
10
10
 
11
- Use this order of truth when working in a Prisma PHP project:
11
+ Do not guess framework behavior from Laravel, Next.js, React, Vue, Livewire, Alpine, Symfony, Socket.IO, or generic PHP habits. Prisma PHP's installed docs in `./node_modules/prisma-php/dist/docs` and the current project files are the source of truth.
12
12
 
13
- 1. The user’s explicit request
13
+ If `.github/instructions/**/*.instructions.md` exists, treat those files as workspace-local task instructions. Inspect `.github/instructions/` before deciding how to implement the task, then read any instruction files whose name, described scope, target files, or library focus matches the current work, such as PHPXUI or `ppicons`.
14
+
15
+ ## Documentation source of truth
16
+
17
+ For Prisma PHP projects, use this order first:
18
+
19
+ 1. the user's explicit request
14
20
  2. `./prisma-php.json`
15
- 3. Installed Prisma PHP docs in `node_modules/prisma-php/dist/docs`
16
- 4. Project-local conventions and existing project files
17
- 5. Prisma PHP core internals in `vendor/tsnc/prisma-php/src`
18
- 6. General framework knowledge
21
+ 3. the relevant `.github/instructions/**/*.instructions.md` files for the current task, library, or target files
22
+ 4. the relevant installed document in `./node_modules/prisma-php/dist/docs`
23
+ 5. `./AGENTS.md`
24
+ 6. project-local conventions and existing app files
25
+ 7. Prisma PHP core internals in `vendor/tsnc/prisma-php/src` only when the docs still leave a gap
26
+ 8. general framework knowledge as the last fallback
19
27
 
20
- If a documented Prisma PHP rule conflicts with a habit from another framework, follow Prisma PHP.
28
+ Important rules:
29
+
30
+ - use `./prisma-php.json` as the single source of truth for current-project feature flags and framework-managed scaffolds
31
+ - if `.github/instructions/**/*.instructions.md` exists, inspect `.github/instructions/` and read the files that match the current task, named library, or target files before generating code
32
+ - treat `.github/instructions/**/*.instructions.md` as workspace-local guidance for third-party libraries, design systems, icon packs, and other implementation-specific rules
33
+ - treat `./node_modules/prisma-php/dist/docs` as the single documentation source of truth for the installed Prisma PHP version
34
+ - treat the docs inventory as a framework reference set for AI routing, not as a statement that every optional Prisma PHP feature is enabled in the current app
35
+ - expect `./AGENTS.md` at the project root
36
+ - when the installed docs and a habit from another framework conflict, follow Prisma PHP
37
+ - when a workspace instruction file and the general Prisma PHP docs both apply, follow both; keep `./prisma-php.json` as the source of truth for feature enablement and prefer the most specific matching instruction for library- or file-scoped implementation details
38
+ - in consumer apps, use `./node_modules/prisma-php/dist/docs` as the installed docs location; do not assume a root-level `./dist/docs` directory exists
39
+ - when updating Prisma PHP package/docs sources in the Prisma PHP package source repo, keep the source-repo `AGENTS.md` and source-repo `dist/docs` aligned; if that repo also maintains `.github/copilot-instructions.md` or `.github/instructions/**/*.instructions.md`, keep those source-repo files aligned there too
40
+
41
+ ## Runtime lookup for AI
42
+
43
+ Use this map only after `prisma-php.json`, matching workspace instructions, installed docs, and current project files do not answer the task.
44
+
45
+ | Need to verify | Runtime/source file |
46
+ | --- | --- |
47
+ | route root scoping, HTML fragment parsing, component tag compilation, prop casing | `vendor/tsnc/prisma-php/src/PHPX/TemplateCompiler.php` |
48
+ | PHPX class composition, `getMergeClasses(...)`, and frontend `twMerge(...)` expression generation | `vendor/tsnc/prisma-php/src/PHPX/PHPX.php`, `vendor/tsnc/prisma-php/src/PHPX/TwMerge.php` |
49
+ | imported PHP partial execution, one-root enforcement, prop serialization, imported `#[Exposed]` functions | `vendor/tsnc/prisma-php/src/ImportComponent.php` |
50
+ | metadata, custom head tags, dynamic head/footer scripts | `vendor/tsnc/prisma-php/src/MainLayout.php` |
51
+ | route and component maps | `vendor/tsnc/prisma-php/src/PrismaPHPSettings.php`, `settings/files-list.json`, `settings/component-map.json` |
52
+ | request data, dynamic params, redirects, RPC/navigation wire detection (`$isRpc`, `$isNavigation`, `$isWire`) | `vendor/tsnc/prisma-php/src/Request.php` |
53
+ | CSRF cookie family (`pp_csrf`, `pp_csrf_<port>`), token issuing and validation | `vendor/tsnc/prisma-php/src/Security/Csrf.php` |
54
+ | exposed functions | `vendor/tsnc/prisma-php/src/Attributes/Exposed.php`, `vendor/tsnc/prisma-php/src/Attributes/ExposedRegistry.php` |
55
+ | validation | `vendor/tsnc/prisma-php/src/Validator.php`, `vendor/tsnc/prisma-php/src/Rule.php` |
56
+ | env values | `vendor/tsnc/prisma-php/src/Env.php` |
57
+ | uploads, email, streaming | `vendor/tsnc/prisma-php/src/FileManager/UploadFile.php`, `vendor/tsnc/prisma-php/src/PHPMailer/Mailer.php`, `vendor/tsnc/prisma-php/src/Streaming/SSE.php` |
21
58
 
22
59
  ## Installed docs location
23
60
 
24
- The installed Prisma PHP documentation for the active project lives in:
61
+ In Prisma PHP applications, the installed docs live in:
25
62
 
26
63
  ```txt
27
64
  node_modules/prisma-php/dist/docs
28
65
  ```
29
66
 
30
- AI agents must treat this directory as the primary documentation source for Prisma PHP behavior, routing, file conventions, features, helpers, and usage patterns for the installed version.
31
-
32
- Before writing framework-specific code, inspect the relevant documentation files in this directory.
33
-
34
- ## Read `prisma-php.json` first
35
-
36
- Before generating code or making framework decisions, read:
67
+ The current docs entry point for the installed version is:
37
68
 
38
69
  ```txt
39
- ./prisma-php.json
70
+ node_modules/prisma-php/dist/docs/index.md
40
71
  ```
41
72
 
42
- Treat it as the capability manifest for the current app.
43
-
44
- Use it to verify whether the project has features such as:
73
+ The project root should also include:
45
74
 
46
- - `tailwindcss`
47
- - `backendOnly`
48
- - `swaggerDocs`
49
- - `websocket`
50
- - `mcp`
51
- - `prisma`
52
- - `typescript`
75
+ ```txt
76
+ AGENTS.md
77
+ ```
53
78
 
54
- Also use it to confirm environment-specific project details such as:
79
+ When present, task-scoped workspace instructions live in:
55
80
 
56
- - project root path
57
- - PHP executable path
58
- - BrowserSync target and path rewrite rules
59
- - component scan directories
60
- - excluded files
81
+ ```txt
82
+ .github/instructions
83
+ ```
61
84
 
62
- Do not assume a feature is enabled unless it is present and enabled in `prisma-php.json`.
85
+ ## Required doc-routing map
63
86
 
64
- ## Framework-managed generated files
87
+ Before generating code, examples, instructions, or reviews, choose the documentation file based on the task.
65
88
 
66
- Prisma PHP automatically generates and maintains certain framework files.
89
+ Use the docs router to learn how Prisma PHP implements a task. Use `./prisma-php.json` to decide whether the current app enables the relevant optional feature. When `.github/instructions/` exists, inspect that directory first and read any `*.instructions.md` files that match the task before routing into the Prisma PHP docs.
67
90
 
68
- ### `files-list.json`
91
+ ### Read workspace instruction files first for these tasks
69
92
 
70
- Do **not** create, edit, reorder, or manually maintain `files-list.json`.
93
+ - **Third-party UI, icon, component, or design-system work such as PHPXUI, `ppicons`, or similar workspace-specific integrations**
94
+ Read the matching `.github/instructions/**/*.instructions.md` file first
71
95
 
72
- Treat `files-list.json` as a **framework-generated file** for route discovery and internal bookkeeping. When creating, renaming, or removing routes, make the change in the actual route folders and route files under `src/app` and let Prisma PHP regenerate `files-list.json` automatically.
96
+ - **Tasks that target files, folders, or conventions covered by a workspace instruction file**
97
+ Read the most specific matching `.github/instructions/**/*.instructions.md` file first
73
98
 
74
- If a route task appears to require editing `files-list.json`, that is almost certainly the wrong approach. The correct workflow is:
99
+ - **Library-specific refactors, reviews, or implementations where the workspace provides a dedicated instruction file**
100
+ Read that instruction file first, then read the matching Prisma PHP docs page for framework behavior
75
101
 
76
- 1. create or update the route folder/file in `src/app`
77
- 2. do **not** touch `files-list.json`
78
- 3. let Prisma PHP regenerate framework-managed route metadata
102
+ ### Read these docs first for these tasks
79
103
 
80
- ## Required doc-routing map
104
+ - **Framework orientation, repo-wide guidance, or the high-level AI quick start**
105
+ Read `index.md`
81
106
 
82
- Before generating code, choose the documentation file based on the task.
107
+ - **Project setup, folder placement, route file choice, feature placement, or overall file conventions**
108
+ Read `project-structure.md`
83
109
 
84
- ### Read these docs first for these tasks
110
+ - **CLI project creation, starter kits, feature flags, or `npx pp update project` usage**
111
+ Read `commands.md`
85
112
 
86
- - **Project setup, folder placement, route file choice, or overall file conventions**
87
- Read `project-structure.md`
113
+ - **Backend-only Prisma PHP usage, API-first projects, `backendOnly`, separate frontend consumers, or CORS setup for API routes**
114
+ Read `backend-only.md`
88
115
 
89
116
  - **Creating a page, layout, nested route, dynamic route, or normal UI route**
90
117
  Read `layouts-and-pages.md`
@@ -92,15 +119,45 @@ Before generating code, choose the documentation file based on the task.
92
119
  - **Creating, editing, composing, or reviewing PHPX components, props, children, fragments, icons, buttons, accordions, or component file placement**
93
120
  Read `components.md`
94
121
 
95
- - **File uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename flows, delete flows, allowed file types, upload size rules, or file manager UI behavior**
96
- Read `file-manager.md`, then verify the official File Manager docs at `get-started-file`
122
+ - **Tailwind utility class composition, `getMergeClasses(...)`, `PP\PHPX\TwMerge`, or frontend `twMerge(...)` usage**
123
+ Confirm `tailwindcss` in `prisma-php.json`, then read `components.md` for PHPX emission, `typescript.md` for app-level helper registration, and `layouts-and-pages.md` for route examples
97
124
 
98
- - **Authentication strategy, `AuthConfig.php`, route privacy model, sign-in, sign-out, JWT session lifecycle, `refreshUserSession`, RBAC, credentials auth, OAuth, social login, or auth state manager usage**
99
- Read `authentication.md`, then verify the matching official docs in this order: `auth-get-started`, `credentials`, and `state-manager-auth`
125
+ - **TypeScript frontend tooling, the `typescript` feature flag, the root `ts/` directory, `ts/main.ts`, npm packages, or registered browser helpers used from template expressions and PulsePoint scripts**
126
+ Read `typescript.md`, then use `pulsepoint.md`, `layouts-and-pages.md`, or `components.md` for the affected component boundary
100
127
 
101
- - **Loading data, calling backend logic from the frontend, `pp.fetchFunction(...)`, `#[Exposed]`, or interactive backend validation**
128
+ - **Loading data, calling backend logic from the frontend, `pp.rpc(...)`, `#[Exposed]`, route-local mutations, streaming responses, or interactive backend validation**
102
129
  Read `fetching-data.md`
103
130
 
131
+ - **AI integration, provider SDKs, chat UIs, streamed assistant output, or deciding between page-local assistant UI, websocket, and MCP tools**
132
+ Read `get-started-ia.md`, then use `fetching-data.md`, `validator.md`, `websocket.md`, or `mcp.md` as needed
133
+
134
+ - **PulsePoint runtime behavior such as `pp.state`, `pp.effect`, `pp-for`, `pp-spread`, `pp-style`, `pp-ref`, context, portals, controlled form values, or keyed diffing**
135
+ Read `pulsepoint.md`
136
+
137
+ - **Validation, sanitization, `PP\Validator`, `PP\Rule`, field validation, form validation, live validation, or request validation rules**
138
+ Read `validator.md`, then apply the relevant local guidance from `fetching-data.md`, `error-handling.md`, and `route-handlers.md`
139
+
140
+ - **Environment variables, `.env`, `PP\Env`, `Env::get`, `Env::string`, `Env::bool`, `Env::int`, feature flags, host and port config, or runtime bootstrap settings**
141
+ Read `env.md`, then verify the official env docs at `env` and `env-file`
142
+
143
+ - **Bootstrap flow, request initialization, `FUNCTION_CALL_SECRET`, `pp_csrf`, route resolution, or runtime init order**
144
+ Read `bootstrap-runtime.md`, then use `env.md`, `fetching-data.md`, or `error-handling.md` as needed
145
+
146
+ - **File uploads, `multipart/form-data`, `$_FILES`, `PP\FileManager\UploadFile`, rename flows, replace flows, delete flows, allowed file types, upload size rules, or file manager UI behavior**
147
+ Read `file-manager.md`, then verify the official File Manager docs and, when internals matter, the core upload file at `vendor/tsnc/prisma-php/src/FileManager/UploadFile.php`
148
+
149
+ - **SMTP setup, `.env` mail variables, `PP\PHPMailer\Mailer`, HTML bodies, plain-text bodies, recipients, reply-to, CC, BCC, or attachments**
150
+ Read `email.md`, then verify the official email docs at `email-get-started`
151
+
152
+ - **Named sockets, `pp.socket(...)`, `SocketRegistry`, `Socket`, `SocketPool`, the Ratchet socket server, or realtime route behavior**
153
+ Read `websocket.md`, then verify the official websocket docs in this order: `websocket-get-started`, `websocket-chat-app`
154
+
155
+ - **MCP support, `#[McpTool]`, `#[Schema]`, `PhpMcp\Server\Server`, `StreamableHttpServerTransport`, AI tool endpoints, or `src/Lib/MCP/mcp-server.php`**
156
+ Read `mcp.md`, then verify the official MCP docs in this order: `prisma-php-ai-mcp`, `ai-tools`
157
+
158
+ - **Authentication strategy, `AuthConfig.php`, route privacy model, sign-in, sign-out, JWT session lifecycle, `refreshUserSession`, RBAC, credentials auth, OAuth, social login, or auth state manager usage**
159
+ Read `authentication.md`, then verify the matching official docs in this order: `auth-get-started`, `credentials`, `state-manager-auth`
160
+
104
161
  - **Cache behavior, route caching, invalidation, or `CacheHandler`**
105
162
  Read `caching.md`
106
163
 
@@ -110,17 +167,17 @@ Before generating code, choose the documentation file based on the task.
110
167
  - **Expected errors, uncaught exceptions, `error.php`, `not-found.php`, `ErrorHandler`, or validation failures as expected errors**
111
168
  Read `error-handling.md`
112
169
 
113
- - **Metadata, title, description, head scripts, favicon, icon, or `MainLayout` metadata behavior**
170
+ - **Metadata, title, description, custom head tags, favicon, icon, apple icon, or `MainLayout` metadata behavior**
114
171
  Read `metadata-and-og-images.md`
115
172
 
116
- - **API-style routes, JSON responses, handlers, form-processing endpoints, `route.php`, or request validation in handlers**
173
+ - **API-style routes, JSON responses, handlers, webhooks, form-processing endpoints, `route.php`, or request validation in handlers**
117
174
  Read `route-handlers.md`
118
175
 
119
- - **PulsePoint runtime behavior such as `pp.state`, `pp.effect`, `pp.ref`, `pp-for`, `pp-spread`, or `pp-ref`**
120
- Read `pulsepoint.md`
176
+ - **Swagger or OpenAPI generation, `swaggerDocs`, generated per-model swagger docs, `create-swagger-docs`, or `settings/prisma-schema-config.json`**
177
+ Read `swagger-docs.md`
121
178
 
122
- - **Sanitization, `PP\Validator`, `PP\Rule`, field validation, form validation, live validation, or backend validation rules**
123
- Read the official Validator docs at `https://prismaphp.tsnc.tech/docs/php-validator`, then apply the relevant local guidance from `fetching-data.md`, `error-handling.md`, and `route-handlers.md`
179
+ - **Writing or running app tests, PHPUnit, the root `tests/` directory, `npm run test`, or verifying a change with the test suite**
180
+ Read `testing.md`, then the project's `tests/README.md`
124
181
 
125
182
  - **Upgrading Prisma PHP, enabling features, syncing framework-managed project files, or running project updates**
126
183
  Read `upgrading.md`
@@ -128,20 +185,151 @@ Before generating code, choose the documentation file based on the task.
128
185
  - **First-time project installation or app creation flow**
129
186
  Read `installation.md`
130
187
 
131
- - **General doc entry point and framework orientation**
132
- Read `index.md`
188
+ ## Framework docs inventory in this repo
189
+
190
+ The current Prisma PHP docs shipped here include:
191
+
192
+ - `authentication.md`
193
+ - `backend-only.md`
194
+ - `bootstrap-runtime.md`
195
+ - `caching.md`
196
+ - `commands.md`
197
+ - `components.md`
198
+ - `email.md`
199
+ - `env.md`
200
+ - `error-handling.md`
201
+ - `fetching-data.md`
202
+ - `file-manager.md`
203
+ - `get-started-ia.md`
204
+ - `index.md`
205
+ - `installation.md`
206
+ - `layouts-and-pages.md`
207
+ - `mcp.md`
208
+ - `metadata-and-og-images.md`
209
+ - `prisma-php-orm.md`
210
+ - `project-structure.md`
211
+ - `pulsepoint.md`
212
+ - `route-handlers.md`
213
+ - `swagger-docs.md`
214
+ - `testing.md`
215
+ - `typescript.md`
216
+ - `upgrading.md`
217
+ - `validator.md`
218
+ - `websocket.md`
219
+
220
+ This inventory exists to help AI find the right Prisma PHP guidance quickly. It is not a feature inventory for the current app.
221
+
222
+ When a task depends on optional capabilities such as `backendOnly`, `swaggerDocs`, `typescript`, `websocket`, or `mcp`, inspect `./prisma-php.json` before assuming the generated scaffold exists.
223
+
224
+ When adding or reviewing AI guidance, do not stop at older docs only. Make sure the guidance also covers `backend-only.md`, `email.md`, `env.md`, `get-started-ia.md`, `mcp.md`, `swagger-docs.md`, `typescript.md`, and `websocket.md`, plus newer behavior documented in `fetching-data.md`, `metadata-and-og-images.md`, and `testing.md`.
225
+
226
+ ## Framework-generated files
227
+
228
+ Prisma PHP automatically generates and maintains certain framework files in consumer apps.
229
+
230
+ ### `files-list.json`
231
+
232
+ Do **not** create, edit, reorder, or manually maintain `files-list.json`.
233
+
234
+ Treat `files-list.json` as a framework-generated file for route discovery and internal bookkeeping. When creating, renaming, or removing routes in a Prisma PHP app, make the change in the actual route folders and route files under `src/app` and let Prisma PHP regenerate `files-list.json` automatically.
235
+
236
+ If a route task appears to require editing `files-list.json`, that is almost certainly the wrong approach.
237
+
238
+ ## Reusable project organization
239
+
240
+ When organizing a growing Prisma PHP app, keep route code and reusable code separated.
241
+
242
+ - keep `src/app` focused on the route tree, route-local layouts, pages, handlers, and route-scoped partials
243
+ - prefer `src/Components` for reusable application UI components shared across multiple routes or layouts
244
+ - keep reusable non-UI code such as services, auth, middleware, Prisma classes, and helper libraries in `src/Lib`
245
+ - treat route-private folders such as `src/app/<route>/_components` as an implementation detail for files that stay owned by that route only
246
+ - treat generated libraries such as `src/Lib/PHPXUI` and `src/Lib/PPIcons` as library-specific surfaces governed by their manifests and matching `.github/instructions/**/*.instructions.md` files
247
+ - if a partial starts in `src/app` but becomes shared across the app, promote it into `src/Components`
248
+ - do **not** default to creating `src/app/<route>/_components` for app-owned section components such as `HeroSection`, `FormSection`, or `SidebarSection`; prefer `src/Components` unless the user explicitly wants route-local colocation and the files are truly private to that route
249
+ - do **not** default to placing app-wide reusable components under `src/app` unless the user explicitly wants route-local colocation
250
+
251
+ ## HTML-first component tag contract
252
+
253
+ Class-based PHPX components and generated icon components are consumed with HTML-first `x-` tags from `settings/component-map.json`, such as `<x-alert>` and `<x-search />`.
133
254
 
134
- ## Default interactive UI and fetching rule
255
+ Important rules:
256
+
257
+ - use the `tagName` entries in `settings/component-map.json` as the supported runtime contract
258
+ - inspect `settings/component-map.json` instead of inventing `x-` tag names from PHP class names
259
+ - document, review, and generate component and icon markup with the current `x-` tag shape
260
+ - keep examples aligned with the current runtime instead of carrying alternate tag-shape guidance
261
+
262
+ ## Component attribute and prop contract
263
+
264
+ Component attributes in Prisma PHP template markup should be authored in kebab-case. The runtime maps kebab-case attribute names to camelCase prop and public property names when hydrating PHPX components and PulsePoint component boundaries.
265
+
266
+ Examples:
267
+
268
+ ```html
269
+ <x-button as-child="true" />
270
+ <x-dialog-content close-on-escape-key="true" />
271
+ <x-calendar selected-date="{selectedDate}" on-date-select="{setSelectedDate}" />
272
+ ```
273
+
274
+ Important rules:
275
+
276
+ - use kebab-case for component attribute names in documentation, examples, reviews, and generated code
277
+ - expect `as-child` to hydrate `asChild`, `close-on-escape-key` to hydrate `closeOnEscapeKey`, and `selected-date` to hydrate `selectedDate`
278
+ - use mustache values such as `selected-date="{selectedDate}"` and `on-date-select="{setSelectedDate}"` when a component prop must receive PulsePoint state or callbacks
279
+ - write component examples as HTML-first Prisma PHP markup using the current `x-` tag contract
280
+ - do not document component props with camelCase template attributes when writing new Prisma PHP markup
281
+
282
+ ## Framework-managed package scripts
283
+
284
+ Prisma PHP can generate `package.json` scripts for BrowserSync, Tailwind, TypeScript, WebSocket, MCP, Swagger docs, and related project helpers.
285
+
286
+ AI agents should follow this default rule:
287
+
288
+ - prefer `npm run dev` for ordinary local development
289
+ - prefer `npm run build` for ordinary production-style asset builds
290
+ - do **not** default to telling users to run `npm run tailwind`, `npm run tailwind:build`, `npm run ts:watch`, or `npm run ts:build` after routine file changes, because those are usually framework-managed through the generated top-level scripts
291
+ - use `npm run websocket` or `npm run mcp` only when isolating local runtime startup, debugging, or when the project's scripts show those services are not already covered by the normal development flow
292
+ - use `npm run create-swagger-docs` only when Swagger or OpenAPI output must be intentionally generated or refreshed
293
+
294
+ When a task involves package scripts, read `commands.md` first and inspect the current `package.json` before assuming which feature scripts exist.
295
+
296
+ ## BrowserSync URL source of truth
297
+
298
+ When AI needs to test or confirm whether a page route, exposed function request, proxy-backed response, or local server workflow is working, check `./settings/bs-config.json` first.
299
+
300
+ Important rules:
301
+
302
+ - use `./settings/bs-config.json` as the source of truth for the active BrowserSync URLs in this app
303
+ - do **not** assume the proxy remains on the default `http://localhost:5090`; if that port is already in use, Prisma PHP may use a different port
304
+ - confirm the current `local`, `external`, `ui`, and `uiExternal` values in `./settings/bs-config.json` before suggesting a browser URL, route test URL, or BrowserSync UI URL
305
+ - when frontend console logs, network errors, or terminal output suggest the app is being tested through the wrong URL or proxy port, re-check `./settings/bs-config.json` before changing app code
306
+
307
+ ## CLI command alignment
308
+
309
+ When a task involves Prisma PHP CLI usage, keep the command guidance aligned with `commands.md`.
310
+
311
+ - for new apps, prefer `npx create-prisma-php-app <project-name>` as the default recommended create command
312
+ - for existing apps, prefer `npx pp update project` after saving feature changes in `prisma-php.json`
313
+ - when an existing app needs a specific release channel or pinned update version, prefer `npx pp update project --tag <value>` or `npx pp update project --tag=<value>`
314
+ - use `--tag <value>` or `--tag=<value>` for release-channel or pinned-version updates
315
+ - do **not** use `npx pp update project` as a substitute for Prisma ORM migration commands
316
+
317
+ ## Default interactive UI and data-flow rule
135
318
 
136
- For normal full-stack Prisma PHP work, assume the user wants the **PulsePoint-first** approach unless they explicitly ask otherwise.
319
+ For normal full-stack Prisma PHP work, assume the user wants the PulsePoint-first approach unless they explicitly ask otherwise.
320
+
321
+ PulsePoint is the primary JavaScript authoring model for frontend work in Prisma PHP. For normal page behavior, keep the client logic inside a plain inline `<script>` within the route or imported-partial root, let Prisma PHP scope and execute it, and prefer `pp.rpc(...)` over ad hoc endpoints.
137
322
 
138
323
  Default interaction stack:
139
324
 
140
325
  1. render route UI with `index.php`
141
- 2. keep browser-side interactivity in **PulsePoint**
142
- 3. call backend PHP from the frontend with **`pp.fetchFunction(...)`**
143
- 4. mark callable PHP functions or methods with **`#[Exposed]`**
144
- 5. validate and normalize input on the PHP side with **`PP\Validator`**
326
+ 2. keep browser-side interactivity in PulsePoint
327
+ 3. call backend PHP from the frontend with `pp.rpc(...)`
328
+ 4. mark callable PHP functions or methods with `#[Exposed]`
329
+ 5. validate and normalize input on the PHP side with `PP\Validator`
330
+ 6. use `pp.socket(...)` (named sockets) only when the flow is genuinely long-lived and bidirectional — chat, presence, live feeds
331
+
332
+ `pp.rpc(...)` is the runtime RPC API. Framework-level RPC failures (unknown function, auth, roles, CSRF, origin, rate limit, server error) arrive as HTTP error statuses with an `{"error": "..."}` body and **reject** the `pp.rpc(...)` promise, so wrap calls in `try/catch` when the UI reacts to failures. Routine, expected validation feedback should still be returned as structured data (`success`, `errors`, normalized values), not thrown.
145
333
 
146
334
  Treat this as the default for:
147
335
 
@@ -154,54 +342,183 @@ Treat this as the default for:
154
342
  - inline validation
155
343
  - route-local CRUD actions
156
344
  - dashboard interactions
345
+ - streaming assistants
346
+ - progress logs
157
347
  - similar reactive page behavior
158
348
 
159
349
  Do **not** default to:
160
350
 
161
351
  - a PHP-only interaction style
352
+ - plain browser-DOM wiring when PulsePoint state, bindings, and native `on*` handlers already fit the task
162
353
  - ad hoc `fetch('/api/...')` patterns
163
- - extra `route.php` files for page-local interactions that already fit `pp.fetchFunction(...)`
354
+ - extra `route.php` files for page-local interactions that already fit `pp.rpc(...)`
355
+ - a separate Node realtime or tool server when the documented Prisma PHP runtime already fits the task
164
356
 
165
- Choose a more PHP-only pattern only when:
357
+ Choose a more PHP-only or handler-only pattern only when:
166
358
 
167
- - the user explicitly asks for PHP-only behavior
359
+ - the user explicitly asks for it
168
360
  - the task is clearly non-reactive
169
361
  - the task is a standalone API, webhook, integration endpoint, or public JSON handler
170
362
 
171
- ## Default workflow for AI agents
363
+ ## Route structure rule AI must not get wrong
364
+
365
+ There are two related structure rules, and AI must not mix their responsibilities.
366
+
367
+ ### Normal route files such as `index.php` and nested `layout.php`
368
+
369
+ Use this pattern:
370
+
371
+ 1. PHP first
372
+ 2. one parent HTML element as the route boundary
373
+ 3. place the visible page or layout content inside that boundary
374
+ 4. when PulsePoint is present, let Prisma PHP inject the route or layout `pp-component` scope on that root automatically
375
+ 5. keep one `<script>` block as the last child of that boundary root
376
+
377
+ Also follow these route-file rules:
378
+
379
+ - `index.php` and nested `layout.php` must render a single parent HTML element
380
+ - use that single parent element as the route boundary; if the visible content should stay inside a semantic element such as `<main>`, `<section>`, or `<article>`, wrap it in a neutral parent such as `<div>`
381
+ - for normal pages and nested layouts, do **not** manually author `pp-component` on that root; Prisma PHP adds it automatically
382
+ - author a plain `<script>` tag inside that root when PulsePoint logic is needed and do **not** put any `type` attribute on it — the runtime only recognizes untyped component scripts
383
+ - keep the `<script>` as the last child of the route boundary, usually as a sibling of the visible content container instead of nesting it inside the semantic content element by default
384
+ - do **not** leave the `<script>` outside the route boundary
385
+ - write PulsePoint state, derived values, and functions directly at the top level of that script; do **not** wrap them in `DOMContentLoaded`, an IIFE, manual `pp.mount()` calls, or custom scoping helpers
386
+ - only the root `layout.php` should define `<html>`, `<head>`, and `<body>`
387
+ - when PulsePoint is present in a root `layout.php`, keep `MainLayout::$children` and any `<script>` inside one clear wrapper
388
+
389
+ Example:
390
+
391
+ ```php
392
+ <?php
393
+
394
+ use PP\MainLayout;
172
395
 
173
- Use this workflow unless the user asks for something narrower:
396
+ MainLayout::$title = 'Todos';
397
+ MainLayout::$description = 'Track tasks and view the current item count.';
398
+ ?>
399
+
400
+ <div>
401
+ <section>
402
+ <h1>Todos</h1>
403
+ <p>Count: {count}</p>
404
+ </section>
405
+
406
+ <script>
407
+ const [count, setCount] = pp.state(0);
408
+ </script>
409
+ </div>
410
+ ```
411
+
412
+ ### Imported partials rendered with `ImportComponent::render(...)`
413
+
414
+ Use this pattern:
415
+
416
+ 1. PHP first
417
+ 2. exactly one parent root element
418
+ 3. keep any component-local `<script>` inside that root element
419
+
420
+ Example:
421
+
422
+ ```php
423
+ <?php
424
+
425
+ // PHP code
426
+
427
+ ?>
428
+
429
+ <div>
430
+ <h2>Search</h2>
431
+ <input value="{query}" />
432
+ <script>
433
+ console.log('Search component ready');
434
+ </script>
435
+ </div>
436
+ ```
174
437
 
175
- 1. Read `./prisma-php.json`
176
- 2. Read the relevant installed doc from `node_modules/prisma-php/dist/docs`
177
- 3. Inspect nearby project files that match the route, feature, or component being changed
178
- 4. If the task is component-related, read `components.md` before generating PHPX component code
179
- 5. If the task is upload- or file-manager-related, read `file-manager.md` before generating upload, rename, delete, or file-listing code
180
- 6. Generate code using Prisma PHP conventions
181
- 7. Inspect `vendor/tsnc/prisma-php/src` only if framework internals are required
438
+ Do not:
182
439
 
183
- Do not jump directly into framework internals if the installed docs already answer the task.
440
+ - put a sibling `<script>` next to a route root or imported partial root
441
+ - manually add `pp-component` inside imported partial source
442
+ - add any `type` attribute to route or imported-partial component scripts
443
+ - wrap imported-partial PulsePoint code in `DOMContentLoaded`, an IIFE, manual `pp.mount()` calls, or custom auto-execute helpers
444
+
445
+ ## Metadata rules
446
+
447
+ For document metadata, prefer `MainLayout::$title` and `MainLayout::$description`.
448
+
449
+ Important metadata rules:
450
+
451
+ - a local `$title` variable only affects rendered page content unless you also assign metadata through `MainLayout`
452
+ - use `MainLayout::addCustomMetadata(...)` for additional `<meta>` values when needed
453
+ - keep visible headings separate from document metadata when the UI text and SEO title must differ
454
+ - read `metadata-and-og-images.md` or `layouts-and-pages.md` before inventing Next.js-style metadata exports or Open Graph image workflows
455
+
456
+ ## Streaming and SSE rules
457
+
458
+ Prisma PHP supports streaming through `pp.rpc(...)` when an exposed function yields values.
459
+
460
+ Default streaming rules:
461
+
462
+ - prefer an exposed generator that simply yields strings or arrays
463
+ - let Prisma PHP handle the SSE response automatically for normal `pp.rpc(...)` streaming
464
+ - on the client, put stream UI updates in `onStream`, `onStreamError`, and `onStreamComplete`
465
+ - do not wait for a final JSON payload when the response is streamed
466
+
467
+ Current parsing rules AI should know:
468
+
469
+ - Prisma PHP sends streamed payloads as SSE `data:` lines
470
+ - the built-in `pp.rpc(...)` stream parser currently forwards only `data:` lines to `onStream`
471
+ - `event:`, `id:`, and `retry:` may be emitted by low-level SSE helpers, but the built-in stream callback currently ignores them
472
+ - prefer JSON values or single-line strings for streamed chunks instead of multi-line text blobs
473
+
474
+ Low-level helpers exist when manual SSE control is required:
475
+
476
+ - `PP\Streaming\SSE`
477
+ - `PP\Streaming\ServerSentEvent`
478
+
479
+ Core locations documented for those helpers are:
480
+
481
+ ```txt
482
+ vendor/tsnc/prisma-php/src/Streaming/SSE.php
483
+ vendor/tsnc/prisma-php/src/Streaming/ServerSentEvent.php
484
+ ```
184
485
 
185
486
  ## Route file decision rules
186
487
 
187
488
  When the task is about creating or editing a route, do not guess.
188
489
 
189
- Important: creating a route means creating or updating the correct folder and route file under `src/app`. It does **not** mean editing generated route metadata. In particular, never update `files-list.json` by hand.
490
+ Important: creating a route means creating or updating the correct folder and route file under `src/app`. It does **not** mean editing generated route metadata.
491
+
492
+ - use `index.php` for rendered UI and normal page routes
493
+ - use `layout.php` for shared UI that wraps route subtrees
494
+ - use `route.php` for direct handlers such as JSON endpoints, API-style routes, AJAX handlers, form-processing endpoints, and webhooks
495
+ - use `not-found.php` for route-specific not-found UI
496
+ - use `error.php` for route or app-level error UI
497
+ - use `loading.php` when the task is specifically about a loading UI state for a route subtree
190
498
 
191
- - Use `index.php` for rendered UI and normal page routes, and default to PulsePoint plus `pp.fetchFunction(...)` for interactive behavior inside those routes unless the user explicitly asks for PHP-only behavior
192
- - Use `layout.php` for shared UI that wraps route subtrees
193
- - Use `route.php` for direct handlers such as JSON endpoints, API-style routes, AJAX handlers, form-processing endpoints, webhooks, or other no-view server logic; do not default to `route.php` for normal route-local interactions that fit PulsePoint plus `pp.fetchFunction(...)`
194
- - Use `not-found.php` for route-specific not-found UI
195
- - Use `error.php` for route or app-level error UI
499
+ For normal route-local interactivity, prefer `index.php` plus PulsePoint and `pp.rpc(...)` over inventing extra handlers.
196
500
 
197
- Also verify `backendOnly` in `prisma-php.json`:
501
+ In a consumer app, also verify `backendOnly` in `prisma-php.json`:
198
502
 
199
503
  - if `backendOnly` is `false`, normal routes should usually be implemented with `index.php`
200
504
  - if `backendOnly` is `true`, route behavior will usually center on `route.php`
201
505
 
506
+ ## Default workflow for AI agents
507
+
508
+ Use this workflow unless the user asks for something narrower.
509
+
510
+ 1. read `./prisma-php.json`
511
+ 2. inspect `.github/instructions/` and read any relevant `*.instructions.md` files when that directory exists
512
+ 3. read the relevant installed doc from `./node_modules/prisma-php/dist/docs`
513
+ 4. inspect `./AGENTS.md` for project-level Prisma PHP guidance
514
+ 5. inspect nearby project files that match the route, feature, or component being changed
515
+ 6. inspect `vendor/tsnc/prisma-php/src` only if the docs and matching workspace instructions do not answer the task
516
+
517
+ Do not jump directly into framework internals if the current docs and matching workspace instruction files already answer the task.
518
+
202
519
  ## Authentication rules
203
520
 
204
- When the task involves auth, do not guess from Laravel, NextAuth, generic JWT packages, or ad hoc middleware habits.
521
+ When the task involves auth, do not guess from Laravel, generic JWT packages, or ad hoc middleware habits.
205
522
 
206
523
  Use this auth decision flow:
207
524
 
@@ -210,15 +527,24 @@ Use this auth decision flow:
210
527
  3. inspect `src/Lib/Auth/AuthConfig.php` when present
211
528
  4. inspect the current auth-related routes under `src/app`
212
529
  5. inspect Prisma models that support auth before generating registration, login, or provider code
213
- 6. keep route protection, function protection, and session lifecycle aligned with Prisma PHP’s documented auth model
530
+ 6. keep route protection, function protection, and session lifecycle aligned with Prisma PHP's documented auth model
214
531
 
215
532
  Important auth rules:
216
533
 
534
+ - the auth classes are app-owned files under `src/Lib/Auth` in the `Lib\Auth` namespace — write `use Lib\Auth\Auth;` and `use Lib\Auth\AuthConfig;`, never `PP\Auth\...`
217
535
  - route privacy strategy is configured from `AuthConfig.php`
218
536
  - Prisma PHP supports both public-default and private-default route protection strategies
219
- - sign users in with `Auth::signIn(...)`
220
- - sign users out with `Auth::signOut(...)`
221
- - use `refreshUserSession(...)` when current-session auth payloads must be updated after role or profile changes
537
+ - Prisma PHP defaults to public routes, so keep the public-default strategy when the app will expose many public pages
538
+ - choose the route privacy strategy early, ideally before creating most routes in a new app or route subtree
539
+ - if the app will have only a few public entry points and most routes should require login, switch to the private-default strategy
540
+ - when choosing private-default routing, enable both `AuthConfig::IS_ALL_ROUTES_PRIVATE` and `AuthConfig::IS_TOKEN_AUTO_REFRESH`
541
+ - when `IS_ALL_ROUTES_PRIVATE` is `true`, keep public exceptions in `AuthConfig::$publicRoutes`; home remains public by default because it starts as `['/']`
542
+ - keep `AuthConfig::$authRoutes` public by default unless the user explicitly wants a different auth route allowlist
543
+ - there is no need to modify other Prisma PHP core files to enable private-default routing
544
+ - if `src/Lib/Auth/AuthConfig.php` was customized, protect it from future project updates by adding `./src/Lib/Auth/AuthConfig.php` to `excludeFiles` in `prisma-php.json`
545
+ - sign users in with `Auth::getInstance()->signIn(...)`
546
+ - sign users out with `Auth::getInstance()->signOut(...)`
547
+ - use `Auth::getInstance()->refreshUserSession(...)` when current-session auth payloads must be updated after role or profile changes
222
548
  - use role-based route protection in auth config for page access control
223
549
  - use `#[Exposed(allowedRoles: [...])]` for function-level access control when frontend code calls PHP directly
224
550
  - for credentials auth, model the schema first, then generate ORM classes before writing auth flows
@@ -233,7 +559,7 @@ Use this file-manager decision flow:
233
559
  1. read `file-manager.md`
234
560
  2. verify the official File Manager docs for the installed version
235
561
  3. decide whether the task belongs in a rendered page with `index.php` or a direct handler with `route.php`
236
- 4. confirm the upload destination directory is outside `src/app`
562
+ 4. use `./public/uploads` as the default local public upload directory and treat it as publicly accessible
237
563
  5. use `PP\FileManager\UploadFile` when the task matches the documented upload workflow
238
564
  6. use `PP\Validator` for non-file request values such as rename targets, labels, or filters
239
565
  7. return structured messages for expected upload failures such as invalid size, invalid type, partial upload, or missing file
@@ -243,9 +569,116 @@ Important file-manager rules:
243
569
  - do **not** omit `enctype="multipart/form-data"` on upload forms
244
570
  - do **not** forget the `[]` suffix when generating multiple-file inputs
245
571
  - do **not** place uploaded files inside `src/app`
572
+ - use `PUBLIC_PATH . '/uploads/'` or the equivalent absolute `./public/uploads` path for local public uploads
573
+ - treat files saved in `./public/uploads` as publicly accessible from the app's public web root
574
+ - keep `./settings/bs-config.ts` aligned with `const PUBLIC_IGNORE_DIRS = ["uploads"];` so local upload mutations do not trigger BrowserSync reloads
575
+ - do **not** document or generate legacy local upload destinations such as `DOCUMENT_PATH . '/uploads/'`, a project-root `/uploads`, or `src/uploads`
246
576
  - do **not** assume HTML size hints replace `php.ini` upload limits
247
577
  - do **not** invent undocumented storage abstractions when `UploadFile` already fits the task
248
- - for upload, rename, replace, delete, and file-listing tasks, read `file-manager.md` first
578
+
579
+ ## Email rules
580
+
581
+ When the task involves email, read `email.md` first.
582
+
583
+ Prisma PHP email follows the documented `PP\PHPMailer\Mailer` model backed by PHPMailer. Do not replace it with raw `mail()`, undocumented wrappers, or habits copied from another mail framework.
584
+
585
+ Use this email workflow:
586
+
587
+ 1. read `email.md`
588
+ 2. inspect `.env` for SMTP and sender values in the target app
589
+ 3. inspect the route, exposed function, or handler that sends the email
590
+ 4. inspect the HTML body or attachment source when present
591
+ 5. inspect framework internals only when the docs and current app code still leave a gap
592
+
593
+ The documented core mailer file is:
594
+
595
+ ```txt
596
+ vendor/tsnc/prisma-php/src/PHPMailer/Mailer.php
597
+ ```
598
+
599
+ Important email rules:
600
+
601
+ - keep SMTP credentials and sender defaults in `.env`, not in route files
602
+ - the documented env vars are `SMTP_HOST`, `SMTP_USERNAME`, `SMTP_PASSWORD`, `SMTP_ENCRYPTION`, `SMTP_PORT`, `MAIL_FROM`, and `MAIL_FROM_NAME`
603
+ - validate user-provided email fields before calling the mailer
604
+ - prefer the documented fluent API such as `to(...)`, `subject(...)`, `html(...)`, `text(...)`, `attach(...)`, and `send()`
605
+ - use `raw()` only when low-level PHPMailer access is genuinely needed
606
+
607
+ ## Env rules
608
+
609
+ When the task involves `.env`, `PP\Env`, feature flags, ports, host names, timezones, API keys, numeric limits, or other runtime configuration values, read `env.md` first.
610
+
611
+ Use this env workflow:
612
+
613
+ 1. read `env.md`
614
+ 2. inspect `.env` or the deployment environment when the task depends on actual values
615
+ 3. inspect the bootstrap or server entry file that loads or consumes the environment
616
+ 4. inspect the feature-specific doc such as `email.md`, `mcp.md`, `websocket.md`, `get-started-ia.md`, or `prisma-php-orm.md` when the env values belong to that feature
617
+ 5. inspect `vendor/tsnc/prisma-php/src/Env.php` only if the docs do not answer the task
618
+
619
+ Important env rules:
620
+
621
+ - prefer `PP\Env` over repeated ad hoc `getenv()` parsing in documented Prisma PHP code paths
622
+ - use `Env::string(...)`, `Env::bool(...)`, and `Env::int(...)` for typed access with defaults
623
+ - use `Env::get(...)` when raw nullable string access is actually needed
624
+ - remember that `PP\Env` reads values from `getenv()`, `$_ENV`, and `$_SERVER`; it does not parse `.env` by itself
625
+ - keep secrets and deployment-specific settings in `.env` or the real runtime environment, not hardcoded in route files or components
626
+
627
+ ## WebSocket rules
628
+
629
+ When the task involves realtime messaging, presence, live dashboards, chat, `pp.socket(...)`, or `Ratchet`, read `websocket.md` first.
630
+
631
+ Prisma PHP realtime support is built on **named sockets**: `pp.socket(name, args, handlers)` in the browser, and a Ratchet-based server under `src/Lib/Websocket` that dispatches each connection to a handler registered with `SocketRegistry`. Do not replace that default with Socket.IO, a separate Node server, raw `new WebSocket(...)` wiring, or an unrelated hosted realtime service unless the user explicitly asks for a different architecture.
632
+
633
+ Use this websocket workflow:
634
+
635
+ 1. read `websocket.md`
636
+ 2. inspect whether websocket support is enabled in `prisma-php.json` in the target app
637
+ 3. inspect `src/Lib/Websocket`, especially `sockets.php` for the registered socket names
638
+ 4. inspect the route script that calls `pp.socket(...)`
639
+ 5. inspect `settings/restart-websocket.ts` when local restart behavior matters
640
+ 6. inspect framework internals only when the docs do not answer the task
641
+
642
+ Important websocket rules:
643
+
644
+ - connect from the browser with `pp.socket(name, args, handlers)`; do **not** generate raw `new WebSocket(...)` wiring for app realtime work
645
+ - register server handlers with `SocketRegistry::register(...)` in `src/Lib/Websocket/sockets.php`; socket names are unique application-wide
646
+ - do not put socket handlers in route files — route files are not loaded by the socket server process
647
+ - keep the wire contract intact: one endpoint (`/__pulsepoint/ws`), the function named in the `name` query parameter, arguments as the connection's first JSON frame, one JSON value per frame in either direction, and `{"error": "..."}` (that key alone) reserved for failures
648
+ - use `src/Lib/Websocket/websocket-server.php` as the source of truth for startup behavior
649
+ - use `src/Lib/Websocket/ConnectionManager.php` as the wire and lifecycle boundary (handshake security, argument frame, dispatch, limits)
650
+ - use `SocketPool` for broadcasts; keep authenticated and guest traffic in separate pools
651
+ - declare auth with `requireAuth` / `allowedRoles` at registration; the handshake is verified against the JWT auth cookie before the handler runs
652
+ - a `Socket::send(...)` that returns `false` means the browser is gone — stop sending, it is not an error
653
+ - preserve documented env vars and defaults: `WS_NAME`, `WS_VERSION`, `WS_HOST`, `WS_PORT`, `WS_VERBOSE`, `APP_TIMEZONE`, `MAX_WEBSOCKET_CONNECTIONS`, `MAX_WEBSOCKET_MESSAGE_BYTES`, `MAX_WEBSOCKET_MESSAGES_PER_WINDOW`, `WEBSOCKET_RATE_WINDOW_SECONDS`, `WEBSOCKET_IDLE_TIMEOUT_SECONDS`, `WEBSOCKET_ALLOWED_ORIGINS`
654
+ - preserve CLI overrides through `--host=...`, `--port=...`, and `--verbose=...`
655
+ - preserve the documented casing `src/Lib/Websocket`
656
+ - in development, `settings/bs-config.ts` proxies `/__pulsepoint/ws` from the BrowserSync origin to the Ratchet server, so `pp.socket(...)` needs no `url` option; pass `url` only outside that proxy
657
+ - for existing apps, enable `websocket` in `prisma-php.json` and run `npx pp update project -y` before inventing manual scaffolding
658
+
659
+ ## MCP rules
660
+
661
+ When the task involves Model Context Protocol support, read `mcp.md` first.
662
+
663
+ Prisma PHP MCP support follows the documented `PhpMcp\Server` model with attribute-based tool discovery. Do not replace it with custom REST endpoints pretending to be MCP, hand-rolled JSON-RPC parsing, or unrelated agent abstractions when the documented Prisma PHP stack already fits the task.
664
+
665
+ Use this MCP workflow:
666
+
667
+ 1. read `mcp.md`
668
+ 2. inspect whether MCP support is enabled in `prisma-php.json` in the target app
669
+ 3. inspect `src/Lib/MCP`
670
+ 4. inspect tool classes and the services they call
671
+ 5. inspect auth, ORM, and env configuration when tools read protected or database-backed data
672
+ 6. inspect framework internals only when the docs do not answer the task
673
+
674
+ Important MCP rules:
675
+
676
+ - use `src/Lib/MCP/mcp-server.php` as the source of truth for startup behavior
677
+ - preserve attribute-based discovery with `#[McpTool]` and `#[Schema]`
678
+ - preserve the documented discovery model built around scanning the source tree instead of manually wiring every tool class by default
679
+ - preserve the documented casing `src/Lib/MCP`
680
+ - preserve documented env vars and defaults: `MCP_NAME`, `MCP_VERSION`, `MCP_HOST`, `MCP_PORT`, `MCP_PATH_PREFIX`, `MCP_JSON_RESPONSE`, `APP_TIMEZONE`
681
+ - for existing apps, enable `mcp` in `prisma-php.json` and run `npx pp update project -y` before inventing manual scaffolding
249
682
 
250
683
  ## Prisma ORM workflow rules
251
684
 
@@ -262,51 +695,59 @@ Use this ORM decision flow:
262
695
  7. after schema synchronization, run `npx ppo generate`
263
696
  8. only then write or update PHP code that depends on the generated Prisma classes
264
697
 
265
- Important rules:
698
+ Important ORM rules:
266
699
 
267
700
  - do **not** use `npx pp update project -y` as the normal fix for Prisma ORM schema changes
268
701
  - use `npx prisma migrate dev` for the normal development migration workflow
269
702
  - use `npx prisma migrate deploy` for production or CI/CD migration application
270
703
  - use `npx prisma db push` only for explicit prototyping or no-migration database sync
271
704
  - do **not** treat `npx ppo generate` as a migration step
272
- - `npx ppo generate` should run the first time generated PHP ORM classes are needed and whenever `schema.prisma` changes
273
- - if the task mentions Prisma ORM, `schema.prisma`, migrations, generated classes, SQLite, MySQL, or PostgreSQL, read `prisma-php-orm.md` first
274
705
 
275
706
  ## Validation rules
276
707
 
277
- When a task involves user input, form handling, search params, JSON payloads, `pp.fetchFunction(...)`, or `route.php` bodies, do not trust raw values.
708
+ When a task involves user input, form handling, search params, JSON payloads, `pp.rpc(...)`, `route.php` bodies, or tool parameters, do not trust raw values.
278
709
 
279
710
  Default Prisma PHP validation rules:
280
711
 
281
- - use **`PP\Validator`** as the backend validation and normalization layer
282
- - prefer the **`Rule` builder** for rule-based validation
712
+ - use `PP\Validator` as the backend validation and normalization layer
713
+ - prefer the `Rule` builder for rule-based validation
714
+ - start `Rule` builders with `Rule::required()`, `Rule::optional()`, or `Rule::make()`
715
+ - chain rule methods such as `->min(...)`, `->max(...)`, `->email()`, and `->regex(...)` on that builder instance
716
+ - do **not** generate static calls such as `Rule::max(80)`; for optional constrained fields use `Rule::optional()->max(80)` or `Rule::make()->max(80)`
283
717
  - validate in PHP even when the frontend already performs local checks
284
718
  - return structured validation results for expected failures
285
719
  - do not treat routine invalid input as an uncaught exception
286
720
  - in reactive flows, use PulsePoint for local state and `Validator` for authoritative server validation
287
721
 
722
+ When internals matter, the documented Prisma PHP core validator location is:
723
+
724
+ ```txt
725
+ vendor/tsnc/prisma-php/src/Validator.php
726
+ vendor/tsnc/prisma-php/src/Rule.php
727
+ ```
728
+
288
729
  ## PulsePoint rules
289
730
 
290
731
  When a task involves reactive frontend behavior, read `pulsepoint.md` first.
291
732
 
292
733
  Also follow these rules:
293
734
 
735
+ - treat PulsePoint as the primary JavaScript authoring model for normal full-stack frontend work
736
+ - keep page and imported-partial client logic inside the boundary's plain `<script>` tag instead of building extra DOM-ready or self-executing wrappers
737
+ - prefer `pp.rpc(...)` over ad hoc `fetch('/api/...')` calls for page-local PHP interactions
738
+ - reserve plain browser JavaScript outside PulsePoint for external libraries, low-level browser APIs, and reusable helpers in `ts/`
294
739
  - do not invent undocumented PulsePoint helpers or directives
295
740
  - do not write React, Vue, Alpine, or Livewire syntax and call it PulsePoint
296
741
  - keep backend concerns separate from PulsePoint runtime concerns
297
742
  - prefer simple documented runtime primitives over abstractions copied from other ecosystems
298
-
299
- ## Reactive frontend + server-call rule
300
-
301
- For frontend interactivity in Prisma PHP, prefer the documented Prisma PHP pattern:
302
-
303
- - use **PulsePoint** for reactive browser state and UI behavior
304
- - use **`pp.fetchFunction(...)`** for page-local or component-local server calls
305
- - expose callable PHP functions with **`#[Exposed]`**
306
-
307
- Do not default to handcrafted `fetch('/api/...')` calls, ad hoc AJAX endpoints, or extra `route.php` files when the task is a normal reactive UI interaction that fits `pp.fetchFunction(...)`.
308
-
309
- Use `route.php` when the user explicitly needs an API-style endpoint, webhook, JSON route, or handler that should exist independently of the current page.
743
+ - do not treat app-registered helpers such as `twMerge(...)` as PulsePoint built-ins; route those tasks through the Tailwind-enabled Prisma PHP docs after checking feature flags
744
+ - use `pp-style` whenever inline CSS contains `{...}` interpolation or any other template-driven/reactive value, and reserve plain `style` for fully static inline CSS
745
+ - do **not** generate reactive inline CSS inside a plain `style` attribute such as `style="width: {progress}%";` use `pp-style="width: {progress}%";` instead so source markup stays editor-friendly
746
+ - use `pp-spread="{...attrs}"` for dynamic attribute objects and omit nullish values from those objects
747
+ - use `pp-for` only on `<template>` with `item in items` or `(item, index) in items`
748
+ - use plain `key` for keyed diffing; do not invent `pp-key`
749
+ - use `pp.ref(...)`, `pp-ref`, `pp.portal(...)`, `pp.createContext(...)`, `Context.Provider`, and `pp.context(...)` according to `pulsepoint.md`
750
+ - use `value`, `defaultvalue`, and `defaultchecked` form bindings according to `pulsepoint.md`; do not author internal `data-pp-*` form attributes
310
751
 
311
752
  ## Component rules
312
753
 
@@ -315,94 +756,51 @@ When the task involves Prisma PHPX components, reusable UI elements, props, chil
315
756
  Also follow these rules:
316
757
 
317
758
  - do not assume React, Vue, Blade, or generic templating component behavior maps directly to Prisma PHPX
759
+ - use HTML-first `x-` tags such as `<x-button>` and `<x-search />` when generating template markup for class-based components
760
+ - use kebab-case component attributes and rely on the runtime to hydrate camelCase PHPX properties and PulsePoint props
318
761
  - keep component file names and class names aligned
319
762
  - preserve documented PHPX patterns for `$props`, `$children`, `$class`, and `getAttributes(...)`
763
+ - in Tailwind-enabled apps, use `getMergeClasses(...)` and `PP\PHPX\TwMerge::merge(...)` as emitters of frontend `twMerge(...)` expressions instead of finalizing Tailwind class conflicts in PHP
764
+ - when a route or imported partial needs direct Tailwind-aware class composition, treat `twMerge(...)` as an app-level browser helper available only when `tailwindcss` is enabled
320
765
  - follow documented component placement and grouping conventions before inspecting framework internals
321
- - use `vendor/tsnc/prisma-php/src` only when the installed docs and `components.md` do not answer the task
322
-
323
- ## Prisma PHP XML syntax rules
324
-
325
- Prisma PHP uses XML-style syntax for PHPX and template markup.
326
-
327
- AI agents must follow strict XML rules when generating tags and attributes.
328
-
329
- ### Closing tags
330
-
331
- All tags must be properly closed.
332
-
333
- Correct:
334
-
335
- ```xml
336
- <hr />
337
- <input type="text" />
338
- <div></div>
339
- ```
340
-
341
- Incorrect:
342
-
343
- ```xml
344
- <hr>
345
- <input type="text">
346
- ```
347
-
348
- ### Attributes
349
-
350
- All attributes must use double quotes.
351
-
352
- Correct:
353
-
354
- ```xml
355
- <input id="email" />
356
- <input required="true" />
357
- ```
358
-
359
- Incorrect:
360
-
361
- ```xml
362
- <input id=email />
363
- <input required />
364
- ```
365
-
366
- ### Boolean attributes
367
-
368
- Boolean attributes must be explicit.
369
-
370
- Correct:
371
-
372
- ```xml
373
- <input disabled="true" />
374
- <option selected="true">Admin</option>
375
- ```
376
-
377
- Incorrect:
378
-
379
- ```xml
380
- <input disabled />
381
- <option selected>Admin</option>
382
- ```
383
-
384
- Do not output permissive HTML shorthand in Prisma PHP UI files.
385
766
 
386
767
  ## When to inspect framework internals
387
768
 
388
- Prisma PHP core Composer package files live in:
769
+ Inspect framework internals only when the docs and current files do not answer the task.
770
+
771
+ Useful app-mode core locations include:
389
772
 
390
773
  ```txt
391
774
  vendor/tsnc/prisma-php/src
775
+ vendor/tsnc/prisma-php/src/PHPX/PHPX.php
776
+ vendor/tsnc/prisma-php/src/PHPX/TwMerge.php
777
+ vendor/tsnc/prisma-php/src/PHPX/TemplateCompiler.php
778
+ vendor/tsnc/prisma-php/src/ImportComponent.php
779
+ vendor/tsnc/prisma-php/src/MainLayout.php
780
+ vendor/tsnc/prisma-php/src/PrismaPHPSettings.php
781
+ vendor/tsnc/prisma-php/src/Request.php
782
+ vendor/tsnc/prisma-php/src/Attributes/Exposed.php
783
+ vendor/tsnc/prisma-php/src/Attributes/ExposedRegistry.php
784
+ vendor/tsnc/prisma-php/src/Env.php
785
+ vendor/tsnc/prisma-php/src/Rule.php
786
+ vendor/tsnc/prisma-php/src/PHPMailer/Mailer.php
787
+ vendor/tsnc/prisma-php/src/FileManager/UploadFile.php
788
+ vendor/tsnc/prisma-php/src/Validator.php
789
+ vendor/tsnc/prisma-php/src/Streaming/SSE.php
790
+ vendor/tsnc/prisma-php/src/Streaming/ServerSentEvent.php
392
791
  ```
393
792
 
394
- Inspect this directory only when the task depends on framework internals not already answered by the installed docs.
395
-
396
- Use it when the task involves:
793
+ Use framework internals when the task involves:
397
794
 
398
795
  - confirming namespaces, classes, or helper names
399
796
  - understanding how a core class behaves internally
400
- - verifying available attributes such as `#[Exposed]`
797
+ - verifying available attributes such as `#[Exposed]`, `#[McpTool]`, or `#[Schema]`
401
798
  - checking PHPX compiler or template compiler behavior
402
799
  - tracing PulsePoint integration points inside Prisma PHP
403
- - debugging framework-level issues that are not explained by the docs
800
+ - confirming mailer, SSE, websocket, or MCP runtime behavior not already clear from the docs
801
+ - debugging framework-level issues that are not explained by the current docs
404
802
 
405
- For ordinary app work, prefer the installed docs and local project files first.
803
+ For ordinary app or docs work, prefer the current docs and local project files first.
406
804
 
407
805
  ## Upgrade and feature-enable workflow
408
806
 
@@ -410,20 +808,17 @@ If the task involves enabling a feature, syncing framework-managed files, or upd
410
808
 
411
809
  Important rules:
412
810
 
413
- - update `prisma-php.json` before assuming a feature is active
811
+ - update `prisma-php.json` before assuming a feature is active in a consumer app
414
812
  - do not assume Tailwind, Prisma, Swagger, WebSocket, MCP, or TypeScript support is enabled unless `prisma-php.json` says so
813
+ - keep customized framework-managed files such as `src/Lib/Auth/AuthConfig.php` in `excludeFiles` when you need project updates to preserve them
415
814
  - after changing feature flags, follow the documented project update flow
416
- - for AI-driven or scripted updates, prefer:
417
-
418
- ```bash
419
- npx pp update project -y
420
- ```
815
+ - for AI-driven or scripted updates, prefer `npx pp update project -y`
421
816
 
422
- This command is for project updates and framework-managed file refreshes. It is not the default ORM migration command.
817
+ That command is for project updates and framework-managed file refreshes. It is not the default ORM migration command.
423
818
 
424
819
  ## Final operating rule
425
820
 
426
- When Prisma PHP behavior is documented locally, read the relevant installed doc first and follow it.
821
+ When Prisma PHP behavior is documented locally, read the relevant current doc first and follow it.
427
822
 
428
823
  Do not guess.
429
824