@jskit-ai/agent-docs 0.1.257 → 0.1.258

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 (230) hide show
  1. package/guide/agent/app-extras/assistant-conversation.md +88 -35
  2. package/guide/agent/app-extras/assistant.md +28 -28
  3. package/guide/agent/app-setup/authentication.md +36 -17
  4. package/guide/agent/app-setup/database-layer.md +116 -17
  5. package/guide/agent/app-setup/existing-application-migration.md +29 -25
  6. package/guide/agent/app-setup/multi-homing.md +94 -48
  7. package/guide/agent/app-setup/run-an-accounts-hub.md +6 -4
  8. package/guide/agent/framework/client-features.md +496 -0
  9. package/guide/agent/framework/crud-operations.md +5 -5
  10. package/guide/agent/framework/translation.md +4 -3
  11. package/guide/agent/framework/typed-features.md +1104 -0
  12. package/guide/agent/framework/ui-operations.md +2 -2
  13. package/guide/agent/index.md +6 -1
  14. package/package.json +1 -1
  15. package/patterns/feature-package/PATTERN.md +104 -10
  16. package/patterns/feature-package/example/booking-engine/package.json +9 -4
  17. package/patterns/feature-package/example/booking-engine/src/server/BookingEngineFeature.js +24 -0
  18. package/patterns/feature-package/example/booking-engine/src/server/bookingAvailability.js +10 -0
  19. package/patterns/feature-package/example/booking-engine/src/server/bookingEngine.js +29 -0
  20. package/patterns/feature-package/example/booking-engine/src/server/bookingEngineActions.js +26 -0
  21. package/patterns/feature-package/example/booking-engine/src/server/inputSchemas.js +1 -2
  22. package/patterns/feature-package/example/booking-engine/src/server/types.js +12 -0
  23. package/patterns/feature-package/example/variations/AvailabilityEngineFeature.js +19 -0
  24. package/patterns/feature-package/example/variations/InvoiceRollupFeature.js +23 -0
  25. package/patterns/feature-package/example/variations/availabilityEngineActions.js +26 -0
  26. package/patterns/feature-package/example/variations/customKnexRepository.js +32 -26
  27. package/patterns/feature-package/example/variations/invoiceRollupActions.js +26 -0
  28. package/patterns/feature-package/example/variations/orchestratorService.js +24 -19
  29. package/patterns/feature-package/example/variations/types.js +7 -0
  30. package/patterns/minimal-foundation/PATTERN.md +30 -1
  31. package/patterns/minimal-foundation/example/AGENTS.md +14 -0
  32. package/patterns/minimal-foundation/example/bin/develop.js +10 -5
  33. package/patterns/minimal-foundation/example/eslint.config.mjs +21 -2
  34. package/patterns/minimal-foundation/example/package.json +5 -4
  35. package/patterns/minimal-foundation/example/playwright.config.mjs +1 -1
  36. package/patterns/minimal-foundation/example/server/lib/envFile.js +19 -0
  37. package/patterns/minimal-foundation/example/server/lib/loggerOptions.js +15 -0
  38. package/patterns/minimal-foundation/example/server/lib/runtimeEnv.js +17 -17
  39. package/patterns/minimal-foundation/example/server.js +32 -29
  40. package/patterns/minimal-foundation/example/tests/server/smoke.test.js +2 -1
  41. package/patterns/shell-foundation/PATTERN.md +29 -0
  42. package/patterns/shell-foundation/example/AGENTS.md +14 -0
  43. package/patterns/shell-foundation/example/bin/develop.js +10 -5
  44. package/patterns/shell-foundation/example/eslint.config.mjs +21 -2
  45. package/patterns/shell-foundation/example/package.json +6 -5
  46. package/patterns/shell-foundation/example/packages/main/package.json +1 -1
  47. package/patterns/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +1 -0
  48. package/patterns/shell-foundation/example/playwright.config.mjs +1 -1
  49. package/patterns/shell-foundation/example/server/lib/envFile.js +19 -0
  50. package/patterns/shell-foundation/example/server/lib/loggerOptions.js +15 -0
  51. package/patterns/shell-foundation/example/server/lib/runtimeEnv.js +17 -17
  52. package/patterns/shell-foundation/example/server.js +32 -29
  53. package/patterns/shell-foundation/example/tests/server/smoke.test.js +2 -1
  54. package/reference/autogen/KERNEL_MAP.md +14 -8
  55. package/reference/autogen/PATTERN_INDEX.md +37 -37
  56. package/reference/autogen/README.md +2 -0
  57. package/reference/autogen/packages/agent-docs.md +70 -26
  58. package/reference/autogen/packages/agent-runtime.md +129 -0
  59. package/reference/autogen/packages/agent.md +149 -0
  60. package/reference/autogen/packages/architecture-inspector.md +97 -44
  61. package/reference/autogen/packages/assistant-core.md +786 -292
  62. package/reference/autogen/packages/assistant-runtime.md +182 -57
  63. package/reference/autogen/packages/assistant-voice-sherpa.md +4 -0
  64. package/reference/autogen/packages/assistant-voice.md +54 -8
  65. package/reference/autogen/packages/auth-core.md +44 -13
  66. package/reference/autogen/packages/auth-provider-local-core.md +86 -34
  67. package/reference/autogen/packages/auth-provider-local-db-core.md +1 -2
  68. package/reference/autogen/packages/auth-provider-oidc-core.md +10 -4
  69. package/reference/autogen/packages/auth-provider-supabase-core.md +52 -66
  70. package/reference/autogen/packages/auth-web.md +19 -11
  71. package/reference/autogen/packages/connectors-catalog.md +71 -43
  72. package/reference/autogen/packages/connectors-core.md +42 -4
  73. package/reference/autogen/packages/console-core.md +27 -14
  74. package/reference/autogen/packages/crud-core.md +178 -170
  75. package/reference/autogen/packages/database-runtime-mysql.md +0 -2
  76. package/reference/autogen/packages/database-runtime-postgres.md +0 -2
  77. package/reference/autogen/packages/database-runtime.md +39 -10
  78. package/reference/autogen/packages/http-runtime.md +79 -57
  79. package/reference/autogen/packages/json-rest-api-core.md +11 -8
  80. package/reference/autogen/packages/kernel.md +144 -83
  81. package/reference/autogen/packages/oidc-issuer-core.md +49 -20
  82. package/reference/autogen/packages/payments-core.md +20 -3
  83. package/reference/autogen/packages/realtime.md +47 -22
  84. package/reference/autogen/packages/resource-core.md +1 -1
  85. package/reference/autogen/packages/resource-crud-core.md +64 -26
  86. package/reference/autogen/packages/rewarded-core.md +47 -36
  87. package/reference/autogen/packages/shell-web.md +7 -10
  88. package/reference/autogen/packages/storage-runtime.md +6 -2
  89. package/reference/autogen/packages/uploads-runtime.md +10 -2
  90. package/reference/autogen/packages/users-core.md +73 -71
  91. package/reference/autogen/packages/workspaces-core.md +121 -106
  92. package/reference/autogen/packages/workspaces-web.md +1 -2
  93. package/reference/autogen/tooling/config-eslint.md +302 -0
  94. package/reference/autogen/tooling/jskit-catalog.md +28 -18
  95. package/reference/autogen/tooling/jskit-release.md +35 -20
  96. package/reference/autogen/tooling/testUtils.md +3 -1
  97. package/skills/jskit/SKILL.md +3 -2
  98. package/skills/jskit/references/app-operations.md +1 -1
  99. package/skills/jskit/references/client-features.md +491 -0
  100. package/skills/jskit/references/crud-form-actions.md +1 -1
  101. package/skills/jskit/references/crud-operations.md +7 -7
  102. package/skills/jskit/references/existing-application-migration.md +31 -27
  103. package/skills/jskit/references/heuristics/INDEX.md +5 -1
  104. package/skills/jskit/references/heuristics/child-cruds.md +1 -1
  105. package/skills/jskit/references/heuristics/client-features.md +66 -0
  106. package/skills/jskit/references/heuristics/client-requests.md +1 -1
  107. package/skills/jskit/references/heuristics/crud-authoring.md +12 -2
  108. package/skills/jskit/references/heuristics/crud-links.md +1 -1
  109. package/skills/jskit/references/heuristics/crud-repository-mapping.md +3 -3
  110. package/skills/jskit/references/heuristics/filters.md +1 -1
  111. package/skills/jskit/references/heuristics/live-actions.md +1 -1
  112. package/skills/jskit/references/heuristics/page-redirects.md +1 -1
  113. package/skills/jskit/references/heuristics/page-scaffolding.md +1 -1
  114. package/skills/jskit/references/heuristics/placements.md +1 -1
  115. package/skills/jskit/references/heuristics/row-policies.md +1 -1
  116. package/skills/jskit/references/heuristics/server-search.md +1 -1
  117. package/skills/jskit/references/heuristics/surfaces.md +1 -1
  118. package/skills/jskit/references/heuristics/typed-features.md +100 -0
  119. package/skills/jskit/references/heuristics/ui-contract.md +1 -1
  120. package/skills/jskit/references/heuristics/ui-testing.md +4 -4
  121. package/skills/jskit/references/material-3.md +2 -2
  122. package/skills/jskit/references/multi-homing.md +96 -50
  123. package/skills/jskit/references/pattern-index.md +37 -37
  124. package/skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md +30 -1
  125. package/skills/jskit/references/patterns/app/minimal-foundation/example/AGENTS.md +14 -0
  126. package/skills/jskit/references/patterns/app/minimal-foundation/example/bin/develop.js +10 -5
  127. package/skills/jskit/references/patterns/app/minimal-foundation/example/eslint.config.mjs +21 -2
  128. package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +5 -4
  129. package/skills/jskit/references/patterns/app/minimal-foundation/example/playwright.config.mjs +1 -1
  130. package/skills/jskit/references/patterns/app/minimal-foundation/example/server/lib/envFile.js +19 -0
  131. package/skills/jskit/references/patterns/app/minimal-foundation/example/server/lib/loggerOptions.js +15 -0
  132. package/skills/jskit/references/patterns/app/minimal-foundation/example/server/lib/runtimeEnv.js +17 -17
  133. package/skills/jskit/references/patterns/app/minimal-foundation/example/server.js +32 -29
  134. package/skills/jskit/references/patterns/app/minimal-foundation/example/tests/server/smoke.test.js +2 -1
  135. package/skills/jskit/references/patterns/app/shell-foundation/PATTERN.md +29 -0
  136. package/skills/jskit/references/patterns/app/shell-foundation/example/AGENTS.md +14 -0
  137. package/skills/jskit/references/patterns/app/shell-foundation/example/bin/develop.js +10 -5
  138. package/skills/jskit/references/patterns/app/shell-foundation/example/eslint.config.mjs +21 -2
  139. package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +6 -5
  140. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
  141. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +1 -0
  142. package/skills/jskit/references/patterns/app/shell-foundation/example/playwright.config.mjs +1 -1
  143. package/skills/jskit/references/patterns/app/shell-foundation/example/server/lib/envFile.js +19 -0
  144. package/skills/jskit/references/patterns/app/shell-foundation/example/server/lib/loggerOptions.js +15 -0
  145. package/skills/jskit/references/patterns/app/shell-foundation/example/server/lib/runtimeEnv.js +17 -17
  146. package/skills/jskit/references/patterns/app/shell-foundation/example/server.js +32 -29
  147. package/skills/jskit/references/patterns/app/shell-foundation/example/tests/server/smoke.test.js +2 -1
  148. package/skills/jskit/references/patterns/assistant/assistant-surface/example/src/ApplicationAiFeature.js +4 -2
  149. package/skills/jskit/references/patterns/auth/accounts-hub/PATTERN.md +2 -1
  150. package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +2 -2
  151. package/skills/jskit/references/patterns/auth/accounts-hub/example/server/hubPaths.js +9 -3
  152. package/skills/jskit/references/patterns/auth/auth-surface/PATTERN.md +25 -12
  153. package/skills/jskit/references/patterns/auth/auth-surface/example/tools/preview-identity +7 -1
  154. package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
  155. package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
  156. package/skills/jskit/references/patterns/connectors/ai-connections/PATTERN.md +16 -1
  157. package/skills/jskit/references/patterns/connectors/ai-connections/example/ai-model.js +12 -3
  158. package/skills/jskit/references/patterns/connectors/ai-connections/example/perplexity-answer.js +15 -4
  159. package/skills/jskit/references/patterns/connectors/api-key-connection/PATTERN.md +9 -1
  160. package/skills/jskit/references/patterns/connectors/api-key-connection/example/connections.js +5 -2
  161. package/skills/jskit/references/patterns/connectors/aws-storage-queries/PATTERN.md +13 -3
  162. package/skills/jskit/references/patterns/connectors/aws-storage-queries/example/s3-transfer.js +14 -3
  163. package/skills/jskit/references/patterns/connectors/calendar-cli/PATTERN.md +8 -0
  164. package/skills/jskit/references/patterns/connectors/calendar-cli/example/knexfile.js +1 -1
  165. package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
  166. package/skills/jskit/references/patterns/connectors/calendar-cli/example/scripts/calendar.js +8 -4
  167. package/skills/jskit/references/patterns/connectors/event-delivery/PATTERN.md +1 -1
  168. package/skills/jskit/references/patterns/connectors/firebase-messaging/PATTERN.md +10 -0
  169. package/skills/jskit/references/patterns/connectors/firebase-messaging/example/server/notifications.js +8 -0
  170. package/skills/jskit/references/patterns/connectors/google-ads-search/PATTERN.md +18 -7
  171. package/skills/jskit/references/patterns/connectors/google-ads-search/example/ads-setup.js +13 -5
  172. package/skills/jskit/references/patterns/connectors/oauth-connection/PATTERN.md +1 -1
  173. package/skills/jskit/references/patterns/connectors/paddle-catalogue/PATTERN.md +11 -2
  174. package/skills/jskit/references/patterns/connectors/paddle-catalogue/example/create-products.js +5 -2
  175. package/skills/jskit/references/patterns/connectors/public-image/PATTERN.md +10 -1
  176. package/skills/jskit/references/patterns/connectors/public-image/example/logo-url.js +4 -1
  177. package/skills/jskit/references/patterns/connectors/redshift-queries/PATTERN.md +1 -1
  178. package/skills/jskit/references/patterns/connectors/source-scanning/PATTERN.md +13 -2
  179. package/skills/jskit/references/patterns/connectors/source-scanning/example/source-scanner.js +9 -0
  180. package/skills/jskit/references/patterns/crud/json-api-resource-package/PATTERN.md +102 -23
  181. package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +3 -2
  182. package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/src/server/types.js +5 -0
  183. package/skills/jskit/references/patterns/crud/resource-contract/PATTERN.md +54 -1
  184. package/skills/jskit/references/patterns/database/mysql-application/PATTERN.md +16 -5
  185. package/skills/jskit/references/patterns/database/mysql-application/example/knexfile.js +2 -2
  186. package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
  187. package/skills/jskit/references/patterns/database/mysql-application/example/scripts/prepare-database.js +1 -1
  188. package/skills/jskit/references/patterns/database/postgres-application/PATTERN.md +16 -5
  189. package/skills/jskit/references/patterns/database/postgres-application/example/knexfile.js +2 -2
  190. package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
  191. package/skills/jskit/references/patterns/database/postgres-application/example/scripts/prepare-database.js +1 -1
  192. package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
  193. package/skills/jskit/references/patterns/rewards/google-rewarded/example/GoogleRewardedDeliveryProvider.js +1 -1
  194. package/skills/jskit/references/patterns/rewards/google-rewarded/example/googlePublisherTag.js +5 -11
  195. package/skills/jskit/references/patterns/server/feature-package/PATTERN.md +104 -10
  196. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +9 -4
  197. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/BookingEngineFeature.js +24 -0
  198. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/bookingAvailability.js +10 -0
  199. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/bookingEngine.js +29 -0
  200. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/bookingEngineActions.js +26 -0
  201. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/inputSchemas.js +1 -2
  202. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/types.js +12 -0
  203. package/skills/jskit/references/patterns/server/feature-package/example/variations/AvailabilityEngineFeature.js +19 -0
  204. package/skills/jskit/references/patterns/server/feature-package/example/variations/InvoiceRollupFeature.js +23 -0
  205. package/skills/jskit/references/patterns/server/feature-package/example/variations/availabilityEngineActions.js +26 -0
  206. package/skills/jskit/references/patterns/server/feature-package/example/variations/customKnexRepository.js +32 -26
  207. package/skills/jskit/references/patterns/server/feature-package/example/variations/invoiceRollupActions.js +26 -0
  208. package/skills/jskit/references/patterns/server/feature-package/example/variations/orchestratorService.js +24 -19
  209. package/skills/jskit/references/patterns/server/feature-package/example/variations/types.js +7 -0
  210. package/skills/jskit/references/patterns/users/user-administration-server/PATTERN.md +16 -1
  211. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +3 -2
  212. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/src/server/types.js +5 -0
  213. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +4 -3
  214. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/src/server/UsersWorkspaceFeature.js +2 -9
  215. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/src/server/types.js +5 -0
  216. package/skills/jskit/references/patterns/workspaces/workspace-server/PATTERN.md +42 -17
  217. package/skills/jskit/references/patterns/workspaces/workspace-server/example/packages/main/src/server/WorkspaceInvitationsFeature.js +27 -0
  218. package/skills/jskit/references/patterns/workspaces/workspace-server/example/packages/main/src/server/email/workspaceInviteEmail.js +11 -10
  219. package/skills/jskit/references/patterns/workspaces/workspace-server/example/packages/main/src/server/email/workspaceInviteMailer.js +27 -0
  220. package/skills/jskit/references/translation.md +5 -4
  221. package/skills/jskit/references/typed-features.md +1099 -0
  222. package/skills/jskit/references/ui-operations.md +3 -3
  223. package/patterns/feature-package/example/booking-engine/src/server/BookingEngineProvider.js +0 -33
  224. package/patterns/feature-package/example/booking-engine/src/server/actions.js +0 -24
  225. package/patterns/feature-package/example/variations/AvailabilityEngineProvider.js +0 -31
  226. package/patterns/feature-package/example/variations/InvoiceRollupProvider.js +0 -36
  227. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/BookingEngineProvider.js +0 -33
  228. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/actions.js +0 -24
  229. package/skills/jskit/references/patterns/server/feature-package/example/variations/AvailabilityEngineProvider.js +0 -31
  230. package/skills/jskit/references/patterns/server/feature-package/example/variations/InvoiceRollupProvider.js +0 -36
@@ -66,7 +66,9 @@ Model product domains through `defineFeature()` when they own a real capability
66
66
  or operation boundary. A Feature declares stable named `requires`, optional
67
67
  inputs, and `provides`; `setup()` receives those values directly and returns
68
68
  only the promised outputs. Named actions capture the exact feature APIs they
69
- need. Register structural catalogue entries during `setup()` and reserve
69
+ need. Write Features and providers as [typed features](/guide/framework/typed-features):
70
+ each collaborator is declared, typed where it is received, and never probed.
71
+ Register structural catalogue entries during `setup()` and reserve
70
72
  `boot()` for long-lived work that starts after composition. `shutdown()` stops
71
73
  that work. The runtime shuts Features down in reverse order and keeps going
72
74
  after one fails; it then rejects with an `AggregateError` holding one error per
@@ -235,8 +237,8 @@ Invitation creation, acceptance and refusal now own their managed transactions:
235
237
  - Replace `members.createInvite(..., { trx })` with
236
238
  `members.prepareInvite(..., { trx })`, save the application association/receipt,
237
239
  commit, then call `members.sendInvite(...)` without `trx`.
238
- - Move related acceptance writes into
239
- `pendingInvitations.registerAcceptanceParticipant(fn)` during feature setup.
240
+ - Move related acceptance writes into a function provided as the
241
+ `workspaces.invite-acceptance-participant` capability.
240
242
  Acceptance/refusal reject borrowed transactions; revocation can still join one.
241
243
  - Terminal repository transitions reject accepted/revoked invitations. Mailer
242
244
  exceptions return a fixed message to keep tokens out of provider diagnostics.
@@ -262,11 +264,13 @@ historical migration when moving it so the existing Knex ledger continues to
262
264
  recognize it. Basenames must be unique across the effective graph.
263
265
 
264
266
  Keep cross-package foreign keys and other dependency-sensitive constraints in
265
- application `migrations/constraints/`, the final phase of
266
- `createKnexMigrationConfigFromApp()`. It uses `sortDirsSeparately: true`: root
267
- `migrations/` runs before the sorted package directories, and filenames only
268
- order work within their own directory. A later timestamp in a package does not
269
- defer its foreign key until another package has created the parent table.
267
+ a constraints phase of `createKnexMigrationConfigFromApp()`: the referencing
268
+ package's own `constraints/` subdirectory, which runs after root `migrations/`,
269
+ or application `migrations/constraints/`, which runs last. It uses
270
+ `sortDirsSeparately: true`: the sorted package directories run before root
271
+ `migrations/`, and filenames only order work within their own directory. A later
272
+ timestamp in a package does not defer its foreign key until another package has
273
+ created the parent table.
270
274
  Follow the [database ordering and partial-failure recovery rules](https://mobily-enterprises.github.io/jskit-ai/guide/app-setup/database-layer#directory-order-comes-before-filenames),
271
275
  including independent checks for columns and constraints after MySQL or MariaDB
272
276
  DDL fails. Seeds are not migrations: run one explicit application-owned,
@@ -317,17 +321,16 @@ Do not conflate these identities:
317
321
 
318
322
  An application with accounts has the standard managed-preview login: retain
319
323
  the app-owned `tools/preview-identity` executable, or add it from
320
- `auth/auth-surface` when it is missing, and declare it under
321
- `#### Preview identity` in the web-presented Vibe64 `Outputs` target exactly as
322
- that pattern shows. JSKIT owns the executable/library pattern, Vibe64 owns
323
- the declaration's grammar and runtime behavior, and Genesis transports the
324
- consumer-owned section without interpreting it. The executable calls the
324
+ `auth/auth-surface` when it is missing, pass it the preview host's protocol id
325
+ and hostnames, and declare it to the host as that pattern shows. JSKIT owns
326
+ the executable/library pattern; the host owns the declaration's grammar, its
327
+ protocol id and its runtime behavior. The executable calls the
325
328
  `@jskit-ai/auth-web` server-side managed-preview library; it does not need a
326
329
  framework CLI. Never expose the exchange secret in browser code, a URL, client
327
330
  environment, logs, or source.
328
331
 
329
332
  Managed Playwright uses the host-provided
330
- `VIBE64_PLAYWRIGHT_STORAGE_STATE`, relative URLs, and the existing managed
333
+ `PLAYWRIGHT_STORAGE_STATE`, relative URLs, and the existing managed
331
334
  server. Direct-local tests may instead use `loginAsExistingUser()` from
332
335
  `@jskit-ai/auth-web/test/playwright` with a server-only development secret.
333
336
  Do not mix those two authentication modes or start a duplicate server against
@@ -353,10 +356,11 @@ do not accept a visually similar screen as behavioral equivalence.
353
356
 
354
357
  ## 7. Reconcile, then Deslop as a distinct pass
355
358
 
356
- When the project uses Genesis, run an explicit reconciliation after the port is
357
- functionally green. Compare the implemented source with the current Blueprint,
358
- selected Stack, Program, resources, managed skills, and effective workspace and
359
- Outputs recipes. Update stale citations and declarations to describe what now
359
+ When the project keeps authoritative project documentation, run an explicit
360
+ reconciliation after the port is functionally green. Compare the implemented
361
+ source with its current product description, selected stack, subsystem notes,
362
+ resources, managed skills, and effective workspace and output recipes. Update
363
+ stale citations and declarations to describe what now
360
364
  exists. Do not duplicate an inherited setup recipe merely to make the project
361
365
  look self-contained.
362
366
 
@@ -381,10 +385,10 @@ evidence in ordinary source, configuration, command output, and tests:
381
385
  1. **Behavior:** focused tests and the full managed browser suite are green
382
386
  against an isolated disposable database. Use the managed host and server
383
387
  when supplied.
384
- 2. **Reconciliation:** a dedicated Genesis reconciliation confirms the
385
- Blueprint, Stack, Program, resources, managed skills, and effective setup and
386
- Outputs recipes match the implementation. For a project without Genesis,
387
- reconcile its equivalent authoritative product and host documentation.
388
+ 2. **Reconciliation:** a dedicated reconciliation confirms the project's
389
+ authoritative product and host documentation (product description, selected
390
+ stack, subsystem notes, resources, managed skills, and effective setup and
391
+ output recipes) matches the implementation.
388
392
  3. **Deslop:** a distinct JSKIT Deslop pass, including the selected Material 3
389
393
  audit where UI is affected, removes obsolete framework residue without
390
394
  changing legitimate behavior.
@@ -400,9 +404,9 @@ Do not satisfy a gate by adding a completion ledger or generated conformance
400
404
  state. If a command cannot run, report the missing evidence rather than marking
401
405
  the port complete.
402
406
 
403
- ## Downstream proof: DogAndGroom
407
+ ## Downstream proof: a production port
404
408
 
405
- DogAndGroom validated this procedure on a substantial existing product rather
409
+ A production application validated this procedure on a substantial existing product rather
406
410
  than a sample. The port redistributed 66 historical migrations among 43 owning
407
411
  packages while retaining globally unique basenames and putting cross-package
408
412
  constraints last. Its imported database ledger remained read-only and
@@ -416,7 +420,7 @@ and safety behavior. Obsolete framework generators, provenance markers,
416
420
  service-location wiring, and empty extension modules were removed without
417
421
  flattening those workflows.
418
422
 
419
- After a separate Genesis reconciliation and JSKIT/Material Deslop, its focused
423
+ After a separate reconciliation and JSKIT/Material Deslop, its focused
420
424
  checks, 339 server tests, client tests, production build, database proofs, and
421
425
  all 105 managed Playwright cases passed. These numbers are downstream evidence
422
426
  that the method scales; they are not template targets or state that another
@@ -58,13 +58,32 @@ config.tenancyPolicy = {
58
58
  Provisioning runs in the users profile-sync lifecycle after registration and
59
59
  sign-in. The first run creates the personal workspace, its owner membership and
60
60
  its settings; later runs reuse it. The default name is the user's display name,
61
- or email, followed by "'s Workspace". Set `personalWorkspaceName` in
62
- `config/server.js` to choose another; it receives the synchronized profile
63
- (`id`, `displayName`, `email`, `username`), and an empty result keeps the default:
61
+ or email, followed by "'s Workspace". To choose another, provide the
62
+ `workspaces.personal-workspace-name` capability from an application feature. It
63
+ receives the synchronized profile (`id`, `displayName`, `email`, `username`), and
64
+ an empty result keeps the default:
64
65
 
65
66
  ```js
66
- // config/server.js
67
- config.personalWorkspaceName = (user) => `${user.displayName || user.email}'s home`;
67
+ import { defineFeature } from "@jskit-ai/kernel/server/features";
68
+ import { homeWorkspaceName } from "./homeWorkspaceName.js";
69
+
70
+ const AppPersonalWorkspaceNameFeature = defineFeature({
71
+ id: "app.personal-workspace-name",
72
+ provides: {
73
+ personalWorkspaceName: "workspaces.personal-workspace-name"
74
+ },
75
+ setup: () => ({ personalWorkspaceName: homeWorkspaceName })
76
+ });
77
+ ```
78
+
79
+ ```js
80
+ // homeWorkspaceName.js
81
+ /** @type {import("@jskit-ai/workspaces-core/server/types").PersonalWorkspaceName} */
82
+ function homeWorkspaceName(user) {
83
+ return `${user.displayName || user.email}'s home`;
84
+ }
85
+
86
+ export { homeWorkspaceName };
68
87
  ```
69
88
 
70
89
  ### Development sign-in
@@ -103,8 +122,13 @@ before an operation discloses records or record existence.
103
122
 
104
123
  For a standard CRUD resource owned by a workspace, give its table the
105
124
  `workspace_id` column, set the resource's `autofilter: "workspace"`, and bind
106
- `defineCrudJsonApiFeature()` with `ownershipFilter: "workspace"` on a workspace
107
- surface. JSKIT then filters `workspaceId` by the workspace in the route.
125
+ `defineCrudJsonApiFeature()` with `ownershipFilter: "workspace"` and `scope:
126
+ WORKSPACE_CRUD_SCOPE` (from `@jskit-ai/workspaces-core/server/support/workspaceCrud`)
127
+ on a workspace surface. JSKIT then filters `workspaceId` by the workspace in the
128
+ route. A repository method you add reads the workspace id with
129
+ `resolveWorkspaceScopeValue(options.context)`
130
+ (`@jskit-ai/json-rest-api-core/server/jsonRestApiHost`), which throws when the
131
+ context names two workspaces.
108
132
  `workspace_user` also filters by the signed-in user. See the CRUD operations
109
133
  guide.
110
134
 
@@ -152,14 +176,31 @@ capability provides:
152
176
 
153
177
  ### Invitation email
154
178
 
155
- To send invitation email, set a mailer in `config/server.js`. Without one,
156
- invitations are still created and delivery reports `mailer_unconfigured`.
157
- `workspaceInviteMailer` is an object whose `sendWorkspaceInvite(message,
158
- options)` receives `{ email, inviteUrl, workspace, inviter, roleSid, expiresAt,
159
- message }`, where the inner `message` is the rendered `{ subject, text, html }`.
160
- `workspaceInviteEmailTemplate` is an optional function that renders that inner
161
- message; it receives `{ email, inviteUrl, workspace, inviter, roleSid,
162
- roleLabel, expiresAt }` (`roleLabel` only when configured). Invitation links use `/invite/:token` unless
179
+ To send invitation email, provide the optional `workspaces.invite-mailer`
180
+ capability from one of the application's providers. Without one, invitations
181
+ are still created and delivery reports `mailer_unconfigured`. The mailer, typed
182
+ `WorkspaceInviteMailer` in `@jskit-ai/workspaces-core/server/types`, is an
183
+ object whose `sendWorkspaceInvite(message, options)` receives `{ email,
184
+ inviteUrl, workspace, inviter, roleSid, expiresAt, message }`, where the inner
185
+ `message` is the rendered `{ subject, text, html }`:
186
+
187
+ ```js
188
+ const InviteMailerProvider = defineProvider({
189
+ id: "app.invite-mailer",
190
+ provides: {
191
+ inviteMailer: "workspaces.invite-mailer"
192
+ },
193
+ setup() {
194
+ return { inviteMailer: createAppInviteMailer() };
195
+ }
196
+ });
197
+ ```
198
+
199
+ The optional `workspaces.invite-email-template` capability is a function that
200
+ renders that inner message; it receives `{ email, inviteUrl, workspace, inviter,
201
+ roleSid, roleLabel, expiresAt, locale, t }` (`roleLabel` only when configured).
202
+ Provide it from an application feature, as for the mailer; without it the
203
+ built-in template renders the message. Invitation links use `/invite/:token` unless
163
204
  `workspaceInvitations.invitePath` names another path. The
164
205
  `workspaces/workspace-server` pattern includes an example renderer.
165
206
 
@@ -252,8 +293,8 @@ authorization and role checks. Do not pass arbitrary HTTP input as options.
252
293
  | `workspaces.repositories.workspaceInvites.lockWorkspaceForInvitations(workspaceId, { trx })` | Locks the workspace before application receipt/draft rows when composing preparation. Requires an active transaction. |
253
294
  | `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. |
254
295
  | `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. |
255
- | `workspaces.services.members.createInvite(workspace, actor, payload, options)` | Owns preparation and commit, then calls `sendInvite`; retains the ordinary response shape. Rejects `options.trx`. |
256
- | `workspaces.services.pendingInvitations.registerAcceptanceParticipant(fn)` | Registers one application callback receiving `({ invite, user }, options)`. Invalid, duplicate and late registration reject. |
296
+ | `workspaces.services.members.createInvite(workspace, actor, payload, options)` | Owns preparation and commit, then calls `sendInvite`, and answers with `sendInvite`'s result as JSON:API data (`returnJsonApiData`, read it from `.value`), as the invite action sends it. Rejects `options.trx`. |
297
+ | `workspaces.invite-acceptance-participant` (optional capability) | One application function receiving `({ invite, user }, options)` inside the acceptance transaction. Without it, acceptance activates the membership only. |
257
298
 
258
299
  `sendInvite` accepts `{ createdInviteId, inviteTokenPreview }` from preparation or
259
300
  only `{ createdInviteId }` for a later attempt. The latter uses JSKIT's existing
@@ -266,30 +307,34 @@ diagnostics and administrative receipts; save the invitation ID in the receipt.
266
307
 
267
308
  ### Preparation, association, commit and controlled delivery
268
309
 
269
- Declare `workspaces: "workspaces.core"` in the application's feature `requires`.
270
- In this example, `reviewedPeople`, `people`, `scopes` and `audit` are application
271
- services. Each forwards the supplied transaction to its repositories.
310
+ The acceptance participant comes from a small application feature that provides
311
+ `workspaces.invite-acceptance-participant` and requires only what its writes need.
312
+ It cannot require `workspaces.core`, which receives it. In this example,
313
+ `reviewedPeople`, `people`, `scopes` and `audit` are application services. Each
314
+ forwards the supplied transaction to its repositories.
272
315
 
273
316
  ```js
274
- // During application Feature.setup, before serving requests:
275
- const { members, pendingInvitations } = workspaces.services;
276
- const invites = workspaces.repositories.workspaceInvites;
277
-
278
- pendingInvitations.registerAcceptanceParticipant(async ({ invite, user }, options) => {
279
- // Resolve from the exact validated invitation, never a client person ID.
280
- const association = await reviewedPeople.resolveInvitation(invite.id, options);
281
- if (association.kind === "ordinary") return;
282
- await reviewedPeople.requireCurrentReview(association, {
283
- workspaceId: invite.workspaceId,
284
- user,
285
- roleSid: invite.roleSid
286
- }, options);
287
- await people.linkAccountAndTraining(association.personId, user.id, options);
288
- await scopes.applyReviewedAccess(association, user.id, options);
289
- await audit.recordInvitationAcceptance(association, user.id, options);
290
- });
317
+ // An application feature providing "workspaces.invite-acceptance-participant":
318
+ setup: ({ reviewedPeople, people, scopes, audit }) => ({
319
+ inviteAcceptanceParticipant: async ({ invite, user }, options) => {
320
+ // Resolve from the exact validated invitation, never a client person ID.
321
+ const association = await reviewedPeople.resolveInvitation(invite.id, options);
322
+ if (association.kind === "ordinary") return;
323
+ await reviewedPeople.requireCurrentReview(association, {
324
+ workspaceId: invite.workspaceId,
325
+ user,
326
+ roleSid: invite.roleSid
327
+ }, options);
328
+ await people.linkAccountAndTraining(association.personId, user.id, options);
329
+ await scopes.applyReviewedAccess(association, user.id, options);
330
+ await audit.recordInvitationAcceptance(association, user.id, options);
331
+ }
332
+ })
291
333
 
292
- // Inside an authorized application command:
334
+ // Inside an authorized application command, in a feature that requires
335
+ // workspaces: "workspaces.core":
336
+ const { members } = workspaces.services;
337
+ const invites = workspaces.repositories.workspaceInvites;
293
338
  const prepared = await invites.withTransaction(async (trx) => {
294
339
  const options = { trx, context };
295
340
  // Match acceptance's order: workspace, then application draft/receipt rows.
@@ -316,23 +361,24 @@ invitation. Association failure rolls back the new invitation, replacement of
316
361
  the previous invitation, receipt and application writes. Send only after the
317
362
  transaction resolves successfully.
318
363
 
319
- With no `workspaceInviteMailer`, delivery returns `status: "mailer_unconfigured"`,
320
- an explanatory `message` and an empty `providerMessageId`; the invitation remains
321
- committed. Use a controlled mailer in tests; SMTP is unnecessary:
364
+ With no provider of `workspaces.invite-mailer`, delivery returns
365
+ `status: "mailer_unconfigured"`, an explanatory `message` and an empty
366
+ `providerMessageId`; the invitation remains committed. Provide a controlled
367
+ mailer in tests; SMTP is unnecessary:
322
368
 
323
369
  ```js
324
- workspaceInviteMailer: {
370
+ const inviteMailer = {
325
371
  async sendWorkspaceInvite(message) {
326
372
  capturedInvites.push(message); // Test-local memory; contains the secret link.
327
373
  return { status: "sent", message: "Captured by test mailer.", providerMessageId: "fixture-1" };
328
374
  }
329
- }
375
+ };
330
376
  ```
331
377
 
332
378
  Renderer/mailer exceptions return `inviteDelivery.status: "failed"` with a fixed
333
379
  message to keep provider errors from exposing tokens. Persistence is unchanged.
334
- Successful mailer results retain their normalized status, message and provider
335
- message ID; the default status is `sent`.
380
+ Successful mailer results retain their normalized status, message, message
381
+ code and provider message ID; the default status is `sent`.
336
382
 
337
383
  A provider may accept a message before throwing or losing its response. The
338
384
  application must track delivery attempts and decide when to retry; email is not
@@ -411,9 +457,9 @@ npm run verify
411
457
  ```
412
458
 
413
459
  Run the application's `npm run jskit:update`, restart its backend and verify that
414
- `members.prepareInvite`, `members.sendInvite` and
415
- `pendingInvitations.registerAcceptanceParticipant` are functions on the installed
416
- `workspaces.core` capability. The first release containing this contract pairs
460
+ `members.prepareInvite` and `members.sendInvite` are functions on the installed
461
+ `workspaces.core` capability, and that the application feature providing
462
+ `workspaces.invite-acceptance-participant` is installed. The first release containing this contract pairs
417
463
  `@jskit-ai/workspaces-core@0.1.198`, `@jskit-ai/jskit-catalog@0.1.245` and
418
464
  `@jskit-ai/agent-docs@0.1.192`. Upgrade the coordinated dependency graph, then run
419
465
  the application's identity, training, permission, privacy and browser tests.
@@ -129,10 +129,12 @@ npx jskit-oidc-issuer import-accounts --in accounts.jsonl --apply
129
129
  password they already had. Emails start unconfirmed: each person confirms
130
130
  theirs once, at their first app sign-in. Rows that clash with a
131
131
  different hub account are refused and listed. A dry run prints only counts.
132
- - `preview-identity` implements `vibe64.preview-identity.command.v1` for the
133
- hub, so an editor's preview can sign in as an existing hub account. It works
134
- only outside production, from loopback, with `AUTH_DEV_BYPASS_ENABLED` and
135
- `AUTH_DEV_BYPASS_SECRET`.
132
+ - `preview-identity` answers the preview identity exchange for the hub, so an
133
+ editor's preview can sign in as an existing hub account. Pass the preview
134
+ host's protocol id with `--protocol` and each hostname pattern, besides
135
+ loopback, that the host serves the hub on with `--local-hostname`. It works
136
+ only outside production, from loopback, with
137
+ `AUTH_DEV_BYPASS_ENABLED` and `AUTH_DEV_BYPASS_SECRET`.
136
138
 
137
139
  ## Connecting an app
138
140