@jskit-ai/agent-docs 0.1.19 → 0.1.21
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/guide/agent/app-setup/authentication.md +8 -0
- package/guide/agent/app-setup/initial-scaffolding.md +14 -8
- package/guide/agent/app-setup/multi-homing.md +59 -0
- package/guide/agent/app-setup/quickstart.md +214 -0
- package/guide/agent/app-setup/users.md +8 -0
- package/guide/agent/app-setup/working-with-the-jskit-cli.md +16 -0
- package/guide/agent/generators/crud-generators.md +210 -62
- package/guide/agent/generators/ui-generators.md +31 -0
- package/guide/agent/index.md +4 -2
- package/package.json +1 -1
- package/patterns/page-redirects.md +5 -1
- package/patterns/ui-testing.md +8 -0
- package/reference/autogen/README.md +1 -0
- package/reference/autogen/packages/assistant-core.md +13 -0
- package/reference/autogen/packages/assistant-runtime.md +2 -0
- package/reference/autogen/packages/auth-provider-supabase-core.md +6 -0
- package/reference/autogen/packages/console-core.md +2 -0
- package/reference/autogen/packages/crud-core.md +4 -0
- package/reference/autogen/packages/crud-ui-generator.md +3 -0
- package/reference/autogen/packages/feature-server-generator.md +74 -0
- package/reference/autogen/packages/json-rest-api-core.md +1 -5
- package/reference/autogen/packages/users-web.md +1 -0
- package/reference/autogen/tooling/create-app.md +4 -16
- package/reference/autogen/tooling/jskit-cli.md +12 -1
- package/templates/app/AGENTS.md +1 -1
- package/workflow/feature-delivery.md +2 -0
- package/workflow/review.md +1 -0
|
@@ -1030,6 +1030,14 @@ npx jskit app verify-ui \
|
|
|
1030
1030
|
--auth-mode dev-auth-login-as
|
|
1031
1031
|
```
|
|
1032
1032
|
|
|
1033
|
+
For local pre-merge review, the next step after recording that Playwright run is usually:
|
|
1034
|
+
|
|
1035
|
+
```bash
|
|
1036
|
+
npx jskit doctor --against origin/main
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
Advanced CI pipelines can use the same `--against` contract too, but JSKIT does not scaffold hosted auth/database/browser verification by default.
|
|
1040
|
+
|
|
1033
1041
|
That flow is preferable to driving the real sign-in form in feature tests because it keeps the test focused on the UI feature being added, not on an external auth dependency. If a chunk changes user-facing UI and the flow requires login, the expected JSKIT review standard is:
|
|
1034
1042
|
|
|
1035
1043
|
- use Playwright
|
|
@@ -151,6 +151,8 @@ That matters because JSKIT maintenance policy changes over time. If the scaffold
|
|
|
151
151
|
|
|
152
152
|
`jskit app verify` is worth noticing specifically. Linting, tests, and builds check your source code and runtime behavior. The JSKIT part of that flow runs `doctor`, which checks JSKIT-managed app state: installed package visibility, lock-file-backed managed files, and other JSKIT-specific health rules. It is there because a JSKIT app is not only code. It is also a descriptor-driven managed project.
|
|
153
153
|
|
|
154
|
+
The starter scaffold also writes `.github/workflows/verify.yml`. That workflow stays intentionally small: it runs `npm run verify` for the normal GitHub Actions gate and leaves browser/auth/database-heavy review flows to app-specific local or CI setups. The `--against <base-ref>` review mode exists in the CLI for local pre-merge checks and for advanced CI pipelines, but it is not assumed by the starter scaffold.
|
|
155
|
+
|
|
154
156
|
The surface-specific script names are also worth noticing early, even in this tiny app. `dev:home`, `server:home`, and `build:home` are the first concrete places where surface selection shows up in the scaffold. They work by setting `VITE_SURFACE=home` on the client side and `SERVER_SURFACE=home` on the server side. In this first chapter, where `home` is the only surface, those variants behave almost the same as the default commands. Later, once more surfaces exist, those scripts become the simplest way to run or build just one surface at a time.
|
|
155
157
|
|
|
156
158
|
### App surfaces in JSKIT
|
|
@@ -630,13 +632,11 @@ export default Object.freeze({
|
|
|
630
632
|
kind: "runtime",
|
|
631
633
|
runtime: {
|
|
632
634
|
server: {
|
|
633
|
-
providerEntrypoint: "src/server/
|
|
635
|
+
providerEntrypoint: "src/server/MainServiceProvider.js",
|
|
634
636
|
providers: [
|
|
635
637
|
{
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
pattern: "*Provider.js"
|
|
639
|
-
}
|
|
638
|
+
entrypoint: "src/server/MainServiceProvider.js",
|
|
639
|
+
export: "MainServiceProvider"
|
|
640
640
|
}
|
|
641
641
|
]
|
|
642
642
|
}
|
|
@@ -651,12 +651,12 @@ export default Object.freeze({
|
|
|
651
651
|
|
|
652
652
|
This is the moment where the scaffold stops looking like "just a Vue app". The app is declaring itself as a runtime package that JSKIT can discover, load, and mutate safely.
|
|
653
653
|
|
|
654
|
-
For the server side, the main file to remember is `packages/main/src/server/
|
|
654
|
+
For the server side, the main file to remember is `packages/main/src/server/MainServiceProvider.js`. It stays intentionally flat and small. That is the point: `packages/main` is the app-local composition package, not the default home for new backend feature trees.
|
|
655
655
|
|
|
656
656
|
The server-side provider starts like this:
|
|
657
657
|
|
|
658
658
|
```js
|
|
659
|
-
import { loadAppConfig } from "
|
|
659
|
+
import { loadAppConfig } from "./loadAppConfig.js";
|
|
660
660
|
|
|
661
661
|
class MainServiceProvider {
|
|
662
662
|
static id = "local.main";
|
|
@@ -674,7 +674,13 @@ class MainServiceProvider {
|
|
|
674
674
|
export { MainServiceProvider };
|
|
675
675
|
```
|
|
676
676
|
|
|
677
|
-
It is deliberately small
|
|
677
|
+
It is deliberately small because it is only for app-local glue: loading config, wiring tiny app-specific behavior, and bootstrapping shared runtime concerns. When a backend capability becomes substantial, do not grow `packages/main` into a mini service tree. Generate a dedicated package instead:
|
|
678
|
+
|
|
679
|
+
```bash
|
|
680
|
+
npx jskit generate feature-server-generator scaffold booking-engine
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
That keeps the ownership boundary clear: `packages/main` stays composition-only, while real server features get their own provider, service, and optional repository seams. The client side uses the same provider lifecycle; you already saw the matching pattern earlier in the client boot path.
|
|
678
684
|
|
|
679
685
|
The `.jskit/lock.json` file is also important. Treat it like JSKIT's own lock and state file. It records which runtime packages JSKIT believes are installed and which managed changes they introduced. When you use `jskit add`, `jskit update`, or generators that depend on installed package state, this file is part of the source of truth. It belongs in version control, and you should not hand-edit it.
|
|
680
686
|
|
|
@@ -47,6 +47,12 @@ npm install
|
|
|
47
47
|
npm run db:migrate
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
**Important: This Block Is Only The Fresh Workspace Install Path**
|
|
51
|
+
|
|
52
|
+
These commands are complete only if the app was already on `tenancyMode = "personal"` when `users-web` / `users-core` were originally installed, or if you already ran the recovery `npx jskit update package users-core` step above.
|
|
53
|
+
|
|
54
|
+
If you changed tenancy after installing users, do not skip that update. The workspace packages add workspace runtime and routes, but `users-core` is what rewrites the app-local users scaffold into its workspace-aware shape.
|
|
55
|
+
|
|
50
56
|
`workspaces-core` adds the server-side workspace runtime and schema migrations. `workspaces-web` adds the workspace-facing client surfaces, shell placements, and app-owned route files.
|
|
51
57
|
|
|
52
58
|
If you want to inspect that package before installing it, this is a very good moment to use the CLI chapter's inspection command:
|
|
@@ -306,6 +312,30 @@ Concretely, that route tree works like this:
|
|
|
306
312
|
- `w/[workspaceSlug]/admin/workspace/settings.vue` is a section shell. It does not own the actual settings fields. It owns the card frame, the left-side settings menu outlet, and the nested `<RouterView />` where child settings pages render.
|
|
307
313
|
- `w/[workspaceSlug]/admin/workspace/settings/index.vue` is intentionally almost empty. Its job is to make `/admin/workspace/settings` a real route today and give you a clean place to redirect or add child settings pages later.
|
|
308
314
|
|
|
315
|
+
If you want to add a real workspace settings child page at this point, use the normal page generator under that route tree:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
npx jskit generate ui-generator page \
|
|
319
|
+
w/[workspaceSlug]/admin/workspace/settings/billing/index.vue \
|
|
320
|
+
--name "Billing"
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
That command does two things:
|
|
324
|
+
|
|
325
|
+
- it creates `src/pages/w/[workspaceSlug]/admin/workspace/settings/billing/index.vue`
|
|
326
|
+
- it also appends the matching workspace settings menu entry into `src/placement.js`
|
|
327
|
+
|
|
328
|
+
The reason JSKIT can wire that link automatically is that the workspace settings shell already exposes a named placement outlet with a default link renderer:
|
|
329
|
+
|
|
330
|
+
```vue
|
|
331
|
+
<ShellOutlet
|
|
332
|
+
target="admin-settings:primary-menu"
|
|
333
|
+
default-link-component-token="local.main.ui.surface-aware-menu-link-item"
|
|
334
|
+
/>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
`target="admin-settings:primary-menu"` tells the generator which settings menu host owns those child links. `default-link-component-token="local.main.ui.surface-aware-menu-link-item"` tells it which local menu-link component to use unless you override it. So a page generated under `w/[workspaceSlug]/admin/workspace/settings/...` automatically lands in the left-side workspace settings menu without you hand-writing the placement entry.
|
|
338
|
+
|
|
309
339
|
### Workspace pages are prepared for missing-workspace states
|
|
310
340
|
|
|
311
341
|
The starter workspace pages already use a dedicated unavailable-state helper:
|
|
@@ -558,6 +588,35 @@ That one block explains a lot of the new shell behavior.
|
|
|
558
588
|
- the admin surface gets workspace tools in the top-right area
|
|
559
589
|
- the admin workspace settings menu is now another nested placement host with both `Settings` and `Members`
|
|
560
590
|
|
|
591
|
+
If you want to add your own app-owned page into that top cog menu, first ask JSKIT which placement targets exist:
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
npx jskit list-placements
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
In a workspace-enabled app, that list now includes:
|
|
598
|
+
|
|
599
|
+
```text
|
|
600
|
+
- admin-cog:primary-menu [package:@jskit-ai/workspaces-web:src/client/components/UsersWorkspaceToolsWidget.vue]
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
If you want more context than the raw target list, `npx jskit show @jskit-ai/workspaces-web --details` also shows that same outlet plus the default `Settings` and `Members` entries already targeting it.
|
|
604
|
+
|
|
605
|
+
Once you know the outlet id, generate the page like this:
|
|
606
|
+
|
|
607
|
+
```bash
|
|
608
|
+
npx jskit generate ui-generator page \
|
|
609
|
+
w/[workspaceSlug]/admin/catalogue/index.vue \
|
|
610
|
+
--name "Catalogue" \
|
|
611
|
+
--link-placement admin-cog:primary-menu
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
That command creates `src/pages/w/[workspaceSlug]/admin/catalogue/index.vue` and appends the matching link entry into `src/placement.js`.
|
|
615
|
+
|
|
616
|
+
`--link-placement` is necessary here because this route is just a normal `admin` page. It is **not** a child page under a local host like `w/[workspaceSlug]/admin/workspace/settings.vue`, so the generator has no nested settings outlet to infer automatically. If you omit `--link-placement`, the new page link falls back to the app's default shell menu outlet instead of the cog menu.
|
|
617
|
+
|
|
618
|
+
You also do **not** need `--link-component-token` here. `admin-cog:primary-menu` already declares `local.main.ui.surface-aware-menu-link-item` as its default link renderer, so JSKIT reuses that automatically when it writes the placement entry.
|
|
619
|
+
|
|
561
620
|
So the placement system from the shell chapter is still doing the same job as before. The app just has a richer routing and tenancy context now.
|
|
562
621
|
|
|
563
622
|
### The local client provider gets one more app-owned token
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<!-- Generated by `npm run agent-docs:build` from `packages/agent-docs/site/guide/app-setup/quickstart.md`. Do not edit manually. -->
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
title: Quickstart
|
|
5
|
+
description: The fastest path to a real JSKIT app, plus the first page-extension patterns you will usually need.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Quickstart
|
|
9
|
+
|
|
10
|
+
This chapter is the fastest reproducible path to a real JSKIT app.
|
|
11
|
+
|
|
12
|
+
The base flow below gives you:
|
|
13
|
+
|
|
14
|
+
- personal workspaces
|
|
15
|
+
- users
|
|
16
|
+
- console
|
|
17
|
+
- MySQL
|
|
18
|
+
- Supabase auth
|
|
19
|
+
- one `admin` assistant configured from `console`
|
|
20
|
+
|
|
21
|
+
It also shows the first page-extension moves most apps need:
|
|
22
|
+
|
|
23
|
+
- add two workspace settings pages
|
|
24
|
+
- make one of them the default landing page
|
|
25
|
+
- add a page to the admin cog
|
|
26
|
+
- add a normal left-menu page
|
|
27
|
+
- inspect placement destinations and understand why some links are inferred automatically
|
|
28
|
+
|
|
29
|
+
## Step 1: Create the app
|
|
30
|
+
|
|
31
|
+
Set these values first:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
OPENAI_API_KEY=...
|
|
35
|
+
SUPABASE_URL=...
|
|
36
|
+
SUPABASE_KEY=...
|
|
37
|
+
DB_HOST=127.0.0.1
|
|
38
|
+
DB_PORT=3306
|
|
39
|
+
DB_NAME=testapp
|
|
40
|
+
DB_USER=...
|
|
41
|
+
DB_PASSWORD=...
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Then run the exact sequence below:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx @jskit-ai/create-app testapp --tenancy-mode personal
|
|
48
|
+
cd testapp
|
|
49
|
+
npm install
|
|
50
|
+
|
|
51
|
+
npx jskit add package shell-web
|
|
52
|
+
|
|
53
|
+
npx jskit add package auth-provider-supabase-core \
|
|
54
|
+
--auth-supabase-url "$SUPABASE_URL" \
|
|
55
|
+
--auth-supabase-publishable-key "$SUPABASE_KEY" \
|
|
56
|
+
--app-public-url "http://localhost:5173"
|
|
57
|
+
|
|
58
|
+
npx jskit add bundle auth-base
|
|
59
|
+
|
|
60
|
+
npx jskit add package database-runtime-mysql \
|
|
61
|
+
--db-host "$DB_HOST" \
|
|
62
|
+
--db-port "$DB_PORT" \
|
|
63
|
+
--db-name "$DB_NAME" \
|
|
64
|
+
--db-user "$DB_USER" \
|
|
65
|
+
--db-password "$DB_PASSWORD"
|
|
66
|
+
|
|
67
|
+
npx jskit add package users-web
|
|
68
|
+
npx jskit add package console-web
|
|
69
|
+
npx jskit add package workspaces-core
|
|
70
|
+
npx jskit add package workspaces-web
|
|
71
|
+
|
|
72
|
+
npx jskit generate assistant setup \
|
|
73
|
+
--surface admin \
|
|
74
|
+
--settings-surface console \
|
|
75
|
+
--config-scope global \
|
|
76
|
+
--ai-provider openai \
|
|
77
|
+
--ai-api-key "$OPENAI_API_KEY"
|
|
78
|
+
|
|
79
|
+
npx jskit generate assistant page \
|
|
80
|
+
w/[workspaceSlug]/admin/assistant/index.vue \
|
|
81
|
+
--name "Assistant"
|
|
82
|
+
|
|
83
|
+
npx jskit generate assistant settings-page \
|
|
84
|
+
console/settings/admin-assistant/index.vue \
|
|
85
|
+
--surface admin \
|
|
86
|
+
--name "Admin Assistant" \
|
|
87
|
+
--link-placement console-settings:primary-menu \
|
|
88
|
+
--link-component-token local.main.ui.surface-aware-menu-link-item
|
|
89
|
+
|
|
90
|
+
npm install
|
|
91
|
+
npm run db:migrate
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
At this point you have:
|
|
95
|
+
|
|
96
|
+
- a workspace-enabled app with `tenancyMode = "personal"`
|
|
97
|
+
- an `admin` assistant at `/w/[workspaceSlug]/admin/assistant`
|
|
98
|
+
- an assistant settings page at `/console/settings/admin-assistant`
|
|
99
|
+
|
|
100
|
+
## Step 2: Add two workspace settings pages
|
|
101
|
+
|
|
102
|
+
Generate two child pages under the workspace settings host:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx jskit generate ui-generator page \
|
|
106
|
+
w/[workspaceSlug]/admin/workspace/settings/billing/index.vue \
|
|
107
|
+
--name "Billing"
|
|
108
|
+
|
|
109
|
+
npx jskit generate ui-generator page \
|
|
110
|
+
w/[workspaceSlug]/admin/workspace/settings/branding/index.vue \
|
|
111
|
+
--name "Branding"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
These commands create:
|
|
115
|
+
|
|
116
|
+
- `src/pages/w/[workspaceSlug]/admin/workspace/settings/billing/index.vue`
|
|
117
|
+
- `src/pages/w/[workspaceSlug]/admin/workspace/settings/branding/index.vue`
|
|
118
|
+
|
|
119
|
+
They also append matching menu entries into `src/placement.js`.
|
|
120
|
+
|
|
121
|
+
## Step 3: Make one settings page the default
|
|
122
|
+
|
|
123
|
+
Best practice is to make the default child explicit.
|
|
124
|
+
|
|
125
|
+
Edit:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
src/pages/w/[workspaceSlug]/admin/workspace/settings/index.vue
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
and replace its contents with:
|
|
132
|
+
|
|
133
|
+
```vue
|
|
134
|
+
<script setup>
|
|
135
|
+
import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
|
|
136
|
+
|
|
137
|
+
definePage({
|
|
138
|
+
redirect: redirectToChild("billing")
|
|
139
|
+
});
|
|
140
|
+
</script>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
That makes `/w/[workspaceSlug]/admin/workspace/settings` land on `/w/[workspaceSlug]/admin/workspace/settings/billing`.
|
|
144
|
+
|
|
145
|
+
Use this explicit redirect pattern instead of trying to infer the default child from placement order or “the first generated page”.
|
|
146
|
+
|
|
147
|
+
## Step 4: Add a page to the admin cog
|
|
148
|
+
|
|
149
|
+
First list the available placement destinations:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
npx jskit list-placements
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
In a workspace-enabled app, that output includes `admin-cog:primary-menu`.
|
|
156
|
+
|
|
157
|
+
Then generate the page:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npx jskit generate ui-generator page \
|
|
161
|
+
w/[workspaceSlug]/admin/catalogue/index.vue \
|
|
162
|
+
--name "Catalogue" \
|
|
163
|
+
--link-placement admin-cog:primary-menu
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`--link-placement` is necessary here because this is just a normal `admin` page. It is not a child page under a local route host that already owns a nested outlet.
|
|
167
|
+
|
|
168
|
+
## Step 5: Add a normal left-menu page
|
|
169
|
+
|
|
170
|
+
Generate a normal `admin` page without an explicit placement:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npx jskit generate ui-generator page \
|
|
174
|
+
w/[workspaceSlug]/admin/reports/index.vue \
|
|
175
|
+
--name "Reports"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Because this page is not under a more specific local host, JSKIT falls back to the app's default shell menu outlet. In practice, that means a normal left-menu entry.
|
|
179
|
+
|
|
180
|
+
## Step 6: Understand the placement "magic"
|
|
181
|
+
|
|
182
|
+
The workspace settings pages in Step 2 auto-linked into the settings menu for two reasons:
|
|
183
|
+
|
|
184
|
+
1. The parent host already exposes a named outlet:
|
|
185
|
+
|
|
186
|
+
```vue
|
|
187
|
+
<ShellOutlet
|
|
188
|
+
target="admin-settings:primary-menu"
|
|
189
|
+
default-link-component-token="local.main.ui.surface-aware-menu-link-item"
|
|
190
|
+
/>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
2. Your generated pages live under that host route:
|
|
194
|
+
|
|
195
|
+
```text
|
|
196
|
+
w/[workspaceSlug]/admin/workspace/settings/...
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
So JSKIT can infer both:
|
|
200
|
+
|
|
201
|
+
- the placement target: `admin-settings:primary-menu`
|
|
202
|
+
- the default link renderer: `local.main.ui.surface-aware-menu-link-item`
|
|
203
|
+
|
|
204
|
+
That is why the simple settings-page commands do not need `--link-placement` or `--link-component-token`.
|
|
205
|
+
|
|
206
|
+
The admin cog example is different. `w/[workspaceSlug]/admin/catalogue/index.vue` is just a normal admin page, so there is no local nested outlet to infer. That is why you must pass `--link-placement admin-cog:primary-menu` there.
|
|
207
|
+
|
|
208
|
+
If you want a little more context than the raw destination list, this is also useful:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
npx jskit show @jskit-ai/workspaces-web --details
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
That output shows both the workspace-owned placement outlets and the default entries already targeting them.
|
|
@@ -343,6 +343,14 @@ Under the hood, `users-core` wires those contributors into the users-backed prof
|
|
|
343
343
|
|
|
344
344
|
The next chapter uses exactly that pattern. `workspaces-core` registers a contributor so the workspace layer can react when a new user enters the system.
|
|
345
345
|
|
|
346
|
+
One forward-looking warning matters here. If this app later changes from `tenancyMode = "none"` to `personal` or `workspaces`, the app-local users scaffold written by `users-core` also needs to be refreshed. The multi-homing chapter calls out that recovery step explicitly with:
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
npx jskit update package users-core
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
That is not only a workspace-package concern. The generated `packages/users/...` scaffold itself changes shape when tenancy becomes workspace-aware.
|
|
353
|
+
|
|
346
354
|
## Summary
|
|
347
355
|
|
|
348
356
|
This chapter is where the app stopped treating signed-in people as only Supabase identities and started treating them as real JSKIT users.
|
|
@@ -80,6 +80,8 @@ This gives you a clean ownership split:
|
|
|
80
80
|
|
|
81
81
|
That split is worth keeping in mind through the rest of the guide. When you see `npm run verify`, that is now shorthand for "run the app's JSKIT baseline verification policy, then any app-specific extra verification hook".
|
|
82
82
|
|
|
83
|
+
The starter scaffold also includes `.github/workflows/verify.yml`. That workflow is intentionally conservative: it runs `npm run verify` and does not assume that every app can stand up full browser, auth, seed-data, and database verification inside hosted CI.
|
|
84
|
+
|
|
83
85
|
If your app uses a non-default npm registry for JSKIT packages, pass it to the maintained CLI command rather than hard-coding it in the scaffold. For example:
|
|
84
86
|
|
|
85
87
|
```bash
|
|
@@ -747,6 +749,20 @@ That command does two things:
|
|
|
747
749
|
|
|
748
750
|
`doctor` then compares the current changed UI files to that receipt. If you edit the UI again afterwards, the receipt is stale and `doctor` tells you to rerun `jskit app verify-ui`.
|
|
749
751
|
|
|
752
|
+
For local pre-merge review, use `--against <base-ref>` so JSKIT compares against the branch delta instead of only the current dirty worktree. The common shape is:
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
npx jskit doctor --against origin/main
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
If the UI changed, the normal local sequence is:
|
|
759
|
+
|
|
760
|
+
1. run the targeted Playwright flow locally
|
|
761
|
+
2. record it with `jskit app verify-ui ...`
|
|
762
|
+
3. run `jskit doctor --against <base-ref>`
|
|
763
|
+
|
|
764
|
+
Advanced CI pipelines can also use `--against <base-ref>`, but that is intentionally app-specific. JSKIT does not scaffold hosted browser/auth/database verification by default, because many real apps need secrets, seeded databases, local auth bypass, or environment-specific bootstrap paths that do not belong in a one-size-fits-all template.
|
|
765
|
+
|
|
750
766
|
### Why `--json` exists
|
|
751
767
|
|
|
752
768
|
If you want machine-readable output, use:
|