@aglyn/plugins-commerce 1.0.0-beta.243 → 1.0.0-beta.246

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 (57) hide show
  1. package/README.md +4 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/commerce-console-page.js +10 -0
  4. package/src/lib/components/commerce-console-page.js.map +1 -1
  5. package/src/lib/components/console/product-zones.d.ts +7 -1
  6. package/src/lib/components/console/product-zones.js.map +1 -1
  7. package/src/lib/components/console/products-hub-zone.component.d.ts +3 -2
  8. package/src/lib/components/console/products-hub-zone.component.js +9 -1
  9. package/src/lib/components/console/products-hub-zone.component.js.map +1 -1
  10. package/src/lib/components/console/review-settings-card.component.d.ts +14 -0
  11. package/src/lib/components/console/review-settings-card.component.js +168 -0
  12. package/src/lib/components/console/review-settings-card.component.js.map +1 -0
  13. package/src/lib/components/console/reviews-moderation-card.component.d.ts +14 -0
  14. package/src/lib/components/console/reviews-moderation-card.component.js +85 -11
  15. package/src/lib/components/console/reviews-moderation-card.component.js.map +1 -1
  16. package/src/lib/components/product-reviews.d.ts +29 -1
  17. package/src/lib/components/product-reviews.js +97 -12
  18. package/src/lib/components/product-reviews.js.map +1 -1
  19. package/src/lib/model/commerce.d.ts +11 -2
  20. package/src/lib/model/commerce.js +14 -2
  21. package/src/lib/model/commerce.js.map +1 -1
  22. package/src/lib/model/index.d.ts +1 -0
  23. package/src/lib/model/index.js +1 -0
  24. package/src/lib/model/index.js.map +1 -1
  25. package/src/lib/model/product-reviews.d.ts +124 -0
  26. package/src/lib/model/product-reviews.js +133 -0
  27. package/src/lib/model/product-reviews.js.map +1 -0
  28. package/src/lib/model/store-setup-content.d.ts +145 -0
  29. package/src/lib/model/store-setup-content.js +813 -0
  30. package/src/lib/model/store-setup-content.js.map +1 -0
  31. package/src/lib/server/membership-reset.js +8 -2
  32. package/src/lib/server/membership-reset.js.map +1 -1
  33. package/src/lib/server/order-event-triggers.d.ts +2 -0
  34. package/src/lib/server/order-event-triggers.js +18 -1
  35. package/src/lib/server/order-event-triggers.js.map +1 -1
  36. package/src/lib/server/review-requests.d.ts +102 -0
  37. package/src/lib/server/review-requests.js +346 -0
  38. package/src/lib/server/review-requests.js.map +1 -0
  39. package/src/lib/server/review-tokens.d.ts +82 -0
  40. package/src/lib/server/review-tokens.js +119 -0
  41. package/src/lib/server/review-tokens.js.map +1 -0
  42. package/src/lib/server/reviews.d.ts +36 -3
  43. package/src/lib/server/reviews.js +310 -52
  44. package/src/lib/server/reviews.js.map +1 -1
  45. package/src/lib/server/store-setup-ai-capability.d.ts +61 -0
  46. package/src/lib/server/store-setup-ai-capability.js +343 -0
  47. package/src/lib/server/store-setup-ai-capability.js.map +1 -0
  48. package/src/lib/server/store-setup-ai-writer.console.d.ts +27 -0
  49. package/src/lib/server/store-setup-ai-writer.console.js +44 -0
  50. package/src/lib/server/store-setup-ai-writer.console.js.map +1 -0
  51. package/src/lib/server/store-setup-ai-writer.d.ts +37 -0
  52. package/src/lib/server/store-setup-ai-writer.js +174 -0
  53. package/src/lib/server/store-setup-ai-writer.js.map +1 -0
  54. package/src/lib/server.js +27 -0
  55. package/src/lib/server.js.map +1 -1
  56. package/src/lib/tenant-emails.js +58 -0
  57. package/src/lib/tenant-emails.js.map +1 -1
@@ -0,0 +1,343 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { registerPluginAiCapability } from "@aglyn/aglyn/plugin-manager/plugin-ai-capabilities";
18
+ import { BUNDLE_ID } from "../constants/bundle-common.js";
19
+ import { COMMERCE_MAX_PRICE_USD } from "../model/commerce.js";
20
+ import { LOCAL_DELIVERY_POSTCODES_MAX, PICKUP_HOURS_MAX, PICKUP_INSTRUCTIONS_MAX } from "../model/local-fulfillment-settings.js";
21
+ import { STORE_SETUP_COUNTRIES_MAX, STORE_SETUP_LOCATION_MAX, STORE_SETUP_MAX_MINUTES, STORE_SETUP_NAME_MAX, STORE_SETUP_RESOURCE, STORE_SHIPPING_ACTIONS, STORE_SHIPPING_AI_KINDS, STORE_SHIPPING_TIERS_MAX, STORE_TAX_LABEL_MAX, STORE_TAX_MODES } from "../model/store-setup-content.js";
22
+ /**
23
+ * WHAT AN AI BUILD CAN SET UP IN A STORE (AGL-3749): shipping zones and
24
+ * rates, local pickup, local delivery and sales tax — "free shipping over $50,
25
+ * otherwise $5 flat in the US", "offer local pickup at our Austin shop",
26
+ * "charge 8.25% Texas sales tax".
27
+ *
28
+ * Four operations the AI plugin's build planner offers, all written by this
29
+ * plugin's `store-settings` writer (`store-setup-ai-writer.ts`), so every
30
+ * change is the console cards' own: the role that may save them, the plan's
31
+ * `commerce` feature, lockdown, and the cards' normalizers and checks. No
32
+ * model runs: the planner fills the arguments and they ARE the change, so an
33
+ * item costs no credits.
34
+ *
35
+ * NEVER A NUMBER THE PERSON DID NOT GIVE. A blank flat rate charges nothing
36
+ * and a tax rate is the merchant's legal call, so every amount and
37
+ * percentage is "only when the request states it", and the writer refuses a
38
+ * rate without one. A request to "set up tax" that says neither how nor what
39
+ * rate is left out of the plan rather than guessed at.
40
+ *
41
+ * NEVER AN ACCOUNT. Carrier rates, label services and outside tax services
42
+ * need a person to connect an account; none of them is offered here.
43
+ *
44
+ * Settings are live once written: the cards save them live, and a store
45
+ * setting has no draft. `live` (the contract's flag, AGL-3745) tells the
46
+ * build step so, and the job reports the change as live.
47
+ * Free has no commerce, so a Free workspace's build is never offered one.
48
+ */ export const STORE_SHIPPING_AI_OP = 'store-shipping';
49
+ export const STORE_PICKUP_AI_OP = 'store-pickup';
50
+ export const STORE_DELIVERY_AI_OP = 'store-delivery';
51
+ export const STORE_TAX_AI_OP = 'store-tax';
52
+ /** Where a person finds what the build set. */ const WHERE = 'Products → Settings';
53
+ /** The writer's content for an item: its arguments, tagged with the section its op changes. */ export function storeSetupContentFromArgs(section, args) {
54
+ const content = {
55
+ section
56
+ };
57
+ for (const [key, value] of Object.entries(args)){
58
+ if (value === undefined || value === null || value === '') continue;
59
+ content[key] = value;
60
+ }
61
+ return content;
62
+ }
63
+ const STATED = 'ONLY when the request states it; never a typical or suggested amount.';
64
+ /** What every store-setup operation shares. */ function storeSetupCapability(op, section, rest) {
65
+ return _extends({
66
+ op,
67
+ where: WHERE
68
+ }, rest, {
69
+ // Free includes no commerce.
70
+ freeAllowed: false,
71
+ feature: 'commerce',
72
+ draftResource: STORE_SETUP_RESOURCE,
73
+ live: true,
74
+ // Written without a model: the planner already filled the arguments.
75
+ estimateCredits: ()=>0,
76
+ degrade: 'omit',
77
+ draftContent: (item)=>storeSetupContentFromArgs(section, item.args)
78
+ });
79
+ }
80
+ export const storeShippingAiCapability = storeSetupCapability(STORE_SHIPPING_AI_OP, 'shipping', {
81
+ noun: 'shipping rate',
82
+ intents: [
83
+ 'store shipping: a shipping zone (countries) and its rate — flat, free over an order total, or tiered by order total or weight; change or remove a rate or zone. Live once the build runs. Amounts only as the request states them'
84
+ ],
85
+ argsSchema: {
86
+ type: 'object',
87
+ properties: {
88
+ action: {
89
+ type: 'string',
90
+ description: 'set (the default) adds or replaces the rate named rateName in the zone; remove deletes that rate, or the whole zone and its rates when rateName is left out.',
91
+ enum: STORE_SHIPPING_ACTIONS
92
+ },
93
+ zoneName: {
94
+ type: 'string',
95
+ description: 'The shipping zone, e.g. "United States" or "Rest of world". An existing zone is matched by this name or by the same countries.',
96
+ maxLength: STORE_SETUP_NAME_MAX
97
+ },
98
+ countries: {
99
+ type: 'array',
100
+ description: 'Two-letter country codes the zone ships to (["US"], ["US","CA"]), or ["*"] for everywhere no other zone names. Required for a new zone.',
101
+ items: {
102
+ type: 'string',
103
+ maxLength: 2
104
+ },
105
+ maxItems: STORE_SETUP_COUNTRIES_MAX
106
+ },
107
+ rateName: {
108
+ type: 'string',
109
+ description: 'What the shopper sees at checkout, e.g. "Standard". Required for set.',
110
+ maxLength: STORE_SETUP_NAME_MAX
111
+ },
112
+ kind: {
113
+ type: 'string',
114
+ description: 'flat: one price. free_over: free at or above an order subtotal, otherwise amountUsd. price_tiers: priced by order subtotal. weight_tiers: priced by parcel weight in grams. Required for set.',
115
+ enum: STORE_SHIPPING_AI_KINDS
116
+ },
117
+ amountUsd: {
118
+ type: 'number',
119
+ description: `flat: the price; free_over: the price below the threshold. In dollars, 0 for free. ${STATED}`,
120
+ minimum: 0,
121
+ maximum: COMMERCE_MAX_PRICE_USD
122
+ },
123
+ freeOverUsd: {
124
+ type: 'number',
125
+ description: `free_over: the order subtotal in dollars at which shipping becomes free. ${STATED}`,
126
+ minimum: 0,
127
+ maximum: COMMERCE_MAX_PRICE_USD
128
+ },
129
+ tiers: {
130
+ type: 'array',
131
+ description: `price_tiers and weight_tiers: "upTo:price" entries — upTo is the subtotal in dollars (price_tiers) or grams (weight_tiers), price in dollars, e.g. ["50:5", "100:8"]. A larger order than the last tier gets no rate from it. ${STATED}`,
132
+ items: {
133
+ type: 'string',
134
+ maxLength: 24
135
+ },
136
+ maxItems: STORE_SHIPPING_TIERS_MAX
137
+ }
138
+ },
139
+ required: [
140
+ 'zoneName'
141
+ ],
142
+ additionalProperties: false
143
+ },
144
+ maxPerPlan: 10
145
+ });
146
+ export const storePickupAiCapability = storeSetupCapability(STORE_PICKUP_AI_OP, 'pickup', {
147
+ noun: 'pickup setting',
148
+ intents: [
149
+ 'store local pickup: let buyers collect orders free, at the store or at a named store location with its pickup hours and arrival instructions; switch pickup off. Live once the build runs'
150
+ ],
151
+ argsSchema: {
152
+ type: 'object',
153
+ properties: {
154
+ location: {
155
+ type: 'string',
156
+ description: 'The store location buyers collect from — its name, city or street, e.g. "Austin" — which must already be one of the store’s inventory locations. Leave out for a plain "Local pickup" choice at checkout with no location.',
157
+ maxLength: STORE_SETUP_LOCATION_MAX
158
+ },
159
+ enabled: {
160
+ type: 'boolean',
161
+ description: 'false to stop offering pickup; leave out to offer it.'
162
+ },
163
+ hours: {
164
+ type: 'string',
165
+ description: 'With location: pickup hours as the request gives them, one set of days per line or separated by ";", e.g. "Mo-Fr 09:00-17:00; Sa 10:00-14:00".',
166
+ maxLength: PICKUP_HOURS_MAX
167
+ },
168
+ instructions: {
169
+ type: 'string',
170
+ description: 'With location: what the buyer does on arrival, as the request says it.',
171
+ maxLength: PICKUP_INSTRUCTIONS_MAX
172
+ },
173
+ readyWithinMinutes: {
174
+ type: 'integer',
175
+ description: 'With location: how long an order usually takes to prepare, in minutes, when the request says.',
176
+ minimum: 0,
177
+ maximum: STORE_SETUP_MAX_MINUTES
178
+ }
179
+ },
180
+ additionalProperties: false
181
+ },
182
+ maxPerPlan: 5
183
+ });
184
+ export const storeDeliveryAiCapability = storeSetupCapability(STORE_DELIVERY_AI_OP, 'local-delivery', {
185
+ noun: 'local delivery setting',
186
+ intents: [
187
+ 'store local delivery the merchant does themselves: delivery zones by postal code with a fee, a minimum and a free-over amount, delivery windows and instructions; switch it off. Live once the build runs. Fees only as the request states them'
188
+ ],
189
+ argsSchema: {
190
+ type: 'object',
191
+ properties: {
192
+ enabled: {
193
+ type: 'boolean',
194
+ description: 'false to stop offering local delivery; leave out to offer it.'
195
+ },
196
+ country: {
197
+ type: 'string',
198
+ description: 'The two-letter country the store delivers within, e.g. US.',
199
+ maxLength: 2
200
+ },
201
+ location: {
202
+ type: 'string',
203
+ description: 'The inventory location orders leave from, by name or city, when the request names one.',
204
+ maxLength: STORE_SETUP_LOCATION_MAX
205
+ },
206
+ zoneName: {
207
+ type: 'string',
208
+ description: 'The delivery zone to add, change or remove, e.g. "Downtown".',
209
+ maxLength: STORE_SETUP_NAME_MAX
210
+ },
211
+ postcodes: {
212
+ type: 'array',
213
+ description: 'The zone’s postal codes: exact ("78701"), a prefix ("787*") or a range ("78701-78705"). Required for a new zone.',
214
+ items: {
215
+ type: 'string',
216
+ maxLength: 24
217
+ },
218
+ maxItems: LOCAL_DELIVERY_POSTCODES_MAX
219
+ },
220
+ feeUsd: {
221
+ type: 'number',
222
+ description: `The zone’s delivery fee in dollars, 0 for free. Required for a new zone. ${STATED}`,
223
+ minimum: 0,
224
+ maximum: COMMERCE_MAX_PRICE_USD
225
+ },
226
+ minimumUsd: {
227
+ type: 'number',
228
+ description: `The smallest order the zone delivers, in dollars. ${STATED}`,
229
+ minimum: 0,
230
+ maximum: COMMERCE_MAX_PRICE_USD
231
+ },
232
+ freeOverUsd: {
233
+ type: 'number',
234
+ description: `Order total in dollars at which delivery is free. ${STATED}`,
235
+ minimum: 0,
236
+ maximum: COMMERCE_MAX_PRICE_USD
237
+ },
238
+ removeZone: {
239
+ type: 'boolean',
240
+ description: 'true to remove the zone named zoneName.'
241
+ },
242
+ windows: {
243
+ type: 'string',
244
+ description: 'Delivery windows as the request gives them, e.g. "Mo-Fr 09:00-12:00; Sa 10:00-14:00". Delivery is offered only with at least one window.',
245
+ maxLength: PICKUP_HOURS_MAX
246
+ },
247
+ leadTimeMinutes: {
248
+ type: 'integer',
249
+ description: 'How long before a window an order must be placed, in minutes, when the request says.',
250
+ minimum: 0,
251
+ maximum: STORE_SETUP_MAX_MINUTES
252
+ },
253
+ daysAhead: {
254
+ type: 'integer',
255
+ description: 'How many days ahead a window can be booked (1 to 30), when the request says.',
256
+ minimum: 1,
257
+ maximum: 30
258
+ },
259
+ instructions: {
260
+ type: 'string',
261
+ description: 'What the buyer is told about delivery, as the request says it.',
262
+ maxLength: PICKUP_INSTRUCTIONS_MAX
263
+ }
264
+ },
265
+ additionalProperties: false
266
+ },
267
+ maxPerPlan: 5
268
+ });
269
+ export const storeTaxAiCapability = storeSetupCapability(STORE_TAX_AI_OP, 'tax', {
270
+ noun: 'tax setting',
271
+ intents: [
272
+ 'store sales tax: collect it at the manual rate the request states for a country or state, calculate it automatically, or not collect it; whether prices include tax; where the store sells from. Live once the build runs. Never a rate the request does not state — "set up tax" alone is a question back, not an item'
273
+ ],
274
+ argsSchema: {
275
+ type: 'object',
276
+ properties: {
277
+ mode: {
278
+ type: 'string',
279
+ description: 'manual: the rates the merchant states. stripe: automatic calculation per buyer location, ONLY when the request asks for automatic tax. none: the store does not collect sales tax, ONLY when the request says so. Leave out to keep the store’s choice.',
280
+ enum: STORE_TAX_MODES
281
+ },
282
+ pricesIncludeTax: {
283
+ type: 'boolean',
284
+ description: 'true when the request says prices already include tax (VAT-style); false when it says tax is added on top.'
285
+ },
286
+ originCountry: {
287
+ type: 'string',
288
+ description: 'The two-letter country the store sells from, e.g. US. Manual rates need it.',
289
+ maxLength: 2
290
+ },
291
+ originState: {
292
+ type: 'string',
293
+ description: 'The state or region the store sells from, e.g. TX.',
294
+ maxLength: 3
295
+ },
296
+ rateCountry: {
297
+ type: 'string',
298
+ description: 'The two-letter country a tax rate applies to.',
299
+ maxLength: 2
300
+ },
301
+ rateState: {
302
+ type: 'string',
303
+ description: 'The state or region a tax rate applies to, e.g. TX; leave out for the whole country.',
304
+ maxLength: 3
305
+ },
306
+ ratePercent: {
307
+ type: 'number',
308
+ description: `The tax rate in percent, e.g. 8.25. ${STATED}`,
309
+ minimum: 0,
310
+ maximum: 100
311
+ },
312
+ rateLabel: {
313
+ type: 'string',
314
+ description: 'The receipt label, e.g. "TX sales tax".',
315
+ maxLength: STORE_TAX_LABEL_MAX
316
+ },
317
+ removeRate: {
318
+ type: 'boolean',
319
+ description: 'true to remove the rate for rateCountry (and rateState).'
320
+ }
321
+ },
322
+ additionalProperties: false
323
+ },
324
+ maxPerPlan: 6
325
+ });
326
+ export const STORE_SETUP_AI_CAPABILITIES = [
327
+ storeShippingAiCapability,
328
+ storePickupAiCapability,
329
+ storeDeliveryAiCapability,
330
+ storeTaxAiCapability
331
+ ];
332
+ /**
333
+ * Registers the four operations; the console surface calls it beside the
334
+ * writer, since only the console runs AI jobs (AGL-3026). Idempotent.
335
+ */ export function registerStoreSetupAiCapabilities() {
336
+ for (const capability of STORE_SETUP_AI_CAPABILITIES){
337
+ registerPluginAiCapability(capability, {
338
+ pluginId: BUNDLE_ID
339
+ });
340
+ }
341
+ }
342
+
343
+ //# sourceMappingURL=store-setup-ai-capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/store-setup-ai-capability.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n registerPluginAiCapability,\n type PluginAiCapability,\n type PluginAiCapabilityArgs,\n} from '@aglyn/aglyn/plugin-manager/plugin-ai-capabilities'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { COMMERCE_MAX_PRICE_USD } from '../model/commerce'\nimport {\n LOCAL_DELIVERY_POSTCODES_MAX,\n PICKUP_HOURS_MAX,\n PICKUP_INSTRUCTIONS_MAX,\n} from '../model/local-fulfillment-settings'\nimport {\n STORE_SETUP_COUNTRIES_MAX,\n STORE_SETUP_LOCATION_MAX,\n STORE_SETUP_MAX_MINUTES,\n STORE_SETUP_NAME_MAX,\n STORE_SETUP_RESOURCE,\n STORE_SHIPPING_ACTIONS,\n STORE_SHIPPING_AI_KINDS,\n STORE_SHIPPING_TIERS_MAX,\n STORE_TAX_LABEL_MAX,\n STORE_TAX_MODES,\n type StoreSetupSection,\n} from '../model/store-setup-content'\n\n/**\n * WHAT AN AI BUILD CAN SET UP IN A STORE (AGL-3749): shipping zones and\n * rates, local pickup, local delivery and sales tax — \"free shipping over $50,\n * otherwise $5 flat in the US\", \"offer local pickup at our Austin shop\",\n * \"charge 8.25% Texas sales tax\".\n *\n * Four operations the AI plugin's build planner offers, all written by this\n * plugin's `store-settings` writer (`store-setup-ai-writer.ts`), so every\n * change is the console cards' own: the role that may save them, the plan's\n * `commerce` feature, lockdown, and the cards' normalizers and checks. No\n * model runs: the planner fills the arguments and they ARE the change, so an\n * item costs no credits.\n *\n * NEVER A NUMBER THE PERSON DID NOT GIVE. A blank flat rate charges nothing\n * and a tax rate is the merchant's legal call, so every amount and\n * percentage is \"only when the request states it\", and the writer refuses a\n * rate without one. A request to \"set up tax\" that says neither how nor what\n * rate is left out of the plan rather than guessed at.\n *\n * NEVER AN ACCOUNT. Carrier rates, label services and outside tax services\n * need a person to connect an account; none of them is offered here.\n *\n * Settings are live once written: the cards save them live, and a store\n * setting has no draft. `live` (the contract's flag, AGL-3745) tells the\n * build step so, and the job reports the change as live.\n * Free has no commerce, so a Free workspace's build is never offered one.\n */\n\nexport const STORE_SHIPPING_AI_OP = 'store-shipping'\nexport const STORE_PICKUP_AI_OP = 'store-pickup'\nexport const STORE_DELIVERY_AI_OP = 'store-delivery'\nexport const STORE_TAX_AI_OP = 'store-tax'\n\n/** Where a person finds what the build set. */\nconst WHERE = 'Products → Settings'\n\n/** The writer's content for an item: its arguments, tagged with the section its op changes. */\nexport function storeSetupContentFromArgs(\n section: StoreSetupSection,\n args: PluginAiCapabilityArgs,\n): Readonly<Record<string, unknown>> {\n const content: Record<string, unknown> = { section }\n for (const [key, value] of Object.entries(args)) {\n if (value === undefined || value === null || value === '') continue\n content[key] = value\n }\n return content\n}\n\nconst STATED = 'ONLY when the request states it; never a typical or suggested amount.'\n\n/** What every store-setup operation shares. */\nfunction storeSetupCapability(\n op: string,\n section: StoreSetupSection,\n rest: Pick<PluginAiCapability, 'noun' | 'intents' | 'argsSchema' | 'maxPerPlan'>,\n): PluginAiCapability {\n return {\n op,\n where: WHERE,\n ...rest,\n // Free includes no commerce.\n freeAllowed: false,\n feature: 'commerce',\n draftResource: STORE_SETUP_RESOURCE,\n live: true,\n // Written without a model: the planner already filled the arguments.\n estimateCredits: () => 0,\n degrade: 'omit',\n draftContent: (item) => storeSetupContentFromArgs(section, item.args),\n }\n}\n\nexport const storeShippingAiCapability = storeSetupCapability(STORE_SHIPPING_AI_OP, 'shipping', {\n noun: 'shipping rate',\n intents: [\n 'store shipping: a shipping zone (countries) and its rate — flat, free over an order total, or tiered by order total or weight; change or remove a rate or zone. Live once the build runs. Amounts only as the request states them',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n description: 'set (the default) adds or replaces the rate named rateName in the zone; remove deletes that rate, or the whole zone and its rates when rateName is left out.',\n enum: STORE_SHIPPING_ACTIONS,\n },\n zoneName: {\n type: 'string',\n description: 'The shipping zone, e.g. \"United States\" or \"Rest of world\". An existing zone is matched by this name or by the same countries.',\n maxLength: STORE_SETUP_NAME_MAX,\n },\n countries: {\n type: 'array',\n description: 'Two-letter country codes the zone ships to ([\"US\"], [\"US\",\"CA\"]), or [\"*\"] for everywhere no other zone names. Required for a new zone.',\n items: { type: 'string', maxLength: 2 },\n maxItems: STORE_SETUP_COUNTRIES_MAX,\n },\n rateName: {\n type: 'string',\n description: 'What the shopper sees at checkout, e.g. \"Standard\". Required for set.',\n maxLength: STORE_SETUP_NAME_MAX,\n },\n kind: {\n type: 'string',\n description:\n 'flat: one price. free_over: free at or above an order subtotal, otherwise amountUsd. price_tiers: priced by order subtotal. weight_tiers: priced by parcel weight in grams. Required for set.',\n enum: STORE_SHIPPING_AI_KINDS,\n },\n amountUsd: {\n type: 'number',\n description: `flat: the price; free_over: the price below the threshold. In dollars, 0 for free. ${STATED}`,\n minimum: 0,\n maximum: COMMERCE_MAX_PRICE_USD,\n },\n freeOverUsd: {\n type: 'number',\n description: `free_over: the order subtotal in dollars at which shipping becomes free. ${STATED}`,\n minimum: 0,\n maximum: COMMERCE_MAX_PRICE_USD,\n },\n tiers: {\n type: 'array',\n description: `price_tiers and weight_tiers: \"upTo:price\" entries — upTo is the subtotal in dollars (price_tiers) or grams (weight_tiers), price in dollars, e.g. [\"50:5\", \"100:8\"]. A larger order than the last tier gets no rate from it. ${STATED}`,\n items: { type: 'string', maxLength: 24 },\n maxItems: STORE_SHIPPING_TIERS_MAX,\n },\n },\n required: ['zoneName'],\n additionalProperties: false,\n },\n maxPerPlan: 10,\n})\n\nexport const storePickupAiCapability = storeSetupCapability(STORE_PICKUP_AI_OP, 'pickup', {\n noun: 'pickup setting',\n intents: [\n 'store local pickup: let buyers collect orders free, at the store or at a named store location with its pickup hours and arrival instructions; switch pickup off. Live once the build runs',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n location: {\n type: 'string',\n description:\n 'The store location buyers collect from — its name, city or street, e.g. \"Austin\" — which must already be one of the store’s inventory locations. Leave out for a plain \"Local pickup\" choice at checkout with no location.',\n maxLength: STORE_SETUP_LOCATION_MAX,\n },\n enabled: { type: 'boolean', description: 'false to stop offering pickup; leave out to offer it.' },\n hours: {\n type: 'string',\n description: 'With location: pickup hours as the request gives them, one set of days per line or separated by \";\", e.g. \"Mo-Fr 09:00-17:00; Sa 10:00-14:00\".',\n maxLength: PICKUP_HOURS_MAX,\n },\n instructions: {\n type: 'string',\n description: 'With location: what the buyer does on arrival, as the request says it.',\n maxLength: PICKUP_INSTRUCTIONS_MAX,\n },\n readyWithinMinutes: {\n type: 'integer',\n description: 'With location: how long an order usually takes to prepare, in minutes, when the request says.',\n minimum: 0,\n maximum: STORE_SETUP_MAX_MINUTES,\n },\n },\n additionalProperties: false,\n },\n maxPerPlan: 5,\n})\n\nexport const storeDeliveryAiCapability = storeSetupCapability(STORE_DELIVERY_AI_OP, 'local-delivery', {\n noun: 'local delivery setting',\n intents: [\n 'store local delivery the merchant does themselves: delivery zones by postal code with a fee, a minimum and a free-over amount, delivery windows and instructions; switch it off. Live once the build runs. Fees only as the request states them',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n enabled: { type: 'boolean', description: 'false to stop offering local delivery; leave out to offer it.' },\n country: { type: 'string', description: 'The two-letter country the store delivers within, e.g. US.', maxLength: 2 },\n location: {\n type: 'string',\n description: 'The inventory location orders leave from, by name or city, when the request names one.',\n maxLength: STORE_SETUP_LOCATION_MAX,\n },\n zoneName: {\n type: 'string',\n description: 'The delivery zone to add, change or remove, e.g. \"Downtown\".',\n maxLength: STORE_SETUP_NAME_MAX,\n },\n postcodes: {\n type: 'array',\n description: 'The zone’s postal codes: exact (\"78701\"), a prefix (\"787*\") or a range (\"78701-78705\"). Required for a new zone.',\n items: { type: 'string', maxLength: 24 },\n maxItems: LOCAL_DELIVERY_POSTCODES_MAX,\n },\n feeUsd: {\n type: 'number',\n description: `The zone’s delivery fee in dollars, 0 for free. Required for a new zone. ${STATED}`,\n minimum: 0,\n maximum: COMMERCE_MAX_PRICE_USD,\n },\n minimumUsd: { type: 'number', description: `The smallest order the zone delivers, in dollars. ${STATED}`, minimum: 0, maximum: COMMERCE_MAX_PRICE_USD },\n freeOverUsd: { type: 'number', description: `Order total in dollars at which delivery is free. ${STATED}`, minimum: 0, maximum: COMMERCE_MAX_PRICE_USD },\n removeZone: { type: 'boolean', description: 'true to remove the zone named zoneName.' },\n windows: {\n type: 'string',\n description: 'Delivery windows as the request gives them, e.g. \"Mo-Fr 09:00-12:00; Sa 10:00-14:00\". Delivery is offered only with at least one window.',\n maxLength: PICKUP_HOURS_MAX,\n },\n leadTimeMinutes: {\n type: 'integer',\n description: 'How long before a window an order must be placed, in minutes, when the request says.',\n minimum: 0,\n maximum: STORE_SETUP_MAX_MINUTES,\n },\n daysAhead: { type: 'integer', description: 'How many days ahead a window can be booked (1 to 30), when the request says.', minimum: 1, maximum: 30 },\n instructions: { type: 'string', description: 'What the buyer is told about delivery, as the request says it.', maxLength: PICKUP_INSTRUCTIONS_MAX },\n },\n additionalProperties: false,\n },\n maxPerPlan: 5,\n})\n\nexport const storeTaxAiCapability = storeSetupCapability(STORE_TAX_AI_OP, 'tax', {\n noun: 'tax setting',\n intents: [\n 'store sales tax: collect it at the manual rate the request states for a country or state, calculate it automatically, or not collect it; whether prices include tax; where the store sells from. Live once the build runs. Never a rate the request does not state — \"set up tax\" alone is a question back, not an item',\n ],\n argsSchema: {\n type: 'object',\n properties: {\n mode: {\n type: 'string',\n description:\n 'manual: the rates the merchant states. stripe: automatic calculation per buyer location, ONLY when the request asks for automatic tax. none: the store does not collect sales tax, ONLY when the request says so. Leave out to keep the store’s choice.',\n enum: STORE_TAX_MODES,\n },\n pricesIncludeTax: {\n type: 'boolean',\n description: 'true when the request says prices already include tax (VAT-style); false when it says tax is added on top.',\n },\n originCountry: {\n type: 'string',\n description: 'The two-letter country the store sells from, e.g. US. Manual rates need it.',\n maxLength: 2,\n },\n originState: { type: 'string', description: 'The state or region the store sells from, e.g. TX.', maxLength: 3 },\n rateCountry: { type: 'string', description: 'The two-letter country a tax rate applies to.', maxLength: 2 },\n rateState: {\n type: 'string',\n description: 'The state or region a tax rate applies to, e.g. TX; leave out for the whole country.',\n maxLength: 3,\n },\n ratePercent: {\n type: 'number',\n description: `The tax rate in percent, e.g. 8.25. ${STATED}`,\n minimum: 0,\n maximum: 100,\n },\n rateLabel: { type: 'string', description: 'The receipt label, e.g. \"TX sales tax\".', maxLength: STORE_TAX_LABEL_MAX },\n removeRate: { type: 'boolean', description: 'true to remove the rate for rateCountry (and rateState).' },\n },\n additionalProperties: false,\n },\n maxPerPlan: 6,\n})\n\nexport const STORE_SETUP_AI_CAPABILITIES: readonly PluginAiCapability[] = [\n storeShippingAiCapability,\n storePickupAiCapability,\n storeDeliveryAiCapability,\n storeTaxAiCapability,\n]\n\n/**\n * Registers the four operations; the console surface calls it beside the\n * writer, since only the console runs AI jobs (AGL-3026). Idempotent.\n */\nexport function registerStoreSetupAiCapabilities(): void {\n for (const capability of STORE_SETUP_AI_CAPABILITIES) {\n registerPluginAiCapability(capability, { pluginId: BUNDLE_ID })\n }\n}\n"],"names":["registerPluginAiCapability","BUNDLE_ID","COMMERCE_MAX_PRICE_USD","LOCAL_DELIVERY_POSTCODES_MAX","PICKUP_HOURS_MAX","PICKUP_INSTRUCTIONS_MAX","STORE_SETUP_COUNTRIES_MAX","STORE_SETUP_LOCATION_MAX","STORE_SETUP_MAX_MINUTES","STORE_SETUP_NAME_MAX","STORE_SETUP_RESOURCE","STORE_SHIPPING_ACTIONS","STORE_SHIPPING_AI_KINDS","STORE_SHIPPING_TIERS_MAX","STORE_TAX_LABEL_MAX","STORE_TAX_MODES","STORE_SHIPPING_AI_OP","STORE_PICKUP_AI_OP","STORE_DELIVERY_AI_OP","STORE_TAX_AI_OP","WHERE","storeSetupContentFromArgs","section","args","content","key","value","Object","entries","undefined","STATED","storeSetupCapability","op","rest","where","freeAllowed","feature","draftResource","live","estimateCredits","degrade","draftContent","item","storeShippingAiCapability","noun","intents","argsSchema","type","properties","action","description","enum","zoneName","maxLength","countries","items","maxItems","rateName","kind","amountUsd","minimum","maximum","freeOverUsd","tiers","required","additionalProperties","maxPerPlan","storePickupAiCapability","location","enabled","hours","instructions","readyWithinMinutes","storeDeliveryAiCapability","country","postcodes","feeUsd","minimumUsd","removeZone","windows","leadTimeMinutes","daysAhead","storeTaxAiCapability","mode","pricesIncludeTax","originCountry","originState","rateCountry","rateState","ratePercent","rateLabel","removeRate","STORE_SETUP_AI_CAPABILITIES","registerStoreSetupAiCapabilities","capability","pluginId"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The `store-settings` writer (AGL-3749) over the console's Admin SDK, with
19
+ * the lockdown verdict every console write door asks: the platform, the
20
+ * workspace, the site and the member, for a write.
21
+ */
22
+ export declare const storeSetupAiWriter: import("@aglyn/aglyn/src").PluginResourceDraftWriter;
23
+ /**
24
+ * Registers the writer; the console surface calls it, since only the console
25
+ * runs AI jobs (AGL-3026). Idempotent: a second call replaces the first.
26
+ */
27
+ export declare function registerStoreSetupAiWriter(): void;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { registerPluginResourceDraftWriter } from "@aglyn/aglyn/plugin-manager/plugin-resource-drafts";
17
+ import { firebaseAdmin, getLockdownVerdict } from "@aglyn/tenant-data-admin";
18
+ import { BUNDLE_ID } from "../constants/bundle-common.js";
19
+ import { STORE_SETUP_RESOURCE } from "../model/store-setup-content.js";
20
+ import { createStoreSetupAiWriter } from "./store-setup-ai-writer.js";
21
+ /**
22
+ * The `store-settings` writer (AGL-3749) over the console's Admin SDK, with
23
+ * the lockdown verdict every console write door asks: the platform, the
24
+ * workspace, the site and the member, for a write.
25
+ */ export const storeSetupAiWriter = createStoreSetupAiWriter({
26
+ firestore: ()=>firebaseAdmin.app().firestore(),
27
+ lockdown: async ({ uid, org, host })=>Boolean(await getLockdownVerdict({
28
+ staff: false,
29
+ uid,
30
+ org: org,
31
+ host: host,
32
+ intent: 'write'
33
+ }))
34
+ });
35
+ /**
36
+ * Registers the writer; the console surface calls it, since only the console
37
+ * runs AI jobs (AGL-3026). Idempotent: a second call replaces the first.
38
+ */ export function registerStoreSetupAiWriter() {
39
+ registerPluginResourceDraftWriter(STORE_SETUP_RESOURCE, storeSetupAiWriter, {
40
+ pluginId: BUNDLE_ID
41
+ });
42
+ }
43
+
44
+ //# sourceMappingURL=store-setup-ai-writer.console.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/store-setup-ai-writer.console.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerPluginResourceDraftWriter } from '@aglyn/aglyn/plugin-manager/plugin-resource-drafts'\nimport { firebaseAdmin, getLockdownVerdict } from '@aglyn/tenant-data-admin'\nimport { BUNDLE_ID } from '../constants/bundle-common'\nimport { STORE_SETUP_RESOURCE } from '../model/store-setup-content'\nimport { createStoreSetupAiWriter } from './store-setup-ai-writer'\n\n/**\n * The `store-settings` writer (AGL-3749) over the console's Admin SDK, with\n * the lockdown verdict every console write door asks: the platform, the\n * workspace, the site and the member, for a write.\n */\nexport const storeSetupAiWriter = createStoreSetupAiWriter({\n firestore: () => firebaseAdmin.app().firestore() as unknown as FirebaseFirestore.Firestore,\n lockdown: async ({ uid, org, host }) =>\n Boolean(await getLockdownVerdict({ staff: false, uid, org: org as never, host: host as never, intent: 'write' })),\n})\n\n/**\n * Registers the writer; the console surface calls it, since only the console\n * runs AI jobs (AGL-3026). Idempotent: a second call replaces the first.\n */\nexport function registerStoreSetupAiWriter(): void {\n registerPluginResourceDraftWriter(STORE_SETUP_RESOURCE, storeSetupAiWriter, { pluginId: BUNDLE_ID })\n}\n"],"names":["registerPluginResourceDraftWriter","firebaseAdmin","getLockdownVerdict","BUNDLE_ID","STORE_SETUP_RESOURCE","createStoreSetupAiWriter","storeSetupAiWriter","firestore","app","lockdown","uid","org","host","Boolean","staff","intent","registerStoreSetupAiWriter","pluginId"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,iCAAiC,QAAQ,qDAAoD;AACtG,SAASC,aAAa,EAAEC,kBAAkB,QAAQ,2BAA0B;AAC5E,SAASC,SAAS,QAAQ,gCAA4B;AACtD,SAASC,oBAAoB,QAAQ,kCAA8B;AACnE,SAASC,wBAAwB,QAAQ,6BAAyB;AAElE;;;;CAIC,GACD,OAAO,MAAMC,qBAAqBD,yBAAyB;IACzDE,WAAW,IAAMN,cAAcO,GAAG,GAAGD,SAAS;IAC9CE,UAAU,OAAO,EAAEC,GAAG,EAAEC,GAAG,EAAEC,IAAI,EAAE,GACjCC,QAAQ,MAAMX,mBAAmB;YAAEY,OAAO;YAAOJ;YAAKC,KAAKA;YAAcC,MAAMA;YAAeG,QAAQ;QAAQ;AAClH,GAAE;AAEF;;;CAGC,GACD,OAAO,SAASC;IACdhB,kCAAkCI,sBAAsBE,oBAAoB;QAAEW,UAAUd;IAAU;AACpG"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { PluginDraftContext, PluginResourceDraftWriter } from '@aglyn/aglyn/plugin-manager/plugin-resource-drafts';
18
+ type Firestore = FirebaseFirestore.Firestore;
19
+ type Stored = Record<string, unknown>;
20
+ /** The refusal for a member without the publishing role (admin or editor). */
21
+ export declare const STORE_SETUP_ROLE_REFUSAL = "Changing store settings through AI needs an admin or editor role";
22
+ /** The refusal for a plan without commerce. */
23
+ export declare const STORE_SETUP_PLAN_REFUSAL = "Selling online is not included in your plan \u2014 see Billing";
24
+ /** What a member is told while a lockdown refuses writes to the site. */
25
+ export declare const STORE_SETUP_LOCKED_REFUSAL = "This site is not accepting changes right now.";
26
+ /** Whether a lockdown refuses this member's write to this site; `true` refuses. */
27
+ export type StoreSetupLockdownCheck = (input: {
28
+ uid: string;
29
+ org: PluginDraftContext['org'];
30
+ host: Stored;
31
+ }) => Promise<boolean>;
32
+ export interface StoreSetupAiWriterDeps {
33
+ firestore: () => Firestore;
34
+ lockdown: StoreSetupLockdownCheck;
35
+ }
36
+ export declare function createStoreSetupAiWriter(deps: StoreSetupAiWriterDeps): PluginResourceDraftWriter;
37
+ export {};