@mccaskie-labs/workbench-config 0.2.4 → 0.2.5
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/CHANGELOG.md +6 -0
- package/capabilities/analytics.json +47 -3
- package/capabilities/country.json +160 -3
- package/capabilities/ui.json +27 -2
- package/dist/capabilities.gen.d.ts +186 -4
- package/dist/capabilities.gen.js +233 -7
- package/dist/capability-schema.d.ts +1 -1
- package/dist/capability-schema.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @mccaskie-labs/workbench-config
|
|
2
2
|
|
|
3
|
+
## 0.2.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Client questions for country formats (where the readers are, the business's time zone, the currency), visitor counts (page views, and which actions to count) and admin pages (which pages, and who sees each).
|
|
8
|
+
|
|
3
9
|
## 0.2.4
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
"status": "built",
|
|
8
8
|
"delivery": {
|
|
9
9
|
"choice": "optional",
|
|
10
|
-
"intro": "Counting page views and the things visitors do on the site."
|
|
11
|
-
"when": "The client wants to know how many people visit, which pages they open, or to count an action such as a sign-up or an order."
|
|
10
|
+
"intro": "Counting page views and the things visitors do on the site."
|
|
12
11
|
},
|
|
13
12
|
"surfaces": {
|
|
14
13
|
"package": [
|
|
@@ -99,5 +98,50 @@
|
|
|
99
98
|
"cost_hint_usd": 0,
|
|
100
99
|
"note": "Create the site, drive page views, query them back (cf_analytics_query, later)"
|
|
101
100
|
}
|
|
102
|
-
]
|
|
101
|
+
],
|
|
102
|
+
"offer": {
|
|
103
|
+
"pattern": "switch_on",
|
|
104
|
+
"when": "The client wants to know how many people visit, which pages they open, or to count an action such as a sign-up or an order.",
|
|
105
|
+
"say": "The project already has Workbench visitor counts: page views counted by Cloudflare without cookies, and the actions you choose counted in the app's own database. I'll switch on what you want.",
|
|
106
|
+
"answers_file": "workbench/analytics.json",
|
|
107
|
+
"answers_format": "`{ \"format\": 1, \"page_views\": true, \"events\": [{ \"name\": \"order.placed\", \"when\": \"a customer sends an order\", \"details\": [\"items\", \"total_band\"] }] }`. For page views, create the Web Analytics site with Workbench Control (`cf_web_analytics_site_create`), write its beacon token onto staging and production (`cf_worker_secret_put source=web_analytics`), and put `beacon(env)` on every page customers see. For each event, call `eventsFor(db).track(name, details)` where the action happens.",
|
|
108
|
+
"questions": [
|
|
109
|
+
{
|
|
110
|
+
"id": "analytics.page-views",
|
|
111
|
+
"sets": "page_views",
|
|
112
|
+
"ask": "Should the site count its page views?",
|
|
113
|
+
"style": "cards",
|
|
114
|
+
"answers": [
|
|
115
|
+
{
|
|
116
|
+
"label": "Yes",
|
|
117
|
+
"value": true,
|
|
118
|
+
"means": "How many people visit and which pages they open, counted by Cloudflare. No cookies, and no personal details kept."
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"label": "No",
|
|
122
|
+
"value": false,
|
|
123
|
+
"means": "Nothing is counted on the site's pages."
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"note": "Only pages customers see; never the owner's or admins' pages."
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"id": "analytics.actions",
|
|
130
|
+
"sets": "events",
|
|
131
|
+
"ask": "Which actions should be counted?",
|
|
132
|
+
"style": "table",
|
|
133
|
+
"note": "Propose the few actions that show whether the site is working for the business (a sign-up, an order, a booking, a form sent), each with a name (`thing.past_verb`, lower case: `order.placed`), when it happens in the client's words, and its details. Details are counts, choices and bands (`items`, `plan`, `total_band`), never an email address, a name, a phone number or free text someone typed. The client accepts, removes or adds; an empty list is fine."
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"not_asked": [
|
|
137
|
+
{
|
|
138
|
+
"sets": "consent",
|
|
139
|
+
"why": "The page-view counter sets no cookies and keeps no personal details, and events hold none either, so they add nothing that a cookie notice would need to cover."
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"sets": "reports",
|
|
143
|
+
"why": "Page views are seen in Cloudflare's Web Analytics, and events are rows in the app's own `events` table; ask what the owner wants to see when they ask for a report."
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
103
147
|
}
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
"status": "built",
|
|
8
8
|
"delivery": {
|
|
9
9
|
"choice": "optional",
|
|
10
|
-
"intro": "Dates, times, numbers and money written the way readers in your country expect."
|
|
11
|
-
"when": "The app shows a date, a time, a number, a phone number or an amount of money to its readers, or the client says where their readers are."
|
|
10
|
+
"intro": "Dates, times, numbers and money written the way readers in your country expect."
|
|
12
11
|
},
|
|
13
12
|
"surfaces": {
|
|
14
13
|
"package": [
|
|
@@ -84,5 +83,163 @@
|
|
|
84
83
|
"cost_hint_usd": 0,
|
|
85
84
|
"note": "Every pack's spelling is one the Gateway accepts (en-PH, en-AU, en-GB, en-US), checked against the ai manifest's spellings; no Gateway call"
|
|
86
85
|
}
|
|
87
|
-
]
|
|
86
|
+
],
|
|
87
|
+
"offer": {
|
|
88
|
+
"pattern": "project",
|
|
89
|
+
"when": "The app shows a date, a time, a number, a phone number or an amount of money to its readers, or the client says where their readers are.",
|
|
90
|
+
"say": "I'll write dates, times and money with Workbench country formats, the way your readers expect them. That needs to know where they are, once for the whole site.",
|
|
91
|
+
"answers_file": "workbench/country.json",
|
|
92
|
+
"answers_format": "`{ \"format\": 1, \"country\": \"AU\", \"time_zone\": null, \"currency\": null }`: the country code (or `ZZ`, the package's WORLDWIDE, for readers everywhere), and an IANA time zone or `{ \"code\", \"symbol\" }` currency only when they differ from the country's own (the Australian and US time questions both fill `time_zone`). Then set `READERS` in `src/lib/country.ts` to match: `audiencePack({ country, timeZone, currency })`, leaving out what is null. Every page, email, PDF and form reads `READERS`, so nothing else changes.",
|
|
93
|
+
"questions": [
|
|
94
|
+
{
|
|
95
|
+
"id": "country.where",
|
|
96
|
+
"sets": "audience.country",
|
|
97
|
+
"ask": "Where are most of the site's readers?",
|
|
98
|
+
"style": "cards",
|
|
99
|
+
"answers": [
|
|
100
|
+
{
|
|
101
|
+
"label": "Australia",
|
|
102
|
+
"value": "AU",
|
|
103
|
+
"means": "26 September 2026, A$1,400, Sydney time, Australian spelling."
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"label": "The Philippines",
|
|
107
|
+
"value": "PH",
|
|
108
|
+
"means": "September 26, 2026, ₱1,400, Manila time."
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"label": "The United Kingdom",
|
|
112
|
+
"value": "GB",
|
|
113
|
+
"means": "26 September 2026, £1,400, UK time, British spelling."
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"label": "The United States",
|
|
117
|
+
"value": "US",
|
|
118
|
+
"means": "September 26, 2026, US$1,400, Eastern time, American spelling."
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"other": {
|
|
122
|
+
"kind": "text",
|
|
123
|
+
"min": 2,
|
|
124
|
+
"max": 60,
|
|
125
|
+
"description": "Another country, or readers all over the world."
|
|
126
|
+
},
|
|
127
|
+
"note": "Recommend Australia unless the client's words say otherwise. A country with no pack yet, or readers everywhere, gets the neutral one (`ZZ`: 26 September 2026, 24-hour clock, UTC, US$): say so, and ask for the currency."
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "country.au-time",
|
|
131
|
+
"sets": "audience.time_zone.au",
|
|
132
|
+
"ask": "Which Australian time should the site show?",
|
|
133
|
+
"style": "cards",
|
|
134
|
+
"answers": [
|
|
135
|
+
{
|
|
136
|
+
"label": "Sydney, Melbourne, Canberra",
|
|
137
|
+
"value": null,
|
|
138
|
+
"means": "The pack's own (Australia/Sydney), with daylight saving."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"label": "Brisbane",
|
|
142
|
+
"value": "Australia/Brisbane",
|
|
143
|
+
"means": "Queensland, no daylight saving."
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"label": "Adelaide",
|
|
147
|
+
"value": "Australia/Adelaide",
|
|
148
|
+
"means": "South Australia, half an hour behind Sydney."
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"label": "Perth",
|
|
152
|
+
"value": "Australia/Perth",
|
|
153
|
+
"means": "Western Australia."
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"other": {
|
|
157
|
+
"kind": "text",
|
|
158
|
+
"min": 5,
|
|
159
|
+
"max": 40,
|
|
160
|
+
"description": "Another Australian time zone, such as Australia/Darwin or Australia/Hobart."
|
|
161
|
+
},
|
|
162
|
+
"when": {
|
|
163
|
+
"id": "country.where",
|
|
164
|
+
"is": [
|
|
165
|
+
"AU"
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
"note": "The time zone of the business, where bookings and opening hours happen. Hobart follows Sydney; Darwin is Australia/Darwin."
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"id": "country.us-time",
|
|
172
|
+
"sets": "audience.time_zone.us",
|
|
173
|
+
"ask": "Which US time should the site show?",
|
|
174
|
+
"style": "cards",
|
|
175
|
+
"answers": [
|
|
176
|
+
{
|
|
177
|
+
"label": "Eastern",
|
|
178
|
+
"value": null,
|
|
179
|
+
"means": "The pack's own (America/New_York)."
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"label": "Central",
|
|
183
|
+
"value": "America/Chicago"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"label": "Mountain",
|
|
187
|
+
"value": "America/Denver"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"label": "Pacific",
|
|
191
|
+
"value": "America/Los_Angeles"
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
"other": {
|
|
195
|
+
"kind": "text",
|
|
196
|
+
"min": 5,
|
|
197
|
+
"max": 40,
|
|
198
|
+
"description": "Another US time zone, such as America/Phoenix or Pacific/Honolulu."
|
|
199
|
+
},
|
|
200
|
+
"when": {
|
|
201
|
+
"id": "country.where",
|
|
202
|
+
"is": [
|
|
203
|
+
"US"
|
|
204
|
+
]
|
|
205
|
+
},
|
|
206
|
+
"note": "The time zone of the business."
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"id": "country.currency",
|
|
210
|
+
"sets": "audience.currency",
|
|
211
|
+
"ask": "Which money are prices in?",
|
|
212
|
+
"style": "cards",
|
|
213
|
+
"answers": [
|
|
214
|
+
{
|
|
215
|
+
"label": "The country's own",
|
|
216
|
+
"value": null,
|
|
217
|
+
"means": "A$ in Australia, ₱ in the Philippines, £ in the UK, US$ in the US."
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"label": "US dollars",
|
|
221
|
+
"value": "USD",
|
|
222
|
+
"means": "Shown as US$1,400."
|
|
223
|
+
}
|
|
224
|
+
],
|
|
225
|
+
"other": {
|
|
226
|
+
"kind": "text",
|
|
227
|
+
"min": 3,
|
|
228
|
+
"max": 3,
|
|
229
|
+
"description": "Another currency's three-letter code, such as NZD or EUR."
|
|
230
|
+
},
|
|
231
|
+
"note": "Write a currency other than the country's as `{ \"code\", \"symbol\" }` (NZD is NZ$). Ask it only when the client sells something; otherwise record null."
|
|
232
|
+
}
|
|
233
|
+
],
|
|
234
|
+
"not_asked": [
|
|
235
|
+
{
|
|
236
|
+
"sets": "audience.format",
|
|
237
|
+
"why": "Date order, the clock, number separators, spelling and phone number shapes all come from the country's pack, so they match what readers expect without asking."
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"sets": "audience.owner_pages",
|
|
241
|
+
"why": "Pages only the owner sees use workbench-ui's own times and money, not the readers'."
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
}
|
|
88
245
|
}
|
package/capabilities/ui.json
CHANGED
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
"status": "built",
|
|
8
8
|
"delivery": {
|
|
9
9
|
"choice": "optional",
|
|
10
|
-
"intro": "A ready-made look for the pages only you and your admins see."
|
|
11
|
-
"when": "The client wants a page only the owner or the app's admins see: a dashboard, a list, a settings page or a status page."
|
|
10
|
+
"intro": "A ready-made look for the pages only you and your admins see."
|
|
12
11
|
},
|
|
13
12
|
"surfaces": {
|
|
14
13
|
"package": [
|
|
@@ -95,5 +94,31 @@
|
|
|
95
94
|
],
|
|
96
95
|
"styles": {
|
|
97
96
|
"prefix": "wb-ui-"
|
|
97
|
+
},
|
|
98
|
+
"offer": {
|
|
99
|
+
"pattern": "switch_on",
|
|
100
|
+
"when": "The client wants a page only the owner or the app's admins see: a dashboard, a list, a settings page or a status page.",
|
|
101
|
+
"say": "I'll build this with the Workbench owner-page look, the same top bar, cards and pills as the other admin pages, so it's quick to build and consistent. Your customers never see it.",
|
|
102
|
+
"answers_file": "workbench/ui.json",
|
|
103
|
+
"answers_format": "`{ \"format\": 1, \"pages\": [{ \"path\": \"/admin/orders\", \"what\": \"every order this month, newest first\", \"who\": \"admins\" }] }`. Build each page with `shell`, `topBar`, `card` and `pill`. An `admins` page lives under `/admin/` and checks `requireUser` and `app_admins` (the workbench-sign-in skill); an `owner` page lives under `/owner/` and is behind Access in production.",
|
|
104
|
+
"questions": [
|
|
105
|
+
{
|
|
106
|
+
"id": "ui.pages",
|
|
107
|
+
"sets": "pages",
|
|
108
|
+
"ask": "Which admin pages should the app have?",
|
|
109
|
+
"style": "table",
|
|
110
|
+
"note": "Propose the pages the request needs, each with its path, what it shows or lets them change in the client's words, and who sees it: `admins` (the business's people, who sign in to the app) or `owner` (whoever runs the app's Workbench, through Access). Recommend `admins` unless the page is about running the app itself, such as a status page. The client accepts, removes or adds pages."
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"not_asked": [
|
|
114
|
+
{
|
|
115
|
+
"sets": "look",
|
|
116
|
+
"why": "Every admin page has the same Workbench look, so the business's people learn it once. Restyle it in project.css (see Restyling) if the client wants their colours."
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"sets": "formats",
|
|
120
|
+
"why": "Times, amounts and durations on these pages come from workbench-ui's `when`, `money` and `duration`. What customers see uses the readers' formats (the workbench-country skill)."
|
|
121
|
+
}
|
|
122
|
+
]
|
|
98
123
|
}
|
|
99
124
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const MANIFEST_VERSION: "
|
|
1
|
+
export declare const MANIFEST_VERSION: "b74fc43c59b7";
|
|
2
2
|
export declare const capabilities: {
|
|
3
3
|
readonly ai: {
|
|
4
4
|
readonly $schema: "./schema.json";
|
|
@@ -413,10 +413,45 @@ export declare const capabilities: {
|
|
|
413
413
|
readonly cost_hint_usd: 0;
|
|
414
414
|
readonly note: "Create the site, drive page views, query them back (cf_analytics_query, later)";
|
|
415
415
|
}];
|
|
416
|
+
readonly offer: {
|
|
417
|
+
readonly pattern: "switch_on";
|
|
418
|
+
readonly when: "The client wants to know how many people visit, which pages they open, or to count an action such as a sign-up or an order.";
|
|
419
|
+
readonly say: "The project already has Workbench visitor counts: page views counted by Cloudflare without cookies, and the actions you choose counted in the app's own database. I'll switch on what you want.";
|
|
420
|
+
readonly answers_file: "workbench/analytics.json";
|
|
421
|
+
readonly answers_format: "`{ \"format\": 1, \"page_views\": true, \"events\": [{ \"name\": \"order.placed\", \"when\": \"a customer sends an order\", \"details\": [\"items\", \"total_band\"] }] }`. For page views, create the Web Analytics site with Workbench Control (`cf_web_analytics_site_create`), write its beacon token onto staging and production (`cf_worker_secret_put source=web_analytics`), and put `beacon(env)` on every page customers see. For each event, call `eventsFor(db).track(name, details)` where the action happens.";
|
|
422
|
+
readonly questions: readonly [{
|
|
423
|
+
readonly id: "analytics.page-views";
|
|
424
|
+
readonly sets: "page_views";
|
|
425
|
+
readonly ask: "Should the site count its page views?";
|
|
426
|
+
readonly style: "cards";
|
|
427
|
+
readonly answers: readonly [{
|
|
428
|
+
readonly label: "Yes";
|
|
429
|
+
readonly value: true;
|
|
430
|
+
readonly means: "How many people visit and which pages they open, counted by Cloudflare. No cookies, and no personal details kept.";
|
|
431
|
+
}, {
|
|
432
|
+
readonly label: "No";
|
|
433
|
+
readonly value: false;
|
|
434
|
+
readonly means: "Nothing is counted on the site's pages.";
|
|
435
|
+
}];
|
|
436
|
+
readonly note: "Only pages customers see; never the owner's or admins' pages.";
|
|
437
|
+
}, {
|
|
438
|
+
readonly id: "analytics.actions";
|
|
439
|
+
readonly sets: "events";
|
|
440
|
+
readonly ask: "Which actions should be counted?";
|
|
441
|
+
readonly style: "table";
|
|
442
|
+
readonly note: "Propose the few actions that show whether the site is working for the business (a sign-up, an order, a booking, a form sent), each with a name (`thing.past_verb`, lower case: `order.placed`), when it happens in the client's words, and its details. Details are counts, choices and bands (`items`, `plan`, `total_band`), never an email address, a name, a phone number or free text someone typed. The client accepts, removes or adds; an empty list is fine.";
|
|
443
|
+
}];
|
|
444
|
+
readonly not_asked: readonly [{
|
|
445
|
+
readonly sets: "consent";
|
|
446
|
+
readonly why: "The page-view counter sets no cookies and keeps no personal details, and events hold none either, so they add nothing that a cookie notice would need to cover.";
|
|
447
|
+
}, {
|
|
448
|
+
readonly sets: "reports";
|
|
449
|
+
readonly why: "Page views are seen in Cloudflare's Web Analytics, and events are rows in the app's own `events` table; ask what the owner wants to see when they ask for a report.";
|
|
450
|
+
}];
|
|
451
|
+
};
|
|
416
452
|
readonly delivery: {
|
|
417
453
|
readonly choice: "optional";
|
|
418
454
|
readonly intro: "Counting page views and the things visitors do on the site.";
|
|
419
|
-
readonly when: "The client wants to know how many people visit, which pages they open, or to count an action such as a sign-up or an order.";
|
|
420
455
|
};
|
|
421
456
|
};
|
|
422
457
|
readonly config: {
|
|
@@ -565,10 +600,137 @@ export declare const capabilities: {
|
|
|
565
600
|
readonly cost_hint_usd: 0;
|
|
566
601
|
readonly note: "Every pack's spelling is one the Gateway accepts (en-PH, en-AU, en-GB, en-US), checked against the ai manifest's spellings; no Gateway call";
|
|
567
602
|
}];
|
|
603
|
+
readonly offer: {
|
|
604
|
+
readonly pattern: "project";
|
|
605
|
+
readonly when: "The app shows a date, a time, a number, a phone number or an amount of money to its readers, or the client says where their readers are.";
|
|
606
|
+
readonly say: "I'll write dates, times and money with Workbench country formats, the way your readers expect them. That needs to know where they are, once for the whole site.";
|
|
607
|
+
readonly answers_file: "workbench/country.json";
|
|
608
|
+
readonly answers_format: "`{ \"format\": 1, \"country\": \"AU\", \"time_zone\": null, \"currency\": null }`: the country code (or `ZZ`, the package's WORLDWIDE, for readers everywhere), and an IANA time zone or `{ \"code\", \"symbol\" }` currency only when they differ from the country's own (the Australian and US time questions both fill `time_zone`). Then set `READERS` in `src/lib/country.ts` to match: `audiencePack({ country, timeZone, currency })`, leaving out what is null. Every page, email, PDF and form reads `READERS`, so nothing else changes.";
|
|
609
|
+
readonly questions: readonly [{
|
|
610
|
+
readonly id: "country.where";
|
|
611
|
+
readonly sets: "audience.country";
|
|
612
|
+
readonly ask: "Where are most of the site's readers?";
|
|
613
|
+
readonly style: "cards";
|
|
614
|
+
readonly answers: readonly [{
|
|
615
|
+
readonly label: "Australia";
|
|
616
|
+
readonly value: "AU";
|
|
617
|
+
readonly means: "26 September 2026, A$1,400, Sydney time, Australian spelling.";
|
|
618
|
+
}, {
|
|
619
|
+
readonly label: "The Philippines";
|
|
620
|
+
readonly value: "PH";
|
|
621
|
+
readonly means: "September 26, 2026, ₱1,400, Manila time.";
|
|
622
|
+
}, {
|
|
623
|
+
readonly label: "The United Kingdom";
|
|
624
|
+
readonly value: "GB";
|
|
625
|
+
readonly means: "26 September 2026, £1,400, UK time, British spelling.";
|
|
626
|
+
}, {
|
|
627
|
+
readonly label: "The United States";
|
|
628
|
+
readonly value: "US";
|
|
629
|
+
readonly means: "September 26, 2026, US$1,400, Eastern time, American spelling.";
|
|
630
|
+
}];
|
|
631
|
+
readonly other: {
|
|
632
|
+
readonly kind: "text";
|
|
633
|
+
readonly min: 2;
|
|
634
|
+
readonly max: 60;
|
|
635
|
+
readonly description: "Another country, or readers all over the world.";
|
|
636
|
+
};
|
|
637
|
+
readonly note: "Recommend Australia unless the client's words say otherwise. A country with no pack yet, or readers everywhere, gets the neutral one (`ZZ`: 26 September 2026, 24-hour clock, UTC, US$): say so, and ask for the currency.";
|
|
638
|
+
}, {
|
|
639
|
+
readonly id: "country.au-time";
|
|
640
|
+
readonly sets: "audience.time_zone.au";
|
|
641
|
+
readonly ask: "Which Australian time should the site show?";
|
|
642
|
+
readonly style: "cards";
|
|
643
|
+
readonly answers: readonly [{
|
|
644
|
+
readonly label: "Sydney, Melbourne, Canberra";
|
|
645
|
+
readonly value: null;
|
|
646
|
+
readonly means: "The pack's own (Australia/Sydney), with daylight saving.";
|
|
647
|
+
}, {
|
|
648
|
+
readonly label: "Brisbane";
|
|
649
|
+
readonly value: "Australia/Brisbane";
|
|
650
|
+
readonly means: "Queensland, no daylight saving.";
|
|
651
|
+
}, {
|
|
652
|
+
readonly label: "Adelaide";
|
|
653
|
+
readonly value: "Australia/Adelaide";
|
|
654
|
+
readonly means: "South Australia, half an hour behind Sydney.";
|
|
655
|
+
}, {
|
|
656
|
+
readonly label: "Perth";
|
|
657
|
+
readonly value: "Australia/Perth";
|
|
658
|
+
readonly means: "Western Australia.";
|
|
659
|
+
}];
|
|
660
|
+
readonly other: {
|
|
661
|
+
readonly kind: "text";
|
|
662
|
+
readonly min: 5;
|
|
663
|
+
readonly max: 40;
|
|
664
|
+
readonly description: "Another Australian time zone, such as Australia/Darwin or Australia/Hobart.";
|
|
665
|
+
};
|
|
666
|
+
readonly when: {
|
|
667
|
+
readonly id: "country.where";
|
|
668
|
+
readonly is: readonly ["AU"];
|
|
669
|
+
};
|
|
670
|
+
readonly note: "The time zone of the business, where bookings and opening hours happen. Hobart follows Sydney; Darwin is Australia/Darwin.";
|
|
671
|
+
}, {
|
|
672
|
+
readonly id: "country.us-time";
|
|
673
|
+
readonly sets: "audience.time_zone.us";
|
|
674
|
+
readonly ask: "Which US time should the site show?";
|
|
675
|
+
readonly style: "cards";
|
|
676
|
+
readonly answers: readonly [{
|
|
677
|
+
readonly label: "Eastern";
|
|
678
|
+
readonly value: null;
|
|
679
|
+
readonly means: "The pack's own (America/New_York).";
|
|
680
|
+
}, {
|
|
681
|
+
readonly label: "Central";
|
|
682
|
+
readonly value: "America/Chicago";
|
|
683
|
+
}, {
|
|
684
|
+
readonly label: "Mountain";
|
|
685
|
+
readonly value: "America/Denver";
|
|
686
|
+
}, {
|
|
687
|
+
readonly label: "Pacific";
|
|
688
|
+
readonly value: "America/Los_Angeles";
|
|
689
|
+
}];
|
|
690
|
+
readonly other: {
|
|
691
|
+
readonly kind: "text";
|
|
692
|
+
readonly min: 5;
|
|
693
|
+
readonly max: 40;
|
|
694
|
+
readonly description: "Another US time zone, such as America/Phoenix or Pacific/Honolulu.";
|
|
695
|
+
};
|
|
696
|
+
readonly when: {
|
|
697
|
+
readonly id: "country.where";
|
|
698
|
+
readonly is: readonly ["US"];
|
|
699
|
+
};
|
|
700
|
+
readonly note: "The time zone of the business.";
|
|
701
|
+
}, {
|
|
702
|
+
readonly id: "country.currency";
|
|
703
|
+
readonly sets: "audience.currency";
|
|
704
|
+
readonly ask: "Which money are prices in?";
|
|
705
|
+
readonly style: "cards";
|
|
706
|
+
readonly answers: readonly [{
|
|
707
|
+
readonly label: "The country's own";
|
|
708
|
+
readonly value: null;
|
|
709
|
+
readonly means: "A$ in Australia, ₱ in the Philippines, £ in the UK, US$ in the US.";
|
|
710
|
+
}, {
|
|
711
|
+
readonly label: "US dollars";
|
|
712
|
+
readonly value: "USD";
|
|
713
|
+
readonly means: "Shown as US$1,400.";
|
|
714
|
+
}];
|
|
715
|
+
readonly other: {
|
|
716
|
+
readonly kind: "text";
|
|
717
|
+
readonly min: 3;
|
|
718
|
+
readonly max: 3;
|
|
719
|
+
readonly description: "Another currency's three-letter code, such as NZD or EUR.";
|
|
720
|
+
};
|
|
721
|
+
readonly note: "Write a currency other than the country's as `{ \"code\", \"symbol\" }` (NZD is NZ$). Ask it only when the client sells something; otherwise record null.";
|
|
722
|
+
}];
|
|
723
|
+
readonly not_asked: readonly [{
|
|
724
|
+
readonly sets: "audience.format";
|
|
725
|
+
readonly why: "Date order, the clock, number separators, spelling and phone number shapes all come from the country's pack, so they match what readers expect without asking.";
|
|
726
|
+
}, {
|
|
727
|
+
readonly sets: "audience.owner_pages";
|
|
728
|
+
readonly why: "Pages only the owner sees use workbench-ui's own times and money, not the readers'.";
|
|
729
|
+
}];
|
|
730
|
+
};
|
|
568
731
|
readonly delivery: {
|
|
569
732
|
readonly choice: "optional";
|
|
570
733
|
readonly intro: "Dates, times, numbers and money written the way readers in your country expect.";
|
|
571
|
-
readonly when: "The app shows a date, a time, a number, a phone number or an amount of money to its readers, or the client says where their readers are.";
|
|
572
734
|
};
|
|
573
735
|
};
|
|
574
736
|
readonly database: {
|
|
@@ -2636,13 +2798,33 @@ export declare const capabilities: {
|
|
|
2636
2798
|
readonly cost_hint_usd: 0;
|
|
2637
2799
|
readonly note: "In the Worker itself: compares money (US$0.0042, US$12.50, and an en dash for nothing), duration (640 ms, 2.35 s, 3 min 5 s) and timeLeft against a fixed now (42 minutes left) with the expected text, and checks when and shortWhen write one fixed moment as its Manila day and hour with UTC beside it";
|
|
2638
2800
|
}];
|
|
2801
|
+
readonly offer: {
|
|
2802
|
+
readonly pattern: "switch_on";
|
|
2803
|
+
readonly when: "The client wants a page only the owner or the app's admins see: a dashboard, a list, a settings page or a status page.";
|
|
2804
|
+
readonly say: "I'll build this with the Workbench owner-page look, the same top bar, cards and pills as the other admin pages, so it's quick to build and consistent. Your customers never see it.";
|
|
2805
|
+
readonly answers_file: "workbench/ui.json";
|
|
2806
|
+
readonly answers_format: "`{ \"format\": 1, \"pages\": [{ \"path\": \"/admin/orders\", \"what\": \"every order this month, newest first\", \"who\": \"admins\" }] }`. Build each page with `shell`, `topBar`, `card` and `pill`. An `admins` page lives under `/admin/` and checks `requireUser` and `app_admins` (the workbench-sign-in skill); an `owner` page lives under `/owner/` and is behind Access in production.";
|
|
2807
|
+
readonly questions: readonly [{
|
|
2808
|
+
readonly id: "ui.pages";
|
|
2809
|
+
readonly sets: "pages";
|
|
2810
|
+
readonly ask: "Which admin pages should the app have?";
|
|
2811
|
+
readonly style: "table";
|
|
2812
|
+
readonly note: "Propose the pages the request needs, each with its path, what it shows or lets them change in the client's words, and who sees it: `admins` (the business's people, who sign in to the app) or `owner` (whoever runs the app's Workbench, through Access). Recommend `admins` unless the page is about running the app itself, such as a status page. The client accepts, removes or adds pages.";
|
|
2813
|
+
}];
|
|
2814
|
+
readonly not_asked: readonly [{
|
|
2815
|
+
readonly sets: "look";
|
|
2816
|
+
readonly why: "Every admin page has the same Workbench look, so the business's people learn it once. Restyle it in project.css (see Restyling) if the client wants their colours.";
|
|
2817
|
+
}, {
|
|
2818
|
+
readonly sets: "formats";
|
|
2819
|
+
readonly why: "Times, amounts and durations on these pages come from workbench-ui's `when`, `money` and `duration`. What customers see uses the readers' formats (the workbench-country skill).";
|
|
2820
|
+
}];
|
|
2821
|
+
};
|
|
2639
2822
|
readonly styles: {
|
|
2640
2823
|
readonly prefix: "wb-ui-";
|
|
2641
2824
|
};
|
|
2642
2825
|
readonly delivery: {
|
|
2643
2826
|
readonly choice: "optional";
|
|
2644
2827
|
readonly intro: "A ready-made look for the pages only you and your admins see.";
|
|
2645
|
-
readonly when: "The client wants a page only the owner or the app's admins see: a dashboard, a list, a settings page or a status page.";
|
|
2646
2828
|
};
|
|
2647
2829
|
};
|
|
2648
2830
|
};
|
package/dist/capabilities.gen.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by `npm run capabilities:build` from capabilities/*.json. Do not edit.
|
|
2
2
|
// check:capabilities fails in Checks when this file is stale.
|
|
3
|
-
export const MANIFEST_VERSION = "
|
|
3
|
+
export const MANIFEST_VERSION = "b74fc43c59b7";
|
|
4
4
|
export const capabilities = {
|
|
5
5
|
"ai": {
|
|
6
6
|
"$schema": "./schema.json",
|
|
@@ -577,10 +577,54 @@ export const capabilities = {
|
|
|
577
577
|
"note": "Create the site, drive page views, query them back (cf_analytics_query, later)"
|
|
578
578
|
}
|
|
579
579
|
],
|
|
580
|
+
"offer": {
|
|
581
|
+
"pattern": "switch_on",
|
|
582
|
+
"when": "The client wants to know how many people visit, which pages they open, or to count an action such as a sign-up or an order.",
|
|
583
|
+
"say": "The project already has Workbench visitor counts: page views counted by Cloudflare without cookies, and the actions you choose counted in the app's own database. I'll switch on what you want.",
|
|
584
|
+
"answers_file": "workbench/analytics.json",
|
|
585
|
+
"answers_format": "`{ \"format\": 1, \"page_views\": true, \"events\": [{ \"name\": \"order.placed\", \"when\": \"a customer sends an order\", \"details\": [\"items\", \"total_band\"] }] }`. For page views, create the Web Analytics site with Workbench Control (`cf_web_analytics_site_create`), write its beacon token onto staging and production (`cf_worker_secret_put source=web_analytics`), and put `beacon(env)` on every page customers see. For each event, call `eventsFor(db).track(name, details)` where the action happens.",
|
|
586
|
+
"questions": [
|
|
587
|
+
{
|
|
588
|
+
"id": "analytics.page-views",
|
|
589
|
+
"sets": "page_views",
|
|
590
|
+
"ask": "Should the site count its page views?",
|
|
591
|
+
"style": "cards",
|
|
592
|
+
"answers": [
|
|
593
|
+
{
|
|
594
|
+
"label": "Yes",
|
|
595
|
+
"value": true,
|
|
596
|
+
"means": "How many people visit and which pages they open, counted by Cloudflare. No cookies, and no personal details kept."
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
"label": "No",
|
|
600
|
+
"value": false,
|
|
601
|
+
"means": "Nothing is counted on the site's pages."
|
|
602
|
+
}
|
|
603
|
+
],
|
|
604
|
+
"note": "Only pages customers see; never the owner's or admins' pages."
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
"id": "analytics.actions",
|
|
608
|
+
"sets": "events",
|
|
609
|
+
"ask": "Which actions should be counted?",
|
|
610
|
+
"style": "table",
|
|
611
|
+
"note": "Propose the few actions that show whether the site is working for the business (a sign-up, an order, a booking, a form sent), each with a name (`thing.past_verb`, lower case: `order.placed`), when it happens in the client's words, and its details. Details are counts, choices and bands (`items`, `plan`, `total_band`), never an email address, a name, a phone number or free text someone typed. The client accepts, removes or adds; an empty list is fine."
|
|
612
|
+
}
|
|
613
|
+
],
|
|
614
|
+
"not_asked": [
|
|
615
|
+
{
|
|
616
|
+
"sets": "consent",
|
|
617
|
+
"why": "The page-view counter sets no cookies and keeps no personal details, and events hold none either, so they add nothing that a cookie notice would need to cover."
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"sets": "reports",
|
|
621
|
+
"why": "Page views are seen in Cloudflare's Web Analytics, and events are rows in the app's own `events` table; ask what the owner wants to see when they ask for a report."
|
|
622
|
+
}
|
|
623
|
+
]
|
|
624
|
+
},
|
|
580
625
|
"delivery": {
|
|
581
626
|
"choice": "optional",
|
|
582
|
-
"intro": "Counting page views and the things visitors do on the site."
|
|
583
|
-
"when": "The client wants to know how many people visit, which pages they open, or to count an action such as a sign-up or an order."
|
|
627
|
+
"intro": "Counting page views and the things visitors do on the site."
|
|
584
628
|
}
|
|
585
629
|
},
|
|
586
630
|
"config": {
|
|
@@ -796,10 +840,167 @@ export const capabilities = {
|
|
|
796
840
|
"note": "Every pack's spelling is one the Gateway accepts (en-PH, en-AU, en-GB, en-US), checked against the ai manifest's spellings; no Gateway call"
|
|
797
841
|
}
|
|
798
842
|
],
|
|
843
|
+
"offer": {
|
|
844
|
+
"pattern": "project",
|
|
845
|
+
"when": "The app shows a date, a time, a number, a phone number or an amount of money to its readers, or the client says where their readers are.",
|
|
846
|
+
"say": "I'll write dates, times and money with Workbench country formats, the way your readers expect them. That needs to know where they are, once for the whole site.",
|
|
847
|
+
"answers_file": "workbench/country.json",
|
|
848
|
+
"answers_format": "`{ \"format\": 1, \"country\": \"AU\", \"time_zone\": null, \"currency\": null }`: the country code (or `ZZ`, the package's WORLDWIDE, for readers everywhere), and an IANA time zone or `{ \"code\", \"symbol\" }` currency only when they differ from the country's own (the Australian and US time questions both fill `time_zone`). Then set `READERS` in `src/lib/country.ts` to match: `audiencePack({ country, timeZone, currency })`, leaving out what is null. Every page, email, PDF and form reads `READERS`, so nothing else changes.",
|
|
849
|
+
"questions": [
|
|
850
|
+
{
|
|
851
|
+
"id": "country.where",
|
|
852
|
+
"sets": "audience.country",
|
|
853
|
+
"ask": "Where are most of the site's readers?",
|
|
854
|
+
"style": "cards",
|
|
855
|
+
"answers": [
|
|
856
|
+
{
|
|
857
|
+
"label": "Australia",
|
|
858
|
+
"value": "AU",
|
|
859
|
+
"means": "26 September 2026, A$1,400, Sydney time, Australian spelling."
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"label": "The Philippines",
|
|
863
|
+
"value": "PH",
|
|
864
|
+
"means": "September 26, 2026, ₱1,400, Manila time."
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
"label": "The United Kingdom",
|
|
868
|
+
"value": "GB",
|
|
869
|
+
"means": "26 September 2026, £1,400, UK time, British spelling."
|
|
870
|
+
},
|
|
871
|
+
{
|
|
872
|
+
"label": "The United States",
|
|
873
|
+
"value": "US",
|
|
874
|
+
"means": "September 26, 2026, US$1,400, Eastern time, American spelling."
|
|
875
|
+
}
|
|
876
|
+
],
|
|
877
|
+
"other": {
|
|
878
|
+
"kind": "text",
|
|
879
|
+
"min": 2,
|
|
880
|
+
"max": 60,
|
|
881
|
+
"description": "Another country, or readers all over the world."
|
|
882
|
+
},
|
|
883
|
+
"note": "Recommend Australia unless the client's words say otherwise. A country with no pack yet, or readers everywhere, gets the neutral one (`ZZ`: 26 September 2026, 24-hour clock, UTC, US$): say so, and ask for the currency."
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
"id": "country.au-time",
|
|
887
|
+
"sets": "audience.time_zone.au",
|
|
888
|
+
"ask": "Which Australian time should the site show?",
|
|
889
|
+
"style": "cards",
|
|
890
|
+
"answers": [
|
|
891
|
+
{
|
|
892
|
+
"label": "Sydney, Melbourne, Canberra",
|
|
893
|
+
"value": null,
|
|
894
|
+
"means": "The pack's own (Australia/Sydney), with daylight saving."
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
"label": "Brisbane",
|
|
898
|
+
"value": "Australia/Brisbane",
|
|
899
|
+
"means": "Queensland, no daylight saving."
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
"label": "Adelaide",
|
|
903
|
+
"value": "Australia/Adelaide",
|
|
904
|
+
"means": "South Australia, half an hour behind Sydney."
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
"label": "Perth",
|
|
908
|
+
"value": "Australia/Perth",
|
|
909
|
+
"means": "Western Australia."
|
|
910
|
+
}
|
|
911
|
+
],
|
|
912
|
+
"other": {
|
|
913
|
+
"kind": "text",
|
|
914
|
+
"min": 5,
|
|
915
|
+
"max": 40,
|
|
916
|
+
"description": "Another Australian time zone, such as Australia/Darwin or Australia/Hobart."
|
|
917
|
+
},
|
|
918
|
+
"when": {
|
|
919
|
+
"id": "country.where",
|
|
920
|
+
"is": [
|
|
921
|
+
"AU"
|
|
922
|
+
]
|
|
923
|
+
},
|
|
924
|
+
"note": "The time zone of the business, where bookings and opening hours happen. Hobart follows Sydney; Darwin is Australia/Darwin."
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
"id": "country.us-time",
|
|
928
|
+
"sets": "audience.time_zone.us",
|
|
929
|
+
"ask": "Which US time should the site show?",
|
|
930
|
+
"style": "cards",
|
|
931
|
+
"answers": [
|
|
932
|
+
{
|
|
933
|
+
"label": "Eastern",
|
|
934
|
+
"value": null,
|
|
935
|
+
"means": "The pack's own (America/New_York)."
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
"label": "Central",
|
|
939
|
+
"value": "America/Chicago"
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
"label": "Mountain",
|
|
943
|
+
"value": "America/Denver"
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
"label": "Pacific",
|
|
947
|
+
"value": "America/Los_Angeles"
|
|
948
|
+
}
|
|
949
|
+
],
|
|
950
|
+
"other": {
|
|
951
|
+
"kind": "text",
|
|
952
|
+
"min": 5,
|
|
953
|
+
"max": 40,
|
|
954
|
+
"description": "Another US time zone, such as America/Phoenix or Pacific/Honolulu."
|
|
955
|
+
},
|
|
956
|
+
"when": {
|
|
957
|
+
"id": "country.where",
|
|
958
|
+
"is": [
|
|
959
|
+
"US"
|
|
960
|
+
]
|
|
961
|
+
},
|
|
962
|
+
"note": "The time zone of the business."
|
|
963
|
+
},
|
|
964
|
+
{
|
|
965
|
+
"id": "country.currency",
|
|
966
|
+
"sets": "audience.currency",
|
|
967
|
+
"ask": "Which money are prices in?",
|
|
968
|
+
"style": "cards",
|
|
969
|
+
"answers": [
|
|
970
|
+
{
|
|
971
|
+
"label": "The country's own",
|
|
972
|
+
"value": null,
|
|
973
|
+
"means": "A$ in Australia, ₱ in the Philippines, £ in the UK, US$ in the US."
|
|
974
|
+
},
|
|
975
|
+
{
|
|
976
|
+
"label": "US dollars",
|
|
977
|
+
"value": "USD",
|
|
978
|
+
"means": "Shown as US$1,400."
|
|
979
|
+
}
|
|
980
|
+
],
|
|
981
|
+
"other": {
|
|
982
|
+
"kind": "text",
|
|
983
|
+
"min": 3,
|
|
984
|
+
"max": 3,
|
|
985
|
+
"description": "Another currency's three-letter code, such as NZD or EUR."
|
|
986
|
+
},
|
|
987
|
+
"note": "Write a currency other than the country's as `{ \"code\", \"symbol\" }` (NZD is NZ$). Ask it only when the client sells something; otherwise record null."
|
|
988
|
+
}
|
|
989
|
+
],
|
|
990
|
+
"not_asked": [
|
|
991
|
+
{
|
|
992
|
+
"sets": "audience.format",
|
|
993
|
+
"why": "Date order, the clock, number separators, spelling and phone number shapes all come from the country's pack, so they match what readers expect without asking."
|
|
994
|
+
},
|
|
995
|
+
{
|
|
996
|
+
"sets": "audience.owner_pages",
|
|
997
|
+
"why": "Pages only the owner sees use workbench-ui's own times and money, not the readers'."
|
|
998
|
+
}
|
|
999
|
+
]
|
|
1000
|
+
},
|
|
799
1001
|
"delivery": {
|
|
800
1002
|
"choice": "optional",
|
|
801
|
-
"intro": "Dates, times, numbers and money written the way readers in your country expect."
|
|
802
|
-
"when": "The app shows a date, a time, a number, a phone number or an amount of money to its readers, or the client says where their readers are."
|
|
1003
|
+
"intro": "Dates, times, numbers and money written the way readers in your country expect."
|
|
803
1004
|
}
|
|
804
1005
|
},
|
|
805
1006
|
"database": {
|
|
@@ -3505,13 +3706,38 @@ export const capabilities = {
|
|
|
3505
3706
|
"note": "In the Worker itself: compares money (US$0.0042, US$12.50, and an en dash for nothing), duration (640 ms, 2.35 s, 3 min 5 s) and timeLeft against a fixed now (42 minutes left) with the expected text, and checks when and shortWhen write one fixed moment as its Manila day and hour with UTC beside it"
|
|
3506
3707
|
}
|
|
3507
3708
|
],
|
|
3709
|
+
"offer": {
|
|
3710
|
+
"pattern": "switch_on",
|
|
3711
|
+
"when": "The client wants a page only the owner or the app's admins see: a dashboard, a list, a settings page or a status page.",
|
|
3712
|
+
"say": "I'll build this with the Workbench owner-page look, the same top bar, cards and pills as the other admin pages, so it's quick to build and consistent. Your customers never see it.",
|
|
3713
|
+
"answers_file": "workbench/ui.json",
|
|
3714
|
+
"answers_format": "`{ \"format\": 1, \"pages\": [{ \"path\": \"/admin/orders\", \"what\": \"every order this month, newest first\", \"who\": \"admins\" }] }`. Build each page with `shell`, `topBar`, `card` and `pill`. An `admins` page lives under `/admin/` and checks `requireUser` and `app_admins` (the workbench-sign-in skill); an `owner` page lives under `/owner/` and is behind Access in production.",
|
|
3715
|
+
"questions": [
|
|
3716
|
+
{
|
|
3717
|
+
"id": "ui.pages",
|
|
3718
|
+
"sets": "pages",
|
|
3719
|
+
"ask": "Which admin pages should the app have?",
|
|
3720
|
+
"style": "table",
|
|
3721
|
+
"note": "Propose the pages the request needs, each with its path, what it shows or lets them change in the client's words, and who sees it: `admins` (the business's people, who sign in to the app) or `owner` (whoever runs the app's Workbench, through Access). Recommend `admins` unless the page is about running the app itself, such as a status page. The client accepts, removes or adds pages."
|
|
3722
|
+
}
|
|
3723
|
+
],
|
|
3724
|
+
"not_asked": [
|
|
3725
|
+
{
|
|
3726
|
+
"sets": "look",
|
|
3727
|
+
"why": "Every admin page has the same Workbench look, so the business's people learn it once. Restyle it in project.css (see Restyling) if the client wants their colours."
|
|
3728
|
+
},
|
|
3729
|
+
{
|
|
3730
|
+
"sets": "formats",
|
|
3731
|
+
"why": "Times, amounts and durations on these pages come from workbench-ui's `when`, `money` and `duration`. What customers see uses the readers' formats (the workbench-country skill)."
|
|
3732
|
+
}
|
|
3733
|
+
]
|
|
3734
|
+
},
|
|
3508
3735
|
"styles": {
|
|
3509
3736
|
"prefix": "wb-ui-"
|
|
3510
3737
|
},
|
|
3511
3738
|
"delivery": {
|
|
3512
3739
|
"choice": "optional",
|
|
3513
|
-
"intro": "A ready-made look for the pages only you and your admins see."
|
|
3514
|
-
"when": "The client wants a page only the owner or the app's admins see: a dashboard, a list, a settings page or a status page."
|
|
3740
|
+
"intro": "A ready-made look for the pages only you and your admins see."
|
|
3515
3741
|
}
|
|
3516
3742
|
}
|
|
3517
3743
|
};
|
|
@@ -401,7 +401,7 @@ export type Offer = z.infer<typeof offer>;
|
|
|
401
401
|
* 11 November 2026: every shared tool ships its questions). The list only
|
|
402
402
|
* shrinks; a new component can't join it.
|
|
403
403
|
*/
|
|
404
|
-
export declare const OFFER_PENDING: readonly ["
|
|
404
|
+
export declare const OFFER_PENDING: readonly ["database", "email", "email-inbound", "strings"];
|
|
405
405
|
export interface ManifestProblem {
|
|
406
406
|
file: string;
|
|
407
407
|
check: "schema" | "proof" | "ids" | "surfaces" | "errors" | "generated";
|
|
@@ -267,7 +267,7 @@ export const capabilitySchema = z.strictObject(baseShape).superRefine((m, ctx) =
|
|
|
267
267
|
* 11 November 2026: every shared tool ships its questions). The list only
|
|
268
268
|
* shrinks; a new component can't join it.
|
|
269
269
|
*/
|
|
270
|
-
export const OFFER_PENDING = ["
|
|
270
|
+
export const OFFER_PENDING = ["database", "email", "email-inbound", "strings"];
|
|
271
271
|
function checkOffer(file, component, o, seen) {
|
|
272
272
|
const problems = [];
|
|
273
273
|
const named = new Map();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mccaskie-labs/workbench-config",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Workbench app configuration: WORKBENCH_ENV, typed variables that fail by name, secrets that are never printed, and the capabilities manifest.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|