@topy-ai/maggie 0.7.49 → 0.7.51
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 +3 -3
- package/README.md +58 -8
- package/bin/maggie.js +33 -14
- package/bundled-contracts/maggie-assistant-tools/tool-registry-example-v1.json +19 -0
- package/bundled-contracts/maggie-assistant-tools/tool-registry-v1.schema.json +50 -0
- package/bundled-contracts/maggie-deployment/bridge-host-example-v1.json +29 -0
- package/bundled-contracts/maggie-design/mobile-app-evidence-v1.schema.json +54 -0
- package/bundled-contracts/maggie-design/mobile-app-surface-v1.schema.json +137 -16
- package/bundled-skills/catalog.json +8 -0
- package/bundled-skills/maggie-assistant-tools/SKILL.md +93 -0
- package/bundled-skills/maggie-assistant-tools/references/approvals-and-audit.md +54 -0
- package/bundled-skills/maggie-assistant-tools/references/bridge-host.md +56 -0
- package/bundled-skills/maggie-assistant-tools/references/product-release.md +57 -0
- package/bundled-skills/maggie-deployment/SKILL.md +13 -0
- package/bundled-skills/maggie-design/SKILL.md +55 -21
- package/bundled-skills/maggie-design/references/app-ui-patterns.md +66 -0
- package/bundled-skills/maggie-feedback/SKILL.md +20 -3
- package/bundled-skills/maggie-marketplace/SKILL.md +28 -0
- package/bundled-skills/maggie-mobile-app/SKILL.md +122 -0
- package/bundled-skills/maggie-qa-workflow/SKILL.md +30 -0
- package/bundled-tools/clis/maggie_app_collect.py +236 -0
- package/bundled-tools/clis/maggie_assistant_tools.py +302 -0
- package/bundled-tools/clis/maggie_bridge_host.py +212 -0
- package/bundled-tools/clis/maggie_design.py +190 -29
- package/bundled-tools/clis/maggie_feedback.py +89 -37
- package/bundled-tools/clis/maggie_mobile.py +221 -0
- package/bundled-tools/clis/maggie_product_release.py +303 -0
- package/bundled-tools/clis/maggie_qa_app_preflight.py +248 -0
- package/bundled-tools/clis/maggie_qa_workflow.py +5 -0
- package/bundled-tools/clis/maggie_skill_catalog.py +262 -0
- package/bundled-tools/runtime/assistant_approval.py +111 -0
- package/bundled-tools/runtime/cdp_client.py +246 -0
- package/package.json +1 -1
package/README-zh-TW.md
CHANGED
|
@@ -29,7 +29,7 @@ npx @topy-ai/maggie init --scope project --agent all
|
|
|
29
29
|
npx @topy-ai/maggie doctor --scope project --project .
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
目前 npm 版本為 `0.7.
|
|
32
|
+
目前 npm 版本為 `0.7.51`,完成 batch 28:17 條 hosted feedback,來自一個跨平台產品開發 session(同一套 Expo 程式碼支援 web、iOS、Android,加上具備 MCP 與 ChatGPT/Claude app 的 AI 助理、產品自己的 CLI/MCP 套件、第三方 skills catalog 以及多租戶 assistant bridge host)。`maggie design app-validate` 改讀每個 viewport 的 evidence(scroll owner、固定 header/footer),只有 `app-init --pane list-detail:1024:2` 宣告的多欄版面才允許多個 scroll owner,並以 PNG 實際尺寸對照 plan viewport;`app-init --capabilities none|camera,…`(或 `--camera none`)讓非相機頁面不必填相機狀態,`--pattern` 加入新的 app UI patterns 驗收規則。新增 `maggie design app-collect`:在同一個瀏覽器分頁逐一以真實尺寸渲染已登入的 app 路由、略過 React Native Web 的包裝層計算 scroll owner、證明固定 shell,並寫出 `runtime-evidence.json` 與截圖(可 `--cdp-url` 接上已登入的 Chrome,或用專用 QA profile,`--read-only` 阻擋寫入)。新增 `maggie qa app-preflight`:偵測以 `CI=1` 或從錯誤資料夾啟動的 Metro/Expo dev server,並對會輪替的 refresh token 與連到 production API 的本機 server 發出警告。新增 `maggie-mobile-app` skill 與 `maggie mobile preflight|plan`(EAS build profile、TestFlight / Play 內部測試、EAS Update channel 與 fingerprint runtime policy、上架審核規則、建置前成本提示;`--auto-submit` 缺 `ascAppId` 或 `appVersion` policy 配上 remote build number 時在花費額度前就失敗)。新增 `maggie-assistant-tools` skill 與 `maggie assistant`(單一 tool registry、風險等級與 gate、與 model description 分開的使用者文案、由風險推導 MCP annotations、自動產生「助理能做與不能做」頁面、audit 檢查與簽章一次性 approval token 參考實作)。新增 `maggie product release-check|smoke|mcp-check|review-status`(產品 npm CLI/MCP 套件 metadata、`server.json`/`mcpName`、打包檔案機密掃描、安裝後 binary smoke、OAuth protected-resource metadata、ChatGPT/Claude/商店審核追蹤)、`maggie skills scaffold|validate|package|smoke`(第三方 skills catalog 打包成分類 plugin、all-in-one plugin 與 Claude Code `marketplace.json`)、`maggie deployment bridge-plan|bridge-collect-script|bridge-check`(多租戶 bridge host);`maggie feedback session-summary` 支援多個 repo 與一般句子形式的 commit。MaggieDash 0.2.12 從 ORA host 上游通用修正。前一版 `0.7.50`:`maggie update` 改為 idempotent,內容已與套件相同的檔案不再改寫(保留時間戳),摘要分別列出 changed/unchanged/preserved 數量,只有真的保留了本機修改時才顯示 preserved 提示。前一版 `0.7.49` 完成 batch 27:33 條 2026-09-09 至 09-16 建立但從未提交的本機 feedback drafts,已逐條對照目前程式碼(其中兩條已被既有功能滿足)。新增離線 `maggie ops notifications`(通知 catalogue 合約、consent/retention/durable lead delivery 規則、provider template drift、只檢查變數名稱的 Resend preflight、queue health 門檻與 operator alerts、dry-run retention plan);`maggie localization email-matrix` 與 `maggie localization lifecycle`(locale 優先順序、未翻譯/缺漏 locale、變數與 HTML/text 一致、market CTA route、consent-aware 行銷 email 預設不發送);Deployment 的 `--keep-releases` 統一 retention policy、`auth-canary`、資料庫 owner 無法讀取 release 路徑時的 streamed migration、`collect` 單一 readiness report;Google failure remediation(`maggie ops google-diagnose`)與唯讀 `google-ads-preflight`/`google-ads-keyword-ideas`;Social Share `reconcile`(timeout 後不重複發文)、`maggie-marketing-run-v1` 合約、命名排程層與只管制對外發布的 regulated-content review;`maggie design icon-glyph-check`、`maggie design verify`、`maggie service import-stages-validate`/`import-readiness`/`fact-provenance`;以及 `--release-metadata` 版本一致性檢查、`maggie docs rollout-status` 與 stdin batch 輸入。前一版 `0.7.48` 處理 2026-10-10 的 27 條 hosted feedback(batch 26):Social Share 新增 `adapters`(每個 provider 一組 canonical OAuth scope,LinkedIn 不同 scope 會撤銷舊 token;共用 OAuth client 警告)、`connections`(撤銷或無法解密的 token 標為 `needs_reconnect`,偵測會過期的簽名頭像 URL)、`queue`(slot-based 排程:not-before、最新優先、campaign 輪流與每日上限、DST-safe)與 `campaigns`(idea stage Start gate);Deployment 新增 hash-only `secret-fingerprint`/`secret-parity`、`env-isolation`(本機 `.env` 指向 production database 時警告)、release retention 與 worker-before-enqueue 發布順序;QA 在未明確同意時阻擋對 production API 的寫入情境,並以 `maggie qa cors-preflight` 只用 OPTIONS 檢查每個 HTTP method;Design 新增 `pressable-check`、`layer-check`(Tailwind v4 unlayered CSS)、onboarding wizard/picker 模式與 `maggie-palette-roles-v1` palette generate/validate;Marketplace 加入 screenshot 完整性與像素預算、從 CSS 量測 palette、asset provenance、中性 `displayName`(全部模板已補齊)、template studio、`maggie-template-content-v1` 合約與圖片生成成本/無文字審查 gate;Booking 新增唯讀 Stripe live setup runbook 與 gift voucher lifecycle 合約(`maggie booking voucher-contract --ledger`);Feedback 新增 `improvement` 類型與 `maggie feedback session-summary`。MaggieDash 0.2.11 會保留尚未部署 template 的 outbox email 而不是 dead-letter,並從 ORA host 上游通用修正。本版也包含 Booking 十個 email events 合約與 CLI validator 同步及安全輸出的 `arrivalNote`。前一版 `0.7.47` 處理 2026-09-26 五條新 feedback:project-scope
|
|
33
33
|
`maggie init` 會建立本地 memory store;context 預設只讀取本 project scope;memory hook
|
|
34
34
|
在 local Python adapter 不存在時 fallback 到已安裝 CLI;重複 init 保留既有檔案與時間戳;
|
|
35
35
|
`maggie feedback list` 的 `--project` 可放在子命令前或後。Generated VPS runner 現在記錄
|
|
@@ -113,7 +113,7 @@ structure drift 或重複 treatment product 時 fail closed。
|
|
|
113
113
|
deployment、memory、feedback 和 MaggieDash。內容先 draft/review,外部寫入、
|
|
114
114
|
publish 與 production deployment 需要明確確認。
|
|
115
115
|
|
|
116
|
-
目前 npm 版本為 `0.7.
|
|
116
|
+
目前 npm 版本為 `0.7.51`,包含 batch 28 產品 app、assistant tools、mobile、product release、skills catalog 與 bridge host 功能、batch 26、27 feedback 修正與 idempotent `maggie update`與 Booking email-template 合約/CLI validator 同步。本版完成 2026-09-24 booking feedback batch:Calendar grid/free-slot entry 與 host modal focus-restoration evidence。本版新增 Starter marketplace provisioning plan;本版完成 feedback batches 22、23:加入 declarative browser interaction evidence、design markup/style/content-key gate、compiler source anchoring、entity double-escape protection、`update --help` read-only、noindex hypothetical indexability、可過期 baseline acknowledgement、DOM-only link extraction regression,以及 MaggieDash 0.2.10 的 content override、短期 browser session、CDN-safe public-session cache contracts。authentication 和 isolated dev server 仍由 host 負責。`maggie-booking` workflow、傳統 email/password、Stripe、Resend、public booking flow 及既有安全邊界維持不變;provider-bound video generation 與 transactional delivery 仍記錄在 issue #39,前一批延後功能仍在 issue #38,不會直接成為 active memory。0.7.33 記錄並審查一筆更正回饋;確認 0.7.32 已正確處理 batch index,沒有修改已驗證的 shared behavior。0.7.32 加入 feedback 一基索引支援、MaggieDash panel 的 source/freshness/error evidence、Consent Mode 與實際 write/no-op reconciliation、SEO baseline recapture、sitemap origin rebasing、content-diff scope、migration ledger reconciliation、deployment credential preflight、release provenance/runtime preflight、icon release gate、opt-in blog auto-publish gate,以及 least-privilege VPS deployer。也修復 top-level `maggie feedback` dispatcher parity。0.7.31 加入 update 差異摘要、atomic installer copy、subset install manifest merge,以及 inventory drift 時 doctor non-zero。0.7.30 補上 feedback tracking issue closeout gate 與 batch 14/15 audit ledger。0.7.29 修正 npm package landing page 使用英文 README;0.7.28 加入 versioned Gemini model policy、明確 fallback 與 provenance、bundled-first CLI
|
|
117
117
|
dispatch、`maggie --version`、feedback batch review 聚合與重複偵測、marketplace enrichment evidence、booking
|
|
118
118
|
worker/resolver evidence,以及 read-only migration preflight。它也包含 host-owned mobile app surface contract、signed-in
|
|
119
119
|
camera-state QA、直接 Astro route resolution、correlated feedback batch,以及
|
|
@@ -265,6 +265,6 @@ maggie service retirement-audit --project . \
|
|
|
265
265
|
--evidence .maggie/booking/retirement-evidence.json
|
|
266
266
|
```
|
|
267
267
|
|
|
268
|
-
完整中文說明、
|
|
268
|
+
完整中文說明、22 個 skills 清單和 roadmap:
|
|
269
269
|
[繁體中文 README](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/README.zh-TW.md)
|
|
270
270
|
· [Roadmap](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/ROADMAP.md)
|
package/README.md
CHANGED
|
@@ -87,9 +87,59 @@ Then invoke the installed skills from your coding agent, for example:
|
|
|
87
87
|
|
|
88
88
|
Maggie keeps the existing project foundation and asks for decisions before
|
|
89
89
|
shared routes, analytics, or publishing boundaries change. The current
|
|
90
|
-
package ships
|
|
91
|
-
|
|
92
|
-
This package is `0.7.
|
|
90
|
+
package ships 22 installable skills and a local-first MaggieDash foundation.
|
|
91
|
+
|
|
92
|
+
This package is `0.7.51`. It closes batch 28: 17 hosted feedback
|
|
93
|
+
records from a cross-platform product session (one Expo codebase for web,
|
|
94
|
+
iOS and Android, an assistant with MCP and ChatGPT/Claude app surfaces,
|
|
95
|
+
product CLI/MCP packages, a third-party skills catalog, and a multi-tenant
|
|
96
|
+
assistant bridge host):
|
|
97
|
+
|
|
98
|
+
- App surfaces: `maggie design app-validate` reads per-viewport evidence
|
|
99
|
+
(scroll owners, fixed shell), accepts extra scroll owners only where
|
|
100
|
+
`app-init --pane list-detail:1024:2` declares them, and checks each PNG's
|
|
101
|
+
real size against the plan viewport. `app-init --capabilities none|camera,…`
|
|
102
|
+
(or `--camera none`) drops irrelevant device states, and `--pattern` adds
|
|
103
|
+
acceptance rules from the new [app UI patterns](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/skills/maggie-design/references/app-ui-patterns.md).
|
|
104
|
+
- New `maggie design app-collect`: renders a signed-in app route one viewport
|
|
105
|
+
at a time in one browser tab at the real size, counts scroll owners while
|
|
106
|
+
skipping React Native Web wrappers, proves the fixed shell, and writes
|
|
107
|
+
`runtime-evidence.json` plus screenshots. It can attach to your signed-in
|
|
108
|
+
Chrome (`--cdp-url`) or use a QA profile, and can block writes (`--read-only`).
|
|
109
|
+
- New `maggie qa app-preflight`: catches Metro/Expo dev servers started with
|
|
110
|
+
`CI=1` or from the wrong folder, and warns about rotating refresh tokens and
|
|
111
|
+
local servers that talk to production APIs.
|
|
112
|
+
- New [`maggie-mobile-app`](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/skills/maggie-mobile-app/SKILL.md) skill and
|
|
113
|
+
`maggie mobile preflight|plan`: EAS build profiles, TestFlight / Play
|
|
114
|
+
internal testing, EAS Update channels and the fingerprint runtime policy,
|
|
115
|
+
store-review rules, and a cost notice. It fails before quota is spent when
|
|
116
|
+
`--auto-submit` lacks `ascAppId` or `appVersion` runtime policy is combined
|
|
117
|
+
with remote build numbers.
|
|
118
|
+
- New [`maggie-assistant-tools`](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/skills/maggie-assistant-tools/SKILL.md)
|
|
119
|
+
skill and `maggie assistant`: one tool registry with risk levels, gates and
|
|
120
|
+
user-facing copy kept apart from model descriptions, MCP annotations derived
|
|
121
|
+
from risk, a generated "what the assistant can and can't do" page, audit
|
|
122
|
+
checks, and reference signed one-time approval tokens.
|
|
123
|
+
- New `maggie product release-check|smoke|mcp-check|review-status` for a
|
|
124
|
+
product's own npm CLI and MCP packages (metadata, `server.json`/`mcpName`,
|
|
125
|
+
packed-file secret scan, installed-binary smoke, OAuth protected-resource
|
|
126
|
+
metadata, ChatGPT/Claude/store review tracking).
|
|
127
|
+
- New `maggie skills scaffold|validate|package|smoke` for third-party skill
|
|
128
|
+
catalogs, packaging category plugins, an all-in-one plugin and a Claude Code
|
|
129
|
+
`marketplace.json` (checked with `claude plugin validate`).
|
|
130
|
+
- New `maggie deployment bridge-plan|bridge-collect-script|bridge-check` for a
|
|
131
|
+
multi-tenant assistant bridge host on a VPS.
|
|
132
|
+
- `maggie feedback session-summary` reads several repositories
|
|
133
|
+
(`--repo app=../app --since-date …`) and classifies plain commit subjects.
|
|
134
|
+
- MaggieDash 0.2.12 upstreams generic fixes from the ORA host.
|
|
135
|
+
|
|
136
|
+
The 0.7.50 release made `maggie update` idempotent: files whose content already
|
|
137
|
+
matches the package are left untouched (timestamps included) and counted as
|
|
138
|
+
unchanged, the summary reports changed/unchanged/preserved counts, and the
|
|
139
|
+
"local files were preserved" notice appears only when a file was actually
|
|
140
|
+
preserved.
|
|
141
|
+
|
|
142
|
+
The 0.7.49 release closed batch 27: 33 local feedback
|
|
93
143
|
drafts from 2026-09-09 to 09-16 that were never submitted, reconciled against
|
|
94
144
|
the current code (two were already satisfied):
|
|
95
145
|
|
|
@@ -728,8 +778,8 @@ artifact schemas.
|
|
|
728
778
|
Recommended upgrade sequence for the current release:
|
|
729
779
|
|
|
730
780
|
```bash
|
|
731
|
-
npx @topy-ai/maggie@0.7.
|
|
732
|
-
npx @topy-ai/maggie@0.7.
|
|
781
|
+
npx @topy-ai/maggie@0.7.51 update --scope project --project . --force
|
|
782
|
+
npx @topy-ai/maggie@0.7.51 cleanup --scope project --project .
|
|
733
783
|
```
|
|
734
784
|
|
|
735
785
|
Maintainers should pass npm credentials through the repository helper, never
|
|
@@ -1235,13 +1285,13 @@ repairs with `maggie dash sections validate`, `fanout-validate`,
|
|
|
1235
1285
|
`maggie dash inventory` to classify published pages once into disjoint kinds.
|
|
1236
1286
|
See the [quality contract examples](https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/contracts/maggiedash/quality-contracts.md).
|
|
1237
1287
|
|
|
1238
|
-
The package includes all
|
|
1288
|
+
The package includes all 22 installable skills: `maggie-blog-bootstrap`,
|
|
1239
1289
|
`maggie-dash`, `maggie-clone`, `maggie-clone-to-template`, `maggie-marketplace`,
|
|
1240
1290
|
`maggie-template`, `maggie-design`, `maggie-ops`, `maggie-deployment`,
|
|
1241
1291
|
`maggie-project-context`, `maggie-seo-geo`, `maggie-social-share`,
|
|
1242
1292
|
`maggie-service-booking`, `maggie-memory`, `maggie-content-localization`,
|
|
1243
|
-
`maggie-feedback`, `maggie-qa-workflow`, `maggie-auth-reference`,
|
|
1244
|
-
`maggie-blog`. Use the stable
|
|
1293
|
+
`maggie-feedback`, `maggie-qa-workflow`, `maggie-auth-reference`,
|
|
1294
|
+
`maggie-blog`, `maggie-mobile-app`, and `maggie-assistant-tools`. Use the stable
|
|
1245
1295
|
commands below after installation:
|
|
1246
1296
|
|
|
1247
1297
|
```bash
|
package/bin/maggie.js
CHANGED
|
@@ -126,7 +126,8 @@ Usage:
|
|
|
126
126
|
maggie design reference-ui --project PATH --reference PATH --surface blog,service --confirm
|
|
127
127
|
maggie design init --project PATH --surface blog|service --reference-run PATH --confirm
|
|
128
128
|
maggie design validate-ui --project PATH --plan PATH --rendered-dir PATH --confirm
|
|
129
|
-
maggie design app-init --project PATH --route /
|
|
129
|
+
maggie design app-init --project PATH --route /inbox --auth-mode existing-session [--capabilities none|camera,...] [--pane list-detail:1024:2] [--pattern usage-hero] --confirm
|
|
130
|
+
maggie design app-collect --plan PATH --base-url URL (--cdp-url http://127.0.0.1:9222 | --profile-dir DIR) [--read-only --allow-write /auth/refresh] --confirm
|
|
130
131
|
maggie design app-validate --project PATH --plan PATH --runtime-evidence FILE --rendered-dir PATH --confirm
|
|
131
132
|
maggie design icon-inventory --project PATH --source-dir src --runtime assets/icons.css --output docs/icon-inventory.json
|
|
132
133
|
maggie design icon-release-gate --icon-report FILE --browser-report FILE --output FILE
|
|
@@ -161,6 +162,14 @@ Usage:
|
|
|
161
162
|
maggie deployment --project PATH --target vps-with-cloudflare-dns
|
|
162
163
|
maggie deployment worker-secrets --project PATH --environment staging --required RESEND_API_KEY
|
|
163
164
|
maggie deployment secret-parity --manifest api-1.json --manifest api-2.json --required KEY
|
|
165
|
+
maggie deployment bridge-plan|bridge-collect-script --plan bridge-host.json
|
|
166
|
+
maggie deployment bridge-check --plan bridge-host.json --observed observed.json
|
|
167
|
+
maggie mobile preflight|plan --project PATH [--app-dir apps/app] [--profile production] [--platform ios|android|all] [--auto-submit]
|
|
168
|
+
maggie assistant registry-validate|annotations|capability-page|audit-check --registry FILE [--mcp-tools FILE] [--session FILE] [--output FILE]
|
|
169
|
+
maggie assistant approval-selftest
|
|
170
|
+
maggie product release-check --package DIR [--server-json FILE] [--changelog FILE] [--pack]
|
|
171
|
+
maggie product smoke --package DIR | mcp-check --mcp-url URL | review-status --reviews FILE [--chatgpt-plugin FILE]
|
|
172
|
+
maggie skills scaffold|validate|package|smoke --root DIR [--out DIR --prefix NAME --owner NAME] [--claude]
|
|
164
173
|
maggie deployment env-isolation --project PATH --production-env .env.production
|
|
165
174
|
maggie deployment readiness --project PATH
|
|
166
175
|
maggie deployment collect --project PATH --config .maggie/deployment/collector.json
|
|
@@ -187,7 +196,7 @@ Usage:
|
|
|
187
196
|
maggie localization <extract|plan|generate|preview|validate|review|publish|stale|glossary|email-matrix|lifecycle> [options]
|
|
188
197
|
maggie seo performance|images|sitemap|indexnow|social-cards|head-tags [options] (sitemap supports strict validate and agent-files)
|
|
189
198
|
maggie feedback <collect|preview|batch|batch-review|session-summary|submit|list> [options]
|
|
190
|
-
maggie qa <start|record|summary|export|assertion-audit|cors-preflight> [options]
|
|
199
|
+
maggie qa <start|record|summary|export|assertion-audit|cors-preflight|app-preflight> [options]
|
|
191
200
|
maggie site-audit URL [--crawl] [--access-log FILE] [--require-sitemap-request] [--languages en-GB,es-MX,ja-JP] [--check-hreflang] [--check-internal-links]
|
|
192
201
|
maggie site-audit URL --crawl --save-baseline FILE --reviewer NAME
|
|
193
202
|
maggie site-audit URL --crawl --baseline FILE [--reason-all REASON]
|
|
@@ -388,13 +397,13 @@ function diffSummary(source, target) {
|
|
|
388
397
|
return `${added} local additions, ${removed} package lines removed across ${blocks} changed blocks (${localLines.length} local lines vs ${packageLines.length} package lines)`;
|
|
389
398
|
}
|
|
390
399
|
|
|
391
|
-
function syncTree(source, target, force, root = null, managedFiles = {}) {
|
|
400
|
+
function syncTree(source, target, force, root = null, managedFiles = {}, stats = { unchanged: 0, preserved: 0 }) {
|
|
392
401
|
let changed = 0;
|
|
393
402
|
for (const entry of readdirSync(source, { withFileTypes: true })) {
|
|
394
403
|
const sourcePath = join(source, entry.name);
|
|
395
404
|
const targetPath = join(target, entry.name);
|
|
396
405
|
if (entry.isDirectory()) {
|
|
397
|
-
changed += syncTree(sourcePath, targetPath, force, root, managedFiles);
|
|
406
|
+
changed += syncTree(sourcePath, targetPath, force, root, managedFiles, stats);
|
|
398
407
|
continue;
|
|
399
408
|
}
|
|
400
409
|
const managedPath = root ? relative(root, targetPath) : targetPath;
|
|
@@ -406,12 +415,16 @@ function syncTree(source, target, force, root = null, managedFiles = {}) {
|
|
|
406
415
|
writeFileSync(targetPath, readFileSync(sourcePath));
|
|
407
416
|
console.log(`installed ${targetPath}`);
|
|
408
417
|
changed++;
|
|
409
|
-
} else if (
|
|
418
|
+
} else if (packageDigest === localDigest) {
|
|
419
|
+
// Identical content: leave the file and its timestamps untouched.
|
|
420
|
+
stats.unchanged++;
|
|
421
|
+
} else if (force || wasManaged) {
|
|
410
422
|
writeFileSync(targetPath, readFileSync(sourcePath));
|
|
411
423
|
console.log(`updated ${targetPath}`);
|
|
412
424
|
changed++;
|
|
413
425
|
} else {
|
|
414
426
|
console.log(`preserved ${targetPath} (local changes; ${diffSummary(sourcePath, targetPath)}; use --force to replace)`);
|
|
427
|
+
stats.preserved++;
|
|
415
428
|
}
|
|
416
429
|
}
|
|
417
430
|
return changed;
|
|
@@ -545,6 +558,7 @@ function update(args) {
|
|
|
545
558
|
const previousManagedFiles = previousManifest.managedFiles && typeof previousManifest.managedFiles === "object" ? previousManifest.managedFiles : {};
|
|
546
559
|
if (!existsSync(SKILLS_ROOT)) throw new Error("bundled skills are missing; run npm pack from the package source");
|
|
547
560
|
let updated = 0;
|
|
561
|
+
const stats = { unchanged: 0, preserved: 0 };
|
|
548
562
|
const managedRoot = scope === USER_SCOPE ? "/" : root;
|
|
549
563
|
for (const agentRoot of roots) {
|
|
550
564
|
for (const skill of skills) {
|
|
@@ -554,22 +568,22 @@ function update(args) {
|
|
|
554
568
|
console.log(`absent ${target} (run install to add it)`);
|
|
555
569
|
continue;
|
|
556
570
|
}
|
|
557
|
-
updated += syncTree(source, target, force, managedRoot, previousManagedFiles);
|
|
571
|
+
updated += syncTree(source, target, force, managedRoot, previousManagedFiles, stats);
|
|
558
572
|
}
|
|
559
|
-
if (existsSync(REFERENCES_ROOT) && existsSync(join(agentRoot, "references"))) updated += syncTree(REFERENCES_ROOT, join(agentRoot, "references"), force, managedRoot, previousManagedFiles);
|
|
573
|
+
if (existsSync(REFERENCES_ROOT) && existsSync(join(agentRoot, "references"))) updated += syncTree(REFERENCES_ROOT, join(agentRoot, "references"), force, managedRoot, previousManagedFiles, stats);
|
|
560
574
|
}
|
|
561
575
|
if (scope === PROJECT_SCOPE) {
|
|
562
576
|
const tools = join(root, "tools");
|
|
563
577
|
if (existsSync(TOOLS_ROOT)) for (const group of ["clis", "runtime", "integrations"]) if (existsSync(join(TOOLS_ROOT, group))) {
|
|
564
578
|
const target = join(tools, group);
|
|
565
|
-
if (existsSync(target)) updated += syncTree(join(TOOLS_ROOT, group), target, force, root, previousManagedFiles);
|
|
579
|
+
if (existsSync(target)) updated += syncTree(join(TOOLS_ROOT, group), target, force, root, previousManagedFiles, stats);
|
|
566
580
|
}
|
|
567
581
|
if (existsSync(join(DESIGN_ROOT, "SPA-DESIGN.md")) && existsSync(join(root, ".maggie", "design-reference"))) {
|
|
568
|
-
updated += syncTree(DESIGN_ROOT, join(root, ".maggie", "design-reference"), force, root, previousManagedFiles);
|
|
582
|
+
updated += syncTree(DESIGN_ROOT, join(root, ".maggie", "design-reference"), force, root, previousManagedFiles, stats);
|
|
569
583
|
}
|
|
570
|
-
if (existsSync(MARKETPLACE_ROOT) && existsSync(join(root, "marketplace"))) updated += syncTree(MARKETPLACE_ROOT, join(root, "marketplace"), force, root, previousManagedFiles);
|
|
571
|
-
if (existsSync(CONTRACTS_ROOT) && existsSync(join(root, "contracts"))) updated += syncTree(CONTRACTS_ROOT, join(root, "contracts"), force, root, previousManagedFiles);
|
|
572
|
-
if (existsSync(join(TEMPLATES_ROOT, "maggiedash")) && existsSync(join(root, "templates", "maggiedash"))) updated += syncTree(join(TEMPLATES_ROOT, "maggiedash"), join(root, "templates", "maggiedash"), force, root, previousManagedFiles);
|
|
584
|
+
if (existsSync(MARKETPLACE_ROOT) && existsSync(join(root, "marketplace"))) updated += syncTree(MARKETPLACE_ROOT, join(root, "marketplace"), force, root, previousManagedFiles, stats);
|
|
585
|
+
if (existsSync(CONTRACTS_ROOT) && existsSync(join(root, "contracts"))) updated += syncTree(CONTRACTS_ROOT, join(root, "contracts"), force, root, previousManagedFiles, stats);
|
|
586
|
+
if (existsSync(join(TEMPLATES_ROOT, "maggiedash")) && existsSync(join(root, "templates", "maggiedash"))) updated += syncTree(join(TEMPLATES_ROOT, "maggiedash"), join(root, "templates", "maggiedash"), force, root, previousManagedFiles, stats);
|
|
573
587
|
}
|
|
574
588
|
const manifestRoots = scope === USER_SCOPE ? allUserAgentRoots() : roots;
|
|
575
589
|
const updatedUserSkills = scope === USER_SCOPE ? mergedUserSkillNames(manifestRoots) : [];
|
|
@@ -577,8 +591,8 @@ function update(args) {
|
|
|
577
591
|
? { scope, version: PACKAGE_VERSION, agents: manifestRoots, skills: updatedUserSkills, skillsByAgent: userSkillInventory(manifestRoots), managedFiles: userManagedFileDigests(manifestRoots, updatedUserSkills, previousManagedFiles), updated_at: new Date().toISOString() }
|
|
578
592
|
: { scope, version: PACKAGE_VERSION, agents: roots.map((item) => item.slice(root.length + 1)), skills: mergedSkillNames(root, skills), managedFiles: managedFileDigests(root, roots, skills, previousManagedFiles), updated_at: new Date().toISOString() };
|
|
579
593
|
writeInstallManifest(root, manifest, scope);
|
|
580
|
-
console.log(`Maggie ${scope} update complete: ${updated} files changed`);
|
|
581
|
-
if (
|
|
594
|
+
console.log(`Maggie ${scope} update complete: ${updated} files changed, ${stats.unchanged} unchanged, ${stats.preserved} preserved`);
|
|
595
|
+
if (stats.preserved) console.log("Local files with changes were preserved. Review the output and rerun with --force only when replacement is intended.");
|
|
582
596
|
}
|
|
583
597
|
|
|
584
598
|
function list() {
|
|
@@ -776,6 +790,11 @@ try {
|
|
|
776
790
|
else if (command === "docs") docs(args);
|
|
777
791
|
else if (command === "seo") seo(args);
|
|
778
792
|
else if (command === "ops") workflowCli("maggie_ops.py", args);
|
|
793
|
+
else if (command === "deployment" && ["bridge-plan", "bridge-collect-script", "bridge-check"].includes(args[0])) workflowCli("maggie_bridge_host.py", args);
|
|
794
|
+
else if (command === "mobile") workflowCli("maggie_mobile.py", args);
|
|
795
|
+
else if (command === "assistant") workflowCli("maggie_assistant_tools.py", args);
|
|
796
|
+
else if (command === "product") workflowCli("maggie_product_release.py", args);
|
|
797
|
+
else if (command === "skills") workflowCli("maggie_skill_catalog.py", args);
|
|
779
798
|
else if (command === "deployment" && args[0] === "canary") workflowCli("maggie_deployment_canary.py", args.slice(1));
|
|
780
799
|
else if (command === "deployment" && args[0] === "readiness") workflowCli("maggie_deployment_readiness.py", args.slice(1));
|
|
781
800
|
else if (command === "deployment" && args[0] === "auth-canary") workflowCli("maggie_deployment_auth_canary.py", args.slice(1));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "maggie-assistant-tool-registry.v1",
|
|
3
|
+
"gates": {
|
|
4
|
+
"verified-site": {"label": "Needs a verified website", "modelNote": "Fails until the site is verified."},
|
|
5
|
+
"credits": {"label": "Uses a post credit", "modelNote": "Consumes one credit per call."},
|
|
6
|
+
"ai-generation": {"label": "Uses AI generation", "modelNote": "Counts against the AI generation allowance."}
|
|
7
|
+
},
|
|
8
|
+
"tools": [
|
|
9
|
+
{"name": "report_traffic", "description": "Return sessions and conversions for the current website over a date range.", "risk": "read", "scope": "workspace", "channels": ["in-app", "mcp", "chatgpt", "claude"], "user": {"label": "Show your traffic", "detail": "Visits and conversions for a date range."}},
|
|
10
|
+
{"name": "post_draft_create", "description": "Create a draft social post for the current website from a brief.", "risk": "write-reversible", "scope": "workspace", "channels": ["in-app", "mcp"], "gates": ["ai-generation"], "user": {"label": "Draft a social post", "detail": "Writes a draft you can edit; nothing is published.", "confirm": "Create a draft post from this brief?"}},
|
|
11
|
+
{"name": "post_schedule", "description": "Schedule an approved post on a connected channel at a time.", "risk": "write-spends", "scope": "workspace", "channels": ["in-app", "mcp"], "gates": ["credits", "verified-site"], "user": {"label": "Schedule a post", "detail": "Uses one post credit when it goes out.", "confirm": "Schedule this post for the time shown?"}},
|
|
12
|
+
{"name": "post_publish_now", "description": "Publish an approved post immediately on a connected channel.", "risk": "write-public", "scope": "workspace", "channels": ["in-app", "mcp"], "gates": ["credits", "verified-site"], "user": {"label": "Publish a post now", "detail": "Goes live straight away and cannot be unpublished from here.", "confirm": "Publish this post now? It will be public."}},
|
|
13
|
+
{"name": "website_add", "description": "Add a website to the account.", "risk": "write-reversible", "scope": "account", "channels": ["in-app", "mcp"], "audit": {"scope": "account"}, "user": {"label": "Add a website", "detail": "Adds it to your account; you can remove it later.", "confirm": "Add this website to your account?"}},
|
|
14
|
+
{"name": "billing_change_plan", "description": "Change the subscription plan.", "risk": "never", "scope": "account", "channels": ["in-app"], "user": {"label": "Change your plan", "detail": "Open Billing in the app to change plans."}}
|
|
15
|
+
],
|
|
16
|
+
"cantDo": [
|
|
17
|
+
{"text": "Read your private messages on social networks.", "instead": "Paste the message you want help with."}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/contracts/maggie-assistant-tools/tool-registry-v1.schema.json",
|
|
4
|
+
"title": "Maggie assistant tool registry",
|
|
5
|
+
"description": "One definition per tool, exported by the product and shared by the in-app agent, MCP server and ChatGPT/Claude apps. Model-facing description and user-facing copy are separate fields. Checked by `maggie assistant registry-validate`.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["schemaVersion", "tools"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schemaVersion": {"const": "maggie-assistant-tool-registry.v1"},
|
|
10
|
+
"gates": {
|
|
11
|
+
"description": "Preconditions a tool may require, e.g. credits, AI generation, verified site.",
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": {"type": "object", "required": ["label"], "properties": {"label": {"type": "string"}, "modelNote": {"type": "string"}}}
|
|
14
|
+
},
|
|
15
|
+
"tools": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"minItems": 1,
|
|
18
|
+
"items": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"required": ["name", "description", "risk", "scope", "channels", "user"],
|
|
21
|
+
"properties": {
|
|
22
|
+
"name": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$", "maxLength": 64},
|
|
23
|
+
"description": {"type": "string", "minLength": 1, "description": "Model-facing; never shown to people."},
|
|
24
|
+
"risk": {"enum": ["read", "write-reversible", "write-spends", "write-public", "never", "R0", "W1", "W2", "W3", "W4"]},
|
|
25
|
+
"scope": {"enum": ["account", "workspace"]},
|
|
26
|
+
"channels": {"type": "array", "minItems": 1, "items": {"enum": ["in-app", "mcp", "chatgpt", "claude", "cli"]}},
|
|
27
|
+
"gates": {"type": "array", "items": {"type": "string"}},
|
|
28
|
+
"idempotent": {"type": "boolean"},
|
|
29
|
+
"openWorld": {"type": "boolean"},
|
|
30
|
+
"hidden": {"type": "boolean", "description": "Omit from the capability page (e.g. host-only helpers)."},
|
|
31
|
+
"user": {
|
|
32
|
+
"type": "object",
|
|
33
|
+
"required": ["label"],
|
|
34
|
+
"properties": {
|
|
35
|
+
"label": {"type": "string", "maxLength": 60},
|
|
36
|
+
"detail": {"type": "string"},
|
|
37
|
+
"confirm": {"type": "string", "description": "Approval-card sentence; required for writes."},
|
|
38
|
+
"status": {"type": "string", "description": "Shown while the tool runs."}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"audit": {"type": "object", "properties": {"scope": {"enum": ["account", "workspace"]}}}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"cantDo": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"items": {"type": "object", "required": ["text"], "properties": {"text": {"type": "string"}, "instead": {"type": "string"}}}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "maggie-bridge-host.v1",
|
|
3
|
+
"tenantsRoot": "/srv/bridge/tenants",
|
|
4
|
+
"isolation": {
|
|
5
|
+
"uidPerTenant": true,
|
|
6
|
+
"uidRange": [20000, 29999],
|
|
7
|
+
"tenantDirMode": "0700",
|
|
8
|
+
"parentDirMode": "0711",
|
|
9
|
+
"cleanEnvironment": true,
|
|
10
|
+
"envAllowlist": ["HOME", "PATH", "LANG", "TZ"],
|
|
11
|
+
"ownerPinning": true,
|
|
12
|
+
"nonDumpable": true
|
|
13
|
+
},
|
|
14
|
+
"network": {"proxy": "nginx", "publicBind": "127.0.0.1:3210", "adminBind": "127.0.0.1:3211", "adminProxied": false},
|
|
15
|
+
"capacity": {"maxSessions": 20, "eviction": "lru-idle", "idleTimeoutMinutes": 15},
|
|
16
|
+
"recycle": {"on": ["mcp", "skills", "cli"], "busySessions": "after-current-turn"},
|
|
17
|
+
"image": {
|
|
18
|
+
"label": "com.example.app=bridge-host",
|
|
19
|
+
"retain": 2,
|
|
20
|
+
"healthcheck": {"path": "/health", "attempts": 30, "intervalSeconds": 2},
|
|
21
|
+
"rollback": true,
|
|
22
|
+
"readOnlyRootfs": true,
|
|
23
|
+
"capDropAll": true,
|
|
24
|
+
"noNewPrivileges": true
|
|
25
|
+
},
|
|
26
|
+
"providers": [
|
|
27
|
+
{"name": "assistant-cli", "accountType": "customer-own", "termsUrl": "https://example.com/terms", "termsReviewedAt": "2026-10-01"}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/TOPY-AI-LTD/ai-cmo-skills/blob/main/contracts/maggie-design/mobile-app-evidence-v1.schema.json",
|
|
4
|
+
"title": "Maggie mobile app runtime evidence",
|
|
5
|
+
"description": "Written by `maggie design app-collect`, read by `maggie design app-validate`. Per-viewport entries are authoritative; no credentials, storage or page text.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["schemaVersion", "route", "auth", "viewports"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schemaVersion": {"const": "maggie-mobile-app-evidence.v1"},
|
|
10
|
+
"collector": {"type": "string"},
|
|
11
|
+
"route": {"type": "string", "pattern": "^/"},
|
|
12
|
+
"auth": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"properties": {
|
|
15
|
+
"signedIn": {"type": "boolean"},
|
|
16
|
+
"sessionMode": {"enum": ["attached-host-session", "dedicated-profile", "manual"]},
|
|
17
|
+
"credentialsRecorded": {"const": false}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"shell": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"fixedHeader": {"type": "boolean"},
|
|
24
|
+
"fixedFooter": {"type": "boolean"},
|
|
25
|
+
"scrollOwnerCount": {"description": "Legacy; ignored by app-validate.", "type": "integer"},
|
|
26
|
+
"method": {"type": "string"}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"capabilities": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": {"type": "object", "properties": {"states": {"type": "array", "items": {"type": "string"}}}}
|
|
32
|
+
},
|
|
33
|
+
"viewports": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": ["desktop", "tablet", "mobile"],
|
|
36
|
+
"additionalProperties": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"required": ["width", "height", "scrollOwners"],
|
|
39
|
+
"properties": {
|
|
40
|
+
"width": {"type": "integer", "minimum": 1},
|
|
41
|
+
"height": {"type": "integer", "minimum": 1},
|
|
42
|
+
"deviceScaleFactor": {"type": "number", "exclusiveMinimum": 0},
|
|
43
|
+
"scrollOwners": {"type": "integer", "minimum": 0},
|
|
44
|
+
"fixedHeader": {"type": "boolean"},
|
|
45
|
+
"fixedFooter": {"type": "boolean"},
|
|
46
|
+
"tabBar": {"enum": ["bottom", "top", "side", "inline", "none"]},
|
|
47
|
+
"fullPage": {"type": "boolean"},
|
|
48
|
+
"screenshot": {"type": "string"}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"warnings": {"type": "array", "items": {"type": "string"}}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -31,10 +31,18 @@
|
|
|
31
31
|
},
|
|
32
32
|
"auth": {
|
|
33
33
|
"type": "object",
|
|
34
|
-
"required": [
|
|
34
|
+
"required": [
|
|
35
|
+
"mode",
|
|
36
|
+
"required",
|
|
37
|
+
"credentialPolicy"
|
|
38
|
+
],
|
|
35
39
|
"properties": {
|
|
36
40
|
"mode": {
|
|
37
|
-
"enum": [
|
|
41
|
+
"enum": [
|
|
42
|
+
"email-password",
|
|
43
|
+
"existing-session",
|
|
44
|
+
"none"
|
|
45
|
+
]
|
|
38
46
|
},
|
|
39
47
|
"required": {
|
|
40
48
|
"type": "boolean"
|
|
@@ -47,41 +55,116 @@
|
|
|
47
55
|
},
|
|
48
56
|
"shell": {
|
|
49
57
|
"type": "object",
|
|
50
|
-
"required": [
|
|
58
|
+
"required": [
|
|
59
|
+
"fixedHeader",
|
|
60
|
+
"fixedFooter"
|
|
61
|
+
],
|
|
51
62
|
"properties": {
|
|
52
|
-
"fixedHeader": {
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
"fixedHeader": {
|
|
64
|
+
"const": true
|
|
65
|
+
},
|
|
66
|
+
"fixedFooter": {
|
|
67
|
+
"const": true
|
|
68
|
+
},
|
|
69
|
+
"oneScrollOwner": {
|
|
70
|
+
"type": "boolean"
|
|
71
|
+
},
|
|
72
|
+
"scrollOwners": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"properties": {
|
|
75
|
+
"default": {
|
|
76
|
+
"const": 1
|
|
77
|
+
},
|
|
78
|
+
"intentionalPanes": {
|
|
79
|
+
"type": "array",
|
|
80
|
+
"items": {
|
|
81
|
+
"type": "object",
|
|
82
|
+
"required": [
|
|
83
|
+
"name",
|
|
84
|
+
"minWidth",
|
|
85
|
+
"scrollOwners"
|
|
86
|
+
],
|
|
87
|
+
"properties": {
|
|
88
|
+
"name": {
|
|
89
|
+
"type": "string",
|
|
90
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
91
|
+
},
|
|
92
|
+
"minWidth": {
|
|
93
|
+
"type": "integer",
|
|
94
|
+
"minimum": 100
|
|
95
|
+
},
|
|
96
|
+
"scrollOwners": {
|
|
97
|
+
"type": "integer",
|
|
98
|
+
"minimum": 2,
|
|
99
|
+
"maximum": 4
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
55
106
|
},
|
|
107
|
+
"anyOf": [
|
|
108
|
+
{
|
|
109
|
+
"required": [
|
|
110
|
+
"oneScrollOwner"
|
|
111
|
+
],
|
|
112
|
+
"properties": {
|
|
113
|
+
"oneScrollOwner": {
|
|
114
|
+
"const": true
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"required": [
|
|
120
|
+
"scrollOwners"
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
],
|
|
56
124
|
"additionalProperties": true
|
|
57
125
|
},
|
|
58
126
|
"camera": {
|
|
59
127
|
"type": "object",
|
|
60
|
-
"required": [
|
|
128
|
+
"required": [
|
|
129
|
+
"requiredStates"
|
|
130
|
+
],
|
|
61
131
|
"properties": {
|
|
62
132
|
"requiredStates": {
|
|
63
133
|
"type": "array",
|
|
64
|
-
"
|
|
134
|
+
"items": {
|
|
135
|
+
"type": "string"
|
|
136
|
+
}
|
|
65
137
|
},
|
|
66
138
|
"controls": {
|
|
67
|
-
"type": "array"
|
|
68
|
-
"minItems": 4
|
|
139
|
+
"type": "array"
|
|
69
140
|
},
|
|
70
141
|
"fallback": {
|
|
71
|
-
"type": "string"
|
|
72
|
-
|
|
142
|
+
"type": "string"
|
|
143
|
+
},
|
|
144
|
+
"notApplicable": {
|
|
145
|
+
"type": "string"
|
|
73
146
|
}
|
|
74
147
|
},
|
|
75
148
|
"additionalProperties": true
|
|
76
149
|
},
|
|
77
150
|
"viewports": {
|
|
78
151
|
"type": "object",
|
|
79
|
-
"required": [
|
|
152
|
+
"required": [
|
|
153
|
+
"desktop",
|
|
154
|
+
"tablet",
|
|
155
|
+
"mobile"
|
|
156
|
+
],
|
|
80
157
|
"additionalProperties": {
|
|
81
158
|
"type": "array",
|
|
82
159
|
"prefixItems": [
|
|
83
|
-
{
|
|
84
|
-
|
|
160
|
+
{
|
|
161
|
+
"type": "integer",
|
|
162
|
+
"minimum": 1
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"type": "integer",
|
|
166
|
+
"minimum": 1
|
|
167
|
+
}
|
|
85
168
|
],
|
|
86
169
|
"minItems": 2,
|
|
87
170
|
"maxItems": 2
|
|
@@ -89,10 +172,48 @@
|
|
|
89
172
|
},
|
|
90
173
|
"requiredSteps": {
|
|
91
174
|
"type": "array",
|
|
92
|
-
"contains": {
|
|
175
|
+
"contains": {
|
|
176
|
+
"const": "signed-in-browser-qa"
|
|
177
|
+
}
|
|
93
178
|
},
|
|
94
179
|
"publicWrite": {
|
|
95
180
|
"const": false
|
|
181
|
+
},
|
|
182
|
+
"capabilities": {
|
|
183
|
+
"type": "object",
|
|
184
|
+
"propertyNames": {
|
|
185
|
+
"enum": [
|
|
186
|
+
"camera",
|
|
187
|
+
"location",
|
|
188
|
+
"notifications",
|
|
189
|
+
"media-library"
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
"additionalProperties": {
|
|
193
|
+
"type": "object",
|
|
194
|
+
"required": [
|
|
195
|
+
"requiredStates"
|
|
196
|
+
],
|
|
197
|
+
"properties": {
|
|
198
|
+
"requiredStates": {
|
|
199
|
+
"type": "array",
|
|
200
|
+
"items": {
|
|
201
|
+
"type": "string"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"patterns": {
|
|
208
|
+
"type": "array",
|
|
209
|
+
"items": {
|
|
210
|
+
"enum": [
|
|
211
|
+
"tabbed-modal",
|
|
212
|
+
"editor-sheet-assistant",
|
|
213
|
+
"usage-hero",
|
|
214
|
+
"site-switcher"
|
|
215
|
+
]
|
|
216
|
+
}
|
|
96
217
|
}
|
|
97
218
|
},
|
|
98
219
|
"additionalProperties": true
|