@jskit-ai/agent-docs 0.1.190 → 0.1.192

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 (26) hide show
  1. package/guide/agent/app-extras/assistant-conversation.md +3 -0
  2. package/guide/agent/app-setup/existing-application-migration.md +30 -0
  3. package/guide/agent/app-setup/multi-homing.md +212 -0
  4. package/package.json +1 -1
  5. package/patterns/feature-package/example/booking-engine/package.json +1 -1
  6. package/patterns/minimal-foundation/example/package.json +4 -4
  7. package/patterns/shell-foundation/example/package.json +5 -5
  8. package/patterns/shell-foundation/example/packages/main/package.json +1 -1
  9. package/reference/autogen/PATTERN_INDEX.md +35 -35
  10. package/skills/jskit/SKILL.md +3 -3
  11. package/skills/jskit/references/existing-application-migration.md +30 -0
  12. package/skills/jskit/references/multi-homing.md +274 -0
  13. package/skills/jskit/references/pattern-index.md +35 -35
  14. package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +4 -4
  15. package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +5 -5
  16. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
  17. package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
  18. package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
  19. package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +2 -2
  20. package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
  21. package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
  22. package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
  23. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +1 -1
  24. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +2 -2
  25. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +3 -3
  26. package/skills/jskit/references/patterns/workspaces/workspace-server/PATTERN.md +49 -0
@@ -15,7 +15,7 @@ A concrete Fastify, Vue, and JSKIT application foundation for products that do n
15
15
 
16
16
  - Id: `app/minimal-foundation`
17
17
  - Keywords: `app`, `fastify`, `foundation`, `minimal`, `server`, `vite`, `vue`
18
- - Owner: `@jskit-ai/agent-docs@0.1.190`
18
+ - Owner: `@jskit-ai/agent-docs@0.1.192`
19
19
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md)
20
20
  - Examples: [example/](../../skills/jskit/references/patterns/app/minimal-foundation/example/)
21
21
  - Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`
@@ -26,7 +26,7 @@ A concrete JSKIT web application foundation with responsive shell navigation, se
26
26
 
27
27
  - Id: `app/shell-foundation`
28
28
  - Keywords: `app`, `foundation`, `material`, `navigation`, `placements`, `shell`, `vite`, `vue`
29
- - Owner: `@jskit-ai/agent-docs@0.1.190`
29
+ - Owner: `@jskit-ai/agent-docs@0.1.192`
30
30
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/app/shell-foundation/PATTERN.md)
31
31
  - Examples: [example/](../../skills/jskit/references/patterns/app/shell-foundation/example/)
32
32
  - Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`, `@jskit-ai/shell-web`
@@ -37,7 +37,7 @@ Configure an assistant runtime for one application surface and expose its chat a
37
37
 
38
38
  - Id: `assistant/assistant-surface`
39
39
  - Keywords: `ai`, `assistant`, `chat`, `config`, `environment`, `page`, `placement`, `settings`, `surface`
40
- - Owner: `@jskit-ai/assistant-runtime@0.1.189`
40
+ - Owner: `@jskit-ai/assistant-runtime@0.1.191`
41
41
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/assistant/assistant-surface/PATTERN.md)
42
42
  - Examples: [example/](../../skills/jskit/references/patterns/assistant/assistant-surface/example/)
43
43
  - Requires: `@jskit-ai/assistant-runtime`, `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`, `@jskit-ai/shell-web`
@@ -48,7 +48,7 @@ Compose JSKIT authentication routes, views, profile controls, and public surface
48
48
 
49
49
  - Id: `auth/auth-surface`
50
50
  - Keywords: `account`, `auth`, `login`, `logout`, `password`, `placement`, `profile`, `reset`, `surface`
51
- - Owner: `@jskit-ai/auth-web@0.1.218`
51
+ - Owner: `@jskit-ai/auth-web@0.1.220`
52
52
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/auth/auth-surface/PATTERN.md)
53
53
  - Examples: [example/](../../skills/jskit/references/patterns/auth/auth-surface/example/)
54
54
  - Requires: `@jskit-ai/auth-core`, `@jskit-ai/auth-web`, `@jskit-ai/shell-web`
@@ -59,7 +59,7 @@ Add Supabase authentication through normal npm composition, explicit environment
59
59
 
60
60
  - Id: `auth/supabase-auth`
61
61
  - Keywords: `auth`, `authentication`, `oauth`, `sessions`, `supabase`
62
- - Owner: `@jskit-ai/auth-provider-supabase-core@0.1.215`
62
+ - Owner: `@jskit-ai/auth-provider-supabase-core@0.1.217`
63
63
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/auth/supabase-auth/PATTERN.md)
64
64
  - Examples: [example/](../../skills/jskit/references/patterns/auth/supabase-auth/example/)
65
65
  - Requires: `@jskit-ai/auth-provider-supabase-core`
@@ -70,7 +70,7 @@ Resolve an administrator environment key or an individual user's grant, then use
70
70
 
71
71
  - Id: `connectors/ai-connections`
72
72
  - Keywords: `ai`, `api-key`, `big-pickle`, `cli`, `environment`, `free`, `models`, `ownership`, `zai`, `zen`
73
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
73
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
74
74
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/ai-connections/PATTERN.md)
75
75
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/ai-connections/example/)
76
76
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -81,7 +81,7 @@ Compose provider operations, authorization and encrypted file storage from a CLI
81
81
 
82
82
  - Id: `connectors/api-key-connection`
83
83
  - Keywords: `api-key`, `clay`, `cli`, `clickhouse`, `connectors`, `dbt`, `files`, `firecrawl`, `granola`, `integrations`, `metrics`, `prestashop`, `resend`, `semantic-layer`, `semrush`, `x-twitter`
84
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
84
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
85
85
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/api-key-connection/PATTERN.md)
86
86
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/api-key-connection/example/)
87
87
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -92,7 +92,7 @@ Compose token-based MCP discovery and explicitly authorized tool calls using the
92
92
 
93
93
  - Id: `connectors/assistant-mcp`
94
94
  - Keywords: `assistant`, `cli`, `connectors`, `files`, `integrations`, `mcp`, `n8n`, `sanity`
95
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
95
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
96
96
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/assistant-mcp/PATTERN.md)
97
97
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/assistant-mcp/example/)
98
98
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -103,7 +103,7 @@ Configure assistant OAuth clients, then compose existing state, encrypted file g
103
103
 
104
104
  - Id: `connectors/assistant-mcp-oauth`
105
105
  - Keywords: `amplitude`, `assistant`, `atlassian`, `canva`, `cli`, `client metadata`, `confidence`, `connectors`, `figma`, `files`, `granola`, `hex`, `mcp`, `miro`, `oauth`
106
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
106
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
107
107
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/assistant-mcp-oauth/PATTERN.md)
108
108
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/assistant-mcp-oauth/example/)
109
109
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -114,7 +114,7 @@ Compose signed AWS operations, file configuration and application authorization
114
114
 
115
115
  - Id: `connectors/aws-storage-queries`
116
116
  - Keywords: `athena`, `aws`, `cli`, `connectors`, `files`, `iam`, `queries`, `s3`, `storage`, `sts`
117
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
117
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
118
118
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/aws-storage-queries/PATTERN.md)
119
119
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/aws-storage-queries/example/)
120
120
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -125,7 +125,7 @@ Compose reusable connection libraries with portable configuration, application o
125
125
 
126
126
  - Id: `connectors/calendar-cli`
127
127
  - Keywords: `calendar`, `cli`, `connectors`, `google`, `integrations`, `oauth`, `permissions`
128
- - Owner: `@jskit-ai/connector-google-calendar@0.1.35`
128
+ - Owner: `@jskit-ai/connector-google-calendar@0.1.37`
129
129
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/calendar-cli/PATTERN.md)
130
130
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/calendar-cli/example/)
131
131
  - Requires: `@jskit-ai/connector-google-calendar`, `@jskit-ai/connectors-core`, `@jskit-ai/database-runtime-mysql`
@@ -136,7 +136,7 @@ Compose the shared connector runtime for event delivery while leaving workflow c
136
136
 
137
137
  - Id: `connectors/event-delivery`
138
138
  - Keywords: `cli`, `connectors`, `events`, `files`, `inngest`, `integrations`, `workflows`
139
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
139
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
140
140
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/event-delivery/PATTERN.md)
141
141
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/event-delivery/example/)
142
142
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -147,7 +147,7 @@ Wire service-account grants, file storage, explicit message actions and public b
147
147
 
148
148
  - Id: `connectors/firebase-messaging`
149
149
  - Keywords: `cli`, `connectors`, `fcm`, `files`, `firebase`, `integrations`, `jwt`, `notifications`, `push`, `service-account`, `vapid`
150
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
150
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
151
151
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/firebase-messaging/PATTERN.md)
152
152
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/firebase-messaging/example/)
153
153
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -158,7 +158,7 @@ Compose reviewed Search campaigns with project-owned Google OAuth and portable s
158
158
 
159
159
  - Id: `connectors/google-ads-search`
160
160
  - Keywords: `ads`, `campaigns`, `cli`, `connectors`, `conversion`, `google`, `search`
161
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
161
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
162
162
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/google-ads-search/PATTERN.md)
163
163
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/google-ads-search/example/)
164
164
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -169,7 +169,7 @@ Compose provider consent, verification and encrypted file persistence from an ap
169
169
 
170
170
  - Id: `connectors/oauth-connection`
171
171
  - Keywords: `accounting`, `assistant permissions`, `books`, `cli`, `client credentials`, `connectors`, `consent`, `crm`, `databricks`, `developer token`, `fabric`, `files`, `gaql`, `google ads`, `graphql`, `integrations`, `linkedin`, `microsoft`, `oauth`, `powerpoint`, `salesforce`, `service principal`, `shopify`, `soql`, `staffing`, `tiktok`, `twitch`, `wave`, `word`, `wordpress`, `workday`, `xero`, `zoho`
172
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
172
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
173
173
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/oauth-connection/PATTERN.md)
174
174
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/oauth-connection/example/)
175
175
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -180,7 +180,7 @@ Compose a sequential catalogue batch and preserve partial success for applicatio
180
180
 
181
181
  - Id: `connectors/paddle-catalogue`
182
182
  - Keywords: `batch`, `paddle`, `payments`, `prices`, `products`
183
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
183
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
184
184
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/paddle-catalogue/PATTERN.md)
185
185
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/paddle-catalogue/example/)
186
186
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -191,7 +191,7 @@ Resolve a publishable image key deliberately and use the shared URL library in a
191
191
 
192
192
  - Id: `connectors/public-image`
193
193
  - Keywords: `cli`, `connectors`, `files`, `images`, `integrations`, `logo-dev`, `public-key`
194
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
194
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
195
195
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/public-image/PATTERN.md)
196
196
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/public-image/example/)
197
197
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -202,7 +202,7 @@ Compose file configuration, Redshift Data API operations and application query o
202
202
 
203
203
  - Id: `connectors/redshift-queries`
204
204
  - Keywords: `aws`, `cli`, `connectors`, `files`, `iam`, `provisioned`, `redshift`, `serverless`, `sql`, `warehouse`
205
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
205
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
206
206
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/redshift-queries/PATTERN.md)
207
207
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/redshift-queries/example/)
208
208
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -213,7 +213,7 @@ Use the shared scanner runtime from a CLI or a host worker with portable configu
213
213
 
214
214
  - Id: `connectors/source-scanning`
215
215
  - Keywords: `cancellation`, `cli`, `connectors`, `integrations`, `scanning`, `security`, `source`, `wiz`, `worker`
216
- - Owner: `@jskit-ai/connectors-catalog@0.1.35`
216
+ - Owner: `@jskit-ai/connectors-catalog@0.1.37`
217
217
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/connectors/source-scanning/PATTERN.md)
218
218
  - Examples: [example/](../../skills/jskit/references/patterns/connectors/source-scanning/example/)
219
219
  - Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
@@ -224,7 +224,7 @@ Add a protected administration surface, settings shell, and semantic navigation
224
224
 
225
225
  - Id: `console/console-surface`
226
226
  - Keywords: `admin`, `console`, `navigation`, `owner`, `placement`, `settings`, `surface`
227
- - Owner: `@jskit-ai/console-web@0.1.186`
227
+ - Owner: `@jskit-ai/console-web@0.1.188`
228
228
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/console/console-surface/PATTERN.md)
229
229
  - Examples: [example/](../../skills/jskit/references/patterns/console/console-surface/example/)
230
230
  - Requires: `@jskit-ai/console-core`, `@jskit-ai/console-web`, `@jskit-ai/shell-web`
@@ -235,7 +235,7 @@ Build a routed CRUD user interface as thin application pages over JSKIT's shared
235
235
 
236
236
  - Id: `crud/crud-screen-set`
237
237
  - Keywords: `actions`, `add`, `crud`, `delete`, `edit`, `filters`, `list`, `material`, `routes`, `view`, `vue`
238
- - Owner: `@jskit-ai/http-web@0.1.63`
238
+ - Owner: `@jskit-ai/http-web@0.1.65`
239
239
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md)
240
240
  - Examples: [example/](../../skills/jskit/references/patterns/crud/crud-screen-set/example/)
241
241
  - Requires: `@jskit-ai/http-web`, `@jskit-ai/resource-crud-core`
@@ -246,7 +246,7 @@ Build a complete application-owned CRUD server package from a migration, resourc
246
246
 
247
247
  - Id: `crud/json-api-resource-package`
248
248
  - Keywords: `actions`, `crud`, `database`, `json-api`, `migration`, `permissions`, `provider`, `repository`, `routes`, `service`
249
- - Owner: `@jskit-ai/crud-core@0.1.229`
249
+ - Owner: `@jskit-ai/crud-core@0.1.231`
250
250
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/crud/json-api-resource-package/PATTERN.md)
251
251
  - Examples: [example/](../../skills/jskit/references/patterns/crud/json-api-resource-package/example/)
252
252
  - Requires: `@jskit-ai/crud-core`, `@jskit-ai/resource-crud-core`
@@ -257,7 +257,7 @@ Define an authenticated application resource whose records belong to the current
257
257
 
258
258
  - Id: `crud/resource-contract`
259
259
  - Keywords: `authenticated`, `crud`, `database`, `owner-scoped`, `resource`, `user`
260
- - Owner: `@jskit-ai/resource-crud-core@0.1.160`
260
+ - Owner: `@jskit-ai/resource-crud-core@0.1.162`
261
261
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/crud/resource-contract/PATTERN.md)
262
262
  - Examples: [example/](../../skills/jskit/references/patterns/crud/resource-contract/example/)
263
263
  - Requires: `@jskit-ai/resource-crud-core`
@@ -268,7 +268,7 @@ Configure a JSKIT application for MySQL with a fixed driver, ordinary environmen
268
268
 
269
269
  - Id: `database/mysql-application`
270
270
  - Keywords: `database`, `knex`, `mariadb`, `migrations`, `mysql`, `mysql2`
271
- - Owner: `@jskit-ai/database-runtime-mysql@0.1.216`
271
+ - Owner: `@jskit-ai/database-runtime-mysql@0.1.218`
272
272
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/database/mysql-application/PATTERN.md)
273
273
  - Examples: [example/](../../skills/jskit/references/patterns/database/mysql-application/example/)
274
274
  - Requires: `@jskit-ai/database-runtime-mysql`
@@ -279,7 +279,7 @@ Configure a JSKIT application for PostgreSQL with a fixed driver, ordinary envir
279
279
 
280
280
  - Id: `database/postgres-application`
281
281
  - Keywords: `database`, `knex`, `migrations`, `pg`, `postgres`, `postgresql`
282
- - Owner: `@jskit-ai/database-runtime-postgres@0.1.215`
282
+ - Owner: `@jskit-ai/database-runtime-postgres@0.1.217`
283
283
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/database/postgres-application/PATTERN.md)
284
284
  - Examples: [example/](../../skills/jskit/references/patterns/database/postgres-application/example/)
285
285
  - Requires: `@jskit-ai/database-runtime-postgres`
@@ -290,7 +290,7 @@ Wrap a JSKIT web application in a Capacitor Android shell using native Capacitor
290
290
 
291
291
  - Id: `mobile/android-application`
292
292
  - Keywords: `android`, `capacitor`, `device`, `mobile`, `native`, `shell`, `webview`
293
- - Owner: `@jskit-ai/mobile-capacitor@0.1.153`
293
+ - Owner: `@jskit-ai/mobile-capacitor@0.1.155`
294
294
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/mobile/android-application/PATTERN.md)
295
295
  - Examples: [example/](../../skills/jskit/references/patterns/mobile/android-application/example/)
296
296
  - Requires: `@capacitor/android`, `@capacitor/app`, `@capacitor/cli`, `@jskit-ai/mobile-capacitor`
@@ -301,7 +301,7 @@ Add JSKIT realtime events with an optional Redis backplane and an explicit shell
301
301
 
302
302
  - Id: `realtime/realtime-application`
303
303
  - Keywords: `realtime`, `redis`, `socket.io`, `sockets`, `status`, `websocket`
304
- - Owner: `@jskit-ai/realtime@0.1.215`
304
+ - Owner: `@jskit-ai/realtime@0.1.217`
305
305
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/realtime/realtime-application/PATTERN.md)
306
306
  - Examples: [example/](../../skills/jskit/references/patterns/realtime/realtime-application/example/)
307
307
  - Requires: `@jskit-ai/realtime`, `@jskit-ai/shell-web`
@@ -312,7 +312,7 @@ Compose application-owned Google Publisher Tag delivery with the generic rewarde
312
312
 
313
313
  - Id: `rewards/google-rewarded`
314
314
  - Keywords: `ads`, `google`, `publisher tag`, `rewarded`, `unlock`
315
- - Owner: `@jskit-ai/rewarded-web@0.1.154`
315
+ - Owner: `@jskit-ai/rewarded-web@0.1.156`
316
316
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/rewards/google-rewarded/PATTERN.md)
317
317
  - Examples: [example/](../../skills/jskit/references/patterns/rewards/google-rewarded/example/)
318
318
  - Requires: `@jskit-ai/rewarded-web`
@@ -323,7 +323,7 @@ Define a server feature through explicit capabilities and first-class actions, a
323
323
 
324
324
  - Id: `server/feature-package`
325
325
  - Keywords: `actions`, `feature`, `json-rest`, `knex`, `orchestration`, `package`, `provider`, `repository`, `routes`, `server`
326
- - Owner: `@jskit-ai/agent-docs@0.1.190`
326
+ - Owner: `@jskit-ai/agent-docs@0.1.192`
327
327
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/server/feature-package/PATTERN.md)
328
328
  - Examples: [example/](../../skills/jskit/references/patterns/server/feature-package/example/)
329
329
  - Requires: `@jskit-ai/kernel`
@@ -334,7 +334,7 @@ Compose the JSKIT responsive shell, semantic placements, settings navigation, an
334
334
 
335
335
  - Id: `shell/application-shell`
336
336
  - Keywords: `adaptive`, `app`, `layout`, `navigation`, `placement`, `responsive`, `settings`, `shell`
337
- - Owner: `@jskit-ai/shell-web@0.1.222`
337
+ - Owner: `@jskit-ai/shell-web@0.1.224`
338
338
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/shell/application-shell/PATTERN.md)
339
339
  - Examples: [example/](../../skills/jskit/references/patterns/shell/application-shell/example/)
340
340
  - Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
@@ -345,7 +345,7 @@ Add product routes and shell extensions through file routing, semantic placement
345
345
 
346
346
  - Id: `ui/page-and-placement`
347
347
  - Keywords: `component`, `navigation`, `outlet`, `page`, `placement`, `routes`, `section`, `shell`, `subpages`, `vue`
348
- - Owner: `@jskit-ai/shell-web@0.1.222`
348
+ - Owner: `@jskit-ai/shell-web@0.1.224`
349
349
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/ui/page-and-placement/PATTERN.md)
350
350
  - Examples: [example/](../../skills/jskit/references/patterns/ui/page-and-placement/example/)
351
351
  - Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
@@ -356,7 +356,7 @@ Compose an account settings route and profile, preference, and notification sect
356
356
 
357
357
  - Id: `users/account-settings`
358
358
  - Keywords: `account`, `notifications`, `preferences`, `profile`, `settings`, `user`, `vue`
359
- - Owner: `@jskit-ai/users-web@0.1.236`
359
+ - Owner: `@jskit-ai/users-web@0.1.238`
360
360
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/users/account-settings/PATTERN.md)
361
361
  - Examples: [example/](../../skills/jskit/references/patterns/users/account-settings/example/)
362
362
  - Requires: `@jskit-ai/shell-web`, `@jskit-ai/users-core`, `@jskit-ai/users-web`
@@ -367,7 +367,7 @@ Expose user administration and workspace-scoped member operations through app-ow
367
367
 
368
368
  - Id: `users/user-administration-server`
369
369
  - Keywords: `account`, `admin`, `member`, `repository`, `resource`, `routes`, `service`, `user`, `workspace`
370
- - Owner: `@jskit-ai/users-core@0.1.231`
370
+ - Owner: `@jskit-ai/users-core@0.1.233`
371
371
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/users/user-administration-server/PATTERN.md)
372
372
  - Examples: [example/](../../skills/jskit/references/patterns/users/user-administration-server/example/)
373
373
  - Requires: `@jskit-ai/crud-core`, `@jskit-ai/users-core`
@@ -378,7 +378,7 @@ Configure roles, workspace access policy, invitations, and app-owned invitation
378
378
 
379
379
  - Id: `workspaces/workspace-server`
380
380
  - Keywords: `access`, `invite`, `membership`, `multitenancy`, `policy`, `role`, `tenancy`, `workspace`
381
- - Owner: `@jskit-ai/workspaces-core@0.1.196`
381
+ - Owner: `@jskit-ai/workspaces-core@0.1.198`
382
382
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/workspaces/workspace-server/PATTERN.md)
383
383
  - Examples: [example/](../../skills/jskit/references/patterns/workspaces/workspace-server/example/)
384
384
  - Requires: `@jskit-ai/users-core`, `@jskit-ai/workspaces-core`
@@ -389,7 +389,7 @@ Compose workspace selection, invitation, member administration, settings, and re
389
389
 
390
390
  - Id: `workspaces/workspace-surfaces`
391
391
  - Keywords: `admin`, `invite`, `member`, `navigation`, `settings`, `surface`, `switcher`, `workspace`
392
- - Owner: `@jskit-ai/workspaces-web@0.1.197`
392
+ - Owner: `@jskit-ai/workspaces-web@0.1.199`
393
393
  - Read: [PATTERN.md](../../skills/jskit/references/patterns/workspaces/workspace-surfaces/PATTERN.md)
394
394
  - Examples: [example/](../../skills/jskit/references/patterns/workspaces/workspace-surfaces/example/)
395
395
  - Requires: `@jskit-ai/shell-web`, `@jskit-ai/workspaces-core`, `@jskit-ai/workspaces-web`
@@ -31,9 +31,9 @@ manifests, migrations, tests, and runtime behaviour are the evidence.
31
31
  existing tree, and the current diff when reviewing changes.
32
32
  3. Read the project's product documentation and current source. JSKIT does not
33
33
  own a second project brain or prescribe a particular agent orchestrator.
34
- 4. Load only the task-relevant direct reference:
35
- - Existing-app migration: read
36
- [port guide](references/existing-application-migration.md).
34
+ 4. Load only relevant references:
35
+ - [port guide](references/existing-application-migration.md) for existing apps.
36
+ - [Tenancy/invitations](references/multi-homing.md).
37
37
  - For creation, foundation patterns, or package selection, read
38
38
  [application operations](references/app-operations.md).
39
39
  - Before database, schema, CRUD, repository, or persistence work, read
@@ -217,6 +217,36 @@ not undo the write. Do not turn pending, committed, or unknown write failures
217
217
  into successful missing-record results, or automatically replay a committed
218
218
  or unresolved write.
219
219
 
220
+ ### Workspace invitation transaction compatibility (workspaces-core 0.1.198)
221
+
222
+ Workspace invitation creation, acceptance and refusal now own managed
223
+ transactions. Existing calls to `members.createInvite(..., { trx })` must become
224
+ `members.prepareInvite(..., { trx })`, application association/receipt writes,
225
+ confirmed commit, then `members.sendInvite(...)` without `trx`. Move writes that
226
+ must accompany built-in acceptance into
227
+ `pendingInvitations.registerAcceptanceParticipant(fn)` during feature setup.
228
+ Acceptance/refusal reject borrowed transactions; revocation can still participate
229
+ in a managed transaction. Ordinary invitation actions retain their IDs and
230
+ response shapes. Terminal repository transitions now reject instead of
231
+ rewriting already accepted/revoked invitations. Mailer exceptions return a fixed
232
+ message to avoid leaking invitation tokens from provider diagnostics.
233
+
234
+ Required participant writes roll back together. Preserve transaction outcomes:
235
+ a failure after commit is not rollback, and an unresolved commit must not be
236
+ blindly replayed. Matching-recipient expiry revocation deliberately commits
237
+ before its 409 rejection. Review the
238
+ [workspace invitation contract and example](./multi-homing.md#transactional-invitation-participation)
239
+ when migrating. No schema migration is required for these framework APIs.
240
+
241
+ The first coordinated release containing this contract includes
242
+ `@jskit-ai/workspaces-core@0.1.198`, `@jskit-ai/jskit-catalog@0.1.245` and
243
+ `@jskit-ai/agent-docs@0.1.192`. Once that release is published, use
244
+ `npm run jskit:update` in the application to upgrade the coordinated graph,
245
+ restart the backend, check the actual installed versions, and assert
246
+ that `prepareInvite`, `sendInvite` and `registerAcceptanceParticipant` are present
247
+ on the resolved capability. Application domain integration and real email
248
+ activation remain separate work.
249
+
220
250
  ## 4. Adopt migrations without breaking either database history
221
251
 
222
252
  Every immutable migration belongs to the package that owns its tables. Declare
@@ -0,0 +1,274 @@
1
+ <!-- Generated from `packages/agent-docs/site/guide/app-setup/multi-homing.md` by `npm run agent-docs:build`. -->
2
+
3
+ # Workspace tenancy
4
+
5
+ Use JSKIT workspaces when routes, records, or permissions belong to a selected
6
+ workspace and membership or role changes access.
7
+
8
+ ```bash
9
+ npm install @jskit-ai/workspaces-web
10
+ npm run db:migrate
11
+ ```
12
+
13
+ The dependency graph supplies `workspaces-core` and the required users runtime.
14
+ Package migrations run from their installed locations through the application's
15
+ normal Knex command.
16
+
17
+ ## Decide the tenancy model first
18
+
19
+ Choose whether the product is:
20
+
21
+ - global, with no workspace concept;
22
+ - personal, with one automatically provisioned personal workspace; or
23
+ - multi-workspace, with named workspaces, membership, invitations, and
24
+ switching.
25
+
26
+ Do not add workspace machinery to a product that only needs an owner id on one
27
+ domain record.
28
+
29
+ ## Server composition
30
+
31
+ Use `workspaces/workspace-server` for role vocabulary, creation policy,
32
+ invitations, settings, and app-owned invitation email rendering.
33
+
34
+ Workspace scope must reach repository queries. Parsing a workspace slug or
35
+ hiding an admin link is not authorization. Membership and role checks happen
36
+ before an operation discloses records or record existence.
37
+
38
+ `workspace_authenticated` and similar policies must implement their documented
39
+ membership semantics exactly; do not synthesize memberships to compensate for
40
+ a policy/runtime mismatch.
41
+
42
+ ## Transactional invitation participation
43
+
44
+ Use the existing `workspaces.core` capability when accepting an invitation must
45
+ also connect an application-owned identity, training history, access scopes or
46
+ required audit records. JSKIT owns tokens, invitation state and membership; the
47
+ application owns its reviewed association and domain policy. The built-in
48
+ `workspace.invite.redeem` action runs the participant. No replacement route,
49
+ client follow-up save or after-action event is needed.
50
+
51
+ Saving intended access without sending remains an application draft. Do not call
52
+ preparation until an administrator deliberately issues an invitation: preparation
53
+ creates a real token and pending invitation, but does not activate membership.
54
+
55
+ ### Public server methods
56
+
57
+ These methods are trusted server composition APIs, not new public actions. The
58
+ caller must authorize creation, delivery and revocation in the requested workspace.
59
+ The ordinary invitation routes retain their existing authorization and role
60
+ validation. Do not forward arbitrary HTTP input as server composition options.
61
+
62
+ | Capability method | Contract |
63
+ | --- | --- |
64
+ | `workspaces.repositories.workspaceInvites.withTransaction(work)` | Delegates to the same JSON REST API's managed `transaction(work)`; awaits commit and completion hooks before resolving. |
65
+ | `workspaces.repositories.workspaceInvites.lockWorkspaceForInvitations(workspaceId, { trx })` | Locks the workspace before application receipt/draft rows when composing preparation. Requires an active transaction. |
66
+ | `workspaces.services.members.prepareInvite(workspace, actor, payload, options)` | Requires a managed `options.trx`. Validates the invitation role, replaces pending invitations for that workspace/email, and returns `{ createdInviteId, inviteTokenPreview }`. Never sends. |
67
+ | `workspaces.services.members.sendInvite(workspace, actor, prepared, options)` | Requires no `options.trx`. Reloads the committed pending invitation and workspace display data, validates expiry and token correspondence, and sends that invitation without replacement. |
68
+ | `workspaces.services.members.createInvite(workspace, actor, payload, options)` | Owns preparation and commit, then calls `sendInvite`; retains the ordinary response shape. Rejects `options.trx`. |
69
+ | `workspaces.services.pendingInvitations.registerAcceptanceParticipant(fn)` | Registers one application callback receiving `({ invite, user }, options)`. Invalid, duplicate and late registration reject. |
70
+
71
+ `sendInvite` accepts `{ createdInviteId, inviteTokenPreview }` from preparation or
72
+ only `{ createdInviteId }` for a later attempt. The latter uses JSKIT's existing
73
+ opaque token-hash encoding without rotating the token. Supplying an empty or
74
+ mismatched token rejects. Email, role, expiry and workspace display fields come
75
+ from the stored invitation/workspace, not replacement input. Its response keeps
76
+ `createdInviteId`, `inviteTokenPreview`, `inviteUrl` and `inviteDelivery` alongside
77
+ the ordinary workspace/invitation-list payload. Treat tokens and URLs as secrets;
78
+ do not log them or put them in diagnostic messages or administrative receipts.
79
+ A receipt normally needs only the exact invitation ID.
80
+
81
+ ### Preparation, association, commit and controlled delivery
82
+
83
+ Inside application feature setup, declare `workspaces: "workspaces.core"` in
84
+ `requires`, then use that capability. The `reviewedPeople`, `people`, `scopes`
85
+ and `audit` names below represent application-owned services, not JSKIT APIs.
86
+ Their writes must forward the provided transaction to their repositories.
87
+
88
+ ```js
89
+ // During application Feature.setup, before serving requests:
90
+ const { members, pendingInvitations } = workspaces.services;
91
+ const invites = workspaces.repositories.workspaceInvites;
92
+
93
+ pendingInvitations.registerAcceptanceParticipant(async ({ invite, user }, options) => {
94
+ // Resolve from the exact validated invitation, never a client person ID.
95
+ const association = await reviewedPeople.resolveInvitation(invite.id, options);
96
+ if (association.kind === "ordinary") return;
97
+ await reviewedPeople.requireCurrentReview(association, {
98
+ workspaceId: invite.workspaceId,
99
+ user,
100
+ roleSid: invite.roleSid
101
+ }, options);
102
+ await people.linkAccountAndTraining(association.personId, user.id, options);
103
+ await scopes.applyReviewedAccess(association, user.id, options);
104
+ await audit.recordInvitationAcceptance(association, user.id, options);
105
+ });
106
+
107
+ // Inside an authorized application command:
108
+ const prepared = await invites.withTransaction(async (trx) => {
109
+ const options = { trx, context };
110
+ // Match acceptance's order: workspace, then application draft/receipt rows.
111
+ await invites.lockWorkspaceForInvitations(workspace.id, options);
112
+ const reviewed = await reviewedPeople.lockAuthorizedDraft(draftId, workspace.id, actor, options);
113
+ const receipt = await reviewedPeople.findMatchingReceipt(reviewed, requestId, options);
114
+ if (receipt) return { createdInviteId: receipt.inviteId };
115
+ const created = await members.prepareInvite(workspace, actor, {
116
+ email: reviewed.email,
117
+ roleSid: reviewed.roleSid
118
+ }, options);
119
+ await reviewedPeople.associateInvitationAndSaveReceipt(reviewed, requestId, created.createdInviteId, options);
120
+ return { createdInviteId: created.createdInviteId };
121
+ }); // Confirmed commit; a rejection here must not fall through to delivery.
122
+
123
+ const result = await members.sendInvite(workspace, actor, prepared, { context });
124
+ // Persist delivery feedback through the application owner. Avoid logging result:
125
+ // it contains a secret token and URL as well as the nonsecret delivery outcome.
126
+ await reviewedPeople.recordDeliveryOutcome(prepared.createdInviteId, result.inviteDelivery, { context });
127
+ ```
128
+
129
+ The application must lock its reviewed draft/receipt, enforce request identity,
130
+ and reject changed input on a reused request ID. A retry after losing the
131
+ preparation response reads that receipt instead of preparing another invitation.
132
+ Association failure rolls back the new invitation, replacement of an older
133
+ invitation, receipt and application writes. This is not generic framework
134
+ idempotency, and does not imply exactly-once email.
135
+
136
+ Real SMTP is unnecessary for implementation and verification. With no
137
+ `workspaceInviteMailer`, delivery returns `status: "mailer_unconfigured"`, an
138
+ explanatory `message` and an empty `providerMessageId`; the invitation remains
139
+ committed. A test application can configure a controlled mailer:
140
+
141
+ ```js
142
+ workspaceInviteMailer: {
143
+ async sendWorkspaceInvite(message) {
144
+ capturedInvites.push(message); // Test-local memory; contains the secret link.
145
+ return { status: "sent", message: "Captured by test mailer.", providerMessageId: "fixture-1" };
146
+ }
147
+ }
148
+ ```
149
+
150
+ A thrown renderer/mailer error returns `inviteDelivery.status: "failed"` and a
151
+ fixed message, avoiding accidental token leakage through provider exceptions.
152
+ It does not delete the invitation/association or activate membership. Mailer
153
+ results retain their normalized status, message and provider message ID; a
154
+ successful default is `sent`. A provider exception or interrupted response may
155
+ occur after a provider accepted the message: `failed` is not proof of nondelivery.
156
+ There is no exactly-once delivery guarantee. Applications own durable delivery
157
+ attempts and safe retry policy. Validation checks committed invitation state
158
+ before sending; revocation after sending starts cannot recall the message.
159
+
160
+ ### Acceptance and failure semantics
161
+
162
+ Register one callback during feature setup. It composes any application domain
163
+ owners explicitly. Non-functions throw `TypeError`; a second registration
164
+ throws, and registration closes when acceptance/refusal first begins. The
165
+ callback's invite, user and options envelope are shallow frozen. It receives the
166
+ same managed `trx` and request `context`; transaction ownership stays with JSKIT.
167
+
168
+ Acceptance authenticates the user, checks email, pending state and expiry, then
169
+ revalidates the invitation under workspace/invitation locks. Membership is
170
+ available as active inside that transaction before the callback runs. Existing
171
+ role-upsert semantics remain: the stored invitation role becomes the membership
172
+ role, including for an existing membership. The callback cannot authorize role
173
+ or scope overrides from client input. It must recheck the reviewed version,
174
+ workspace, current inviter authority, person eligibility, existing account link,
175
+ and scope eligibility using application-owned data.
176
+
177
+ An ordinary invitation with no application association may pass through. A
178
+ stale, revoked, conflicting or expected-but-missing association must fail closed.
179
+ The application needs enough durable association/review state to distinguish
180
+ these cases; absence alone cannot identify a deleted reviewed association.
181
+
182
+ Await every owner write and forward the same transaction. Do not commit,
183
+ roll back, use savepoints, start a new transaction, or perform external side
184
+ effects in the callback. Do not swallow failures. Participant exceptions and
185
+ later invitation-status failures roll back membership (including its prior role
186
+ and status), person/training links, scopes, required audit and accepted status.
187
+ The callback is not invoked for an invalid invitation or on refusal. Acceptance
188
+ and refusal reject borrowed `options.trx`; revocation can join a managed
189
+ transaction or own one when none is supplied.
190
+
191
+ A missing/already-handled invitation rejects with 404; mismatched authenticated
192
+ email with 403; unauthenticated access with 401. An expired invitation for its
193
+ matching recipient is revoked in a committed transaction and then rejects with
194
+ 409 and `transactionOutcome: "committed"`. It never activates membership or
195
+ runs the participant. A failure to commit that revocation preserves the managed
196
+ transaction error instead. Delivery rejects missing/foreign/handled invitations
197
+ with 404, expired invitations with 409, and mismatched tokens with 400.
198
+
199
+ Keep `error.transactionOutcome` and `error.cause` when translating failures.
200
+ `rolledBack` confirms rollback; `committed` can indicate a completion-hook error
201
+ after successful persistence; `unknown` leaves the outcome unresolved. A thrown
202
+ error alone does not prove rollback. After-commit failures and external effects
203
+ cannot be included in the atomic guarantee. See
204
+ [managed transaction guidance](./existing-application-migration.md#json-rest-v2-integration).
205
+
206
+ Invitation mutations lock workspace before invitation rows, and use current
207
+ locking reads before terminal transitions. Accepted/revoked state cannot be
208
+ overwritten by a losing acceptance, refusal, revocation or replacement. A
209
+ replacement after acceptance may create a new pending invitation while retaining
210
+ the older accepted invitation. Keep callbacks short: invitation changes in the
211
+ same workspace serialize. Database deadlocks/serialization failures remain
212
+ transaction errors; callbacks are not automatically replayed.
213
+
214
+ ### Compatibility and verification
215
+
216
+ This server-composition contract starts with `@jskit-ai/workspaces-core@0.1.198`.
217
+ Transactional callers of
218
+ `createInvite` must migrate to preparation plus post-commit delivery. Related
219
+ acceptance writes must move into the participant. `markAcceptedById` and
220
+ `revokeById` now reject terminal/missing invitations rather than overwriting their
221
+ state. No route/action ID, package export, table or migration is added.
222
+
223
+ Verify ordinary invitations, rollback after each domain write, late framework
224
+ failure, existing membership restoration, recipient checks, stale associations,
225
+ controlled delivery failures and lost-response receipts. Run the normal redeem
226
+ action in tests. Use independent connections to race acceptance against acceptance,
227
+ refusal, revocation and replacement in both winning orders. The package fixture
228
+ runs these races on native MySQL/MariaDB and PostgreSQL; SQLite skips those races
229
+ and is not evidence of native locking correctness.
230
+
231
+ Use only a verified empty disposable database named
232
+ `jskit_repository_test_*` for native tests. The runner verifies the actual target,
233
+ reports its engine version, applies package migrations and drops fixture tables.
234
+
235
+ ```sh
236
+ node --test packages/workspaces-core/test/*.test.js
237
+ # Set JSKIT_REPOSITORY_TEST_DATABASE_URL to the verified empty disposable target.
238
+ node --test packages/workspaces-core/test/repositories.integration.test.js
239
+ npm run verify
240
+ ```
241
+
242
+ A passing framework fixture does not complete the application's People, training,
243
+ permissions, privacy or browser integration. Publication remains a separate
244
+ maintainer operation. After a coordinated release is published, run the
245
+ application's `npm run jskit:update`, restart its backend and verify that
246
+ `members.prepareInvite`, `members.sendInvite` and
247
+ `pendingInvitations.registerAcceptanceParticipant` are functions on the installed
248
+ `workspaces.core` capability. Check the installed package/catalogue versions
249
+ against that release. The first coordinated release containing this contract pairs
250
+ `@jskit-ai/workspaces-core@0.1.198`, `@jskit-ai/jskit-catalog@0.1.245` and
251
+ `@jskit-ai/agent-docs@0.1.192`. Upgrade the coordinated dependency graph rather
252
+ than pinning only `workspaces-core`. Do not patch installed `node_modules`.
253
+
254
+ ## Browser composition
255
+
256
+ Use `workspaces/workspace-surfaces` for workspace selection, invitation landing,
257
+ member administration, settings, not-found states, and semantic shell
258
+ placements.
259
+
260
+ The route slug, selected workspace, query keys, and server scope stay aligned.
261
+ Invalid workspace URLs show a deliberate not-found/forbidden state instead of
262
+ silently selecting another workspace.
263
+
264
+ Loading uses skeletons; mutation errors use toasts. Warm-cache and browser
265
+ back/forward navigation must restore the correct workspace context.
266
+
267
+ ## Verification
268
+
269
+ Test create/list/select, each role boundary, invitations and expiry,
270
+ cross-workspace isolation, invalid routes, direct URLs, switching, browser
271
+ back/forward, and responsive navigation.
272
+
273
+ Do not authorize from client state, add unscoped queries, or preserve old
274
+ tenancy setup through compatibility shims.