@jskit-ai/agent-docs 0.1.150 → 0.1.152

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 (81) hide show
  1. package/guide/agent/app-extras/realtime.md +33 -1
  2. package/guide/agent/framework/material-3.md +3 -2
  3. package/guide/agent/framework/ui-operations.md +2 -1
  4. package/package.json +1 -1
  5. package/patterns/feature-package/example/booking-engine/package.json +1 -1
  6. package/patterns/minimal-foundation/PATTERN.md +2 -0
  7. package/patterns/minimal-foundation/example/AGENTS.md +4 -0
  8. package/patterns/minimal-foundation/example/Procfile +0 -1
  9. package/patterns/minimal-foundation/example/package.json +4 -4
  10. package/patterns/minimal-foundation/example/src/pages/home/index.vue +0 -27
  11. package/patterns/minimal-foundation/example/tests/e2e/base-shell.spec.ts +1 -1
  12. package/patterns/page-scaffolding.md +5 -3
  13. package/patterns/shell-foundation/PATTERN.md +2 -0
  14. package/patterns/shell-foundation/example/AGENTS.md +4 -0
  15. package/patterns/shell-foundation/example/Procfile +0 -1
  16. package/patterns/shell-foundation/example/package.json +5 -5
  17. package/patterns/shell-foundation/example/packages/main/package.json +1 -1
  18. package/patterns/shell-foundation/example/src/pages/home/index.vue +5 -31
  19. package/patterns/shell-foundation/example/src/pages/home/settings/general/index.vue +3 -6
  20. package/patterns/shell-foundation/example/src/pages/home/settings.vue +0 -19
  21. package/patterns/shell-foundation/example/tests/e2e/base-shell.spec.ts +1 -1
  22. package/patterns/ui-contract.md +2 -0
  23. package/patterns/ui-testing.md +1 -1
  24. package/reference/autogen/PATTERN_INDEX.md +20 -20
  25. package/reference/autogen/packages/realtime.md +8 -3
  26. package/skills/jskit/references/material-3.md +3 -2
  27. package/skills/jskit/references/pattern-index.md +20 -20
  28. package/skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md +2 -0
  29. package/skills/jskit/references/patterns/app/minimal-foundation/example/AGENTS.md +4 -0
  30. package/skills/jskit/references/patterns/app/minimal-foundation/example/Procfile +0 -1
  31. package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +4 -4
  32. package/skills/jskit/references/patterns/app/minimal-foundation/example/src/pages/home/index.vue +0 -27
  33. package/skills/jskit/references/patterns/app/minimal-foundation/example/tests/e2e/base-shell.spec.ts +1 -1
  34. package/skills/jskit/references/patterns/app/shell-foundation/PATTERN.md +2 -0
  35. package/skills/jskit/references/patterns/app/shell-foundation/example/AGENTS.md +4 -0
  36. package/skills/jskit/references/patterns/app/shell-foundation/example/Procfile +0 -1
  37. package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +5 -5
  38. package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
  39. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home/index.vue +5 -31
  40. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home/settings/general/index.vue +3 -6
  41. package/skills/jskit/references/patterns/app/shell-foundation/example/src/pages/home/settings.vue +0 -19
  42. package/skills/jskit/references/patterns/app/shell-foundation/example/tests/e2e/base-shell.spec.ts +1 -1
  43. package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
  44. package/skills/jskit/references/patterns/console/console-surface/PATTERN.md +1 -0
  45. package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console/index.vue +5 -24
  46. package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console/settings/index.vue +0 -1
  47. package/skills/jskit/references/patterns/console/console-surface/example/src/pages/console/settings.vue +0 -14
  48. package/skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md +1 -0
  49. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookEditPage.vue +0 -2
  50. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookListPage.vue +0 -4
  51. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookNewPage.vue +0 -2
  52. package/skills/jskit/references/patterns/crud/crud-screen-set/example/books/BookViewPage.vue +0 -1
  53. package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +2 -2
  54. package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
  55. package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
  56. package/skills/jskit/references/patterns/realtime/realtime-application/PATTERN.md +17 -0
  57. package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
  58. package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +1 -1
  59. package/skills/jskit/references/patterns/shell/application-shell/PATTERN.md +1 -0
  60. package/skills/jskit/references/patterns/shell/application-shell/example/expected-existing/src/pages/home/index.vue +0 -27
  61. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home/index.vue +5 -31
  62. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home/settings/general/index.vue +3 -6
  63. package/skills/jskit/references/patterns/shell/application-shell/example/src/pages/home/settings.vue +0 -19
  64. package/skills/jskit/references/patterns/ui/page-and-placement/PATTERN.md +1 -0
  65. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports/activity.vue +1 -2
  66. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports/overview.vue +1 -2
  67. package/skills/jskit/references/patterns/ui/page-and-placement/example/src/pages/home/reports.vue +0 -8
  68. package/skills/jskit/references/patterns/users/account-settings/PATTERN.md +2 -0
  69. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsNotificationsSection.vue +0 -14
  70. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsPreferencesSection.vue +0 -14
  71. package/skills/jskit/references/patterns/users/account-settings/example/src/components/account/settings/AccountSettingsProfileSection.vue +0 -14
  72. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +2 -2
  73. package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +3 -3
  74. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/PATTERN.md +2 -0
  75. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/components/WorkspaceNotFoundCard.vue +3 -14
  76. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/pages/admin/workspace/settings/index.vue +0 -8
  77. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/pages/admin/workspace/settings.vue +0 -14
  78. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/admin/index.vue +4 -31
  79. package/skills/jskit/references/patterns/workspaces/workspace-surfaces/example/src/surfaces/app/index.vue +0 -15
  80. package/skills/jskit/references/ui-operations.md +2 -1
  81. package/templates/app/AGENTS.md +4 -0
@@ -12,8 +12,6 @@ const routeRecordId = computed(() => String(route.params.bookId || "").trim());
12
12
 
13
13
  const screen = useCrudAddEditScreen({
14
14
  mode: "edit",
15
- title: "Edit book",
16
- subtitle: "Update this catalogue entry.",
17
15
  saveLabel: "Save changes",
18
16
  cancelTo: "/books/:bookId",
19
17
  preserveCancelQuery: true,
@@ -25,11 +25,7 @@ const screen = useCrudListScreen({
25
25
  <template>
26
26
  <CrudListScreen
27
27
  :screen="screen"
28
- title-label="Books"
29
- heading-title="My books"
30
- subtitle="Search and maintain your catalogue."
31
28
  create-label="Add book"
32
- empty-title="No books yet"
33
29
  empty-body="Add your first book to begin the catalogue."
34
30
  >
35
31
  <template #card-fields="{ record, formatListCardValue }">
@@ -7,8 +7,6 @@ import { bookFormFields } from "./formFields.js";
7
7
 
8
8
  const screen = useCrudAddEditScreen({
9
9
  mode: "new",
10
- title: "Add book",
11
- subtitle: "Add a book to your catalogue.",
12
10
  saveLabel: "Save book",
13
11
  cancelTo: "/books",
14
12
  resource: bookResource,
@@ -30,7 +30,6 @@ const deleteAction = useCrudDeleteAction({
30
30
  :screen="screen"
31
31
  resource-singular-title="Book"
32
32
  resource-plural-title="Books"
33
- description="Review this catalogue entry."
34
33
  >
35
34
  <template #actions>
36
35
  <CrudDeleteAction :action="deleteAction" resource-singular-title="Book" />
@@ -8,8 +8,8 @@
8
8
  "./shared": "./src/shared/index.js"
9
9
  },
10
10
  "dependencies": {
11
- "@jskit-ai/crud-core": "0.1.189",
12
- "@jskit-ai/resource-crud-core": "0.1.120"
11
+ "@jskit-ai/crud-core": "0.1.191",
12
+ "@jskit-ai/resource-crud-core": "0.1.122"
13
13
  },
14
14
  "jskit": {
15
15
  "kind": "runtime",
@@ -8,6 +8,6 @@
8
8
  "db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
9
9
  },
10
10
  "dependencies": {
11
- "@jskit-ai/database-runtime-mysql": "0.1.176"
11
+ "@jskit-ai/database-runtime-mysql": "0.1.178"
12
12
  }
13
13
  }
@@ -8,6 +8,6 @@
8
8
  "db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
9
9
  },
10
10
  "dependencies": {
11
- "@jskit-ai/database-runtime-postgres": "0.1.175"
11
+ "@jskit-ai/database-runtime-postgres": "0.1.177"
12
12
  }
13
13
  }
@@ -53,9 +53,26 @@ Omit the placement when the product does not need a visible connection state.
53
53
  Change event listeners, Redis provisioning, and client invalidation behavior to
54
54
  match the product. Keep transport retry policy in the realtime runtime.
55
55
 
56
+ When every realtime event belongs behind the application's authentication
57
+ boundary, let the selected `auth.service` opt in with
58
+ `realtime.requireAuthentication: true`. Socket.IO then rejects an
59
+ unauthenticated handshake before the client can join any broadcast room. A
60
+ browser whose login identity changes must disconnect and reconnect its socket
61
+ so the next handshake resolves the new actor.
62
+
63
+ Use `auth.service.realtime.authorizeEvent({ actor, event: { name, payload } })`
64
+ for resource-specific read authorization. Return `true` only when the current
65
+ actor can read that event's resource. Authentication is revalidated before
66
+ delivery and every 30 seconds while idle. Redis peers perform the same checks
67
+ locally. Realtime failures are logged without failing an already-successful
68
+ mutation; one mutation owner publishes each completion, while progress events
69
+ describe distinct lifecycle states.
70
+
56
71
  ## Verification
57
72
 
58
73
  - Test in-process delivery without Redis.
74
+ - When authenticated-client mode is selected, reject an anonymous handshake
75
+ and reconnect after login, logout, and identity changes.
59
76
  - When Redis is selected, test delivery across two server processes.
60
77
  - Disconnect and reconnect a browser and verify recovery behavior.
61
78
  - Confirm the status contribution renders in compact and expanded shells.
@@ -2,7 +2,7 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@jskit-ai/realtime": "0.1.175",
6
- "@jskit-ai/shell-web": "0.1.182"
5
+ "@jskit-ai/realtime": "0.1.177",
6
+ "@jskit-ai/shell-web": "0.1.184"
7
7
  }
8
8
  }
@@ -5,7 +5,7 @@
5
5
  "private": true,
6
6
  "type": "module",
7
7
  "dependencies": {
8
- "@jskit-ai/kernel": "0.1.178",
8
+ "@jskit-ai/kernel": "0.1.180",
9
9
  "json-rest-schema": "^1.0.17"
10
10
  },
11
11
  "exports": {
@@ -32,6 +32,7 @@ placement registry, topology, and adaptive smoke helper exported by
32
32
  ## Invariants
33
33
 
34
34
  - `App.vue`, the shell layout, placements, topology, and route pages agree.
35
+ - Route pages do not add a page header or standalone heading by default.
35
36
  - Navigation uses semantic placements rather than direct component injection.
36
37
  - Compact controls have accessible names and at least 48 CSS-pixel targets.
37
38
  - Cached route/resource state hydrates writable UI state synchronously or with
@@ -1,15 +1,6 @@
1
1
  <template>
2
2
  <section class="home-start-screen d-flex flex-column ga-4">
3
- <header>
4
- <p class="text-overline text-medium-emphasis mb-1">Home</p>
5
- <h1 class="home-start-screen__title">Home base</h1>
6
- <p class="text-body-2 text-medium-emphasis mb-0">
7
- The app runtime is online and ready for the first real workflow.
8
- </p>
9
- </header>
10
-
11
3
  <v-sheet rounded="lg" border class="home-start-screen__panel">
12
- <h2 class="text-h6 mb-2">No activity yet</h2>
13
4
  <p class="text-body-2 text-medium-emphasis mb-0">
14
5
  Recent work, saved records, and next actions will appear here once this app has data.
15
6
  </p>
@@ -19,30 +10,12 @@
19
10
 
20
11
  <style scoped>
21
12
  .home-start-screen {
22
- --home-start-title-size: 2rem;
23
13
  --home-start-panel-padding: 1rem;
24
- }
25
-
26
- .home-start-screen {
27
14
  margin-inline: auto;
28
15
  max-width: 48rem;
29
16
  }
30
17
 
31
- .home-start-screen__title {
32
- font-size: var(--home-start-title-size);
33
- font-weight: 700;
34
- letter-spacing: 0;
35
- line-height: 1.08;
36
- margin: 0 0 0.45rem;
37
- }
38
-
39
18
  .home-start-screen__panel {
40
19
  padding: var(--home-start-panel-padding);
41
20
  }
42
-
43
- @media (max-width: 640px) {
44
- .home-start-screen {
45
- --home-start-title-size: 1.5rem;
46
- }
47
- }
48
21
  </style>
@@ -29,16 +29,9 @@ const health = computed(() => {
29
29
 
30
30
  <template>
31
31
  <section class="home-surface-screen d-flex flex-column ga-4">
32
- <header class="home-surface-screen__header">
33
- <div>
34
- <p class="text-overline text-medium-emphasis mb-1">Home</p>
35
- <h1 class="home-surface-screen__title">Ready</h1>
36
- <p class="text-body-2 text-medium-emphasis mb-0">
37
- Core services are available.
38
- </p>
39
- </div>
32
+ <div class="home-surface-screen__actions">
40
33
  <v-btn color="primary" variant="flat" to="/home/settings/general">Settings</v-btn>
41
- </header>
34
+ </div>
42
35
 
43
36
  <v-sheet rounded="lg" border class="home-surface-screen__panel">
44
37
  <div class="home-surface-screen__status">
@@ -56,23 +49,12 @@ const health = computed(() => {
56
49
 
57
50
  <style scoped>
58
51
  .home-surface-screen {
59
- --home-surface-title-size: 2rem;
60
52
  --home-surface-panel-padding: 1rem;
61
53
  }
62
54
 
63
- .home-surface-screen__header {
64
- align-items: flex-start;
55
+ .home-surface-screen__actions {
65
56
  display: flex;
66
- gap: 1rem;
67
- justify-content: space-between;
68
- }
69
-
70
- .home-surface-screen__title {
71
- font-size: var(--home-surface-title-size);
72
- font-weight: 700;
73
- letter-spacing: 0;
74
- line-height: 1.1;
75
- margin: 0 0 0.4rem;
57
+ justify-content: flex-end;
76
58
  }
77
59
 
78
60
  .home-surface-screen__panel {
@@ -90,15 +72,7 @@ const health = computed(() => {
90
72
  }
91
73
 
92
74
  @media (max-width: 640px) {
93
- .home-surface-screen {
94
- --home-surface-title-size: 1.5rem;
95
- }
96
-
97
- .home-surface-screen__header {
98
- flex-direction: column;
99
- }
100
-
101
- .home-surface-screen__header :deep(.v-btn) {
75
+ .home-surface-screen__actions :deep(.v-btn) {
102
76
  min-height: 48px;
103
77
  width: 100%;
104
78
  }
@@ -16,12 +16,9 @@ const drawerDefaultOpenModel = computed({
16
16
 
17
17
  <template>
18
18
  <section class="settings-general-screen d-flex flex-column ga-4">
19
- <div>
20
- <h2 class="text-h6 mb-2">Navigation</h2>
21
- <p class="text-body-2 text-medium-emphasis mb-0">
22
- On wider screens, collapsed navigation remains available as a rail. Phone layouts close the drawer and keep primary navigation in the bottom bar.
23
- </p>
24
- </div>
19
+ <p class="text-body-2 text-medium-emphasis mb-0">
20
+ On wider screens, collapsed navigation remains available as a rail. Phone layouts close the drawer and keep primary navigation in the bottom bar.
21
+ </p>
25
22
 
26
23
  <v-switch
27
24
  v-model="drawerDefaultOpenModel"
@@ -5,12 +5,6 @@ import { RouterView } from "vue-router";
5
5
 
6
6
  <template>
7
7
  <section class="settings-shell d-flex flex-column ga-4">
8
- <header>
9
- <p class="text-overline text-medium-emphasis mb-1">Settings</p>
10
- <h1 class="settings-shell__title">Home settings</h1>
11
- <p class="text-body-2 text-medium-emphasis mb-0">Configure shell behavior for this surface.</p>
12
- </header>
13
-
14
8
  <v-sheet rounded="lg" border class="settings-shell__panel">
15
9
  <div class="settings-shell__body">
16
10
  <nav class="settings-shell__nav" aria-label="Home settings sections">
@@ -29,18 +23,9 @@ import { RouterView } from "vue-router";
29
23
 
30
24
  <style scoped>
31
25
  .settings-shell {
32
- --settings-shell-title-size: 1.85rem;
33
26
  --settings-shell-panel-padding: 1rem;
34
27
  }
35
28
 
36
- .settings-shell__title {
37
- font-size: var(--settings-shell-title-size);
38
- font-weight: 650;
39
- letter-spacing: 0;
40
- line-height: 1.15;
41
- margin: 0 0 0.35rem;
42
- }
43
-
44
29
  .settings-shell__panel {
45
30
  overflow: hidden;
46
31
  }
@@ -81,10 +66,6 @@ import { RouterView } from "vue-router";
81
66
  }
82
67
 
83
68
  @media (max-width: 960px) {
84
- .settings-shell {
85
- --settings-shell-title-size: 1.35rem;
86
- }
87
-
88
69
  .settings-shell__body {
89
70
  grid-template-columns: 1fr;
90
71
  }
@@ -30,6 +30,7 @@ a filename alone.
30
30
  ## Invariants
31
31
 
32
32
  - File routes and placement destinations agree.
33
+ - Route pages do not add a page header or standalone heading by default.
33
34
  - Placement ids describe product ownership, not the authoring mechanism.
34
35
  - Child links share an explicit section owner.
35
36
  - Topology maps each semantic placement to concrete responsive outlets.
@@ -1,6 +1,5 @@
1
1
  <template>
2
- <section aria-labelledby="reports-activity-title">
3
- <h2 id="reports-activity-title" class="text-h5 mb-2">Activity</h2>
2
+ <section>
4
3
  <p class="text-body-1 text-medium-emphasis mb-0">
5
4
  Recent catalogue changes appear here.
6
5
  </p>
@@ -1,6 +1,5 @@
1
1
  <template>
2
- <section aria-labelledby="reports-overview-title">
3
- <h2 id="reports-overview-title" class="text-h5 mb-2">Overview</h2>
2
+ <section>
4
3
  <p class="text-body-1 text-medium-emphasis mb-0">
5
4
  Your reading and catalogue summary appears here.
6
5
  </p>
@@ -5,14 +5,6 @@ import { RouterView } from "vue-router";
5
5
 
6
6
  <template>
7
7
  <section class="reports-section d-flex flex-column ga-4">
8
- <header>
9
- <p class="text-overline text-medium-emphasis mb-1">Insights</p>
10
- <h1 class="text-h4 font-weight-medium mb-1">Reports</h1>
11
- <p class="text-body-2 text-medium-emphasis mb-0">
12
- Review catalogue activity and completion trends.
13
- </p>
14
- </header>
15
-
16
8
  <nav aria-label="Report sections">
17
9
  <v-tabs density="comfortable">
18
10
  <ShellOutlet target="reports:section-nav" />
@@ -31,6 +31,8 @@ ordinary `useCommand()` mutation behavior, and JSKIT shell placements.
31
31
  ## Invariants
32
32
 
33
33
  - Sections use JSKIT account settings APIs rather than direct HTTP helpers.
34
+ - Settings pages and sections do not add headers or standalone headings by
35
+ default.
34
36
  - Cached resource data hydrates local writable fields immediately.
35
37
  - Mutation errors use the standard toast and do not push the form down.
36
38
  - Loading uses layout-stable skeletons, never an indeterminate spinner.
@@ -11,9 +11,6 @@ const notifications = props.runtime.notifications;
11
11
 
12
12
  <template>
13
13
  <v-sheet rounded="lg" border class="account-settings-section">
14
- <header class="account-settings-section__header">
15
- <h2 class="account-settings-section__title">Notifications</h2>
16
- </header>
17
14
  <div class="account-settings-section__body">
18
15
  <v-form @submit.prevent="notifications.submit" novalidate>
19
16
  <v-switch
@@ -58,17 +55,6 @@ const notifications = props.runtime.notifications;
58
55
  overflow: hidden;
59
56
  }
60
57
 
61
- .account-settings-section__header {
62
- padding: 1rem 1rem 0;
63
- }
64
-
65
- .account-settings-section__title {
66
- font-size: 1rem;
67
- font-weight: 650;
68
- line-height: 1.2;
69
- margin: 0;
70
- }
71
-
72
58
  .account-settings-section__body {
73
59
  padding: 1rem;
74
60
  }
@@ -11,9 +11,6 @@ const preferences = props.runtime.preferences;
11
11
 
12
12
  <template>
13
13
  <v-sheet rounded="lg" border class="account-settings-section">
14
- <header class="account-settings-section__header">
15
- <h2 class="account-settings-section__title">Preferences</h2>
16
- </header>
17
14
  <div class="account-settings-section__body">
18
15
  <v-form @submit.prevent="preferences.submit" novalidate>
19
16
  <v-row>
@@ -128,17 +125,6 @@ const preferences = props.runtime.preferences;
128
125
  overflow: hidden;
129
126
  }
130
127
 
131
- .account-settings-section__header {
132
- padding: 1rem 1rem 0;
133
- }
134
-
135
- .account-settings-section__title {
136
- font-size: 1rem;
137
- font-weight: 650;
138
- line-height: 1.2;
139
- margin: 0;
140
- }
141
-
142
128
  .account-settings-section__body {
143
129
  padding: 1rem;
144
130
  }
@@ -11,9 +11,6 @@ const profile = props.runtime.profile;
11
11
 
12
12
  <template>
13
13
  <v-sheet rounded="lg" border class="account-settings-section">
14
- <header class="account-settings-section__header">
15
- <h2 class="account-settings-section__title">Profile</h2>
16
- </header>
17
14
  <div class="account-settings-section__body">
18
15
  <v-form @submit.prevent="profile.submit" novalidate>
19
16
  <v-row class="mb-2">
@@ -97,17 +94,6 @@ const profile = props.runtime.profile;
97
94
  overflow: hidden;
98
95
  }
99
96
 
100
- .account-settings-section__header {
101
- padding: 1rem 1rem 0;
102
- }
103
-
104
- .account-settings-section__title {
105
- font-size: 1rem;
106
- font-weight: 650;
107
- line-height: 1.2;
108
- margin: 0;
109
- }
110
-
111
97
  .account-settings-section__body {
112
98
  padding: 1rem;
113
99
  }
@@ -9,8 +9,8 @@
9
9
  "./shared": "./src/shared/index.js"
10
10
  },
11
11
  "dependencies": {
12
- "@jskit-ai/crud-core": "0.1.189",
13
- "@jskit-ai/resource-crud-core": "0.1.120"
12
+ "@jskit-ai/crud-core": "0.1.191",
13
+ "@jskit-ai/resource-crud-core": "0.1.122"
14
14
  },
15
15
  "jskit": {
16
16
  "kind": "runtime",
@@ -9,9 +9,9 @@
9
9
  "./shared": "./src/shared/index.js"
10
10
  },
11
11
  "dependencies": {
12
- "@jskit-ai/crud-core": "0.1.189",
13
- "@jskit-ai/resource-crud-core": "0.1.120",
14
- "@jskit-ai/workspaces-core": "0.1.156"
12
+ "@jskit-ai/crud-core": "0.1.191",
13
+ "@jskit-ai/resource-crud-core": "0.1.122",
14
+ "@jskit-ai/workspaces-core": "0.1.158"
15
15
  },
16
16
  "jskit": {
17
17
  "kind": "runtime",
@@ -32,6 +32,8 @@ Use the workspace client provider, components, and composables exported by
32
32
  ## Invariants
33
33
 
34
34
  - Route workspace slug, selected workspace, and server scope stay synchronized.
35
+ - Route and surface pages do not add a page header or standalone heading by
36
+ default.
35
37
  - Invitation acceptance is public only where the server contract permits it.
36
38
  - Administrative UI visibility never substitutes for server authorization.
37
39
  - Query and route state hydrate immediately on warm-cache navigation.
@@ -19,12 +19,9 @@ const normalizedMessage = computed(() => String(props.message || "").trim() || "
19
19
 
20
20
  <template>
21
21
  <v-sheet rounded="lg" border class="workspace-unavailable-panel">
22
- <div class="workspace-unavailable-panel__header">
22
+ <div class="workspace-unavailable-panel__status">
23
23
  <v-icon :icon="mdiAlertCircleOutline" color="error" />
24
- <div>
25
- <h1 class="workspace-unavailable-panel__title">Unavailable</h1>
26
- <p class="text-body-2 text-medium-emphasis mb-0">{{ normalizedSurfaceLabel }} surface.</p>
27
- </div>
24
+ <p class="text-body-2 text-medium-emphasis mb-0">{{ normalizedSurfaceLabel }} surface unavailable.</p>
28
25
  </div>
29
26
  <p class="text-body-2 text-medium-emphasis mb-0">{{ normalizedMessage }}</p>
30
27
  </v-sheet>
@@ -37,17 +34,9 @@ const normalizedMessage = computed(() => String(props.message || "").trim() || "
37
34
  padding: 1rem;
38
35
  }
39
36
 
40
- .workspace-unavailable-panel__header {
37
+ .workspace-unavailable-panel__status {
41
38
  align-items: flex-start;
42
39
  display: flex;
43
40
  gap: 0.75rem;
44
41
  }
45
-
46
- .workspace-unavailable-panel__title {
47
- font-size: clamp(1.35rem, 2vw, 1.85rem);
48
- font-weight: 650;
49
- letter-spacing: -0.02em;
50
- line-height: 1.15;
51
- margin: 0 0 0.25rem;
52
- }
53
42
  </style>
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <section class="workspace-settings-landing">
3
3
  <v-sheet rounded="lg" border class="workspace-settings-landing__panel">
4
- <h2 class="workspace-settings-landing__title">No settings sections yet</h2>
5
4
  <p class="text-body-2 text-medium-emphasis mb-0">
6
5
  This app has no workspace-level settings configured.
7
6
  </p>
@@ -13,11 +12,4 @@
13
12
  .workspace-settings-landing__panel {
14
13
  padding: 1rem;
15
14
  }
16
-
17
- .workspace-settings-landing__title {
18
- font-size: 1rem;
19
- font-weight: 650;
20
- line-height: 1.2;
21
- margin: 0 0 0.25rem;
22
- }
23
15
  </style>
@@ -5,12 +5,6 @@ import { RouterView } from "vue-router";
5
5
 
6
6
  <template>
7
7
  <section class="settings-shell d-flex flex-column ga-4">
8
- <header>
9
- <p class="text-overline text-medium-emphasis mb-1">Settings</p>
10
- <h1 class="settings-shell__title">Workspace settings</h1>
11
- <p class="text-body-2 text-medium-emphasis mb-0">Configure the current workspace and its members.</p>
12
- </header>
13
-
14
8
  <v-sheet rounded="lg" border class="settings-shell__panel">
15
9
  <nav class="settings-shell__nav" aria-label="Workspace settings sections">
16
10
  <v-list nav density="compact" class="settings-shell__nav-list">
@@ -25,14 +19,6 @@ import { RouterView } from "vue-router";
25
19
  </template>
26
20
 
27
21
  <style scoped>
28
- .settings-shell__title {
29
- font-size: clamp(1.35rem, 2vw, 1.85rem);
30
- font-weight: 650;
31
- letter-spacing: -0.02em;
32
- line-height: 1.15;
33
- margin: 0 0 0.35rem;
34
- }
35
-
36
22
  .settings-shell__panel {
37
23
  display: grid;
38
24
  gap: 1rem;
@@ -20,20 +20,12 @@ function adminChildPath(suffix = "") {
20
20
  surface-label="Admin"
21
21
  />
22
22
  <section v-else class="workspace-admin-screen d-flex flex-column ga-4">
23
- <header class="workspace-admin-screen__header">
24
- <div>
25
- <p class="text-overline text-medium-emphasis mb-1">Admin</p>
26
- <h1 class="workspace-admin-screen__title">Workspace Admin</h1>
27
- <p class="text-body-2 text-medium-emphasis mb-0">Manage members and workspace settings.</p>
28
- </div>
29
- <div class="workspace-admin-screen__actions">
30
- <v-btn color="primary" variant="flat" :to="adminChildPath('members')">Members</v-btn>
31
- <v-btn color="primary" variant="tonal" :to="adminChildPath('workspace/settings')">Settings</v-btn>
32
- </div>
33
- </header>
23
+ <div class="workspace-admin-screen__actions">
24
+ <v-btn color="primary" variant="flat" :to="adminChildPath('members')">Members</v-btn>
25
+ <v-btn color="primary" variant="tonal" :to="adminChildPath('workspace/settings')">Settings</v-btn>
26
+ </div>
34
27
 
35
28
  <v-sheet rounded="lg" border class="workspace-admin-screen__panel">
36
- <h2 class="text-h6 mb-2">Admin tasks</h2>
37
29
  <p class="text-body-2 text-medium-emphasis mb-0">
38
30
  Review workspace access, members, and operational settings from this surface.
39
31
  </p>
@@ -42,21 +34,6 @@ function adminChildPath(suffix = "") {
42
34
  </template>
43
35
 
44
36
  <style scoped>
45
- .workspace-admin-screen__header {
46
- align-items: flex-start;
47
- display: flex;
48
- gap: 1rem;
49
- justify-content: space-between;
50
- }
51
-
52
- .workspace-admin-screen__title {
53
- font-size: clamp(1.5rem, 2.5vw, 2.25rem);
54
- font-weight: 700;
55
- letter-spacing: -0.03em;
56
- line-height: 1.1;
57
- margin: 0 0 0.4rem;
58
- }
59
-
60
37
  .workspace-admin-screen__actions {
61
38
  display: flex;
62
39
  flex-wrap: wrap;
@@ -69,10 +46,6 @@ function adminChildPath(suffix = "") {
69
46
  }
70
47
 
71
48
  @media (max-width: 640px) {
72
- .workspace-admin-screen__header {
73
- flex-direction: column;
74
- }
75
-
76
49
  .workspace-admin-screen__actions {
77
50
  width: 100%;
78
51
  }
@@ -12,14 +12,7 @@ const { workspaceUnavailable, workspaceUnavailableMessage } = useWorkspaceNotFou
12
12
  surface-label="App"
13
13
  />
14
14
  <section v-else class="workspace-home-screen d-flex flex-column ga-4">
15
- <header>
16
- <p class="text-overline text-medium-emphasis mb-1">Workspace</p>
17
- <h1 class="workspace-home-screen__title">Workspace Home</h1>
18
- <p class="text-body-2 text-medium-emphasis mb-0">The current workspace is active.</p>
19
- </header>
20
-
21
15
  <v-sheet rounded="lg" border class="workspace-home-screen__panel">
22
- <h2 class="text-h6 mb-2">No workspace activity yet</h2>
23
16
  <p class="text-body-2 text-medium-emphasis mb-0">
24
17
  Activity from workspace workflows will appear here.
25
18
  </p>
@@ -28,14 +21,6 @@ const { workspaceUnavailable, workspaceUnavailableMessage } = useWorkspaceNotFou
28
21
  </template>
29
22
 
30
23
  <style scoped>
31
- .workspace-home-screen__title {
32
- font-size: clamp(1.5rem, 2.5vw, 2.25rem);
33
- font-weight: 700;
34
- letter-spacing: -0.03em;
35
- line-height: 1.1;
36
- margin: 0 0 0.4rem;
37
- }
38
-
39
24
  .workspace-home-screen__panel {
40
25
  margin-inline: auto;
41
26
  max-width: 34rem;