@jskit-ai/agent-docs 0.1.278 → 0.1.280

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 (114) hide show
  1. package/guide/agent/app-extras/assistant.md +123 -0
  2. package/guide/agent/app-setup/authentication.md +46 -4
  3. package/guide/agent/app-setup/database-layer.md +35 -6
  4. package/guide/agent/app-setup/material-3-migration.md +53 -10
  5. package/guide/agent/app-setup/multi-homing.md +8 -2
  6. package/guide/agent/app-setup/upgrading-jskit.md +30 -0
  7. package/guide/agent/app-setup/users.md +9 -1
  8. package/guide/agent/framework/material-3.md +153 -71
  9. package/guide/agent/framework/sanity-checks.md +180 -0
  10. package/guide/agent/framework/translation.md +4 -0
  11. package/guide/agent/framework/typed-features.md +158 -105
  12. package/guide/agent/framework/ui-operations.md +3 -1
  13. package/guide/agent/index.md +3 -0
  14. package/package.json +2 -2
  15. package/patterns/feature-package/example/booking-engine/package.json +1 -1
  16. package/patterns/minimal-foundation/PATTERN.md +6 -2
  17. package/patterns/minimal-foundation/example/AGENTS.md +10 -0
  18. package/patterns/minimal-foundation/example/package.json +6 -6
  19. package/patterns/minimal-foundation/example/playwright.config.mjs +3 -0
  20. package/patterns/minimal-foundation/example/src/main.js +3 -2
  21. package/patterns/minimal-foundation/example/vite.config.mjs +3 -1
  22. package/patterns/shell-foundation/PATTERN.md +4 -1
  23. package/patterns/shell-foundation/example/AGENTS.md +10 -0
  24. package/patterns/shell-foundation/example/package.json +7 -7
  25. package/patterns/shell-foundation/example/packages/main/package.json +1 -1
  26. package/patterns/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +3 -0
  27. package/patterns/shell-foundation/example/playwright.config.mjs +3 -0
  28. package/patterns/shell-foundation/example/src/components/menus/SectionTabLinkItem.vue +42 -0
  29. package/patterns/shell-foundation/example/src/main.js +3 -2
  30. package/patterns/shell-foundation/example/src/pages/home.vue +1 -1
  31. package/patterns/shell-foundation/example/src/views/NotFound.vue +1 -1
  32. package/patterns/shell-foundation/example/vite.config.mjs +3 -1
  33. package/reference/autogen/PATTERN_INDEX.md +37 -37
  34. package/reference/autogen/packages/agent-docs.md +4 -0
  35. package/reference/autogen/packages/assistant-runtime.md +27 -2
  36. package/reference/autogen/packages/auth-provider-local-core.md +1 -1
  37. package/reference/autogen/packages/auth-web.md +10 -0
  38. package/reference/autogen/packages/crud-core.md +3 -0
  39. package/reference/autogen/packages/http-web.md +0 -6
  40. package/reference/autogen/packages/json-rest-api-core.md +17 -4
  41. package/reference/autogen/packages/kernel.md +10 -1
  42. package/reference/autogen/packages/material-web.md +2 -1
  43. package/reference/autogen/packages/shell-web.md +95 -4
  44. package/reference/autogen/packages/users-web.md +9 -2
  45. package/reference/autogen/packages/workspaces-core.md +2 -0
  46. package/reference/autogen/tooling/jskit-catalog.md +55 -6
  47. package/reference/autogen/tooling/testUtils.md +15 -1
  48. package/skills/jskit/SKILL.md +15 -5
  49. package/skills/jskit/references/heuristics/INDEX.md +3 -1
  50. package/skills/jskit/references/heuristics/row-policies.md +3 -3
  51. package/skills/jskit/references/heuristics/typed-features.md +7 -7
  52. package/skills/jskit/references/heuristics/ui-testing.md +8 -7
  53. package/skills/jskit/references/material-3.md +153 -71
  54. package/skills/jskit/references/multi-homing.md +8 -2
  55. package/skills/jskit/references/pattern-index.md +37 -37
  56. package/skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md +6 -2
  57. package/skills/jskit/references/patterns/app/minimal-foundation/example/AGENTS.md +10 -0
  58. package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +6 -6
  59. package/skills/jskit/references/patterns/app/minimal-foundation/example/playwright.config.mjs +3 -0
  60. package/skills/jskit/references/patterns/app/minimal-foundation/example/src/main.js +3 -2
  61. package/skills/jskit/references/patterns/app/minimal-foundation/example/vite.config.mjs +3 -1
  62. package/skills/jskit/references/patterns/app/shell-foundation/PATTERN.md +4 -1
  63. package/skills/jskit/references/patterns/app/shell-foundation/example/AGENTS.md +10 -0
  64. package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +7 -7
  65. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
  66. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +3 -0
  67. package/skills/jskit/references/patterns/app/shell-foundation/example/playwright.config.mjs +3 -0
  68. package/skills/jskit/references/patterns/app/shell-foundation/example/src/components/menus/SectionTabLinkItem.vue +42 -0
  69. package/skills/jskit/references/patterns/app/shell-foundation/example/src/main.js +3 -2
  70. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home.vue +1 -1
  71. package/skills/jskit/references/patterns/app/shell-foundation/example/src/views/NotFound.vue +1 -1
  72. package/skills/jskit/references/patterns/app/shell-foundation/example/vite.config.mjs +3 -1
  73. package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +2 -2
  74. package/skills/jskit/references/patterns/auth/auth-surface/PATTERN.md +18 -5
  75. package/skills/jskit/references/patterns/auth/auth-surface/example/src/components/AppBrand.vue +17 -0
  76. package/skills/jskit/references/patterns/auth/auth-surface/example/src/pages/auth/login.vue +2 -2
  77. package/skills/jskit/references/patterns/auth/auth-surface/example/src/pages/auth/reset-password.vue +2 -2
  78. package/skills/jskit/references/patterns/auth/auth-surface/example/src/pages/auth/signout.vue +2 -2
  79. package/skills/jskit/references/patterns/auth/auth-surface/example/src/views/auth/LoginView.vue +6 -1
  80. package/skills/jskit/references/patterns/auth/auth-surface/example/src/views/auth/ResetPasswordView.vue +6 -1
  81. package/skills/jskit/references/patterns/auth/auth-surface/example/src/views/auth/SignOutView.vue +6 -1
  82. package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
  83. package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
  84. package/skills/jskit/references/patterns/connectors/aws-storage-queries/example/formats/package.json +1 -1
  85. package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
  86. package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console.vue +1 -1
  87. package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +2 -2
  88. package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
  89. package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
  90. package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
  91. package/skills/jskit/references/patterns/rewards/google-rewarded/example/googlePublisherTag.js +5 -2
  92. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +1 -1
  93. package/skills/jskit/references/patterns/shell/application-shell/PATTERN.md +11 -6
  94. package/skills/jskit/references/patterns/shell/application-shell/example/src/components/menus/SectionTabLinkItem.vue +42 -0
  95. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home.vue +1 -1
  96. package/skills/jskit/references/patterns/shell/application-shell/example/src/views/NotFound.vue +1 -1
  97. package/skills/jskit/references/patterns/ui/page-and-placement/PATTERN.md +6 -0
  98. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports.vue +9 -4
  99. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/placementTopology.js +5 -3
  100. package/skills/jskit/references/patterns/users/account-settings/PATTERN.md +28 -2
  101. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsNotificationsSection.vue +1 -1
  102. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsPreferencesSection.vue +2 -1
  103. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsProfileSection.vue +3 -2
  104. package/skills/jskit/references/patterns/users/account-settings/example/src/pages/account/[section].vue +23 -0
  105. package/skills/jskit/references/patterns/users/account-settings/example/src/pages/account.vue +23 -0
  106. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +2 -2
  107. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +3 -3
  108. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/packages/main/src/client/components/AccountPendingInvitesCue.vue +3 -3
  109. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/admin/root.vue +1 -1
  110. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/app/root.vue +1 -1
  111. package/skills/jskit/references/sanity-checks.md +180 -0
  112. package/skills/jskit/references/translation.md +4 -0
  113. package/skills/jskit/references/typed-features.md +158 -105
  114. package/skills/jskit/references/ui-operations.md +3 -1
@@ -10,8 +10,8 @@
10
10
  "./shared": "./src/shared/index.js"
11
11
  },
12
12
  "dependencies": {
13
- "@jskit-ai/crud-core": "0.2.11",
14
- "@jskit-ai/resource-crud-core": "0.1.201"
13
+ "@jskit-ai/crud-core": "0.2.12",
14
+ "@jskit-ai/resource-crud-core": "0.1.202"
15
15
  },
16
16
  "jskit": {
17
17
  "kind": "runtime",
@@ -10,9 +10,9 @@
10
10
  "./shared": "./src/shared/index.js"
11
11
  },
12
12
  "dependencies": {
13
- "@jskit-ai/crud-core": "0.2.11",
14
- "@jskit-ai/resource-crud-core": "0.1.201",
15
- "@jskit-ai/workspaces-core": "0.2.12"
13
+ "@jskit-ai/crud-core": "0.2.12",
14
+ "@jskit-ai/resource-crud-core": "0.1.202",
15
+ "@jskit-ai/workspaces-core": "0.2.13"
16
16
  },
17
17
  "jskit": {
18
18
  "kind": "runtime",
@@ -57,16 +57,16 @@ const isVisible = computed(() => {
57
57
 
58
58
  const resolvedTo = computed(() => {
59
59
  const hasAccountSurface = Boolean(resolveSurfaceDefinitionFromPlacementContext(placementContext.value, "account"));
60
+ // The invitations section of account settings, /account/invites.
60
61
  const accountSettingsPath = hasAccountSurface
61
- ? resolveSurfacePathFromPlacementContext(placementContext.value, "account", "/")
62
- : "/account";
62
+ ? resolveSurfacePathFromPlacementContext(placementContext.value, "account", "/invites")
63
+ : "/account/invites";
63
64
  const accountSettingsNavigation = resolveSurfaceNavigationTargetFromPlacementContext(placementContext.value, {
64
65
  path: accountSettingsPath,
65
66
  surfaceId: "account"
66
67
  });
67
68
 
68
69
  const query = new URLSearchParams({
69
- section: "invites",
70
70
  returnTo: accountSettingsNavigation.sameOrigin ? resolveReturnTo() : resolveReturnToHref()
71
71
  });
72
72
  return appendQueryString(accountSettingsPath, query.toString());
@@ -14,7 +14,7 @@ import { RouterView } from "vue-router";
14
14
  </script>
15
15
 
16
16
  <template>
17
- <ShellLayout title="" subtitle="">
17
+ <ShellLayout>
18
18
  <RouterView />
19
19
  </ShellLayout>
20
20
  </template>
@@ -14,7 +14,7 @@ import { RouterView } from "vue-router";
14
14
  </script>
15
15
 
16
16
  <template>
17
- <ShellLayout title="" subtitle="">
17
+ <ShellLayout>
18
18
  <RouterView />
19
19
  </ShellLayout>
20
20
  </template>
@@ -0,0 +1,180 @@
1
+ <!-- Generated from `packages/agent-docs/site/guide/framework/sanity-checks.md`. -->
2
+
3
+ # Sanity checks
4
+
5
+ Before calling a list, a save, a test, a refactor, a screen or a deployment
6
+ done, measure what it actually costs and does, judge whether that is sane, and
7
+ fix the cause when it is not. This page is the JSKIT part of that: the
8
+ pitfalls JSKIT's own packages cause, then which JSKIT call, helper or setting
9
+ applies each check, with one line on what the check catches and why.
10
+
11
+ ## JSKIT's own pitfalls
12
+
13
+ ### Theme and component defaults
14
+
15
+ **Check:** after changing a theme, a Vuetify default, a material-web default
16
+ or a shared component, use what it affects in a production build: open a
17
+ select and type, press a segmented button at desktop width, tap neighbouring
18
+ icon buttons, and leave a field to see whether the layout shifts under the
19
+ next tap. A default reaches every component that renders the one it names, so
20
+ a change made for one screen can break others that never import it
21
+ ([Material 3](material-3.md)).
22
+
23
+ **Examples:**
24
+
25
+ - A `VMenu: { VSheet: {} }` default broke a select's typeahead.
26
+ - A common button padding squeezed segmented buttons into slivers.
27
+ - A field that grew 32 px on blur moved the button under a person's tap.
28
+
29
+ ### Navigation metadata
30
+
31
+ **Check:** open each inner page directly and by link, and see its Up arrow
32
+ and title. Some navigation declarations look right but switch Up off, and
33
+ some shapes leave pages the navigation rules cannot judge
34
+ ([Material 3](material-3.md)):
35
+
36
+ - a parent declared beside `jskit.surface` is never read; the surface goes on
37
+ the layout page and the parent on the page it renders (`nav/surface-parent`
38
+ reports the two on one record);
39
+ - an inner page repeating its surface becomes a root of its own, with no Up;
40
+ - until a main-navigation placement is literal data, no page is judged for a
41
+ missing parent (`nav/placement-data`);
42
+ - a layout that also renders its pages without `ShellLayout` leaves those
43
+ pages unjudged by `nav/missing-parent`, so a missing parent passes;
44
+ - a package route is judged only when its client entry lists
45
+ `routeComponents` literally; a built map passes unjudged.
46
+
47
+ **Example:** a design-system update moved a page title into a top app bar
48
+ that one page did not have, so its title vanished; only the browser suite
49
+ caught it.
50
+
51
+ ### Generated action and tool contracts
52
+
53
+ **Check:** call each assistant tool the way the model will, with sparse
54
+ `fields` and an `include`, and compare the result with the output contract it
55
+ advertises. An action is a tool only when it has an input contract and a
56
+ truthful model-facing output; the assistant validates the result against
57
+ `extensions.assistant.output` and rejects unexpected fields, so a contract
58
+ that promises what execution cannot return fails at run time, not at review
59
+ ([Assistant](/guide/app-extras/assistant#database-surface-action-tools)).
60
+
61
+ **Example:** sparse primary fields stay sparse, and an included record is read
62
+ from its lookup container (`items[0].lookups.pet.name`); a contract that
63
+ expects the relationship id or an unselected field never gets it.
64
+
65
+ ## Applying each check
66
+
67
+ ### Every row
68
+
69
+ - An unpaged JSON:API query returns the first 20 rows, and a page above the
70
+ resource's `queryMaxLimit` (100 unless it sets one) is cut to that size,
71
+ both without an error; CRUD `queryDocuments()` refuses such a `limit`. A
72
+ read its callers treat as complete uses `queryAllJsonRestCollectionRows()`
73
+ or the repository's `queryEveryDocument()`, because the missing rows
74
+ otherwise vanish from every picker and delivery built on it
75
+ ([Every row](typed-features.md#every-row)).
76
+ - A lookup by a unique key matches at most one row, so it may read `rows[0]`
77
+ of a plain query.
78
+
79
+ ### Query counts and batches
80
+
81
+ - Count a path's queries with the test Knex instance's `query` event at a few
82
+ rows and at a realistic number; the count should follow tables and pages,
83
+ not rows ([Query counts at realistic
84
+ sizes](typed-features.md#query-counts-at-realistic-sizes)).
85
+ - A JSON:API read adds a few lookup and visibility queries per page and per
86
+ relationship field. That follows pages, so it is expected.
87
+ - `getDocumentById()`, `queryDocuments()` or a service `get` inside a loop is
88
+ the usual per-row read; batch it with an id-list `searchSchema` filter or
89
+ `include`, grouped with `Map.groupBy()` ([Lists read related rows in
90
+ batches](typed-features.md#lists-read-related-rows-in-batches)).
91
+ - A `rowPolicy` adds one correlated predicate to the query it is given, so
92
+ its cost follows the rows read, not the subject's history. It runs on every
93
+ single-record read, including a write's default `returning: "full"` read
94
+ back, so a write that discards its result passes `returning: "minimal"` and
95
+ a batch of creates uses `createDocuments()`, in the owner's transaction
96
+ ([Bounded access
97
+ checks](typed-features.md#bounded-access-checks)).
98
+
99
+ ### Tests
100
+
101
+ - `jskit test` runs test files in parallel within the machine's test budget
102
+ (`V64_TEST_CONCURRENCY`, else half the CPUs), and Playwright's `workers` and
103
+ Vitest's `maxWorkers` come from `testConcurrency()`. `jskit check` reports a
104
+ script or config that runs files one at a time; a file that must run alone
105
+ says why on its first line, `// jskit-test: alone - <reason>` ([Test files
106
+ run in parallel](typed-features.md#test-files-run-in-parallel)).
107
+ - Tests use `TEST_DB_NAME` and `BROWSER_TEST_DB_NAME`, both different from
108
+ `DB_NAME`, because tests write and delete rows and would destroy the
109
+ developer's data. A skip for want of a test database is a failure.
110
+ - Test databases restore a stored snapshot checked by a digest of the
111
+ migration and seed sources, and the harness reports each preparation phase's
112
+ duration, so slow preparation shows ([Test databases are prepared
113
+ once](typed-features.md#test-databases-are-prepared-once),
114
+ [integration test
115
+ databases](/guide/app-setup/database-layer#integration-test-databases)).
116
+
117
+ ### Inputs and access
118
+
119
+ - An action input declared `mode: "patch"` makes every field optional. Use it
120
+ only for an action that updates part of a record, and send that action
121
+ nothing to see what it does, because a missing field is then never refused.
122
+ - A route that repetition can abuse declares `rateLimit`, which the kernel
123
+ refuses with 429 and `kernel.http.rateLimited`; auth's limits come from
124
+ `config.auth.rateLimits` ([Sign-in
125
+ protection](/guide/app-setup/authentication#sign-in-protection)). Each
126
+ limit needs a test expecting the 429, or a dropped one goes unseen.
127
+ - Who acts comes from `resolveActor(context)` and the workspace from the
128
+ context's resolvers ([One reader per
129
+ fact](typed-features.md#one-reader-per-fact)); send another
130
+ workspace's id in the body and see the context win.
131
+
132
+ ### Refactors
133
+
134
+ Before changing a JSKIT feature, list where its behaviour lives, with the test
135
+ that covers each item, and walk the list again after: routes, actions and
136
+ their input schemas, row policies, CRUD fields, lookups and hooks, placements
137
+ and navigation meta, messages and their codes, events, jobs and migrations.
138
+ These are the places a consolidation drops behaviour without a failing build.
139
+
140
+ ### Changes others depend on
141
+
142
+ - After updating JSKIT packages, read [Upgrade
143
+ JSKIT](/guide/app-setup/upgrading-jskit) and each package changelog's
144
+ "Upgrading" notes, then boot, sign in and run the browser tests before
145
+ anything else, because a changed default shows only at run time.
146
+
147
+ ### Screens
148
+
149
+ - A long list renders what is visible, with pages or `v-virtual-scroll`,
150
+ because every row rendered costs DOM nodes and main-thread time.
151
+ - Command feedback goes through the shell's snackbar path: `ShellErrorHost`
152
+ keeps it clear of the FAB and the actions it reports on, and a full-screen
153
+ dialog puts its confirm action in the top bar, where a snackbar never covers
154
+ it ([Material 3](material-3.md)).
155
+ - Up is the shell's, from `meta.jskit.parent`; the navigation rules forbid
156
+ `router.back()` and hand-made back controls, so Up lands inside the app
157
+ even on a page opened from a link.
158
+
159
+ ### Production settings
160
+
161
+ - `NODE_ENV=production` is JSKIT's only production switch. Without it a
162
+ deployed server runs as development: no first-account setup code, and
163
+ development-only settings accepted.
164
+ - On an empty production database, local auth asks for the first account's
165
+ setup code, so whoever reaches a new deployment first cannot own it ([The
166
+ first account in
167
+ production](/guide/app-setup/authentication#the-first-account-in-production-local-auth)).
168
+ Give any registration of your own the same protection.
169
+ - `config.securityHeaders` sends the security headers, with the content
170
+ security policy reported, not enforced, by default; read them on a
171
+ production build ([Security
172
+ headers](/guide/app-setup/initial-scaffolding#security-headers)).
173
+ - Email confirmation needs `auth.local.confirmation-sender` in production, or
174
+ the server refuses to start while anyone may register ([Email
175
+ confirmation](/guide/app-setup/authentication#email-confirmation-local-auth)).
176
+ - Changing the assistant's instructions needs `assistant.settings.update` or
177
+ the surface's own permission ([Who may change the
178
+ instructions](/guide/app-extras/assistant#who-may-change-the-instructions)).
179
+ Its tools run as the typing user, through the `automation` channel, so an
180
+ action kept off that channel is never a tool.
@@ -193,6 +193,10 @@ and params to `details.fieldErrorCodes`, so an untranslated app shows exactly
193
193
  the English it showed before. The failed check's own params (for example
194
194
  `limit`) are sent too, and the coded entry's `params` win over them. JSKIT's
195
195
  own schemas use this form, which is why their field messages translate.
196
+ With json-rest-schema 1.0.18 or later, which checks them, an array field's
197
+ `minItems` and `maxItems` failures send `kernel.validation.field.minItems` and
198
+ `kernel.validation.field.maxItems` with `{ min | max, actual }`, and its
199
+ `messages.minItems` and `messages.maxItems` override them.
196
200
 
197
201
  ## Placement labels
198
202