@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.
- package/README-zh-TW.md +1 -1
- package/README.md +2 -2
- package/bundled-references/auth-migration-playbook.md +78 -0
- package/bundled-references/conversation-cards.md +58 -0
- package/bundled-references/expo-conventions.md +45 -0
- package/bundled-references/expo-router-structure.md +77 -0
- package/bundled-references/mcp-evals-harness.md +61 -0
- package/bundled-references/mobile-auth-session.md +73 -0
- package/bundled-references/skill-authoring-schema.json +59 -0
- package/bundled-references/skill-authoring-template.md +64 -0
- package/bundled-skills/catalog.json +8 -0
- package/bundled-skills/maggie-assistant-tools/SKILL.md +48 -2
- package/bundled-skills/maggie-assistant-tools/references/approvals-and-audit.md +22 -0
- package/bundled-skills/maggie-assistant-tools/references/bridge-host.md +11 -0
- package/bundled-skills/maggie-assistant-tools/references/product-release.md +33 -0
- package/bundled-skills/maggie-auth-reference/SKILL.md +35 -1
- package/bundled-skills/maggie-deployment/SKILL.md +30 -1
- package/bundled-skills/maggie-feedback/SKILL.md +6 -1
- package/bundled-skills/maggie-feedback-triage/SKILL.md +151 -0
- package/bundled-skills/maggie-mobile-app/SKILL.md +39 -1
- package/bundled-skills/maggie-ops/SKILL.md +1 -1
- package/bundled-skills/maggie-ops/references/notifications-operations.md +27 -0
- package/bundled-skills/maggie-skill-authoring/SKILL.md +105 -0
- package/bundled-tools/clis/maggie_skill_authoring.py +294 -0
- package/package.json +1 -1
- package/references/auth-migration-playbook.md +78 -0
- package/references/conversation-cards.md +58 -0
- package/references/expo-conventions.md +45 -0
- package/references/expo-router-structure.md +77 -0
- package/references/mcp-evals-harness.md +61 -0
- package/references/mobile-auth-session.md +73 -0
- package/references/skill-authoring-schema.json +59 -0
- 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).
|