@jskit-ai/agent-docs 0.1.274 → 0.1.276

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 (109) hide show
  1. package/guide/agent/app-extras/assistant-conversation.md +7 -1
  2. package/guide/agent/app-extras/assistant-voice.md +5 -1
  3. package/guide/agent/app-setup/database-layer.md +30 -0
  4. package/guide/agent/app-setup/material-3-migration.md +180 -0
  5. package/guide/agent/app-setup/upgrading-jskit.md +5 -0
  6. package/guide/agent/framework/material-3.md +316 -73
  7. package/guide/agent/framework/typed-features.md +207 -0
  8. package/guide/agent/framework/ui-operations.md +18 -35
  9. package/guide/agent/framework/ui-pass.md +155 -0
  10. package/guide/agent/index.md +3 -0
  11. package/package.json +1 -1
  12. package/patterns/feature-package/example/booking-engine/package.json +1 -1
  13. package/patterns/minimal-foundation/example/package.json +5 -4
  14. package/patterns/minimal-foundation/example/src/main.js +5 -11
  15. package/patterns/minimal-foundation/example/src/pages/home/index.vue +5 -18
  16. package/patterns/minimal-foundation/example/src/theme/index.js +9 -0
  17. package/patterns/minimal-foundation/example/src/views/NotFound.vue +5 -4
  18. package/patterns/shell-foundation/example/package.json +6 -6
  19. package/patterns/shell-foundation/example/packages/main/package.json +1 -1
  20. package/patterns/shell-foundation/example/src/main.js +5 -11
  21. package/patterns/shell-foundation/example/src/pages/home/index.vue +21 -57
  22. package/patterns/shell-foundation/example/src/pages/home/settings/general/index.vue +24 -19
  23. package/patterns/shell-foundation/example/src/pages/home/settings.vue +27 -84
  24. package/patterns/shell-foundation/example/src/theme/index.js +9 -0
  25. package/patterns/shell-foundation/example/src/views/NotFound.vue +9 -7
  26. package/reference/autogen/PATTERN_INDEX.md +37 -37
  27. package/reference/autogen/README.md +1 -0
  28. package/reference/autogen/packages/agent-docs.md +8 -4
  29. package/reference/autogen/packages/assistant-core.md +1 -0
  30. package/reference/autogen/packages/console-web.md +5 -0
  31. package/reference/autogen/packages/http-web.md +29 -2
  32. package/reference/autogen/packages/kernel.md +2 -1
  33. package/reference/autogen/packages/material-web.md +54 -0
  34. package/reference/autogen/packages/shell-web.md +121 -9
  35. package/reference/autogen/tooling/jskit-catalog.md +81 -0
  36. package/reference/autogen/tooling/testUtils.md +7 -0
  37. package/skills/jskit/SKILL.md +17 -6
  38. package/skills/jskit/references/heuristics/INDEX.md +3 -3
  39. package/skills/jskit/references/heuristics/row-policies.md +10 -0
  40. package/skills/jskit/references/heuristics/typed-features.md +12 -0
  41. package/skills/jskit/references/heuristics/ui-contract.md +10 -7
  42. package/skills/jskit/references/heuristics/ui-testing.md +14 -8
  43. package/skills/jskit/references/material-3.md +315 -72
  44. package/skills/jskit/references/pattern-index.md +37 -37
  45. package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +5 -4
  46. package/skills/jskit/references/patterns/app/minimal-foundation/example/src/main.js +5 -11
  47. package/skills/jskit/references/patterns/app/minimal-foundation/example/src/pages/home/index.vue +5 -18
  48. package/skills/jskit/references/patterns/app/minimal-foundation/example/src/theme/index.js +9 -0
  49. package/skills/jskit/references/patterns/app/minimal-foundation/example/src/views/NotFound.vue +5 -4
  50. package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +6 -6
  51. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
  52. package/skills/jskit/references/patterns/app/shell-foundation/example/src/main.js +5 -11
  53. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home/index.vue +21 -57
  54. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home/settings/general/index.vue +24 -19
  55. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home/settings.vue +27 -84
  56. package/skills/jskit/references/patterns/app/shell-foundation/example/src/theme/index.js +9 -0
  57. package/skills/jskit/references/patterns/app/shell-foundation/example/src/views/NotFound.vue +9 -7
  58. package/skills/jskit/references/patterns/assistant/assistant-surface/example/src/placement.js +1 -1
  59. package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +2 -2
  60. package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
  61. package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
  62. package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
  63. package/skills/jskit/references/patterns/console/console-surface/PATTERN.md +4 -2
  64. package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console/index.vue +10 -40
  65. package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console/settings/index.vue +3 -11
  66. package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console/settings.vue +24 -72
  67. package/skills/jskit/references/patterns/console/console-surface/example/src/placement.js +28 -0
  68. package/skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md +13 -0
  69. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookEditPage.vue +2 -0
  70. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookFormFields.vue +0 -6
  71. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookListPage.vue +5 -2
  72. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookNewPage.vue +2 -0
  73. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookViewPage.vue +5 -9
  74. package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +2 -2
  75. package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
  76. package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
  77. package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
  78. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +1 -1
  79. package/skills/jskit/references/patterns/shell/application-shell/PATTERN.md +3 -1
  80. package/skills/jskit/references/patterns/shell/application-shell/example/expected-existing/src/pages/home/index.vue +5 -18
  81. package/skills/jskit/references/patterns/shell/application-shell/example/expected-existing/src/views/NotFound.vue +14 -0
  82. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home/index.vue +21 -57
  83. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home/settings/general/index.vue +24 -19
  84. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home/settings.vue +27 -84
  85. package/skills/jskit/references/patterns/shell/application-shell/example/src/views/NotFound.vue +15 -0
  86. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/components/SyncStatusElement.vue +2 -2
  87. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports/activity.vue +1 -1
  88. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports/overview.vue +1 -1
  89. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports.vue +6 -3
  90. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/placement.js +1 -1
  91. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsNotificationsSection.vue +2 -8
  92. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsPreferencesSection.vue +2 -8
  93. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsProfileSection.vue +5 -11
  94. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsSignInMethodsSection.vue +3 -9
  95. package/skills/jskit/references/patterns/users/account-settings/example/src/pages/account/index.vue +7 -0
  96. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +2 -2
  97. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +3 -3
  98. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/packages/main/src/client/components/AccountPendingInvitesCue.vue +1 -2
  99. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/components/WorkspaceNotFoundCard.vue +5 -6
  100. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/pages/admin/workspace/settings/index.vue +5 -12
  101. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/pages/admin/workspace/settings.vue +24 -72
  102. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/admin/index.vue +3 -4
  103. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/app/index.vue +3 -3
  104. package/skills/jskit/references/typed-features.md +207 -0
  105. package/skills/jskit/references/ui-operations.md +18 -35
  106. package/skills/jskit/references/ui-pass.md +150 -0
  107. package/patterns/shell-foundation/example/src/pages/home/settings/index.vue +0 -7
  108. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home/settings/index.vue +0 -7
  109. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home/settings/index.vue +0 -7
@@ -80,12 +80,25 @@ Exports
80
80
  ### `src/client/components/ShellLayout.vue`
81
81
  Exports
82
82
  - None
83
+ Local functions
84
+ - `updateScrolled()`
85
+ - `goUp()`
86
+
87
+ ### `src/client/components/ShellListDetail.vue`
88
+ Exports
89
+ - None
90
+ Local functions
91
+ - `releasePane()`
83
92
 
84
93
  ### `src/client/components/ShellMenuLinkItem.vue`
85
94
  Exports
86
95
  - None
87
96
 
88
- ### `src/client/components/ShellNavigationTooltip.vue`
97
+ ### `src/client/components/ShellNavigationItem.vue`
98
+ Exports
99
+ - None
100
+
101
+ ### `src/client/components/ShellNavigationScope.vue`
89
102
  Exports
90
103
  - None
91
104
 
@@ -100,6 +113,16 @@ Local functions
100
113
  Exports
101
114
  - None
102
115
 
116
+ ### `src/client/components/ShellPageAction.vue`
117
+ Exports
118
+ - None
119
+ Local functions
120
+ - `handleClick(event)`
121
+
122
+ ### `src/client/components/ShellPageActions.vue`
123
+ Exports
124
+ - None
125
+
103
126
  ### `src/client/components/ShellRouteTransition.vue`
104
127
  Exports
105
128
  - None
@@ -120,7 +143,7 @@ Exports
120
143
 
121
144
  ### `src/client/composables/useShellDrawer.js`
122
145
  Exports
123
- - `useShellDrawer({ props, isCompactLayout, navigationToggle, layoutState })`
146
+ - `useShellDrawer({ props, modalLayout, viewportWidth, navigationToggle, layoutState })`
124
147
  Local functions
125
148
  - `navigationDrawerElement()`
126
149
 
@@ -142,6 +165,10 @@ Exports
142
165
  - `shellNavigationLinkProps`
143
166
  - `useShellNavigationLink(props)`
144
167
 
168
+ ### `src/client/composables/useShellPageTitle.js`
169
+ Exports
170
+ - `useShellPageTitle(title)`
171
+
145
172
  ### `src/client/composables/useShellPullToRefresh.js`
146
173
  Exports
147
174
  - `useShellPullToRefresh({ enabled, refreshRuntime })`
@@ -152,6 +179,10 @@ Local functions
152
179
  Exports
153
180
  - `useShellRouteTransition(props)`
154
181
 
182
+ ### `src/client/composables/useShellWindowSizeClass.js`
183
+ Exports
184
+ - `useShellWindowSizeClass()`
185
+
155
186
  ### `src/client/error/index.js`
156
187
  Exports
157
188
  - `createDefaultErrorPolicy`
@@ -244,7 +275,15 @@ Exports
244
275
  - `ShellMenuLinkItem`
245
276
  - `ShellSurfaceAwareMenuLinkItem`
246
277
  - `ShellTabLinkItem`
278
+ - `ShellPageActions`
279
+ - `ShellPageAction`
280
+ - `ShellListDetail`
247
281
  - `useShellLayoutState`
282
+ - `useShellPageTitle`
283
+ - `useShellWindowSizeClass`
284
+ - `useShellNavigation`
285
+ - `leaveApp`
286
+ - `reloadAppPage`
248
287
  - `useShellLayoutStore`
249
288
  - `useShellErrorPresentationStore`
250
289
  - `SHELL_ASYNC_MODULE_RECOVERY_RUNTIME_KEY`
@@ -265,6 +304,11 @@ Local functions
265
304
  - `normalizePathname(value = "")`
266
305
  - `resolveSurfaceSwitchIdFromLabel(label = "")`
267
306
 
307
+ ### `src/client/navigation/documentNavigation.js`
308
+ Exports
309
+ - `leaveApp(url)`
310
+ - `reloadAppPage(target)`
311
+
268
312
  ### `src/client/navigation/linkResolver.js`
269
313
  Exports
270
314
  - `resolveShellLinkPath({ context = null, surface = "", explicitTo = "", relativePath = "/", surfaceRelativePath = "", params = {}, strictParams = true } = {})`
@@ -273,6 +317,18 @@ Local functions
273
317
  - `materializeSurfaceRouteBase(routeBaseTemplate = "/", { params = {}, strictParams = true, surface = "" } = {})`
274
318
  - `resolveSurfaceBasePath(context = null, surface = "", { params = {}, strictParams = true } = {})`
275
319
 
320
+ ### `src/client/navigation/shellNavigationRuntime.js`
321
+ Exports
322
+ - `PAGE_TITLE_ID`
323
+ - `SHELL_NAVIGATION_RUNTIME_KEY`
324
+ - `TRAIL_STATE_KEY`
325
+ - `createShellNavigationRuntime({ router })`
326
+ - `resolvePageParent(matched)`
327
+ - `resolvePageTitle(matched)`
328
+ Local functions
329
+ - `normalizeTrail(value)`
330
+ - `cssAttributeValue(value)`
331
+
276
332
  ### `src/client/navigation/usePaths.js`
277
333
  Exports
278
334
  - `usePaths({ routeContext = useSurfaceRouteContext() } = {})`
@@ -282,6 +338,15 @@ Local functions
282
338
  - `resolveDefaultSurfaceIdFromPlacementContext(placementContext = null)`
283
339
  - `resolveRouteParams(baseParams = {}, overrideParams = null)`
284
340
 
341
+ ### `src/client/navigation/useShellNavigation.js`
342
+ Exports
343
+ - `NO_SHELL_NAVIGATION_RUNTIME`
344
+ - `useShellNavigation()`
345
+ - `useShellNavigationRuntime()`
346
+ Local functions
347
+ - `resolvedNothing()`
348
+ - `releaseNothing()`
349
+
285
350
  ### `src/client/navigation/useSurfaceRouteContext.js`
286
351
  Exports
287
352
  - `useSurfaceRouteContext()`
@@ -459,14 +524,15 @@ Exports
459
524
  Exports
460
525
  - `DESKTOP_DRAWER_CLOSED_MODES`
461
526
  - `normalizeDesktopDrawerClosedMode(value = "rail")`
462
- - `resolveShellDrawerPresentation({ compact = false, open = false, desktopClosedMode = "rail" } = {})`
463
- - `resolveShellDrawerToggleLabel({ compact = false, open = false } = {})`
527
+ - `resolveShellDrawerPresentation({ modal = false, open = false, desktopClosedMode = "rail" } = {})`
528
+ - `resolveShellDrawerToggleLabel({ modal = false, open = false } = {})`
464
529
 
465
530
  ### `src/client/support/drawerWidth.js`
466
531
  Exports
467
532
  - `DEFAULT_SHELL_DRAWER_WIDTH`
468
533
  - `DEFAULT_SHELL_NAVIGATION_ITEM_SPACING`
469
534
  - `DEFAULT_SHELL_RAIL_WIDTH`
535
+ - `MATERIAL_DRAWER_WIDTH`
470
536
  - `MAXIMUM_SHELL_DRAWER_WIDTH`
471
537
  - `MINIMUM_SHELL_DRAWER_WIDTH`
472
538
  - `measureDrawerContentWidth(drawerElement, navigationItemSpacing)`
@@ -474,6 +540,7 @@ Exports
474
540
  - `normalizeShellNavigationItemSpacing(value, fallback = DEFAULT_SHELL_NAVIGATION_ITEM_SPACING)`
475
541
  - `normalizeShellRailWidth(value, fallback = DEFAULT_SHELL_RAIL_WIDTH)`
476
542
  - `resolveContentAwareDrawerWidth(measurements = [], { endGap = DEFAULT_SHELL_NAVIGATION_ITEM_SPACING, minimum = MINIMUM_SHELL_DRAWER_WIDTH, maximum = MAXIMUM_SHELL_DRAWER_WIDTH, fallback = DEFAULT_SHELL_DRAWER_WIDTH } = {})`
543
+ - `resolveMaterialDrawerWidth({ modal = false, viewportWidth = Number.POSITIVE_INFINITY } = {})`
477
544
  Local functions
478
545
  - `clampNumber(value, minimum, maximum)`
479
546
  - `measureRenderedText(element)`
@@ -498,6 +565,17 @@ Local functions
498
565
  Exports
499
566
  - `activateShellNavigationLinkOnSpace(event)`
500
567
 
568
+ ### `src/client/support/navigationPresentation.js`
569
+ Exports
570
+ - `NO_SHELL_NAVIGATION_PRESENTATION`
571
+ - `NO_SHELL_PAGE_ACTIONS_TARGET`
572
+ - `NO_VUETIFY_ICONS`
573
+ - `SHELL_NAVIGATION_PRESENTATION_KEY`
574
+ - `SHELL_PAGE_ACTIONS_ID`
575
+ - `SHELL_PAGE_ACTIONS_TARGET_KEY`
576
+ - `VUETIFY_ICONS_KEY`
577
+ - `filledIconAlias(icon, aliases)`
578
+
501
579
  ### `src/client/support/primaryNavigation.js`
502
580
  Exports
503
581
  - `normalizeComparablePathname(value = "")`
@@ -523,7 +601,15 @@ Exports
523
601
 
524
602
  ### `src/client/support/shellLayoutClass.js`
525
603
  Exports
526
- - `resolveShellLayoutClass(displayName = "", viewportWidth = pageViewportWidth())`
604
+ - `resolveShellLayoutClass(viewportWidth = pageViewportWidth())`
605
+
606
+ ### `src/client/support/windowSizeClass.js`
607
+ Exports
608
+ - `EXPANDED_MIN_WIDTH`
609
+ - `LARGE_MIN_WIDTH`
610
+ - `MEDIUM_MIN_WIDTH`
611
+ - `WINDOW_SIZE_CLASSES`
612
+ - `resolveWindowSizeClass(width)`
527
613
 
528
614
  ### `src/client/types.js`
529
615
  Exports
@@ -552,11 +638,33 @@ Exports
552
638
  Local functions
553
639
  - `createSurfacePlacement(surface, order, label, suffix)`
554
640
  - `createSurfacePlacements(surface)`
641
+ - `refuseBlockedRecord(to)`
642
+
643
+ ### `fixtures/adaptive-shell/src/RecordListPage.vue`
644
+ Exports
645
+ - None
646
+
647
+ ### `fixtures/adaptive-shell/src/RecordPage.vue`
648
+ Exports
649
+ - None
650
+
651
+ ### `fixtures/adaptive-shell/src/records.js`
652
+ Exports
653
+ - `records`
555
654
 
556
655
  ### `fixtures/adaptive-shell/src/ScreenPage.vue`
557
656
  Exports
558
657
  - None
559
658
 
659
+ ### `fixtures/adaptive-shell/src/SettingsPage.vue`
660
+ Exports
661
+ - None
662
+
663
+ ### `fixtures/adaptive-shell/src/theme/index.js`
664
+ Exports
665
+ - `theme`
666
+ - `adminTheme`
667
+
560
668
  ### `fixtures/adaptive-shell/vite.config.mjs`
561
669
  Exports
562
670
  - None
@@ -575,6 +683,10 @@ Exports
575
683
  Exports
576
684
  - None
577
685
 
686
+ ### `patterns/application-shell/example/expected-existing/src/views/NotFound.vue`
687
+ Exports
688
+ - None
689
+
578
690
  ### `patterns/application-shell/example/src/App.vue`
579
691
  Exports
580
692
  - None
@@ -615,10 +727,6 @@ Exports
615
727
  Exports
616
728
  - None
617
729
 
618
- ### `patterns/application-shell/example/src/pages/home/settings/index.vue`
619
- Exports
620
- - None
621
-
622
730
  ### `patterns/application-shell/example/src/placement.js`
623
731
  Exports
624
732
  - `addPlacement`
@@ -629,6 +737,10 @@ Exports
629
737
  - `addPlacementTopology(value = {})`
630
738
  - `default`
631
739
 
740
+ ### `patterns/application-shell/example/src/views/NotFound.vue`
741
+ Exports
742
+ - None
743
+
632
744
  ### `patterns/page-and-placement/example/packages/main/src/client/providers/MainClientProvider.js`
633
745
  Exports
634
746
  - `MainClientProvider`
@@ -67,9 +67,90 @@ Exports
67
67
  - `usage()`
68
68
  Local functions
69
69
  - `parseI18nArgs(options, positionals)`
70
+ - `parseMaterial3Args(options, positionals)`
71
+ - `runMaterial3({ projectRoot, paths })`
70
72
  - `runI18n({ subcommand, locale, projectRoot })`
71
73
  - `readCatalog()`
72
74
 
75
+ ### `scripts/material3-source.mjs`
76
+ Exports
77
+ - `HEX_COLOUR`
78
+ - `blankCssComments(source)`
79
+ - `blankHtmlComments(source)`
80
+ - `blankJsComments(source)`
81
+ - `kebab(name)`
82
+ - `lineIndex(text)`
83
+ - `readDeclarations(css, offset)`
84
+ - `readExceptions(source)`
85
+ - `readInlineDeclarations(text, offset)`
86
+ - `readTags(template)`
87
+ - `splitVue(source)`
88
+ Local functions
89
+ - `blank(text)`
90
+ - `blankMatches(source, pattern)`
91
+ - `findBlocks(source, tag)`
92
+ - `readAttributes(text, offset)`
93
+
94
+ ### `scripts/material3.mjs`
95
+ Exports
96
+ - `MATERIAL3_RULES`
97
+ - `checkMaterial3({ projectRoot = process.cwd(), paths = [], navigationOnly = false } = {})`
98
+ - `formatMaterial3Report(result)`
99
+ - `formatNavigationReport(result)`
100
+ Local functions
101
+ - `hexPattern()`
102
+ - `quotedHex()`
103
+ - `isNavigationRule(rule)`
104
+ - `isSkippedDirectory(name)`
105
+ - `isSourceFile(relativePath)`
106
+ - `walk(projectRoot, directory, files)`
107
+ - `collectFiles(projectRoot, paths)`
108
+ - `createReporter(file, source, { navigationOnly = false } = {})`
109
+ - `checkCode(code, offset, { report, themed })`
110
+ - `checkScript(code, offset, context)`
111
+ - `checkCss(css, offset, context)`
112
+ - `checkDeclaration(declaration, context)`
113
+ - `attribute(tag, name)`
114
+ - `checkTemplate(template, context)`
115
+ - `checkAttribute(tag, entry, context)`
116
+ - `checkSurface(tag, report)`
117
+ - `checkButtonSize(tag, report)`
118
+ - `checkFile(file, source, context)`
119
+ - `readProjectManifest(projectRoot)`
120
+ - `usesShell(manifest)`
121
+ - `checkDarkScheme(projectRoot, checkedFiles, wholeApp)`
122
+ - `formatFindings(result)`
123
+
124
+ ### `scripts/navigation.mjs`
125
+ Exports
126
+ - `NAVIGATION_RULES`
127
+ - `checkBackControl(tag, report)`
128
+ - `checkLinkAttribute(tag, entry, report)`
129
+ - `checkNavigationCode(code, offset, report)`
130
+ - `checkPageParents({ root, appFiles, pageFiles, report })`
131
+ - `checkScriptBackNames(code, offset, report)`
132
+ - `isInAppPath(value)`
133
+ - `isPageFile(file)`
134
+ Local functions
135
+ - `compact(text)`
136
+ - `isPlacementLink(code, offset)`
137
+ - `attribute(tag, name)`
138
+ - `visibleText(inner)`
139
+ - `isBackTag(tag)`
140
+ - `looksLikeBack(tag)`
141
+ - `balancedFrom(text, start, open = "{", close = "}")`
142
+ - `enclosingObject(text, offset)`
143
+ - `stringValue(text, key)`
144
+ - `readMainNavigation(sources)`
145
+ - `normalisePath(value)`
146
+ - `routeOf(file)`
147
+ - `routePattern(route)`
148
+ - `readSurfaces(configSource, pageRoutes)`
149
+ - `surfaceOf(route, surfaces)`
150
+ - `routeDeclarations(source)`
151
+ - `readPage(file, source)`
152
+ - `pageKey(file)`
153
+
73
154
  ### `scripts/pattern-assets.mjs`
74
155
  Exports
75
156
  - `PATTERN_DOCUMENT_NAME`
@@ -27,3 +27,10 @@ Exports
27
27
  - `createFakeFastifyPolicyRuntime({ csrfHandler = passCsrfProtection } = {})`
28
28
  Local functions
29
29
  - `passCsrfProtection(_request, _reply, done)`
30
+
31
+ ### `visualBaseline.mjs`
32
+ Exports
33
+ - `expectMaterialBaseline(page, { directory, name, probes })`
34
+ - `readMaterialStyles(page, probes)`
35
+ Local functions
36
+ - `comparePixels(page, actual, expected)`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: jskit
3
- description: Build, extend, troubleshoot, review, deslop, and verify JSKIT apps using its public framework APIs, package-owned source patterns, runtime capabilities, surfaces, placements, CRUDs, verification conventions, and Vue/Vuetify Material 3 UI contract. Use for every JSKIT UI creation, modification, review, or cleanup task.
3
+ description: Build, extend, troubleshoot, review, deslop, and verify JSKIT apps using its public framework APIs, package-owned source patterns, runtime capabilities, surfaces, placements, CRUDs, verification conventions, and Vue/Vuetify Material 3 UI contract, including UI passes over a task's changes, a section, or the whole app. Use for every JSKIT UI creation, modification, review, cleanup, or UI pass task.
4
4
  ---
5
5
 
6
6
  # JSKIT
@@ -56,6 +56,8 @@ manifests, migrations, tests, and runtime behaviour are the evidence.
56
56
  [UI operations](references/ui-operations.md).
57
57
  - For every Vue/Vuetify UI creation, modification, review, or deslop task,
58
58
  also read [Material 3](references/material-3.md) completely before acting.
59
+ - For a UI pass (the changes, a section, or the whole app), also read
60
+ [UI pass](references/ui-pass.md) completely.
59
61
 
60
62
  These are complete operational references required by this skill. Do not load
61
63
  irrelevant references or other docs.
@@ -90,9 +92,11 @@ only when required. Use only a fresh disposable development database for
90
92
  schema work—never valuable data. For UI, respect surface/placements, compact
91
93
  layout, all operational states, permissions/ownership, and browser
92
94
  verification.
93
- Check every page for meaningful Back navigation: previous page by default,
94
- with justified omissions or explicitly named fixed destinations. UI operations
95
- has navigation seams, placement and direct-entry fallback.
95
+ Navigation is a MUST that plain `jskit check` enforces (Material 3,
96
+ Navigation and Up): the shell owns the Up arrow and the trail; every inner page
97
+ declares its parent as route meta `jskit.parent`; every inner link goes through
98
+ JSKIT navigation; never write back logic, a "Back to X" control,
99
+ `router.back()`, `history.back()` or `window.location` navigation.
96
100
 
97
101
  ## Caller-owned verification
98
102
 
@@ -107,8 +111,9 @@ For review-only work, report without editing. Check dead or duplicated code,
107
111
  accidental abstraction, incomplete states, missed high-level JSKIT seams,
108
112
  invalid ownership or migration choices, UI quality, and verification. Server
109
113
  code follows typed features, client code client features; `npm run lint` is
110
- clean. Run the Material 3 audit for affected UI, Back included; a hardcoded
111
- parent link is not previous-page navigation. Findings first by severity and file.
114
+ clean. Run the Material 3 audit for affected UI, navigation first, plain
115
+ `jskit check`, and `jskit check m3` on the affected files. Findings first by
116
+ severity and file.
112
117
 
113
118
  ## Verify
114
119
 
@@ -116,3 +121,9 @@ Run focused tests for a slice and the application's `npm run verify` for a
116
121
  whole changeset. Use the current-state owners in application operations and
117
122
  Playwright for affected UI. There is no current JSKIT Doctor command; ignore
118
123
  old CLI authoring-history diagnoses. Never expose environment values.
124
+
125
+ Tests and requests take the time their work needs, no more: a list reads each
126
+ table once, a row policy is bounded by the rows it reads, list and batch paths
127
+ have a query budget tested at realistic row counts, and test databases restore
128
+ a stored snapshot instead of replaying migrations. Find why a check is slow;
129
+ never raise its time limit. Typed features' repository and Tests rules say how.
@@ -34,7 +34,7 @@ How to use it:
34
34
  - [client-requests.md](./client-requests.md)
35
35
  - playwright, browser test, e2e, ui verification, baseline test, authenticated ui test, test auth, dev login as, dev auth bypass
36
36
  - [ui-testing.md](./ui-testing.md)
37
- - UI contract, design contract, navigation roles, Back button, previous page, history, hardcoded destination, Deslop, density, placeholder copy, card shells, shared CRUD screens, row actions, synthetic rows, detail slots
37
+ - UI contract, design contract, navigation roles, Up arrow, Back button, declared parent, jskit.parent, in-app trail, history.back, hand-built links, jskit check, Deslop, density, placeholder copy, card shells, shared CRUD screens, row actions, synthetic rows, detail slots
38
38
  - [ui-contract.md](./ui-contract.md)
39
39
  - filter, filters, search facets, chips, date range, enum filter, lookup filter, `useCrudListFilters`, `createCrudListFilters`
40
40
  - [filters.md](./filters.md)
@@ -42,9 +42,9 @@ How to use it:
42
42
  - [server-search.md](./server-search.md)
43
43
  - `actualField`, `storage.writeSerializer`, `storage.virtual`, computed field, virtual field, projection, `createCrudResourceRuntime`, datetime write serialization, temporalPrecision, json-rest-schema dates
44
44
  - [crud-repository-mapping.md](./crud-repository-mapping.md)
45
- - row policy, permission filtering, visibility before pagination, recursive CTE, descendants, package cycle, `RowPolicyPlugin`
45
+ - row policy, permission filtering, visibility before pagination, recursive CTE, descendants, package cycle, `RowPolicyPlugin`, row policy cost, slow writes through a policy, access check per history item
46
46
  - [row-policies.md](./row-policies.md)
47
- - typed features, server feature, provider, service, repository, collaborator, `typeof`, `= null`, `setProvider`, `register`, `input || {}`, `payload = {}`, `async execute`, `Object.freeze`, `requires`, `optional`, `types.js`, `RuntimeKnex`, `silentLogger`, `create<Name>Actions`, `ActionSpecifications`, request context, `api.resources.x.query`, every row, list stops at 20 rows, `queryAllJsonRestCollectionRows`, `jskit/*` lint findings, `readable-check: allow`, `optional operation:`, `process.env`, `AppError` code, `Object.assign(new Error`, `idempotency`, `…ForTests` export, file or function size
47
+ - typed features, server feature, provider, service, repository, collaborator, `typeof`, `= null`, `setProvider`, `register`, `input || {}`, `payload = {}`, `async execute`, `Object.freeze`, `requires`, `optional`, `types.js`, `RuntimeKnex`, `silentLogger`, `create<Name>Actions`, `ActionSpecifications`, request context, `api.resources.x.query`, every row, list stops at 20 rows, `queryAllJsonRestCollectionRows`, `jskit/*` lint findings, `readable-check: allow`, `optional operation:`, `process.env`, `AppError` code, `Object.assign(new Error`, `idempotency`, `…ForTests` export, file or function size, read per row, N+1 queries, slow endpoint, query budget, realistic row counts, slow tests, raised timeout, `migrate.latest()` in tests, test database snapshot
48
48
  - [typed-features.md](./typed-features.md)
49
49
  - client features, composable, `use<Name>`, Vue component, client provider, props, emits, `inject`, `provide`, `ref`, `reactive`, `watch`, `addEventListener`, `setInterval`, module state, `Object.freeze` on a composable, `?.()` in a template, `jskit/typed-inject`, `jskit/collaborator-props`, `jskit/fixed-result-shape`, `jskit/released-listeners`, `jskit/no-module-state`, `jskit/no-frozen-vue-state`, `clientFeaturesConfig`, `shared resource:`
50
50
  - [client-features.md](./client-features.md)
@@ -8,6 +8,7 @@ Use when:
8
8
  - filtering after pagination produces empty or incomplete pages
9
9
  - another package grants access to a resource but a reverse dependency would create a cycle
10
10
  - the user mentions `RowPolicyPlugin`, recursive CTEs, descendants, or permission-filtered counts
11
+ - reads or writes of a resource with a policy get slower as records or a person's history grow
11
12
 
12
13
  Read first:
13
14
 
@@ -36,6 +37,13 @@ Package composition:
36
37
  - the owner seals the contributions and builds the policy during `boot()`
37
38
  - do not use module-global mutable registries
38
39
 
40
+ Cost:
41
+
42
+ - a policy's cost follows the rows its query reads: add a join, `EXISTS` or subquery correlated with the row through `column()` and `value()`, on indexed columns
43
+ - never load the subject's whole history (every source, notice or grant they were ever linked to) to build an `IN` list, and never call another owner's access check per item of it; another package's grant is a predicate contribution
44
+ - the policy runs on every single-record read, including the read-back after `createDocument()` and `patchDocumentById()` (`returning: "full"`) and the lookup before `patch` and `delete`, so a write pays it once per row it writes
45
+ - a write decides access once, inside its transaction; a batch write that would pay an expensive read-back per row follows the typed features guide's [Bounded access checks](../typed-features.md#bounded-access-checks)
46
+
39
47
  Child-resource rules:
40
48
 
41
49
  - a self-referencing relationship targets the same resource and receives the same row policy
@@ -50,6 +58,7 @@ Testing:
50
58
  - assert hidden direct records behave as not found
51
59
  - assert children and includes do not leak records
52
60
  - assert package and provider dependencies stay one-way
61
+ - run one read and one write for a subject with a short history and with a realistic long one (hundreds of linked rows), and assert the same query count
53
62
 
54
63
  AnyAPI boundary:
55
64
 
@@ -65,3 +74,4 @@ Avoid:
65
74
  - adding a default policy file to every CRUD
66
75
  - returning a Knex builder or promise from a synchronous grouped contribution
67
76
  - swallowing a policy error and retrying without mandatory visibility
77
+ - a policy that reads the subject's history or calls an access check per history item
@@ -65,6 +65,10 @@ ends with the same link.
65
65
  - [One reader per fact](../typed-features.md#one-reader-per-fact)
66
66
  - `api.resources.x.query(…)` with no `page` for a list, `queryDocuments(query)` with no `limit` in a service, a list that stops at 20 rows
67
67
  - [Every row](../typed-features.md#every-row)
68
+ - `await getDocumentById(…)`, `queryDocuments(…)` or a service `get` inside a loop or a `Promise.all` over a list, a single-record helper reused for a list, N+1 queries, a slow list endpoint
69
+ - [One read per table](../typed-features.md#one-read-per-table)
70
+ - a `rowPolicy` that loads a person's whole history or calls an access check per item, `createDocument` per row of a batch, a write that gets slower as history grows
71
+ - [Bounded access checks](../typed-features.md#bounded-access-checks)
68
72
  - a route that queries storage, `boot*.js` holding routes
69
73
  - [Routes](../typed-features.md#routes)
70
74
  - `new AppError(status, message)` with no code, `new NotFoundError("…")`, one code for two sentences (`jskit/app-error-code`)
@@ -81,6 +85,12 @@ ends with the same link.
81
85
  - [Tests are not callers](../typed-features.md#tests-are-not-callers)
82
86
  - `…ForTests`, `__reset…`, `testOnly…` exports (`jskit/no-test-only-export`)
83
87
  - [No test-only exports](../typed-features.md#no-test-only-exports)
88
+ - a list, batch or write test with one to three rows, no query count, a slow endpoint first seen with real data
89
+ - [Budgets at realistic counts](../typed-features.md#budgets-at-realistic-counts)
90
+ - a raised `{ timeout }`, `test.setTimeout()`, `--test-timeout` or Playwright `timeout`, retries or a request loop that absorbs slowness, a slow suite
91
+ - [Time limits are not fixes](../typed-features.md#time-limits-are-not-fixes)
92
+ - `knex.migrate.latest()` in each test file, a template database rebuilt by migrating, test preparation slower than its tests
93
+ - [Test databases are prepared once](../typed-features.md#test-databases-are-prepared-once)
84
94
  - a file over 750 lines, a function over 600 (`max-lines`, `max-lines-per-function`), a data module
85
95
  - [Size limits](../typed-features.md#size-limits), [Data modules](../typed-features.md#data-modules)
86
96
  - two properties on one line in `Object.freeze({ … })` or a token map (`jskit/one-property-per-line`)
@@ -100,3 +110,5 @@ Avoid:
100
110
  - module-level registries
101
111
  - refusals without their own code
102
112
  - excusing a finding without a reason in its `readable-check: allow` comment
113
+ - a read per row of a list, or an access check sized by stored history
114
+ - raising a time limit instead of finding why a check is slow
@@ -13,11 +13,13 @@ and action UI.
13
13
  overflow.
14
14
  - Compact interactive targets are at least 48 CSS pixels.
15
15
  - Navigation uses semantic placements and explicit navigation roles.
16
- - Check every page for Back to the previous page unless returning makes no
17
- product sense. Use the existing navigation owner; fixed destinations are
18
- deliberate, explicitly labelled exceptions. Follow the
19
- [Back navigation contract](../ui-operations.md#back-navigation)
20
- for history, direct-entry fallback, retained context, and consistent placement.
16
+ - MUST, enforced by plain `jskit check`: every inner page declares its parent
17
+ (route meta `jskit.parent`) and gets one Up arrow in the top app bar from the
18
+ shell; it returns to the in-app origin, or to the parent on direct entry.
19
+ Main-menu destinations show none. No "Back to X" controls, no back logic, no
20
+ `router.back()`/`history.back()`/`window.location`, no hand-built in-app
21
+ links. Follow
22
+ [Navigation and Up](../material-3.md#navigation-and-up).
21
23
  - Pages do not stack decorative cards inside structural cards.
22
24
  - Pages do not include a header, title block, welcome heading, or standalone
23
25
  heading copy unless the user explicitly requests one.
@@ -57,8 +59,9 @@ it as a closed sheet and wider layouts as a closed side panel.
57
59
 
58
60
  - test skeleton, empty, loaded, local error, retry, and mutation feedback states
59
61
  - navigate away and back with warm query cache, including browser back/forward
60
- - during review or Deslop, audit Back's presence or justified omission, leading
61
- position, label, and actual destination; verify two origins and direct entry
62
+ - during review, Deslop or a UI pass, audit Up: a sideways origin returns
63
+ there, chains unwind, direct entry reaches the declared parent, and main-menu
64
+ destinations show no arrow
62
65
  - exercise compact, medium, and expanded viewports
63
66
  - verify accessible names, keyboard operation, target size, and no overflow
64
67
  - assert that no spinner or layout-shifting transient error banner appears
@@ -22,9 +22,11 @@ Rules:
22
22
  - Use relative paths such as `page.goto("/home")`. The shared config owns the browser base URL.
23
23
  - After clicking a client-side navigation control, wait for its destination
24
24
  with `await expect(page).toHaveURL(...)` before reloading. Awaiting the click
25
- alone does not wait for Vue Router to complete. Contextual Back tests must
26
- reach the form before reload, then assert the original list URL; direct entry
27
- checks the configured fallback separately. Do not replace this wait with sleeps.
25
+ alone does not wait for Vue Router to complete. Up tests reach a page
26
+ through in-app links (one of them sideways), then press
27
+ `pressShellBack(page)` (`@jskit-ai/shell-web/test/shellNavigation`) and
28
+ assert that each Up returns to its origin in order; a direct `page.goto()`
29
+ asserts the declared parent. Do not replace this wait with sleeps.
28
30
  - A managed runner supplies `PLAYWRIGHT_BASE_URL`. When it is set, JSKIT does not start another app server.
29
31
  - Otherwise the config starts the app on `PLAYWRIGHT_PORT`, 4173 by default. A runner that shares a machine between runs sets a free port for each run; with one fixed port, a second run would wait for it or reuse another run's server.
30
32
  - A managed runner may supply an authenticated context through `PLAYWRIGHT_STORAGE_STATE`. Treat that file as a temporary secret: do not commit it, print it, or retain it after the run.
@@ -63,11 +65,15 @@ in the regression: one test's teardown must not erase another test's migrations.
63
65
 
64
66
  Do not drop/recreate the database, replay completed migrations, build every
65
67
  module fixture, or run a production frontend build for each focused check.
66
- Choose small fixture sets for the selected suite. Fresh-schema migration tests
67
- and production-artifact tests are separate operations. Measure migration,
68
- fixture, and server startup time before retrying a slow launch or raising its
69
- deadline. When a host supplies a managed target, use its scoped suite command so
70
- one startup serves the whole batch and cleanup restores normal Preview.
68
+ Choose small fixture sets for the selected suite; realistic row counts belong
69
+ in the database tests that hold each endpoint's query budget. Fresh-schema
70
+ migration tests and production-artifact tests are separate operations. Measure
71
+ migration, fixture, and server startup time and fix the slow phase; never retry
72
+ a slow launch, or raise its deadline or a spec's timeout, to absorb it. A page
73
+ that needs a longer timeout to load is a slow endpoint to fix (typed features'
74
+ Time limits are not fixes). When a host supplies a managed target, use its
75
+ scoped suite command so one startup serves the whole batch and cleanup
76
+ restores normal Preview.
71
77
 
72
78
  ## Keep browser evidence focused
73
79