@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,153 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.TOLT_API_KEY
4
+ const BASE_URL = 'https://api.tolt.io/v1'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'TOLT_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' }, 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
+ },
21
+ body: body ? JSON.stringify(body) : undefined,
22
+ })
23
+ const text = await res.text()
24
+ try {
25
+ return JSON.parse(text)
26
+ } catch {
27
+ return { status: res.status, body: text }
28
+ }
29
+ }
30
+
31
+ function parseArgs(args) {
32
+ const result = { _: [] }
33
+ for (let i = 0; i < args.length; i++) {
34
+ const arg = args[i]
35
+ if (arg.startsWith('--')) {
36
+ const key = arg.slice(2)
37
+ const next = args[i + 1]
38
+ if (next && !next.startsWith('--')) {
39
+ result[key] = next
40
+ i++
41
+ } else {
42
+ result[key] = true
43
+ }
44
+ } else {
45
+ result._.push(arg)
46
+ }
47
+ }
48
+ return result
49
+ }
50
+
51
+ const args = parseArgs(process.argv.slice(2))
52
+ const [cmd, sub, ...rest] = args._
53
+
54
+ async function main() {
55
+ let result
56
+
57
+ switch (cmd) {
58
+ case 'affiliates':
59
+ switch (sub) {
60
+ case 'list':
61
+ result = await api('GET', '/affiliates')
62
+ break
63
+ case 'get': {
64
+ const id = rest[0] || args.id
65
+ if (!id) { result = { error: 'Affiliate ID required (positional arg or --id)' }; break }
66
+ result = await api('GET', `/affiliates/${id}`)
67
+ break
68
+ }
69
+ case 'create': {
70
+ const body = {}
71
+ if (args.email) body.email = args.email
72
+ if (args.name) body.name = args.name
73
+ result = await api('POST', '/affiliates', body)
74
+ break
75
+ }
76
+ case 'update': {
77
+ if (!args.id) { result = { error: '--id required (affiliate ID)' }; break }
78
+ const body = {}
79
+ if (args['commission-rate']) body.commission_rate = Number(args['commission-rate'])
80
+ if (args['payout-method']) body.payout_method = args['payout-method']
81
+ if (args['paypal-email']) body.paypal_email = args['paypal-email']
82
+ result = await api('PATCH', `/affiliates/${args.id}`, body)
83
+ break
84
+ }
85
+ default:
86
+ result = { error: 'Unknown affiliates subcommand. Use: list, get, create, update' }
87
+ }
88
+ break
89
+
90
+ case 'referrals':
91
+ switch (sub) {
92
+ case 'list': {
93
+ const params = new URLSearchParams()
94
+ if (args['affiliate-id']) params.set('affiliate_id', args['affiliate-id'])
95
+ result = await api('GET', `/referrals?${params}`)
96
+ break
97
+ }
98
+ case 'get': {
99
+ const params = new URLSearchParams()
100
+ if (args['customer-id']) params.set('customer_id', args['customer-id'])
101
+ result = await api('GET', `/referrals?${params}`)
102
+ break
103
+ }
104
+ default:
105
+ result = { error: 'Unknown referrals subcommand. Use: list, get' }
106
+ }
107
+ break
108
+
109
+ case 'commissions':
110
+ switch (sub) {
111
+ case 'list': {
112
+ const params = new URLSearchParams()
113
+ if (args['affiliate-id']) params.set('affiliate_id', args['affiliate-id'])
114
+ result = await api('GET', `/commissions?${params}`)
115
+ break
116
+ }
117
+ default:
118
+ result = { error: 'Unknown commissions subcommand. Use: list' }
119
+ }
120
+ break
121
+
122
+ case 'payouts':
123
+ switch (sub) {
124
+ case 'list': {
125
+ const params = new URLSearchParams()
126
+ if (args['affiliate-id']) params.set('affiliate_id', args['affiliate-id'])
127
+ result = await api('GET', `/payouts?${params}`)
128
+ break
129
+ }
130
+ default:
131
+ result = { error: 'Unknown payouts subcommand. Use: list' }
132
+ }
133
+ break
134
+
135
+ default:
136
+ result = {
137
+ error: 'Unknown command',
138
+ usage: {
139
+ affiliates: 'affiliates [list|get|create|update] [id] [--email <email>] [--name <name>] [--id <id>] [--commission-rate <rate>] [--payout-method <method>] [--paypal-email <email>]',
140
+ referrals: 'referrals [list|get] [--affiliate-id <id>] [--customer-id <id>]',
141
+ commissions: 'commissions [list] [--affiliate-id <id>]',
142
+ payouts: 'payouts [list] [--affiliate-id <id>]',
143
+ }
144
+ }
145
+ }
146
+
147
+ console.log(JSON.stringify(result, null, 2))
148
+ }
149
+
150
+ main().catch(err => {
151
+ console.error(JSON.stringify({ error: err.message }))
152
+ process.exit(1)
153
+ })
@@ -0,0 +1,276 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.TRUSTPILOT_API_KEY
4
+ const API_SECRET = process.env.TRUSTPILOT_API_SECRET
5
+ const BUSINESS_UNIT_ID = process.env.TRUSTPILOT_BUSINESS_UNIT_ID
6
+ const BASE_URL = 'https://api.trustpilot.com/v1'
7
+
8
+ if (!API_KEY) {
9
+ console.error(JSON.stringify({ error: 'TRUSTPILOT_API_KEY environment variable required' }))
10
+ process.exit(1)
11
+ }
12
+
13
+ let accessToken = null
14
+
15
+ async function getAccessToken() {
16
+ if (accessToken) return accessToken
17
+ if (!API_SECRET) return null
18
+ const res = await fetch(`${BASE_URL}/oauth/oauth-business-users-for-applications/accesstoken`, {
19
+ method: 'POST',
20
+ headers: {
21
+ 'Authorization': 'Basic ' + Buffer.from(`${API_KEY}:${API_SECRET}`).toString('base64'),
22
+ 'Content-Type': 'application/x-www-form-urlencoded',
23
+ },
24
+ body: 'grant_type=client_credentials',
25
+ })
26
+ const data = await res.json()
27
+ if (data.access_token) {
28
+ accessToken = data.access_token
29
+ return accessToken
30
+ }
31
+ return null
32
+ }
33
+
34
+ async function api(method, path, body, auth = 'apikey') {
35
+ if (args['dry-run']) {
36
+ const maskedHeaders = { 'Content-Type': 'application/json', 'Accept': 'application/json' }
37
+ if (auth === 'bearer') {
38
+ maskedHeaders['Authorization'] = '***'
39
+ } else {
40
+ maskedHeaders['apikey'] = '***'
41
+ }
42
+ return { _dry_run: true, method, url: `${BASE_URL}${path}`, headers: maskedHeaders, body: body || undefined }
43
+ }
44
+ const headers = {
45
+ 'Content-Type': 'application/json',
46
+ 'Accept': 'application/json',
47
+ }
48
+ if (auth === 'bearer') {
49
+ const token = await getAccessToken()
50
+ if (!token) {
51
+ return { error: 'TRUSTPILOT_API_SECRET required for private API endpoints' }
52
+ }
53
+ headers['Authorization'] = `Bearer ${token}`
54
+ } else {
55
+ headers['apikey'] = API_KEY
56
+ }
57
+ const res = await fetch(`${BASE_URL}${path}`, {
58
+ method,
59
+ headers,
60
+ body: body ? JSON.stringify(body) : undefined,
61
+ })
62
+ const text = await res.text()
63
+ try {
64
+ return JSON.parse(text)
65
+ } catch {
66
+ return { status: res.status, body: text }
67
+ }
68
+ }
69
+
70
+ function parseArgs(args) {
71
+ const result = { _: [] }
72
+ for (let i = 0; i < args.length; i++) {
73
+ const arg = args[i]
74
+ if (arg.startsWith('--')) {
75
+ const key = arg.slice(2)
76
+ const next = args[i + 1]
77
+ if (next && !next.startsWith('--')) {
78
+ result[key] = next
79
+ i++
80
+ } else {
81
+ result[key] = true
82
+ }
83
+ } else {
84
+ result._.push(arg)
85
+ }
86
+ }
87
+ return result
88
+ }
89
+
90
+ const args = parseArgs(process.argv.slice(2))
91
+ const [cmd, sub, ...rest] = args._
92
+
93
+ async function main() {
94
+ let result
95
+ const businessUnitId = args['business-unit'] || BUSINESS_UNIT_ID
96
+ const limit = args.limit ? Number(args.limit) : 20
97
+
98
+ switch (cmd) {
99
+ case 'business':
100
+ switch (sub) {
101
+ case 'search': {
102
+ const query = args.query
103
+ if (!query) { result = { error: '--query required' }; break }
104
+ result = await api('GET', `/business-units/search?query=${encodeURIComponent(query)}&limit=${limit}`)
105
+ break
106
+ }
107
+ case 'get': {
108
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
109
+ result = await api('GET', `/business-units/${businessUnitId}`)
110
+ break
111
+ }
112
+ case 'profile': {
113
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
114
+ result = await api('GET', `/business-units/${businessUnitId}/profileinfo`)
115
+ break
116
+ }
117
+ case 'categories': {
118
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
119
+ result = await api('GET', `/business-units/${businessUnitId}/categories`)
120
+ break
121
+ }
122
+ case 'web-links': {
123
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
124
+ const locale = args.locale || 'en-US'
125
+ result = await api('GET', `/business-units/${businessUnitId}/web-links?locale=${encodeURIComponent(locale)}`)
126
+ break
127
+ }
128
+ default:
129
+ result = { error: 'Unknown business subcommand. Use: search, get, profile, categories, web-links' }
130
+ }
131
+ break
132
+
133
+ case 'reviews':
134
+ switch (sub) {
135
+ case 'list': {
136
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
137
+ const reviewParams = new URLSearchParams({ perPage: String(limit), orderBy: args['order-by'] || 'createdat.desc' })
138
+ if (args.stars) reviewParams.set('stars', args.stars)
139
+ if (args.language) reviewParams.set('language', args.language)
140
+ result = await api('GET', `/business-units/${businessUnitId}/reviews?${reviewParams}`)
141
+ break
142
+ }
143
+ case 'get': {
144
+ const reviewId = args.id
145
+ if (!reviewId) { result = { error: '--id required' }; break }
146
+ result = await api('GET', `/reviews/${reviewId}`)
147
+ break
148
+ }
149
+ case 'private': {
150
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
151
+ const privateParams = new URLSearchParams({ perPage: String(limit) })
152
+ if (args.stars) privateParams.set('stars', args.stars)
153
+ result = await api('GET', `/private/business-units/${businessUnitId}/reviews?${privateParams}`, null, 'bearer')
154
+ break
155
+ }
156
+ case 'latest':
157
+ result = await api('GET', `/reviews/latest?count=${limit}`)
158
+ break
159
+ case 'reply': {
160
+ const reviewId = args.id
161
+ const message = args.message
162
+ if (!reviewId) { result = { error: '--id required' }; break }
163
+ if (!message) { result = { error: '--message required' }; break }
164
+ result = await api('POST', `/private/reviews/${reviewId}/reply`, { message }, 'bearer')
165
+ break
166
+ }
167
+ case 'delete-reply': {
168
+ const reviewId = args.id
169
+ if (!reviewId) { result = { error: '--id required' }; break }
170
+ result = await api('DELETE', `/private/reviews/${reviewId}/reply`, null, 'bearer')
171
+ break
172
+ }
173
+ default:
174
+ result = { error: 'Unknown reviews subcommand. Use: list, get, private, latest, reply, delete-reply' }
175
+ }
176
+ break
177
+
178
+ case 'invitations':
179
+ switch (sub) {
180
+ case 'create': {
181
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
182
+ const email = args.email
183
+ const name = args.name
184
+ if (!email) { result = { error: '--email required' }; break }
185
+ if (!name) { result = { error: '--name required' }; break }
186
+ const templateId = args.template
187
+ const redirectUri = args['redirect-uri'] || 'https://trustpilot.com'
188
+ const payload = {
189
+ consumerEmail: email,
190
+ consumerName: name,
191
+ referenceNumber: args.reference || '',
192
+ senderEmail: args['sender-email'] || undefined,
193
+ replyTo: args['reply-to'] || undefined,
194
+ templateId: templateId || undefined,
195
+ redirectUri,
196
+ }
197
+ result = await api('POST', `/private/business-units/${businessUnitId}/email-invitations`, payload, 'bearer')
198
+ break
199
+ }
200
+ case 'link': {
201
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
202
+ const email = args.email
203
+ const name = args.name
204
+ if (!email) { result = { error: '--email required' }; break }
205
+ if (!name) { result = { error: '--name required' }; break }
206
+ result = await api('POST', `/private/business-units/${businessUnitId}/invitation-links`, {
207
+ email,
208
+ name,
209
+ referenceId: args.reference || '',
210
+ redirectUri: args['redirect-uri'] || 'https://trustpilot.com',
211
+ }, 'bearer')
212
+ break
213
+ }
214
+ case 'templates': {
215
+ if (!businessUnitId) { result = { error: '--business-unit or TRUSTPILOT_BUSINESS_UNIT_ID required' }; break }
216
+ result = await api('GET', `/private/business-units/${businessUnitId}/templates`, null, 'bearer')
217
+ break
218
+ }
219
+ default:
220
+ result = { error: 'Unknown invitations subcommand. Use: create, link, templates' }
221
+ }
222
+ break
223
+
224
+ case 'tags':
225
+ switch (sub) {
226
+ case 'get': {
227
+ const reviewId = args.id
228
+ if (!reviewId) { result = { error: '--id required' }; break }
229
+ result = await api('GET', `/private/reviews/${reviewId}/tags`, null, 'bearer')
230
+ break
231
+ }
232
+ case 'add': {
233
+ const reviewId = args.id
234
+ const group = args.group
235
+ const value = args.value
236
+ if (!reviewId) { result = { error: '--id required' }; break }
237
+ if (!group || !value) { result = { error: '--group and --value required' }; break }
238
+ result = await api('PUT', `/private/reviews/${reviewId}/tags`, {
239
+ tags: [{ group, value }],
240
+ }, 'bearer')
241
+ break
242
+ }
243
+ case 'remove': {
244
+ const reviewId = args.id
245
+ const group = args.group
246
+ const value = args.value
247
+ if (!reviewId) { result = { error: '--id required' }; break }
248
+ if (!group || !value) { result = { error: '--group and --value required' }; break }
249
+ result = await api('DELETE', `/private/reviews/${reviewId}/tags?group=${encodeURIComponent(group)}&value=${encodeURIComponent(value)}`, null, 'bearer')
250
+ break
251
+ }
252
+ default:
253
+ result = { error: 'Unknown tags subcommand. Use: get, add, remove' }
254
+ }
255
+ break
256
+
257
+ default:
258
+ result = {
259
+ error: 'Unknown command',
260
+ usage: {
261
+ business: 'business [search --query <q> | get | profile | categories | web-links]',
262
+ reviews: 'reviews [list | get --id <id> | private | latest | reply --id <id> --message <msg> | delete-reply --id <id>]',
263
+ invitations: 'invitations [create --email <e> --name <n> | link --email <e> --name <n> | templates]',
264
+ tags: 'tags [get --id <id> | add --id <id> --group <g> --value <v> | remove --id <id> --group <g> --value <v>]',
265
+ options: '--business-unit <id> --limit <n> --stars <1-5> --language <code>',
266
+ }
267
+ }
268
+ }
269
+
270
+ console.log(JSON.stringify(result, null, 2))
271
+ }
272
+
273
+ main().catch(err => {
274
+ console.error(JSON.stringify({ error: err.message }))
275
+ process.exit(1)
276
+ })
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env node
2
+
3
+ const API_KEY = process.env.TYPEFORM_API_KEY
4
+ const BASE_URL = 'https://api.typeform.com'
5
+
6
+ if (!API_KEY) {
7
+ console.error(JSON.stringify({ error: 'TYPEFORM_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 pageSize = args['page-size'] ? Number(args['page-size']) : undefined
58
+
59
+ switch (cmd) {
60
+ case 'forms':
61
+ switch (sub) {
62
+ case 'list': {
63
+ const params = new URLSearchParams()
64
+ if (pageSize) params.set('page_size', String(pageSize))
65
+ if (args.page) params.set('page', args.page)
66
+ if (args['workspace-id']) params.set('workspace_id', args['workspace-id'])
67
+ if (args.search) params.set('search', args.search)
68
+ const qs = params.toString()
69
+ result = await api('GET', `/forms${qs ? '?' + qs : ''}`)
70
+ break
71
+ }
72
+ case 'get': {
73
+ const id = args.id
74
+ if (!id) { result = { error: '--id required (form ID)' }; break }
75
+ result = await api('GET', `/forms/${id}`)
76
+ break
77
+ }
78
+ case 'create': {
79
+ const title = args.title
80
+ if (!title) { result = { error: '--title required' }; break }
81
+ const body = { title }
82
+ if (args['workspace-id']) {
83
+ body.workspace = { href: `${BASE_URL}/workspaces/${args['workspace-id']}` }
84
+ }
85
+ result = await api('POST', '/forms', body)
86
+ break
87
+ }
88
+ case 'update': {
89
+ const id = args.id
90
+ if (!id) { result = { error: '--id required (form ID)' }; break }
91
+ const body = {}
92
+ if (args.title) body.title = args.title
93
+ result = await api('PUT', `/forms/${id}`, body)
94
+ break
95
+ }
96
+ case 'delete': {
97
+ const id = args.id
98
+ if (!id) { result = { error: '--id required (form ID)' }; break }
99
+ result = await api('DELETE', `/forms/${id}`)
100
+ break
101
+ }
102
+ default:
103
+ result = { error: 'Unknown forms subcommand. Use: list, get, create, update, delete' }
104
+ }
105
+ break
106
+
107
+ case 'responses':
108
+ switch (sub) {
109
+ case 'list': {
110
+ const id = args.id
111
+ if (!id) { result = { error: '--id required (form ID)' }; break }
112
+ const params = new URLSearchParams()
113
+ if (pageSize) params.set('page_size', String(pageSize))
114
+ if (args.since) params.set('since', args.since)
115
+ if (args.until) params.set('until', args.until)
116
+ if (args.after) params.set('after', args.after)
117
+ if (args.before) params.set('before', args.before)
118
+ if (args['response-type']) params.set('response_type', args['response-type'])
119
+ if (args.query) params.set('query', args.query)
120
+ if (args.fields) params.set('fields', args.fields)
121
+ if (args.sort) params.set('sort', args.sort)
122
+ const qs = params.toString()
123
+ result = await api('GET', `/forms/${id}/responses${qs ? '?' + qs : ''}`)
124
+ break
125
+ }
126
+ case 'delete': {
127
+ const id = args.id
128
+ if (!id) { result = { error: '--id required (form ID)' }; break }
129
+ const responseIds = args['response-ids']
130
+ if (!responseIds) { result = { error: '--response-ids required (comma-separated)' }; break }
131
+ result = await api('DELETE', `/forms/${id}/responses?included_response_ids=${encodeURIComponent(responseIds)}`)
132
+ break
133
+ }
134
+ default:
135
+ result = { error: 'Unknown responses subcommand. Use: list, delete' }
136
+ }
137
+ break
138
+
139
+ case 'webhooks':
140
+ switch (sub) {
141
+ case 'list': {
142
+ const id = args.id
143
+ if (!id) { result = { error: '--id required (form ID)' }; break }
144
+ result = await api('GET', `/forms/${id}/webhooks`)
145
+ break
146
+ }
147
+ case 'get': {
148
+ const id = args.id
149
+ const tag = args.tag
150
+ if (!id || !tag) { result = { error: '--id (form ID) and --tag required' }; break }
151
+ result = await api('GET', `/forms/${id}/webhooks/${tag}`)
152
+ break
153
+ }
154
+ case 'create': {
155
+ const id = args.id
156
+ const tag = args.tag
157
+ const url = args.url
158
+ if (!id || !tag || !url) { result = { error: '--id (form ID), --tag, and --url required' }; break }
159
+ const body = { url, enabled: args.enabled !== 'false' }
160
+ result = await api('PUT', `/forms/${id}/webhooks/${tag}`, body)
161
+ break
162
+ }
163
+ case 'delete': {
164
+ const id = args.id
165
+ const tag = args.tag
166
+ if (!id || !tag) { result = { error: '--id (form ID) and --tag required' }; break }
167
+ result = await api('DELETE', `/forms/${id}/webhooks/${tag}`)
168
+ break
169
+ }
170
+ default:
171
+ result = { error: 'Unknown webhooks subcommand. Use: list, get, create, delete' }
172
+ }
173
+ break
174
+
175
+ case 'themes':
176
+ switch (sub) {
177
+ case 'list': {
178
+ const params = new URLSearchParams()
179
+ if (pageSize) params.set('page_size', String(pageSize))
180
+ if (args.page) params.set('page', args.page)
181
+ const qs = params.toString()
182
+ result = await api('GET', `/themes${qs ? '?' + qs : ''}`)
183
+ break
184
+ }
185
+ case 'get': {
186
+ const id = args.id
187
+ if (!id) { result = { error: '--id required (theme ID)' }; break }
188
+ result = await api('GET', `/themes/${id}`)
189
+ break
190
+ }
191
+ case 'create': {
192
+ const name = args.name
193
+ if (!name) { result = { error: '--name required' }; break }
194
+ const body = { name }
195
+ if (args.font) body.font = args.font
196
+ result = await api('POST', '/themes', body)
197
+ break
198
+ }
199
+ case 'delete': {
200
+ const id = args.id
201
+ if (!id) { result = { error: '--id required (theme ID)' }; break }
202
+ result = await api('DELETE', `/themes/${id}`)
203
+ break
204
+ }
205
+ default:
206
+ result = { error: 'Unknown themes subcommand. Use: list, get, create, delete' }
207
+ }
208
+ break
209
+
210
+ case 'images':
211
+ switch (sub) {
212
+ case 'list':
213
+ result = await api('GET', '/images')
214
+ break
215
+ case 'get': {
216
+ const id = args.id
217
+ if (!id) { result = { error: '--id required (image ID)' }; break }
218
+ result = await api('GET', `/images/${id}`)
219
+ break
220
+ }
221
+ default:
222
+ result = { error: 'Unknown images subcommand. Use: list, get' }
223
+ }
224
+ break
225
+
226
+ case 'workspaces':
227
+ switch (sub) {
228
+ case 'list': {
229
+ const params = new URLSearchParams()
230
+ if (pageSize) params.set('page_size', String(pageSize))
231
+ if (args.page) params.set('page', args.page)
232
+ if (args.search) params.set('search', args.search)
233
+ const qs = params.toString()
234
+ result = await api('GET', `/workspaces${qs ? '?' + qs : ''}`)
235
+ break
236
+ }
237
+ case 'get': {
238
+ const id = args.id
239
+ if (!id) { result = { error: '--id required (workspace ID)' }; break }
240
+ result = await api('GET', `/workspaces/${id}`)
241
+ break
242
+ }
243
+ default:
244
+ result = { error: 'Unknown workspaces subcommand. Use: list, get' }
245
+ }
246
+ break
247
+
248
+ default:
249
+ result = {
250
+ error: 'Unknown command',
251
+ usage: {
252
+ forms: 'forms [list | get --id <id> | create --title <title> | update --id <id> --title <title> | delete --id <id>]',
253
+ responses: 'responses [list --id <form_id> | delete --id <form_id> --response-ids <id1,id2>]',
254
+ webhooks: 'webhooks [list --id <form_id> | get --id <form_id> --tag <tag> | create --id <form_id> --tag <tag> --url <url> | delete --id <form_id> --tag <tag>]',
255
+ themes: 'themes [list | get --id <id> | create --name <name> | delete --id <id>]',
256
+ images: 'images [list | get --id <id>]',
257
+ workspaces: 'workspaces [list | get --id <id>]',
258
+ options: '--page-size <n> --page <n> --since <iso> --until <iso> --query <text>',
259
+ }
260
+ }
261
+ }
262
+
263
+ console.log(JSON.stringify(result, null, 2))
264
+ }
265
+
266
+ main().catch(err => {
267
+ console.error(JSON.stringify({ error: err.message }))
268
+ process.exit(1)
269
+ })