create-caspian-app 1.6.4-alpha → 1.8.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.
- package/dist/.claude/settings.json +36 -0
- package/dist/.codex/hooks.json +29 -0
- package/dist/.github/copilot-instructions.md +12 -2
- package/dist/.github/hooks/dev-hold.json +27 -0
- package/dist/AGENTS.md +470 -445
- package/dist/app-gitignore +2 -0
- package/dist/index.js +1 -1
- package/dist/main.py +440 -65
- package/dist/public/js/pp-reactive-v2.min.js +49 -1
- package/dist/settings/build-static.py +32 -2
- package/dist/settings/check.py +106 -4
- package/dist/settings/dev-hold-hook.ts +211 -0
- package/dist/src/app/error.py +94 -95
- package/dist/src/app/layout.py +12 -16
- package/dist/tests/README.md +1 -1
- package/dist/tests/conftest.py +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "Edit|Write|NotebookEdit|MultiEdit|Bash",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "node settings/dev-hold-hook.ts"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"Stop": [
|
|
16
|
+
{
|
|
17
|
+
"hooks": [
|
|
18
|
+
{
|
|
19
|
+
"type": "command",
|
|
20
|
+
"command": "node settings/dev-hold.ts release --quiet"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"SessionEnd": [
|
|
26
|
+
{
|
|
27
|
+
"hooks": [
|
|
28
|
+
{
|
|
29
|
+
"type": "command",
|
|
30
|
+
"command": "node settings/dev-hold.ts release --quiet"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PreToolUse": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "Edit|Write|NotebookEdit|MultiEdit|Bash|apply_patch|shell|exec_command|write_file",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node settings/dev-hold-hook.ts",
|
|
10
|
+
"statusMessage": "Holding dev reloads",
|
|
11
|
+
"timeout": 10
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"Stop": [
|
|
17
|
+
{
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "node settings/dev-hold.ts release --quiet",
|
|
22
|
+
"statusMessage": "Applying queued dev reloads",
|
|
23
|
+
"timeout": 10
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -24,7 +24,7 @@ This is the top architectural requirement for this workspace. Treat it as a hard
|
|
|
24
24
|
|
|
25
25
|
## Global Rules
|
|
26
26
|
|
|
27
|
-
- **Required frontend feedback loop:** for every UI change or browser-error fix, run `npm run logs` before editing
|
|
27
|
+
- **Required frontend feedback loop:** for every UI change or browser-error fix, run `npm run logs` before editing. Make the whole related edit set while the dev hold queues changes, then run `npm run dev:resume` **once after the final edit**, reload the affected route, exercise the changed interactions, and run `npm run logs` again. Do not resume after each file: one editing run must produce one Python restart and one browser reload. The digest reads `.casp/browser-log.jsonl`; a green gate or visually correct first paint is not browser verification. If the browser or dev session is unavailable, report that gap explicitly. See `node_modules/caspian-utils/dist/docs/agent-development.md`.
|
|
28
28
|
- **Read `pp.props` in the owning script, never directly in authored markup.** Forward incoming props onto the native root, then expose top-level script bindings: `const dialogOpen = !!pp.props.open; const isRotating = !!pp.props.rotate; const projectId = pp.props.projectId || '';`. Use `open="{dialogOpen}"`, `hidden="{isRotating}"`, and `project-id="{projectId}"`. Nested boundary/slot evaluation does not guarantee the script-local prop bag; `open="{!!pp.props.open}"` can throw even when root forwarding is correct. Script-defined callbacks/effects/RPC handlers may use `pp.props`. Do not mask this with optional chaining, replace browser `{...}` with Jinja `{{...}}`, or freeze derived props in state. Read `pulsepoint.md` "Read props in the script, bind names in markup" and `components.md` before editing prop-driven components.
|
|
29
29
|
|
|
30
30
|
- Use this decision order: `caspian.config.json` for optional feature enablement, app runtime and app-owned code for current project behavior, matching workspace instruction files under `.github/instructions/**/*.instructions.md` for task-specific implementation guidance, installed `casp` runtime for framework internals, and packaged markdown docs for Caspian feature discovery and task routing.
|
|
@@ -173,6 +173,16 @@ This is the top architectural requirement for this workspace. Treat it as a hard
|
|
|
173
173
|
- The digest is informational inside `npm run test` and must stay that way — it cannot become part of the exit code, because whether a route has been exercised depends on someone opening a browser. `--fail-on-error` exists for callers that opt in.
|
|
174
174
|
- The log lives in `.casp/` so that `settings/project-name.ts` (which deletes that directory at the start of every `npm run dev`) truncates it per session for free. Do not relocate it somewhere that survives a restart without adding explicit truncation.
|
|
175
175
|
|
|
176
|
+
### `settings/dev-hold.ts`, `settings/dev-hold-hook.ts`, and the agent hook configs
|
|
177
|
+
|
|
178
|
+
- **An agent's whole editing run must cost one Python restart and one browser reload, not one per edit.** The change coordinator in `settings/bs-config.ts` batches on a 1500 ms quiet period tuned for a human's burst-save; an agent's gap between two edits is a tool round-trip and is always wider, so without a hold every edit restarts the server and reloads every open tab, re-running each route's Prisma queries against a pool the restart just discarded.
|
|
179
|
+
- **The signal is explicit, because chokidar sees an inode change and not a writer.** `settings/dev-hold.ts` owns `.casp/dev-hold.json`; while it is active `SettledBatchWorker` keeps queueing and skips both the restart and the reload, then drains the run as one batch. Both expiry valves fail open (120 s without a refresh, 600 s absolute), so a crashed agent degrades to normal reloading rather than a frozen stack.
|
|
180
|
+
- **Every supported agent host is wired, not just Claude Code.** `settings/dev-hold-hook.ts` runs on `PreToolUse` and `node settings/dev-hold.ts release --quiet` runs when the turn ends, configured in `.claude/settings.json`, `.github/hooks/dev-hold.json` (Copilot CLI and VS Code), and `.codex/hooks.json` (Codex CLI and compatible clients). One script serves all three because they deliver the same PascalCase stdin payload (`tool_name`, `tool_input.command`); only the config file differs. Codex has no `SessionEnd`, so it releases on `Stop` alone and relies on the stale valve for a killed session.
|
|
181
|
+
- **`Bash` is in the matcher on purpose.** An agent told to prefer the shell for file changes edits with `cat > file <<'EOF'`, `sed -i`, or a throwaway Python script, none of which an `Edit|Write` matcher can see — that gap once cost a single feature branch eight restarts and five reloads. A blanket Bash match would over-correct, so `commandCanWrite` holds only for commands that can write, and never for the hold's own controls or the read-only quality gate: holding around `npm run logs` would print `DEV HOLD ACTIVE` over a perfectly current digest.
|
|
182
|
+
- **The hook must never exit non-zero.** `PreToolUse` is fail-closed in GitHub Copilot, so a non-zero exit denies the agent's tool call outright. `dev-hold.ts` is therefore imported lazily inside the `try`/`catch`, the `.ts` extension in that specifier is load-bearing (this hook runs under plain `node`, which cannot resolve an extensionless relative import — unlike `bs-config.ts`, which runs under tsx), and nothing is written to stdout.
|
|
183
|
+
- Tool names are normalised before matching, because the hosts spell the same tool `Edit`, `apply_patch`, and `insert_edit_into_file`. Adding a host means extending those sets plus that host's `matcher`, never forking the script.
|
|
184
|
+
- Manual controls, and the fallback for a host without hooks: `npm run dev:hold`, `npm run dev:resume`, `npm run dev:hold:status`. Finish all related edits before the single explicit `dev:resume` used for in-turn browser verification. **If it reports `No hold was active` during an editing run, the current host's hook layer is not wired or did not fire** — check the applicable config and use the manual pair for the next batch. Coverage is in `settings/dev-hold.test.ts` and `settings/utils.test.ts`; the reusable workflow is in `node_modules/caspian-utils/dist/docs/agent-development.md`.
|
|
185
|
+
|
|
176
186
|
### `settings/build-static.py` and `settings/serve-static.py`
|
|
177
187
|
|
|
178
188
|
- Treat these as the app-owned static-export tooling (not shipped `casp` runtime). `settings/build-static.py` is the SSG exporter; `settings/serve-static.py` is the preview server. Document behavior against these files, `package.json`, and `settings/project-name.ts`, not against a `casp` module.
|
|
@@ -249,7 +259,7 @@ This is the top architectural requirement for this workspace. Treat it as a hard
|
|
|
249
259
|
|
|
250
260
|
- These files are the packaged Caspian documentation layer, not the runtime and not the source of current workspace state.
|
|
251
261
|
- Use them to help AI answer three questions: which Caspian feature applies, which project files should be inspected next, and which workflow is appropriate once the feature is confirmed as enabled.
|
|
252
|
-
- Use `node_modules/caspian-utils/dist/docs/file-conventions.md` for the general special-file model, then verify the completed Python migration in `main.py` and `.venv/Lib/site-packages/casp/**`: navigation loading UI uses `loading.py`,
|
|
262
|
+
- Use `node_modules/caspian-utils/dist/docs/file-conventions.md` for the general special-file model, then verify the completed Python migration in `main.py` and `.venv/Lib/site-packages/casp/**`: navigation loading UI uses `loading.py`, the global 404 uses `not_found.py`, and failures render the nearest ancestor `error.py` boundary (raise `casp.errors.HttpError` for known failures). This app has no authored `.html` special files.
|
|
253
263
|
- Use `node_modules/caspian-utils/dist/docs/websockets.md` when deciding how to document or implement named sockets (`@socket()` / `pp.socket(...)`), the shared socket endpoint, origin checks, per-socket auth/RBAC, the JSON frame contract, and the choice between sockets, RPC, and RPC streaming.
|
|
254
264
|
- Verify behavior claims in this order:
|
|
255
265
|
1. `caspian.config.json`, then `main.py`, `src/lib/**`, `public/js/**`, `prisma/**`, `src/app/**`
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"type": "command",
|
|
7
|
+
"matcher": "Edit|Write|NotebookEdit|MultiEdit|Bash|edit|create|str_replace|bash|shell|run_in_terminal",
|
|
8
|
+
"command": "node settings/dev-hold-hook.ts",
|
|
9
|
+
"timeoutSec": 10
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"Stop": [
|
|
13
|
+
{
|
|
14
|
+
"type": "command",
|
|
15
|
+
"command": "node settings/dev-hold.ts release --quiet",
|
|
16
|
+
"timeoutSec": 10
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"SessionEnd": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "node settings/dev-hold.ts release --quiet",
|
|
23
|
+
"timeoutSec": 10
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|