caspian-utils 0.0.25 → 0.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/ai-validation-checklist.md +6 -3
- package/dist/docs/cache.md +12 -5
- package/dist/docs/components.md +5 -4
- package/dist/docs/core-runtime-map.md +48 -8
- package/dist/docs/fetch-data.md +9 -7
- package/dist/docs/file-uploads.md +14 -5
- package/dist/docs/index.md +44 -15
- package/dist/docs/metadata.md +11 -3
- package/dist/docs/pulsepoint-runtime-map.md +129 -0
- package/dist/docs/pulsepoint.md +6 -3
- package/dist/docs/routing.md +7 -2
- package/dist/docs/state.md +12 -5
- package/dist/docs/validation.md +10 -3
- package/package.json +1 -1
|
@@ -58,9 +58,12 @@ Use prompts like these to check whether AI lands on the correct docs and files.
|
|
|
58
58
|
| Add a file manager page with upload progress and persisted metadata. | [index.md](./index.md), [file-uploads.md](./file-uploads.md), [fetch-data.md](./fetch-data.md), [database.md](./database.md) | `src/app/**/index.html`, `src/app/**/index.py`, `src/lib/**`, `prisma/schema.prisma` when Prisma applies | route-owned upload actions, persisted metadata flow, and Prisma-backed storage boundaries |
|
|
59
59
|
| Explain why authored Caspian templates use a plain `<script>` instead of `type="text/pp"`. | [index.md](./index.md), [pulsepoint.md](./pulsepoint.md), [components.md](./components.md), [routing.md](./routing.md) | `main.py`, `.venv/Lib/site-packages/casp/scripts_type.py`, `.venv/Lib/site-packages/casp/components_compiler.py` | script rewriting, `pp-component` injection, and authored-vs-runtime boundaries |
|
|
60
60
|
| Debug why `StateManager` does not persist across a full redirect. | [index.md](./index.md), [state.md](./state.md), [auth.md](./auth.md), [core-runtime-map.md](./core-runtime-map.md) | `main.py`, `.venv/Lib/site-packages/casp/state_manager.py` | wire vs non-wire reset behavior and `request.state.session` dependency |
|
|
61
|
-
| Trace the auth cookie and CSRF cookie names used in development. | [index.md](./index.md), [auth.md](./auth.md), [core-runtime-map.md](./core-runtime-map.md) | `main.py`, `.venv/Lib/site-packages/casp/auth.py` | development cookie scoping and CSRF or session naming ownership |
|
|
62
|
-
| Find how route params and query params reach `page()`. | [index.md](./index.md), [routing.md](./routing.md), [core-runtime-map.md](./core-runtime-map.md) | `main.py`, `.venv/Lib/site-packages/casp/layout.py` | path-dict delivery, query coercion, and `request` injection |
|
|
63
|
-
| Decide whether a dashboard child route should use page caching. | [index.md](./index.md), [cache.md](./cache.md), [routing.md](./routing.md), [fetch-data.md](./fetch-data.md) | `main.py`, `.venv/Lib/site-packages/casp/cache_handler.py`, the route's `index.py` | route-level cache ownership, cacheable HTML scope, and invalidation points |
|
|
61
|
+
| Trace the auth cookie and CSRF cookie names used in development. | [index.md](./index.md), [auth.md](./auth.md), [core-runtime-map.md](./core-runtime-map.md) | `main.py`, `.venv/Lib/site-packages/casp/auth.py` | development cookie scoping and CSRF or session naming ownership |
|
|
62
|
+
| Find how route params and query params reach `page()`. | [index.md](./index.md), [routing.md](./routing.md), [core-runtime-map.md](./core-runtime-map.md) | `main.py`, `.venv/Lib/site-packages/casp/layout.py` | path-dict delivery, query coercion, and `request` injection |
|
|
63
|
+
| Decide whether a dashboard child route should use page caching. | [index.md](./index.md), [cache.md](./cache.md), [routing.md](./routing.md), [fetch-data.md](./fetch-data.md) | `main.py`, `.venv/Lib/site-packages/casp/cache_handler.py`, the route's `index.py` | route-level cache ownership, cacheable HTML scope, and invalidation points |
|
|
64
|
+
| Add a PulsePoint context provider to a reusable component. | [index.md](./index.md), [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md), [pulsepoint.md](./pulsepoint.md), [components.md](./components.md) | `public/js/pp-reactive-v2.js`, component `.html`, `.venv/Lib/site-packages/casp/components_compiler.py` | `Context.Provider` usage, logical ancestry, single-root template shape |
|
|
65
|
+
| Add upload progress to an existing file manager. | [index.md](./index.md), [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md), [file-uploads.md](./file-uploads.md), [fetch-data.md](./fetch-data.md) | `src/app/**/index.py`, `src/app/**/index.html`, `src/lib/**`, `public/js/pp-reactive-v2.js` | `pp.rpc` upload options, state replacement, persisted metadata, BrowserSync ignore rules |
|
|
66
|
+
| Decide whether MCP files should be created. | [index.md](./index.md), [mcp.md](./mcp.md), [commands.md](./commands.md), [project-structure.md](./project-structure.md) | `caspian.config.json`, `settings/restart-mcp.ts`, `package.json`, `src/lib/mcp/**` when enabled | `mcp` feature gate, update workflow, nested FastMCP config ownership |
|
|
64
67
|
|
|
65
68
|
Treat the table as a prompt pack for spot checks, not as a full validation matrix.
|
|
66
69
|
|
package/dist/docs/cache.md
CHANGED
|
@@ -26,11 +26,18 @@ Import the API like this:
|
|
|
26
26
|
from casp.cache_handler import Cache, CacheHandler
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
The current installed implementation lives in `.venv/Lib/site-packages/casp/cache_handler.py`.
|
|
30
|
-
|
|
31
|
-
Use [core-runtime-map.md](./core-runtime-map.md) when a cache task crosses `main.py` request flow, cache lookup timing, and the installed cache-handler internals.
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
The current installed implementation lives in `.venv/Lib/site-packages/casp/cache_handler.py`.
|
|
30
|
+
|
|
31
|
+
Use [core-runtime-map.md](./core-runtime-map.md) when a cache task crosses `main.py` request flow, cache lookup timing, and the installed cache-handler internals.
|
|
32
|
+
|
|
33
|
+
## Source Of Truth
|
|
34
|
+
|
|
35
|
+
- Route cache intent belongs in `src/app/**/index.py` through module-level `cache_settings = Cache(...)`.
|
|
36
|
+
- Cache lookup and save timing are controlled by `main.py`.
|
|
37
|
+
- Disk-backed cache behavior lives in `.venv/Lib/site-packages/casp/cache_handler.py`.
|
|
38
|
+
- Cache invalidation after writes usually belongs in the owning route `@rpc()` action or a shared helper under `src/lib/**`.
|
|
39
|
+
|
|
40
|
+
The real API surface is:
|
|
34
41
|
|
|
35
42
|
- declarative route config with `Cache(ttl=..., enabled=...)`
|
|
36
43
|
- disk-backed HTML lookup with `CacheHandler.serve_cache(...)`
|
package/dist/docs/components.md
CHANGED
|
@@ -7,9 +7,10 @@ related:
|
|
|
7
7
|
links:
|
|
8
8
|
- /docs/project-structure
|
|
9
9
|
- /docs/core-runtime-map
|
|
10
|
-
- /docs/routing
|
|
11
|
-
- /docs/pulsepoint
|
|
12
|
-
- /docs/
|
|
10
|
+
- /docs/routing
|
|
11
|
+
- /docs/pulsepoint
|
|
12
|
+
- /docs/pulsepoint-runtime-map
|
|
13
|
+
- /docs/fetch-data
|
|
13
14
|
- /docs/index
|
|
14
15
|
---
|
|
15
16
|
|
|
@@ -39,7 +40,7 @@ When the task is about component internals rather than normal app-owned componen
|
|
|
39
40
|
- `.venv/Lib/site-packages/casp/html_attrs.py` owns `get_attributes(...)` and the Python-side `merge_classes(...)` contract.
|
|
40
41
|
- `.venv/Lib/site-packages/casp/syntax_compiler.py` owns Caspian template syntax transpilation before Jinja render.
|
|
41
42
|
|
|
42
|
-
Use [core-runtime-map.md](./core-runtime-map.md) when you need the broader runtime-module map.
|
|
43
|
+
Use [core-runtime-map.md](./core-runtime-map.md) when you need the broader Python runtime-module map. Use [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md) when a component task is specifically about browser-side PulsePoint state, refs, context, portals, events, RPC, or SPA behavior.
|
|
43
44
|
|
|
44
45
|
## Basic Component
|
|
45
46
|
|
|
@@ -8,9 +8,10 @@ related:
|
|
|
8
8
|
- /docs/project-structure
|
|
9
9
|
- /docs/routing
|
|
10
10
|
- /docs/auth
|
|
11
|
-
- /docs/fetch-data
|
|
12
|
-
- /docs/pulsepoint
|
|
13
|
-
- /docs/
|
|
11
|
+
- /docs/fetch-data
|
|
12
|
+
- /docs/pulsepoint
|
|
13
|
+
- /docs/pulsepoint-runtime-map
|
|
14
|
+
- /docs/index
|
|
14
15
|
---
|
|
15
16
|
|
|
16
17
|
This page maps the app entry point and the installed Caspian runtime modules to the packaged docs that explain them.
|
|
@@ -24,21 +25,60 @@ Use it when you already know a behavior is controlled by `main.py` or `.venv/Lib
|
|
|
24
25
|
- the task is about framework internals rather than normal app-owned route or component code
|
|
25
26
|
- AI needs to know which packaged doc should be kept aligned with a core-file change
|
|
26
27
|
|
|
27
|
-
## App Entry Point
|
|
28
|
+
## App Entry Point
|
|
28
29
|
|
|
29
30
|
| Concern | Core file | Read first | Why it matters |
|
|
30
31
|
| --- | --- | --- | --- |
|
|
31
32
|
| App bootstrap and request flow | [main.py](../../../../main.py) | [project-structure.md](./project-structure.md), [routing.md](./routing.md), [auth.md](./auth.md) | FastAPI app creation, static asset routes, middleware order, route registration, cache check and save, exception handlers, and final HTML transforms all live here. |
|
|
32
|
-
| Browser runtime, SPA navigation, and scroll restoration | [public/js/pp-reactive-v2.js](../../../../public/js/pp-reactive-v2.js) | [pulsepoint.md](./pulsepoint.md), [fetch-data.md](./fetch-data.md) | The shipped `pp` runtime, same-origin SPA interception, per-history-entry scroll state, `pp-reset-scroll` behavior, and browser RPC helpers live here. |
|
|
33
|
-
|
|
34
|
-
Important current `main.py` behaviors AI should keep in mind:
|
|
33
|
+
| Browser runtime, SPA navigation, and scroll restoration | [public/js/pp-reactive-v2.js](../../../../public/js/pp-reactive-v2.js) | [pulsepoint.md](./pulsepoint.md), [fetch-data.md](./fetch-data.md) | The shipped `pp` runtime, same-origin SPA interception, per-history-entry scroll state, `pp-reset-scroll` behavior, and browser RPC helpers live here. |
|
|
34
|
+
|
|
35
|
+
Important current `main.py` behaviors AI should keep in mind:
|
|
35
36
|
|
|
36
37
|
- In development, `_scoped_cookie_name(...)` appends the active BrowserSync or dev port to both the session cookie name and the CSRF cookie name. The scope is resolved from `CASPIAN_BROWSER_SYNC_PORT`, then `settings/bs-config.json`, then `PORT`.
|
|
37
38
|
- `register_single_route(...)` passes path params to `page()` as one positional dict, injects matching query params by name, and injects `request` by keyword when declared.
|
|
38
39
|
- The render pipeline is `transform_components(...)`, then `render_with_nested_layouts(...)`, then `transform_scripts(...)`.
|
|
39
40
|
- Route-level generators returned from `page()` are wrapped in `SSE(...)` before the response is sent.
|
|
40
41
|
- Middleware is added in source order as `RPCMiddleware`, `AuthMiddleware`, `CSRFMiddleware`, `SessionMiddleware`, so the effective request order is reversed at runtime.
|
|
41
|
-
- `public/js/pp-reactive-v2.js` saves scroll positions per history entry, resets window scroll on push navigation, and uses `pp-reset-scroll="true"` to opt specific containers or the whole body into reset behavior.
|
|
42
|
+
- `public/js/pp-reactive-v2.js` saves scroll positions per history entry, resets window scroll on push navigation, and uses `pp-reset-scroll="true"` to opt specific containers or the whole body into reset behavior.
|
|
43
|
+
|
|
44
|
+
## Caspian Core Feature Map
|
|
45
|
+
|
|
46
|
+
Use this table when the task names a framework feature but the owning file is not obvious yet.
|
|
47
|
+
|
|
48
|
+
| Core feature | App-owned entry points | Runtime owner | Packaged docs |
|
|
49
|
+
| --- | --- | --- | --- |
|
|
50
|
+
| Feature flags and generated surface area | `caspian.config.json` | `casp.caspian_config` | [commands.md](./commands.md), [project-structure.md](./project-structure.md) |
|
|
51
|
+
| File-based routing | `src/app/**/index.html`, `src/app/**/index.py` | `main.py`, `casp.layout`, `casp.caspian_config` | [routing.md](./routing.md) |
|
|
52
|
+
| Nested layouts | `src/app/**/layout.html`, `src/app/**/layout.py` | `casp.layout`, `main.py` | [routing.md](./routing.md), [metadata.md](./metadata.md) |
|
|
53
|
+
| Metadata | route or layout `metadata`, runtime metadata helpers | `casp.layout`, `main.py` | [metadata.md](./metadata.md), [routing.md](./routing.md) |
|
|
54
|
+
| Component imports and `x-*` tags | `src/components/**`, `src/app/**/*.html` | `casp.components_compiler`, `casp.component_decorator` | [components.md](./components.md), [routing.md](./routing.md) |
|
|
55
|
+
| Auth and route protection | `src/lib/auth/auth_config.py`, `main.py`, route decorators | `casp.auth`, `main.py` middleware | [auth.md](./auth.md) |
|
|
56
|
+
| RPC and server actions | route or component Python modules with `@rpc()` | `casp.rpc`, `main.py` middleware | [fetch-data.md](./fetch-data.md), [file-uploads.md](./file-uploads.md) |
|
|
57
|
+
| Streaming | route `page()` generators, RPC generators | `casp.streaming`, `casp.rpc`, `main.py` | [fetch-data.md](./fetch-data.md) |
|
|
58
|
+
| Server state | request handlers and RPC actions | `casp.state_manager`, `main.py` middleware | [state.md](./state.md) |
|
|
59
|
+
| Page caching | route-level `Cache(...)` declarations | `casp.cache_handler`, `main.py` cache check/save | [cache.md](./cache.md) |
|
|
60
|
+
| Validation | route and RPC input boundaries | `casp.validate` | [validation.md](./validation.md) |
|
|
61
|
+
| Tailwind class merge | Python components and PulsePoint templates | `casp.html_attrs`, browser `twMerge(...)` | [components.md](./components.md), [pulsepoint.md](./pulsepoint.md) |
|
|
62
|
+
| Prisma persistence | `prisma/**`, `src/lib/prisma/**`, route/RPC code | generated Prisma and Python clients | [database.md](./database.md), [fetch-data.md](./fetch-data.md) |
|
|
63
|
+
| MCP tools | `src/lib/mcp/**` when enabled | app-owned FastMCP server | [mcp.md](./mcp.md), [commands.md](./commands.md) |
|
|
64
|
+
|
|
65
|
+
For browser-side PulsePoint details, use [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md) instead of expanding this Python-runtime map.
|
|
66
|
+
|
|
67
|
+
## Task-To-File Examples
|
|
68
|
+
|
|
69
|
+
Protected dashboard route:
|
|
70
|
+
|
|
71
|
+
1. Check `caspian.config.json` for enabled features such as Prisma and Tailwind.
|
|
72
|
+
2. Read [routing.md](./routing.md) for the section layout shape.
|
|
73
|
+
3. Read [auth.md](./auth.md) for route privacy and decorators.
|
|
74
|
+
4. Update `src/app/dashboard/layout.html` for the shared shell and child `index.html` or `index.py` files for page-specific behavior.
|
|
75
|
+
5. Verify auth bootstrap and middleware ownership in `main.py` only if route protection behaves unexpectedly.
|
|
76
|
+
|
|
77
|
+
Interactive CRUD page:
|
|
78
|
+
|
|
79
|
+
1. Read [fetch-data.md](./fetch-data.md) for the `page()` plus `@rpc()` split.
|
|
80
|
+
2. Read [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md) for browser-side `pp.rpc(...)` behavior.
|
|
81
|
+
3. Keep first-render data in `src/app/**/index.py`, visible markup in `src/app/**/index.html`, reusable helpers in `src/lib/**`, and database schema changes in `prisma/**`.
|
|
42
82
|
|
|
43
83
|
## Installed Runtime Map
|
|
44
84
|
|
package/dist/docs/fetch-data.md
CHANGED
|
@@ -12,9 +12,10 @@ related:
|
|
|
12
12
|
- /docs/database
|
|
13
13
|
- /docs/file-uploads
|
|
14
14
|
- /docs/cache
|
|
15
|
-
- /docs/routing
|
|
16
|
-
- /docs/pulsepoint
|
|
17
|
-
- /docs/
|
|
15
|
+
- /docs/routing
|
|
16
|
+
- /docs/pulsepoint
|
|
17
|
+
- /docs/pulsepoint-runtime-map
|
|
18
|
+
- /docs/project-structure
|
|
18
19
|
- /docs/index
|
|
19
20
|
---
|
|
20
21
|
|
|
@@ -139,10 +140,11 @@ Validate incoming form and mutation payloads before persisting them. See [valida
|
|
|
139
140
|
|
|
140
141
|
If an RPC action needs transient request-scoped success or error state beyond its direct return payload, read [state.md](./state.md) and verify the current wire-request lifecycle before depending on persistence across navigations or full-page reloads.
|
|
141
142
|
|
|
142
|
-
Important:
|
|
143
|
-
|
|
144
|
-
- `pp.rpc()` posts to the current route RPC bridge.
|
|
145
|
-
- Older docs may refer to `pp.fetchFunction()`. In this repo's current runtime, the supported helper is `pp.rpc()`.
|
|
143
|
+
Important:
|
|
144
|
+
|
|
145
|
+
- `pp.rpc()` posts to the current route RPC bridge.
|
|
146
|
+
- Older docs may refer to `pp.fetchFunction()`. In this repo's current runtime, the supported helper is `pp.rpc()`.
|
|
147
|
+
- Use [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md) when debugging browser-side RPC options such as streaming, upload progress, abort behavior, redirects, or SPA interaction.
|
|
146
148
|
|
|
147
149
|
## Streaming Responses
|
|
148
150
|
|
|
@@ -16,11 +16,20 @@ related:
|
|
|
16
16
|
|
|
17
17
|
This page documents the recommended file upload and file manager pattern for Caspian projects.
|
|
18
18
|
|
|
19
|
-
Treat uploads as normal route behavior. Keep the owning browser UI in the route template, keep upload and delete `@rpc()` actions in the owning route `index.py`, and move reusable storage or persistence helpers into `src/lib/`.
|
|
20
|
-
|
|
21
|
-
If the file manager lives inside a grouped subtree such as a dashboard, account area, or admin area, apply the section layout pattern from [routing.md](./routing.md): keep the shared shell in the parent folder's `layout.html` and keep the file-manager route itself in a child folder.
|
|
22
|
-
|
|
23
|
-
##
|
|
19
|
+
Treat uploads as normal route behavior. Keep the owning browser UI in the route template, keep upload and delete `@rpc()` actions in the owning route `index.py`, and move reusable storage or persistence helpers into `src/lib/`.
|
|
20
|
+
|
|
21
|
+
If the file manager lives inside a grouped subtree such as a dashboard, account area, or admin area, apply the section layout pattern from [routing.md](./routing.md): keep the shared shell in the parent folder's `layout.html` and keep the file-manager route itself in a child folder.
|
|
22
|
+
|
|
23
|
+
## Source Of Truth
|
|
24
|
+
|
|
25
|
+
- File picker UI and upload progress state belong in `src/app/**/index.html`.
|
|
26
|
+
- Upload, delete, and list refresh actions belong in the owning `src/app/**/index.py` as `@rpc()` actions.
|
|
27
|
+
- Reusable storage, naming, and persistence helpers belong in `src/lib/**`.
|
|
28
|
+
- Durable metadata belongs in Prisma when `caspian.config.json` enables Prisma.
|
|
29
|
+
- Browser-side progress, state replacement, and `pp-for` list rendering follow [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md).
|
|
30
|
+
- BrowserSync upload ignore behavior belongs in `settings/bs-config.ts`.
|
|
31
|
+
|
|
32
|
+
## Default Pattern
|
|
24
33
|
|
|
25
34
|
- Keep first-render file manager data in `page()` so the initial HTML already contains the current asset list and storage summary.
|
|
26
35
|
- Keep upload and delete actions in the route's `index.py`; do not move ordinary upload flows into `main.py`.
|
package/dist/docs/index.md
CHANGED
|
@@ -8,8 +8,9 @@ related:
|
|
|
8
8
|
- /docs/ai-validation-checklist
|
|
9
9
|
- /docs/installation
|
|
10
10
|
- /docs/commands
|
|
11
|
-
- /docs/core-runtime-map
|
|
12
|
-
- /docs/
|
|
11
|
+
- /docs/core-runtime-map
|
|
12
|
+
- /docs/pulsepoint-runtime-map
|
|
13
|
+
- /docs/mcp
|
|
13
14
|
- /docs/file-uploads
|
|
14
15
|
- /docs/project-structure
|
|
15
16
|
- /docs/components
|
|
@@ -23,15 +24,41 @@ The docs can mention optional features even when those features are disabled in
|
|
|
23
24
|
|
|
24
25
|
Before making feature, tooling, or file-placement decisions in a Caspian project, read `./caspian.config.json` almost immediately. That file tells you which optional capabilities are enabled, such as Prisma, MCP, TypeScript, Tailwind, backend-only mode, and component scan directories.
|
|
25
26
|
|
|
26
|
-
## Default Stack
|
|
27
|
-
|
|
28
|
-
When generating or editing a Caspian app, treat these as the default choices unless the task explicitly requires something else:
|
|
27
|
+
## Default Stack
|
|
28
|
+
|
|
29
|
+
When generating or editing a Caspian app, treat these as the default choices unless the task explicitly requires something else:
|
|
29
30
|
|
|
30
31
|
- Use PulsePoint for reactive frontend behavior.
|
|
31
32
|
- Treat every authored route, layout, and component HTML file like a React component return value: exactly one top-level parent HTML element or one imported `x-*` root, with any owned plain `<script>` kept inside that same root.
|
|
32
33
|
- When `caspian.config.json` has `tailwindcss: true`, use Python `merge_classes(...)` plus browser `twMerge(...)` as the only supported Tailwind class-merging path.
|
|
33
|
-
- Use `@rpc()` plus `pp.rpc()` for browser-triggered reads, writes, streaming, and uploads.
|
|
34
|
-
- Use `Validate` and `Rule` from `casp.validate` for server-side input validation and sanitization.
|
|
34
|
+
- Use `@rpc()` plus `pp.rpc()` for browser-triggered reads, writes, streaming, and uploads.
|
|
35
|
+
- Use `Validate` and `Rule` from `casp.validate` for server-side input validation and sanitization.
|
|
36
|
+
|
|
37
|
+
## AI Doc Shape
|
|
38
|
+
|
|
39
|
+
Each packaged feature doc should help AI answer the same five questions quickly:
|
|
40
|
+
|
|
41
|
+
- When does this doc apply?
|
|
42
|
+
- Which `caspian.config.json` flag, if any, gates the feature?
|
|
43
|
+
- Which app-owned files usually change?
|
|
44
|
+
- Which `main.py` or installed `casp` runtime files own the behavior?
|
|
45
|
+
- Which behavior should be verified before editing or explaining the feature?
|
|
46
|
+
|
|
47
|
+
Keep project-specific facts, temporary file inventory, and current app feature flags out of packaged docs. Put those in `AGENTS.md`, `.github/copilot-instructions.md`, or the project code instead.
|
|
48
|
+
|
|
49
|
+
Use [core-runtime-map.md](./core-runtime-map.md) for Python-side Caspian runtime ownership and [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md) for browser-side PulsePoint runtime ownership.
|
|
50
|
+
|
|
51
|
+
## Redundancy Rule
|
|
52
|
+
|
|
53
|
+
Prefer one canonical explanation plus links from related docs.
|
|
54
|
+
|
|
55
|
+
- Put the full authored-template and PulsePoint runtime contract in [pulsepoint.md](./pulsepoint.md).
|
|
56
|
+
- Put the full route and layout placement contract in [routing.md](./routing.md).
|
|
57
|
+
- Put the full reusable component contract in [components.md](./components.md).
|
|
58
|
+
- Put the full Python runtime ownership map in [core-runtime-map.md](./core-runtime-map.md).
|
|
59
|
+
- Put the full PulsePoint feature lookup map in [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md).
|
|
60
|
+
|
|
61
|
+
Other docs should summarize these rules only when the reminder prevents a common mistake, then link to the canonical page instead of restating the whole rule block.
|
|
35
62
|
|
|
36
63
|
## Docs Location
|
|
37
64
|
|
|
@@ -45,8 +72,9 @@ The packaged Caspian docs referenced by this index live here:
|
|
|
45
72
|
- `ai-validation-checklist.md` - workflow and representative prompts for checking whether AI can find the correct Caspian docs, core files, and verification checkpoints
|
|
46
73
|
- `installation.md` - First-time setup flow for creating a new Caspian application
|
|
47
74
|
- `commands.md` - Main Caspian CLI workflows for project creation, generation, updates, and config-aware maintenance
|
|
48
|
-
- `core-runtime-map.md` - map of `main.py` plus installed `casp` modules to the packaged docs that explain them and the behaviors AI should trace there
|
|
49
|
-
- `
|
|
75
|
+
- `core-runtime-map.md` - map of `main.py` plus installed `casp` modules to the packaged docs that explain them and the behaviors AI should trace there
|
|
76
|
+
- `pulsepoint-runtime-map.md` - fast feature-to-runtime lookup for PulsePoint state, effects, refs, context, portals, lists, events, RPC, uploads, streaming, SPA navigation, scroll restoration, and Tailwind merge behavior
|
|
77
|
+
- `mcp.md` - MCP-specific layout, launch flow, and AI routing rules for projects where `caspian.config.json` enables MCP
|
|
50
78
|
- `database.md` - Prisma schema, migration, seed, and client-generation workflow for projects where `caspian.config.json` enables Prisma, plus Python-side helper caveats
|
|
51
79
|
- `auth.md` - Session-backed authentication with `casp.auth`, centralized `auth_config.py`, public-vs-private route mode guidance, RPC-first signout guidance, RBAC, and OAuth provider helpers
|
|
52
80
|
- `components.md` - Create reusable Python components, template-backed UI, HTML-first `x-*` component tags, the single-parent authored-root rule for component HTML files, and the Python-side `merge_classes(...)` contract when Tailwind CSS is enabled
|
|
@@ -70,12 +98,13 @@ Preferred lookup order:
|
|
|
70
98
|
2. Read `./caspian.config.json` before making any feature assumption. A doc existing in the package does not mean that feature is enabled in the current project.
|
|
71
99
|
3. Before authoring or editing any `src/app/**` or component HTML template, apply the single-root invariant: one authored root only, any owned `<script>` inside that root, and no handwritten `pp-component` or `type="text/pp"`.
|
|
72
100
|
4. Treat `caspian.config.json` as the single source of truth for optional features. Use feature-specific docs only when the matching flag is enabled. If a feature is disabled and the user wants it, ask first, then update `caspian.config.json` and follow the update workflow in `commands.md`.
|
|
73
|
-
5. If the task touches `main.py` or `.venv/Lib/site-packages/casp/**`, read `core-runtime-map.md` to jump to the controlling runtime file and the matching feature doc.
|
|
74
|
-
6.
|
|
75
|
-
7.
|
|
76
|
-
8.
|
|
77
|
-
9.
|
|
78
|
-
10.
|
|
101
|
+
5. If the task touches `main.py` or `.venv/Lib/site-packages/casp/**`, read `core-runtime-map.md` to jump to the controlling runtime file and the matching feature doc.
|
|
102
|
+
6. If the task names a PulsePoint feature or directive, read `pulsepoint-runtime-map.md` for the fastest feature-to-runtime lookup, then read `pulsepoint.md` for authoring rules.
|
|
103
|
+
7. After the feature is confirmed, inspect the actual project files that decide behavior, such as `package.json`, `main.py`, `src/app/**`, `src/lib/**`, `settings/**`, `prisma/**`, and the installed `casp` runtime.
|
|
104
|
+
8. Use `commands.md` for scaffold and update workflows, `project-structure.md` for placement decisions, and the feature docs such as `mcp.md`, `database.md`, `auth.md`, `fetch-data.md`, and `file-uploads.md` for task-specific guidance.
|
|
105
|
+
9. Prefer packaged Caspian docs before upstream documentation when generating code, commands, or migration guidance.
|
|
106
|
+
10. Use `ai-validation-checklist.md` when you want to verify that the docs lead AI to the correct files and behavior checkpoints.
|
|
107
|
+
11. Keep `index.md` and cross-links aligned so AI can quickly discover the right doc.
|
|
79
108
|
|
|
80
109
|
## Maintenance
|
|
81
110
|
|
package/dist/docs/metadata.md
CHANGED
|
@@ -12,9 +12,17 @@ related:
|
|
|
12
12
|
|
|
13
13
|
This page explains how Caspian handles document metadata, SEO fields, and social sharing tags.
|
|
14
14
|
|
|
15
|
-
At render time, Caspian resolves metadata through the layout engine and exposes the merged result to templates as `[[ metadata.* ]]`.
|
|
16
|
-
|
|
17
|
-
##
|
|
15
|
+
At render time, Caspian resolves metadata through the layout engine and exposes the merged result to templates as `[[ metadata.* ]]`.
|
|
16
|
+
|
|
17
|
+
## Source Of Truth
|
|
18
|
+
|
|
19
|
+
- Metadata objects and layout merge behavior are implemented in `.venv/Lib/site-packages/casp/layout.py`.
|
|
20
|
+
- Route registration and runtime metadata collection are controlled by `main.py`.
|
|
21
|
+
- Shared metadata defaults belong in `src/app/**/layout.py`.
|
|
22
|
+
- Page-specific static or dynamic metadata belongs in `src/app/**/index.py`.
|
|
23
|
+
- Rendered metadata is consumed from layout templates through `[[ metadata.* ]]`.
|
|
24
|
+
|
|
25
|
+
## Overview
|
|
18
26
|
|
|
19
27
|
Caspian uses a cascading metadata model similar to the Next.js App Router. Define defaults high in the tree, then override them closer to the final route.
|
|
20
28
|
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: PulsePoint Runtime Map
|
|
3
|
+
description: Use this page when AI needs a fast feature-to-runtime lookup for PulsePoint behavior before editing `src/app/**`, component templates, or `public/js/pp-reactive-v2.js`.
|
|
4
|
+
related:
|
|
5
|
+
title: Related docs
|
|
6
|
+
description: Use the PulsePoint guide for authoring rules, the routing and component guides for template placement, and the core runtime map when Python-side transforms are involved.
|
|
7
|
+
links:
|
|
8
|
+
- /docs/pulsepoint
|
|
9
|
+
- /docs/routing
|
|
10
|
+
- /docs/components
|
|
11
|
+
- /docs/fetch-data
|
|
12
|
+
- /docs/core-runtime-map
|
|
13
|
+
- /docs/index
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
This page is the quick AI routing layer for PulsePoint core features.
|
|
17
|
+
|
|
18
|
+
Use [pulsepoint.md](./pulsepoint.md) for the full authoring contract. Use this file when you need to jump from a feature name, directive, or runtime symptom to the files and behavior checkpoints that matter.
|
|
19
|
+
|
|
20
|
+
## Source Of Truth
|
|
21
|
+
|
|
22
|
+
- `public/js/pp-reactive-v2.js` is the shipped browser runtime.
|
|
23
|
+
- `main.py` owns the final render pipeline that calls `transform_components(...)` and `transform_scripts(...)`.
|
|
24
|
+
- `.venv/Lib/site-packages/casp/components_compiler.py` injects `pp-component` after component expansion and validates the single-root contract.
|
|
25
|
+
- `.venv/Lib/site-packages/casp/scripts_type.py` rewrites authored body `<script>` tags to `type="text/pp"`.
|
|
26
|
+
- `.venv/Lib/site-packages/casp/html_attrs.py` owns Python-side class and attribute helpers such as `merge_classes(...)`.
|
|
27
|
+
|
|
28
|
+
If an inspected browser DOM disagrees with authored template source, remember that the runtime DOM includes framework-managed output. Do not copy runtime-only attributes back into authored templates.
|
|
29
|
+
|
|
30
|
+
## Feature Map
|
|
31
|
+
|
|
32
|
+
| PulsePoint feature | Authoring surface | Runtime owner | Verify before changing |
|
|
33
|
+
| --- | --- | --- | --- |
|
|
34
|
+
| Component roots | `src/app/**/index.html`, `layout.html`, component `.html` files | `components_compiler.py`, `pp-reactive-v2.js` | one authored root, final expanded root receives one `pp-component`, no sibling scripts |
|
|
35
|
+
| Component scripts | plain `<script>` inside the authored root | `scripts_type.py`, `pp-reactive-v2.js` | authored scripts are plain, runtime scripts become `type="text/pp"`, one owned script per root |
|
|
36
|
+
| Template expressions | text and attributes with `{...}` | `pp-reactive-v2.js` | top-level script bindings are exported, nested bindings are not assumed |
|
|
37
|
+
| State | `pp.state(initial)` | `pp-reactive-v2.js` | setters accept values or updater functions, state belongs to the component instance |
|
|
38
|
+
| Effects | `pp.effect(...)`, `pp.layoutEffect(...)` | `pp-reactive-v2.js` | callbacks may return cleanup functions, promises are not awaited |
|
|
39
|
+
| Refs | `pp.ref(...)`, `pp-ref` | `pp-reactive-v2.js` | generated ref internals are runtime-managed; do not author `data-pp-ref` |
|
|
40
|
+
| Context | `pp.createContext(...)`, `<Context.Provider>`, `pp.context(token)` | `pp-reactive-v2.js` | ancestry is logical component ancestry; do not invent `pp-context` or `pp.provideContext` |
|
|
41
|
+
| Portals | `pp.portal(ref, target?)` | `pp-reactive-v2.js` | context should preserve logical ancestry through the registry |
|
|
42
|
+
| Lists | `<template pp-for="item in items">` | `pp-reactive-v2.js` | `pp-for` belongs on `<template>`, use plain `key`, not `pp-key` |
|
|
43
|
+
| Events | native `onclick`, `oninput`, `onsubmit` | `pp-reactive-v2.js` | event scope exposes `event`, `e`, `$event`, `target`, `currentTarget`, and `el` |
|
|
44
|
+
| RPC | `pp.rpc(...)` in scripts, `@rpc()` in Python | `pp-reactive-v2.js`, `casp/rpc.py` | use `pp.rpc`, not legacy `pp.fetchFunction`; protected actions use `@rpc(require_auth=True)` |
|
|
45
|
+
| Upload progress | `pp.rpc(..., { onUploadProgress })` | `pp-reactive-v2.js`, `casp/rpc.py` | XHR path is used for progress callbacks; replace state from returned payload |
|
|
46
|
+
| Streaming | `pp.rpc(..., { onStream })` | `pp-reactive-v2.js`, `casp/rpc.py`, `casp/streaming.py` | server generators become SSE responses |
|
|
47
|
+
| SPA navigation | `body[pp-spa="true"]`, links | `pp-reactive-v2.js`, `main.py` | same-origin eligible links intercept; root-layout mismatches hard reload |
|
|
48
|
+
| Scroll restoration | `pp-reset-scroll="true"` | `pp-reactive-v2.js` | push navigation resets window; mark only content panes that should reset |
|
|
49
|
+
| Tailwind merge | `{twMerge(...)}`, Python `merge_classes(...)` | `html_attrs.py`, `pp-reactive-v2.js` | Python emits frontend-ready expressions when Tailwind is enabled |
|
|
50
|
+
|
|
51
|
+
## AI Decision Rules
|
|
52
|
+
|
|
53
|
+
- Read `caspian.config.json` first when the task depends on Tailwind, generated files, or optional project features.
|
|
54
|
+
- Read [routing.md](./routing.md) before adding route or layout templates.
|
|
55
|
+
- Read [components.md](./components.md) before adding reusable Python components or `x-*` imports.
|
|
56
|
+
- Read [fetch-data.md](./fetch-data.md) before adding browser-triggered backend work.
|
|
57
|
+
- Use this map when the task names a PulsePoint feature and you need the owning runtime file quickly.
|
|
58
|
+
- Verify implemented behavior in `public/js/pp-reactive-v2.js` before adding new PulsePoint API claims.
|
|
59
|
+
|
|
60
|
+
## Copy-Safe Authoring Rules
|
|
61
|
+
|
|
62
|
+
- Author one root element or one imported `x-*` root per route, layout, or component template.
|
|
63
|
+
- Keep any owned plain `<script>` inside that same root.
|
|
64
|
+
- Do not handwrite `pp-component`, `type="text/pp"`, `data-pp-ref`, `pp-owner`, `pp-event-owner`, or other runtime-managed attributes.
|
|
65
|
+
- Use `pp.rpc(...)` for current browser-to-server calls.
|
|
66
|
+
- Use `Context.Provider` and `pp.context(...)` for context.
|
|
67
|
+
- Use `pp-for` only on `<template>` and plain `key` for keyed lists.
|
|
68
|
+
- Prefer PulsePoint state and directives over manual `innerHTML` repainting.
|
|
69
|
+
|
|
70
|
+
## Compact Examples
|
|
71
|
+
|
|
72
|
+
Context provider:
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<section>
|
|
76
|
+
<script>
|
|
77
|
+
const ThemeContext = pp.createContext("light");
|
|
78
|
+
const [theme, setTheme] = pp.state("dark");
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<ThemeContext.Provider value="{theme}">
|
|
82
|
+
<button onclick="setTheme(theme === 'dark' ? 'light' : 'dark')">
|
|
83
|
+
Theme: {theme}
|
|
84
|
+
</button>
|
|
85
|
+
</ThemeContext.Provider>
|
|
86
|
+
</section>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Upload progress:
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<section>
|
|
93
|
+
<input type="file" onchange="{uploadFile(event.target.files?.[0])}" />
|
|
94
|
+
<p>{progress}%</p>
|
|
95
|
+
|
|
96
|
+
<script>
|
|
97
|
+
const [progress, setProgress] = pp.state(0);
|
|
98
|
+
|
|
99
|
+
async function uploadFile(file) {
|
|
100
|
+
if (!file) return;
|
|
101
|
+
|
|
102
|
+
await pp.rpc("upload_asset", { file }, {
|
|
103
|
+
onUploadProgress: (event) => setProgress(event.percentage ?? 0),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
</script>
|
|
107
|
+
</section>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Grouped shell scroll reset:
|
|
111
|
+
|
|
112
|
+
```html
|
|
113
|
+
<section class="dashboard-shell">
|
|
114
|
+
<aside class="dashboard-sidebar">...</aside>
|
|
115
|
+
<main class="dashboard-content" pp-reset-scroll="true">
|
|
116
|
+
[[ children | safe ]]
|
|
117
|
+
</main>
|
|
118
|
+
</section>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Verification Prompts
|
|
122
|
+
|
|
123
|
+
Use these prompts after docs or runtime changes to confirm AI can route correctly:
|
|
124
|
+
|
|
125
|
+
- "Create an interactive filter in a Caspian route template."
|
|
126
|
+
- "Explain why authored scripts are plain `<script>` but browser output shows `type=\"text/pp\"`."
|
|
127
|
+
- "Debug a dashboard sidebar losing scroll during child-route navigation."
|
|
128
|
+
- "Add an upload widget with progress and a reactive file list."
|
|
129
|
+
- "Use context to share theme state between parent and child components."
|
package/dist/docs/pulsepoint.md
CHANGED
|
@@ -7,8 +7,9 @@ related:
|
|
|
7
7
|
links:
|
|
8
8
|
- /docs/components
|
|
9
9
|
- /docs/routing
|
|
10
|
-
- /docs/fetch-data
|
|
11
|
-
- /docs/
|
|
10
|
+
- /docs/fetch-data
|
|
11
|
+
- /docs/pulsepoint-runtime-map
|
|
12
|
+
- /docs/core-runtime-map
|
|
12
13
|
- /docs/project-structure
|
|
13
14
|
- /docs/index
|
|
14
15
|
---
|
|
@@ -43,7 +44,9 @@ Important current facts:
|
|
|
43
44
|
|
|
44
45
|
If docs, generated examples, or older notes disagree with `public/js/pp-reactive-v2.js` plus `main.py`, follow the code that actually runs.
|
|
45
46
|
|
|
46
|
-
Use [core-runtime-map.md](./core-runtime-map.md) when the controlling runtime file is not obvious yet.
|
|
47
|
+
Use [core-runtime-map.md](./core-runtime-map.md) when the controlling runtime file is not obvious yet.
|
|
48
|
+
|
|
49
|
+
Use [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md) when the task names a specific PulsePoint feature or directive and you need a quick feature-to-runtime lookup before reading the full guide.
|
|
47
50
|
|
|
48
51
|
## Default Frontend Rule
|
|
49
52
|
|
package/dist/docs/routing.md
CHANGED
|
@@ -12,6 +12,7 @@ related:
|
|
|
12
12
|
- /docs/file-uploads
|
|
13
13
|
- /docs/metadata
|
|
14
14
|
- /docs/pulsepoint
|
|
15
|
+
- /docs/pulsepoint-runtime-map
|
|
15
16
|
- /docs/index
|
|
16
17
|
---
|
|
17
18
|
|
|
@@ -227,7 +228,7 @@ Also bad:
|
|
|
227
228
|
</section>
|
|
228
229
|
```
|
|
229
230
|
|
|
230
|
-
Use [pulsepoint.md](./pulsepoint.md) when you need the full authored-vs-rendered example instead of this routing-focused reminder.
|
|
231
|
+
Use [pulsepoint.md](./pulsepoint.md) when you need the full authored-vs-rendered example instead of this routing-focused reminder. Use [pulsepoint-runtime-map.md](./pulsepoint-runtime-map.md) when a route task names a specific PulsePoint directive or SPA behavior and you need the owning runtime file quickly.
|
|
231
232
|
|
|
232
233
|
### `index.py`
|
|
233
234
|
|
|
@@ -235,6 +236,8 @@ Use `index.py` as the backend companion when a route needs metadata or async ser
|
|
|
235
236
|
|
|
236
237
|
Use `index.py` by itself only for non-visual routes such as redirects or action-only handlers. Because Caspian runs on FastAPI, the page entry should be async when it performs async work.
|
|
237
238
|
|
|
239
|
+
When `page()` calls `render_page(__file__, ...)`, root-validation errors are attributed to the sibling `index.html` because that file is the authored template. If `page()` returns a raw HTML string directly, Caspian treats that value as a runtime fragment instead of an authored template and wraps it in a runtime host root when needed.
|
|
240
|
+
|
|
238
241
|
Example:
|
|
239
242
|
|
|
240
243
|
```python
|
|
@@ -390,6 +393,8 @@ Example root layout:
|
|
|
390
393
|
|
|
391
394
|
If a layout needs shared synchronous props or metadata, add a `layout.py` file next to the HTML layout. Treat it as the backend companion for the layout, not as the place to author visible wrapper markup.
|
|
392
395
|
|
|
396
|
+
When `layout()` calls `render_layout(__file__, ...)`, root-validation errors are attributed to the sibling `layout.html` because that file is the authored template. If `layout()` returns a raw HTML string directly, Caspian treats that value as a runtime fragment instead of an authored template and wraps it in a runtime host root when needed.
|
|
397
|
+
|
|
393
398
|
Example:
|
|
394
399
|
|
|
395
400
|
```python
|
|
@@ -400,7 +405,7 @@ def layout(context_data):
|
|
|
400
405
|
|
|
401
406
|
return {
|
|
402
407
|
"user": user,
|
|
403
|
-
|
|
408
|
+
"dashboard_body_class": "w-screen h-screen overflow-hidden",
|
|
404
409
|
"theme": "dark",
|
|
405
410
|
}
|
|
406
411
|
```
|
package/dist/docs/state.md
CHANGED
|
@@ -27,11 +27,18 @@ Import the public API like this:
|
|
|
27
27
|
from casp.state_manager import StateManager
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
The current installed implementation lives in `.venv/Lib/site-packages/casp/state_manager.py`.
|
|
31
|
-
|
|
32
|
-
Use [core-runtime-map.md](./core-runtime-map.md) when a state task crosses `main.py` middleware setup, wire-request behavior, and the installed state-manager internals.
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
The current installed implementation lives in `.venv/Lib/site-packages/casp/state_manager.py`.
|
|
31
|
+
|
|
32
|
+
Use [core-runtime-map.md](./core-runtime-map.md) when a state task crosses `main.py` middleware setup, wire-request behavior, and the installed state-manager internals.
|
|
33
|
+
|
|
34
|
+
## Source Of Truth
|
|
35
|
+
|
|
36
|
+
- Request initialization and middleware timing are controlled by `main.py`.
|
|
37
|
+
- The server state implementation lives in `.venv/Lib/site-packages/casp/state_manager.py`.
|
|
38
|
+
- Route and RPC code should use `StateManager` only for transient server request state.
|
|
39
|
+
- Browser interaction state belongs in PulsePoint; read [pulsepoint.md](./pulsepoint.md) before moving UI state into `StateManager`.
|
|
40
|
+
|
|
41
|
+
The real API surface is:
|
|
35
42
|
|
|
36
43
|
- request initialization with `StateManager.init(request)`
|
|
37
44
|
- top-level state reads with `StateManager.get_state(...)`
|
package/dist/docs/validation.md
CHANGED
|
@@ -26,9 +26,16 @@ Import the public API like this:
|
|
|
26
26
|
from casp.validate import Validate, Rule
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
The current installed implementation lives in `.venv/Lib/site-packages/casp/validate.py`.
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
The current installed implementation lives in `.venv/Lib/site-packages/casp/validate.py`.
|
|
30
|
+
|
|
31
|
+
## Source Of Truth
|
|
32
|
+
|
|
33
|
+
- The implemented validation API lives in `.venv/Lib/site-packages/casp/validate.py`.
|
|
34
|
+
- Route and RPC input boundaries live in `src/app/**/index.py`.
|
|
35
|
+
- Reusable app-owned validation workflows belong in `src/lib/**`.
|
|
36
|
+
- Browser-side validation is UX only; server-side `Validate` and `Rule` checks remain authoritative.
|
|
37
|
+
|
|
38
|
+
The real API surface is:
|
|
32
39
|
|
|
33
40
|
- direct single-value validation with `Validate.*(...)`
|
|
34
41
|
- multi-rule validation with `Validate.with_rules(...)`
|