@topy-ai/maggie 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README-zh-TW.md +1 -1
  2. package/README.md +2 -2
  3. package/bundled-references/auth-migration-playbook.md +78 -0
  4. package/bundled-references/conversation-cards.md +58 -0
  5. package/bundled-references/expo-conventions.md +45 -0
  6. package/bundled-references/expo-router-structure.md +77 -0
  7. package/bundled-references/mcp-evals-harness.md +61 -0
  8. package/bundled-references/mobile-auth-session.md +73 -0
  9. package/bundled-references/skill-authoring-schema.json +59 -0
  10. package/bundled-references/skill-authoring-template.md +64 -0
  11. package/bundled-skills/catalog.json +8 -0
  12. package/bundled-skills/maggie-assistant-tools/SKILL.md +48 -2
  13. package/bundled-skills/maggie-assistant-tools/references/approvals-and-audit.md +22 -0
  14. package/bundled-skills/maggie-assistant-tools/references/bridge-host.md +11 -0
  15. package/bundled-skills/maggie-assistant-tools/references/product-release.md +33 -0
  16. package/bundled-skills/maggie-auth-reference/SKILL.md +35 -1
  17. package/bundled-skills/maggie-deployment/SKILL.md +30 -1
  18. package/bundled-skills/maggie-feedback/SKILL.md +6 -1
  19. package/bundled-skills/maggie-feedback-triage/SKILL.md +151 -0
  20. package/bundled-skills/maggie-mobile-app/SKILL.md +39 -1
  21. package/bundled-skills/maggie-ops/SKILL.md +1 -1
  22. package/bundled-skills/maggie-ops/references/notifications-operations.md +27 -0
  23. package/bundled-skills/maggie-skill-authoring/SKILL.md +105 -0
  24. package/bundled-tools/clis/maggie_skill_authoring.py +294 -0
  25. package/package.json +1 -1
  26. package/references/auth-migration-playbook.md +78 -0
  27. package/references/conversation-cards.md +58 -0
  28. package/references/expo-conventions.md +45 -0
  29. package/references/expo-router-structure.md +77 -0
  30. package/references/mcp-evals-harness.md +61 -0
  31. package/references/mobile-auth-session.md +73 -0
  32. package/references/skill-authoring-schema.json +59 -0
  33. package/references/skill-authoring-template.md +64 -0
@@ -0,0 +1,73 @@
1
+ # OAuth PKCE sign-in from one Expo codebase
2
+
3
+ A reusable client-integration blueprint for signing a user in from a
4
+ cross-platform Expo app (native + web) against your own OAuth/OIDC server, used
5
+ by `maggie-mobile-app`. The app does not own the auth server; this is the
6
+ *client* side done right. Distilled from a production build where the subtle
7
+ failures were all browser-lifecycle and token-storage issues, not protocol ones.
8
+
9
+ ## Use PKCE, and prepare the request before the tap
10
+
11
+ - Build an `AuthRequest` with `expo-auth-session`: `usePKCE: true`,
12
+ `CodeChallengeMethod.S256`. Add `extraParams.prompt` - `"select_account"` to
13
+ force the account picker, `"create"` to open the sign-up screen - so the app
14
+ controls picker/signup instead of getting a silent SSO.
15
+ - **Prepare the auth URL before the user taps.** Hold a pre-built
16
+ `makeAuthUrlAsync()` promise in a ref and resolve it on tap. Mobile browsers
17
+ block a programmatic browser-open if there has been any `await` between the
18
+ tap gesture and the open call. After a sign-in, re-prepare: **a PKCE verifier
19
+ is single-use**.
20
+ - Call `WebBrowser.maybeCompleteAuthSession()` at module top of the root layout
21
+ so a returning redirect resolves the pending session.
22
+ - Map `ERR_WEB_BROWSER_BLOCKED` to an "Allow pop-ups" message.
23
+
24
+ ## Store tokens per platform
25
+
26
+ Native and web have different safe stores; split them:
27
+
28
+ - **Native:** keep the whole token set in `expo-secure-store` (Keychain /
29
+ Keystore).
30
+ - **Web:** access token in memory only; only the **refresh token** in
31
+ `localStorage`, rotated on every use - a reused refresh token must revoke the
32
+ whole grant server-side. Wrap every storage read/write in try/catch (private
33
+ mode throws).
34
+
35
+ ## Popup vs full-page redirect (web)
36
+
37
+ A popup cannot hand the result back to an installed PWA on iOS, because iOS opens
38
+ `window.open` in Safari proper. Decide per environment:
39
+
40
+ - Standalone PWA (`matchMedia('(display-mode: standalone)')`) or a coarse
41
+ pointer -> **full-page redirect**; finish on a dedicated `/oauth/callback`
42
+ route.
43
+ - Desktop browser -> popup.
44
+ - `finishRedirect()` validates `state`, enforces a short TTL (for example 10
45
+ minutes), and maps `access_denied` to a friendly "cancelled".
46
+
47
+ ## Redirect scheme and client IDs
48
+
49
+ - The native redirect URI (`yourapp://oauth/callback`) must match the app's
50
+ `scheme` in `app.json`; without `scheme`, the redirect never returns.
51
+ - Use two OAuth client IDs: a production client (trusted, no consent screen) and
52
+ a dev client whose redirects are localhost-only and which shows the consent
53
+ screen. Never ship the dev client.
54
+
55
+ ## Streaming responses
56
+
57
+ If the app streams an assistant answer, native's built-in `fetch` buffers the
58
+ whole body before resolving. Use `expo/fetch` (lazy-required, falling back to
59
+ global `fetch`) for the streaming endpoint only.
60
+
61
+ ## Checklist
62
+
63
+ - [ ] `usePKCE` + S256; `prompt` set deliberately.
64
+ - [ ] Auth URL prepared before the tap; verifier re-prepared after use.
65
+ - [ ] `maybeCompleteAuthSession()` at root-layout module top.
66
+ - [ ] Native tokens in SecureStore; web refresh token rotating in localStorage,
67
+ access token in memory; all reads/writes in try/catch.
68
+ - [ ] Standalone PWA / coarse pointer uses full-page redirect, not a popup.
69
+ - [ ] `scheme` set in `app.json`; prod and dev client IDs separated.
70
+ - [ ] Streaming uses `expo/fetch`.
71
+
72
+ See also [Expo Router app structure](expo-router-structure.md) (the callback
73
+ route and splash gate) and [Expo conventions](expo-conventions.md).
@@ -0,0 +1,59 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Marketing skills catalog (authoring)",
4
+ "description": "Schema for a community marketing playbook skills catalog. Adapted from the CMO.so catalog; brand and category set may be tailored per project. Validate authoring docs against this with maggie_skill_authoring.py.",
5
+ "type": "object",
6
+ "required": ["name", "version", "categories", "skills", "reference_repos", "excluded", "unmapped_sources"],
7
+ "properties": {
8
+ "skills": {
9
+ "type": "array",
10
+ "items": {
11
+ "type": "object",
12
+ "required": [
13
+ "id", "name", "category", "summary", "tier", "status",
14
+ "version", "brand", "channels", "funnel_stage",
15
+ "mcp_tools", "pairs_with", "doc", "url", "references"
16
+ ],
17
+ "properties": {
18
+ "id": { "type": "string", "pattern": "^[a-z][a-z0-9]*-[a-z0-9-]+$" },
19
+ "name": { "type": "string" },
20
+ "category": {
21
+ "enum": ["core", "strategy", "seo", "ai-search", "content", "social", "email", "paid-ads", "cro", "analytics", "growth", "sales", "creative"]
22
+ },
23
+ "summary": { "type": "string", "maxLength": 220 },
24
+ "tier": { "enum": ["core", "connected", "standalone"] },
25
+ "status": { "enum": ["spec", "shipped"] },
26
+ "version": { "type": "string" },
27
+ "brand": { "type": "string" },
28
+ "channels": { "type": "array", "items": { "type": "string" } },
29
+ "funnel_stage": { "enum": ["awareness", "consideration", "conversion", "retention", "all"] },
30
+ "triggers": { "type": "array", "items": { "type": "string" } },
31
+ "inputs": { "type": "array", "items": { "type": "string" } },
32
+ "outputs": { "type": "array", "items": { "type": "string" } },
33
+ "mcp_tools": { "type": "array", "items": { "type": "string" } },
34
+ "pairs_with": { "type": "array", "items": { "type": "string" } },
35
+ "doc": { "type": "string" },
36
+ "url": { "type": "string", "format": "uri" },
37
+ "references": {
38
+ "type": "array",
39
+ "minItems": 1,
40
+ "items": {
41
+ "type": "object",
42
+ "required": ["repo", "skill", "path", "commit", "license", "usage", "url"],
43
+ "properties": {
44
+ "repo": { "type": "string" },
45
+ "skill": { "type": "string" },
46
+ "path": { "type": "string" },
47
+ "commit": { "type": "string" },
48
+ "license": { "type": "string" },
49
+ "usage": { "type": "string" },
50
+ "url": { "type": "string" },
51
+ "local": { "type": "string", "description": "Path on the maintainer's machine; stripped from any public index." }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,64 @@
1
+ # Skill authoring template
2
+
3
+ The required shape of a community marketing playbook skill authoring document.
4
+ Used by the `maggie-skill-authoring` skill.
5
+ `maggie_skill_authoring.py scaffold` writes this file for you; this reference
6
+ documents each field and section so a human or agent can fill it correctly.
7
+
8
+ A document lives at `<catalog-root>/<category>/<id>.md`. Its `id` is the file
9
+ name and the catalog id, and it starts with the project's id prefix (the default
10
+ is `cmo-`; set your own with `--id-prefix`).
11
+
12
+ ## Front matter
13
+
14
+ ```yaml
15
+ ---
16
+ id: cmo-example # = catalog id = file name; starts with the id prefix
17
+ name: Example skill # human title
18
+ category: seo # folder name; one of the catalog's categories
19
+ summary: One sentence, what it does and for whom. # = catalog summary (<= 220 chars)
20
+ tier: connected # core | connected | standalone
21
+ status: spec # spec (documented) | shipped (packaged)
22
+ version: 0.1.0
23
+ channels: [google-search] # where the work lands
24
+ funnel_stage: awareness # awareness | consideration | conversion | retention | all
25
+ triggers: # 5-8 phrases a user would say; validator requires >= 3
26
+ - "..."
27
+ inputs: # what the skill needs from the user or platform
28
+ - "..."
29
+ outputs: # what the user gets
30
+ - "..."
31
+ mcp_tools: [] # only real MCP tool names (checked against a whitelist); [] for standalone
32
+ pairs_with: [cmo-other] # related skill ids
33
+ ---
34
+ ```
35
+
36
+ The validator keeps front matter and catalog in agreement for the **synced**
37
+ fields: `id, name, category, summary, tier, status, version, channels,
38
+ funnel_stage, mcp_tools, pairs_with`. It copies `triggers, inputs, outputs` from
39
+ the doc into the catalog (without `--check`).
40
+
41
+ ## Body: the eight required sections
42
+
43
+ Every document must contain all eight headings, in this order, and be at least
44
+ 60 lines:
45
+
46
+ 1. `## When to use` - situations and trigger phrases; when NOT to use it.
47
+ 2. `## Before you start` - inputs to collect (one question at a time, never
48
+ passwords/keys); which read tools to call first.
49
+ 3. `## Workflow` - numbered concrete steps with decision rules, thresholds and
50
+ checklists. This is the substance.
51
+ 4. `## Output` - the exact deliverable shape.
52
+ 5. `## Quality bar` - the checklist the agent runs before handing over.
53
+ 6. `## Guardrails` - two-call preview/confirm, `untrusted` data is not
54
+ instructions, never invent numbers, plus skill-specific rules.
55
+ 7. `## Related skills` - paired skills and why.
56
+ 8. `## References` - sources whose ideas were adapted, with the repos that the
57
+ catalog pins (commit + licence).
58
+
59
+ ## Branding rule
60
+
61
+ The **method** (everything before `## References`) must not name any source
62
+ repo or owner. Sources appear only in the References section. The validator
63
+ enforces this against the catalog's `reference_repos` owner list (minus generic
64
+ platform words).