@jskit-ai/agent-docs 0.1.291 → 0.1.293

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 (48) hide show
  1. package/guide/agent/app-setup/authentication.md +19 -8
  2. package/guide/agent/app-setup/multi-homing.md +19 -0
  3. package/guide/agent/app-setup/upgrading-jskit.md +4 -0
  4. package/guide/agent/framework/client-features.md +26 -1
  5. package/guide/agent/framework/data-access.md +118 -12
  6. package/guide/agent/framework/sanity-checks.md +4 -0
  7. package/guide/agent/framework/typed-features.md +33 -2
  8. package/package.json +1 -1
  9. package/patterns/feature-package/example/booking-engine/package.json +2 -2
  10. package/patterns/minimal-foundation/example/AGENTS.md +5 -1
  11. package/patterns/minimal-foundation/example/package.json +5 -5
  12. package/patterns/shell-foundation/example/AGENTS.md +5 -1
  13. package/patterns/shell-foundation/example/package.json +6 -6
  14. package/patterns/shell-foundation/example/packages/main/package.json +1 -1
  15. package/reference/autogen/PATTERN_INDEX.md +38 -38
  16. package/reference/autogen/packages/crud-core.md +1 -1
  17. package/reference/autogen/packages/kernel.md +7 -1
  18. package/reference/autogen/packages/resource-runtime.md +13 -4
  19. package/reference/autogen/packages/workspaces-core.md +8 -2
  20. package/reference/autogen/packages/workspaces-web.md +1 -0
  21. package/reference/autogen/tooling/config-eslint.md +18 -1
  22. package/reference/autogen/tooling/jskit-catalog.md +8 -0
  23. package/skills/jskit/references/client-features.md +26 -1
  24. package/skills/jskit/references/data-access.md +118 -12
  25. package/skills/jskit/references/heuristics/ui-testing.md +6 -3
  26. package/skills/jskit/references/multi-homing.md +19 -0
  27. package/skills/jskit/references/pattern-index.md +38 -38
  28. package/skills/jskit/references/patterns/app/minimal-foundation/example/AGENTS.md +5 -1
  29. package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +5 -5
  30. package/skills/jskit/references/patterns/app/shell-foundation/example/AGENTS.md +5 -1
  31. package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +6 -6
  32. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
  33. package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +3 -3
  34. package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
  35. package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
  36. package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
  37. package/skills/jskit/references/patterns/crud/crud-feature-package/example/packages/books/package.json +3 -3
  38. package/skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md +3 -1
  39. package/skills/jskit/references/patterns/database/mysql-application/example/package.json +2 -2
  40. package/skills/jskit/references/patterns/database/postgres-application/example/package.json +2 -2
  41. package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
  42. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +2 -2
  43. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsPreferencesSection.vue +7 -0
  44. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +3 -3
  45. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +6 -6
  46. package/skills/jskit/references/patterns/workspaces/workspace-server/PATTERN.md +9 -0
  47. package/skills/jskit/references/sanity-checks.md +4 -0
  48. package/skills/jskit/references/typed-features.md +33 -2
@@ -34,24 +34,24 @@
34
34
  "dependencies": {
35
35
  "@local/main": "0.1.0",
36
36
  "@fastify/static": "^10.1.3",
37
- "@jskit-ai/kernel": "0.2.17",
37
+ "@jskit-ai/kernel": "0.2.18",
38
38
  "@jskit-ai/material-web": "0.1.5",
39
39
  "@tanstack/vue-query": "^5.101.0",
40
40
  "fastify": "^5.12.7",
41
41
  "pino": "^10.3.1",
42
- "json-rest-schema": "^1.0.17",
42
+ "json-rest-schema": "^1.0.20",
43
43
  "pinia": "^4.0.3",
44
44
  "vue": "^3.5.44",
45
45
  "vue-router": "^5.3.1",
46
46
  "vuetify": "^4.3.0",
47
- "@jskit-ai/http-runtime": "0.2.17",
48
- "@jskit-ai/shell-web": "0.2.21",
47
+ "@jskit-ai/http-runtime": "0.2.18",
48
+ "@jskit-ai/shell-web": "0.2.22",
49
49
  "@fastify/fast-json-stringify-compiler": "^5.1.0",
50
50
  "@vue/devtools-api": "^8.2.1"
51
51
  },
52
52
  "devDependencies": {
53
- "@jskit-ai/config-eslint": "0.1.248",
54
- "@jskit-ai/jskit-catalog": "0.2.43",
53
+ "@jskit-ai/config-eslint": "0.1.249",
54
+ "@jskit-ai/jskit-catalog": "0.2.45",
55
55
  "@playwright/test": "1.61.1",
56
56
  "@vitejs/plugin-vue": "^6.0.7",
57
57
  "eslint": "^10.8.0",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "description": "App-local runtime composition and lightweight glue.",
11
11
  "dependencies": {
12
- "@jskit-ai/kernel": "0.2.17"
12
+ "@jskit-ai/kernel": "0.2.18"
13
13
  },
14
14
  "jskit": {
15
15
  "kind": "runtime",
@@ -2,8 +2,8 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@jskit-ai/database-runtime": "0.1.266",
6
- "@jskit-ai/database-runtime-mysql": "0.1.264",
7
- "@jskit-ai/oidc-issuer-core": "0.1.25"
5
+ "@jskit-ai/database-runtime": "0.1.267",
6
+ "@jskit-ai/database-runtime-mysql": "0.1.265",
7
+ "@jskit-ai/oidc-issuer-core": "0.1.26"
8
8
  }
9
9
  }
@@ -2,7 +2,7 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@jskit-ai/auth-provider-oidc-core": "0.2.25",
6
- "@jskit-ai/auth-web": "0.2.23"
5
+ "@jskit-ai/auth-provider-oidc-core": "0.2.26",
6
+ "@jskit-ai/auth-web": "0.2.24"
7
7
  }
8
8
  }
@@ -2,6 +2,6 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@jskit-ai/auth-provider-supabase-core": "0.2.19"
5
+ "@jskit-ai/auth-provider-supabase-core": "0.2.20"
6
6
  }
7
7
  }
@@ -7,10 +7,10 @@
7
7
  "db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
8
8
  },
9
9
  "dependencies": {
10
- "@jskit-ai/connectors-core": "0.2.21",
11
- "@jskit-ai/connector-google-calendar": "0.2.21",
12
- "@jskit-ai/database-runtime": "0.1.266",
13
- "@jskit-ai/database-runtime-mysql": "0.1.264",
10
+ "@jskit-ai/connectors-core": "0.2.23",
11
+ "@jskit-ai/connector-google-calendar": "0.2.23",
12
+ "@jskit-ai/database-runtime": "0.1.267",
13
+ "@jskit-ai/database-runtime-mysql": "0.1.265",
14
14
  "knex": "^3.1.0"
15
15
  }
16
16
  }
@@ -9,9 +9,9 @@
9
9
  "./shared": "./src/shared/index.js"
10
10
  },
11
11
  "dependencies": {
12
- "@jskit-ai/crud-core": "0.2.21",
13
- "@jskit-ai/resource-core": "0.1.208",
14
- "@jskit-ai/resource-crud-core": "0.1.208"
12
+ "@jskit-ai/crud-core": "0.2.23",
13
+ "@jskit-ai/resource-core": "0.1.209",
14
+ "@jskit-ai/resource-crud-core": "0.1.209"
15
15
  },
16
16
  "jskit": {
17
17
  "kind": "runtime",
@@ -143,7 +143,9 @@ arrive. `SelectField` hides an unresolved value while `loading` is true, shows
143
143
  "Unavailable option" once the options settle, and remembers titles it has seen
144
144
  so a narrowing search does not blank a chosen value. Display never changes the
145
145
  stored value. `searchable` renders an autocomplete; other props and slots pass
146
- through to Vuetify.
146
+ through to Vuetify. The lint rule `jskit/selection-field` reports a raw
147
+ selection whose items are not fixed, and a `SelectField` over loaded items
148
+ without `loading`.
147
149
 
148
150
  ```vue
149
151
  <CrudAddEditScreen :screen="screen" v-bind="lookups">
@@ -9,7 +9,7 @@
9
9
  "test": "jskit test --databases"
10
10
  },
11
11
  "dependencies": {
12
- "@jskit-ai/database-runtime": "0.1.266",
13
- "@jskit-ai/database-runtime-mysql": "0.1.264"
12
+ "@jskit-ai/database-runtime": "0.1.267",
13
+ "@jskit-ai/database-runtime-mysql": "0.1.265"
14
14
  }
15
15
  }
@@ -9,7 +9,7 @@
9
9
  "test": "jskit test --databases"
10
10
  },
11
11
  "dependencies": {
12
- "@jskit-ai/database-runtime": "0.1.266",
13
- "@jskit-ai/database-runtime-postgres": "0.1.263"
12
+ "@jskit-ai/database-runtime": "0.1.267",
13
+ "@jskit-ai/database-runtime-postgres": "0.1.264"
14
14
  }
15
15
  }
@@ -2,7 +2,7 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@jskit-ai/realtime": "0.2.24",
6
- "@jskit-ai/shell-web": "0.2.21"
5
+ "@jskit-ai/realtime": "0.2.25",
6
+ "@jskit-ai/shell-web": "0.2.22"
7
7
  }
8
8
  }
@@ -5,8 +5,8 @@
5
5
  "private": true,
6
6
  "type": "module",
7
7
  "dependencies": {
8
- "@jskit-ai/kernel": "0.2.17",
9
- "json-rest-schema": "^1.0.17"
8
+ "@jskit-ai/kernel": "0.2.18",
9
+ "json-rest-schema": "^1.0.20"
10
10
  },
11
11
  "exports": {
12
12
  "./server/actions": "./src/server/bookingEngineActions.js",
@@ -15,6 +15,7 @@ const preferences = props.runtime.preferences;
15
15
  <v-form @submit.prevent="preferences.submit" novalidate>
16
16
  <v-row>
17
17
  <v-col cols="12" md="4">
18
+ <!-- readable-check: allow selection-field - data: the account settings runtime holds these as fixed lists, so nothing loads -->
18
19
  <v-select
19
20
  v-model="preferences.form.theme"
20
21
  label="Theme"
@@ -29,6 +30,7 @@ const preferences = props.runtime.preferences;
29
30
  </v-col>
30
31
 
31
32
  <v-col cols="12" md="4">
33
+ <!-- readable-check: allow selection-field - data: the account settings runtime holds these as fixed lists, so nothing loads -->
32
34
  <v-select
33
35
  v-model="preferences.form.locale"
34
36
  label="Language / locale"
@@ -43,6 +45,7 @@ const preferences = props.runtime.preferences;
43
45
  </v-col>
44
46
 
45
47
  <v-col cols="12" md="4">
48
+ <!-- readable-check: allow selection-field - data: the account settings runtime holds these as fixed lists, so nothing loads -->
46
49
  <v-select
47
50
  v-model="preferences.form.timeZone"
48
51
  label="Time zone"
@@ -55,6 +58,7 @@ const preferences = props.runtime.preferences;
55
58
  </v-col>
56
59
 
57
60
  <v-col cols="12" md="4">
61
+ <!-- readable-check: allow selection-field - data: the account settings runtime holds these as fixed lists, so nothing loads -->
58
62
  <v-select
59
63
  v-model="preferences.form.dateFormat"
60
64
  label="Date format"
@@ -69,6 +73,7 @@ const preferences = props.runtime.preferences;
69
73
  </v-col>
70
74
 
71
75
  <v-col cols="12" md="4">
76
+ <!-- readable-check: allow selection-field - data: the account settings runtime holds these as fixed lists, so nothing loads -->
72
77
  <v-select
73
78
  v-model="preferences.form.numberFormat"
74
79
  label="Number format"
@@ -83,6 +88,7 @@ const preferences = props.runtime.preferences;
83
88
  </v-col>
84
89
 
85
90
  <v-col cols="12" md="4">
91
+ <!-- readable-check: allow selection-field - data: the account settings runtime holds these as fixed lists, so nothing loads -->
86
92
  <v-select
87
93
  v-model="preferences.form.currencyCode"
88
94
  label="Currency"
@@ -95,6 +101,7 @@ const preferences = props.runtime.preferences;
95
101
  </v-col>
96
102
 
97
103
  <v-col cols="12" md="4">
104
+ <!-- readable-check: allow selection-field - data: the account settings runtime holds these as fixed lists, so nothing loads -->
98
105
  <v-select
99
106
  v-model.number="preferences.form.avatarSize"
100
107
  label="Avatar size"
@@ -10,9 +10,9 @@
10
10
  "./shared": "./src/shared/index.js"
11
11
  },
12
12
  "dependencies": {
13
- "@jskit-ai/crud-core": "0.2.21",
14
- "@jskit-ai/resource-crud-core": "0.1.208",
15
- "@jskit-ai/users-core": "0.2.22"
13
+ "@jskit-ai/crud-core": "0.2.23",
14
+ "@jskit-ai/resource-crud-core": "0.1.209",
15
+ "@jskit-ai/users-core": "0.2.24"
16
16
  },
17
17
  "jskit": {
18
18
  "kind": "runtime",
@@ -10,14 +10,14 @@
10
10
  "./shared": "./src/shared/index.js"
11
11
  },
12
12
  "dependencies": {
13
- "@jskit-ai/crud-core": "0.2.21",
14
- "@jskit-ai/resource-crud-core": "0.1.208",
15
- "@jskit-ai/users-core": "0.2.22",
16
- "@jskit-ai/workspaces-core": "0.2.22"
13
+ "@jskit-ai/crud-core": "0.2.23",
14
+ "@jskit-ai/resource-crud-core": "0.1.209",
15
+ "@jskit-ai/users-core": "0.2.24",
16
+ "@jskit-ai/workspaces-core": "0.2.24"
17
17
  },
18
18
  "peerDependencies": {
19
- "@jskit-ai/kernel": "0.2.17",
20
- "@jskit-ai/resource-runtime": "0.2.18"
19
+ "@jskit-ai/kernel": "0.2.18",
20
+ "@jskit-ai/resource-runtime": "0.2.20"
21
21
  },
22
22
  "jskit": {
23
23
  "kind": "runtime",
@@ -74,6 +74,15 @@ external effects out of it. Without the capability, acceptance activates the
74
74
  membership only. Allow ordinary invitations; reject stale, revoked, conflicting
75
75
  or unexpectedly missing application associations.
76
76
 
77
+ Provide the optional `workspaces.workspace-created-participant` capability the
78
+ same way to write application records for every new workspace. The
79
+ `workspace.workspaces.create` action and personal workspace provisioning invoke
80
+ `fn({ workspace, owner }, txOptions)` after writing the workspace, its owner's
81
+ membership and its settings, in the creation's uncommitted transaction (the
82
+ caller's when it passes one). Pass `txOptions` on and propagate failures: a
83
+ failure rolls the whole creation back. An existing personal workspace does not
84
+ call it.
85
+
77
86
  Call `members.prepareInvite(workspace, actor, payload, txOptions)` inside
78
87
  `repositories.workspaceInvites.withTransaction(options, async (txOptions) => …)`
79
88
  or another resource handle's `withTransaction`. It returns
@@ -116,6 +116,10 @@ expects the relationship id or an unselected field never gets it.
116
116
  once](typed-features.md#test-databases-are-prepared-once),
117
117
  [integration test
118
118
  databases](database-layer.md#integration-test-databases)).
119
+ - A component's content and states are checked in a Vitest component test;
120
+ a browser check is an assertion in the Playwright spec that already reaches
121
+ that screen. Every Playwright run ends with its 10 slowest tests: compare a
122
+ new test's time, and the suite's, before and after.
119
123
 
120
124
  ### Inputs and access
121
125
 
@@ -76,6 +76,31 @@ setup: ({ resources }) => ({ invoices: { list: (options) => resources.invoices.q
76
76
  actions: ({ invoices }) => [{ id: "invoices.list", execute: () => invoices.list() }]
77
77
  ```
78
78
 
79
+ ### Package manifest
80
+
81
+ **A package's manifest, `jskit.capabilities` in its `package.json`, lists
82
+ exactly what its features provide, and every capability they require beyond
83
+ the kernel's own (`runtime.actions`, `runtime.events`, `runtime.http`,
84
+ `runtime.bootstrap`) and those the package provides itself.** Optional
85
+ capabilities are not required. A requirement no feature has stays only when
86
+ the package needs it at install time, such as the database its migrations
87
+ need.
88
+
89
+ Why: start-up resolves every package's requirements from the manifests, and
90
+ refuses a manifest that disagrees with the package's features. Plain
91
+ `jskit check` loads each application package's features (the server providers
92
+ `jskit.runtime.server.providers` declares) and reports the drift before that
93
+ (`manifest/capabilities`), each capability to add or remove; it lists the
94
+ requirements no feature has for review.
95
+
96
+ ```jsonc
97
+ // good: BooksFeature provides app.books and requires crud.contracts and runtime.actions
98
+ "capabilities": { "provides": ["app.books"], "requires": ["crud.contracts"] }
99
+
100
+ // bad: app.books missing from provides, crud.contracts from requires
101
+ "capabilities": { "provides": ["app.book"], "requires": [] }
102
+ ```
103
+
79
104
  ### Capability types
80
105
 
81
106
  **Each provided token has one `@typedef` in its package's `src/server/types.js`,
@@ -691,6 +716,11 @@ way (is this user an operator) is a member of its owner's capability.**
691
716
  meaning of 0 and false before replacing a copy.
692
717
  - A helper two packages of an application use lives in its shared package,
693
718
  never inside one of them.
719
+ - A component's closure over its own state is not a helper: a function of at
720
+ most two statements in `<script setup>` whose every outside name is a
721
+ binding `<script setup>` declares (not an import or a global). Two pages
722
+ that reload their own resources the same way keep their own `reload()`;
723
+ sharing it would take a module that receives each page's state.
694
724
 
695
725
  Why: the kernel's helpers fix one meaning of empty, and a copy brings its own.
696
726
 
@@ -1170,8 +1200,9 @@ Why: a comment that narrates history is wrong the day after it is written.
1170
1200
 
1171
1201
  `npm run lint` runs ESLint with `@jskit-ai/config-eslint`, and `npm run
1172
1202
  verify` runs `jskit check` (the package graph, navigation, [data
1173
- access](data-access.md#exceptions) and [test
1174
- runs](#test-run-rules)), lint, the tests and the build. The foundations'
1203
+ access](data-access.md#exceptions), [test
1204
+ runs](#test-run-rules) and [package manifests](#package-manifest)), lint, the
1205
+ tests and the build. The foundations'
1175
1206
  `eslint.config.mjs` already holds a new
1176
1207
  application's code to every check:
1177
1208