@miranda0808/maya-codex 0.1.0
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 +30 -0
- package/bin/maya-codex.js +36 -0
- package/package.json +19 -0
- package/payload/.agents/skills/ab-test-setup/SKILL.md +266 -0
- package/payload/.agents/skills/ab-test-setup/evals/evals.json +105 -0
- package/payload/.agents/skills/ab-test-setup/references/sample-size-guide.md +263 -0
- package/payload/.agents/skills/ab-test-setup/references/test-templates.md +277 -0
- package/payload/.agents/skills/ad-creative/SKILL.md +362 -0
- package/payload/.agents/skills/ad-creative/evals/evals.json +90 -0
- package/payload/.agents/skills/ad-creative/references/generative-tools.md +637 -0
- package/payload/.agents/skills/ad-creative/references/platform-specs.md +213 -0
- package/payload/.agents/skills/ai-seo/SKILL.md +398 -0
- package/payload/.agents/skills/ai-seo/evals/evals.json +90 -0
- package/payload/.agents/skills/ai-seo/references/content-patterns.md +285 -0
- package/payload/.agents/skills/ai-seo/references/platform-ranking-factors.md +152 -0
- package/payload/.agents/skills/analytics-tracking/SKILL.md +309 -0
- package/payload/.agents/skills/analytics-tracking/evals/evals.json +90 -0
- package/payload/.agents/skills/analytics-tracking/references/event-library.md +260 -0
- package/payload/.agents/skills/analytics-tracking/references/ga4-implementation.md +300 -0
- package/payload/.agents/skills/analytics-tracking/references/gtm-implementation.md +390 -0
- package/payload/.agents/skills/churn-prevention/SKILL.md +424 -0
- package/payload/.agents/skills/churn-prevention/evals/evals.json +93 -0
- package/payload/.agents/skills/churn-prevention/references/cancel-flow-patterns.md +316 -0
- package/payload/.agents/skills/churn-prevention/references/dunning-playbook.md +408 -0
- package/payload/.agents/skills/cold-email/SKILL.md +158 -0
- package/payload/.agents/skills/cold-email/evals/evals.json +94 -0
- package/payload/.agents/skills/cold-email/references/benchmarks.md +83 -0
- package/payload/.agents/skills/cold-email/references/follow-up-sequences.md +81 -0
- package/payload/.agents/skills/cold-email/references/frameworks.md +90 -0
- package/payload/.agents/skills/cold-email/references/personalization.md +79 -0
- package/payload/.agents/skills/cold-email/references/subject-lines.md +53 -0
- package/payload/.agents/skills/competitor-alternatives/SKILL.md +256 -0
- package/payload/.agents/skills/competitor-alternatives/evals/evals.json +93 -0
- package/payload/.agents/skills/competitor-alternatives/references/content-architecture.md +271 -0
- package/payload/.agents/skills/competitor-alternatives/references/templates.md +223 -0
- package/payload/.agents/skills/content-strategy/SKILL.md +359 -0
- package/payload/.agents/skills/content-strategy/evals/evals.json +90 -0
- package/payload/.agents/skills/copy-editing/SKILL.md +447 -0
- package/payload/.agents/skills/copy-editing/evals/evals.json +89 -0
- package/payload/.agents/skills/copy-editing/references/plain-english-alternatives.md +394 -0
- package/payload/.agents/skills/copywriting/SKILL.md +252 -0
- package/payload/.agents/skills/copywriting/evals/evals.json +111 -0
- package/payload/.agents/skills/copywriting/references/copy-frameworks.md +344 -0
- package/payload/.agents/skills/copywriting/references/natural-transitions.md +272 -0
- package/payload/.agents/skills/email-sequence/SKILL.md +309 -0
- package/payload/.agents/skills/email-sequence/evals/evals.json +93 -0
- package/payload/.agents/skills/email-sequence/references/copy-guidelines.md +113 -0
- package/payload/.agents/skills/email-sequence/references/email-types.md +515 -0
- package/payload/.agents/skills/email-sequence/references/sequence-templates.md +168 -0
- package/payload/.agents/skills/form-cro/SKILL.md +429 -0
- package/payload/.agents/skills/form-cro/evals/evals.json +90 -0
- package/payload/.agents/skills/free-tool-strategy/SKILL.md +178 -0
- package/payload/.agents/skills/free-tool-strategy/evals/evals.json +90 -0
- package/payload/.agents/skills/free-tool-strategy/references/tool-types.md +217 -0
- package/payload/.agents/skills/launch-strategy/SKILL.md +353 -0
- package/payload/.agents/skills/launch-strategy/evals/evals.json +91 -0
- package/payload/.agents/skills/marketing-ideas/SKILL.md +167 -0
- package/payload/.agents/skills/marketing-ideas/evals/evals.json +90 -0
- package/payload/.agents/skills/marketing-ideas/references/ideas-by-category.md +366 -0
- package/payload/.agents/skills/marketing-psychology/SKILL.md +455 -0
- package/payload/.agents/skills/marketing-psychology/evals/evals.json +88 -0
- package/payload/.agents/skills/onboarding-cro/SKILL.md +220 -0
- package/payload/.agents/skills/onboarding-cro/evals/evals.json +92 -0
- package/payload/.agents/skills/onboarding-cro/references/experiments.md +258 -0
- package/payload/.agents/skills/page-cro/SKILL.md +182 -0
- package/payload/.agents/skills/page-cro/evals/evals.json +111 -0
- package/payload/.agents/skills/page-cro/references/experiments.md +248 -0
- package/payload/.agents/skills/paid-ads/SKILL.md +315 -0
- package/payload/.agents/skills/paid-ads/evals/evals.json +90 -0
- package/payload/.agents/skills/paid-ads/references/ad-copy-templates.md +207 -0
- package/payload/.agents/skills/paid-ads/references/audience-targeting.md +243 -0
- package/payload/.agents/skills/paid-ads/references/platform-setup-checklists.md +277 -0
- package/payload/.agents/skills/paywall-upgrade-cro/SKILL.md +227 -0
- package/payload/.agents/skills/paywall-upgrade-cro/evals/evals.json +93 -0
- package/payload/.agents/skills/paywall-upgrade-cro/references/experiments.md +164 -0
- package/payload/.agents/skills/popup-cro/SKILL.md +453 -0
- package/payload/.agents/skills/popup-cro/evals/evals.json +94 -0
- package/payload/.agents/skills/pricing-strategy/SKILL.md +231 -0
- package/payload/.agents/skills/pricing-strategy/evals/evals.json +90 -0
- package/payload/.agents/skills/pricing-strategy/references/research-methods.md +152 -0
- package/payload/.agents/skills/pricing-strategy/references/tier-structure.md +232 -0
- package/payload/.agents/skills/product-marketing-context/SKILL.md +27 -0
- package/payload/.agents/skills/product-marketing-context/evals/evals.json +40 -0
- package/payload/.agents/skills/programmatic-seo/SKILL.md +238 -0
- package/payload/.agents/skills/programmatic-seo/evals/evals.json +94 -0
- package/payload/.agents/skills/programmatic-seo/references/playbooks.md +308 -0
- package/payload/.agents/skills/referral-program/SKILL.md +255 -0
- package/payload/.agents/skills/referral-program/evals/evals.json +89 -0
- package/payload/.agents/skills/referral-program/references/affiliate-programs.md +164 -0
- package/payload/.agents/skills/referral-program/references/program-examples.md +143 -0
- package/payload/.agents/skills/revops/SKILL.md +343 -0
- package/payload/.agents/skills/revops/evals/evals.json +91 -0
- package/payload/.agents/skills/revops/references/automation-playbooks.md +290 -0
- package/payload/.agents/skills/revops/references/lifecycle-definitions.md +278 -0
- package/payload/.agents/skills/revops/references/routing-rules.md +203 -0
- package/payload/.agents/skills/revops/references/scoring-models.md +247 -0
- package/payload/.agents/skills/sales-enablement/SKILL.md +349 -0
- package/payload/.agents/skills/sales-enablement/evals/evals.json +91 -0
- package/payload/.agents/skills/sales-enablement/references/deck-frameworks.md +263 -0
- package/payload/.agents/skills/sales-enablement/references/demo-scripts.md +355 -0
- package/payload/.agents/skills/sales-enablement/references/objection-library.md +270 -0
- package/payload/.agents/skills/sales-enablement/references/one-pager-templates.md +208 -0
- package/payload/.agents/skills/schema-markup/SKILL.md +179 -0
- package/payload/.agents/skills/schema-markup/evals/evals.json +87 -0
- package/payload/.agents/skills/schema-markup/references/schema-examples.md +398 -0
- package/payload/.agents/skills/seo-audit/SKILL.md +412 -0
- package/payload/.agents/skills/seo-audit/evals/evals.json +136 -0
- package/payload/.agents/skills/seo-audit/references/ai-writing-detection.md +200 -0
- package/payload/.agents/skills/signup-flow-cro/SKILL.md +359 -0
- package/payload/.agents/skills/signup-flow-cro/evals/evals.json +88 -0
- package/payload/.agents/skills/site-architecture/SKILL.md +357 -0
- package/payload/.agents/skills/site-architecture/evals/evals.json +88 -0
- package/payload/.agents/skills/site-architecture/references/mermaid-templates.md +216 -0
- package/payload/.agents/skills/site-architecture/references/navigation-patterns.md +305 -0
- package/payload/.agents/skills/site-architecture/references/site-type-templates.md +293 -0
- package/payload/.agents/skills/social-content/SKILL.md +278 -0
- package/payload/.agents/skills/social-content/evals/evals.json +92 -0
- package/payload/.agents/skills/social-content/references/platforms.md +170 -0
- package/payload/.agents/skills/social-content/references/post-templates.md +177 -0
- package/payload/.agents/skills/social-content/references/reverse-engineering.md +195 -0
- package/payload/.maya/executor.md +79 -0
- package/payload/.maya/meta-api-agent.md +48 -0
- package/payload/.maya/modes/consult.md +63 -0
- package/payload/.maya/modes/task.md +97 -0
- package/payload/.maya/planner.md +69 -0
- package/payload/.maya/researcher.md +51 -0
- package/payload/.maya/templates/plan.md +77 -0
- package/payload/.maya/templates/state.md +87 -0
- package/payload/.maya/templates/task-packet.md +75 -0
- package/payload/MAYA-CATALOG.md +115 -0
- package/payload/MAYA-DEPENDENCIES.md +58 -0
- package/payload/MAYA.md +151 -0
- package/payload/campaigns/README.md +14 -0
- package/payload/commands/maya-consult.md +28 -0
- package/payload/commands/maya-task.md +38 -0
- package/payload/commands/product.md +55 -0
- package/payload/research/README.md +14 -0
- package/payload/templates/README.md +15 -0
- package/payload/templates/plan.md +77 -0
- package/payload/templates/state.md +87 -0
- package/payload/templates/task-packet.md +75 -0
- package/payload/tools/REGISTRY.md +368 -0
- package/payload/tools/clis/README.md +187 -0
- package/payload/tools/clis/activecampaign.js +435 -0
- package/payload/tools/clis/adobe-analytics.js +161 -0
- package/payload/tools/clis/ahrefs.js +192 -0
- package/payload/tools/clis/amplitude.js +182 -0
- package/payload/tools/clis/apollo.js +142 -0
- package/payload/tools/clis/beehiiv.js +245 -0
- package/payload/tools/clis/brevo.js +368 -0
- package/payload/tools/clis/buffer.js +260 -0
- package/payload/tools/clis/calendly.js +253 -0
- package/payload/tools/clis/clearbit.js +163 -0
- package/payload/tools/clis/customer-io.js +205 -0
- package/payload/tools/clis/dataforseo.js +257 -0
- package/payload/tools/clis/demio.js +149 -0
- package/payload/tools/clis/dub.js +158 -0
- package/payload/tools/clis/g2.js +186 -0
- package/payload/tools/clis/ga4.js +194 -0
- package/payload/tools/clis/google-ads.js +189 -0
- package/payload/tools/clis/google-search-console.js +166 -0
- package/payload/tools/clis/hotjar.js +167 -0
- package/payload/tools/clis/hunter.js +249 -0
- package/payload/tools/clis/instantly.js +270 -0
- package/payload/tools/clis/intercom.js +399 -0
- package/payload/tools/clis/keywords-everywhere.js +185 -0
- package/payload/tools/clis/kit.js +232 -0
- package/payload/tools/clis/klaviyo.js +348 -0
- package/payload/tools/clis/lemlist.js +221 -0
- package/payload/tools/clis/linkedin-ads.js +185 -0
- package/payload/tools/clis/livestorm.js +292 -0
- package/payload/tools/clis/mailchimp.js +220 -0
- package/payload/tools/clis/mention-me.js +161 -0
- package/payload/tools/clis/meta-ads.js +181 -0
- package/payload/tools/clis/mixpanel.js +248 -0
- package/payload/tools/clis/onesignal.js +241 -0
- package/payload/tools/clis/optimizely.js +233 -0
- package/payload/tools/clis/paddle.js +385 -0
- package/payload/tools/clis/partnerstack.js +382 -0
- package/payload/tools/clis/plausible.js +249 -0
- package/payload/tools/clis/postmark.js +375 -0
- package/payload/tools/clis/resend.js +370 -0
- package/payload/tools/clis/rewardful.js +160 -0
- package/payload/tools/clis/savvycal.js +223 -0
- package/payload/tools/clis/segment.js +192 -0
- package/payload/tools/clis/semrush.js +207 -0
- package/payload/tools/clis/sendgrid.js +211 -0
- package/payload/tools/clis/snov.js +237 -0
- package/payload/tools/clis/tiktok-ads.js +190 -0
- package/payload/tools/clis/tolt.js +153 -0
- package/payload/tools/clis/trustpilot.js +276 -0
- package/payload/tools/clis/typeform.js +269 -0
- package/payload/tools/clis/wistia.js +256 -0
- package/payload/tools/clis/zapier.js +160 -0
- package/payload/tools/integrations/activecampaign.md +337 -0
- package/payload/tools/integrations/adobe-analytics.md +156 -0
- package/payload/tools/integrations/ahrefs.md +142 -0
- package/payload/tools/integrations/amplitude.md +135 -0
- package/payload/tools/integrations/apollo.md +148 -0
- package/payload/tools/integrations/beehiiv.md +157 -0
- package/payload/tools/integrations/brevo.md +268 -0
- package/payload/tools/integrations/buffer.md +138 -0
- package/payload/tools/integrations/calendly.md +161 -0
- package/payload/tools/integrations/clearbit.md +142 -0
- package/payload/tools/integrations/customer-io.md +187 -0
- package/payload/tools/integrations/dataforseo.md +165 -0
- package/payload/tools/integrations/demio.md +182 -0
- package/payload/tools/integrations/dub-co.md +160 -0
- package/payload/tools/integrations/g2.md +179 -0
- package/payload/tools/integrations/ga4.md +126 -0
- package/payload/tools/integrations/google-ads.md +159 -0
- package/payload/tools/integrations/google-search-console.md +147 -0
- package/payload/tools/integrations/hotjar.md +147 -0
- package/payload/tools/integrations/hubspot.md +178 -0
- package/payload/tools/integrations/hunter.md +90 -0
- package/payload/tools/integrations/instantly.md +104 -0
- package/payload/tools/integrations/intercom.md +292 -0
- package/payload/tools/integrations/keywords-everywhere.md +207 -0
- package/payload/tools/integrations/kit.md +167 -0
- package/payload/tools/integrations/klaviyo.md +228 -0
- package/payload/tools/integrations/lemlist.md +110 -0
- package/payload/tools/integrations/linkedin-ads.md +164 -0
- package/payload/tools/integrations/livestorm.md +313 -0
- package/payload/tools/integrations/mailchimp.md +150 -0
- package/payload/tools/integrations/mention-me.md +160 -0
- package/payload/tools/integrations/meta-ads.md +147 -0
- package/payload/tools/integrations/mixpanel.md +137 -0
- package/payload/tools/integrations/onesignal.md +229 -0
- package/payload/tools/integrations/optimizely.md +171 -0
- package/payload/tools/integrations/paddle.md +212 -0
- package/payload/tools/integrations/partnerstack.md +222 -0
- package/payload/tools/integrations/plausible.md +177 -0
- package/payload/tools/integrations/posthog.md +151 -0
- package/payload/tools/integrations/postmark.md +234 -0
- package/payload/tools/integrations/resend.md +168 -0
- package/payload/tools/integrations/rewardful.md +147 -0
- package/payload/tools/integrations/salesforce.md +150 -0
- package/payload/tools/integrations/savvycal.md +181 -0
- package/payload/tools/integrations/segment.md +159 -0
- package/payload/tools/integrations/semrush.md +121 -0
- package/payload/tools/integrations/sendgrid.md +161 -0
- package/payload/tools/integrations/shopify.md +176 -0
- package/payload/tools/integrations/snov.md +94 -0
- package/payload/tools/integrations/stripe.md +148 -0
- package/payload/tools/integrations/tiktok-ads.md +161 -0
- package/payload/tools/integrations/tolt.md +144 -0
- package/payload/tools/integrations/trustpilot.md +191 -0
- package/payload/tools/integrations/typeform.md +190 -0
- package/payload/tools/integrations/webflow.md +198 -0
- package/payload/tools/integrations/wistia.md +164 -0
- package/payload/tools/integrations/wordpress.md +175 -0
- package/payload/tools/integrations/zapier.md +150 -0
- package/payload/tools/meta/README.md +55 -0
- package/payload/tools/meta/meta-cache-schema.md +65 -0
- package/payload/tools/meta/meta-fetch.ps1 +324 -0
- package/payload/tools/meta/meta-fetch.test.ps1 +38 -0
- package/vendor/shared-installer/manifests/claude-files.json +13 -0
- package/vendor/shared-installer/manifests/codex-files.json +13 -0
- package/vendor/shared-installer/manifests/common-files.json +13 -0
- package/vendor/shared-installer/package.json +15 -0
- package/vendor/shared-installer/src/bootstrap.js +12 -0
- package/vendor/shared-installer/src/cli-options.js +53 -0
- package/vendor/shared-installer/src/fs.js +105 -0
- package/vendor/shared-installer/src/index.js +44 -0
- package/vendor/shared-installer/src/install.js +157 -0
- package/vendor/shared-installer/src/manifest.js +52 -0
- package/vendor/shared-installer/templates/claude/.claude/skills/.gitkeep +1 -0
- package/vendor/shared-installer/templates/claude/CLAUDE.md +27 -0
- package/vendor/shared-installer/templates/codex/.agent/skills/.gitkeep +1 -0
- package/vendor/shared-installer/templates/codex/AGENTS.md +27 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Zapier
|
|
2
|
+
|
|
3
|
+
Workflow automation platform connecting apps without code.
|
|
4
|
+
|
|
5
|
+
## Capabilities
|
|
6
|
+
|
|
7
|
+
| Integration | Available | Notes |
|
|
8
|
+
|-------------|-----------|-------|
|
|
9
|
+
| API | ✓ | REST API for Zaps, tasks, and webhooks |
|
|
10
|
+
| MCP | ✓ | Available via Zapier MCP server |
|
|
11
|
+
| CLI | - | Not available |
|
|
12
|
+
| SDK | - | API and webhooks only |
|
|
13
|
+
|
|
14
|
+
## Authentication
|
|
15
|
+
|
|
16
|
+
- **Type**: API Key
|
|
17
|
+
- **Header**: `X-API-Key: {api_key}`
|
|
18
|
+
- **Get key**: Settings > API in Zapier account
|
|
19
|
+
|
|
20
|
+
## Common Agent Operations
|
|
21
|
+
|
|
22
|
+
### List Zaps
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
GET https://api.zapier.com/v1/zaps
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Get Zap details
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
GET https://api.zapier.com/v1/zaps/{zap_id}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Turn Zap on/off
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
POST https://api.zapier.com/v1/zaps/{zap_id}/on
|
|
38
|
+
POST https://api.zapier.com/v1/zaps/{zap_id}/off
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Get task history
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
GET https://api.zapier.com/v1/zaps/{zap_id}/tasks
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Get profile info
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
GET https://api.zapier.com/v1/profiles/me
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Webhooks (Triggers)
|
|
54
|
+
|
|
55
|
+
### Catch Hook (receive data)
|
|
56
|
+
|
|
57
|
+
Create a "Webhooks by Zapier" trigger to receive data:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
POST https://hooks.zapier.com/hooks/catch/{webhook_id}/
|
|
61
|
+
|
|
62
|
+
{
|
|
63
|
+
"event": "user.created",
|
|
64
|
+
"user_id": "123",
|
|
65
|
+
"email": "user@example.com"
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Send data to Zapier
|
|
70
|
+
|
|
71
|
+
Most common: trigger a Zap from your app:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
POST https://hooks.zapier.com/hooks/catch/{account_id}/{hook_id}/
|
|
75
|
+
|
|
76
|
+
{
|
|
77
|
+
"name": "John Doe",
|
|
78
|
+
"email": "john@example.com",
|
|
79
|
+
"plan": "pro"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Common Marketing Automations
|
|
84
|
+
|
|
85
|
+
### Lead capture to CRM
|
|
86
|
+
```
|
|
87
|
+
Typeform → Zapier → HubSpot
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### New customer notifications
|
|
91
|
+
```
|
|
92
|
+
Stripe (new customer) → Zapier → Slack
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Email sequence triggers
|
|
96
|
+
```
|
|
97
|
+
Form submission → Zapier → Customer.io
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Social proof automation
|
|
101
|
+
```
|
|
102
|
+
New review → Zapier → Twitter/Slack
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Referral tracking
|
|
106
|
+
```
|
|
107
|
+
New referral → Zapier → Spreadsheet + Slack
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Webhook Payload Structure
|
|
111
|
+
|
|
112
|
+
When sending to Zapier, structure data as flat JSON:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"customer_name": "John Doe",
|
|
117
|
+
"customer_email": "john@example.com",
|
|
118
|
+
"plan_name": "Pro",
|
|
119
|
+
"plan_price": 99,
|
|
120
|
+
"signup_date": "2024-01-15"
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Key Concepts
|
|
125
|
+
|
|
126
|
+
- **Zap** - Automated workflow
|
|
127
|
+
- **Trigger** - Event that starts a Zap
|
|
128
|
+
- **Action** - Task performed by Zap
|
|
129
|
+
- **Task** - Single action execution
|
|
130
|
+
- **Filter** - Conditional logic
|
|
131
|
+
- **Path** - Branching logic
|
|
132
|
+
|
|
133
|
+
## When to Use
|
|
134
|
+
|
|
135
|
+
- Connecting marketing tools without code
|
|
136
|
+
- Automating lead routing
|
|
137
|
+
- Syncing data between platforms
|
|
138
|
+
- Triggering notifications
|
|
139
|
+
- Building marketing workflows
|
|
140
|
+
|
|
141
|
+
## Rate Limits
|
|
142
|
+
|
|
143
|
+
- 100 requests per minute
|
|
144
|
+
- Task limits by plan tier
|
|
145
|
+
|
|
146
|
+
## Relevant Skills
|
|
147
|
+
|
|
148
|
+
- email-sequence
|
|
149
|
+
- analytics-tracking
|
|
150
|
+
- referral-program
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Meta Tool Maintenance
|
|
2
|
+
|
|
3
|
+
## Source
|
|
4
|
+
|
|
5
|
+
- Vendored from the upstream `marketingskills` repository: [coreyhaines31/marketingskills](https://github.com/coreyhaines31/marketingskills)
|
|
6
|
+
- Local CLI file: `tools/clis/meta-ads.js`
|
|
7
|
+
- Approved Maya boundary: `tools/meta/meta-fetch.ps1`
|
|
8
|
+
- Current local API base in the vendored file: `https://graph.facebook.com/v18.0`
|
|
9
|
+
|
|
10
|
+
## Usage Boundary
|
|
11
|
+
|
|
12
|
+
- Agents should prefer `tools/meta/meta-fetch.ps1` for Meta reads.
|
|
13
|
+
- `meta-fetch.ps1` is the Maya-owned boundary for validation, read-only allowlisting, output sanitization, and cache writes.
|
|
14
|
+
- Keep secrets in environment variables only.
|
|
15
|
+
- Do not place raw tokens, headers, or unsafe debug output in prompts, logs, state files, or cache files.
|
|
16
|
+
|
|
17
|
+
## Maintenance Policy
|
|
18
|
+
|
|
19
|
+
- Treat `tools/clis/meta-ads.js` as vendored upstream code.
|
|
20
|
+
- Do not hand-maintain feature changes in the vendored file unless there is an urgent local fix.
|
|
21
|
+
- When the tool stops working, Meta deprecates an API version, or we need a newer endpoint or field, check the exact upstream tool first.
|
|
22
|
+
- Prefer replacing the local vendored file from upstream over accumulating local drift.
|
|
23
|
+
|
|
24
|
+
## Update Triggers
|
|
25
|
+
|
|
26
|
+
Review the upstream `meta-ads.js` when any of the following happens:
|
|
27
|
+
|
|
28
|
+
- Meta returns version deprecation or unsupported endpoint errors.
|
|
29
|
+
- Expected fields disappear or response shapes change.
|
|
30
|
+
- We need a newer Graph API version than the one pinned in the vendored file.
|
|
31
|
+
- The upstream `marketingskills` repo updates the same tool.
|
|
32
|
+
|
|
33
|
+
## Safe Update Workflow
|
|
34
|
+
|
|
35
|
+
1. Compare the local `tools/clis/meta-ads.js` with the upstream `meta-ads.js` in `coreyhaines31/marketingskills`.
|
|
36
|
+
2. Prefer a clean vendor refresh instead of manually mixing old and new logic.
|
|
37
|
+
3. Re-run dry-run and read-only verification commands after updating.
|
|
38
|
+
4. Keep any future Maya-specific safety behavior in wrappers under `tools/meta/`, not inside the vendored CLI unless strictly necessary.
|
|
39
|
+
|
|
40
|
+
## Verification After A Bump
|
|
41
|
+
|
|
42
|
+
Run at minimum:
|
|
43
|
+
|
|
44
|
+
```powershell
|
|
45
|
+
node --check 'tools/clis/meta-ads.js'
|
|
46
|
+
powershell -ExecutionPolicy Bypass -File 'tools/meta/meta-fetch.ps1' -Resource campaigns -Action list -DryRun
|
|
47
|
+
powershell -ExecutionPolicy Bypass -File 'tools/meta/meta-fetch.ps1' -Resource campaigns -Action insights -Id 123 -DatePreset last_30d -DryRun
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Confirm:
|
|
51
|
+
|
|
52
|
+
- syntax still passes
|
|
53
|
+
- dry-run masks authorization data
|
|
54
|
+
- command structure still matches expected usage
|
|
55
|
+
- no local secrets are written to files, prompts, logs, or outputs
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Meta Cache Schema
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Sanitized cache files written by `tools/meta/meta-fetch.ps1` for read-only Meta Ads data access.
|
|
6
|
+
|
|
7
|
+
## Location
|
|
8
|
+
|
|
9
|
+
- Cache directory: `outputs/meta-cache/`
|
|
10
|
+
- One JSON file per non-dry-run fetch
|
|
11
|
+
|
|
12
|
+
## Schema
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"schema_version": 1,
|
|
17
|
+
"source": "meta-ads",
|
|
18
|
+
"safe_account_alias": "acct-***6789",
|
|
19
|
+
"fetched_at": "2026-03-12T10:00:00.0000000+08:00",
|
|
20
|
+
"date_range": {
|
|
21
|
+
"date_preset": "last_30d"
|
|
22
|
+
},
|
|
23
|
+
"normalized_params": {
|
|
24
|
+
"resource": "campaigns",
|
|
25
|
+
"action": "insights",
|
|
26
|
+
"account_id": "acct-***6789",
|
|
27
|
+
"id": "120000000000000001",
|
|
28
|
+
"adset_id": null,
|
|
29
|
+
"date_preset": "last_30d"
|
|
30
|
+
},
|
|
31
|
+
"forbidden_fields": [
|
|
32
|
+
"authorization",
|
|
33
|
+
"access_token",
|
|
34
|
+
"token",
|
|
35
|
+
"secret",
|
|
36
|
+
"password",
|
|
37
|
+
"api_key"
|
|
38
|
+
],
|
|
39
|
+
"payload": {}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Required Fields
|
|
44
|
+
|
|
45
|
+
- `schema_version`: cache schema version number
|
|
46
|
+
- `source`: upstream tool source
|
|
47
|
+
- `safe_account_alias`: masked account identifier
|
|
48
|
+
- `fetched_at`: ISO-8601 fetch timestamp
|
|
49
|
+
- `normalized_params`: normalized request parameters used for the fetch
|
|
50
|
+
- `forbidden_fields`: sensitive fields that must never appear in cache payloads
|
|
51
|
+
- `payload`: sanitized response payload
|
|
52
|
+
|
|
53
|
+
## Optional Fields
|
|
54
|
+
|
|
55
|
+
- `date_range`: included when the underlying fetch uses a date window or preset
|
|
56
|
+
|
|
57
|
+
## Security Rules
|
|
58
|
+
|
|
59
|
+
Cache files must never contain:
|
|
60
|
+
|
|
61
|
+
- raw access tokens
|
|
62
|
+
- authorization headers
|
|
63
|
+
- secrets, passwords, or API keys
|
|
64
|
+
- unsafe debug dumps
|
|
65
|
+
- raw environment variable values
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
param(
|
|
2
|
+
[Parameter(Mandatory = $true)]
|
|
3
|
+
[ValidateSet('accounts', 'campaigns', 'adsets', 'ads', 'audiences')]
|
|
4
|
+
[string]$Resource,
|
|
5
|
+
|
|
6
|
+
[Parameter(Mandatory = $true)]
|
|
7
|
+
[string]$Action,
|
|
8
|
+
|
|
9
|
+
[string]$AccountId,
|
|
10
|
+
[string]$Id,
|
|
11
|
+
[string]$AdsetId,
|
|
12
|
+
[string]$DatePreset = 'last_30d',
|
|
13
|
+
[switch]$DryRun
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
$ErrorActionPreference = 'Stop'
|
|
17
|
+
|
|
18
|
+
$allowedActions = @{
|
|
19
|
+
accounts = @('list')
|
|
20
|
+
campaigns = @('list', 'insights')
|
|
21
|
+
adsets = @('list')
|
|
22
|
+
ads = @('list')
|
|
23
|
+
audiences = @('list')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (-not $allowedActions.ContainsKey($Resource) -or $Action -notin $allowedActions[$Resource]) {
|
|
27
|
+
throw "Unsupported operation '$Resource $Action'. Allowed read-only operations: accounts list, campaigns list|insights, adsets list, ads list, audiences list."
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (-not $env:META_ACCESS_TOKEN) {
|
|
31
|
+
throw 'META_ACCESS_TOKEN environment variable is required.'
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
$effectiveAccountId = if ($AccountId) { $AccountId } else { $env:META_AD_ACCOUNT_ID }
|
|
35
|
+
|
|
36
|
+
switch ("$Resource/$Action") {
|
|
37
|
+
'campaigns/list' {
|
|
38
|
+
if (-not $effectiveAccountId) { throw 'META_AD_ACCOUNT_ID or -AccountId is required for campaigns list.' }
|
|
39
|
+
}
|
|
40
|
+
'campaigns/insights' {
|
|
41
|
+
if (-not $Id) { throw '-Id is required for campaigns insights.' }
|
|
42
|
+
}
|
|
43
|
+
'adsets/list' {
|
|
44
|
+
if (-not $effectiveAccountId) { throw 'META_AD_ACCOUNT_ID or -AccountId is required for adsets list.' }
|
|
45
|
+
}
|
|
46
|
+
'ads/list' {
|
|
47
|
+
if (-not $AdsetId) { throw '-AdsetId is required for ads list.' }
|
|
48
|
+
}
|
|
49
|
+
'audiences/list' {
|
|
50
|
+
if (-not $effectiveAccountId) { throw 'META_AD_ACCOUNT_ID or -AccountId is required for audiences list.' }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function Get-SafeAccountAlias([string]$Value) {
|
|
55
|
+
if (-not $Value) { return 'none' }
|
|
56
|
+
$trimmed = $Value.Trim()
|
|
57
|
+
if ($trimmed.Length -le 4) { return "acct-$trimmed" }
|
|
58
|
+
return "acct-***$($trimmed.Substring($trimmed.Length - 4))"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function Sanitize-Data($InputObject) {
|
|
62
|
+
if ($null -eq $InputObject) { return $null }
|
|
63
|
+
|
|
64
|
+
if ($InputObject -is [System.Collections.IDictionary]) {
|
|
65
|
+
$result = [ordered]@{}
|
|
66
|
+
foreach ($key in $InputObject.Keys) {
|
|
67
|
+
$keyText = [string]$key
|
|
68
|
+
$value = $InputObject[$key]
|
|
69
|
+
if ($keyText -match '(?i)authorization|access_token|token|secret|password|api[_-]?key') {
|
|
70
|
+
$result[$keyText] = '***'
|
|
71
|
+
} else {
|
|
72
|
+
$result[$keyText] = Sanitize-Data $value
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return $result
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if ($InputObject -is [pscustomobject]) {
|
|
79
|
+
$result = [ordered]@{}
|
|
80
|
+
foreach ($property in $InputObject.PSObject.Properties) {
|
|
81
|
+
$name = [string]$property.Name
|
|
82
|
+
$value = $property.Value
|
|
83
|
+
if ($name -match '(?i)authorization|access_token|token|secret|password|api[_-]?key') {
|
|
84
|
+
$result[$name] = '***'
|
|
85
|
+
} else {
|
|
86
|
+
$result[$name] = Sanitize-Data $value
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return $result
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if ($InputObject -is [System.Collections.IEnumerable] -and -not ($InputObject -is [string])) {
|
|
93
|
+
$items = @()
|
|
94
|
+
foreach ($item in $InputObject) {
|
|
95
|
+
$items += ,(Sanitize-Data $item)
|
|
96
|
+
}
|
|
97
|
+
return $items
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if ($InputObject -is [string] -and $InputObject -eq $env:META_ACCESS_TOKEN) {
|
|
101
|
+
return '***'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return $InputObject
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function Get-JsonKey($Object) {
|
|
108
|
+
return (($Object | ConvertTo-Json -Depth 20 -Compress) -replace '\s+', '')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function Get-RequestPolicy([string]$ResourceName, [string]$ActionName, [string]$Preset) {
|
|
112
|
+
if ($ResourceName -eq 'campaigns' -and $ActionName -eq 'insights') {
|
|
113
|
+
$safeClosedPresets = @('yesterday')
|
|
114
|
+
if ($Preset -notin $safeClosedPresets) {
|
|
115
|
+
return [ordered]@{
|
|
116
|
+
cache_bypass = $true
|
|
117
|
+
coverage_type = 'intraday'
|
|
118
|
+
is_complete = $false
|
|
119
|
+
ttl_minutes = 0
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return [ordered]@{
|
|
124
|
+
cache_bypass = $false
|
|
125
|
+
coverage_type = 'complete_day'
|
|
126
|
+
is_complete = $true
|
|
127
|
+
ttl_minutes = 360
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return [ordered]@{
|
|
132
|
+
cache_bypass = $false
|
|
133
|
+
coverage_type = 'complete_snapshot'
|
|
134
|
+
is_complete = $true
|
|
135
|
+
ttl_minutes = 15
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
$repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
|
140
|
+
$cliPath = Join-Path $repoRoot 'tools\clis\meta-ads.js'
|
|
141
|
+
$cacheRoot = Join-Path $repoRoot 'outputs\meta-cache'
|
|
142
|
+
|
|
143
|
+
if (-not (Test-Path $cliPath)) {
|
|
144
|
+
throw "Vendored CLI not found at $cliPath"
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
$normalizedParams = [ordered]@{
|
|
148
|
+
resource = $Resource
|
|
149
|
+
action = $Action
|
|
150
|
+
account_id = if ($effectiveAccountId) { Get-SafeAccountAlias $effectiveAccountId } else { $null }
|
|
151
|
+
id = if ($Id) { $Id } else { '' }
|
|
152
|
+
adset_id = if ($AdsetId) { Get-SafeAccountAlias $AdsetId } else { $null }
|
|
153
|
+
date_preset = if ($Resource -eq 'campaigns' -and $Action -eq 'insights') { $DatePreset } else { $null }
|
|
154
|
+
}
|
|
155
|
+
$requestKey = Get-JsonKey $normalizedParams
|
|
156
|
+
$policy = Get-RequestPolicy -ResourceName $Resource -ActionName $Action -Preset $DatePreset
|
|
157
|
+
|
|
158
|
+
function Find-FreshCacheEntry {
|
|
159
|
+
param(
|
|
160
|
+
[string]$CacheDirectory,
|
|
161
|
+
[string]$WantedKey
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
if (-not (Test-Path $CacheDirectory)) {
|
|
165
|
+
return $null
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
$now = Get-Date
|
|
169
|
+
foreach ($file in Get-ChildItem $CacheDirectory -Filter '*.json' -File -ErrorAction SilentlyContinue) {
|
|
170
|
+
try {
|
|
171
|
+
$doc = Get-Content $file.FullName -Raw | ConvertFrom-Json
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
continue
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (-not $doc.normalized_params) {
|
|
178
|
+
continue
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
$docKey = Get-JsonKey (Sanitize-Data $doc.normalized_params)
|
|
182
|
+
if ($docKey -ne $WantedKey) {
|
|
183
|
+
continue
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (-not $doc.expires_at) {
|
|
187
|
+
continue
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
$expiresAt = [datetimeoffset]::Parse([string]$doc.expires_at)
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
continue
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if ($expiresAt -le [datetimeoffset]$now) {
|
|
198
|
+
continue
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return [ordered]@{
|
|
202
|
+
file = $file.FullName
|
|
203
|
+
document = $doc
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return $null
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function Invoke-MetaCli {
|
|
211
|
+
param([switch]$UseDryRun)
|
|
212
|
+
|
|
213
|
+
$cliArgs = @($cliPath, $Resource, $Action)
|
|
214
|
+
if ($effectiveAccountId -and $Resource -in @('campaigns', 'adsets', 'audiences')) {
|
|
215
|
+
$cliArgs += @('--account-id', $effectiveAccountId)
|
|
216
|
+
}
|
|
217
|
+
if ($Id) {
|
|
218
|
+
$cliArgs += @('--id', $Id)
|
|
219
|
+
}
|
|
220
|
+
if ($AdsetId) {
|
|
221
|
+
$cliArgs += @('--adset-id', $AdsetId)
|
|
222
|
+
}
|
|
223
|
+
if ($Resource -eq 'campaigns' -and $Action -eq 'insights' -and $DatePreset) {
|
|
224
|
+
$cliArgs += @('--date-preset', $DatePreset)
|
|
225
|
+
}
|
|
226
|
+
if ($UseDryRun) {
|
|
227
|
+
$cliArgs += '--dry-run'
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
$rawOutput = & node @cliArgs 2>&1
|
|
231
|
+
$exitCode = $LASTEXITCODE
|
|
232
|
+
$textOutput = ($rawOutput | Out-String).Trim()
|
|
233
|
+
|
|
234
|
+
if ($exitCode -ne 0) {
|
|
235
|
+
$safeError = $textOutput -replace [regex]::Escape($env:META_ACCESS_TOKEN), '***'
|
|
236
|
+
throw "meta-ads.js failed: $safeError"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
return $textOutput | ConvertFrom-Json
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
throw "meta-ads.js returned non-JSON output: $textOutput"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function Build-Result {
|
|
248
|
+
param(
|
|
249
|
+
[string]$CacheStatus,
|
|
250
|
+
[string]$CoverageType,
|
|
251
|
+
[bool]$IsComplete,
|
|
252
|
+
[object]$Payload,
|
|
253
|
+
[string]$AsOf,
|
|
254
|
+
[string]$ExpiresAt,
|
|
255
|
+
[string]$CachePath
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
$result = [ordered]@{
|
|
259
|
+
source = 'meta-ads'
|
|
260
|
+
dry_run = [bool]$DryRun
|
|
261
|
+
cache_status = $CacheStatus
|
|
262
|
+
safe_account_alias = Get-SafeAccountAlias $effectiveAccountId
|
|
263
|
+
as_of = $AsOf
|
|
264
|
+
expires_at = $ExpiresAt
|
|
265
|
+
coverage_type = $CoverageType
|
|
266
|
+
is_complete = $IsComplete
|
|
267
|
+
normalized_params = $normalizedParams
|
|
268
|
+
payload = $Payload
|
|
269
|
+
forbidden_fields = @('authorization', 'access_token', 'token', 'secret', 'password', 'api_key')
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if ($CachePath) {
|
|
273
|
+
$result['cache_path'] = $CachePath
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return $result
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
$cacheEntry = $null
|
|
280
|
+
if (-not $policy.cache_bypass) {
|
|
281
|
+
$cacheEntry = Find-FreshCacheEntry -CacheDirectory $cacheRoot -WantedKey $requestKey
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if ($cacheEntry) {
|
|
285
|
+
$doc = $cacheEntry.document
|
|
286
|
+
$payload = Sanitize-Data $doc.payload
|
|
287
|
+
$result = Build-Result -CacheStatus 'hit' -CoverageType ([string]$doc.coverage_type) -IsComplete ([bool]$doc.is_complete) -Payload $payload -AsOf ([string]$doc.as_of) -ExpiresAt ([string]$doc.expires_at) -CachePath $cacheEntry.file
|
|
288
|
+
($result | ConvertTo-Json -Depth 20)
|
|
289
|
+
exit 0
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
$livePayload = Sanitize-Data (Invoke-MetaCli -UseDryRun:$DryRun)
|
|
293
|
+
$cacheStatus = if ($policy.cache_bypass) { 'bypass' } else { 'miss' }
|
|
294
|
+
$asOf = (Get-Date).ToString('o')
|
|
295
|
+
$expiresAt = if ($policy.ttl_minutes -gt 0) { (Get-Date).AddMinutes($policy.ttl_minutes).ToString('o') } else { $null }
|
|
296
|
+
$cachePath = $null
|
|
297
|
+
|
|
298
|
+
if (-not $DryRun -and -not $policy.cache_bypass) {
|
|
299
|
+
New-Item -ItemType Directory -Force -Path $cacheRoot | Out-Null
|
|
300
|
+
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
|
|
301
|
+
$fileName = "meta-$Resource-$Action-$stamp.json"
|
|
302
|
+
$cachePath = Join-Path $cacheRoot $fileName
|
|
303
|
+
|
|
304
|
+
$cacheDocument = [ordered]@{
|
|
305
|
+
schema_version = 1
|
|
306
|
+
source = 'meta-ads'
|
|
307
|
+
cache_status = $cacheStatus
|
|
308
|
+
safe_account_alias = Get-SafeAccountAlias $effectiveAccountId
|
|
309
|
+
as_of = $asOf
|
|
310
|
+
fetched_at = $asOf
|
|
311
|
+
expires_at = $expiresAt
|
|
312
|
+
coverage_type = $policy.coverage_type
|
|
313
|
+
is_complete = $policy.is_complete
|
|
314
|
+
date_range = if ($Resource -eq 'campaigns' -and $Action -eq 'insights') { @{ date_preset = $DatePreset } } else { $null }
|
|
315
|
+
normalized_params = $normalizedParams
|
|
316
|
+
forbidden_fields = @('authorization', 'access_token', 'token', 'secret', 'password', 'api_key')
|
|
317
|
+
payload = $livePayload
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
($cacheDocument | ConvertTo-Json -Depth 20) | Set-Content $cachePath
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
$result = Build-Result -CacheStatus $cacheStatus -CoverageType $policy.coverage_type -IsComplete $policy.is_complete -Payload $livePayload -AsOf $asOf -ExpiresAt $expiresAt -CachePath $cachePath
|
|
324
|
+
($result | ConvertTo-Json -Depth 20)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
$ErrorActionPreference = 'Stop'
|
|
2
|
+
Set-ExecutionPolicy -Scope Process Bypass -Force
|
|
3
|
+
|
|
4
|
+
$wrapper = Join-Path $PSScriptRoot 'meta-fetch.ps1'
|
|
5
|
+
|
|
6
|
+
if (-not (Test-Path $wrapper)) {
|
|
7
|
+
throw 'meta-fetch.ps1 is missing'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
$oldToken = $env:META_ACCESS_TOKEN
|
|
11
|
+
$oldAccount = $env:META_AD_ACCOUNT_ID
|
|
12
|
+
$env:META_ACCESS_TOKEN = 'super-secret-token'
|
|
13
|
+
$env:META_AD_ACCOUNT_ID = '1234567890'
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
$output = & $wrapper -Resource campaigns -Action list -DryRun 2>&1
|
|
17
|
+
$text = ($output | Out-String)
|
|
18
|
+
|
|
19
|
+
if ($LASTEXITCODE -ne 0) {
|
|
20
|
+
throw "Expected dry run to succeed but exit code was $LASTEXITCODE. Output: $text"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if ($text -match 'super-secret-token') {
|
|
24
|
+
throw 'Dry run output leaked META_ACCESS_TOKEN'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if ($text -notmatch '"dry_run"\s*:\s*true') {
|
|
28
|
+
throw "Expected dry_run marker in output. Output: $text"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if ($text -notmatch '"cache_status"\s*:\s*"miss"') {
|
|
32
|
+
throw "Expected cache_status miss marker in dry-run output. Output: $text"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
$env:META_ACCESS_TOKEN = $oldToken
|
|
37
|
+
$env:META_AD_ACCOUNT_ID = $oldAccount
|
|
38
|
+
}
|