@topy-ai/maggie 0.7.46 → 0.7.48
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-zh-TW.md +12 -4
- package/README.md +55 -11
- package/bin/maggie.js +26 -4
- package/bundled-contracts/maggie-design/palette-roles-v1.schema.json +47 -0
- package/bundled-contracts/maggie-marketplace/template-content-v1.schema.json +103 -0
- package/bundled-contracts/maggiedash/booking-browser-evidence-v1.json +21 -0
- package/bundled-contracts/maggiedash/booking-browser-evidence-v2.json +191 -0
- package/bundled-contracts/maggiedash/booking-email-templates-v1.json +3 -1
- package/bundled-contracts/maggiedash/booking-voucher-lifecycle-v1.json +85 -0
- package/bundled-contracts/maggiedash/execution-board.json +4629 -1553
- package/bundled-contracts/maggiedash/stripe-booking-capabilities-v1.json +1 -0
- package/bundled-marketplace/README.md +17 -0
- package/bundled-marketplace/catalog.json +56 -7
- package/bundled-references/browser-inspection.md +25 -0
- package/bundled-references/maggiedash-booking/CURRENT-STATE.md +128 -10
- package/bundled-references/maggiedash-booking/EXECUTION-BOARD.json +4629 -1553
- package/bundled-references/maggiedash-booking/HOST-ADAPTER.md +5 -0
- package/bundled-references/maggiedash-booking/ORAWELLNESS-INTEGRATION-AUDIT.md +64 -21
- package/bundled-references/maggiedash-booking/PRD.md +9 -1
- package/bundled-references/maggiedash-booking/PROGRESS.md +244 -2399
- package/bundled-references/maggiedash-booking/QA-TEST-PLAN.md +37 -6
- package/bundled-references/maggiedash-booking/README.md +23 -6
- package/bundled-references/maggiedash-booking/RUNTIME-OPERATIONS.md +64 -8
- package/bundled-references/maggiedash-booking/SKILLS-AND-CLI.md +11 -2
- package/bundled-references/maggiedash-booking/STRIPE-INTEGRATION.md +66 -2
- package/bundled-references/maggiedash-booking/TASK-RUNBOOK.md +1 -1
- package/bundled-references/maggiedash-booking/TASKS.md +44 -3
- package/bundled-references/maggiedash-booking/VOUCHERS.md +47 -0
- package/bundled-references/memory-hook.md +18 -5
- package/bundled-references/provider-adapter-contract.md +33 -0
- package/bundled-skills/maggie-booking/SKILL.md +8 -0
- package/bundled-skills/maggie-clone-to-template/SKILL.md +26 -0
- package/bundled-skills/maggie-deployment/SKILL.md +59 -1
- package/bundled-skills/maggie-deployment/references/vps.md +41 -0
- package/bundled-skills/maggie-design/SKILL.md +99 -0
- package/bundled-skills/maggie-feedback/SKILL.md +41 -2
- package/bundled-skills/maggie-marketplace/SKILL.md +91 -0
- package/bundled-skills/maggie-memory/SKILL.md +10 -1
- package/bundled-skills/maggie-qa-workflow/SKILL.md +41 -1
- package/bundled-skills/maggie-service-booking/SKILL.md +23 -0
- package/bundled-skills/maggie-social-share/SKILL.md +37 -5
- package/bundled-skills/maggie-social-share/references/queue-and-connections.md +101 -0
- package/bundled-skills/maggie-template/SKILL.md +57 -3
- package/bundled-skills/maggie-template/references/template-content-v1.example.json +34 -0
- package/bundled-tools/clis/maggie_booking.py +199 -26
- package/bundled-tools/clis/maggie_booking_vouchers.py +185 -0
- package/bundled-tools/clis/maggie_clone_to_template.py +14 -0
- package/bundled-tools/clis/maggie_deployment.py +295 -0
- package/bundled-tools/clis/maggie_design.py +9 -0
- package/bundled-tools/clis/maggie_design_lint.py +277 -0
- package/bundled-tools/clis/maggie_feedback.py +107 -3
- package/bundled-tools/clis/maggie_marketplace.py +199 -5
- package/bundled-tools/clis/maggie_memory.py +10 -3
- package/bundled-tools/clis/maggie_palette.py +280 -0
- package/bundled-tools/clis/maggie_qa_workflow.py +156 -1
- package/bundled-tools/clis/maggie_social_queue.py +338 -0
- package/bundled-tools/clis/maggie_social_share.py +42 -9
- package/bundled-tools/clis/maggie_template_package.py +1141 -0
- package/bundled-tools/runtime/maggie_memory.py +17 -2
- package/package.json +1 -1
- package/references/browser-inspection.md +25 -0
- package/references/memory-hook.md +18 -5
- package/references/provider-adapter-contract.md +33 -0
|
@@ -150,6 +150,39 @@ image-processing contract: optimisation may use Cloudflare Images
|
|
|
150
150
|
transformations, Astro build tooling or a provider-specific implementation
|
|
151
151
|
behind the same interface.
|
|
152
152
|
|
|
153
|
+
## OAuth connections
|
|
154
|
+
|
|
155
|
+
A provider connection is only as reliable as its weakest connect path:
|
|
156
|
+
|
|
157
|
+
- Each adapter declares one canonical OAuth scope set. Every client that
|
|
158
|
+
starts the flow (dashboard, mobile app, CLI) requests exactly that set.
|
|
159
|
+
LinkedIn invalidates a member's earlier tokens when a later sign-in asks for
|
|
160
|
+
a different scope set, so a mobile app that omits `email` silently revokes
|
|
161
|
+
the dashboard's token while the database still says `active`.
|
|
162
|
+
- Prefer one OAuth client per product. When a client ID is shared with other
|
|
163
|
+
products or callbacks, record it as `client_shared_with`; their sign-ins can
|
|
164
|
+
revoke this product's tokens unless they use the identical scope set.
|
|
165
|
+
- Treat stored connection status as a cache. A token that the provider has
|
|
166
|
+
revoked, or that the serving host cannot decrypt, is `needs_reconnect`
|
|
167
|
+
before anything is scheduled on it — not when a post fails.
|
|
168
|
+
- Provider media URLs (for example `media.licdn.com` with an `e=` expiry) are
|
|
169
|
+
signed and expire. Cache the bytes in owned storage or refresh on readback.
|
|
170
|
+
|
|
171
|
+
`maggie tool maggie_social_share.py adapters` and `connections` check these
|
|
172
|
+
rules from a redacted JSON manifest; see the Social Share skill for shapes.
|
|
173
|
+
|
|
174
|
+
## Structured model output
|
|
175
|
+
|
|
176
|
+
Keep structured-output schemas small. Gemini rejected a JSON schema whose enum
|
|
177
|
+
had 125 values with `400 INVALID_ARGUMENT`, and the caller silently fell back
|
|
178
|
+
for every request. For a large vocabulary (styles, categories, catalogue IDs):
|
|
179
|
+
|
|
180
|
+
1. ask for a free string (optionally with a short list of examples in the
|
|
181
|
+
prompt) instead of a large `enum`;
|
|
182
|
+
2. validate the returned value server-side against the authoritative list;
|
|
183
|
+
3. treat a schema rejection or an unknown value as a visible, counted failure —
|
|
184
|
+
never a silent fallback to a default.
|
|
185
|
+
|
|
153
186
|
## Adding a provider
|
|
154
187
|
|
|
155
188
|
1. Implement the relevant interface in `src/lib/providers/`.
|
|
@@ -373,6 +373,14 @@ node scripts/maggie-booking-schema.mjs --apply --confirm
|
|
|
373
373
|
node scripts/maggie-booking-worker.mjs --write --confirm
|
|
374
374
|
```
|
|
375
375
|
|
|
376
|
+
Before switching Stripe to live mode, follow the read-only live setup runbook
|
|
377
|
+
in `docs/maggiedash-booking/STRIPE-INTEGRATION.md`: verify with list/retrieve
|
|
378
|
+
calls only, never use a create call as a probe, have the owner install
|
|
379
|
+
webhook and event-destination signing secrets with a no-echo command, and hand
|
|
380
|
+
Dashboard-only steps to the owner. Gift vouchers follow the host-owned
|
|
381
|
+
`booking-voucher-lifecycle-v1.json` contract; validate a host ledger with
|
|
382
|
+
`maggie booking voucher-contract --ledger FIXTURE`.
|
|
383
|
+
|
|
376
384
|
The dry-run executes the complete additive migration in a transaction and
|
|
377
385
|
rolls it back, which verifies PostgreSQL permissions without changing data.
|
|
378
386
|
The apply command commits the migration as one transaction.
|
|
@@ -67,6 +67,32 @@ then stores the prompt as
|
|
|
67
67
|
`CUSTOMIZATION_PROMPT.md` beside the package. It creates a resumable job under
|
|
68
68
|
`marketplace/.maggie/clone-to-template-jobs/`.
|
|
69
69
|
|
|
70
|
+
### Neutral display identity
|
|
71
|
+
|
|
72
|
+
A package's customer-facing identity is separate from its source evidence.
|
|
73
|
+
`template.json` `name` and `id` are internal; `sourceMetadata` records the
|
|
74
|
+
source title only as provenance. Pass a designed, neutral style name and a short
|
|
75
|
+
description when planning:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
maggie tool maggie_clone_to_template.py plan <url> "<approved brief>" --rename <template-id> \
|
|
79
|
+
--display-name "Olive Atelier" \
|
|
80
|
+
--display-description "A light editorial beauty homepage with olive accents."
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Packaging forwards both to the marketplace importer. Without them, completion
|
|
84
|
+
derives a name from the measured design (accent hue, display typeface,
|
|
85
|
+
industry). The validator rejects a name that repeats a distinctive source-title
|
|
86
|
+
word, looks like a counter (`Beauty Studio 20 001`), or duplicates another
|
|
87
|
+
catalogue entry. Change it later with `maggie_marketplace.py identity <id>
|
|
88
|
+
--display-name …`. Template pickers must show `displayName` and
|
|
89
|
+
`displayDescription`, never the source business name.
|
|
90
|
+
|
|
91
|
+
Packaging also measures `DESIGN.md` from the rendered CSS, records
|
|
92
|
+
`screenshotReview`, and lists every asset with its provenance. Review captures
|
|
93
|
+
stay at viewport height; tile any full-page capture as described in the
|
|
94
|
+
`maggie-marketplace` package quality gates.
|
|
95
|
+
|
|
70
96
|
If the full clone run fails or cannot reach `verified`, stop and report the
|
|
71
97
|
clone checkpoint. Do not invoke the marketplace importer as a fallback. If the
|
|
72
98
|
Maggie design review fails, stop before declaring the template ready.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: maggie-deployment
|
|
3
3
|
description: Deploy and operate Maggie blog projects with Cloudflare Workers as the default target, while preserving an adapter boundary for VPS, GCP, and AWS.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.5.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Maggie Deployment
|
|
@@ -219,6 +219,12 @@ files and the application remain separated (`maggie-deploy` versus
|
|
|
219
219
|
Install and review that narrow sudoers policy on the host before executing a
|
|
220
220
|
runner.
|
|
221
221
|
|
|
222
|
+
Generated release runners include their Maggie version and a template
|
|
223
|
+
fingerprint. VPS preflight checks runners under `.maggie/deployment/` and warns
|
|
224
|
+
when they are unmarked or stale; use `--check-runner PATH` for a runner stored
|
|
225
|
+
elsewhere. Regenerate from the reviewed VPS plan, inspect the diff, and replace
|
|
226
|
+
the checked-in runner only after review.
|
|
227
|
+
|
|
222
228
|
VPS plans include a bounded retention policy: keep two immutable releases,
|
|
223
229
|
preserve the `current` target and rollback target, and review prune candidates
|
|
224
230
|
before any operator executes cleanup. Generate a read-only candidate report:
|
|
@@ -233,6 +239,58 @@ maggie tool maggie_deployment.py --retention-plan \
|
|
|
233
239
|
The CLI never deletes release directories and never permits fewer than two
|
|
234
240
|
retained releases.
|
|
235
241
|
|
|
242
|
+
### Multi-host secret parity
|
|
243
|
+
|
|
244
|
+
When several hosts serve the same routes, check that each one holds every
|
|
245
|
+
required secret. The check compares key names and SHA-256 fingerprints and
|
|
246
|
+
never prints, stores, or transmits values:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Local env files (one per host):
|
|
250
|
+
maggie deployment secret-parity \
|
|
251
|
+
--host api-1=.secrets/api-1.env --host api-2=.secrets/api-2.env \
|
|
252
|
+
--required SOCIAL_SHARE_ENCRYPTION_KEY
|
|
253
|
+
|
|
254
|
+
# Or fingerprint manifests produced on each host:
|
|
255
|
+
maggie deployment secret-fingerprint --env-file /etc/example.env \
|
|
256
|
+
--host api-1 --output api-1.json
|
|
257
|
+
maggie deployment secret-parity --manifest api-1.json --manifest api-2.json \
|
|
258
|
+
--required SOCIAL_SHARE_ENCRYPTION_KEY
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
A required key that is missing or differs on any host fails the check. Other
|
|
262
|
+
drifting keys are warnings unless `--strict` is set. A host without Maggie can
|
|
263
|
+
use the no-echo shell snippet in [the VPS reference](references/vps.md); the
|
|
264
|
+
parity command accepts its `KEY <sha256>` output directly. Manifests that
|
|
265
|
+
contain anything other than names and 64-character hex digests are rejected.
|
|
266
|
+
|
|
267
|
+
### Local and production database isolation
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
maggie deployment env-isolation --project . \
|
|
271
|
+
--production-env .env.production
|
|
272
|
+
# or: --production-db-host db.example.net
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The check fails when the local `.env` points at the production database (same
|
|
276
|
+
host, and port/name when known). The same server with a different database is
|
|
277
|
+
a warning. Deployment preflight runs the check automatically, as a non-blocking
|
|
278
|
+
warning, when `.env.production` exists or `MAGGIE_PRODUCTION_DB_HOST` is set.
|
|
279
|
+
Database URLs are reduced to host/port; credentials are never reported.
|
|
280
|
+
|
|
281
|
+
### Release ordering for workers and notification templates
|
|
282
|
+
|
|
283
|
+
Deploy the worker and its templates before any code path can enqueue an event
|
|
284
|
+
that uses a new template. When local development or a staged app shares a
|
|
285
|
+
queue with production, an event that names a template the running worker does
|
|
286
|
+
not know yet must be held and retried, not dead-lettered: an unknown template
|
|
287
|
+
during a rollout is a release-ordering state, not a permanent failure. Check
|
|
288
|
+
that the outbox worker (MaggieDash Booking or the host's own) does not let
|
|
289
|
+
unknown-template deliveries consume the retry budget, and after the release
|
|
290
|
+
confirm the held deliveries were sent.
|
|
291
|
+
If dead-lettered rows already exist, requeue them only after the worker that
|
|
292
|
+
knows the template is live.
|
|
293
|
+
|
|
236
294
|
Validate the database release separately before a VPS migration:
|
|
237
295
|
|
|
238
296
|
```bash
|
|
@@ -132,6 +132,47 @@ inspect → plan → backup/migrate → npm ci → npm run build
|
|
|
132
132
|
Deploy staging first. A passing build does not prove Nginx, systemd, DNS, TLS,
|
|
133
133
|
robots, sitemap, or private-route correctness.
|
|
134
134
|
|
|
135
|
+
### Release retention
|
|
136
|
+
|
|
137
|
+
Keep exactly the `current` release plus one previous release as the rollback
|
|
138
|
+
target. Prune after every deploy, and only after the new release passed its
|
|
139
|
+
health checks: an unhealthy release must still have its predecessor on disk.
|
|
140
|
+
The generated release runner does this as its final step; it never removes the
|
|
141
|
+
release `current` points at or the release it replaced. Without pruning,
|
|
142
|
+
`releases/` grows by one full `node_modules` tree per deploy until the disk
|
|
143
|
+
fills. Use `--retention-plan` for a read-only list of prune candidates on hosts
|
|
144
|
+
whose runner predates this step, and review it before deleting anything.
|
|
145
|
+
|
|
146
|
+
### Multi-host secret parity
|
|
147
|
+
|
|
148
|
+
When more than one host can serve the same routes (failover, load-balanced API
|
|
149
|
+
nodes, workers), every host must hold the same required secrets. A key that
|
|
150
|
+
exists on only one host is invisible until traffic fails over to another and
|
|
151
|
+
returns 5xx. Compare hosts by name and SHA-256 fingerprint, never by value:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# On each host (prints names and digests only; values are never echoed):
|
|
155
|
+
for k in SOCIAL_SHARE_ENCRYPTION_KEY DATABASE_URL; do
|
|
156
|
+
v=$(sed -n "s/^$k=//p" /etc/example.env | head -1)
|
|
157
|
+
printf '%s %s\n' "$k" "$(printf %s "$v" | sha256sum | cut -c1-64)"
|
|
158
|
+
done > /tmp/api-1.fingerprints
|
|
159
|
+
|
|
160
|
+
# Locally, after copying each host's fingerprint file:
|
|
161
|
+
maggie deployment secret-parity \
|
|
162
|
+
--manifest api-1.fingerprints --manifest api-2.fingerprints \
|
|
163
|
+
--manifest api-3.fingerprints \
|
|
164
|
+
--required SOCIAL_SHARE_ENCRYPTION_KEY --required DATABASE_URL
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Run it after adding a secret and before enabling a host in a pool.
|
|
168
|
+
|
|
169
|
+
### Environment isolation
|
|
170
|
+
|
|
171
|
+
A local `.env` must never point at the production database. Shared databases
|
|
172
|
+
let local test records (vouchers, palettes, emails) appear on live pages and be
|
|
173
|
+
picked up by production workers. `maggie deployment env-isolation` fails when
|
|
174
|
+
the local database host, port, and name match production.
|
|
175
|
+
|
|
135
176
|
## Verification and rollback
|
|
136
177
|
|
|
137
178
|
Verify the homepage, changed service routes, `/robots.txt`, `/sitemap.xml`,
|
|
@@ -285,6 +285,57 @@ all required camera states, and valid PNGs at 390px, 768px, and desktop
|
|
|
285
285
|
widths. The machine-readable contract is
|
|
286
286
|
[mobile-app-surface-v1.schema.json](../../bundled-contracts/maggie-design/mobile-app-surface-v1.schema.json).
|
|
287
287
|
|
|
288
|
+
### Onboarding wizards
|
|
289
|
+
|
|
290
|
+
Use one pattern for multi-step setup (brand, logo, voice, posting hours, and
|
|
291
|
+
similar first-run flows) instead of designing each flow ad hoc:
|
|
292
|
+
|
|
293
|
+
- A segmented progress bar with one segment per step; the current step is
|
|
294
|
+
visibly distinct and completed steps are tappable.
|
|
295
|
+
- Each step shows Maggie (or the product guide) with exactly one headline and,
|
|
296
|
+
at most, one supporting line. Put help in the control, not in paragraphs.
|
|
297
|
+
- Record step state on the server (`pending`, `done`, `skipped`) after every
|
|
298
|
+
step, and resume from the first unfinished step on any device. Local state
|
|
299
|
+
alone loses progress on reinstall or a second device.
|
|
300
|
+
- Every optional step offers **Later**. A skipped step reopens on the next
|
|
301
|
+
sign-in until it is done or explicitly dismissed; never block the app on it.
|
|
302
|
+
- Completed steps keep a redo action (for example "Retrain voice" or
|
|
303
|
+
"Choose another logo") that reopens that step with the saved value
|
|
304
|
+
preselected, without restarting the wizard.
|
|
305
|
+
- The primary action stays in the fixed footer; Back never discards saved
|
|
306
|
+
server state.
|
|
307
|
+
|
|
308
|
+
### Pickers with previews
|
|
309
|
+
|
|
310
|
+
For choices that need to be seen (logo styles, templates, palettes, voices):
|
|
311
|
+
|
|
312
|
+
- The list sheet shows a thumbnail, name, and selection state per row; the
|
|
313
|
+
row itself selects, and a separate preview control opens a larger view.
|
|
314
|
+
- The large preview opens as a sheet nested in the list sheet, so dismissing
|
|
315
|
+
it returns to the same scroll position in the list. It offers **Use this**
|
|
316
|
+
and close; it never replaces the list route.
|
|
317
|
+
- Thumbnails are generated or cached assets, not live renders of every option.
|
|
318
|
+
|
|
319
|
+
### React Native Web pressables
|
|
320
|
+
|
|
321
|
+
React Native Web renders `Pressable` and the `Touchable*` family as button-like
|
|
322
|
+
DOM elements. A chip with a nested remove control becomes `<button>` inside
|
|
323
|
+
`<button>`: the DOM is invalid, browsers repair it differently, and taps land
|
|
324
|
+
on the wrong control (for example, removing a tag opens its preview). Render
|
|
325
|
+
the chip body and its remove control as **sibling** pressables inside a plain
|
|
326
|
+
`View`, each with its own accessible label. The same rule applies to `<a>`
|
|
327
|
+
and `<button>` on the web.
|
|
328
|
+
|
|
329
|
+
Run the static check before browser QA; it scans `.tsx`/`.jsx`, skips build
|
|
330
|
+
and dependency folders, and treats `asChild` wrappers (such as an expo-router
|
|
331
|
+
`Link`) as a pass-through:
|
|
332
|
+
|
|
333
|
+
maggie design pressable-check --project . [--pressable Chip --pressable IconButton]
|
|
334
|
+
|
|
335
|
+
Pass `--pressable` for project components that render a pressable. A rare,
|
|
336
|
+
reviewed exception can carry `maggie-allow-nested-pressable` in a comment on
|
|
337
|
+
the inner element's line.
|
|
338
|
+
|
|
288
339
|
## Explicit homepage rebrand mode
|
|
289
340
|
|
|
290
341
|
The homepage `review` mode only compares screenshots. It does not rebrand a
|
|
@@ -543,6 +594,54 @@ collapsed-rail, mobile-drawer, and modal evidence. Sample plans require
|
|
|
543
594
|
noindex, sitemap exclusion, a visible sample banner, placeholders, and a
|
|
544
595
|
finish checklist.
|
|
545
596
|
|
|
597
|
+
### Tailwind v4 cascade layers
|
|
598
|
+
|
|
599
|
+
Tailwind v4 emits utilities inside `@layer utilities`. An unlayered rule beats
|
|
600
|
+
every layered rule regardless of specificity, so an unlayered
|
|
601
|
+
`h1, h2, h3 { font-family: … }` silently defeats template `font-*` utilities,
|
|
602
|
+
and an unlayered icon runtime rule such as `.ph { display: inline-block }`
|
|
603
|
+
defeats `hidden` and `group-open:inline` (a mobile menu then shows both the
|
|
604
|
+
open and close icons). Static class checks pass; only a browser shows it.
|
|
605
|
+
|
|
606
|
+
- Put app-wide element rules (headings, links, body copy) in `@layer base`.
|
|
607
|
+
- Put icon-font runtime rules and component classes in `@layer components`,
|
|
608
|
+
or import the icon stylesheet with `@import "./icons.css" layer(components);`.
|
|
609
|
+
- Keep `@theme`, `@utility`, and `@font-face` as they are; they are not
|
|
610
|
+
competing rules.
|
|
611
|
+
|
|
612
|
+
Run the static check whenever CSS or the icon package changes:
|
|
613
|
+
|
|
614
|
+
maggie design layer-check --project .
|
|
615
|
+
|
|
616
|
+
It runs only when an `@import "tailwindcss"` entry exists (or with
|
|
617
|
+
`--tailwind-v4`), honours `@layer` blocks and `layer(...)` imports, and fails on
|
|
618
|
+
unlayered element or icon rules that set utility-competing properties.
|
|
619
|
+
Unlayered `html`/`body` rules and class rules that set `display` are reported
|
|
620
|
+
as warnings. Keep `css-cascade-check` for the rendered-browser proof.
|
|
621
|
+
|
|
622
|
+
### Palette role contract
|
|
623
|
+
|
|
624
|
+
A template that offers brand colour choices exposes semantic roles instead of
|
|
625
|
+
raw hex values in markup: `canvas`, `panel`, `soft`, `text`, `accent`,
|
|
626
|
+
`accentText`, `onAccent`, `dark`, and `deep`. Bind them to CSS variables (for
|
|
627
|
+
example `--color-canvas`) so a palette swap never edits markup. The generator
|
|
628
|
+
keeps the signature palette and derives named variants by moving hue while
|
|
629
|
+
keeping lightness; neutrals never gain chroma, accent saturation is capped
|
|
630
|
+
(uncapped variants turn garish), `accentText` is forced to 4.5:1 on canvas,
|
|
631
|
+
and `onAccent` is the most legible of white, deep, text, and canvas:
|
|
632
|
+
|
|
633
|
+
maggie design palette generate --template <template-id> \
|
|
634
|
+
--canvas '#F7F3EE' --text '#1F1B16' --accent '#B5651D' \
|
|
635
|
+
[--roles roles.json] [--count 17] [--max-saturation 0.65] \
|
|
636
|
+
--output design/palettes.json
|
|
637
|
+
maggie design palette validate --palette design/palettes.json
|
|
638
|
+
|
|
639
|
+
Measure the signature roles from the template's rendered CSS, not from a
|
|
640
|
+
reference palette. Generation stops if the signature itself fails the
|
|
641
|
+
contrast rules; fix the signature rather than lowering the threshold. The
|
|
642
|
+
contract is
|
|
643
|
+
[palette-roles-v1.schema.json](../../bundled-contracts/maggie-design/palette-roles-v1.schema.json).
|
|
644
|
+
|
|
546
645
|
For generated or converted pages, run the markup gate before handing the page
|
|
547
646
|
to a host editor:
|
|
548
647
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: maggie-feedback
|
|
3
3
|
description: Collect, review, and explicitly submit privacy-safe feedback about a Maggie skill run, workflow result, bug, or feature request.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.2.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Maggie Feedback
|
|
@@ -30,7 +30,9 @@ maggie feedback --project . collect \
|
|
|
30
30
|
maggie feedback preview .maggie/feedback/<feedback-id>.json --format markdown
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
The draft is written to `.maggie/feedback/`.
|
|
33
|
+
The draft is written to `.maggie/feedback/`. List local drafts with
|
|
34
|
+
`maggie feedback list --project .`; `--project` works before or after the
|
|
35
|
+
subcommand. A draft contains the Maggie version,
|
|
34
36
|
skill, run ID, phase, error fingerprint, expected/actual result, reproduction
|
|
35
37
|
steps, resolution, validation, and metadata-only screenshot references.
|
|
36
38
|
|
|
@@ -116,6 +118,43 @@ Example:
|
|
|
116
118
|
]
|
|
117
119
|
}
|
|
118
120
|
|
|
121
|
+
## Feedback types
|
|
122
|
+
|
|
123
|
+
- `bug`: the skill or CLI did something wrong.
|
|
124
|
+
- `quality`: the result works but falls short (unclear output, weak defaults).
|
|
125
|
+
- `feature`: a missing capability.
|
|
126
|
+
- `improvement`: a concrete proposal to change an existing skill or CLI
|
|
127
|
+
(a new flag, a better default, a guidance section).
|
|
128
|
+
- `general`: anything else.
|
|
129
|
+
|
|
130
|
+
The hosted endpoint accepts `bug`, `feature`, `quality`, and `general`. An
|
|
131
|
+
`improvement` draft keeps its type locally and is submitted as `feature` with
|
|
132
|
+
`subtype: "improvement"`, so maintainers can still filter it.
|
|
133
|
+
|
|
134
|
+
## Draft a batch from a working session
|
|
135
|
+
|
|
136
|
+
After a long session, draft batch items from the commits made since a known
|
|
137
|
+
point instead of writing them by hand:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
maggie feedback session-summary --project . \
|
|
141
|
+
--repo . --since v1.4.0 \
|
|
142
|
+
--batch-id social-session-2026-10 --skill maggie-social-share
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The helper reads commit subjects only (no diffs, paths, or file contents) and
|
|
146
|
+
redacts secrets and local paths. `fix:` commits become fixed `bug` items with a
|
|
147
|
+
`commit:<sha>` evidence reference; `feat:`, `perf:` and `refactor:` commits
|
|
148
|
+
become `improvement` candidates; other commits are skipped and counted. It also
|
|
149
|
+
adds one placeholder for an open ask. It writes a draft batch file under
|
|
150
|
+
`.maggie/feedback/batches/` and does not create or submit feedback.
|
|
151
|
+
|
|
152
|
+
Review the file: delete items that concern the project rather than a Maggie
|
|
153
|
+
skill or CLI, and replace every `REVIEW:` field (expected, actual, validation).
|
|
154
|
+
`maggie feedback batch` rejects a file that still contains `REVIEW:`
|
|
155
|
+
placeholders. Then continue with `batch`, `batch-review`, and explicit
|
|
156
|
+
`submit` as usual.
|
|
157
|
+
|
|
119
158
|
## Submit explicitly
|
|
120
159
|
|
|
121
160
|
The CLI never submits automatically. After reviewing the draft:
|
|
@@ -52,6 +52,18 @@ maggie tool maggie_marketplace.py apply \
|
|
|
52
52
|
--id medical-spa-landing-30 --project /path/to/astro-project
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
Package-quality commands (read-only unless `--write`/`--record`/`--approve`):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
maggie tool maggie_marketplace.py audit-package <id> # all package-quality gates, JSON report
|
|
59
|
+
maggie tool maggie_marketplace.py measure-design <id> --write # palette roles + fonts from homepage CSS
|
|
60
|
+
maggie tool maggie_marketplace.py repair-assets <id> --write # list unlisted assets honestly; add file extensions
|
|
61
|
+
maggie tool maggie_marketplace.py identity <id> --display-name "Olive Atelier" \
|
|
62
|
+
--display-description "A light editorial beauty homepage with olive accents."
|
|
63
|
+
maggie tool maggie_marketplace.py image-plan <id> --unit-cost 0.04 --currency USD
|
|
64
|
+
maggie tool maggie_marketplace.py image-review <id> [--approve --reviewer NAME | --flag assets/x.png]
|
|
65
|
+
```
|
|
66
|
+
|
|
55
67
|
The native installer exposes the same operation as
|
|
56
68
|
`maggie marketplace add <template-url> clone <preview-url> --rename <id>`.
|
|
57
69
|
|
|
@@ -95,6 +107,55 @@ validator before it is reported complete. If the validator has changed or the
|
|
|
95
107
|
artifact drifted, the job becomes `STALE` and must be resumed or rebuilt; do
|
|
96
108
|
not treat an old readiness flag as proof of current validity.
|
|
97
109
|
|
|
110
|
+
## Package quality gates
|
|
111
|
+
|
|
112
|
+
`validate` and the completion checkpoint include five package-quality gates.
|
|
113
|
+
`audit-package` runs only these, without the mutating cleanup that `validate`
|
|
114
|
+
performs, so it is safe on any checkout.
|
|
115
|
+
|
|
116
|
+
1. **Screenshots decode and fit a pixel budget.** Every file in
|
|
117
|
+
`screenshots/` must fully decode (PNG chunk CRCs and inflated size, JPEG
|
|
118
|
+
frame/end markers, WebP header; Pillow is used too when installed). A
|
|
119
|
+
corrupt capture shows as glitch noise and is reported as
|
|
120
|
+
`recapture-required`; recapture it with `maggie_clone_to_template.py
|
|
121
|
+
review` — never hand-edit or keep it. The budget is 40 MP per image and
|
|
122
|
+
16383 px per edge, well under sharp's default `limitInputPixels`
|
|
123
|
+
(268,402,689 px) and Pillow's decompression-bomb guard, so consumers never
|
|
124
|
+
need to disable those limits. Ship full-page captures as tiles no taller
|
|
125
|
+
than 4096 px (`desktop-full-01.png`, `desktop-full-02.png`, …) or as a
|
|
126
|
+
compressed WebP preview; keep `desktop.png`/`tablet.png`/`mobile.png` at
|
|
127
|
+
viewport height. `audit-package --record` stores the per-file result in
|
|
128
|
+
`template.json` `screenshotReview`.
|
|
129
|
+
2. **`DESIGN.md` palette is measured, not inherited.** The palette and fonts
|
|
130
|
+
come from the template's own CSS: Tailwind config colours and fonts,
|
|
131
|
+
arbitrary utilities (`bg-[#…]`), the Tailwind neutral scales, body rules,
|
|
132
|
+
inline and stylesheet declarations, and Google Fonts links.
|
|
133
|
+
`measure-design --write` rewrites the `### Reference palette` and
|
|
134
|
+
typography lines, stores `designTokens` (the nine
|
|
135
|
+
`maggie-palette-roles-v1` roles plus fonts and missing font links) in
|
|
136
|
+
`template.json`, and fills empty `styleTags` with measured tags
|
|
137
|
+
(`light-canvas`, `serif-display`, `warm-neutral`, …). Every declared colour
|
|
138
|
+
must exist in the page CSS and Background/Text primary must match the
|
|
139
|
+
measured canvas/text; derived contrast-safe roles are labelled `derived`.
|
|
140
|
+
Check the result against the screenshots before overriding anything.
|
|
141
|
+
3. **Every asset has provenance.** Every image under `assets/` must be listed
|
|
142
|
+
in `generated-asset-manifest.json` with a provider and role. Captured
|
|
143
|
+
source images are listed as `provider: captured-source`, `reuse: false`,
|
|
144
|
+
`replacementRequired: true`; files without a generation record are
|
|
145
|
+
`provider: unrecorded`, `reuse: false`, `provenanceReview: required`. Both
|
|
146
|
+
block publishing. Files without an extension are rejected;
|
|
147
|
+
`repair-assets --write` sniffs the type, renames the file, and rewrites
|
|
148
|
+
`homepage.html` and `image-inventory.json`.
|
|
149
|
+
4. **Neutral display identity.** `template.json` carries a customer-facing
|
|
150
|
+
`displayName` and `displayDescription` that are separate from the ID,
|
|
151
|
+
`name`, and `sourceMetadata`. The name must not repeat a distinctive word
|
|
152
|
+
from the source title, must not be a counter such as `Beauty Studio 20
|
|
153
|
+
001`, and must be unique in the catalogue. Completion derives one from the
|
|
154
|
+
measured design (accent hue, display typeface, industry) when none is
|
|
155
|
+
given; prefer a reviewed, designed name. `list`, `suggest`, and the catalogue
|
|
156
|
+
show `displayName`; source titles never appear in customer-facing pickers.
|
|
157
|
+
5. **Generated images pass a no-text review.** See step 4 below.
|
|
158
|
+
|
|
98
159
|
Each import also creates `tasks.json`. It is the workflow ledger: it stores
|
|
99
160
|
source/output inventories for logos, icons, images, headings, links, buttons,
|
|
100
161
|
visible copy, and Tailwind, plus evidence and status for source analysis,
|
|
@@ -222,6 +283,32 @@ role, provider, date, and prompt in `generated-asset-manifest.json`. Validate
|
|
|
222
283
|
that every PNG/JPEG decodes. Never apply text replacement tools to binary
|
|
223
284
|
assets.
|
|
224
285
|
|
|
286
|
+
Report cost before and after every generation run, and review every output
|
|
287
|
+
for text. A "no text, no labels" prompt is not a guarantee: product bottles,
|
|
288
|
+
signage, and packaging routinely come back with readable words.
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# before generating: planned image count and estimated cost
|
|
292
|
+
maggie tool maggie_marketplace.py image-plan <id> --unit-cost <price-per-image> --currency USD
|
|
293
|
+
# after generating: actual count/cost, contact sheet, and text review
|
|
294
|
+
maggie tool maggie_marketplace.py image-review <id>
|
|
295
|
+
# a person checked image-review/contact-sheet.html and found no text
|
|
296
|
+
maggie tool maggie_marketplace.py image-review <id> --approve --reviewer <name>
|
|
297
|
+
# or record a failure, regenerate that asset, and review again
|
|
298
|
+
maggie tool maggie_marketplace.py image-review <id> --flag assets/maggie-hero.png
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
`image-plan` counts inventory occurrences marked `needs-generation`, pending
|
|
302
|
+
roles, and captured-source assets awaiting replacement. Take the unit cost from
|
|
303
|
+
the provider's current price list; when omitted, the estimate is recorded as
|
|
304
|
+
unknown rather than guessed. `image-review` writes the post-run count and cost,
|
|
305
|
+
`image-review/contact-sheet.html`, and a per-image `textReview` in
|
|
306
|
+
`image-generation-report.json`. When `tesseract` is installed, OCR flags any
|
|
307
|
+
image with readable words; otherwise the review stays `pending-human-review`
|
|
308
|
+
until `--approve`. Completion and `validate` block until the review is
|
|
309
|
+
`passed` and covers every generated asset. These commands make no model or
|
|
310
|
+
paid API calls themselves.
|
|
311
|
+
|
|
225
312
|
Before generating anything, create `image-inventory.json` from the final
|
|
226
313
|
section structure. Include one record for every logo and image occurrence:
|
|
227
314
|
`id`, source occurrence/line, semantic role, composition, dimensions/aspect
|
|
@@ -315,6 +402,10 @@ image references. It also verifies the generated asset roles used by the
|
|
|
315
402
|
sample. A mismatch blocks `apply` and publish until the template is repaired
|
|
316
403
|
or an explicitly approved `--sample` contract is selected.
|
|
317
404
|
|
|
405
|
+
The validator also runs the package quality gates above (screenshot
|
|
406
|
+
integrity and budget, measured palette, asset provenance, neutral display
|
|
407
|
+
identity, generated-image text review).
|
|
408
|
+
|
|
318
409
|
Also parse all JSON and JSON-LD, require exactly one canonical, verify `en-GB`,
|
|
319
410
|
decode every local image, scan for source brand/person/place/phone/social URL
|
|
320
411
|
remnants, confirm no Iconify/platform runtime remains, and inspect desktop,
|
|
@@ -29,7 +29,7 @@ truth, content state, or audit log.
|
|
|
29
29
|
|
|
30
30
|
## Workflow
|
|
31
31
|
|
|
32
|
-
1. At the start of a relevant workflow, run `maggie memory context --project . --skill <skill>` and load only matching active items.
|
|
32
|
+
1. At the start of a relevant workflow, run `maggie memory context --project . --skill <skill>` and load only matching active project-scope items. Use `--include-shared` only after explicit opt-in.
|
|
33
33
|
2. Show material preferences, conventions, and prevention lessons before making a decision.
|
|
34
34
|
3. When the user gives a durable preference or confirms a repaired pitfall, save it explicitly as `candidate` or `active` with scope and evidence.
|
|
35
35
|
4. Record every meaningful failure with `record-error`; include a stable fingerprint, resolution, and validation result when fixed.
|
|
@@ -45,6 +45,15 @@ truth, content state, or audit log.
|
|
|
45
45
|
preserving project scope. Expired active items remain inspectable through
|
|
46
46
|
explicit status listing but are excluded from normal context.
|
|
47
47
|
|
|
48
|
+
Project-scope `maggie init` creates the repository's `.maggie/memory/` store.
|
|
49
|
+
Repeated initialization preserves existing memory files without rewriting
|
|
50
|
+
their contents or timestamps. A context response distinguishes a ready store
|
|
51
|
+
from an uninitialized project; the shared memory hook falls back to the
|
|
52
|
+
installed CLI when local Python tools are absent.
|
|
53
|
+
|
|
54
|
+
Project `context`, `search`, and `list` read only project-scope items by
|
|
55
|
+
default. `--include-shared` explicitly opts into user/workspace-scoped entries.
|
|
56
|
+
|
|
48
57
|
```bash
|
|
49
58
|
maggie memory init --project .
|
|
50
59
|
maggie memory context --project . --skill maggie-clone
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: maggie-qa-workflow
|
|
3
3
|
description: Run scenario-based browser QA with explicit evidence, fix/retest lifecycle, and release-gate decisions for web projects.
|
|
4
4
|
metadata:
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.3.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Maggie QA Workflow
|
|
@@ -74,6 +74,46 @@ the host browser adapter. The adapter owns console, network, authentication,
|
|
|
74
74
|
URL, viewport, and screenshot capture; this skill stores only a relative path,
|
|
75
75
|
URL reference, and hash when a local file exists.
|
|
76
76
|
|
|
77
|
+
## Protect production data
|
|
78
|
+
|
|
79
|
+
Declare which API the build under test talks to, and mark scenarios that
|
|
80
|
+
write data with `"mutates": true` in the scenario manifest:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
maggie qa start --project . --run-id local-qa-002 \
|
|
84
|
+
--environment local --base-url http://localhost:4321 \
|
|
85
|
+
--api-base https://api.example.com \
|
|
86
|
+
--production-api https://api.example.com
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
When the API base is a production API, mutating scenarios start as `blocked`
|
|
90
|
+
and `record` refuses a pass or fail result for them. Run those scenarios
|
|
91
|
+
against a non-production API, or start a run with `--allow-production-writes`
|
|
92
|
+
only after the user explicitly consents and a restore path exists. Overriding
|
|
93
|
+
`window.fetch` from the page does not stop a bundled API client from sending
|
|
94
|
+
requests; use network-layer interception as described in the
|
|
95
|
+
[browser inspection contract](../../references/browser-inspection.md).
|
|
96
|
+
|
|
97
|
+
## Check CORS for every method the client uses
|
|
98
|
+
|
|
99
|
+
Before a release that adds or changes API calls from a browser or webview,
|
|
100
|
+
preflight every HTTP method the client sends through the public edge, not only
|
|
101
|
+
the origin server:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
maggie qa cors-preflight --project . \
|
|
105
|
+
--url https://api.example.com/v1/setup \
|
|
106
|
+
--origin https://app.example.com \
|
|
107
|
+
--method GET,POST,PUT,PATCH,DELETE \
|
|
108
|
+
--request-header content-type,authorization \
|
|
109
|
+
--output .maggie/qa-runs/cors-preflight.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The command sends only `OPTIONS` requests and fails when a method, origin, or
|
|
113
|
+
request header is not allowed. A method missing from the edge allow-list
|
|
114
|
+
fails in the browser with a generic network error (Safari: "Load failed") and
|
|
115
|
+
leaves no request in server logs, so it is easy to misdiagnose.
|
|
116
|
+
|
|
77
117
|
## Assert the requirement at runtime
|
|
78
118
|
|
|
79
119
|
Do not use a source class, edited markup fragment, or implementation detail as
|
|
@@ -427,6 +427,29 @@ FAQ helper from the first category implementation; it is a known gap and must
|
|
|
427
427
|
remain marked incomplete until each FAQ record is independently AI-authored and
|
|
428
428
|
reviewed.
|
|
429
429
|
|
|
430
|
+
## Payments: Stripe live setup and gift vouchers
|
|
431
|
+
|
|
432
|
+
Service pages often lead to first-party payments. When the host takes money
|
|
433
|
+
through MaggieDash Booking (rather than the external provider), follow the
|
|
434
|
+
read-only live setup runbook in `docs/maggiedash-booking/STRIPE-INTEGRATION.md`:
|
|
435
|
+
|
|
436
|
+
- verify live state with list/retrieve (`GET`) calls only; never use a create
|
|
437
|
+
call as a probe — a probe expected to fail can create a real live object;
|
|
438
|
+
- the owner installs webhook and Connect event-destination signing secrets
|
|
439
|
+
with a no-echo command (`read -rs … | <secret store>`); the agent never sees
|
|
440
|
+
them;
|
|
441
|
+
- thin-event destination signing secrets cannot be retrieved via the API;
|
|
442
|
+
roll them in the Dashboard if they were not captured;
|
|
443
|
+
- the Stripe Dashboard may be unusable under browser automation, so hand
|
|
444
|
+
Dashboard-only steps to the owner and confirm them with read-only calls.
|
|
445
|
+
|
|
446
|
+
Gift vouchers (online and at the till, partial redemption, undo, void, expiry,
|
|
447
|
+
refunds, buyer/recipient emails, merchant ledger) follow the host-owned
|
|
448
|
+
`contracts/maggiedash/booking-voucher-lifecycle-v1.json` contract described in
|
|
449
|
+
`docs/maggiedash-booking/VOUCHERS.md`. Do not invent a separate voucher model;
|
|
450
|
+
replay the host's sanitized ledger with
|
|
451
|
+
`maggie booking voucher-contract --ledger FIXTURE`.
|
|
452
|
+
|
|
430
453
|
## Gates
|
|
431
454
|
|
|
432
455
|
The workflow stops when any gate fails:
|