@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.
Files changed (270) hide show
  1. package/README.md +30 -0
  2. package/bin/maya-codex.js +36 -0
  3. package/package.json +19 -0
  4. package/payload/.agents/skills/ab-test-setup/SKILL.md +266 -0
  5. package/payload/.agents/skills/ab-test-setup/evals/evals.json +105 -0
  6. package/payload/.agents/skills/ab-test-setup/references/sample-size-guide.md +263 -0
  7. package/payload/.agents/skills/ab-test-setup/references/test-templates.md +277 -0
  8. package/payload/.agents/skills/ad-creative/SKILL.md +362 -0
  9. package/payload/.agents/skills/ad-creative/evals/evals.json +90 -0
  10. package/payload/.agents/skills/ad-creative/references/generative-tools.md +637 -0
  11. package/payload/.agents/skills/ad-creative/references/platform-specs.md +213 -0
  12. package/payload/.agents/skills/ai-seo/SKILL.md +398 -0
  13. package/payload/.agents/skills/ai-seo/evals/evals.json +90 -0
  14. package/payload/.agents/skills/ai-seo/references/content-patterns.md +285 -0
  15. package/payload/.agents/skills/ai-seo/references/platform-ranking-factors.md +152 -0
  16. package/payload/.agents/skills/analytics-tracking/SKILL.md +309 -0
  17. package/payload/.agents/skills/analytics-tracking/evals/evals.json +90 -0
  18. package/payload/.agents/skills/analytics-tracking/references/event-library.md +260 -0
  19. package/payload/.agents/skills/analytics-tracking/references/ga4-implementation.md +300 -0
  20. package/payload/.agents/skills/analytics-tracking/references/gtm-implementation.md +390 -0
  21. package/payload/.agents/skills/churn-prevention/SKILL.md +424 -0
  22. package/payload/.agents/skills/churn-prevention/evals/evals.json +93 -0
  23. package/payload/.agents/skills/churn-prevention/references/cancel-flow-patterns.md +316 -0
  24. package/payload/.agents/skills/churn-prevention/references/dunning-playbook.md +408 -0
  25. package/payload/.agents/skills/cold-email/SKILL.md +158 -0
  26. package/payload/.agents/skills/cold-email/evals/evals.json +94 -0
  27. package/payload/.agents/skills/cold-email/references/benchmarks.md +83 -0
  28. package/payload/.agents/skills/cold-email/references/follow-up-sequences.md +81 -0
  29. package/payload/.agents/skills/cold-email/references/frameworks.md +90 -0
  30. package/payload/.agents/skills/cold-email/references/personalization.md +79 -0
  31. package/payload/.agents/skills/cold-email/references/subject-lines.md +53 -0
  32. package/payload/.agents/skills/competitor-alternatives/SKILL.md +256 -0
  33. package/payload/.agents/skills/competitor-alternatives/evals/evals.json +93 -0
  34. package/payload/.agents/skills/competitor-alternatives/references/content-architecture.md +271 -0
  35. package/payload/.agents/skills/competitor-alternatives/references/templates.md +223 -0
  36. package/payload/.agents/skills/content-strategy/SKILL.md +359 -0
  37. package/payload/.agents/skills/content-strategy/evals/evals.json +90 -0
  38. package/payload/.agents/skills/copy-editing/SKILL.md +447 -0
  39. package/payload/.agents/skills/copy-editing/evals/evals.json +89 -0
  40. package/payload/.agents/skills/copy-editing/references/plain-english-alternatives.md +394 -0
  41. package/payload/.agents/skills/copywriting/SKILL.md +252 -0
  42. package/payload/.agents/skills/copywriting/evals/evals.json +111 -0
  43. package/payload/.agents/skills/copywriting/references/copy-frameworks.md +344 -0
  44. package/payload/.agents/skills/copywriting/references/natural-transitions.md +272 -0
  45. package/payload/.agents/skills/email-sequence/SKILL.md +309 -0
  46. package/payload/.agents/skills/email-sequence/evals/evals.json +93 -0
  47. package/payload/.agents/skills/email-sequence/references/copy-guidelines.md +113 -0
  48. package/payload/.agents/skills/email-sequence/references/email-types.md +515 -0
  49. package/payload/.agents/skills/email-sequence/references/sequence-templates.md +168 -0
  50. package/payload/.agents/skills/form-cro/SKILL.md +429 -0
  51. package/payload/.agents/skills/form-cro/evals/evals.json +90 -0
  52. package/payload/.agents/skills/free-tool-strategy/SKILL.md +178 -0
  53. package/payload/.agents/skills/free-tool-strategy/evals/evals.json +90 -0
  54. package/payload/.agents/skills/free-tool-strategy/references/tool-types.md +217 -0
  55. package/payload/.agents/skills/launch-strategy/SKILL.md +353 -0
  56. package/payload/.agents/skills/launch-strategy/evals/evals.json +91 -0
  57. package/payload/.agents/skills/marketing-ideas/SKILL.md +167 -0
  58. package/payload/.agents/skills/marketing-ideas/evals/evals.json +90 -0
  59. package/payload/.agents/skills/marketing-ideas/references/ideas-by-category.md +366 -0
  60. package/payload/.agents/skills/marketing-psychology/SKILL.md +455 -0
  61. package/payload/.agents/skills/marketing-psychology/evals/evals.json +88 -0
  62. package/payload/.agents/skills/onboarding-cro/SKILL.md +220 -0
  63. package/payload/.agents/skills/onboarding-cro/evals/evals.json +92 -0
  64. package/payload/.agents/skills/onboarding-cro/references/experiments.md +258 -0
  65. package/payload/.agents/skills/page-cro/SKILL.md +182 -0
  66. package/payload/.agents/skills/page-cro/evals/evals.json +111 -0
  67. package/payload/.agents/skills/page-cro/references/experiments.md +248 -0
  68. package/payload/.agents/skills/paid-ads/SKILL.md +315 -0
  69. package/payload/.agents/skills/paid-ads/evals/evals.json +90 -0
  70. package/payload/.agents/skills/paid-ads/references/ad-copy-templates.md +207 -0
  71. package/payload/.agents/skills/paid-ads/references/audience-targeting.md +243 -0
  72. package/payload/.agents/skills/paid-ads/references/platform-setup-checklists.md +277 -0
  73. package/payload/.agents/skills/paywall-upgrade-cro/SKILL.md +227 -0
  74. package/payload/.agents/skills/paywall-upgrade-cro/evals/evals.json +93 -0
  75. package/payload/.agents/skills/paywall-upgrade-cro/references/experiments.md +164 -0
  76. package/payload/.agents/skills/popup-cro/SKILL.md +453 -0
  77. package/payload/.agents/skills/popup-cro/evals/evals.json +94 -0
  78. package/payload/.agents/skills/pricing-strategy/SKILL.md +231 -0
  79. package/payload/.agents/skills/pricing-strategy/evals/evals.json +90 -0
  80. package/payload/.agents/skills/pricing-strategy/references/research-methods.md +152 -0
  81. package/payload/.agents/skills/pricing-strategy/references/tier-structure.md +232 -0
  82. package/payload/.agents/skills/product-marketing-context/SKILL.md +27 -0
  83. package/payload/.agents/skills/product-marketing-context/evals/evals.json +40 -0
  84. package/payload/.agents/skills/programmatic-seo/SKILL.md +238 -0
  85. package/payload/.agents/skills/programmatic-seo/evals/evals.json +94 -0
  86. package/payload/.agents/skills/programmatic-seo/references/playbooks.md +308 -0
  87. package/payload/.agents/skills/referral-program/SKILL.md +255 -0
  88. package/payload/.agents/skills/referral-program/evals/evals.json +89 -0
  89. package/payload/.agents/skills/referral-program/references/affiliate-programs.md +164 -0
  90. package/payload/.agents/skills/referral-program/references/program-examples.md +143 -0
  91. package/payload/.agents/skills/revops/SKILL.md +343 -0
  92. package/payload/.agents/skills/revops/evals/evals.json +91 -0
  93. package/payload/.agents/skills/revops/references/automation-playbooks.md +290 -0
  94. package/payload/.agents/skills/revops/references/lifecycle-definitions.md +278 -0
  95. package/payload/.agents/skills/revops/references/routing-rules.md +203 -0
  96. package/payload/.agents/skills/revops/references/scoring-models.md +247 -0
  97. package/payload/.agents/skills/sales-enablement/SKILL.md +349 -0
  98. package/payload/.agents/skills/sales-enablement/evals/evals.json +91 -0
  99. package/payload/.agents/skills/sales-enablement/references/deck-frameworks.md +263 -0
  100. package/payload/.agents/skills/sales-enablement/references/demo-scripts.md +355 -0
  101. package/payload/.agents/skills/sales-enablement/references/objection-library.md +270 -0
  102. package/payload/.agents/skills/sales-enablement/references/one-pager-templates.md +208 -0
  103. package/payload/.agents/skills/schema-markup/SKILL.md +179 -0
  104. package/payload/.agents/skills/schema-markup/evals/evals.json +87 -0
  105. package/payload/.agents/skills/schema-markup/references/schema-examples.md +398 -0
  106. package/payload/.agents/skills/seo-audit/SKILL.md +412 -0
  107. package/payload/.agents/skills/seo-audit/evals/evals.json +136 -0
  108. package/payload/.agents/skills/seo-audit/references/ai-writing-detection.md +200 -0
  109. package/payload/.agents/skills/signup-flow-cro/SKILL.md +359 -0
  110. package/payload/.agents/skills/signup-flow-cro/evals/evals.json +88 -0
  111. package/payload/.agents/skills/site-architecture/SKILL.md +357 -0
  112. package/payload/.agents/skills/site-architecture/evals/evals.json +88 -0
  113. package/payload/.agents/skills/site-architecture/references/mermaid-templates.md +216 -0
  114. package/payload/.agents/skills/site-architecture/references/navigation-patterns.md +305 -0
  115. package/payload/.agents/skills/site-architecture/references/site-type-templates.md +293 -0
  116. package/payload/.agents/skills/social-content/SKILL.md +278 -0
  117. package/payload/.agents/skills/social-content/evals/evals.json +92 -0
  118. package/payload/.agents/skills/social-content/references/platforms.md +170 -0
  119. package/payload/.agents/skills/social-content/references/post-templates.md +177 -0
  120. package/payload/.agents/skills/social-content/references/reverse-engineering.md +195 -0
  121. package/payload/.maya/executor.md +79 -0
  122. package/payload/.maya/meta-api-agent.md +48 -0
  123. package/payload/.maya/modes/consult.md +63 -0
  124. package/payload/.maya/modes/task.md +97 -0
  125. package/payload/.maya/planner.md +69 -0
  126. package/payload/.maya/researcher.md +51 -0
  127. package/payload/.maya/templates/plan.md +77 -0
  128. package/payload/.maya/templates/state.md +87 -0
  129. package/payload/.maya/templates/task-packet.md +75 -0
  130. package/payload/MAYA-CATALOG.md +115 -0
  131. package/payload/MAYA-DEPENDENCIES.md +58 -0
  132. package/payload/MAYA.md +151 -0
  133. package/payload/campaigns/README.md +14 -0
  134. package/payload/commands/maya-consult.md +28 -0
  135. package/payload/commands/maya-task.md +38 -0
  136. package/payload/commands/product.md +55 -0
  137. package/payload/research/README.md +14 -0
  138. package/payload/templates/README.md +15 -0
  139. package/payload/templates/plan.md +77 -0
  140. package/payload/templates/state.md +87 -0
  141. package/payload/templates/task-packet.md +75 -0
  142. package/payload/tools/REGISTRY.md +368 -0
  143. package/payload/tools/clis/README.md +187 -0
  144. package/payload/tools/clis/activecampaign.js +435 -0
  145. package/payload/tools/clis/adobe-analytics.js +161 -0
  146. package/payload/tools/clis/ahrefs.js +192 -0
  147. package/payload/tools/clis/amplitude.js +182 -0
  148. package/payload/tools/clis/apollo.js +142 -0
  149. package/payload/tools/clis/beehiiv.js +245 -0
  150. package/payload/tools/clis/brevo.js +368 -0
  151. package/payload/tools/clis/buffer.js +260 -0
  152. package/payload/tools/clis/calendly.js +253 -0
  153. package/payload/tools/clis/clearbit.js +163 -0
  154. package/payload/tools/clis/customer-io.js +205 -0
  155. package/payload/tools/clis/dataforseo.js +257 -0
  156. package/payload/tools/clis/demio.js +149 -0
  157. package/payload/tools/clis/dub.js +158 -0
  158. package/payload/tools/clis/g2.js +186 -0
  159. package/payload/tools/clis/ga4.js +194 -0
  160. package/payload/tools/clis/google-ads.js +189 -0
  161. package/payload/tools/clis/google-search-console.js +166 -0
  162. package/payload/tools/clis/hotjar.js +167 -0
  163. package/payload/tools/clis/hunter.js +249 -0
  164. package/payload/tools/clis/instantly.js +270 -0
  165. package/payload/tools/clis/intercom.js +399 -0
  166. package/payload/tools/clis/keywords-everywhere.js +185 -0
  167. package/payload/tools/clis/kit.js +232 -0
  168. package/payload/tools/clis/klaviyo.js +348 -0
  169. package/payload/tools/clis/lemlist.js +221 -0
  170. package/payload/tools/clis/linkedin-ads.js +185 -0
  171. package/payload/tools/clis/livestorm.js +292 -0
  172. package/payload/tools/clis/mailchimp.js +220 -0
  173. package/payload/tools/clis/mention-me.js +161 -0
  174. package/payload/tools/clis/meta-ads.js +181 -0
  175. package/payload/tools/clis/mixpanel.js +248 -0
  176. package/payload/tools/clis/onesignal.js +241 -0
  177. package/payload/tools/clis/optimizely.js +233 -0
  178. package/payload/tools/clis/paddle.js +385 -0
  179. package/payload/tools/clis/partnerstack.js +382 -0
  180. package/payload/tools/clis/plausible.js +249 -0
  181. package/payload/tools/clis/postmark.js +375 -0
  182. package/payload/tools/clis/resend.js +370 -0
  183. package/payload/tools/clis/rewardful.js +160 -0
  184. package/payload/tools/clis/savvycal.js +223 -0
  185. package/payload/tools/clis/segment.js +192 -0
  186. package/payload/tools/clis/semrush.js +207 -0
  187. package/payload/tools/clis/sendgrid.js +211 -0
  188. package/payload/tools/clis/snov.js +237 -0
  189. package/payload/tools/clis/tiktok-ads.js +190 -0
  190. package/payload/tools/clis/tolt.js +153 -0
  191. package/payload/tools/clis/trustpilot.js +276 -0
  192. package/payload/tools/clis/typeform.js +269 -0
  193. package/payload/tools/clis/wistia.js +256 -0
  194. package/payload/tools/clis/zapier.js +160 -0
  195. package/payload/tools/integrations/activecampaign.md +337 -0
  196. package/payload/tools/integrations/adobe-analytics.md +156 -0
  197. package/payload/tools/integrations/ahrefs.md +142 -0
  198. package/payload/tools/integrations/amplitude.md +135 -0
  199. package/payload/tools/integrations/apollo.md +148 -0
  200. package/payload/tools/integrations/beehiiv.md +157 -0
  201. package/payload/tools/integrations/brevo.md +268 -0
  202. package/payload/tools/integrations/buffer.md +138 -0
  203. package/payload/tools/integrations/calendly.md +161 -0
  204. package/payload/tools/integrations/clearbit.md +142 -0
  205. package/payload/tools/integrations/customer-io.md +187 -0
  206. package/payload/tools/integrations/dataforseo.md +165 -0
  207. package/payload/tools/integrations/demio.md +182 -0
  208. package/payload/tools/integrations/dub-co.md +160 -0
  209. package/payload/tools/integrations/g2.md +179 -0
  210. package/payload/tools/integrations/ga4.md +126 -0
  211. package/payload/tools/integrations/google-ads.md +159 -0
  212. package/payload/tools/integrations/google-search-console.md +147 -0
  213. package/payload/tools/integrations/hotjar.md +147 -0
  214. package/payload/tools/integrations/hubspot.md +178 -0
  215. package/payload/tools/integrations/hunter.md +90 -0
  216. package/payload/tools/integrations/instantly.md +104 -0
  217. package/payload/tools/integrations/intercom.md +292 -0
  218. package/payload/tools/integrations/keywords-everywhere.md +207 -0
  219. package/payload/tools/integrations/kit.md +167 -0
  220. package/payload/tools/integrations/klaviyo.md +228 -0
  221. package/payload/tools/integrations/lemlist.md +110 -0
  222. package/payload/tools/integrations/linkedin-ads.md +164 -0
  223. package/payload/tools/integrations/livestorm.md +313 -0
  224. package/payload/tools/integrations/mailchimp.md +150 -0
  225. package/payload/tools/integrations/mention-me.md +160 -0
  226. package/payload/tools/integrations/meta-ads.md +147 -0
  227. package/payload/tools/integrations/mixpanel.md +137 -0
  228. package/payload/tools/integrations/onesignal.md +229 -0
  229. package/payload/tools/integrations/optimizely.md +171 -0
  230. package/payload/tools/integrations/paddle.md +212 -0
  231. package/payload/tools/integrations/partnerstack.md +222 -0
  232. package/payload/tools/integrations/plausible.md +177 -0
  233. package/payload/tools/integrations/posthog.md +151 -0
  234. package/payload/tools/integrations/postmark.md +234 -0
  235. package/payload/tools/integrations/resend.md +168 -0
  236. package/payload/tools/integrations/rewardful.md +147 -0
  237. package/payload/tools/integrations/salesforce.md +150 -0
  238. package/payload/tools/integrations/savvycal.md +181 -0
  239. package/payload/tools/integrations/segment.md +159 -0
  240. package/payload/tools/integrations/semrush.md +121 -0
  241. package/payload/tools/integrations/sendgrid.md +161 -0
  242. package/payload/tools/integrations/shopify.md +176 -0
  243. package/payload/tools/integrations/snov.md +94 -0
  244. package/payload/tools/integrations/stripe.md +148 -0
  245. package/payload/tools/integrations/tiktok-ads.md +161 -0
  246. package/payload/tools/integrations/tolt.md +144 -0
  247. package/payload/tools/integrations/trustpilot.md +191 -0
  248. package/payload/tools/integrations/typeform.md +190 -0
  249. package/payload/tools/integrations/webflow.md +198 -0
  250. package/payload/tools/integrations/wistia.md +164 -0
  251. package/payload/tools/integrations/wordpress.md +175 -0
  252. package/payload/tools/integrations/zapier.md +150 -0
  253. package/payload/tools/meta/README.md +55 -0
  254. package/payload/tools/meta/meta-cache-schema.md +65 -0
  255. package/payload/tools/meta/meta-fetch.ps1 +324 -0
  256. package/payload/tools/meta/meta-fetch.test.ps1 +38 -0
  257. package/vendor/shared-installer/manifests/claude-files.json +13 -0
  258. package/vendor/shared-installer/manifests/codex-files.json +13 -0
  259. package/vendor/shared-installer/manifests/common-files.json +13 -0
  260. package/vendor/shared-installer/package.json +15 -0
  261. package/vendor/shared-installer/src/bootstrap.js +12 -0
  262. package/vendor/shared-installer/src/cli-options.js +53 -0
  263. package/vendor/shared-installer/src/fs.js +105 -0
  264. package/vendor/shared-installer/src/index.js +44 -0
  265. package/vendor/shared-installer/src/install.js +157 -0
  266. package/vendor/shared-installer/src/manifest.js +52 -0
  267. package/vendor/shared-installer/templates/claude/.claude/skills/.gitkeep +1 -0
  268. package/vendor/shared-installer/templates/claude/CLAUDE.md +27 -0
  269. package/vendor/shared-installer/templates/codex/.agent/skills/.gitkeep +1 -0
  270. package/vendor/shared-installer/templates/codex/AGENTS.md +27 -0
@@ -0,0 +1,382 @@
1
+ #!/usr/bin/env node
2
+
3
+ const PUBLIC_KEY = process.env.PARTNERSTACK_PUBLIC_KEY
4
+ const SECRET_KEY = process.env.PARTNERSTACK_SECRET_KEY
5
+ const BASE_URL = 'https://api.partnerstack.com/api/v2'
6
+
7
+ if (!PUBLIC_KEY || !SECRET_KEY) {
8
+ console.error(JSON.stringify({ error: 'PARTNERSTACK_PUBLIC_KEY and PARTNERSTACK_SECRET_KEY environment variables required' }))
9
+ process.exit(1)
10
+ }
11
+
12
+ const AUTH = 'Basic ' + Buffer.from(`${PUBLIC_KEY}:${SECRET_KEY}`).toString('base64')
13
+
14
+ async function api(method, path, body) {
15
+ if (args['dry-run']) {
16
+ return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { Authorization: '***', 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: body || undefined }
17
+ }
18
+ const res = await fetch(`${BASE_URL}${path}`, {
19
+ method,
20
+ headers: {
21
+ 'Authorization': AUTH,
22
+ 'Content-Type': 'application/json',
23
+ 'Accept': 'application/json',
24
+ },
25
+ body: body ? JSON.stringify(body) : undefined,
26
+ })
27
+ const text = await res.text()
28
+ try {
29
+ return JSON.parse(text)
30
+ } catch {
31
+ return { status: res.status, body: text }
32
+ }
33
+ }
34
+
35
+ function parseArgs(args) {
36
+ const result = { _: [] }
37
+ for (let i = 0; i < args.length; i++) {
38
+ const arg = args[i]
39
+ if (arg.startsWith('--')) {
40
+ const key = arg.slice(2)
41
+ const next = args[i + 1]
42
+ if (next && !next.startsWith('--')) {
43
+ result[key] = next
44
+ i++
45
+ } else {
46
+ result[key] = true
47
+ }
48
+ } else {
49
+ result._.push(arg)
50
+ }
51
+ }
52
+ return result
53
+ }
54
+
55
+ const args = parseArgs(process.argv.slice(2))
56
+ const [cmd, sub, ...rest] = args._
57
+ const limit = args.limit ? Number(args.limit) : 10
58
+
59
+ function buildQuery() {
60
+ const params = new URLSearchParams()
61
+ if (args.limit) params.set('limit', args.limit)
62
+ if (args.after) params.set('starting_after', args.after)
63
+ if (args.before) params.set('ending_before', args.before)
64
+ if (args['order-by']) params.set('order_by', args['order-by'])
65
+ return params.toString() ? `?${params.toString()}` : ''
66
+ }
67
+
68
+ async function main() {
69
+ let result
70
+
71
+ switch (cmd) {
72
+ case 'partnerships':
73
+ switch (sub) {
74
+ case 'list':
75
+ result = await api('GET', `/partnerships${buildQuery()}`)
76
+ break
77
+ case 'get': {
78
+ const key = args.key
79
+ if (!key) { result = { error: '--key required (partnership key)' }; break }
80
+ result = await api('GET', `/partnerships/${key}`)
81
+ break
82
+ }
83
+ case 'create': {
84
+ const email = args.email
85
+ const group = args.group
86
+ if (!email) { result = { error: '--email required' }; break }
87
+ if (!group) { result = { error: '--group required (group key)' }; break }
88
+ const body = { email, group_key: group }
89
+ if (args.name) body.name = args.name
90
+ if (args['first-name']) body.first_name = args['first-name']
91
+ if (args['last-name']) body.last_name = args['last-name']
92
+ result = await api('POST', '/partnerships', body)
93
+ break
94
+ }
95
+ case 'update': {
96
+ const key = args.key
97
+ if (!key) { result = { error: '--key required (partnership key)' }; break }
98
+ const body = {}
99
+ if (args.name) body.name = args.name
100
+ if (args.group) body.group_key = args.group
101
+ result = await api('PATCH', `/partnerships/${key}`, body)
102
+ break
103
+ }
104
+ default:
105
+ result = { error: 'Unknown partnerships subcommand. Use: list, get, create, update' }
106
+ }
107
+ break
108
+
109
+ case 'customers':
110
+ switch (sub) {
111
+ case 'list':
112
+ result = await api('GET', `/customers${buildQuery()}`)
113
+ break
114
+ case 'get': {
115
+ const key = args.key
116
+ if (!key) { result = { error: '--key required (customer key)' }; break }
117
+ result = await api('GET', `/customers/${key}`)
118
+ break
119
+ }
120
+ case 'create': {
121
+ const email = args.email
122
+ const partnerKey = args['partner-key']
123
+ if (!email) { result = { error: '--email required' }; break }
124
+ if (!partnerKey) { result = { error: '--partner-key required' }; break }
125
+ const body = { email, partner_key: partnerKey }
126
+ if (args.name) body.name = args.name
127
+ if (args['customer-key']) body.customer_key = args['customer-key']
128
+ result = await api('POST', '/customers', body)
129
+ break
130
+ }
131
+ case 'update': {
132
+ const key = args.key
133
+ if (!key) { result = { error: '--key required (customer key)' }; break }
134
+ const body = {}
135
+ if (args.name) body.name = args.name
136
+ if (args.email) body.email = args.email
137
+ if (args['partner-key']) body.partner_key = args['partner-key']
138
+ result = await api('PATCH', `/customers/${key}`, body)
139
+ break
140
+ }
141
+ case 'delete': {
142
+ const key = args.key
143
+ if (!key) { result = { error: '--key required (customer key)' }; break }
144
+ result = await api('DELETE', `/customers/${key}`)
145
+ break
146
+ }
147
+ default:
148
+ result = { error: 'Unknown customers subcommand. Use: list, get, create, update, delete' }
149
+ }
150
+ break
151
+
152
+ case 'transactions':
153
+ switch (sub) {
154
+ case 'list':
155
+ result = await api('GET', `/transactions${buildQuery()}`)
156
+ break
157
+ case 'get': {
158
+ const key = args.key
159
+ if (!key) { result = { error: '--key required (transaction key)' }; break }
160
+ result = await api('GET', `/transactions/${key}`)
161
+ break
162
+ }
163
+ case 'create': {
164
+ const customerKey = args['customer-key']
165
+ const amount = args.amount
166
+ if (!customerKey) { result = { error: '--customer-key required' }; break }
167
+ if (!amount) { result = { error: '--amount required (in cents)' }; break }
168
+ const body = {
169
+ customer_key: customerKey,
170
+ amount: Number(amount),
171
+ }
172
+ if (args.currency) body.currency = args.currency
173
+ if (args.category) body.category = args.category
174
+ if (args['product-key']) body.product_key = args['product-key']
175
+ result = await api('POST', '/transactions', body)
176
+ break
177
+ }
178
+ case 'delete': {
179
+ const key = args.key
180
+ if (!key) { result = { error: '--key required (transaction key)' }; break }
181
+ result = await api('DELETE', `/transactions/${key}`)
182
+ break
183
+ }
184
+ default:
185
+ result = { error: 'Unknown transactions subcommand. Use: list, get, create, delete' }
186
+ }
187
+ break
188
+
189
+ case 'deals':
190
+ switch (sub) {
191
+ case 'list':
192
+ result = await api('GET', `/deals${buildQuery()}`)
193
+ break
194
+ case 'get': {
195
+ const key = args.key
196
+ if (!key) { result = { error: '--key required (deal key)' }; break }
197
+ result = await api('GET', `/deals/${key}`)
198
+ break
199
+ }
200
+ case 'create': {
201
+ const partnerKey = args['partner-key']
202
+ const name = args.name
203
+ if (!partnerKey) { result = { error: '--partner-key required' }; break }
204
+ if (!name) { result = { error: '--name required' }; break }
205
+ const body = { partner_key: partnerKey, name }
206
+ if (args.amount) body.amount = Number(args.amount)
207
+ if (args.currency) body.currency = args.currency
208
+ if (args.stage) body.stage = args.stage
209
+ result = await api('POST', '/deals', body)
210
+ break
211
+ }
212
+ case 'update': {
213
+ const key = args.key
214
+ if (!key) { result = { error: '--key required (deal key)' }; break }
215
+ const body = {}
216
+ if (args.name) body.name = args.name
217
+ if (args.amount) body.amount = Number(args.amount)
218
+ if (args.stage) body.stage = args.stage
219
+ if (args.status) body.status = args.status
220
+ result = await api('PATCH', `/deals/${key}`, body)
221
+ break
222
+ }
223
+ case 'archive': {
224
+ const key = args.key
225
+ if (!key) { result = { error: '--key required (deal key)' }; break }
226
+ result = await api('DELETE', `/deals/${key}`)
227
+ break
228
+ }
229
+ default:
230
+ result = { error: 'Unknown deals subcommand. Use: list, get, create, update, archive' }
231
+ }
232
+ break
233
+
234
+ case 'actions':
235
+ switch (sub) {
236
+ case 'list':
237
+ result = await api('GET', `/actions${buildQuery()}`)
238
+ break
239
+ case 'create': {
240
+ const customerKey = args['customer-key']
241
+ const actionKey = args['action-key']
242
+ if (!customerKey) { result = { error: '--customer-key required' }; break }
243
+ if (!actionKey) { result = { error: '--action-key required' }; break }
244
+ const body = {
245
+ customer_key: customerKey,
246
+ key: actionKey,
247
+ }
248
+ if (args.value) body.value = Number(args.value)
249
+ result = await api('POST', '/actions', body)
250
+ break
251
+ }
252
+ default:
253
+ result = { error: 'Unknown actions subcommand. Use: list, create' }
254
+ }
255
+ break
256
+
257
+ case 'rewards':
258
+ switch (sub) {
259
+ case 'list':
260
+ result = await api('GET', `/rewards${buildQuery()}`)
261
+ break
262
+ case 'create': {
263
+ const partnerKey = args['partner-key']
264
+ const amount = args.amount
265
+ if (!partnerKey) { result = { error: '--partner-key required' }; break }
266
+ if (!amount) { result = { error: '--amount required (in cents)' }; break }
267
+ const body = {
268
+ partner_key: partnerKey,
269
+ amount: Number(amount),
270
+ }
271
+ if (args.description) body.description = args.description
272
+ if (args.currency) body.currency = args.currency
273
+ result = await api('POST', '/rewards', body)
274
+ break
275
+ }
276
+ default:
277
+ result = { error: 'Unknown rewards subcommand. Use: list, create' }
278
+ }
279
+ break
280
+
281
+ case 'leads':
282
+ switch (sub) {
283
+ case 'list':
284
+ result = await api('GET', `/leads${buildQuery()}`)
285
+ break
286
+ case 'get': {
287
+ const key = args.key
288
+ if (!key) { result = { error: '--key required (lead key)' }; break }
289
+ result = await api('GET', `/leads/${key}`)
290
+ break
291
+ }
292
+ case 'create': {
293
+ const partnerKey = args['partner-key']
294
+ const email = args.email
295
+ if (!partnerKey) { result = { error: '--partner-key required' }; break }
296
+ if (!email) { result = { error: '--email required' }; break }
297
+ const body = { partner_key: partnerKey, email }
298
+ if (args.name) body.name = args.name
299
+ if (args.company) body.company = args.company
300
+ result = await api('POST', '/leads', body)
301
+ break
302
+ }
303
+ case 'update': {
304
+ const key = args.key
305
+ if (!key) { result = { error: '--key required (lead key)' }; break }
306
+ const body = {}
307
+ if (args.email) body.email = args.email
308
+ if (args.name) body.name = args.name
309
+ if (args.status) body.status = args.status
310
+ result = await api('PATCH', `/leads/${key}`, body)
311
+ break
312
+ }
313
+ default:
314
+ result = { error: 'Unknown leads subcommand. Use: list, get, create, update' }
315
+ }
316
+ break
317
+
318
+ case 'groups':
319
+ switch (sub) {
320
+ case 'list':
321
+ result = await api('GET', `/groups${buildQuery()}`)
322
+ break
323
+ default:
324
+ result = { error: 'Unknown groups subcommand. Use: list' }
325
+ }
326
+ break
327
+
328
+ case 'webhooks':
329
+ switch (sub) {
330
+ case 'list':
331
+ result = await api('GET', `/webhooks${buildQuery()}`)
332
+ break
333
+ case 'get': {
334
+ const key = args.key
335
+ if (!key) { result = { error: '--key required (webhook key)' }; break }
336
+ result = await api('GET', `/webhooks/${key}`)
337
+ break
338
+ }
339
+ case 'create': {
340
+ const target = args.target
341
+ if (!target) { result = { error: '--target required (webhook URL)' }; break }
342
+ const body = { target }
343
+ if (args.events) body.events = args.events.split(',')
344
+ result = await api('POST', '/webhooks', body)
345
+ break
346
+ }
347
+ case 'delete': {
348
+ const key = args.key
349
+ if (!key) { result = { error: '--key required (webhook key)' }; break }
350
+ result = await api('DELETE', `/webhooks/${key}`)
351
+ break
352
+ }
353
+ default:
354
+ result = { error: 'Unknown webhooks subcommand. Use: list, get, create, delete' }
355
+ }
356
+ break
357
+
358
+ default:
359
+ result = {
360
+ error: 'Unknown command',
361
+ usage: {
362
+ partnerships: 'partnerships [list | get --key <key> | create --email <email> --group <group-key> | update --key <key>]',
363
+ customers: 'customers [list | get --key <key> | create --email <email> --partner-key <key> | update --key <key> | delete --key <key>]',
364
+ transactions: 'transactions [list | get --key <key> | create --customer-key <key> --amount <cents> | delete --key <key>]',
365
+ deals: 'deals [list | get --key <key> | create --partner-key <key> --name <name> | update --key <key> | archive --key <key>]',
366
+ actions: 'actions [list | create --customer-key <key> --action-key <key> [--value <n>]]',
367
+ rewards: 'rewards [list | create --partner-key <key> --amount <cents>]',
368
+ leads: 'leads [list | get --key <key> | create --partner-key <key> --email <email> | update --key <key>]',
369
+ groups: 'groups [list]',
370
+ webhooks: 'webhooks [list | get --key <key> | create --target <url> [--events <evt1,evt2>] | delete --key <key>]',
371
+ options: '--limit <n> --after <cursor> --before <cursor> --order-by <field>',
372
+ }
373
+ }
374
+ }
375
+
376
+ console.log(JSON.stringify(result, null, 2))
377
+ }
378
+
379
+ main().catch(err => {
380
+ console.error(JSON.stringify({ error: err.message }))
381
+ process.exit(1)
382
+ })
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.PLAUSIBLE_API_KEY
4
+ const BASE_URL = process.env.PLAUSIBLE_BASE_URL || 'https://plausible.io'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'PLAUSIBLE_API_KEY environment variable required' }))
8
+ process.exit(1)
9
+ }
10
+
11
+ async function api(method, path, body) {
12
+ if (args['dry-run']) {
13
+ return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: { Authorization: '***', 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: body || undefined }
14
+ }
15
+ const res = await fetch(`${BASE_URL}${path}`, {
16
+ method,
17
+ headers: {
18
+ 'Authorization': `Bearer ${API_KEY}`,
19
+ 'Content-Type': 'application/json',
20
+ 'Accept': 'application/json',
21
+ },
22
+ body: body ? JSON.stringify(body) : undefined,
23
+ })
24
+ const text = await res.text()
25
+ try {
26
+ return JSON.parse(text)
27
+ } catch {
28
+ return { status: res.status, body: text }
29
+ }
30
+ }
31
+
32
+ function parseArgs(args) {
33
+ const result = { _: [] }
34
+ for (let i = 0; i < args.length; i++) {
35
+ const arg = args[i]
36
+ if (arg.startsWith('--')) {
37
+ const key = arg.slice(2)
38
+ const next = args[i + 1]
39
+ if (next && !next.startsWith('--')) {
40
+ result[key] = next
41
+ i++
42
+ } else {
43
+ result[key] = true
44
+ }
45
+ } else {
46
+ result._.push(arg)
47
+ }
48
+ }
49
+ return result
50
+ }
51
+
52
+ const args = parseArgs(process.argv.slice(2))
53
+ const [cmd, sub, ...rest] = args._
54
+
55
+ async function main() {
56
+ let result
57
+ const siteId = args['site-id']
58
+ const dateRange = args['date-range'] || '30d'
59
+ const limit = args.limit ? Number(args.limit) : 100
60
+
61
+ switch (cmd) {
62
+ case 'stats':
63
+ if (!siteId) { result = { error: '--site-id required (your domain, e.g. example.com)' }; break }
64
+ switch (sub) {
65
+ case 'aggregate': {
66
+ const metrics = args.metrics?.split(',') || ['visitors', 'pageviews', 'bounce_rate', 'visit_duration']
67
+ result = await api('POST', '/api/v2/query', {
68
+ site_id: siteId,
69
+ metrics,
70
+ date_range: dateRange,
71
+ })
72
+ break
73
+ }
74
+ case 'timeseries': {
75
+ const metrics = args.metrics?.split(',') || ['visitors', 'pageviews']
76
+ const period = args.period || 'time:day'
77
+ result = await api('POST', '/api/v2/query', {
78
+ site_id: siteId,
79
+ metrics,
80
+ date_range: dateRange,
81
+ dimensions: [period],
82
+ })
83
+ break
84
+ }
85
+ case 'pages': {
86
+ const metrics = args.metrics?.split(',') || ['visitors', 'pageviews']
87
+ result = await api('POST', '/api/v2/query', {
88
+ site_id: siteId,
89
+ metrics,
90
+ date_range: dateRange,
91
+ dimensions: ['event:page'],
92
+ pagination: { limit },
93
+ })
94
+ break
95
+ }
96
+ case 'sources': {
97
+ const metrics = args.metrics?.split(',') || ['visitors', 'bounce_rate']
98
+ result = await api('POST', '/api/v2/query', {
99
+ site_id: siteId,
100
+ metrics,
101
+ date_range: dateRange,
102
+ dimensions: ['visit:source'],
103
+ pagination: { limit },
104
+ })
105
+ break
106
+ }
107
+ case 'countries': {
108
+ const metrics = args.metrics?.split(',') || ['visitors', 'percentage']
109
+ result = await api('POST', '/api/v2/query', {
110
+ site_id: siteId,
111
+ metrics,
112
+ date_range: dateRange,
113
+ dimensions: ['visit:country'],
114
+ pagination: { limit },
115
+ })
116
+ break
117
+ }
118
+ case 'devices': {
119
+ const metrics = args.metrics?.split(',') || ['visitors', 'percentage']
120
+ result = await api('POST', '/api/v2/query', {
121
+ site_id: siteId,
122
+ metrics,
123
+ date_range: dateRange,
124
+ dimensions: ['visit:device'],
125
+ pagination: { limit },
126
+ })
127
+ break
128
+ }
129
+ case 'utm': {
130
+ const param = args.param || 'utm_source'
131
+ const metrics = args.metrics?.split(',') || ['visitors', 'bounce_rate']
132
+ result = await api('POST', '/api/v2/query', {
133
+ site_id: siteId,
134
+ metrics,
135
+ date_range: dateRange,
136
+ dimensions: [`visit:${param}`],
137
+ pagination: { limit },
138
+ })
139
+ break
140
+ }
141
+ case 'query': {
142
+ const metrics = args.metrics?.split(',')
143
+ if (!metrics) { result = { error: '--metrics required (comma-separated)' }; break }
144
+ const body = { site_id: siteId, metrics, date_range: dateRange }
145
+ if (args.dimensions) body.dimensions = args.dimensions.split(',')
146
+ if (args.filters) {
147
+ try { body.filters = JSON.parse(args.filters) } catch { result = { error: '--filters must be valid JSON' }; break }
148
+ }
149
+ body.pagination = { limit }
150
+ result = await api('POST', '/api/v2/query', body)
151
+ break
152
+ }
153
+ case 'realtime':
154
+ result = await api('GET', `/api/v1/stats/realtime/visitors?site_id=${encodeURIComponent(siteId)}`)
155
+ break
156
+ default:
157
+ result = { error: 'Unknown stats subcommand. Use: aggregate, timeseries, pages, sources, countries, devices, utm, query, realtime' }
158
+ }
159
+ break
160
+
161
+ case 'sites':
162
+ switch (sub) {
163
+ case 'list':
164
+ result = await api('GET', '/api/v1/sites')
165
+ break
166
+ case 'get': {
167
+ if (!siteId) { result = { error: '--site-id required' }; break }
168
+ result = await api('GET', `/api/v1/sites/${encodeURIComponent(siteId)}`)
169
+ break
170
+ }
171
+ case 'create': {
172
+ const domain = args.domain
173
+ if (!domain) { result = { error: '--domain required' }; break }
174
+ const body = { domain }
175
+ if (args.timezone) body.timezone = args.timezone
176
+ result = await api('POST', '/api/v1/sites', body)
177
+ break
178
+ }
179
+ case 'delete': {
180
+ if (!siteId) { result = { error: '--site-id required' }; break }
181
+ result = await api('DELETE', `/api/v1/sites/${encodeURIComponent(siteId)}`)
182
+ break
183
+ }
184
+ default:
185
+ result = { error: 'Unknown sites subcommand. Use: list, get, create, delete' }
186
+ }
187
+ break
188
+
189
+ case 'goals':
190
+ if (!siteId) { result = { error: '--site-id required' }; break }
191
+ switch (sub) {
192
+ case 'list':
193
+ result = await api('GET', `/api/v1/sites/goals?site_id=${encodeURIComponent(siteId)}`)
194
+ break
195
+ case 'create': {
196
+ const goalType = args['goal-type']
197
+ if (!goalType) { result = { error: '--goal-type required (event or page)' }; break }
198
+ const body = { site_id: siteId, goal_type: goalType }
199
+ if (goalType === 'event') {
200
+ if (!args['event-name']) { result = { error: '--event-name required for event goals' }; break }
201
+ body.event_name = args['event-name']
202
+ } else if (goalType === 'page') {
203
+ if (!args['page-path']) { result = { error: '--page-path required for page goals' }; break }
204
+ body.page_path = args['page-path']
205
+ }
206
+ result = await api('PUT', '/api/v1/sites/goals', body)
207
+ break
208
+ }
209
+ case 'delete': {
210
+ const goalId = args['goal-id']
211
+ if (!goalId) { result = { error: '--goal-id required' }; break }
212
+ result = await api('DELETE', `/api/v1/sites/goals/${goalId}`, { site_id: siteId })
213
+ break
214
+ }
215
+ default:
216
+ result = { error: 'Unknown goals subcommand. Use: list, create, delete' }
217
+ }
218
+ break
219
+
220
+ default:
221
+ result = {
222
+ error: 'Unknown command',
223
+ usage: {
224
+ stats: {
225
+ aggregate: 'stats aggregate --site-id <domain> [--date-range <30d>] [--metrics <m1,m2>]',
226
+ timeseries: 'stats timeseries --site-id <domain> [--date-range <30d>] [--period <time:day>]',
227
+ pages: 'stats pages --site-id <domain> [--date-range <30d>] [--limit <n>]',
228
+ sources: 'stats sources --site-id <domain> [--date-range <30d>]',
229
+ countries: 'stats countries --site-id <domain> [--date-range <30d>]',
230
+ devices: 'stats devices --site-id <domain> [--date-range <30d>]',
231
+ utm: 'stats utm --site-id <domain> [--param <utm_source>] [--date-range <30d>]',
232
+ query: 'stats query --site-id <domain> --metrics <m1,m2> [--dimensions <d1,d2>] [--filters <json>]',
233
+ realtime: 'stats realtime --site-id <domain>',
234
+ },
235
+ sites: 'sites [list | get --site-id <domain> | create --domain <domain> | delete --site-id <domain>]',
236
+ goals: 'goals [list | create --goal-type <event|page> --event-name <name> | delete --goal-id <id>] --site-id <domain>',
237
+ options: '--date-range <day|7d|30d|month|6mo|12mo|year> --limit <n>',
238
+ env: 'PLAUSIBLE_BASE_URL for self-hosted instances (default: https://plausible.io)',
239
+ }
240
+ }
241
+ }
242
+
243
+ console.log(JSON.stringify(result, null, 2))
244
+ }
245
+
246
+ main().catch(err => {
247
+ console.error(JSON.stringify({ error: err.message }))
248
+ process.exit(1)
249
+ })