@topy-ai/maggie 0.7.12 → 0.7.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -11
- package/README.zh-TW.md +19 -3
- package/bin/maggie.js +5 -1
- package/bundled-contracts/maggiedash/README.md +3 -0
- package/bundled-contracts/maggiedash/quality-contracts.md +58 -0
- package/bundled-skills/README.md +1 -0
- package/bundled-skills/catalog.json +4 -0
- package/bundled-skills/maggie-dash/SKILL.md +31 -8
- package/bundled-skills/maggie-deployment/SKILL.md +15 -0
- package/bundled-skills/maggie-qa-workflow/SKILL.md +102 -0
- package/bundled-skills/maggie-seo-geo/SKILL.md +1 -1
- package/bundled-templates/maggiedash/section-fanout.json +84 -8
- package/bundled-templates/maggiedash/section-registry.json +3 -3
- package/bundled-tools/clis/maggie_dash.py +48 -2
- package/bundled-tools/clis/maggie_migration.py +67 -0
- package/bundled-tools/clis/maggie_qa_workflow.py +367 -0
- package/bundled-tools/runtime/maggie_quality.py +231 -0
- package/bundled-tools/runtime/maggie_sections.py +112 -12
- package/bundled-tools/runtime/maggie_sitemap.py +9 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,7 +58,23 @@ Then invoke the installed skills from your coding agent, for example:
|
|
|
58
58
|
|
|
59
59
|
Maggie keeps the existing project foundation and asks for decisions before
|
|
60
60
|
shared routes, analytics, or publishing boundaries change. The current
|
|
61
|
-
package ships
|
|
61
|
+
package ships 19 installable skills and a local-first MaggieDash foundation.
|
|
62
|
+
|
|
63
|
+
For repeatable browser QA, create a project-owned scenario manifest and record
|
|
64
|
+
the test, fix, and retest lifecycle:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
maggie qa start --project . \
|
|
68
|
+
--scenario-file .maggie/scenario-manifest.json \
|
|
69
|
+
--environment local --base-url http://localhost:4321
|
|
70
|
+
maggie qa record --project . --run <run-id> \
|
|
71
|
+
--scenario HOME-001 --phase test --status pass \
|
|
72
|
+
--summary "Homepage smoke passed" --evidence .maggie/qa/home.png
|
|
73
|
+
maggie qa summary --project . --run <run-id>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The QA workflow stores secret-free run state under `.maggie/qa-runs/` and
|
|
77
|
+
keeps project-specific scenarios and evidence outside the npm package.
|
|
62
78
|
|
|
63
79
|
For Google integrations, validate a redacted provider matrix before reporting
|
|
64
80
|
access. The command fails closed on unknown scopes, missing Ads prerequisites,
|
|
@@ -104,7 +120,8 @@ maggie bootstrap interview | phase ...
|
|
|
104
120
|
maggie dash install | init | status | migrate | cms ...
|
|
105
121
|
maggie dash transition ... # explicit content approval transition
|
|
106
122
|
maggie dash variant ... # service variant create/review/preview/publish
|
|
107
|
-
maggie dash sections ... #
|
|
123
|
+
maggie dash sections ... # field fan-out, locale, binding, media, copy, identity keys
|
|
124
|
+
maggie dash inventory ... # disjoint published-page inventory
|
|
108
125
|
maggie agent-content write ... # host-authorized, origin-bound content bridge
|
|
109
126
|
maggie verification coverage ... # changed surface/locale evidence gate
|
|
110
127
|
maggie clone ... # authorized homepage capture
|
|
@@ -113,12 +130,14 @@ maggie clone-to-template ... # URL → validated marketplace template
|
|
|
113
130
|
maggie marketplace ... # catalog and on-demand template workflow
|
|
114
131
|
maggie memory ... # confirmed preferences and lessons
|
|
115
132
|
maggie feedback ... # redact, preview, submit, list
|
|
133
|
+
maggie qa ... # scenario browser QA, fix/retest, release gate
|
|
116
134
|
maggie localization ... # plan, validate, review, publish, stale
|
|
117
135
|
maggie service ... # import, sync, generate, validate
|
|
118
136
|
maggie seo performance ... # sampled PageSpeed/CWV report and baseline
|
|
119
137
|
maggie seo images ... # inventory, variants, confirmation, validate
|
|
120
138
|
maggie seo sitemap ... # typed/semantic plan, agent-files, apply, rollback
|
|
121
139
|
maggie deployment | migration | release | analytics | schedule
|
|
140
|
+
maggie migration identity --identity-file FILE [--expected-file FILE]
|
|
122
141
|
maggie deployment canary --asset URL=SHA256 --render-report report.json
|
|
123
142
|
maggie design icon-inventory --source-dir src --runtime assets/icons.css
|
|
124
143
|
maggie api lifecycle | site-audit | ops audit
|
|
@@ -218,8 +237,8 @@ artifact schemas.
|
|
|
218
237
|
Recommended upgrade sequence for the current release:
|
|
219
238
|
|
|
220
239
|
```bash
|
|
221
|
-
npx @topy-ai/maggie@0.7.
|
|
222
|
-
npx @topy-ai/maggie@0.7.
|
|
240
|
+
npx @topy-ai/maggie@0.7.14 update --project . --force
|
|
241
|
+
npx @topy-ai/maggie@0.7.14 cleanup --project .
|
|
223
242
|
```
|
|
224
243
|
|
|
225
244
|
Maintainers should pass npm credentials through the repository helper, never
|
|
@@ -229,7 +248,14 @@ as a command-line argument:
|
|
|
229
248
|
node scripts/publish-npm.mjs --maggie-env-file ../.env
|
|
230
249
|
```
|
|
231
250
|
|
|
232
|
-
The 0.7.
|
|
251
|
+
The 0.7.14 workflow adds the general `maggie-qa-workflow` skill and `maggie qa`
|
|
252
|
+
CLI for scenario manifests, secret-free browser evidence metadata, test/fix/
|
|
253
|
+
retest lifecycle, adjacent regression checks, and explicit release gates. The
|
|
254
|
+
0.7.13 workflow adds field-aware section fan-out and locale coverage,
|
|
255
|
+
sibling-copy/media checks, disjoint page inventory, binding validation,
|
|
256
|
+
idempotency and database-target identity gates, full W3C sitemap lastmod
|
|
257
|
+
validation, and the accepted `X-Robots-Tag: noindex` response contract. The
|
|
258
|
+
0.7.12 workflow adds served-content equivalence checks, query-route
|
|
233
259
|
baseline exclusions, changed-surface render evidence gates, generated skill
|
|
234
260
|
catalogs, component-binding audits, and icon-family noise filtering. It also
|
|
235
261
|
includes the 0.7.9 nested section-field contracts, renderer-backed examples,
|
|
@@ -478,6 +504,7 @@ python3 tools/clis/maggie_design.py rebrand \
|
|
|
478
504
|
| `maggie-memory` | Persist confirmed preferences, conventions, lessons, and errors |
|
|
479
505
|
| `maggie-content-localization` | Manage locale-aware translation, review, provenance, stale state, and publication gates |
|
|
480
506
|
| `maggie-feedback` | Collect redacted feedback drafts and explicitly submit them to the NoBlox feedback endpoint |
|
|
507
|
+
| `maggie-qa-workflow` | Run scenario-based browser QA with evidence, fix/retest lifecycle, and release gates |
|
|
481
508
|
| `maggie-auth-reference` | Generate and validate traditional email/password auth with secure server-side sessions |
|
|
482
509
|
| `maggie-blog` | Run a provider-neutral blog lifecycle with stable identity, topics, feeds, settings, and rollback |
|
|
483
510
|
|
|
@@ -514,16 +541,21 @@ maggie design section-validate --before before.json --after after.json \
|
|
|
514
541
|
```
|
|
515
542
|
|
|
516
543
|
MaggieDash section contracts include a compact `pairs` band for factual
|
|
517
|
-
label/value rows. Validate required values, registry fan-out,
|
|
518
|
-
|
|
519
|
-
`
|
|
520
|
-
|
|
521
|
-
|
|
544
|
+
label/value rows. Validate required values, field-aware registry fan-out,
|
|
545
|
+
all locale copy fields, sibling copy/media, stored bindings, and idempotent
|
|
546
|
+
repairs with `maggie dash sections validate`, `fanout-validate`,
|
|
547
|
+
`locale-validate`, `variant-copy-validate`, `media-validate`,
|
|
548
|
+
`bindings-validate`, `idempotency-validate`, and `reconcile`. Use
|
|
549
|
+
`maggie dash inventory` to classify published pages once into disjoint kinds.
|
|
550
|
+
See the [quality contract examples](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/contracts/maggiedash/quality-contracts.md).
|
|
551
|
+
|
|
552
|
+
The package includes all 19 installable skills: `maggie-blog-bootstrap`,
|
|
522
553
|
`maggie-dash`, `maggie-clone`, `maggie-clone-to-template`, `maggie-marketplace`,
|
|
523
554
|
`maggie-template`, `maggie-design`, `maggie-ops`, `maggie-deployment`,
|
|
524
555
|
`maggie-project-context`, `maggie-seo-geo`, `maggie-social-share`,
|
|
525
556
|
`maggie-service-booking`, `maggie-memory`, `maggie-content-localization`,
|
|
526
|
-
`maggie-feedback`, `maggie-
|
|
557
|
+
`maggie-feedback`, `maggie-qa-workflow`, `maggie-auth-reference`, and
|
|
558
|
+
`maggie-blog`. Use the stable
|
|
527
559
|
commands below after installation:
|
|
528
560
|
|
|
529
561
|
```bash
|
package/README.zh-TW.md
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
[English README](README.md) · [完整繁體中文 README](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/README.zh-TW.md)
|
|
4
4
|
|
|
5
|
-
`@topy-ai/maggie` 提供
|
|
5
|
+
`@topy-ai/maggie` 提供 19 個可安裝的 AI website workflow skills,支援
|
|
6
6
|
Codex、Claude Code 與相容的 coding agents。
|
|
7
7
|
|
|
8
8
|
## 安裝
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
npx @topy-ai/maggie@0.7.
|
|
11
|
+
npx @topy-ai/maggie@0.7.14 init --agent all
|
|
12
12
|
npx @topy-ai/maggie doctor --project .
|
|
13
13
|
```
|
|
14
14
|
|
|
@@ -39,8 +39,24 @@ maggie deployment canary --project . \
|
|
|
39
39
|
--asset https://example.com/assets/app.js=<sha256> \
|
|
40
40
|
--render-report .maggie/rendered-canary.json \
|
|
41
41
|
--output docs/deployment-canary.json
|
|
42
|
+
|
|
43
|
+
# MaggieDash section/page quality contracts
|
|
44
|
+
maggie dash sections fanout-validate --registry templates/maggiedash/section-registry.json \
|
|
45
|
+
--fanout-file templates/maggiedash/section-fanout.json
|
|
46
|
+
maggie dash sections variant-copy-validate --pages-file .maggie/variant-pages.json
|
|
47
|
+
maggie dash sections media-validate --pages-file .maggie/variant-pages.json --across-siblings
|
|
48
|
+
maggie dash inventory --pages-file .maggie/published-pages.json
|
|
49
|
+
|
|
50
|
+
# Migration target identity (never prints or stores a database URL)
|
|
51
|
+
maggie migration identity --identity-file .maggie/db-identity.json \
|
|
52
|
+
--expected-file .maggie/service-db-identity.json
|
|
53
|
+
|
|
54
|
+
# Scenario browser QA
|
|
55
|
+
maggie qa start --project . --scenario-file .maggie/scenario-manifest.json \
|
|
56
|
+
--environment local --base-url http://localhost:4321
|
|
57
|
+
maggie qa summary --project . --run <run-id>
|
|
42
58
|
```
|
|
43
59
|
|
|
44
|
-
完整中文說明、
|
|
60
|
+
完整中文說明、19 個 skills 清單和 roadmap:
|
|
45
61
|
[繁體中文 README](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/README.zh-TW.md)
|
|
46
62
|
· [Roadmap](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/ROADMAP.md)
|
package/bin/maggie.js
CHANGED
|
@@ -58,7 +58,8 @@ Usage:
|
|
|
58
58
|
maggie doctor [--project PATH]
|
|
59
59
|
maggie bootstrap interview [project]
|
|
60
60
|
maggie dash init|install|status|migrate|transition|variant|cms --project PATH [options]
|
|
61
|
-
maggie dash sections <validate|prompt|keys|remap-translations|fanout-validate|locale-validate|reconcile> [options]
|
|
61
|
+
maggie dash sections <validate|prompt|keys|remap-translations|fanout-validate|locale-validate|variant-copy-validate|media-validate|bindings-validate|idempotency-validate|reconcile> [options]
|
|
62
|
+
maggie dash inventory --pages-file FILE
|
|
62
63
|
maggie dash components-audit --bindings-file FILE --sections-file FILE --pages-file FILE
|
|
63
64
|
maggie dash status --project PATH
|
|
64
65
|
maggie dash migrate --project PATH --confirm
|
|
@@ -104,6 +105,7 @@ Usage:
|
|
|
104
105
|
maggie deployment --project PATH --target vps-with-cloudflare-dns
|
|
105
106
|
maggie deployment canary --project PATH --asset URL=SHA256 --render-report report.json --output docs/deployment-canary.json
|
|
106
107
|
maggie migration --project PATH --environment staging
|
|
108
|
+
maggie migration identity --identity-file FILE [--expected-file FILE]
|
|
107
109
|
maggie schedule PATH/.maggie/schedule.json --project PATH
|
|
108
110
|
maggie analytics [traffic-audit|release-gate] --project PATH --environment staging
|
|
109
111
|
maggie release PATH --environment staging --target vps-with-cloudflare-dns
|
|
@@ -112,6 +114,7 @@ Usage:
|
|
|
112
114
|
maggie localization <extract|plan|generate|preview|validate|review|publish|stale|glossary> [options]
|
|
113
115
|
maggie seo performance|images|sitemap [options] (sitemap supports strict validate and agent-files)
|
|
114
116
|
maggie feedback <collect|preview|submit|list> [options]
|
|
117
|
+
maggie qa <start|record|summary|export> [options]
|
|
115
118
|
maggie site-audit URL [--crawl] [--access-log FILE] [--require-sitemap-request] [--languages en-GB,es-MX,ja-JP] [--check-hreflang]
|
|
116
119
|
maggie site-audit URL --crawl --save-baseline FILE --reviewer NAME
|
|
117
120
|
maggie site-audit URL --crawl --baseline FILE
|
|
@@ -404,6 +407,7 @@ try {
|
|
|
404
407
|
else if (command === "memory") workflowCli("maggie_memory.py", args);
|
|
405
408
|
else if (command === "localization") workflowCli("maggie_localization.py", args);
|
|
406
409
|
else if (command === "feedback") workflowCli("maggie_feedback.py", args);
|
|
410
|
+
else if (command === "qa") workflowCli("maggie_qa_workflow.py", args);
|
|
407
411
|
else if (command === "site-audit") workflowCli("site_audit.py", args);
|
|
408
412
|
else if (command === "browser-audit") workflowCli("maggie_browser_audit.py", args);
|
|
409
413
|
else if (command === "verification") workflowCli("maggie_verification.py", args);
|
|
@@ -24,6 +24,9 @@ frontend framework.
|
|
|
24
24
|
for translation keys and ordered migration;
|
|
25
25
|
- [`translation-cache-policy-v1.json`](translation-cache-policy-v1.json):
|
|
26
26
|
restart-after-out-of-band-write evidence.
|
|
27
|
+
- [`quality-contracts.md`](quality-contracts.md): reviewable inputs for
|
|
28
|
+
disjoint page inventory, variant/media checks, binding resolution, repair
|
|
29
|
+
convergence, and database target identity.
|
|
27
30
|
|
|
28
31
|
The section registry is an adapter input rather than a fixed six-band list.
|
|
29
32
|
Each registry entry must describe its purpose and limits, include a
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# MaggieDash quality contracts
|
|
2
|
+
|
|
3
|
+
These inputs are reviewable JSON evidence. They do not write a database or
|
|
4
|
+
publish content.
|
|
5
|
+
|
|
6
|
+
## Page inventory
|
|
7
|
+
|
|
8
|
+
```json
|
|
9
|
+
{
|
|
10
|
+
"pages": [
|
|
11
|
+
{"path": "/", "sections": [{"type": "hero"}]},
|
|
12
|
+
{"path": "/about", "source": "src/pages/about.astro"}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Run `maggie dash inventory --pages-file .maggie/published-pages.json`. The
|
|
18
|
+
result assigns each path exactly one kind and reports `bandCount` and
|
|
19
|
+
`codeRenderedCount`; unknown or duplicate paths fail.
|
|
20
|
+
|
|
21
|
+
## Variant and media checks
|
|
22
|
+
|
|
23
|
+
Variant pages should provide `id`, `family`, `locale`, and either a `sections`
|
|
24
|
+
array or direct fields. Run `variant-copy-validate` with one or more copy field
|
|
25
|
+
names (the default is `faq`). Run `media-validate` for page duplicates and add
|
|
26
|
+
`--across-siblings` to catch shared media in one variant family.
|
|
27
|
+
|
|
28
|
+
## Bindings
|
|
29
|
+
|
|
30
|
+
The sections file may contain a `binding` object or fields such as
|
|
31
|
+
`categorySlug`, `collectionId`, or `serviceRef`. The references file maps each
|
|
32
|
+
type to IDs, slugs, names, or values. `bindings-validate` fails when a stored
|
|
33
|
+
reference cannot be resolved.
|
|
34
|
+
|
|
35
|
+
## Repair idempotency
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"schemaVersion": "maggie-reconcile-contract.v1",
|
|
40
|
+
"candidateSelection": {"strategy": "all-candidates", "query": "SELECT all repair candidates"},
|
|
41
|
+
"compareFields": ["sections", "translations"],
|
|
42
|
+
"writesOnlyWhenChanged": true,
|
|
43
|
+
"report": {"changed": true, "unchanged": true},
|
|
44
|
+
"secondRun": {"convergent": true}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`idempotency-validate` rejects a selection that only targets rows that look
|
|
49
|
+
unconverted. The actual adapter must still use a transaction and report its
|
|
50
|
+
real changed/unchanged counts.
|
|
51
|
+
|
|
52
|
+
## Database identity
|
|
53
|
+
|
|
54
|
+
`maggie migration identity` accepts a `maggie-database-identity.v1` report with
|
|
55
|
+
environment, target/database name, server identity, service release identity,
|
|
56
|
+
row counts, and a matching SHA-256 fingerprint. It can compare a second
|
|
57
|
+
service-owned report. Reports must never contain a database URL, password, or
|
|
58
|
+
credential.
|
package/bundled-skills/README.md
CHANGED
|
@@ -20,6 +20,7 @@ Skills are the agent-facing workflows. They compose with the tools in
|
|
|
20
20
|
| `maggie-memory` | Persist confirmed preferences, project conventions, lessons, and error history across skill runs | local `.maggie/memory/` state |
|
|
21
21
|
| `maggie-content-localization` | Plan, validate, review, publish, and age localized content with market, locale, provenance, and translation safeguards | localization contract, locale CLI |
|
|
22
22
|
| `maggie-feedback` | Collect, redact, review, and explicitly submit feedback from skill runs | feedback CLI, hosted endpoint, GitHub Issue Forms |
|
|
23
|
+
| `maggie-qa-workflow` | Run scenario-based browser QA with evidence, fix/retest lifecycle, and release gates | browser adapter, QA workflow CLI, scenario manifest |
|
|
23
24
|
|
|
24
25
|
Read only the selected skill and its linked references for a task. Do not load
|
|
25
26
|
all skills as one undifferentiated prompt.
|
|
@@ -58,6 +58,10 @@
|
|
|
58
58
|
"name": "maggie-project-context",
|
|
59
59
|
"description": "Sync a site's safe AI CMO Project, selected brand voice, site settings, and CTA context into a local generated context file. Use when connecting a vibe-coded blog or existing website to AI CMO, refreshing brand context, or diagnosing missing CTA/project data."
|
|
60
60
|
},
|
|
61
|
+
{
|
|
62
|
+
"name": "maggie-qa-workflow",
|
|
63
|
+
"description": "Run scenario-based browser QA with explicit evidence, fix/retest lifecycle, and release-gate decisions for web projects."
|
|
64
|
+
},
|
|
61
65
|
{
|
|
62
66
|
"name": "maggie-seo-geo",
|
|
63
67
|
"description": "Plan, audit, create, rewrite, and measure content for AI CMO's paid SEO and GEO workflow. Use for topic opportunities, AI visibility, technical SEO, extractable article structure, sitemap-based rewrites, GSC readback, or SEO/GEO client reports."
|
|
@@ -182,15 +182,26 @@ maggie dash sections remap-translations \
|
|
|
182
182
|
--mapping-file .maggie/section-translation-map.json \
|
|
183
183
|
--output .maggie/translations-v2.json --confirm
|
|
184
184
|
|
|
185
|
-
# Validate
|
|
185
|
+
# Validate every registry-declared translatable field for every locale before publishing:
|
|
186
186
|
maggie dash sections locale-validate \
|
|
187
187
|
--page-id <page-id> --sections-file .maggie/sections.json \
|
|
188
|
-
--translations-file .maggie/translations-by-locale.json
|
|
188
|
+
--translations-file .maggie/translations-by-locale.json \
|
|
189
|
+
--registry templates/maggiedash/section-registry.json --locale zh-Hant
|
|
189
190
|
|
|
190
191
|
# Check that a host wired every registry type through all implementation surfaces:
|
|
191
192
|
maggie dash sections fanout-validate \
|
|
192
193
|
--registry templates/maggiedash/section-registry.json \
|
|
193
194
|
--fanout-file templates/maggiedash/section-fanout.json
|
|
195
|
+
|
|
196
|
+
# Validate sibling copy, media uniqueness, references, and repair convergence:
|
|
197
|
+
maggie dash sections variant-copy-validate --pages-file .maggie/variant-pages.json --field faq
|
|
198
|
+
maggie dash sections media-validate --pages-file .maggie/variant-pages.json --across-siblings
|
|
199
|
+
maggie dash sections bindings-validate --sections-file .maggie/sections.json \
|
|
200
|
+
--references-file .maggie/reference-inventory.json
|
|
201
|
+
maggie dash sections idempotency-validate --contract-file .maggie/reconcile-contract.json
|
|
202
|
+
|
|
203
|
+
# Classify every published page exactly once:
|
|
204
|
+
maggie dash inventory --pages-file .maggie/published-pages.json
|
|
194
205
|
```
|
|
195
206
|
|
|
196
207
|
The catalogue declares purpose, usage, placement, repeatability and layout
|
|
@@ -211,10 +222,13 @@ as a fixed number of bands.
|
|
|
211
222
|
Required fields and repeated `pairs` values cannot be blank. The `pairs`
|
|
212
223
|
starter band is intended for compact label/value facts such as opening hours;
|
|
213
224
|
it is not a prose fallback. The registry fan-out manifest is a host integration
|
|
214
|
-
contract: when a host adds a type, update its type union/schema, blank
|
|
215
|
-
validation, readable-content extraction, renderer, and editor entry
|
|
216
|
-
then run `fanout-validate`.
|
|
217
|
-
|
|
225
|
+
contract: when a host adds a type or field, update its type union/schema, blank
|
|
226
|
+
state, validation, readable-content extraction, renderer, and editor entry
|
|
227
|
+
together, then run `fanout-validate`. The check is field-aware and requires two
|
|
228
|
+
editor screens, so adding a field without wiring both editing surfaces fails
|
|
229
|
+
closed. `locale-validate --registry` checks every declared translatable scalar
|
|
230
|
+
and repeated item field; URLs and media sources can be marked non-translatable.
|
|
231
|
+
The host adapter must write the section and all non-default locale rows in one
|
|
218
232
|
transaction. The JSON report is evidence, not a database write.
|
|
219
233
|
|
|
220
234
|
Translation keys use stable section IDs, with an array-index fallback only
|
|
@@ -233,8 +247,17 @@ is the reviewable output form, not a substitute for the adapter's transaction.
|
|
|
233
247
|
Keep data-owned values out of page copy. For example, a pricing band should
|
|
234
248
|
store a service identifier or slug and let the live service/booking adapter
|
|
235
249
|
render current options and prices. Inventory reports must classify each
|
|
236
|
-
published page once into disjoint groups;
|
|
237
|
-
|
|
250
|
+
published page once into disjoint groups; `maggie dash inventory` reports band
|
|
251
|
+
and code-rendered counts. Price options, arrangements, and other child records
|
|
252
|
+
are counts, not pages. Run the variant-copy and media checks before publishing
|
|
253
|
+
localized sibling pages, and the bindings check whenever a section stores a
|
|
254
|
+
category, collection, or service reference; an unresolved binding is a publish
|
|
255
|
+
failure, not an empty state.
|
|
256
|
+
|
|
257
|
+
Repair scripts must select all candidates, compare every target field, write
|
|
258
|
+
only changed rows, and report both changed and unchanged rows. Validate that
|
|
259
|
+
contract with `idempotency-validate`; a query that selects only rows that look
|
|
260
|
+
unconverted cannot repair its own bad output.
|
|
238
261
|
|
|
239
262
|
After any script or direct adapter write to translation data, invalidate the
|
|
240
263
|
running process before verification. Record the restart and run the rendering
|
|
@@ -111,6 +111,21 @@ The manifest must reference `DATABASE_URL` (not a literal URL), declare an
|
|
|
111
111
|
advancing version, forward-only/idempotent policy, backup and restore commands,
|
|
112
112
|
and a tested restore artifact. The validator never runs those commands.
|
|
113
113
|
|
|
114
|
+
Before a write, prove that the migration target is the database used by the
|
|
115
|
+
running service. The identity report is intentionally secret-free and includes
|
|
116
|
+
the environment, target/database name, server identity, service release
|
|
117
|
+
identity, row counts, and a SHA-256 fingerprint. Compare it with the deployment
|
|
118
|
+
identity when available:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
maggie migration identity --identity-file .maggie/db-identity.json \
|
|
122
|
+
--expected-file .maggie/service-db-identity.json
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The gate fails on a missing or mismatched target identity and never executes a
|
|
126
|
+
migration. A successful connection alone is not proof that the intended
|
|
127
|
+
database was selected.
|
|
128
|
+
|
|
114
129
|
If a release depends on existing rows or seeded data, set
|
|
115
130
|
`dataDependencies: true` in `.maggie/migration-manifest.json` and provide
|
|
116
131
|
`.maggie/deployment/data-release.json` before deployment. The checkpoint must
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: maggie-qa-workflow
|
|
3
|
+
description: Run scenario-based browser QA with explicit evidence, fix/retest lifecycle, and release-gate decisions for web projects.
|
|
4
|
+
metadata:
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Maggie QA Workflow
|
|
9
|
+
|
|
10
|
+
Use this skill when a web project needs repeatable user-scenario testing that
|
|
11
|
+
connects browser evidence to a fix, a same-scenario retest, adjacent regression
|
|
12
|
+
checks, and an explicit Pass/Blocked/Fail release decision. It is framework
|
|
13
|
+
neutral and does not replace the project's browser-control or test tools.
|
|
14
|
+
Follow the shared [memory hook](../../references/memory-hook.md) before and
|
|
15
|
+
after the run; memory and feedback remain bounded by the privacy rules below.
|
|
16
|
+
|
|
17
|
+
## Prepare a scenario manifest
|
|
18
|
+
|
|
19
|
+
Create `.maggie/scenario-manifest.json` or pass another JSON file with a
|
|
20
|
+
non-empty `scenarios` array. Each scenario needs a unique `id`; useful fields
|
|
21
|
+
include `title`, `group`, `priority`, `routes`, `persona`, `auth`, `browser`,
|
|
22
|
+
and `viewport`. Keep project-specific scenarios in the project; do not ship
|
|
23
|
+
them in the Maggie package.
|
|
24
|
+
|
|
25
|
+
## Start and record a run
|
|
26
|
+
|
|
27
|
+
The CLI stores only secret-free run state under `.maggie/qa-runs/`. Screenshots
|
|
28
|
+
and logs stay in the project and are represented by relative paths and hashes.
|
|
29
|
+
Use a real browser adapter for visible interaction, computed layout,
|
|
30
|
+
console/network evidence, final URLs, and response status:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
maggie qa start --project . \
|
|
34
|
+
--scenario-file .maggie/scenario-manifest.json \
|
|
35
|
+
--run-id local-qa-001 --environment local \
|
|
36
|
+
--base-url http://localhost:4321 --browser chrome \
|
|
37
|
+
--commit "$(git rev-parse --short HEAD)"
|
|
38
|
+
|
|
39
|
+
maggie qa record --project . --run local-qa-001 \
|
|
40
|
+
--scenario HOME-001 --phase test --status pass \
|
|
41
|
+
--summary "Homepage navigation and consent passed" \
|
|
42
|
+
--evidence .maggie/qa-runs/local-qa-001/home.png
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For a failure, record expected behavior, actual behavior, and a stable error
|
|
46
|
+
fingerprint. A failed scenario cannot be silently changed to Pass:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
maggie qa record --project . --run local-qa-001 \
|
|
50
|
+
--scenario SEARCH-001 --phase test --status fail \
|
|
51
|
+
--summary "Search dialog did not open" \
|
|
52
|
+
--expected "Selecting a result opens its detail page" \
|
|
53
|
+
--actual "The click leaves the dialog open" \
|
|
54
|
+
--error-fingerprint search-dialog-click-stale \
|
|
55
|
+
--evidence .maggie/qa-runs/local-qa-001/search-console.txt
|
|
56
|
+
|
|
57
|
+
maggie qa record --project . --run local-qa-001 \
|
|
58
|
+
--scenario SEARCH-001 --phase fix \
|
|
59
|
+
--resolution "Guarded the dialog transition after the selected result is resolved" \
|
|
60
|
+
--validation "focused browser check and project build passed"
|
|
61
|
+
|
|
62
|
+
maggie qa record --project . --run local-qa-001 \
|
|
63
|
+
--scenario SEARCH-001 --phase retest --status pass \
|
|
64
|
+
--summary "Search result opens the detail page" \
|
|
65
|
+
--evidence .maggie/qa-runs/local-qa-001/search-retest.png
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`fix` must follow a recorded failure. `retest` must follow a test and, when
|
|
69
|
+
the test failed, a fix. After a fix, retest the original scenario and at least
|
|
70
|
+
one adjacent scenario affected by the same surface.
|
|
71
|
+
|
|
72
|
+
## Gate and release evidence
|
|
73
|
+
|
|
74
|
+
The run gate is `fail` when any scenario fails, `blocked` when there is no
|
|
75
|
+
failure but pending/blocked/inconclusive scenarios remain, and `pass` only
|
|
76
|
+
when every scenario passes. Missing credentials, unsafe fixtures, a real
|
|
77
|
+
mobile viewport, a payment sandbox, or a fault-injection environment are
|
|
78
|
+
explicit blockers; never guess around them.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
maggie qa summary --project . --run local-qa-001
|
|
82
|
+
maggie qa summary --project . --run local-qa-001 --format markdown
|
|
83
|
+
maggie qa export --project . --run local-qa-001 \
|
|
84
|
+
--output docs/qa-runs/local-qa-001.md
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Before calling a release Pass, also run the relevant build, accessibility,
|
|
88
|
+
SEO, media, API, and deployment-canary checks. A green build, HTTP 200, source
|
|
89
|
+
class, or one guest smoke is not browser QA evidence.
|
|
90
|
+
|
|
91
|
+
## Privacy and feedback
|
|
92
|
+
|
|
93
|
+
Do not put passwords, tokens, cookies, full private URLs, personal data,
|
|
94
|
+
provider response bodies, or secrets in run state, screenshots, or exported
|
|
95
|
+
reports. When the same workflow defect is reusable across projects, create a
|
|
96
|
+
privacy-safe draft through `maggie-feedback`; submitting it remains an explicit
|
|
97
|
+
user-confirmed action. Do not promote a project-specific preference directly
|
|
98
|
+
to active memory.
|
|
99
|
+
|
|
100
|
+
The implementation is `tools/clis/maggie_qa_workflow.py`; it is intentionally
|
|
101
|
+
small enough to run without a browser dependency and delegates browser
|
|
102
|
+
interaction to the host agent/browser capability.
|
|
@@ -62,7 +62,7 @@ advertising it are separate decisions.
|
|
|
62
62
|
Generated sitemap XML uses the conventional readable shape by default: one
|
|
63
63
|
`<url>`/`<sitemap>` entry per block, UTF-8 XML, and date-only `lastmod` evidence
|
|
64
64
|
rendered as a full UTC W3C datetime. The plan also exposes the response
|
|
65
|
-
contract (`text/xml; charset=utf-8` and `X-Robots-Tag:
|
|
65
|
+
contract (`text/xml; charset=utf-8` and `X-Robots-Tag: noindex`) for the framework
|
|
66
66
|
route or reverse proxy to apply; writing a file cannot set HTTP headers itself.
|
|
67
67
|
When Search Console reports a valid sitemap as unfetched, probe success alone
|
|
68
68
|
is not a diagnosis. Supply a sanitized local access log to distinguish
|
|
@@ -1,11 +1,87 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "maggiedash-section-fanout.v1",
|
|
3
|
-
"description": "
|
|
4
|
-
"typeUnion":
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
"description": "Field-aware host contract: every registry type and declared field must be wired through each implementation surface and two editor screens.",
|
|
4
|
+
"typeUnion": {
|
|
5
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
6
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
7
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
8
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
9
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
10
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
11
|
+
"cta": ["heading", "body", "label"]
|
|
12
|
+
},
|
|
13
|
+
"sectionSchema": {
|
|
14
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
15
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
16
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
17
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
18
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
19
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
20
|
+
"cta": ["heading", "body", "label"]
|
|
21
|
+
},
|
|
22
|
+
"blank": {
|
|
23
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
24
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
25
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
26
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
27
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
28
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
29
|
+
"cta": ["heading", "body", "label"]
|
|
30
|
+
},
|
|
31
|
+
"validation": {
|
|
32
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
33
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
34
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
35
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
36
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
37
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
38
|
+
"cta": ["heading", "body", "label"]
|
|
39
|
+
},
|
|
40
|
+
"textExtraction": {
|
|
41
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
42
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
43
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
44
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
45
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
46
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
47
|
+
"cta": ["heading", "body", "label"]
|
|
48
|
+
},
|
|
49
|
+
"renderer": {
|
|
50
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
51
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
52
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
53
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
54
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
55
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
56
|
+
"cta": ["heading", "body", "label"]
|
|
57
|
+
},
|
|
58
|
+
"editor": {
|
|
59
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
60
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
61
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
62
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
63
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
64
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
65
|
+
"cta": ["heading", "body", "label"]
|
|
66
|
+
},
|
|
67
|
+
"editorScreens": {
|
|
68
|
+
"section-editor": {
|
|
69
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
70
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
71
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
72
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
73
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
74
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
75
|
+
"cta": ["heading", "body", "label"]
|
|
76
|
+
},
|
|
77
|
+
"document-detail": {
|
|
78
|
+
"hero": ["title", "intro", "image", "imageAlt", "ctaLabel"],
|
|
79
|
+
"prose": ["heading", "paragraphs", "paragraphs.paragraph", "image", "imageAlt"],
|
|
80
|
+
"pairs": ["heading", "rows", "rows.label", "rows.value", "note"],
|
|
81
|
+
"cards": ["heading", "items", "items.title", "items.body"],
|
|
82
|
+
"links": ["heading", "items", "items.label", "items.href", "items.body"],
|
|
83
|
+
"faq": ["heading", "items", "items.question", "items.answer"],
|
|
84
|
+
"cta": ["heading", "body", "label"]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
11
87
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"fields": [
|
|
14
14
|
{"name": "title", "usage": "Plain words a visitor would search for.", "limit": 70, "required": true},
|
|
15
15
|
{"name": "intro", "usage": "Who it is for and what it does.", "limit": 220},
|
|
16
|
-
{"name": "image", "usage": "The hero image rendered beside or behind the copy.", "limit": 500},
|
|
16
|
+
{"name": "image", "usage": "The hero image rendered beside or behind the copy.", "limit": 500, "translatable": false},
|
|
17
17
|
{"name": "imageAlt", "usage": "What the hero image shows for a reader who cannot see it.", "limit": 160},
|
|
18
18
|
{"name": "ctaLabel", "usage": "The action as a verb.", "limit": 30}
|
|
19
19
|
],
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"fields": [
|
|
29
29
|
{"name": "heading", "usage": "The argument in a sentence.", "limit": 90},
|
|
30
30
|
{"name": "paragraphs", "usage": "Standalone paragraphs.", "limit": 0, "repeats": {"min": 1, "max": 4, "of": [{"name": "paragraph", "usage": "One paragraph of plain prose.", "limit": 400}]}},
|
|
31
|
-
{"name": "image", "usage": "An optional supporting image.", "limit": 500},
|
|
31
|
+
{"name": "image", "usage": "An optional supporting image.", "limit": 500, "translatable": false},
|
|
32
32
|
{"name": "imageAlt", "usage": "What the supporting image shows.", "limit": 160}
|
|
33
33
|
],
|
|
34
34
|
"example": {"type": "prose", "heading": "Make the important part easier to understand", "paragraphs": ["Start with the decision your reader is trying to make.", "Then give them the context, evidence and next step in that order."]}
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"repeatable": true,
|
|
67
67
|
"fields": [
|
|
68
68
|
{"name": "heading", "usage": "What the links have in common.", "limit": 90},
|
|
69
|
-
{"name": "items", "usage": "Real related pages on this site.", "limit": 0, "repeats": {"min": 2, "max": 6, "of": [{"name": "label", "usage": "The destination page name.", "limit": 60, "required": true}, {"name": "href", "usage": "A real path on this site.", "limit": 200, "required": true}, {"name": "body", "usage": "One sentence on what is there.", "limit": 160}]}}
|
|
69
|
+
{"name": "items", "usage": "Real related pages on this site.", "limit": 0, "repeats": {"min": 2, "max": 6, "of": [{"name": "label", "usage": "The destination page name.", "limit": 60, "required": true}, {"name": "href", "usage": "A real path on this site.", "limit": 200, "required": true, "translatable": false}, {"name": "body", "usage": "One sentence on what is there.", "limit": 160}]}}
|
|
70
70
|
],
|
|
71
71
|
"example": {"type": "links", "heading": "Keep exploring", "items": [{"label": "How it works", "href": "/how-it-works/", "body": "See the process from start to finish."}, {"label": "Frequently asked questions", "href": "/faq/", "body": "Find concise answers to common questions."}]}
|
|
72
72
|
},
|