@jskit-ai/ui-generator 0.1.13 → 0.1.15

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @jskit-ai/ui-generator
2
2
 
3
- Generate non-CRUD UI pages and outlet elements for JSKIT apps.
3
+ Generate app-local UI pages, page links, placed elements, and routed subpage hosts for JSKIT apps.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -10,181 +10,205 @@ List available placement targets in the current app:
10
10
  npx jskit list placements
11
11
  ```
12
12
 
13
- Generate a page (default placement target):
13
+ Create a normal page at an explicit file:
14
14
 
15
15
  ```bash
16
- npx jskit generate @jskit-ai/ui-generator page --name "Reports Dashboard" --surface admin
16
+ npx jskit generate @jskit-ai/ui-generator page \
17
+ admin/reports-dashboard/index.vue \
18
+ --name "Reports Dashboard"
17
19
  ```
18
20
 
19
- Generate a page in a subdirectory:
21
+ Create a file-route page:
20
22
 
21
23
  ```bash
22
- npx jskit generate @jskit-ai/ui-generator page --name "Reports Dashboard" --surface admin --directory-prefix ops
24
+ npx jskit generate @jskit-ai/ui-generator page \
25
+ admin/contacts/[contactId].vue \
26
+ --name "Contact"
23
27
  ```
24
28
 
25
- Generate a page and place its menu entry in the workspace cog dropdown:
29
+ Upgrade an existing page into a routed subpage host:
26
30
 
27
31
  ```bash
28
- npx jskit generate @jskit-ai/ui-generator page --name "Reports" --surface admin --placement workspace-tools:primary-menu
32
+ npx jskit generate @jskit-ai/ui-generator add-subpages \
33
+ admin/contacts/[contactId].vue \
34
+ --title "Contact" \
35
+ --subtitle "Manage contact modules."
29
36
  ```
30
37
 
31
- Generate an element at a specific outlet:
38
+ Create a reusable placed element:
32
39
 
33
40
  ```bash
34
- npx jskit generate @jskit-ai/ui-generator element --name "Ops Panel" --surface admin --placement shell-layout:top-right
41
+ npx jskit generate @jskit-ai/ui-generator placed-element \
42
+ --name "Alerts Widget" \
43
+ --surface admin
35
44
  ```
36
45
 
37
- Generate an element with custom component path:
46
+ Inject a plain generic outlet into an existing Vue file:
38
47
 
39
48
  ```bash
40
- npx jskit generate @jskit-ai/ui-generator element --name "Alerts Widget" --surface admin --path src/widgets --placement shell-layout:top-right
49
+ npx jskit generate @jskit-ai/ui-generator outlet \
50
+ src/components/ContactSummaryCard.vue \
51
+ --target contact-view:summary-actions
41
52
  ```
42
53
 
43
- Generate a route container page with nested outlet (for embedded sub-pages):
54
+ ## Commands
44
55
 
45
- ```bash
46
- npx jskit generate @jskit-ai/ui-generator container --name "Practice" --surface admin
47
- ```
56
+ - `page <target-file>`: create a route page at that exact file relative to `src/pages/` and add a link placement entry for it.
57
+ - `add-subpages <target-file>`: upgrade an existing page relative to `src/pages/` into the standard `SectionContainerShell + ShellOutlet + RouterView` host shape.
58
+ - `placed-element`: create a reusable component and register a placement for it.
59
+ - `outlet <target-file>`: inject a plain `ShellOutlet` into an existing Vue SFC.
48
60
 
49
- Generate a route container with explicit dynamic route path:
61
+ For `placed-element`, the default placement target is `shell-layout:top-right`.
62
+ Use `--placement host:position` to override it.
50
63
 
51
- ```bash
52
- npx jskit generate @jskit-ai/ui-generator container --name "Contact" --surface admin --directory-prefix contacts --route-path "[contactId]"
53
- ```
64
+ ## The Mental Model
54
65
 
55
- Add a shell menu entry for that container (optional):
66
+ `page` and `add-subpages` operate on explicit page files relative to `src/pages/`. `outlet` still targets an explicit Vue file path relative to the app root.
56
67
 
57
- ```bash
58
- npx jskit generate @jskit-ai/ui-generator container --name "Practice" --surface admin --placement shell-layout:primary-menu
59
- ```
68
+ That means:
60
69
 
61
- Inject an inline outlet into an existing Vue page/component:
70
+ - `catalog/index.vue` is obviously an index-route page
71
+ - `catalog.vue` is obviously a file-route page
72
+ - there is no extra route-shape flag to remember
73
+ - the owning surface is derived from where the file lives
62
74
 
63
- ```bash
64
- npx jskit generate @jskit-ai/ui-generator outlet --file src/pages/w/[workspaceSlug]/admin/contacts/[contactId]/index.vue --host contact-view
65
- ```
75
+ This is the reference model for JSKIT page-producing generators.
66
76
 
67
- Show generator and subcommand help:
77
+ - `@jskit-ai/ui-generator page <target-file>` works from an explicit page file relative to `src/pages/`.
78
+ - `@jskit-ai/crud-ui-generator crud <target-root>` works from an explicit route root relative to `src/pages/`.
79
+ - `@jskit-ai/assistant page <target-file>` and `settings-page <target-file>` work from explicit page files relative to `src/pages/`.
68
80
 
69
- ```bash
70
- npx jskit generate @jskit-ai/ui-generator help
71
- npx jskit generate @jskit-ai/ui-generator outlet help
72
- npx jskit generate @jskit-ai/ui-generator outlet
73
- ```
81
+ ## Page Links
74
82
 
75
- ## Commands
83
+ `page` creates a page file and appends a link placement block for it.
84
+
85
+ These options control that generated page link:
86
+
87
+ - `--link-placement`: where the page link renders
88
+ - `--link-component-token`: how the page link is rendered
89
+ - `--link-to`: explicit `props.to` override for the page link
90
+
91
+ This is intentionally separate from `placed-element`, which still uses `--placement` because it places arbitrary UI, not a page link.
92
+
93
+ ## Routed Subpages
94
+
95
+ `add-subpages` is the only routed-subpages command.
96
+
97
+ It upgrades an existing page so the page itself owns:
98
+
99
+ - `SectionContainerShell`
100
+ - `ShellOutlet host="..." position="sub-pages"`
101
+ - `RouterView`
102
+
103
+ `--target` controls that outlet target:
104
+
105
+ - if omitted, the target is derived from the page path
106
+ - `--target contact-view` means `contact-view:sub-pages`
107
+ - `--target contact-view:secondary-tabs` uses an explicit custom position
108
+
109
+ Derived target examples:
76
110
 
77
- - `page`: `--name --surface [--directory-prefix] [--placement]`
78
- - `element`: `--name --surface [--path] [--placement]`
79
- - `container`: `--name --surface [--directory-prefix] [--route-path] [--placement]`
80
- - `outlet`: `--file --host [--position] [--mode]`
111
+ - `src/pages/admin/catalog/index.vue` -> `catalog:sub-pages`
112
+ - `src/pages/admin/catalog.vue` -> `catalog:sub-pages`
113
+ - `src/pages/admin/contacts/[contactId].vue` -> `contacts-contact-id:sub-pages`
114
+ - `src/pages/admin/catalog/products/index.vue` -> `catalog-products:sub-pages`
81
115
 
82
- `page` also supports:
116
+ If the page already contains a `RouterView`, `add-subpages` fails instead of trying to update an existing routed host.
83
117
 
84
- - `--placement-component-token` to override the placement component token.
85
- - `--placement-to` to set explicit `props.to` in the generated placement block.
86
- - if `--placement-to` is omitted and `--directory-prefix` includes a `(nestedChildren)` route group, `props.to` is auto-set to `./<page-slug>`.
118
+ It also ensures the shared support scaffold exists:
87
119
 
88
- ## Container Workflow
120
+ - `src/components/SectionContainerShell.vue`
121
+ - `src/components/TabLinkItem.vue`
122
+ - `packages/main/src/client/providers/MainClientProvider.js` registration for `local.main.ui.tab-link-item`
89
123
 
90
- - `container` creates app-owned scaffolding:
91
- - `src/components/SectionContainerShell.vue` (shared container shell with responsive tab row)
92
- - `src/components/TabLinkItem.vue` (tab link item token component)
93
- - `packages/main/src/client/providers/MainClientProvider.js` registration for `local.main.ui.tab-link-item`
94
- - `<route>.vue` as a thin wrapper around `SectionContainerShell` + `<RouterView />`, with route meta outlet declaration at `meta.jskit.placements.outlets`
95
- - no shell menu placement is added unless `--placement` is explicitly provided
96
- - Child pages for a `container` go directly under the container route path, not under `(nestedChildren)`.
97
- - Example container route: `src/pages/admin/practice.vue`
98
- - Example child page path: `src/pages/admin/practice/notes/index.vue`
99
- - Example URL: `/admin/practice/notes`
100
- - Use `(nestedChildren)` for the `page + outlet` pattern when the parent page is an existing `index.vue` route that should render child routes inside its own `RouterView`.
124
+ ## Child Route Placement Rule
101
125
 
102
- Generate a child page inside a container:
126
+ Child routes attach differently depending on the parent page file shape.
127
+
128
+ If the parent is a file route:
129
+
130
+ - parent: `src/pages/admin/catalog.vue`
131
+ - child pages go under: `src/pages/admin/catalog/...`
132
+ - example child page: `src/pages/admin/catalog/products/index.vue`
133
+
134
+ If the parent is an index route:
135
+
136
+ - parent: `src/pages/admin/catalog/index.vue`
137
+ - child pages go under: `src/pages/admin/catalog/index/...`
138
+ - example child page: `src/pages/admin/catalog/index/products/index.vue`
139
+
140
+ That `index/...` folder shape is the native file-based routing rule for nesting children under an `index.vue` page.
141
+
142
+ ## Example: File Route Parent
143
+
144
+ Create the parent page:
103
145
 
104
146
  ```bash
105
147
  npx jskit generate @jskit-ai/ui-generator page \
106
- --name "Notes" \
107
- --surface admin \
108
- --directory-prefix "practice" \
109
- --placement practice:sub-pages \
110
- --placement-component-token local.main.ui.tab-link-item
148
+ admin/contacts/[contactId].vue \
149
+ --name "Contact"
111
150
  ```
112
151
 
113
- - Generate CRUD pages into that container using `@jskit-ai/crud-ui-generator` with:
114
- - `--container <route-slug>`
115
- - `--route-path <resource-slug>`
116
- - optional `--placement` override (default becomes `<container>:sub-pages` for list pages)
152
+ Upgrade it to host subpages:
117
153
 
118
- ## Inline Outlet Workflow
154
+ ```bash
155
+ npx jskit generate @jskit-ai/ui-generator add-subpages \
156
+ admin/contacts/[contactId].vue \
157
+ --title "Contact" \
158
+ --subtitle "Manage contact modules."
159
+ ```
119
160
 
120
- - `outlet` patches an app-owned Vue SFC by adding:
121
- - `import ShellOutlet from "@jskit-ai/shell-web/client/components/ShellOutlet";`
122
- - `<ShellOutlet host="<host>" position="<position>" />` in template
123
- - optional `<RouterView />` (when `--mode routed`, only if one does not already exist in the file)
124
- - `--mode` supports:
125
- - `routed` (default): insert `RouterView` if missing
126
- - `outlet-only`: insert only `ShellOutlet`
161
+ Generate a child page link inside that host:
127
162
 
128
- ## End-to-End Example: Embed Pets CRUD in Contact View
163
+ ```bash
164
+ npx jskit generate @jskit-ai/ui-generator page \
165
+ admin/contacts/[contactId]/notes/index.vue \
166
+ --name "Notes"
167
+ ```
129
168
 
130
- Goal: render pets CRUD pages inside `contacts/[contactId]/index.vue` using a routed outlet and tab-style placement links.
169
+ ## Example: Index Route Parent
131
170
 
132
- 1. Inject a routed outlet into the contact page:
171
+ Create the parent page:
133
172
 
134
173
  ```bash
135
- npx jskit generate ui-generator outlet \
136
- --file src/pages/w/[workspaceSlug]/admin/contacts/[contactId]/index.vue \
137
- --host contact-view \
138
- --position sub-pages \
139
- --mode routed
174
+ npx jskit generate @jskit-ai/ui-generator page \
175
+ admin/catalog/index.vue \
176
+ --name "Catalog"
140
177
  ```
141
178
 
142
- What each option does:
179
+ Upgrade it to host subpages:
180
+
181
+ ```bash
182
+ npx jskit generate @jskit-ai/ui-generator add-subpages \
183
+ admin/catalog/index.vue \
184
+ --title "Catalog"
185
+ ```
143
186
 
144
- - `--file`: target Vue SFC to patch.
145
- - `--host`: outlet host namespace (used later by placements).
146
- - `--position`: outlet position key under that host.
147
- - `--mode routed`: ensures `<RouterView />` exists so nested pages render inline.
187
+ Because the parent page is `index.vue`, nested child pages live under the matching `index/` folder.
148
188
 
149
- 2. Generate pets CRUD pages under the nested-children group and place a tab link into that outlet:
189
+ Generate a child page link inside that host:
150
190
 
151
191
  ```bash
152
- npx jskit generate crud-ui-generator \
153
- --namespace pets \
154
- --surface admin \
155
- --operations list,view,new,edit \
156
- --resource-file packages/pets/src/shared/petResource.js \
157
- --directory-prefix "contacts/[contactId]/(nestedChildren)" \
158
- --placement contact-view:sub-pages \
159
- --placement-component-token local.main.ui.tab-link-item \
160
- --placement-to ./pets \
161
- --id-param petId
192
+ npx jskit generate @jskit-ai/ui-generator page \
193
+ admin/catalog/index/products/index.vue \
194
+ --name "Products"
162
195
  ```
163
196
 
164
- What each option does:
165
-
166
- - `--namespace pets`: CRUD namespace for generated UI artifacts.
167
- - `--surface admin`: generate pages under admin surface routes.
168
- - `--operations list,view,new,edit`: generate full CRUD page set.
169
- - `--resource-file`: resource contract used to scaffold fields/forms.
170
- - `--directory-prefix "contacts/[contactId]/(nestedChildren)"`: place generated routes under the contact context, in a route-group folder that does not appear in URL.
171
- - `--placement contact-view:sub-pages`: append a placement targeting the outlet created in step 1.
172
- - `--placement-component-token local.main.ui.tab-link-item`: render placement as a tab link component.
173
- - `--placement-to ./pets`: tab link resolves relative to current contact route (for example `/contacts/538779/pets`).
174
- - `--id-param petId`: dynamic route parameter for view/edit pages.
175
-
176
- Expected result:
177
-
178
- - Contact page keeps its own route and renders nested pets pages inline via `RouterView`.
179
- - Pets routes are generated under `contacts/[contactId]/(nestedChildren)/pets/...`.
180
- - URL remains clean (`(nestedChildren)` is not part of URL).
181
- - A placement entry is added so the pets tab appears in `contact-view:sub-pages`.
182
-
183
- ## Placement Notes
184
-
185
- - `--placement` expects `host:position`.
186
- - Targets come from:
187
- - app-declared `<ShellOutlet host="..." position="..." />` in `src/**/*.vue`
188
- - app route meta `meta.jskit.placements.outlets` declarations in `src/**/*.vue`
189
- - installed package metadata `metadata.ui.placements.outlets`
190
- - If `--placement` is omitted, the app default outlet is used.
197
+ When `page` finds the nearest parent page upgraded with `add-subpages`, it reuses that parent’s real outlet target, defaults the link renderer to `local.main.ui.tab-link-item`, and derives `to` from the child route automatically.
198
+
199
+ ## Generic Outlet Injection
200
+
201
+ `outlet` is intentionally small.
202
+
203
+ It only adds:
204
+
205
+ - `import ShellOutlet from "@jskit-ai/shell-web/client/components/ShellOutlet";`
206
+ - `<ShellOutlet host="..." position="..." />`
207
+
208
+ It does not:
209
+
210
+ - add `RouterView`
211
+ - add `SectionContainerShell`
212
+ - add routed subpage scaffolding
213
+
214
+ Use `add-subpages` when the goal is routed child pages inside a page.