@jskit-ai/agent-docs 0.1.257 → 0.1.259

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 +9 -8
  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
@@ -103,8 +103,8 @@ For Back, enter the same page from two different origins and verify each
103
103
  returns to its own origin with context intact. Also check direct entry, reload,
104
104
  browser back/forward, fixed-destination exceptions, and any unsaved-change guard.
105
105
 
106
- Vibe64 owns its managed browser and may provide
107
- `VIBE64_PLAYWRIGHT_STORAGE_STATE`; never print or commit that value, bypass it,
106
+ A managed host owns its browser and may provide
107
+ `PLAYWRIGHT_STORAGE_STATE`; never print or commit that value, bypass it,
108
108
  or install another browser. For explicitly enabled direct-local auth, use
109
109
  `loginAsExistingUser()` from `@jskit-ai/auth-web/test/playwright`; never expose
110
110
  the exchange secret to browser code, URLs, or client environment.
@@ -26,6 +26,10 @@ apply or adapt. It does not prescribe an agent host or project orchestrator.
26
26
  - [Application operations](/guide/framework/application-operations)
27
27
  - [CRUD operations](/guide/framework/crud-operations)
28
28
  - [Record form actions](/guide/framework/crud-form-actions)
29
+ - [Typed features](/guide/framework/typed-features): read before writing any
30
+ server feature, provider, action, service or repository
31
+ - [Client features](/guide/framework/client-features): read before writing any
32
+ composable, component, client factory or client provider
29
33
  - [UI operations](/guide/framework/ui-operations)
30
34
  - [Material 3](/guide/framework/material-3)
31
35
  - [Translating a JSKIT app](/guide/framework/translation)
@@ -42,7 +46,8 @@ apply or adapt. It does not prescribe an agent host or project orchestrator.
42
46
  ## How to use the guide
43
47
 
44
48
  Begin with the Quickstart and one application-foundation pattern. Add only the
45
- capabilities selected by the product. The public pattern library contains every
49
+ capabilities selected by the product. Server code follows Typed features from
50
+ its first line; the foundations' lint configuration reports what breaks it. The public pattern library contains every
46
51
  published `PATTERN.md` and links its complete example tree. If a runtime package
47
52
  is installed, its package-owned copy is the version-matched implementation
48
53
  reference. The optional standalone JSKIT Agent Skill bundles the same pattern
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/agent-docs",
3
- "version": "0.1.257",
3
+ "version": "0.1.259",
4
4
  "description": "Distributed JSKIT agent references, prompts, guides, and generated reference maps.",
5
5
  "type": "module",
6
6
  "files": [
@@ -42,8 +42,43 @@ questionnaire.
42
42
  the feature package.
43
43
  - `defineFeature()` receives only declared capabilities and returns only
44
44
  declared feature APIs.
45
- - Actions define the public operation contract and close over the feature APIs
46
- they need. They never resolve arbitrary dependencies at execution time.
45
+ - Each provided capability exports its type. A named `create<Name>` factory in
46
+ its own module builds the value `setup()` returns, and `types.js` declares
47
+ one `@typedef` per provided token, named after the token in PascalCase
48
+ (`feature.booking-engine` -> `BookingEngine`). A package exports it as
49
+ `./server/types`.
50
+ - Every factory, action creator and hook that receives a collaborator names its
51
+ type in a JSDoc `@param`: `import("./types.js").<Name>` or
52
+ `ReturnType<typeof createX>` inside the package, the owner's `./server/types`
53
+ across packages; a Knex client is database-runtime's `RuntimeKnex`.
54
+ - Collaborators are required. There is no `= null`, `= {}` or no-op default,
55
+ no `typeof` probe, no optional call and no "requires x" guard: the capability
56
+ runtime refuses to start without a required token.
57
+ - An extension point is an `optional` token whose default the package names
58
+ in a module of its own and `setup()` resolves once with `??`, never a setter
59
+ that fills a slot later or a module-level registry. The token is typed
60
+ `X | null` only in `setup()`; what `setup()` builds receives it as required.
61
+ - One `create<Name>Actions({ <api> })` per feature, destructured, in
62
+ `<name>Actions.js`, creates its actions and closes over the feature APIs they
63
+ need. Every definition and the list are frozen. Each definition spreads one
64
+ frozen constant of the fields its kind shares (`version`, `kind`,
65
+ `channels`, `surfaces`) first. Each id is a string literal or a module-level
66
+ constant, and `execute: (input, context) => api.method(input, { context })`
67
+ is one call, without `async`, a body, an envelope or a helper that builds or
68
+ strips it. Actions never resolve arbitrary dependencies at execution time.
69
+ - Methods take the validated input as it is: no `input = {}` default, no
70
+ `input?.x` and no second normalization of fields the input schema already
71
+ checked. An options bag whose fields are optional by contract
72
+ (`options = {}` with `trx`) keeps its default.
73
+ - The package reads the actor from an action context one way, with the
74
+ kernel's `resolveActorId(context)` or `resolveActor(context)`
75
+ (`@jskit-ai/kernel/server/actions/actionContributorHelpers`), and its actions
76
+ pass the context one way.
77
+ - Every `create*` returns `Object.freeze({ … })` of named inner functions, and
78
+ exposes another factory's functions by name, never by spreading it.
79
+ - A description sits inside its `/** */` block, never in a `//` line above it.
80
+ - One copy of each pure helper per package, imported directly. Files stay under
81
+ 750 lines and functions under 600, one concern per factory.
47
82
  - The service orchestrates the feature and does not issue SQL directly.
48
83
  - A repository owns persistence and accepts transaction/context options.
49
84
  - The normal persistence lane uses a public or documented high-level resource
@@ -68,20 +103,65 @@ The custom persistence variation uses `createWithTransaction()` from
68
103
  ## Example files
69
104
 
70
105
  `example/booking-engine/` is a concrete app-local package showing the preferred
71
- small-feature boundary. Its status query is deliberately small: product logic
72
- can grow inside the returned feature API without creating ceremonial layers.
73
-
74
- `example/variations/AvailabilityEngineProvider.js` and
106
+ small-feature boundary:
107
+
108
+ - `src/server/BookingEngineFeature.js` declares the feature, its optional
109
+ `feature.booking-engine.availability` slot and the engine it provides;
110
+ - `src/server/bookingEngine.js` builds the engine with `createBookingEngine()`,
111
+ a frozen object of named functions, and reads who asked with the kernel's
112
+ `resolveActorId(context)`;
113
+ - `src/server/bookingAvailability.js` names the slot's default,
114
+ `everyScopeOpen`;
115
+ - `src/server/bookingEngineActions.js` creates its one-line, frozen actions
116
+ with `createBookingEngineActions({ bookingEngine })`, each spreading the
117
+ shared `BOOKING_QUERY` fields first;
118
+ - `src/server/types.js` declares `BookingEngine` and
119
+ `BookingEngineAvailability`, exported as `./server/types`.
120
+
121
+ Its status query is deliberately small: product logic can grow inside the
122
+ returned feature API without creating ceremonial layers. The feature resolves
123
+ the slot once:
124
+
125
+ ```js
126
+ optional: {
127
+ availability: "feature.booking-engine.availability"
128
+ },
129
+ /** @param {{ availability: import("./types.js").BookingEngineAvailability | null }} capabilities */
130
+ setup({ availability }) {
131
+ return { bookingEngine: createBookingEngine({ availability: availability ?? everyScopeOpen }) };
132
+ },
133
+ ```
134
+
135
+ Another package fills the slot by providing the token, never by calling a
136
+ setter:
137
+
138
+ ```js
139
+ const SeasonalAvailabilityFeature = defineFeature({
140
+ id: "feature.seasonal-availability",
141
+ provides: { availability: "feature.booking-engine.availability" },
142
+ setup: () => ({ availability: isInSeason })
143
+ });
144
+ ```
145
+
146
+ `example/variations/AvailabilityEngineFeature.js`,
147
+ `example/variations/availabilityEngineActions.js` and
75
148
  `example/variations/orchestratorService.js` show the repository-free lane.
76
- `example/variations/InvoiceRollupProvider.js` and
149
+ `example/variations/InvoiceRollupFeature.js`,
150
+ `example/variations/invoiceRollupActions.js` and
77
151
  `example/variations/customKnexRepository.js` show the explicit custom
78
- persistence lane.
152
+ persistence lane. `example/variations/types.js` declares the
153
+ `AvailabilityEngine` and `InvoiceRollup` types.
154
+
155
+ The [typed features guide](https://mobily-enterprises.github.io/jskit-ai/guide/framework/typed-features)
156
+ explains each rule this example follows, with a good and a bad example, and
157
+ `npm run lint` checks the ones a machine can see.
79
158
 
80
159
  ## Variation points
81
160
 
82
161
  Rename the package, capability id, actions, validators, and domain methods.
83
- Select the correct channels and surfaces in `actionDefaults`, overriding them
84
- only for exceptional actions. Add a service when orchestration is shared or
162
+ Select the channels and surfaces in the shared-field constant each definition
163
+ spreads first; a kind of action whose values differ gets a constant of its
164
+ own. Add a service when orchestration is shared or
85
165
  stateful. Add a repository only when the feature owns persistence. Replace the
86
166
  illustrative status query with narrow product language before shipping.
87
167
 
@@ -104,5 +184,19 @@ illustrative status query with narrow product language before shipping.
104
184
  - a repository for an orchestration-only feature
105
185
  - generic `execute(anything)` operations in finished product code
106
186
  - `app.make()`, `scope.make()`, container tokens, or service-location helpers
187
+ - probing a collaborator (`typeof x.method === "function"`, `x?.method?.()`)
188
+ before calling it
189
+ - absent defaults on a collaborator or on the dependencies object (`= null`,
190
+ `= {}`, a no-op)
191
+ - setters that fill a slot after construction, and module-level registries
192
+ - a collaborator accepted in two shapes (`capability.service || capability`)
193
+ - an `async` `execute`, an `execute` with a body, or a helper that builds an
194
+ action or strips its input
195
+ - a hand-written `(...args: any[]) => Promise<any>` type instead of the
196
+ owner's type, and the same `ReturnType<…>` or indexed type spelled out in
197
+ several files
198
+ - spreading an in-package factory's result into a provided value
199
+ - unfrozen `create*` results and inline methods
200
+ - a guard, default or comment that exists for a test double
107
201
  - metadata claiming which authoring tool or pattern created the package
108
202
  - field questionnaires, overwrite switches, or durable operation records
@@ -5,11 +5,12 @@
5
5
  "private": true,
6
6
  "type": "module",
7
7
  "dependencies": {
8
- "@jskit-ai/kernel": "0.2.3",
8
+ "@jskit-ai/kernel": "0.2.4",
9
9
  "json-rest-schema": "^1.0.17"
10
10
  },
11
11
  "exports": {
12
- "./server/actions": "./src/server/actions.js"
12
+ "./server/actions": "./src/server/bookingEngineActions.js",
13
+ "./server/types": "./src/server/types.js"
13
14
  },
14
15
  "jskit": {
15
16
  "kind": "runtime",
@@ -25,8 +26,8 @@
25
26
  "server": {
26
27
  "providers": [
27
28
  {
28
- "entrypoint": "src/server/BookingEngineProvider.js",
29
- "export": "BookingEngineProvider"
29
+ "entrypoint": "src/server/BookingEngineFeature.js",
30
+ "export": "BookingEngineFeature"
30
31
  }
31
32
  ]
32
33
  },
@@ -40,6 +41,10 @@
40
41
  {
41
42
  "subpath": "./server/actions",
42
43
  "summary": "Exports booking-engine action definitions."
44
+ },
45
+ {
46
+ "subpath": "./server/types",
47
+ "summary": "Types of the feature.booking-engine capability and its optional feature.booking-engine.availability slot."
43
48
  }
44
49
  ]
45
50
  }
@@ -0,0 +1,24 @@
1
+ import { defineFeature } from "@jskit-ai/kernel/server/features";
2
+ import { everyScopeOpen } from "./bookingAvailability.js";
3
+ import { createBookingEngine } from "./bookingEngine.js";
4
+ import { createBookingEngineActions } from "./bookingEngineActions.js";
5
+
6
+ const BookingEngineFeature = defineFeature({
7
+ id: "feature.booking-engine",
8
+ domain: "booking",
9
+ optional: {
10
+ availability: "feature.booking-engine.availability"
11
+ },
12
+ provides: {
13
+ bookingEngine: "feature.booking-engine"
14
+ },
15
+ /** @param {{ availability: import("./types.js").BookingEngineAvailability | null }} capabilities */
16
+ setup({ availability }) {
17
+ return { bookingEngine: createBookingEngine({ availability: availability ?? everyScopeOpen }) };
18
+ },
19
+ actions({ bookingEngine }) {
20
+ return createBookingEngineActions({ bookingEngine });
21
+ }
22
+ });
23
+
24
+ export { BookingEngineFeature };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The `feature.booking-engine.availability` default when no package provides
3
+ * one: every scope takes bookings.
4
+ * @type {import("./types.js").BookingEngineAvailability}
5
+ */
6
+ async function everyScopeOpen() {
7
+ return true;
8
+ }
9
+
10
+ export { everyScopeOpen };
@@ -0,0 +1,29 @@
1
+ import { resolveActorId } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
2
+
3
+ /**
4
+ * The booking engine the feature provides as `feature.booking-engine`.
5
+ * @param {object} dependencies
6
+ * @param {import("./types.js").BookingEngineAvailability} dependencies.availability
7
+ */
8
+ function createBookingEngine({ availability }) {
9
+ /**
10
+ * Reports, for the validated query, whether its scope takes bookings and who
11
+ * asked.
12
+ * @param {{ scope?: string, verbose?: boolean }} query
13
+ * @param {{ context: object }} options
14
+ */
15
+ async function readStatus({ scope = "default", verbose = false }, { context }) {
16
+ return {
17
+ ok: true,
18
+ feature: "booking-engine",
19
+ scope,
20
+ verbose,
21
+ open: await availability(scope),
22
+ requestedBy: resolveActorId(context)
23
+ };
24
+ }
25
+
26
+ return Object.freeze({ readStatus });
27
+ }
28
+
29
+ export { createBookingEngine };
@@ -0,0 +1,26 @@
1
+ import { statusQueryInputValidator } from "./inputSchemas.js";
2
+
3
+ const ACTION_GET_STATUS = "feature.booking-engine.status.read";
4
+
5
+ /** The fields every booking query shares, spread first into each definition. */
6
+ const BOOKING_QUERY = Object.freeze({
7
+ version: 1,
8
+ kind: "query",
9
+ channels: ["api", "assistant", "internal"],
10
+ surfaces: ["app"]
11
+ });
12
+
13
+ /** @param {{ bookingEngine: import("./types.js").BookingEngine }} dependencies */
14
+ function createBookingEngineActions({ bookingEngine }) {
15
+ return Object.freeze([
16
+ Object.freeze({
17
+ ...BOOKING_QUERY,
18
+ id: ACTION_GET_STATUS,
19
+ input: statusQueryInputValidator,
20
+ output: null,
21
+ execute: (input, context) => bookingEngine.readStatus(input, { context })
22
+ })
23
+ ]);
24
+ }
25
+
26
+ export { ACTION_GET_STATUS, createBookingEngineActions };
@@ -12,8 +12,7 @@ const statusQueryInputValidator = deepFreeze({
12
12
  type: "boolean",
13
13
  required: false
14
14
  }
15
- }),
16
- mode: "patch"
15
+ })
17
16
  });
18
17
 
19
18
  export { statusQueryInputValidator };
@@ -0,0 +1,12 @@
1
+ // The types of the `feature.booking-engine` capability and of its optional
2
+ // `feature.booking-engine.availability` slot.
3
+
4
+ /** @typedef {ReturnType<typeof import("./bookingEngine.js").createBookingEngine>} BookingEngine */
5
+
6
+ /**
7
+ * The `feature.booking-engine.availability` slot: answers whether a scope takes
8
+ * bookings. A package supplies it by providing that token.
9
+ * @typedef {(scope: string) => Promise<boolean>} BookingEngineAvailability
10
+ */
11
+
12
+ export {};
@@ -0,0 +1,19 @@
1
+ import { defineFeature } from "@jskit-ai/kernel/server/features";
2
+ import { createAvailabilityEngineActions } from "./availabilityEngineActions.js";
3
+ import { createAvailabilityEngine } from "./orchestratorService.js";
4
+
5
+ const AvailabilityEngineFeature = defineFeature({
6
+ id: "feature.availability-engine",
7
+ domain: "availability",
8
+ provides: {
9
+ availabilityEngine: "feature.availability-engine"
10
+ },
11
+ setup() {
12
+ return { availabilityEngine: createAvailabilityEngine() };
13
+ },
14
+ actions({ availabilityEngine }) {
15
+ return createAvailabilityEngineActions({ availabilityEngine });
16
+ }
17
+ });
18
+
19
+ export { AvailabilityEngineFeature };
@@ -0,0 +1,23 @@
1
+ import { defineFeature } from "@jskit-ai/kernel/server/features";
2
+ import { createInvoiceRollup } from "./customKnexRepository.js";
3
+ import { createInvoiceRollupActions } from "./invoiceRollupActions.js";
4
+
5
+ const InvoiceRollupFeature = defineFeature({
6
+ id: "feature.invoice-rollup",
7
+ domain: "invoices",
8
+ requires: {
9
+ database: "runtime.database"
10
+ },
11
+ provides: {
12
+ invoiceRollup: "feature.invoice-rollup"
13
+ },
14
+ /** @param {{ database: import("@jskit-ai/database-runtime/server/types").RuntimeDatabase }} capabilities */
15
+ setup({ database }) {
16
+ return { invoiceRollup: createInvoiceRollup({ knex: database.knex }) };
17
+ },
18
+ actions({ invoiceRollup }) {
19
+ return createInvoiceRollupActions({ invoiceRollup });
20
+ }
21
+ });
22
+
23
+ export { InvoiceRollupFeature };
@@ -0,0 +1,26 @@
1
+ import { emptyInputValidator } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
2
+
3
+ const ACTION_GET_AVAILABILITY_STATUS = "availability.status.read";
4
+
5
+ /** The fields every availability query shares, spread first into each definition. */
6
+ const AVAILABILITY_QUERY = Object.freeze({
7
+ version: 1,
8
+ kind: "query",
9
+ channels: ["api", "assistant", "internal"],
10
+ surfaces: ["app"]
11
+ });
12
+
13
+ /** @param {{ availabilityEngine: import("./types.js").AvailabilityEngine }} dependencies */
14
+ function createAvailabilityEngineActions({ availabilityEngine }) {
15
+ return Object.freeze([
16
+ Object.freeze({
17
+ ...AVAILABILITY_QUERY,
18
+ id: ACTION_GET_AVAILABILITY_STATUS,
19
+ input: emptyInputValidator,
20
+ output: null,
21
+ execute: (input) => availabilityEngine.getStatus(input)
22
+ })
23
+ ]);
24
+ }
25
+
26
+ export { ACTION_GET_AVAILABILITY_STATUS, createAvailabilityEngineActions };
@@ -1,34 +1,40 @@
1
1
  import { createWithTransaction } from "@jskit-ai/database-runtime/shared";
2
2
 
3
- function createRepository({ knex } = {}) {
4
- if (!knex) {
5
- throw new TypeError("createRepository requires knex.");
3
+ /**
4
+ * The invoice rollup's persistence: a reviewed custom Knex repository.
5
+ * @param {{ knex: import("@jskit-ai/database-runtime/server/types").RuntimeKnex }} dependencies
6
+ */
7
+ function createInvoiceRollup({ knex }) {
8
+ const withTransaction = createWithTransaction(knex);
9
+
10
+ async function getStatus(input, options = {}) {
11
+ return {
12
+ ok: true,
13
+ feature: "invoice-rollup",
14
+ persistence: "custom-knex",
15
+ tableName: "invoice_rollups",
16
+ hasTransaction: Boolean(options.trx),
17
+ input
18
+ };
19
+ }
20
+
21
+ async function execute(input, options = {}) {
22
+ return {
23
+ accepted: false,
24
+ feature: "invoice-rollup",
25
+ persistence: "custom-knex",
26
+ tableName: "invoice_rollups",
27
+ hasTransaction: Boolean(options.trx),
28
+ input,
29
+ message: "Replace this example with the reviewed domain-specific query."
30
+ };
6
31
  }
7
32
 
8
33
  return Object.freeze({
9
- withTransaction: createWithTransaction(knex),
10
- async getStatus(input = {}, options = {}) {
11
- return {
12
- ok: true,
13
- feature: "invoice-rollup",
14
- persistence: "custom-knex",
15
- tableName: "invoice_rollups",
16
- hasTransaction: Boolean(options.trx),
17
- input
18
- };
19
- },
20
- async execute(input = {}, options = {}) {
21
- return {
22
- accepted: false,
23
- feature: "invoice-rollup",
24
- persistence: "custom-knex",
25
- tableName: "invoice_rollups",
26
- hasTransaction: Boolean(options.trx),
27
- input,
28
- message: "Replace this example with the reviewed domain-specific query."
29
- };
30
- }
34
+ withTransaction,
35
+ getStatus,
36
+ execute
31
37
  });
32
38
  }
33
39
 
34
- export { createRepository };
40
+ export { createInvoiceRollup };
@@ -0,0 +1,26 @@
1
+ import { emptyInputValidator } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
2
+
3
+ const ACTION_GET_ROLLUP_STATUS = "invoices.rollup.status.read";
4
+
5
+ /** The fields every invoice rollup query shares, spread first into each definition: they run on the admin surface. */
6
+ const ROLLUP_QUERY = Object.freeze({
7
+ version: 1,
8
+ kind: "query",
9
+ channels: ["api", "assistant", "internal"],
10
+ surfaces: ["admin"]
11
+ });
12
+
13
+ /** @param {{ invoiceRollup: import("./types.js").InvoiceRollup }} dependencies */
14
+ function createInvoiceRollupActions({ invoiceRollup }) {
15
+ return Object.freeze([
16
+ Object.freeze({
17
+ ...ROLLUP_QUERY,
18
+ id: ACTION_GET_ROLLUP_STATUS,
19
+ input: emptyInputValidator,
20
+ output: null,
21
+ execute: (input, context) => invoiceRollup.getStatus(input, { context })
22
+ })
23
+ ]);
24
+ }
25
+
26
+ export { ACTION_GET_ROLLUP_STATUS, createInvoiceRollupActions };
@@ -1,23 +1,28 @@
1
- function createService() {
1
+ /** The availability engine: orchestration with no persistence of its own. */
2
+ function createAvailabilityEngine() {
3
+ async function getStatus(input) {
4
+ return {
5
+ ok: true,
6
+ feature: "availability-engine",
7
+ mode: "orchestrator",
8
+ input
9
+ };
10
+ }
11
+
12
+ async function execute(input) {
13
+ return {
14
+ accepted: false,
15
+ feature: "availability-engine",
16
+ mode: "orchestrator",
17
+ input,
18
+ message: "Replace this example with calls to the feature's injected collaborators."
19
+ };
20
+ }
21
+
2
22
  return Object.freeze({
3
- async getStatus(input = {}) {
4
- return {
5
- ok: true,
6
- feature: "availability-engine",
7
- mode: "orchestrator",
8
- input
9
- };
10
- },
11
- async execute(input = {}) {
12
- return {
13
- accepted: false,
14
- feature: "availability-engine",
15
- mode: "orchestrator",
16
- input,
17
- message: "Replace this example with calls to the feature's injected collaborators."
18
- };
19
- }
23
+ getStatus,
24
+ execute
20
25
  });
21
26
  }
22
27
 
23
- export { createService };
28
+ export { createAvailabilityEngine };
@@ -0,0 +1,7 @@
1
+ // The types of the `feature.availability-engine` and `feature.invoice-rollup`
2
+ // capabilities, for features that require them.
3
+
4
+ /** @typedef {ReturnType<typeof import("./orchestratorService.js").createAvailabilityEngine>} AvailabilityEngine */
5
+ /** @typedef {ReturnType<typeof import("./customKnexRepository.js").createInvoiceRollup>} InvoiceRollup */
6
+
7
+ export {};
@@ -57,7 +57,34 @@ questionnaire or infer tenancy, authentication, or database requirements.
57
57
  - Treat copied files as app-owned source. Do not add provenance, ownership
58
58
  markers, receipts, ledgers, or operation-history state.
59
59
  - Keep browser dependencies aligned with the execution environment that will
60
- run the tests. Vibe64 supplies its exact managed Playwright version.
60
+ run the tests. A managed runner supplies its exact Playwright version.
61
+ - Server code the application adds follows
62
+ [typed features](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/agent-docs/site/guide/framework/typed-features.md):
63
+ a provided capability exports its type from `types.js`; collaborators arrive
64
+ through declared capabilities, typed in a JSDoc `@param` and required, never
65
+ probed or defaulted to nothing; slots are `optional` tokens with a named
66
+ default; one `create<Name>Actions({ <api> })` per feature returns frozen
67
+ actions whose `execute` is one call; every `create*` returns a frozen object
68
+ of named functions; one copy of each helper per package; files stay under
69
+ 750 lines and functions under 600. `createServer({ runtimeEnv })` requires
70
+ the environment it runs with, typed as the kernel's `RuntimeEnv` (the process
71
+ environment, string values: `resolveRuntimeEnv()` keeps `PORT` a string), and
72
+ `server.js` takes `API_BASE_PATH` and `toRequestPathname` from the kernel's
73
+ `shared/surface/paths`. `server/lib/envFile.js` loads `.env` once per process
74
+ for every entry point. `server/lib/loggerOptions.js` gives Fastify's logger
75
+ pino's error serializer under `error` as well as `err`, so
76
+ `logger.error({ error }, "...")` keeps the error's message and stack. `eslint.config.mjs` holds
77
+ server and shared code to every typed-features rule (`typedFeaturesConfig`),
78
+ client code (`src/**` and `packages/*/src/client/**`, Vue components
79
+ included) to the client rules (`clientFeaturesConfig`), all hand-written
80
+ code to the size limits (`sizeLimitsConfig`), and server, config and script
81
+ code to the formatter (`formatterConfig`), all as errors, so `npm run lint`
82
+ reports code that breaks the
83
+ [typed features guide](https://mobily-enterprises.github.io/jskit-ai/guide/framework/typed-features)
84
+ or the
85
+ [client features guide](https://mobily-enterprises.github.io/jskit-ai/guide/framework/client-features).
86
+ Client code the application adds keeps simple, direct code first, and types
87
+ each provider hook with `@jskit-ai/kernel/client/types`.
61
88
 
62
89
  ## Framework APIs
63
90
 
@@ -129,3 +156,5 @@ Confirm `/api/health` and the first product route.
129
156
  - Do not keep `reading-room` names that no longer describe the product.
130
157
  - Do not add a hidden file recording that this pattern was copied.
131
158
  - Do not turn the example into a field interpolation language.
159
+ - Do not probe a collaborator, default one to `null`, `{}` or a no-op, fill a
160
+ slot with a setter after construction, or keep a module-level registry.
@@ -8,6 +8,20 @@ Framework references:
8
8
  - `https://mobily-enterprises.github.io/jskit-ai/guide/`
9
9
  - `https://mobily-enterprises.github.io/jskit-ai/patterns/`
10
10
 
11
+ Before writing or reviewing server code (a feature, provider, action, service,
12
+ repository, route, error or test), read the typed features guide at
13
+ `https://mobily-enterprises.github.io/jskit-ai/guide/framework/typed-features`.
14
+ `npm run lint` checks its rules, and each finding links the section that
15
+ explains it; `npm run verify` adds the package graph, tests and build. Fix a
16
+ finding in the code; excuse one only with the guide's `readable-check: allow`
17
+ comment and reason prefix.
18
+
19
+ Before writing or reviewing client code (a composable, component, client
20
+ factory or client provider), read the client features guide at
21
+ `https://mobily-enterprises.github.io/jskit-ai/guide/framework/client-features`.
22
+ Simple, direct code comes first: never add a layer, wrapper, registry or tiny
23
+ module only to satisfy a rule. `npm run lint` checks its rules too.
24
+
11
25
  Before implementation, read the narrow relevant source pattern completely. If
12
26
  its owner package is installed, prefer that version-matched package-owned copy.
13
27
  Do not install an unrelated runtime package only to read documentation.